仅对英特尔可见 — GUID: mwh1409959587208
Ixiasoft
仅对英特尔可见 — GUID: mwh1409959587208
Ixiasoft
1.4.1.8. 真双端口同步RAM
Intel FPGA同步存储器模块有两个独立的地址端口,允许同时在两个唯一地址上进行操作。如果读取操作和写入操作共享相同的地址,那么它们可以共享相同的端口。
Intel® Quartus® Prime软件可在Verilog HDL和VHDL中推断真双端口RAM,具有以下特征:
- 在同一时钟周期内独立读取或写入操作的任意组合。
- 最多两个唯一的端口地址。
- 在一个时钟周期中,具有一个或两个唯一地址,它们可以执行:
- 两次读取和一次写入
- 两次写入和一次读取
- 两次写入和两次读取
在同步RAM模块体系结构中,两个端口之间没有优先级。因此,如果同时在两个端口上写入相同的位置,那么结果在器件体系结构中是不确定的。如果要在专用硬件存储器模块中实现设计,那么必须确保HDL代码不暗含写入存储器模块的优先级。例如,如果两个端口都在同一处理模块中定义,那么代码将被综合和顺序仿真,以使两个端口之间具有优先级。如果代码确实暗含了优先级,那么该逻辑不能在器件RAM模块中实现,而是在普通逻辑单元中实现。您还必须考虑RAM模块的read-during-write行为,以确保能够将其直接映射到器件RAM体系结构。
当在同一端口上对同一地址进行读取和写入操作时,读取操作可能会表现如下:
- Read new data— Intel® Arria® 10 和 Intel® Stratix® 10 器件支持此行为。
- Read old data—不支持。
当在同一地址的不同端口上发生读取和写入操作(也称为混合端口)时,读取操作可能会表现如下:
- Read new data— Intel® Quartus® Prime Pro Edition synthesis通过在同步存储器模块周围创建旁路逻辑来支持此模式。
- Read old data— Intel® Arria® 10和 Intel® Cyclone® 10器件支持此行为。
- Read don’t care—同步存储器模块在简单双端口模式下支持此行为。
Verilog HDL单时钟代码样例直接映射到同步 Intel® Arria® 10存储器模块 。当在同一端口上对同一地址进行读写操作时,将读取正在写入存储器的新数据。当在同一地址的不同端口上进行读写操作时,将读取存储器中的旧数据。同时写入两个端口上的相同位置会导致不确定行为。
如果生成此设计的双时钟版本来描述相同的行为,那么目标器件中的推断存储器将呈现未定义的混合端口read-during-write行为,因为这取决于时钟之间的关系。
具有单时钟的Verilog HDL真双端口RAM
/ Quartus Prime Verilog Template
// True Dual Port RAM with single clock
//
// Read-during-write behavior is undefined for mixed ports
// and "new data" on the same port
module true_dual_port_ram_single_clock
#(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=6)
(
input [(DATA_WIDTH-1):0] data_a, data_b,
input [(ADDR_WIDTH-1):0] addr_a, addr_b,
input we_a, we_b, clk,
output reg [(DATA_WIDTH-1):0] q_a, q_b
);
// Declare the RAM variable
reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];
// Port A
always @ (posedge clk)
begin
if (we_a)
begin
ram[addr_a] = data_a;
end
q_a <= ram[addr_a];
end
// Port B
always @ (posedge clk)
begin
if (we_b)
begin
ram[addr_b] = data_b;
end
q_b <= ram[addr_b];
end
endmodule
VHDL读语句示例
-- Port A
process(clk)
begin
if(rising_edge(clk)) then
if(we_a = '1') then
ram(addr_a) := data_a;
end if;
q_a <= ram(addr_a);
end if;
end process;
-- Port B
process(clk)
begin
if(rising_edge(clk)) then
if(we_b = '1') then
ram(addr_b) := data_b;
end if;
q_b <= ram(addr_b);
end if;
end process;
VHDL单时钟代码样例直接映射到Intel FPGA同步存储器。当在同一端口上对同一地址进行读写操作时,将读取写入存储器的新数据。当在同一地址的不同端口上进行读取和写入操作时,此行为将对 Intel® Arria® 10和 Intel® Cyclone® 10器件产生旧数据 , 对于 Intel® Stratix® 10器件是未定义的 。对两个端口上相同位置的同时写操作将导致不确定的行为。
如果生成此设计的双时钟版本来描述相同的行为,那么目标器件中的存储器将呈现未定义的混合端口read-during-write行为,因为这取决于时钟之间的关系。
具有单时钟的VHDL真双端口RAM
-- Quartus Prime VHDL Template
-- True Dual-Port RAM with single clock
--
-- Read-during-write behavior is undefined for mixed ports
-- and "new data" on the same port
library ieee;
use ieee.std_logic_1164.all;
entity true_dual_port_ram_single_clock is
generic
(
DATA_WIDTH : natural := 8;
ADDR_WIDTH : natural := 6
);
port
(
clk : in std_logic;
addr_a : in natural range 0 to 2**ADDR_WIDTH - 1;
addr_b : in natural range 0 to 2**ADDR_WIDTH - 1;
data_a : in std_logic_vector((DATA_WIDTH-1) downto 0);
data_b : in std_logic_vector((DATA_WIDTH-1) downto 0);
we_a : in std_logic := '1';
we_b : in std_logic := '1';
q_a : out std_logic_vector((DATA_WIDTH -1) downto 0);
q_b : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end true_dual_port_ram_single_clock;
architecture rtl of true_dual_port_ram_single_clock is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;
-- Declare the RAM
shared variable ram : memory_t;
begin
-- Port A
process(clk)
begin
if(rising_edge(clk)) then
if(we_a = '1') then
ram(addr_a) := data_a;
end if;
q_a <= ram(addr_a);
end if;
end process;
-- Port B
process(clk)
begin
if(rising_edge(clk)) then
if(we_b = '1') then
ram(addr_b) := data_b;
end if;
q_b <= ram(addr_b);
end if;
end process;
end rtl;