From 93ec0c8b1417c555780f28eb856457aca2ebe83b Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 4 Apr 2022 06:32:45 +0200 Subject: testsuite/synth: add test for #2023 --- testsuite/synth/issue2023/abs_square.vhd | 99 +++++++++++++ testsuite/synth/issue2023/async_dpram.vhd | 85 +++++++++++ testsuite/synth/issue2023/delay_bit.vhd | 33 +++++ testsuite/synth/issue2023/delay_vector.vhd | 36 +++++ testsuite/synth/issue2023/test_comp.vhd | 230 +++++++++++++++++++++++++++++ testsuite/synth/issue2023/testsuite.sh | 12 ++ 6 files changed, 495 insertions(+) create mode 100644 testsuite/synth/issue2023/abs_square.vhd create mode 100644 testsuite/synth/issue2023/async_dpram.vhd create mode 100644 testsuite/synth/issue2023/delay_bit.vhd create mode 100644 testsuite/synth/issue2023/delay_vector.vhd create mode 100644 testsuite/synth/issue2023/test_comp.vhd create mode 100755 testsuite/synth/issue2023/testsuite.sh (limited to 'testsuite') diff --git a/testsuite/synth/issue2023/abs_square.vhd b/testsuite/synth/issue2023/abs_square.vhd new file mode 100644 index 000000000..85647401f --- /dev/null +++ b/testsuite/synth/issue2023/abs_square.vhd @@ -0,0 +1,99 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; + +entity abs_square is + port ( + reset : in std_logic; + clk : in std_logic; + + din_i : in std_logic_vector(7 downto 0); + din_q : in std_logic_vector(7 downto 0); + din_valid : in std_logic; + din_mark : in std_logic_vector; + + dout_i : out std_logic_vector(7 downto 0); + dout_q : out std_logic_vector(7 downto 0); + dout_valid : out std_logic; + dout_pow_sq : out std_logic_vector(15 downto 0); + dout_mark : out std_logic_vector + ); +end abs_square; + +architecture rtl of abs_square is + + constant COMP_DELAY : natural := 3; -- wrong! + + signal din_i_r : std_logic_vector(7 downto 0); + signal din_q_r : std_logic_vector(7 downto 0); + + signal din_i_rr : std_logic_vector(7 downto 0); + signal din_q_rr : std_logic_vector(7 downto 0); + signal din_i_sq_rr : signed(15 downto 0); + + signal din_i_rrr : std_logic_vector(7 downto 0); + signal din_q_rrr : std_logic_vector(7 downto 0); + signal din_i_sq_rrr : signed(15 downto 0); + signal din_q_sq_rrr : signed(15 downto 0); + +begin + process (clk) begin + if rising_edge(clk) then + din_i_r <= din_i; + din_q_r <= din_q; + end if; + end process; + + process (clk) begin + if rising_edge(clk) then + din_i_rr <= din_i_r; + din_q_rr <= din_q_r; + din_i_sq_rr <= signed(din_i_r) * signed(din_i_r); + end if; + end process; + + process (clk) begin + if rising_edge(clk) then + din_i_rrr <= din_i_rr; + din_q_rrr <= din_q_rr; + din_i_sq_rrr <= din_i_sq_rr; + din_q_sq_rrr <= signed(din_q_rr) * signed(din_q_rr); + end if; + end process; + + process (clk) begin + if rising_edge(clk) then + dout_i <= din_i_rrr; + dout_q <= din_q_rrr; + dout_pow_sq <= std_logic_vector(din_i_sq_rrr + din_q_sq_rrr); + end if; + end process; + + dv : entity work.delay_vector + generic map + ( + DELAY => 4 + ) + port map + ( + clk => clk, + clken => '1', + d => din_mark, + q => dout_mark + ); + + db : entity work.delay_bit + generic map + ( + DELAY => 4 + ) + port map + ( + clk => clk, + clken => '1', + d => din_valid, + q => dout_valid + ); +end rtl; \ No newline at end of file diff --git a/testsuite/synth/issue2023/async_dpram.vhd b/testsuite/synth/issue2023/async_dpram.vhd new file mode 100644 index 000000000..6a35eced0 --- /dev/null +++ b/testsuite/synth/issue2023/async_dpram.vhd @@ -0,0 +1,85 @@ +-- +-- Dual-Port Block RAM with Two Write Ports +-- Correct Modelization with a Shared Variable +-- +-- Download: ftp://ftp.xilinx.com/pub/documentation/misc/xstug_examples.zip +-- File: HDL_Coding_Techniques/rams/rams_16b.vhd +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_unsigned.all; + +entity async_dpram is + generic + ( + ADDR_BITS : natural := 9; + DATA_BITS : natural := 16; + OUTPUT_REG : boolean := true + ); + port + ( + clka : in std_logic; + clkb : in std_logic; + ena : in std_logic := '1'; + enb : in std_logic := '1'; + wea : in std_logic; + web : in std_logic; + addra : in std_logic_vector(ADDR_BITS-1 downto 0); + addrb : in std_logic_vector(ADDR_BITS-1 downto 0); + dia : in std_logic_vector(DATA_BITS-1 downto 0); + dib : in std_logic_vector(DATA_BITS-1 downto 0) := (others => '0'); + doa : out std_logic_vector(DATA_BITS-1 downto 0); + dob : out std_logic_vector(DATA_BITS-1 downto 0) + ); +end async_dpram; + +architecture rtl of async_dpram is + type ram_type is array (2**ADDR_BITS-1 downto 0) of std_logic_vector(DATA_BITS-1 downto 0); + shared variable RAM : ram_type; + + signal ram_out_a : std_logic_vector(DATA_BITS-1 downto 0); + signal ram_out_b : std_logic_vector(DATA_BITS-1 downto 0); +begin + + process (CLKA) begin + if rising_edge(CLKA) then + if ENA = '1' then + ram_out_a <= RAM(conv_integer(ADDRA)); + if WEA = '1' then + RAM(conv_integer(ADDRA)) := DIA; + end if; + end if; + end if; + end process; + + process (CLKB) begin + if rising_edge(CLKB) then + if ENB = '1' then + ram_out_b <= RAM(conv_integer(ADDRB)); + if WEB = '1' then + RAM(conv_integer(ADDRB)) := DIB; + end if; + end if; + end if; + end process; + + gen_output_reg : if OUTPUT_REG generate + process (CLKA) begin + if rising_edge(CLKA) then + doa <= ram_out_a; + end if; + end process; + + process (CLKB) begin + if rising_edge(CLKB) then + dob <= ram_out_b; + end if; + end process; + end generate; + + no_output_reg : if OUTPUT_REG = false generate + doa <= ram_out_a; + dob <= ram_out_b; + end generate; + +end; diff --git a/testsuite/synth/issue2023/delay_bit.vhd b/testsuite/synth/issue2023/delay_bit.vhd new file mode 100644 index 000000000..c7e7eb41f --- /dev/null +++ b/testsuite/synth/issue2023/delay_bit.vhd @@ -0,0 +1,33 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity delay_bit is + generic + ( + DELAY : integer := 32 + ); + port + ( + clk : in std_logic; + clken : in std_logic := '1'; + d : in std_logic; + q : out std_logic + ); + +end delay_bit; + +architecture archi of delay_bit is + signal shreg : std_logic_vector(DELAY - 1 downto 0); +begin + + process (clk) begin + if rising_edge(clk) then + if clken = '1' then + shreg <= shreg(DELAY - 2 downto 0) & d; + end if; + end if; + end process; + + q <= shreg(DELAY - 1); + +end archi; \ No newline at end of file diff --git a/testsuite/synth/issue2023/delay_vector.vhd b/testsuite/synth/issue2023/delay_vector.vhd new file mode 100644 index 000000000..834551f58 --- /dev/null +++ b/testsuite/synth/issue2023/delay_vector.vhd @@ -0,0 +1,36 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity delay_vector is + + generic ( + DELAY : integer := 32 + ); + port ( + clk : in std_logic; + clken : in std_logic := '1'; + d : in std_logic_vector; + q : out std_logic_vector); + +end delay_vector; + +architecture archi of delay_vector is + +begin + + gen_bits : for i in d'low to d'high generate + db : entity work.delay_bit + generic map + ( + DELAY => DELAY + ) + port map + ( + clk => clk, + clken => clken, + d => d(i), + q => q(i) + ); + end generate; + + end; \ No newline at end of file diff --git a/testsuite/synth/issue2023/test_comp.vhd b/testsuite/synth/issue2023/test_comp.vhd new file mode 100644 index 000000000..6816ed35c --- /dev/null +++ b/testsuite/synth/issue2023/test_comp.vhd @@ -0,0 +1,230 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; + +entity test_comp is + port + ( + reset : in std_logic; + clk : in std_logic; + + din_i : in std_logic_vector(7 downto 0); + din_q : in std_logic_vector(7 downto 0); + din_valid : in std_logic; + din_pps : in std_logic; + + dout_i : out std_logic_vector(7 downto 0); + dout_q : out std_logic_vector(7 downto 0); + dout_sq_power : out std_logic_vector(15 downto 0); + dout_valid : out std_logic; + dout_pps : out std_logic; + dout_frame : out std_logic; + + reg_clk : in std_logic; + reg_addr : in std_logic_vector(7 downto 0); + reg_wr_data : in std_logic_vector(15 downto 0); + reg_wr_en : in std_logic; + reg_en : in std_logic; + reg_rd_data : out std_logic_vector(15 downto 0); + reg_rd_ack : out std_logic + ); +end test_comp; + +architecture rtl_bob of test_comp is + + signal din_i_r : std_logic_vector(7 downto 0); + signal din_q_r : std_logic_vector(7 downto 0); + signal din_valid_r : std_logic; + signal din_pps_r : std_logic; + + signal abs_i : std_logic_vector(7 downto 0); + signal abs_q : std_logic_vector(7 downto 0); + signal abs_pow : std_logic_vector(15 downto 0); + signal abs_valid : std_logic; + signal abs_pps : std_logic; + + signal ram_wr_addr : std_logic_vector(8 downto 0); + signal ram_wr_data : std_logic_vector(abs_i'length + abs_q'length + abs_pow'length + 1 - 1 downto 0); + signal ram_wr_en : std_logic; + + signal ram_rd_addr : std_logic_vector(ram_wr_addr'range); + signal ram_rd_data : std_logic_vector(ram_wr_data'range); + + signal ram_rd_valid : std_logic; + signal ram_rd_valid_r : std_logic; + + signal ram_out_i : std_logic_vector(7 downto 0); + signal ram_out_q : std_logic_vector(7 downto 0); + signal ram_out_pow : std_logic_vector(15 downto 0); + signal ram_out_pps : std_logic; + signal abs_pow_delayed : std_logic_vector(15 downto 0); + + signal ram_out_i_r : std_logic_vector(7 downto 0); + signal ram_out_q_r : std_logic_vector(7 downto 0); + signal ram_out_pow_r : std_logic_vector(15 downto 0); + signal ram_out_valid_r : std_logic; + signal ram_out_pps_r : std_logic; + signal power_difference : signed(16 downto 0); + + signal ram_out_i_rr : std_logic_vector(7 downto 0); + signal ram_out_q_rr : std_logic_vector(7 downto 0); + signal ram_out_pow_rr : std_logic_vector(15 downto 0); + signal ram_out_valid_rr : std_logic; + signal ram_out_pps_rr : std_logic; + signal edge_detected : std_logic; + + signal threshold : std_logic_vector(15 downto 0); + signal threshold_reg : std_logic_vector(threshold'range); + signal threshold_reg_r : std_logic_vector(threshold'range); + + +begin + + process (clk) begin + if rising_edge(clk) then + din_i_r <= din_i; + din_q_r <= din_q; + din_valid_r <= din_valid; + din_pps_r <= din_pps; + end if; + end process; + + abs_sq : entity work.abs_square + port map + ( + reset => reset, + clk => clk, + + din_i => din_i_r, + din_q => din_q_r, + din_valid => din_valid_r, + din_mark(0) => din_pps_r, + + dout_i => abs_i, + dout_q => abs_q, + dout_valid => abs_valid, + dout_pow_sq => abs_pow, + dout_mark(0) => abs_pps + ); + + dv : entity work.delay_vector + generic map + ( + DELAY => 4 + ) + port map + ( + clk => clk, + clken => '1', + d => abs_pow, + q => abs_pow_delayed + ); + + process (clk) begin + if rising_edge(clk) then + ram_wr_data <= abs_pow & abs_i & abs_q & abs_pps; + ram_wr_en <= abs_valid; + if abs_valid = '1' then + ram_wr_addr <= std_logic_vector(unsigned(ram_wr_addr) + 1); + end if; + end if; + end process; + + ram_inst : entity work.async_dpram + generic map + ( + ADDR_BITS => ram_wr_addr'length, + DATA_BITS => ram_wr_data'length, + OUTPUT_REG => true + ) + port map + ( + clka => clk, + clkb => clk, + + wea => ram_wr_en, + addra => ram_wr_addr, + dia => ram_wr_data, + doa => open, + + web => '0', + addrb => ram_rd_addr, + dib => "000000000000000000000000000000000", + dob => ram_rd_data + ); + + process (clk) begin + if rising_edge(clk) then + ram_rd_addr <= std_logic_vector(unsigned(ram_wr_addr) - to_unsigned(400, ram_rd_addr'length)); + + ram_rd_valid <= ram_wr_en; + ram_rd_valid_r <= ram_rd_valid; + end if; + end process; + + ram_out_pow <= ram_rd_data(32 downto 17); + ram_out_i <= ram_rd_data(16 downto 9); + ram_out_q <= ram_rd_data(8 downto 1); + ram_out_pps <= ram_rd_data(0); + + process (clk) begin + if rising_edge(clk) then + ram_out_i_r <= ram_out_i; + ram_out_q_r <= ram_out_q; + ram_out_pow_r <= ram_out_pow; + ram_out_valid_r <= ram_rd_valid_r; + ram_out_pps_r <= ram_out_pps; + power_difference <= signed('0' & abs_pow_delayed) - signed('0' & ram_out_pow); + end if; + end process; + + + process (clk) begin + if rising_edge(clk) then + ram_out_i_rr <= ram_out_i_r; + ram_out_q_rr <= ram_out_q_r; + ram_out_pow_rr <= ram_out_pow_r; + ram_out_valid_rr <= ram_out_valid_r; + ram_out_pps_rr <= ram_out_pps_r; + edge_detected <= '0'; + if power_difference > signed('0' & threshold) then + edge_detected <= '1'; + end if; + end if; + end process; + + dout_i <= ram_out_i_rr; + dout_q <= ram_out_q_rr; + dout_sq_power <= ram_out_pow_rr; + dout_valid <= ram_out_valid_rr; + dout_pps <= ram_out_pps_rr; + dout_frame <= edge_detected; + + process (reg_clk) begin + if rising_edge(reg_clk) then + reg_rd_ack <= reg_en; + if reg_en = '1' then + if reg_wr_en = '0' then + case reg_addr is + when x"00" => + reg_rd_data <= x"0b0b"; + when x"01" => + reg_rd_data <= threshold_reg; + when others => + reg_rd_data <= (others => '-'); + end case; + else + case reg_addr is + when x"01" => + threshold_reg <= reg_wr_data; + when others => + null; + end case; + end if; + end if; + end if; + end process; + +end; \ No newline at end of file diff --git a/testsuite/synth/issue2023/testsuite.sh b/testsuite/synth/issue2023/testsuite.sh new file mode 100755 index 000000000..67a9daa1a --- /dev/null +++ b/testsuite/synth/issue2023/testsuite.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +. ../../testenv.sh + +GHDL_FLAGS=-fsynopsys + +analyze delay_bit.vhd delay_vector.vhd async_dpram.vhd abs_square.vhd test_comp.vhd +synth test_comp > syn_test_comp.vhdl + +clean + +echo "Test successful" -- cgit v1.2.3