aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/synth/issue1069
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-03-28 09:04:32 +0100
committerTristan Gingold <tgingold@free.fr>2020-03-28 09:04:32 +0100
commitbe59edef25d4f828579bce7221757c6a17412c58 (patch)
tree7bbe01140c8bfd92ab739f88b336606bc227033a /testsuite/synth/issue1069
parentceda8dddc57cd3e41f187d6589804b76090a6f04 (diff)
downloadghdl-be59edef25d4f828579bce7221757c6a17412c58.tar.gz
ghdl-be59edef25d4f828579bce7221757c6a17412c58.tar.bz2
ghdl-be59edef25d4f828579bce7221757c6a17412c58.zip
testsuite/synth: add testcase for #1069
Diffstat (limited to 'testsuite/synth/issue1069')
-rw-r--r--testsuite/synth/issue1069/ram3.vhdl58
-rw-r--r--testsuite/synth/issue1069/ram4.vhdl54
-rw-r--r--testsuite/synth/issue1069/ram41.vhdl52
-rw-r--r--testsuite/synth/issue1069/ram5.vhdl54
-rw-r--r--testsuite/synth/issue1069/tdp_ram.vhdl112
-rw-r--r--testsuite/synth/issue1069/tdp_ram2.vhdl109
-rw-r--r--testsuite/synth/issue1069/tdp_ram_single.vhdl84
-rw-r--r--testsuite/synth/issue1069/tdp_ram_single2.vhdl80
-rwxr-xr-xtestsuite/synth/issue1069/testsuite.sh8
9 files changed, 611 insertions, 0 deletions
diff --git a/testsuite/synth/issue1069/ram3.vhdl b/testsuite/synth/issue1069/ram3.vhdl
new file mode 100644
index 000000000..f63c11ae0
--- /dev/null
+++ b/testsuite/synth/issue1069/ram3.vhdl
@@ -0,0 +1,58 @@
+library ieee;
+use ieee.std_logic_1164.all,
+ ieee.numeric_std.all;
+
+entity tdp_ram is
+ generic (
+ ADDRWIDTH : positive := 12;
+ WIDTH : positive := 8
+ );
+ port (
+ clk_a : in std_logic;
+ read_a : in std_logic;
+ write_a : in std_logic;
+ addr_a : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_a : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_a : in std_logic_vector(WIDTH - 1 downto 0);
+
+ clk_b : in std_logic;
+ read_b : in std_logic;
+ write_b : in std_logic;
+ addr_b : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_b : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_b : in std_logic_vector(WIDTH - 1 downto 0)
+ );
+end tdp_ram;
+
+architecture behavioral of tdp_ram is
+ signal reg_a : std_logic_vector(WIDTH - 1 downto 0);
+ signal reg_b : std_logic_vector(WIDTH - 1 downto 0);
+begin
+ process(clk_a, clk_b)
+ type ram_t is array(0 to 2**ADDRWIDTH - 1) of std_logic_vector(WIDTH - 1 downto 0);
+ variable store : ram_t := (others => (others => '0'));
+
+ begin
+ if rising_edge(clk_a) then
+ if write_a = '1' then
+ store(to_integer(unsigned(addr_a))) := data_write_a;
+ end if;
+
+ if read_a = '1' then
+ reg_a <= store(to_integer(unsigned(addr_a)));
+ end if;
+ data_read_a <= reg_a;
+ end if;
+
+ if rising_edge(clk_b) then
+ if write_b = '1' then
+ store(to_integer(unsigned(addr_b))) := data_write_b;
+ end if;
+
+ if read_b = '1' then
+ reg_b <= store(to_integer(unsigned(addr_b)));
+ end if;
+ data_read_b <= reg_b;
+ end if;
+ end process;
+end behavioral;
diff --git a/testsuite/synth/issue1069/ram4.vhdl b/testsuite/synth/issue1069/ram4.vhdl
new file mode 100644
index 000000000..3321e59c1
--- /dev/null
+++ b/testsuite/synth/issue1069/ram4.vhdl
@@ -0,0 +1,54 @@
+library ieee;
+use ieee.std_logic_1164.all,
+ ieee.numeric_std.all;
+
+entity tdp_ram is
+ generic (
+ ADDRWIDTH : positive := 7;
+ WIDTH : positive := 8
+ );
+ port (
+ clk_a : in std_logic;
+ read_a : in std_logic;
+ write_a : in std_logic;
+ addr_a : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_a : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_a : in std_logic_vector(WIDTH - 1 downto 0);
+
+ clk_b : in std_logic;
+ read_b : in std_logic;
+ write_b : in std_logic;
+ addr_b : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_b : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_b : in std_logic_vector(WIDTH - 1 downto 0)
+ );
+end tdp_ram;
+
+architecture behavioral of tdp_ram is
+begin
+ process(clk_a, clk_b)
+ type ram_t is array(0 to 2**ADDRWIDTH - 1) of std_logic_vector(WIDTH - 1 downto 0);
+ variable store : ram_t := (others => (others => '0'));
+
+ begin
+ if rising_edge(clk_a) then
+ if read_a = '1' then
+ data_read_a <= store(to_integer(unsigned(addr_a)));
+ end if;
+
+ if write_a = '1' then
+ store(to_integer(unsigned(addr_a))) := data_write_a;
+ end if;
+ end if;
+
+ if rising_edge(clk_b) then
+ if read_b = '1' then
+ data_read_b <= store(to_integer(unsigned(addr_b)));
+ end if;
+
+ if write_b = '1' then
+ store(to_integer(unsigned(addr_b))) := data_write_b;
+ end if;
+ end if;
+ end process;
+end behavioral;
diff --git a/testsuite/synth/issue1069/ram41.vhdl b/testsuite/synth/issue1069/ram41.vhdl
new file mode 100644
index 000000000..7e5b2e296
--- /dev/null
+++ b/testsuite/synth/issue1069/ram41.vhdl
@@ -0,0 +1,52 @@
+library ieee;
+use ieee.std_logic_1164.all,
+ ieee.numeric_std.all;
+
+entity tdp_ram is
+ generic (
+ ADDRWIDTH : positive := 7;
+ WIDTH : positive := 8
+ );
+ port (
+ clk_a : in std_logic;
+ read_a : in std_logic;
+ write_a : in std_logic;
+ addr_a : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_a : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_a : in std_logic_vector(WIDTH - 1 downto 0);
+
+ clk_b : in std_logic;
+ read_b : in std_logic;
+ write_b : in std_logic;
+ addr_b : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_b : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_b : in std_logic_vector(WIDTH - 1 downto 0)
+ );
+end tdp_ram;
+
+architecture behavioral of tdp_ram is
+begin
+ process(clk_a, clk_b)
+ type ram_t is array(0 to 2**ADDRWIDTH - 1) of std_logic_vector(WIDTH - 1 downto 0);
+ variable store : ram_t := (others => (others => '0'));
+
+ begin
+ if rising_edge(clk_a) then
+ if read_a = '1' then
+ data_read_a <= store(to_integer(unsigned(addr_a)));
+ end if;
+
+ if write_a = '1' then
+ store(to_integer(unsigned(addr_a))) := data_write_a;
+ end if;
+ elsif rising_edge(clk_b) then
+ if read_b = '1' then
+ data_read_b <= store(to_integer(unsigned(addr_b)));
+ end if;
+
+ if write_b = '1' then
+ store(to_integer(unsigned(addr_b))) := data_write_b;
+ end if;
+ end if;
+ end process;
+end behavioral;
diff --git a/testsuite/synth/issue1069/ram5.vhdl b/testsuite/synth/issue1069/ram5.vhdl
new file mode 100644
index 000000000..4fed38abf
--- /dev/null
+++ b/testsuite/synth/issue1069/ram5.vhdl
@@ -0,0 +1,54 @@
+library ieee;
+use ieee.std_logic_1164.all,
+ ieee.numeric_std.all;
+
+entity tdp_ram is
+ generic (
+ ADDRWIDTH : positive := 7;
+ WIDTH : positive := 8
+ );
+ port (
+ clk_a : in std_logic;
+ read_a : in std_logic;
+ write_a : in std_logic;
+ addr_a : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_a : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_a : in std_logic_vector(WIDTH - 1 downto 0);
+
+ clk_b : in std_logic;
+ read_b : in std_logic;
+ write_b : in std_logic;
+ addr_b : in std_logic_vector(ADDRWIDTH - 1 downto 0);
+ data_read_b : out std_logic_vector(WIDTH - 1 downto 0);
+ data_write_b : in std_logic_vector(WIDTH - 1 downto 0)
+ );
+end tdp_ram;
+
+architecture behavioral of tdp_ram is
+begin
+ process(clk_a, clk_b)
+ type ram_t is array(0 to 2**ADDRWIDTH - 1) of std_logic_vector(WIDTH - 1 downto 0);
+ variable store : ram_t := (others => (others => '0'));
+
+ begin
+ if rising_edge(clk_a) then
+ if write_a = '1' then
+ store(to_integer(unsigned(addr_a))) := data_write_a;
+ end if;
+
+ if read_a = '1' then
+ data_read_a <= store(to_integer(unsigned(addr_a)));
+ end if;
+ end if;
+
+ if rising_edge(clk_b) then
+ if write_b = '1' then
+ store(to_integer(unsigned(addr_b))) := data_write_b;
+ end if;
+
+ if read_b = '1' then
+ data_read_b <= store(to_integer(unsigned(addr_b)));
+ end if;
+ end if;
+ end process;
+end behavioral;
diff --git a/testsuite/synth/issue1069/tdp_ram.vhdl b/testsuite/synth/issue1069/tdp_ram.vhdl
new file mode 100644
index 000000000..8a1a07581
--- /dev/null
+++ b/testsuite/synth/issue1069/tdp_ram.vhdl
@@ -0,0 +1,112 @@
+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);
+
+ clk_b : in std_logic;
+ read_b : in std_logic;
+ write_b : in std_logic;
+ byteen_b : in std_logic_vector(WIDTH_B/COL_WIDTH - 1 downto 0);
+ addr_b : in std_logic_vector(ADDRWIDTH_B - 1 downto 0);
+ data_read_b : out std_logic_vector(WIDTH_B - 1 downto 0);
+ data_write_b : in std_logic_vector(WIDTH_B - 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);
+ signal reg_b : std_logic_vector(WIDTH_B - 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;
+
+ process(clk_b)
+ begin
+ if rising_edge(clk_b) then
+ for i in 0 to COLS_B - 1 loop
+ if write_b = '1' and byteen_b(i) = '1' then
+ store(to_integer(unsigned(addr_b) & to_unsigned(i, EXTRA_ADDR_BITS_B))) :=
+ data_write_b((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH);
+ end if;
+
+ if read_b = '1' then
+ reg_b((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH) <=
+ store(to_integer(unsigned(addr_b) & to_unsigned(i, EXTRA_ADDR_BITS_B)));
+ end if;
+ end loop;
+
+ data_read_b <= reg_b;
+ end if;
+ end process;
+end behavioral;
diff --git a/testsuite/synth/issue1069/tdp_ram2.vhdl b/testsuite/synth/issue1069/tdp_ram2.vhdl
new file mode 100644
index 000000000..763c966ff
--- /dev/null
+++ b/testsuite/synth/issue1069/tdp_ram2.vhdl
@@ -0,0 +1,109 @@
+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);
+
+ clk_b : in std_logic;
+ read_b : in std_logic;
+ write_b : in std_logic;
+ byteen_b : in std_logic_vector(WIDTH_B/COL_WIDTH - 1 downto 0);
+ addr_b : in std_logic_vector(ADDRWIDTH_B - 1 downto 0);
+ data_read_b : out std_logic_vector(WIDTH_B - 1 downto 0);
+ data_write_b : in std_logic_vector(WIDTH_B - 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);
+
+ signal reg_a : std_logic_vector(WIDTH_A - 1 downto 0);
+ signal reg_b : std_logic_vector(WIDTH_B - 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, clk_b)
+ type ram_t is array(0 to TOTAL_COLS - 1) of std_logic_vector(COL_WIDTH - 1 downto 0);
+ variable store : ram_t := (others => (others => '0'));
+
+ 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;
+
+ if rising_edge(clk_b) then
+ for i in 0 to COLS_B - 1 loop
+ if write_b = '1' and byteen_b(i) = '1' then
+ store(to_integer(unsigned(addr_b) & to_unsigned(i, EXTRA_ADDR_BITS_B))) :=
+ data_write_b((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH);
+ end if;
+
+ if read_b = '1' then
+ reg_b((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH) <=
+ store(to_integer(unsigned(addr_b) & to_unsigned(i, EXTRA_ADDR_BITS_B)));
+ end if;
+ end loop;
+
+ data_read_b <= reg_b;
+ end if;
+ end process;
+end behavioral;
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;
diff --git a/testsuite/synth/issue1069/tdp_ram_single2.vhdl b/testsuite/synth/issue1069/tdp_ram_single2.vhdl
new file mode 100644
index 000000000..ebae9a022
--- /dev/null
+++ b/testsuite/synth/issue1069/tdp_ram_single2.vhdl
@@ -0,0 +1,80 @@
+library ieee;
+use ieee.std_logic_1164.all,
+ ieee.numeric_std.all;
+
+entity tdp_ram is
+ generic (
+ ADDRWIDTH_A : positive := 10;
+ WIDTH_A : positive := 32;
+
+ 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 TOTAL_COLS : positive := COLS_A * 2 ** ADDRWIDTH_A;
+
+ constant EXTRA_ADDR_BITS_A : positive := log2(COLS_A);
+
+ 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
+ 2 ** (ADDRWIDTH_A + EXTRA_ADDR_BITS_A) = TOTAL_COLS
+ report "WIDTH_A 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;
diff --git a/testsuite/synth/issue1069/testsuite.sh b/testsuite/synth/issue1069/testsuite.sh
new file mode 100755
index 000000000..b591f0e9d
--- /dev/null
+++ b/testsuite/synth/issue1069/testsuite.sh
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+. ../../testenv.sh
+
+synth_analyze tdp_ram
+clean
+
+echo "Test successful"