Visible to Intel only — GUID: mwh1409959590153
Ixiasoft
Visible to Intel only — GUID: mwh1409959590153
Ixiasoft
1.4.1.11. Specifying Initial Memory Contents at Power-Up
Your synthesis tool may offer various ways to specify the initial contents of an inferred memory. There are slight power-up and initialization differences between dedicated RAM blocks and the MLAB memory, due to the continuous read of the MLAB.
Intel FPGA dedicated RAM block outputs always power-up to zero, and are set to the initial value on the first read. For example, if address 0 is pre-initialized to FF, the RAM block powers up with the output at 0. A subsequent read after power-up from address 0 outputs the pre-initialized value of FF. Therefore, if a RAM powers up and an enable (read enable or clock enable) is held low, the power-up output of 0 maintains until the first valid read cycle. The synthesis tool implements MLAB using registers that power-up to 0, but initialize to their initial value immediately at power-up or reset. Therefore, the initial value is seen, regardless of the enable status. The Quartus® Prime software maps inferred memory to MLABs when the HDL code specifies an appropriate ramstyle attribute.
In Verilog HDL, you can use an initial block to initialize the contents of an inferred memory. Quartus® Prime Pro Edition synthesis automatically converts the initial block into a Memory Initialization File (.mif) for the inferred RAM.
Verilog HDL RAM with Initialized Contents
module ram_with_init( output reg [7:0] q, input [7:0] d, input [4:0] write_address, read_address, input we, clk ); reg [7:0] mem [0:31]; integer i; initial begin for (i = 0; i < 32; i = i + 1) mem[i] = i[7:0]; end always @ (posedge clk) begin if (we) mem[write_address] <= d; q <= mem[read_address]; end endmodule
Quartus® Prime Pro Edition synthesis and other synthesis tools also support the $readmemb and $readmemh attributes. These attributes allow RAM initialization and ROM initialization work identically in synthesis and simulation.
Verilog HDL RAM Initialized with the readmemb Command
reg [7:0] ram[0:15]; initial begin $readmemb("ram.txt", ram); end
In VHDL, you can initialize the contents of an inferred memory by specifying a default value for the corresponding signal. Quartus® Prime Pro Edition synthesis automatically converts the default value into a .mif file for the inferred RAM.
VHDL RAM with Initialized Contents
LIBRARY ieee; USE ieee.std_logic_1164.all; use ieee.numeric_std.all; ENTITY ram_with_init IS PORT( clock: IN STD_LOGIC; data: IN UNSIGNED (7 DOWNTO 0); write_address: IN integer RANGE 0 to 31; read_address: IN integer RANGE 0 to 31; we: IN std_logic; q: OUT UNSIGNED (7 DOWNTO 0)); END; ARCHITECTURE rtl OF ram_with_init IS TYPE MEM IS ARRAY(31 DOWNTO 0) OF unsigned(7 DOWNTO 0); FUNCTION initialize_ram return MEM is variable result : MEM; BEGIN FOR i IN 31 DOWNTO 0 LOOP result(i) := to_unsigned(natural(i), natural'(8)); END LOOP; RETURN result; END initialize_ram; SIGNAL ram_block : MEM := initialize_ram; BEGIN PROCESS (clock) BEGIN IF (rising_edge(clock)) THEN IF (we = '1') THEN ram_block(write_address) <= data; END IF; q <= ram_block(read_address); END IF; END PROCESS; END rtl;
Verilog HDL Single-Clock, Simple Dual-Port RAM with Synchronous Reset
// Simple Dual-Port Block with Single Clock module simple_dual_port_ram_single_clock #( parameter DATA_WIDTH = 8, parameter ADDR_WIDTH = 6 ) ( input clk, clr, we, input [ADDR_WIDTH-1:0] waddr, input [ADDR_WIDTH-1:0] raddr, input [DATA_WIDTH-1:0] data_in, output reg [DATA_WIDTH-1:0] data_out ); (*ramstyle = "M20K"*) reg [DATA_WIDTH-1:0] memory[2**ADDR_WIDTH-1:0]; always @(posedge clk) begin if (clr) begin data_out <= 0; end else begin data_out <= memory[raddr]; end end always @(posedge clk) begin if (we) begin memory[waddr] <= data_in; end end endmodule
RAM inference with synchronous reset is supported for single-port, simple-dual port, and true dual port RAM.
Verilog HDL Single-Clock, Simple Dual-Port RAM with Asynchronous Reset
// Simple Dual-Port Block with Single Clock module simple_dual_port_ram_single_clock_aclr #( parameter DATA_WIDTH = 8, parameter ADDR_WIDTH = 6 ) ( input clk, clr, we, input [ADDR_WIDTH-1:0] waddr, input [ADDR_WIDTH-1:0] raddr, input [DATA_WIDTH-1:0] data_in, output reg [DATA_WIDTH-1:0] data_out ); (*ramstyle = "M20K"*) reg [DATA_WIDTH-1:0] memory[2**ADDR_WIDTH-1:0]; always @(posedge clk or posedge clr) begin if (clr) begin data_out <= 0; end else begin data_out <= memory[raddr]; end end always @(posedge clk) begin if (we) begin memory[waddr] <= data_in; end end endmodule
RAM inference with asynchronous reset is supported for single-port and simple-dual port RAM.