使用 VHDL 实例化 FPGA 中的 RAM

2023-12-24

我试图按照中的指导实现双端口 RAM这篇优秀的博文 http://danstrother.com/2010/09/11/inferring-rams-in-fpgas/。然而,ModelSim 在编译时给出以下警告:

** Warning: fifo_ram.vhdl(24): (vcom-1236) Shared variables must be of a protected type.

我似乎也无法将其创建为波形,这表明使用下面的代码无法识别该变量。

如何正确将此变量声明为“受保护”类型?另外,作为关于共享变量的更普遍的问题 - 该变量是否在设计中的所有实体之间共享?

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

entity fifo_ram is 
    generic (data : natural := 8;
             addr : natural := 16);

    port (w_clk : in std_logic;
          w_en : in std_logic;
          w_addr : in std_logic_vector (addr-1 downto 0);
          w_data : in std_logic_vector (data-1 downto 0);
          --
          r_clk : in std_logic;
          r_rdy : in std_logic;
          r_addr : in std_logic_vector (addr-1 downto 0);
          r_data : out std_logic_vector (data-1 downto 0));
end fifo_ram;

architecture rtl of fifo_ram is 
    -- shared memory
    type mem_type is array ( (2**addr) - 1 downto 0 ) of std_logic_vector(data-1 downto 0);
    shared variable mem : mem_type;

begin
    write: process (w_clk)
    begin 
        if (rising_edge(w_clk)) then 
            if (w_en = '1') then
                mem(conv_integer(w_addr)) := w_data;
            end if;
        end if;
    end process write;

end architecture;

----------------------------------------------

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

entity tb_fifo is 
    generic (data : natural := 8;
             addr : natural := 16);
end entity;

architecture testbed of tb_fifo is

    signal tb_w_clk, tb_w_en : std_logic := '0';
    signal tb_w_addr : std_logic_vector (addr-1 downto 0);
    signal tb_w_data : std_logic_vector (data-1 downto 0);
    signal tb_r_clk, tb_r_rdy : std_logic := '0';
    signal tb_r_addr : std_logic_vector (addr-1 downto 0);
    signal tb_r_data : std_logic_vector (data-1 downto 0);
begin 
    dut : entity work.fifo_ram(rtl)
        port map(tb_w_clk, tb_w_en, tb_w_addr, tb_w_data,
                 tb_r_clk, tb_r_rdy, tb_r_addr, tb_r_data);

    wclock : process is
    begin
        tb_w_clk <= '1';
        wait for 10 ns;
        tb_w_clk <= '0';
        wait for 10 ns;
    end process wclock;

    wdata : process is
    begin
        tb_w_addr <= x"FFFF";
        tb_w_data <= x"AA";
        wait for 100 ns;
        tb_w_en <= '1';
        wait for 70 ns;
        tb_w_en <= '0';
        wait;
    end process wdata;

end architecture;

好的,读完这篇博客文章后,我现在明白为什么他们使用共享变量而不是信号。这是因为多个进程正在分配给这个变量,这在 a 的情况下是不可能的reg在 Verilog 或signal在VHDL中。在这种情况下,合成器将产生一个错误,抱怨多个驱动程序mem。但为了在这种情况下使用共享变量,您必须将其声明为受保护的。您需要做的是声明一个受保护的数据类型,然后封装您的mem其中的变量,很像面向对象语言中的类。以下是受保护数据类型的示例:

type mem_envelope is protected        -- protected type declaration

variable mem : mem_type;

function GetVal( addr : integer ) return std_logic_vector(data - 1 downto 0);
function SetVal( addr : integer; val : std_logic_vector(data - 1 downto 0) ) return boolean; --may be used to indicate whether write was successfull or not

end protected mem_envelope;

然后声明一个 mem_envelope 类型的共享变量并使用GetVal and SetVal用于在进程内的内存中读取/写入值的函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 VHDL 实例化 FPGA 中的 RAM 的相关文章

  • git 嵌套存储库 - 子模块、符号链接、其他

    我正在尝试使用 git 设置我的 Zend Framework 开发环境 或更重要的是我的目录结构 然而 我的根本问题实际上与所涉及的特定库无关 但更重要的是如何让 git 完成我想要的事情 我的项目根目录是 home jsuggs pro

随机推荐