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

View File

@ -5,9 +5,6 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
entity true_dual_port_ram is
generic (
ADDR_WIDTH : natural := 8;
@ -31,49 +28,49 @@ end entity;
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
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 => "OLD_DATA",
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
);
ram_A_prc : process(all)
begin
if rising_edge(clk) then
-- Mixed Port Read-During-Write not supported
assert (not (addr_a = addr_b and ((ren_a = '1' and wen_b = '1') or (wen_b = '1' and ren_a = '1')))) severity FAILURE;
-- Port A
rd_data_a <= (others => '0');
if (wen_a = '1') then
mem(to_integer(unsigned(addr_a))) <= wr_data_a;
end if;
if (ren_a = '1') then
-- Same Port Read-During-Write returns New Data
if (wen_a = '1') then
rd_data_a <= wr_data_a;
else
rd_data_a <= mem(to_integer(unsigned(addr_a)));
end if;
end if;
-- Port B
rd_data_b <= (others => '0');
if (wen_b = '1') then
mem(to_integer(unsigned(addr_b))) <= wr_data_b;
end if;
if (ren_b = '1') then
-- Same Port Read-During-Write returns New Data
if (wen_b = '1') then
rd_data_b <= wr_data_b;
else
rd_data_b <= mem(to_integer(unsigned(addr_b)));
end if;
end if;
end if;
end process;
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;