-- 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 true_dual_port_ram is generic ( ADDR_WIDTH : natural := 8; DATA_WIDTH : natural := 12; MEMORY_DEPTH : natural := 256 ); port ( clk : in std_logic; addr_a : in std_logic_vector(ADDR_WIDTH-1 downto 0); addr_b : in std_logic_vector(ADDR_WIDTH-1 downto 0); wen_a : in std_logic; wen_b : in std_logic; ren_a : in std_logic; ren_b : in std_logic; wr_data_a : in std_logic_vector(DATA_WIDTH-1 downto 0); wr_data_b : in std_logic_vector(DATA_WIDTH-1 downto 0); rd_data_a : out std_logic_vector(DATA_WIDTH-1 downto 0); rd_data_b : out std_logic_vector(DATA_WIDTH-1 downto 0) ); 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 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;