Intel® Quartus® Prime Pro Edition用户指南: 设计建议

ID 683082
日期 9/28/2020
Public

本文档可提供新的版本。客户应 单击此处 前往查看最新版本。

文档目录

1.4.1.10. 带Byte-Enable信号的RAM

本节中的RAM代码示例显示SystemVerilog和VHDL代码,这些代码通过将单个字节写入存储字或字节使能信号的控件来推断RAM。

综合通过创建包含两个索引的写表达式并写入RAM “word”的一部分来对字节使能信号进行建模。通过这些实现,您还可以通过使能相应的字节使能(byte enable)一次写入多个字节。

Verilog-1995不支持混合宽度RAM,因为此标准缺少用于对不同的读取宽度和/或写入宽度进行建模的多维数组。Verilog-2001不支持混合宽度RAM,因为这种类型的逻辑需要多个封装尺寸。不同的综合工具对这些存储器的支持可能有所不同。本节描述 Intel® Quartus® Prime Pro Edition综合的推断规则。

请参考 Intel® Quartus® Prime HDL模板来了解用于不同地址宽度的参数化示例,以及带有两个读端口和两个写端口的真双端口RAM示例。

带字节使能的SystemVerilog简单双端口同步RAM

module byte_enabled_simple_dual_port_ram  
( 
    input we, clk,
    input [ADDRESS_WIDTH-1:0] waddr, raddr,// address width = 6 
    input [NUM_BYTES-1:0] be, // 4 bytes per word
    input [(BYTE_WIDTH * NUM_BYTES -1):0] wdata, // byte width = 8, 4 bytes per word
    output reg [(BYTE_WIDTH * NUM_BYTES -1):0] q // byte width = 8, 4 bytes per word
);

   parameter ADDRESS_WIDTH = 6;
   parameter DEPTH = 2**ADDRESS_WIDTH;
   parameter BYTE_WIDTH = 8;
   parameter NUM_BYTES = 4;

   // use a multi-dimensional packed array
   //to model individual bytes within the word
   logic [NUM_BYTES-1:0][BYTE_WIDTH-1:0] ram[0:DEPTH-1]; 
     // # words = 1 << address width

	// port A
   always@(posedge clk)
   begin
	   if(we) begin
          for (int i = 0; i < NUM_BYTES; i = i + 1) begin
            if(be[i]) ram[waddr][i] <= wdata[i*BYTE_WIDTH +: BYTE_WIDTH];
          end
      end
      q <= ram[raddr];
   end
endmodule

带字节使能的VHDL简单双端口同步RAM

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

entity byte_enabled_simple_dual_port_ram is
generic (DEPTH      : integer := 64;
         NUM_BYTES  : integer :=  4;
         BYTE_WIDTH : integer :=  8
);
port (
    we, clk : in  std_logic;
    waddr, raddr : in  integer range 0 to DEPTH -1 ;     -- address width = 6
    be   : in  std_logic_vector (NUM_BYTES-1 downto 0);   -- 4 bytes per word
    wdata: in  std_logic_vector((NUM_BYTES * BYTE_WIDTH -1) downto 0);   -- width = 32
    q    : out std_logic_vector((NUM_BYTES * BYTE_WIDTH -1) downto 0) ); -- width = 32
end byte_enabled_simple_dual_port_ram;

architecture rtl of byte_enabled_simple_dual_port_ram is

    --  build up 2D array to hold the memory
    type word_t is array (0 to NUM_BYTES-1) of std_logic_vector(BYTE_WIDTH-1 downto 0);
    type ram_t is array (0 to DEPTH-1) of word_t;

    signal ram : ram_t;
    signal q_local : word_t;

    begin  -- Re-organize the read data from the RAM to match the output
        unpack: for i in 0 to NUM_BYTES-1 generate    
            q(BYTE_WIDTH*(i+1) - 1 downto BYTE_WIDTH*i) <= q_local(i);
    end generate unpack;
        
    -- port A
    process(clk)
    begin
        if(rising_edge(clk)) then 
            if(we = '1') then
                for I in (NUM_BYTES-1) downto 0 loop
                    if(be(I) = '1') then
                        ram(waddr)(I) <= wdata(((I+1)*BYTE_WIDTH-1) downto I*BYTE_WIDTH);
                    end if;
                 end loop;
            end if;
            q_local <= ram(raddr);
        end if;
    end process;  
end rtl;