+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+entity tb_vector_scale is
+end tb_vector_scale;
+
+--------------------------------------------------------------------------------
+
+architecture testbench of tb_vector_scale is
+
+ constant period : time := 500 ns;
+ constant offset : time := 0 us;
+
+ constant IRF_ADR_W : integer := 5;
+
+
+ signal ACK_O : std_logic;
+ signal CLK_I : std_logic;
+ signal RST_I : std_logic;
+ signal STB_I : std_logic;
+
+ signal IRF_ACK_I : std_logic;
+ signal IRF_ADR_O : std_logic_vector (IRF_ADR_W-1 downto 0);
+ signal IRF_CYC_O : std_logic;
+ signal IRF_DAT_I : std_logic_vector (15 downto 0);
+ signal IRF_DAT_O : std_logic_vector (15 downto 0);
+ signal IRF_STB_O : std_logic;
+ signal IRF_WE_O : std_logic;
+
+ signal MUL_A : std_logic_vector (15 downto 0);
+ signal MUL_B : std_logic_vector (15 downto 0);
+ signal MUL_PROD : std_logic_vector (31 downto 0);
+
+
+ subtype word_t is std_logic_vector (15 downto 0);
+
+ signal dbg_mem0x05 : word_t := (others => '0');
+ signal dbg_mem0x10 : word_t := (others => '0');
+ signal dbg_mem0x11 : word_t := (others => '0');
+ signal dbg_ack : std_logic := '0';
+
+--------------------------------------------------------------------------------
+
+begin
+
+ uut : entity work.vector_scale
+ generic map (
+ IRF_ADR_W => IRF_ADR_W,
+ BASE => 0,
+ SCALE_OFF => 5,
+ PHASE_BASE => 16,
+ VECTOR_OFF => 0,
+ SCALED_OFF => 1,
+ VECTOR_W => 10)
+ port map (
+ ACK_O => ACK_O,
+ CLK_I => CLK_I,
+ RST_I => RST_I,
+ STB_I => STB_I,
+ MUL_A => MUL_A,
+ MUL_B => MUL_B,
+ MUL_PROD => MUL_PROD,
+ IRF_ACK_I => IRF_ACK_I,
+ IRF_ADR_O => IRF_ADR_O,
+ IRF_DAT_I => IRF_DAT_I,
+ IRF_DAT_O => IRF_DAT_O,
+ IRF_STB_O => IRF_STB_O,
+ IRF_WE_O => IRF_WE_O);
+
+ multiplier_1 : entity work.multiplier
+ port map (
+ A => MUL_A,
+ B => MUL_B,
+ prod => MUL_PROD);
+
+
+ SYSCON_CLK : process is
+ begin
+ CLK_I <= '0';
+ wait for offset;
+ loop
+ CLK_I <= '1';
+ wait for period/2;
+ CLK_I <= '0';
+ wait for period/2;
+ end loop;
+ end process;
+
+ SYSCON_RST : process is
+ begin
+ RST_I <= '0';
+ wait for offset;
+ wait for 0.75*period;
+ RST_I <= '1';
+ wait for 2*period;
+ RST_I <= '0';
+ wait;
+ end process;
+
+
+ DBG_MEM : process (IRF_STB_O, CLK_I) is
+ begin
+ IRF_ACK_I <= IRF_STB_O and (IRF_WE_O or dbg_ack);
+
+ if rising_edge(CLK_I) then
+ dbg_ack <= IRF_STB_O;
+ end if;
+
+ if rising_edge(CLK_I) and IRF_STB_O = '1' then
+ if IRF_WE_O = '0' then
+ case conv_integer(IRF_ADR_O) is
+ when 16#05# => IRF_DAT_I <= dbg_mem0x05;
+ when 16#10# => IRF_DAT_I <= dbg_mem0x10;
+ when 16#11# => IRF_DAT_I <= dbg_mem0x11;
+ when others =>
+ IRF_DAT_I <= (others => '0');
+ report "Reading from non-existing register" severity warning;
+ end case;
+ else
+ case conv_integer(IRF_ADR_O) is
+ --when 16#05# => dbg_mem0x05 <= IRF_DAT_O;
+ --when 16#10# => dbg_mem0x10 <= IRF_DAT_O;
+ when 16#11# => dbg_mem0x11 <= IRF_DAT_O;
+ when others =>
+ report "Writing to read-only registers" severity error;
+ end case;
+ end if;
+ end if;
+ end process;
+
+--------------------------------------------------------------------------------
+
+ UUT_FEED : process is
+ begin
+ STB_I <= '0';
+
+ wait for offset;
+ wait for 4*period;
+
+ for i in 0 to 10 loop
+ dbg_mem0x10 <= "0000000111111111";
+
+ dbg_mem0x05 <= conv_std_logic_vector(i*(2**10), 16);
+
+ wait for 0.75*period;
+ STB_I <= '1';
+ wait for 0.25*period;
+ wait until rising_edge(CLK_I) and ACK_O = '1';
+ wait for 0.25*period;
+ STB_I <= '0';
+ wait for 0.75*period;
+
+ wait for 4*period;
+ end loop;
+
+ wait;
+ end process;
+
+end testbench;
+