Add and Redefine existing Dual Port RAM Implementations

Simple Dual Port (Read and Write Port), and True Dual Port RAM
implementations, together with their respective Altera implementations
were added.
The 'arch' Architectures should have the same behaviour as the Altera
Implementations (single_port_ram was modified to achieve that)
This commit is contained in:
Greek 2021-12-08 11:22:23 +01:00
parent 1871adac6d
commit 46ca2228b6
8 changed files with 222 additions and 51 deletions

View File

@ -0,0 +1,4 @@
configuration dual_port_ram_cfg of dual_port_ram is
for arch
end for;
end configuration;

51
src/dual_port_ram.vhd Normal file
View File

@ -0,0 +1,51 @@
-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dual_port_ram is
generic (
ADDR_WIDTH : natural := 8;
DATA_WIDTH : natural := 12;
MEMORY_DEPTH : natural := 256
);
port (
clk : in std_logic;
raddr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
waddr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
wen : in std_logic;
ren : in std_logic;
wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end entity;
architecture arch of dual_port_ram is
type RAM_TYPE is array (0 to MEMORY_DEPTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
signal mem : RAM_TYPE := (others => (others => '0'));
begin
ram_prc : process(all)
begin
if rising_edge(clk) then
rd_data <= (others => '0');
-- Mixed Port Read-During-Write not supported
assert(not (waddr = raddr and wen = '1' and ren = '1')) severity FAILURE;
if (wen = '1') then
mem(to_integer(unsigned(waddr))) <= wr_data;
end if;
if (ren = '1') then
rd_data <= mem(to_integer(unsigned(raddr)));
end if;
end if;
end process;
end architecture;

View File

@ -0,0 +1,48 @@
-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
architecture altera of dual_port_ram is
begin
altsyncram_component : altsyncram
generic map (
address_aclr_b => "NONE",
address_reg_b => "CLOCK0",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_b => "BYPASS",
intended_device_family => "Cyclone V",
lpm_type => "altsyncram",
numwords_a => MEMORY_DEPTH,
numwords_b => MEMORY_DEPTH,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => "UNREGISTERED",
power_up_uninitialized => "FALSE",
rdcontrol_reg_b => "CLOCK0",
read_during_write_mode_mixed_ports => "DONT_CARE",
widthad_a => ADDR_WIDTH,
widthad_b => ADDR_WIDTH,
width_a => DATA_WIDTH,
width_b => DATA_WIDTH,
width_byteena_a => 1
)
port map (
address_a => waddr,
address_b => raddr,
clock0 => clk,
data_a => wr_data,
rden_b => ren,
wren_a => wen,
q_b => rd_data
);
end architecture;

View File

@ -0,0 +1,7 @@
-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)
configuration dual_port_ram_cfg of dual_port_ram is
for altera
end for;
end configuration;

View File

@ -34,16 +34,15 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
rd_data <= (others => '0'); rd_data <= (others => '0');
-- Read-During-Write not supported
assert(wen = '1' nand ren = '1') severity FAILURE;
if (wen = '1') then if (wen = '1') then
mem(to_integer(unsigned(addr))) <= wr_data; mem(to_integer(unsigned(addr))) <= wr_data;
end if; end if;
if (ren = '1') then if (ren = '1') then
if (wen = '1') then rd_data <= mem(to_integer(unsigned(addr)));
rd_data <= wr_data;
else
rd_data <= mem(to_integer(unsigned(addr)));
end if;
end if; end if;
end if; end if;
end process; end process;

View File

@ -5,9 +5,6 @@ library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
entity true_dual_port_ram is entity true_dual_port_ram is
generic ( generic (
ADDR_WIDTH : natural := 8; ADDR_WIDTH : natural := 8;
@ -31,49 +28,49 @@ end entity;
architecture arch of true_dual_port_ram is architecture arch of true_dual_port_ram is
type RAM_TYPE is array (0 to MEMORY_DEPTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
signal mem : RAM_TYPE := (others => (others => '0'));
begin begin
altsyncram_component : altsyncram ram_A_prc : process(all)
generic map ( begin
address_reg_b => "CLOCK0", if rising_edge(clk) then
clock_enable_input_a => "BYPASS", -- Mixed Port Read-During-Write not supported
clock_enable_input_b => "BYPASS", assert (not (addr_a = addr_b and ((ren_a = '1' and wen_b = '1') or (wen_b = '1' and ren_a = '1')))) severity FAILURE;
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS", -- Port A
indata_reg_b => "CLOCK0", rd_data_a <= (others => '0');
intended_device_family => "Cyclone V",
lpm_type => "altsyncram", if (wen_a = '1') then
numwords_a => MEMORY_DEPTH, mem(to_integer(unsigned(addr_a))) <= wr_data_a;
numwords_b => MEMORY_DEPTH, end if;
operation_mode => "BIDIR_DUAL_PORT",
outdata_aclr_a => "NONE", if (ren_a = '1') then
outdata_aclr_b => "NONE", -- Same Port Read-During-Write returns New Data
outdata_reg_a => "UNREGISTERED", if (wen_a = '1') then
outdata_reg_b => "UNREGISTERED", rd_data_a <= wr_data_a;
power_up_uninitialized => "FALSE", else
read_during_write_mode_mixed_ports => "OLD_DATA", rd_data_a <= mem(to_integer(unsigned(addr_a)));
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", end if;
read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ", end if;
widthad_a => ADDR_WIDTH,
widthad_b => ADDR_WIDTH, -- Port B
width_a => DATA_WIDTH, rd_data_b <= (others => '0');
width_b => DATA_WIDTH,
width_byteena_a => 1, if (wen_b = '1') then
width_byteena_b => 1, mem(to_integer(unsigned(addr_b))) <= wr_data_b;
wrcontrol_wraddress_reg_b => "CLOCK0" end if;
)
port map ( if (ren_b = '1') then
address_a => addr_a, -- Same Port Read-During-Write returns New Data
address_b => addr_b, if (wen_b = '1') then
clock0 => clk, rd_data_b <= wr_data_b;
data_a => wr_data_a, else
data_b => wr_data_b, rd_data_b <= mem(to_integer(unsigned(addr_b)));
rden_a => ren_a, end if;
rden_b => ren_b, end if;
wren_a => wen_a, end if;
wren_b => wen_b, end process;
q_a => rd_data_a,
q_b => rd_data_b
);
end architecture; end architecture;

View File

@ -0,0 +1,58 @@
-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
architecture altera of true_dual_port_ram is
begin
altsyncram_component : altsyncram
generic map (
address_reg_b => "CLOCK0",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK0",
intended_device_family => "Cyclone V",
lpm_type => "altsyncram",
numwords_a => MEMORY_DEPTH,
numwords_b => MEMORY_DEPTH,
operation_mode => "BIDIR_DUAL_PORT",
outdata_aclr_a => "NONE",
outdata_aclr_b => "NONE",
outdata_reg_a => "UNREGISTERED",
outdata_reg_b => "UNREGISTERED",
power_up_uninitialized => "FALSE",
read_during_write_mode_mixed_ports => "DONT_CARE",
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ",
widthad_a => ADDR_WIDTH,
widthad_b => ADDR_WIDTH,
width_a => DATA_WIDTH,
width_b => DATA_WIDTH,
width_byteena_a => 1,
width_byteena_b => 1,
wrcontrol_wraddress_reg_b => "CLOCK0"
)
port map (
address_a => addr_a,
address_b => addr_b,
clock0 => clk,
data_a => wr_data_a,
data_b => wr_data_b,
rden_a => ren_a,
rden_b => ren_b,
wren_a => wen_a,
wren_b => wen_b,
q_a => rd_data_a,
q_b => rd_data_b
);
end architecture;

View File

@ -0,0 +1,7 @@
-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)
configuration true_dual_port_ram_cfg of true_dual_port_ram is
for altera
end for;
end configuration;