Quartus® Prime Standard Edition User Guide: Design Compilation

ID 683283
Date 10/22/2021
Public
Document Table of Contents

3.5.8. Disabling Add Pass-Through Logic to Inferred RAMs no_rw_check Attribute

Use the no_rw_check value for the ramstyle attribute, or disable the add_pass_through_logic_to_inferred_rams option logic option assignment to indicate that your design does not depend on the behavior of the inferred RAM, when there are reads and writes to the same address in the same clock cycle. If you specify the attribute or disbale the logic option, the Quartus® Prime software chooses a read-during-write behavior instead of the read-during-write behavior of your HDL source code.

You disable or edit the attributes of this option by modifying the add_pass_through_logic_to_inferred_rams option in the Quartus® Prime Settings File (.qsf). There is no corresponding GUI setting for this option.

Sometimes, you must map an inferred RAM into regular logic cells because the inferred RAM has a read-during-write behavior that the TriMatrix memory blocks in your target device do not support. In other cases, the Quartus® Prime software must insert extra logic to mimic read-during-write behavior of the HDL source to increase the area of your design and potentially reduce its performance. In some of these cases, you can use the attribute to specify that the software can implement the RAM directly in a TriMatrix memory block without using logic. You can also use the attribute to prevent a warning message for dual-clock RAMs in the case that the inferred behavior in the device does not exactly match the read-during-write conditions described in the HDL code.

These examples use two addresses and normally require extra logic after the RAM to ensure that the read-during-write conditions in the device match the HDL code. If your design does not require a defined read-during-write condition, the extra logic is not necessary. With the no_rw_check attribute, Quartus® Prime Integrated Synthesis does not generate the extra logic.

Table 41.   Inferred RAM Using no_rw_check Attribute
HDL Code
Verilog HDL
module ram_infer (q, wa, ra, d, we, clk);
	output [7:0] q;
	input [7:0] d;
	input [6:0] wa;
	input [6:0] ra;
	input we, clk;
	reg [6:0] read_add;
	(* ramstyle = "no_rw_check" *) reg [7:0] mem [127:0];
	always @ (posedge clk) begin
		if (we)
			mem[wa] <= d;
		read_add <= ra;
	end
	assign q = mem[read_add];
endmodule
 VHDL
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY ram IS
	PORT (
		clock: IN STD_LOGIC;
		data: IN STD_LOGIC_VECTOR (2 DOWNTO 0);
		write_address: IN INTEGER RANGE 0 to 31;
		read_address: IN INTEGER RANGE 0 to 31;
		we: IN STD_LOGIC;
		q: OUT STD_LOGIC_VECTOR (2 DOWNTO 0)	);
END ram;
ARCHITECTURE rtl OF ram IS
	TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL ram_block: MEM;
	ATTRIBUTE ramstyle : string;
	ATTRIBUTE ramstyle of ram_block : signal is "no_rw_check";
	SIGNAL read_address_reg: INTEGER RANGE 0 to 31;
BEGIN
	PROCESS (clock)
	BEGIN
		IF (clock'event AND clock = '1') THEN
			IF (we = '1') THEN
				ram_block(write_address) <= data;
			END IF;
			read_address_reg <= read_address;
		END IF;
	END PROCESS;
	q <= ram_block(read_address_reg);
END rtl;

You can use a ramstyle attribute with the MLAB value, so that the Quartus® Prime software can infer a small RAM block and place it in an MLAB.

Note: You can use this attribute in cases in which some asynchronous RAM blocks might be coded with read-during-write behavior that does not match the Stratix IV and Stratix V architectures. Thus, the device behavior would not exactly match the behavior that the code describes. If the difference in behavior is acceptable in your design, use the ramstyle attribute with the no_rw_check value to specify that the software should not check the read-during-write behavior when inferring the RAM. When you set this attribute, Quartus® Prime Integrated Synthesis allows the behavior of the output to differ when the asynchronous read occurs on an address that had a write on the most recent clock edge. That is, the functional HDL simulation results do not match the hardware behavior if you write to an address that is being read. To include these attributes, set the value of the ramstyle attribute to MLAB, no_rw_check.

These examples show the method of setting two values to the ramstyle attribute with a small asynchronous RAM block, with the ramstyle synthesis attribute set, so that the software can implement the memory in the MLAB memory block and so that the read-during-write behavior is not important. Without the attribute, this design requires 512 registers and 240 ALUTs. With the attribute, the design requires eight memory ALUTs and only 15 registers.

Table 42.   Inferred RAM Using no_rw_check and MLAB Attributes
HDL Code
Verilog HDL
module async_ram (
    input   [5:0] addr,
    input   [7:0] data_in,
    input         clk,
    input         write,
    output  [7:0] data_out );
   (* ramstyle = "MLAB, no_rw_check" *) reg [7:0] mem[0:63];
   assign  data_out = mem[addr];
   always @ (posedge clk)
   begin
      if (write)
         mem[addr] = data_in;
   end
endmodule
VHDL
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY ram IS
	PORT (
		clock: IN STD_LOGIC;
		data: IN STD_LOGIC_VECTOR (2 DOWNTO 0);
		write_address: IN INTEGER RANGE 0 to 31;
		read_address: IN INTEGER RANGE 0 to 31;
		we: IN STD_LOGIC;
		q: OUT STD_LOGIC_VECTOR (2 DOWNTO 0));
END ram;
ARCHITECTURE rtl OF ram IS
	TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL ram_block: MEM;
	ATTRIBUTE ramstyle : string;
	ATTRIBUTE ramstyle of ram_block : signal is "MLAB , no_rw_check";
	SIGNAL read_address_reg: INTEGER RANGE 0 to 31;
BEGIN
	PROCESS (clock)
	BEGIN
		IF (clock'event AND clock = '1') THEN
			IF (we = '1') THEN
				ram_block(write_address) <= data;
			END IF;
			read_address_reg <= read_address;
		END IF;
	END PROCESS;
	q <= ram_block(read_address_reg);
END rtl;