LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY volume_multiplier IS GENERIC ( TDATA_WIDTH : POSITIVE := 24; VOLUME_WIDTH : POSITIVE := 10; VOLUME_STEP_2 : POSITIVE := 6 -- i.e., volume_values_per_step = 2**VOLUME_STEP_2 ); PORT ( aclk : IN STD_LOGIC; aresetn : IN STD_LOGIC; s_axis_tvalid : IN STD_LOGIC; s_axis_tdata : IN STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0); s_axis_tlast : IN STD_LOGIC; s_axis_tready : OUT STD_LOGIC; m_axis_tvalid : OUT STD_LOGIC; m_axis_tdata : OUT STD_LOGIC_VECTOR(TDATA_WIDTH - 1 + 2 ** (VOLUME_WIDTH - VOLUME_STEP_2 - 1) DOWNTO 0); m_axis_tlast : OUT STD_LOGIC; m_axis_tready : IN STD_LOGIC; volume : IN STD_LOGIC_VECTOR(VOLUME_WIDTH - 1 DOWNTO 0) ); END volume_multiplier; ARCHITECTURE Behavioral OF volume_multiplier IS CONSTANT VOLUME_STEPS : INTEGER := (2 ** (VOLUME_WIDTH - 1)) / (2 ** VOLUME_STEP_2) + 1; SIGNAL volume_exp_mult : INTEGER RANGE -VOLUME_STEPS TO VOLUME_STEPS := 0; SIGNAL m_axis_tvalid_int : STD_LOGIC; BEGIN -- Assigning the output signals m_axis_tvalid <= m_axis_tvalid_int; s_axis_tready <= m_axis_tready AND aresetn; -- Volume to exp PROCESS (aclk) BEGIN IF rising_edge(aclk) THEN IF aresetn = '0' THEN volume_exp_mult <= 0; ELSE -- Volume to signed and centered and convert to power of 2 exponent volume_exp_mult <= to_integer( shift_right(signed('0' & volume) - to_signed(480, volume'length + 1), VOLUME_STEP_2) ); END IF; END IF; END PROCESS; -- Handle AXIS stream PROCESS (aclk) BEGIN IF rising_edge(aclk) THEN IF aresetn = '0' THEN m_axis_tvalid_int <= '0'; m_axis_tlast <= '0'; m_axis_tdata <= (OTHERS => '0'); ELSE -- Default output signals m_axis_tlast <= '0'; -- Clear valid flag when master interface is ready IF m_axis_tready = '1' THEN m_axis_tvalid_int <= '0'; END IF; -- Handle the data flow IF s_axis_tvalid = '1' AND m_axis_tready = '1' THEN -- Multiply the input data with the volume and assign to output IF volume_exp_mult >= 0 THEN m_axis_tdata <= STD_LOGIC_VECTOR( shift_left( resize( signed(s_axis_tdata), m_axis_tdata'LENGTH ), volume_exp_mult ) ); ELSE m_axis_tdata <= STD_LOGIC_VECTOR( shift_right( resize( signed(s_axis_tdata), m_axis_tdata'LENGTH ), - volume_exp_mult ) ); END IF; m_axis_tvalid_int <= '1'; m_axis_tlast <= s_axis_tlast; END IF; END IF; END IF; END PROCESS; END Behavioral;