使用VHDL实例化FPGA中的RAM [英] Instantiation of RAM in FPGAs using VHDL

查看:411
本文介绍了使用VHDL实例化FPGA中的RAM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图按照此优秀的博客文章.但是,ModelSim在编译时会发出以下警告:

I was attempting to implement a dual port RAM as guided in this excellent blog post. However, ModelSim is giving the following warning when compiling:

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

我似乎也无法将其创建为wave,这向我表明该变量未被使用下面的代码识别.

I also seem unable to create this as a wave, indicating to me that the variable is not being recognised using my code below.

如何正确地将此变量声明为受保护"类型?另外,作为关于共享变量的更一般的问题-这个变量是否在设计中的所有实体之间共享?

How can I correctly declare this variable as a "protected" type? Also, as a more general question about shared variables - is this variable shared between all entities in a design?

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;

推荐答案

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

OK, having gone through the blog post I now understand why they're using shared variable instead of signals. Its because multiple processes are assigning to this variable, which is not possible in the case of a reg in Verilog or a signal in VHDL. In that case the synthesizer will produce an error complaining of multiple drivers for mem. But in order to use shared variable in this case, you'll have to declare it as protected. What you need to do is declare a protected data type, and then encapsulate your mem variable inside it, much like classes in object oriented languages. Here's an example of the protected data type:

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类型的sharede变量,并使用 GetVal SetVal 函数将值读/写到进程内部的内存中.

Then declare a sharede variable of type mem_envelope and use GetVal and SetVal functions to read/write values to the memory inside your processes.

这篇关于使用VHDL实例化FPGA中的RAM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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