Visible to Intel only — GUID: mwh1409959585519
Ixiasoft
Visible to Intel only — GUID: mwh1409959585519
Ixiasoft
1.4.1.6. Single-Clock Synchronous RAM with New Data Read-During-Write Behavior
To implement this behavior in the target device, synthesis tools add bypass logic around the RAM block. This bypass logic increases the area utilization of the design, and decreases the performance if the RAM block is part of the design’s critical path. If the device memory supports new data read-during-write behavior when in single-port mode (same clock, same read address, and same write address), the Verilog memory block doesn't require any bypass logic. Refer to the appropriate device handbook for specifications on your target device.
The following examples use a blocking assignment for the write so that the data is assigned intermediately.
Verilog HDL Single-Clock, Simple Dual-Port Synchronous RAM with New Data Read-During-Write Behavior
module single_clock_wr_ram(
output reg [7:0] q,
input [7:0] d,
input [6:0] write_address, read_address,
input we, clk
);
reg [7:0] mem [127:0];
always @ (posedge clk) begin
if (we)
mem[write_address] = d;
q = mem[read_address]; // q does get d in this clock
// cycle if we is high
end
endmodule
VHDL Single-Clock, Simple Dual-Port Synchronous RAM with New Data Read-During-Write Behavior:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY single_clock_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 single_clock_ram;
ARCHITECTURE rtl OF single_clock_ram IS
TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
PROCESS (clock)
VARIABLE ram_block: MEM;
BEGIN
IF (rising_edge(clock)) THEN
IF (we = '1') THEN
ram_block(write_address) := data;
END IF;
q <= ram_block(read_address);
-- VHDL semantics imply that q doesn't get data
-- in this clock cycle
END IF;
END PROCESS;
END rtl;
It is possible to create a single-clock RAM by using an assign statement to read the address of mem and create the output q. By itself, the RTL describes new data read-during-write behavior. However, if the RAM output feeds a register in another hierarchy, a read-during-write results in the old data. Synthesis tools may not infer a RAM block if the tool cannot determine which behavior is described, such as when the memory feeds a hard hierarchical partition boundary. Avoid this type of RTL.
Avoid Verilog Coding Style with Vague read-during-write Behavior
reg [7:0] mem [127:0];
reg [6:0] read_address_reg;
always @ (posedge clk) begin
if (we)
mem[write_address] <= d;
read_address_reg <= read_address;
end
assign q = mem[read_address_reg];
Avoid VHDL Coding Style with Vague read-during-write Behavior
The following example uses a concurrent signal assignment to read from the RAM, and presents a similar behavior.
ARCHITECTURE rtl OF single_clock_rw_ram IS
TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL ram_block: MEM;
SIGNAL read_address_reg: INTEGER RANGE 0 to 31;
BEGIN
PROCESS (clock)
BEGIN
IF (rising_edge(clock)) 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;