用VHDL创建大型双端口RAM

时间:2014-12-02 04:39:09

标签: memory vhdl ram fpga

我正在尝试生成一个RAM来存储VHDL中基本绘图程序的可编辑位图。为此,一组I / O获取当前像素的地址并输出存储的像素颜色。另一组获取要写入的像素的地址和其数据输入的颜色。由于显示器的尺寸,这需要是1Megx12bit双端口RAM。然而,综合推断锁存器正好在2 ^ 13地址开始,这让我相信我的资源已经耗尽。我该怎么做才能让这个RAM工作?

这里是代码(请注意,输入工具未使用,最终会被删除):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity DUALRAM_Custom is port (
    ADDR1  : in  STD_LOGIC_VECTOR(19 downto 0);
    D_in2  : in  STD_LOGIC_VECTOR(11 downto 0);
    ADDR2  : in  STD_LOGIC_VECTOR(19 downto 0);
    WE2    : in  STD_LOGIC;
    tool   : in  STD_LOGIC_VECTOR(3 downto 0);
    CLR    : in  STD_LOGIC;
    CLK    : in  STD_LOGIC;
    D_out1 : out STD_LOGIC_VECTOR(11 downto 0)
);      
end DUALRAM_Custom;

architecture Behavioral of DUALRAM_Custom is
    type RAM_type is ARRAY(0 to 1048575) of STD_LOGIC_VECTOR(11 downto 0);
    signal RAM : RAM_type := (others => (others => '0'));
begin

    process(CLK) is
    begin
        if((CLK'event) AND (CLK = '1')) THEN
            D_out1 <= RAM(to_integer(unsigned(ADDR1)));

            if ((WE2 = '1') AND (CLR = '0')) THEN
                if (CLR = '1') THEN
                    RAM(to_integer(unsigned(ADDR2))) <= x"000";
                else
                    RAM(to_integer(unsigned(ADDR2))) <= D_in2;
                end if;
            end if;
        end if;
    end process;
end Behavioral;

1 个答案:

答案 0 :(得分:2)

您需要准确了解您的部件支持哪种类型的RAM。可能导致问题的一件事是RAM的初始化。某些技术不支持在RAM上重置。有些将在上电期间作为预加载。

signal RAM : RAM_type := (others => (others => '0'));

另请注意,您的CLR逻辑有点奇怪(如Bill Lynch所述)。请注意,芯片上RAM的功能部分可能没有任何形式的复位,因此这将是RAM前端的额外逻辑。将其与您的编码风格混合在一起可能会导致您的综合工具无法支持。我建议至少暂时删除CLR功能,让它在没有它的情况下工作并尝试重新添加它。

我还建议为RAM使用变量而不是信号,因为正在实现的RAM大小的信号可能会导致模拟运行比变量慢得多。

以下代码适用于真正的双端口RAM。我已经为Xilinx和Altera合成了这个。它具有比您需要的更多功能,因此请删除您不需要的部分并尝试一下。可能需要一些实验才能获得完全合成您想要的工具。

architecture RTL of DPRam_RIRO_RF_1024_var is
begin
  MemProc : process (ClkA, ClkB) 
    type MemType is array (0 to 1023) of std_logic_vector(7 downto 0) ;
    variable Mem : MemType ;
  begin
    if rising_edge(ClkA) then     
      DataOutA <= Mem(to_integer(unsigned(AddrA))) ; 
      if WriteA = '1' then 
        Mem(to_integer(unsigned(AddrA))) := DataInA ; 
      end if ;
    end if ;

    if rising_edge(ClkB) then     
      DataOutB <= Mem(to_integer(unsigned(AddrB))) ; 
      if WriteB = '1' then 
        Mem(to_integer(unsigned(AddrB))) := DataInB ; 
      end if ;
    end if ;

  end process ; 
end RTL ;

一旦你得到了一些有用的东西,一定要看看它使用了多少资源,因为我注意到我的一些工作RAM最终使用了我需要的2倍资源,直到我得到正确的编码。