aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/synth/issue1069/tdp_ram_single.vhdl
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/synth/issue1069/tdp_ram_single.vhdl')
-rw-r--r--testsuite/synth/issue1069/tdp_ram_single.vhdl84
1 files changed, 84 insertions, 0 deletions
diff --git a/testsuite/synth/issue1069/tdp_ram_single.vhdl b/testsuite/synth/issue1069/tdp_ram_single.vhdl
new file mode 100644
index 000000000..057dc9f50
--- /dev/null
+++ b/testsuite/synth/issue1069/tdp_ram_single.vhdl
@@ -0,0 +1,84 @@
+library ieee;
+use ieee.std_logic_1164.all,
+ ieee.numeric_std.all;
+
+entity tdp_ram is
+ generic (
+ ADDRWIDTH_A : positive := 12;
+ WIDTH_A : positive := 8;
+
+ ADDRWIDTH_B : positive := 10;
+ WIDTH_B : positive := 32;
+
+ COL_WIDTH : positive := 8
+ );
+ port (
+ clk_a : in std_logic;
+ read_a : in std_logic;
+ write_a : in std_logic;
+ byteen_a : in std_logic_vector(WIDTH_A/COL_WIDTH - 1 downto 0);
+ addr_a : in std_logic_vector(ADDRWIDTH_A - 1 downto 0);
+ data_read_a : out std_logic_vector(WIDTH_A - 1 downto 0);
+ data_write_a : in std_logic_vector(WIDTH_A - 1 downto 0)
+ );
+end tdp_ram;
+
+architecture behavioral of tdp_ram is
+ function log2(val : INTEGER) return natural is
+ variable res : natural;
+ begin
+ for i in 0 to 31 loop
+ if (val <= (2 ** i)) then
+ res := i;
+ exit;
+ end if;
+ end loop;
+
+ return res;
+ end function log2;
+
+ function eq_assert(x : integer; y : integer) return integer is
+ begin
+ assert x = y;
+ return x;
+ end function eq_assert;
+
+ constant COLS_A : positive := WIDTH_A / COL_WIDTH;
+ constant COLS_B : positive := WIDTH_B / COL_WIDTH;
+
+ constant TOTAL_COLS : positive := eq_assert(COLS_A * 2 ** ADDRWIDTH_A, COLS_B * 2 ** ADDRWIDTH_B);
+
+ constant EXTRA_ADDR_BITS_A : positive := log2(COLS_A);
+ constant EXTRA_ADDR_BITS_B : positive := log2(COLS_B);
+
+ type ram_t is array(0 to TOTAL_COLS - 1) of std_logic_vector(COL_WIDTH - 1 downto 0);
+ shared variable store : ram_t := (others => (others => '0'));
+
+ signal reg_a : std_logic_vector(WIDTH_A - 1 downto 0);
+begin
+ assert WIDTH_A mod COL_WIDTH = 0 and
+ WIDTH_B mod COL_WIDTH = 0 and
+ 2 ** (ADDRWIDTH_A + EXTRA_ADDR_BITS_A) = TOTAL_COLS and
+ 2 ** (ADDRWIDTH_B + EXTRA_ADDR_BITS_B) = TOTAL_COLS
+ report "Both WIDTH_A and WIDTH_B have to be a power-of-two multiple of COL_WIDTH"
+ severity failure;
+
+ process(clk_a)
+ begin
+ if rising_edge(clk_a) then
+ for i in 0 to COLS_A - 1 loop
+ if write_a = '1' and byteen_a(i) = '1' then
+ store(to_integer(unsigned(addr_a) & to_unsigned(i, EXTRA_ADDR_BITS_A))) :=
+ data_write_a((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH);
+ end if;
+
+ if read_a = '1' then
+ reg_a((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH) <=
+ store(to_integer(unsigned(addr_a) & to_unsigned(i, EXTRA_ADDR_BITS_A)));
+ end if;
+ end loop;
+
+ data_read_a <= reg_a;
+ end if;
+ end process;
+end behavioral;