为 Xilinx vivado 推断 VHDL 中的 2d 块 RAM [英] Infer 2d block RAM in VHDL for Xilinx vivado

查看:115
本文介绍了为 Xilinx vivado 推断 VHDL 中的 2d 块 RAM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 VHDL 中推断一个 2d 块 ram.但精心设计的电路原来是一个寄存器和多路复用器的电路.与 RAM 有关的代码的主要文件是:

I am trying to infer a 2d block ram in VHDL. But the elaborated circuit turns out to be a circuit of registers and MUXs. The main file for the code pertaining to the RAM is:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.shared_resources.all;

entity weight_ram is
    port (clk : in std_logic;
            write_enable : in std_logic;
            row_addr : in natural range 0 to max_NR-1;
            data_in : in neuron_weight_array;
            data_out : out neuron_weight_array);
end weight_ram;

architecture rtl of weight_ram is
    signal ram : weight_ram_array;
begin
    ram_process : process (clk)
        variable f : integer;
    begin
        if (rising_edge (clk)) then
            if (write_enable = '1') then
                for f in 0 to n_feature-1 loop
                    ram (row_addr, f) <= data_in (f);
                end loop;
            end if;
            for f in 0 to n_feature-1 loop
                data_out (f) <= ram (row_addr, f);
            end loop;
        end if;
    end process;
end rtl;

包含使用的常量的文件是:

The file containing the constants used is:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package shared_resources is
    constant n_feature : integer := 24;
    constant max_NR : integer := 10; -- maximum number of neurons allowed
    constant weightw : integer := 10; -- width of the weight (1:0:9)

    subtype weight_type is signed (weightw-1 downto 0);
    type neuron_weight_array is array (0 to n_feature-1) of weight_type;
    type weight_ram_array is array (0 to max_NR-1, 0 to n_feature-1) of weight_type;
end shared_resources;

如何确保代码被推断为块 RAM?

How can I ensure that the code gets inferred as a block RAM?

更新:更新了代码以从二维数组中读取单个元素(基于 morten zilmer 的回答).但它仍然没有被推断为块 RAM.

Update: Updated the code to read single element from 2d array (based on morten zilmer's answer). But it still does not gets inferred as block RAM.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.shared_resources.all;

entity weight_ram is
    port (clk : in std_logic;
            write_enable : in std_logic;
            row_addr : in natural range 0 to max_NR-1;
            col_addr : in natural range 0 to n_feature-1;
            data_in : in weight_type;
            data_out : out weight_type);
end weight_ram;

architecture rtl of weight_ram is
    signal ram : weight_ram_array;
begin
    ram_process : process (clk)
        variable f : integer;
    begin
        if (rising_edge (clk)) then
            if (write_enable = '1') then
                ram (row_addr, col_addr) <= data_in;
            end if;
            data_out <= ram (row_addr, col_addr);
        end if;
    end process;
end rtl;

推荐答案

这个:

subtype weight_type is signed (weightw-1 downto 0);
type weight_ram_array is array (0 to max_NR-1, 0 to n_feature-1) of weight_type;

不会被合成到 Xilinx 器件上的 BRAM.我假设您会看到类似这样的消息:它不会映射到 BRAM,它太稀疏了" 或类似的消息.但是,您可以做一个小技巧.如果您想使用单独的 row_addrcol_addr 进行地址计算,您可以更改内存并连接地址,例如:

won't be synthesized to the BRAM on Xilinx devices. I assume you are seeing messages like: "It won't be mapped to BRAM, it is too sparse" or similar. However, there is a small trick you can do. If you want to use separate row_addr and col_addr for your address calculation you can change your memory and concatenate the addresses like:

architecture rtl of weight_ram is

type my_weight_type_array is array(0 to max_NR*n_feature-1) of weight_type;
signal ram : my_weight_type_array;

signal row_and_col : natural range 0 to max_NR*n_feature-1 ;

begin
    row_and_col <= to_integer(to_unsigned(row_addr,4) & to_unsigned(col_addr,5));                                                                                                                    

    ram_process : process (clk)
        variable f : integer;
    begin
        if (rising_edge (clk)) then
            if (write_enable = '1') then
                ram (row_and_col) <= data_in;
            end if; 
            data_out <= ram (row_and_col);
        end if; 
    end process;
end rtl;

注意:过去 5 年我没有用 VHDL 写过任何东西,所以你应该模拟它并检查它的行为是否正确.尤其是这部分:

NOTE: I haven't written anything in VHDL for last 5 years so you should simulate it and check if that behaves correctly. Especially this part:

row_and_col <= to_integer(to_unsigned(row_addr,4) & to_unsigned(col_addr,5));

Ekhm...强类型语言...

Ekhm... Strongly typed language...

这篇关于为 Xilinx vivado 推断 VHDL 中的 2d 块 RAM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆