使用3D阵列的RAM
以下示例显示了使用3D阵列对RAM的推断。
3D RAM Inference Single Port (Verilog)
filename: rams_sp_3d.sv
// 3-D Ram Inference Example (Single port)
// File:rams_sp_3d.sv
module rams_sp_3d #(
parameter NUM_RAMS = 2,
A_WID = 10,
D_WID = 32
)
(
input clk,
input [NUM_RAMS-1:0] we,
input [NUM_RAMS-1:0] ena,
input [A_WID-1:0] addr [NUM_RAMS-1:0],
input [D_WID-1:0] din [NUM_RAMS-1:0],
output reg [D_WID-1:0] dout [NUM_RAMS-1:0]
);
reg [D_WID-1:0] mem [NUM_RAMS-1:0][2**A_WID-1:0];
genvar i;
generate
for(i=0;i<NUM_RAMS;i=i+1)
begin:u
always @ (posedge clk)
begin
if (ena[i]) begin
if(we[i])
begin
mem[i][addr[i]] <= din[i];
end
dout[i] <= mem[i][addr[i]];
end
end
end
endgenerate
endmodule
3D RAM Inference Single Port (VHDL)
Filename: ram_sp_3d.vhd
-- 3-D Ram Inference Example (Single port)
-- Compile this file in VHDL2008 mode
-- File:rams_sp_3d.vhd
library ieee;
use ieee.std_logic_1164.all;
package mypack is
type myarray_t is array(integer range<>) of std_logic_vector;
type mem_t is array(integer range<>) of myarray_t;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.mypack.all;
entity rams_sp_3d is generic (
NUM_RAMS : integer := 2;
A_WID : integer := 10;
D_WID : integer := 32
);
port (
clk : in std_logic;
we : in std_logic_vector(NUM_RAMS-1 downto 0);
ena : in std_logic_vector(NUM_RAMS-1 downto 0);
addr : in myarray_t(NUM_RAMS-1 downto 0)(A_WID-1 downto 0);
din : in myarray_t(NUM_RAMS-1 downto 0)(D_WID-1 downto 0);
dout : out myarray_t(NUM_RAMS-1 downto 0)(D_WID-1 downto 0)
);
end rams_sp_3d;
architecture arch of rams_sp_3d is
signal mem : mem_t(NUM_RAMS-1 downto 0)(2**A_WID-1 downto 0)(D_WID-1 downto
0);
begin
process(clk)
begin
if(clk'event and clk='1') then
for i in 0 to NUM_RAMS-1 loop
if(ena(i) = '1') then
if(we(i) = '1') then
mem(i)(to_integer(unsigned(addr(i)))) <= din(i);
end if;
dout(i) <= mem(i)(to_integer(unsigned(addr(i))));
end if;
end loop;
end if;
end process;
end arch;
3D RAM Inference Simple Dual Port (Verilog)
Filename: rams_sdp_3d.sv
// 3-D Ram Inference Example (Simple Dual port)
// File:rams_sdp_3d.sv
module rams_sdp_3d #(
parameter NUM_RAMS = 2,
A_WID = 10,
D_WID = 32
)
(
input clka,
input clkb,
input [NUM_RAMS-1:0] wea,
input [NUM_RAMS-1:0] ena,
input [NUM_RAMS-1:0] enb,
input [A_WID-1:0] addra [NUM_RAMS-1:0],
input [A_WID-1:0] addrb [NUM_RAMS-1:0],
input [D_WID-1:0] dina [NUM_RAMS-1:0],
output reg [D_WID-1:0] doutb [NUM_RAMS-1:0]
);
reg [D_WID-1:0] mem [NUM_RAMS-1:0][2**A_WID-1:0];
// PORT_A
genvar i;
generate
for(i=0;i<NUM_RAMS;i=i+1)
begin:port_a_ops
always @ (posedge clka)
begin
if (ena[i]) begin
if(wea[i])
begin
mem[i][addra[i]] <= dina[i];
end
end
end
end
endgenerate
//PORT_B
generate
for(i=0;i<NUM_RAMS;i=i+1)
begin:port_b_ops
always @ (posedge clkb)
begin
if (enb[i])
doutb[i] <= mem[i][addrb[i]];
end
end
endgenerate
endmodule
3D RAM Inference - Simple Dual Port (VHDL)
filename: rams_sdp_3d.vhd
-- 3-D Ram Inference Example ( Simple Dual port)
-- Compile this file in VHDL2008 mode
-- File:rams_sdp_3d.vhd
library ieee;
use ieee.std_logic_1164.all;
package mypack is
type myarray_t is array(integer range<>) of std_logic_vector;
type mem_t is array(integer range<>) of myarray_t;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.mypack.all;
entity rams_sdp_3d is generic (
NUM_RAMS : integer := 2;
A_WID : integer := 10;
D_WID : integer := 32
);
port (
clka : in std_logic;
clkb : in std_logic;
wea : in std_logic_vector(NUM_RAMS-1 downto 0);
ena : in std_logic_vector(NUM_RAMS-1 downto 0);
enb : in std_logic_vector(NUM_RAMS-1 downto 0);
addra : in myarray_t(NUM_RAMS-1 downto 0)(A_WID-1 downto 0);
addrb : in myarray_t(NUM_RAMS-1 downto 0)(A_WID-1 downto 0);
dina : in myarray_t(NUM_RAMS-1 downto 0)(D_WID-1 downto 0);
doutb : out myarray_t(NUM_RAMS-1 downto 0)(D_WID-1 downto 0)
);
end rams_sdp_3d;
architecture arch of rams_sdp_3d is
signal mem : mem_t(NUM_RAMS-1 downto 0)(2**A_WID-1 downto 0)(D_WID-1 downto
0);
begin
process(clka)
begin
if(clka'event and clka='1') then
for i in 0 to NUM_RAMS-1 loop
if(ena(i) = '1') then
if(wea(i) = '1') then
mem(i)(to_integer(unsigned(addra(i)))) <= dina(i);
end if;
end if;
end loop;
end if;
end process;
process(clkb)
begin
if(clkb'event and clkb='1') then
for i in 0 to NUM_RAMS-1 loop
if(enb(i) = '1') then
doutb(i) <= mem(i)(to_integer(unsigned(addrb(i))));
end if;
end loop;
end if;
end process;
end arch;
3D RAM Inference True Dual Port (Verilog)
Filename: rams_tdp_3d.sv
// 3-D Ram Inference Example (True Dual port)
// File:rams_tdp_3d.sv
module rams_tdp_3d #(
parameter NUM_RAMS = 2,
A_WID = 10,
D_WID = 32
)
(
input clka,
input clkb,
input [NUM_RAMS-1:0] wea,
input [NUM_RAMS-1:0] web,
input [NUM_RAMS-1:0] ena,
input [NUM_RAMS-1:0] enb,
input [A_WID-1:0] addra [NUM_RAMS-1:0],
input [A_WID-1:0] addrb [NUM_RAMS-1:0],
input [D_WID-1:0] dina [NUM_RAMS-1:0],
input [D_WID-1:0] dinb [NUM_RAMS-1:0],
output reg [D_WID-1:0] douta [NUM_RAMS-1:0],
output reg [D_WID-1:0] doutb [NUM_RAMS-1:0]
);
reg [D_WID-1:0] mem [NUM_RAMS-1:0][2**A_WID-1:0];
// PORT_A
genvar i;
generate
for(i=0;i<NUM_RAMS;i=i+1)
begin:port_a_ops
always @ (posedge clka)
begin
if (ena[i]) begin
if(wea[i])
begin
mem[i][addra[i]] <= dina[i];
end
douta[i] <= mem[i][addra[i]];
end
end
end
endgenerate
//PORT_B
generate
for(i=0;i<NUM_RAMS;i=i+1)
begin:port_b_ops
always @ (posedge clkb)
begin
if (enb[i]) begin
if(web[i])
begin
mem[i][addrb[i]] <= dinb[i];
end
doutb[i] <= mem[i][addrb[i]];
end
end
end
endgenerate
endmodule