Visible to Intel only — GUID: mwh1409959589276
Ixiasoft
Visible to Intel only — GUID: mwh1409959589276
Ixiasoft
1.4.1.10. RAM with Byte-Enable Signals
Synthesis models byte-enable signals by creating write expressions with two indexes, and writing part of a RAM "word." With these implementations, you can also write more than one byte at once by enabling the appropriate byte enables.
Verilog-1995 doesn't support mixed-width RAMs because the standard lacks a multi-dimensional array to model the different read width, write width, or both. Verilog-2001 doesn't support mixed-width RAMs because this type of logic requires multiple packed dimensions. Different synthesis tools may differ in their support for these memories. This section describes the inference rules for Quartus® Prime Pro Edition synthesis.
Refer to the Quartus® Prime HDL templates for parameterized examples that you can use for different address widths, and true dual port RAM examples with two read ports and two write ports.
SystemVerilog Simple Dual-Port Synchronous RAM with Byte Enable
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 Simple Dual-Port Synchronous RAM with Byte Enable
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;