Refactor volume_saturator VHDL code for improved readability and structure; update project files for consistent path references and disable unused components in lab3 design.
This commit is contained in:
@@ -24,9 +24,6 @@ END all_pass_filter;
|
||||
|
||||
ARCHITECTURE Behavioral OF all_pass_filter IS
|
||||
|
||||
SIGNAL trigger : STD_LOGIC := '0'; -- Used to control when to send data
|
||||
|
||||
SIGNAL s_axis_tlast_reg : STD_LOGIC := '0';
|
||||
SIGNAL s_axis_tready_int : STD_LOGIC := '0';
|
||||
SIGNAL m_axis_tvalid_int : STD_LOGIC := '0';
|
||||
|
||||
@@ -49,29 +46,21 @@ BEGIN
|
||||
m_axis_tvalid_int <= '0';
|
||||
|
||||
ELSE
|
||||
-- Set the ready signal for the slave interface
|
||||
s_axis_tready_int <= m_axis_tready OR NOT m_axis_tvalid_int;
|
||||
|
||||
-- Get the data from the slave interface
|
||||
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||
s_axis_tlast_reg <= s_axis_tlast; -- Store the last signal
|
||||
trigger <= '1'; -- Trigger the output
|
||||
|
||||
END IF;
|
||||
|
||||
-- Clear valid flag when master interface is ready
|
||||
IF m_axis_tready = '1' THEN
|
||||
m_axis_tvalid_int <= '0';
|
||||
END IF;
|
||||
|
||||
-- Send data to the master interface
|
||||
IF trigger = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
m_axis_tvalid_int <= '1'; -- Set valid flag for master interface
|
||||
m_axis_tlast <= s_axis_tlast_reg;
|
||||
-- Hndle data transfer
|
||||
IF s_axis_tvalid = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
s_axis_tready_int <= '1';
|
||||
m_axis_tvalid_int <= '1';
|
||||
m_axis_tdata <= s_axis_tdata;
|
||||
m_axis_tlast <= s_axis_tlast;
|
||||
|
||||
ELSE
|
||||
s_axis_tready_int <= '0';
|
||||
|
||||
-- Reset trigger
|
||||
trigger <= '0';
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
@@ -1,33 +1,88 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
entity balance_controller is
|
||||
generic (
|
||||
TDATA_WIDTH : positive := 24;
|
||||
BALANCE_WIDTH : positive := 10;
|
||||
BALANCE_STEP_2 : positive := 6 -- i.e., balance_values_per_step = 2**VOLUME_STEP_2
|
||||
ENTITY balance_controller IS
|
||||
GENERIC (
|
||||
TDATA_WIDTH : POSITIVE := 24;
|
||||
BALANCE_WIDTH : POSITIVE := 10;
|
||||
BALANCE_STEP_2 : POSITIVE := 6 -- i.e., balance_values_per_step = 2**VOLUME_STEP_2
|
||||
);
|
||||
Port (
|
||||
aclk : in std_logic;
|
||||
aresetn : in std_logic;
|
||||
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_tready : out std_logic;
|
||||
s_axis_tlast : in std_logic;
|
||||
s_axis_tvalid : IN STD_LOGIC;
|
||||
s_axis_tdata : IN STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0);
|
||||
s_axis_tready : OUT STD_LOGIC;
|
||||
s_axis_tlast : IN STD_LOGIC;
|
||||
|
||||
m_axis_tvalid : out std_logic;
|
||||
m_axis_tdata : out std_logic_vector(TDATA_WIDTH-1 downto 0);
|
||||
m_axis_tready : in std_logic;
|
||||
m_axis_tlast : out std_logic;
|
||||
m_axis_tvalid : OUT STD_LOGIC;
|
||||
m_axis_tdata : OUT STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0);
|
||||
m_axis_tready : IN STD_LOGIC;
|
||||
m_axis_tlast : OUT STD_LOGIC;
|
||||
|
||||
balance : in std_logic_vector(BALANCE_WIDTH-1 downto 0)
|
||||
balance : IN STD_LOGIC_VECTOR(BALANCE_WIDTH - 1 DOWNTO 0)
|
||||
);
|
||||
end balance_controller;
|
||||
END balance_controller;
|
||||
|
||||
architecture Behavioral of balance_controller is
|
||||
ARCHITECTURE Behavioral OF balance_controller IS
|
||||
|
||||
begin
|
||||
CONSTANT BAL_MID : INTEGER := 2 ** (BALANCE_WIDTH - 1); -- 512 per 10 bit
|
||||
CONSTANT DEAD_ZONE : INTEGER := 32;
|
||||
CONSTANT BLOCK_SIZE : INTEGER := 64;
|
||||
|
||||
end Behavioral;
|
||||
SIGNAL tvalid_reg : STD_LOGIC := '0';
|
||||
SIGNAL tdata_reg : STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
SIGNAL tlast_reg : STD_LOGIC := '0';
|
||||
|
||||
SIGNAL left_shift : INTEGER RANGE 0 TO BALANCE_WIDTH := 0;
|
||||
SIGNAL right_shift : INTEGER RANGE 0 TO BALANCE_WIDTH := 0;
|
||||
SIGNAL bal_int : INTEGER;
|
||||
|
||||
BEGIN
|
||||
|
||||
-- Handshake & cattura dati in ingresso
|
||||
PROCESS (aclk)
|
||||
BEGIN
|
||||
IF rising_edge(aclk) THEN
|
||||
IF aresetn = '0' THEN
|
||||
tvalid_reg <= '0';
|
||||
tdata_reg <= (OTHERS => '0');
|
||||
tlast_reg <= '0';
|
||||
ELSIF s_axis_tvalid = '1' AND m_axis_tready = '1' THEN
|
||||
tvalid_reg <= '1';
|
||||
tdata_reg <= s_axis_tdata;
|
||||
tlast_reg <= s_axis_tlast;
|
||||
ELSIF m_axis_tready = '1' THEN
|
||||
tvalid_reg <= '0';
|
||||
END IF;
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
s_axis_tready <= m_axis_tready;
|
||||
|
||||
bal_int <= to_integer(unsigned(balance));
|
||||
|
||||
-- Calcolo shift esponenziale per balance con zona morta centrale e blocchi da 64
|
||||
left_shift <= ((bal_int - (BAL_MID + DEAD_ZONE)) / BLOCK_SIZE) WHEN bal_int > (BAL_MID + DEAD_ZONE) ELSE 0;
|
||||
right_shift <= (((BAL_MID - DEAD_ZONE) - bal_int) / BLOCK_SIZE) WHEN bal_int < (BAL_MID - DEAD_ZONE) ELSE 0;
|
||||
|
||||
-- Applicazione gain esponenziale tramite shift (process combinatorio)
|
||||
PROCESS (tvalid_reg, tlast_reg, tdata_reg, left_shift, right_shift)
|
||||
BEGIN
|
||||
IF tvalid_reg = '1' THEN
|
||||
IF tlast_reg = '0' THEN -- left
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(shift_right(signed(tdata_reg), left_shift));
|
||||
ELSE -- right
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(shift_right(signed(tdata_reg), right_shift));
|
||||
END IF;
|
||||
ELSE
|
||||
m_axis_tdata <= (OTHERS => '0');
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
m_axis_tvalid <= tvalid_reg;
|
||||
m_axis_tlast <= tlast_reg;
|
||||
|
||||
END Behavioral;
|
||||
@@ -15,6 +15,39 @@ end edge_detector_toggle;
|
||||
|
||||
architecture Behavioral of edge_detector_toggle is
|
||||
|
||||
signal output_signal_int : std_logic;
|
||||
signal input_signal_old : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-- We will have to read output_signal, but it's an output port, so we have to
|
||||
-- define a new signal and connect it directly with the output port.
|
||||
-- In this way signal and output port have the exact same value without delays,
|
||||
-- but the signal can be read.
|
||||
output_signal <= output_signal_int;
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
if reset = '1' then
|
||||
output_signal_int <= '0';
|
||||
input_signal_old <= '0';
|
||||
else
|
||||
|
||||
-- Sample the old input_signal
|
||||
-- In this way, at each clock cycle, we have the current value and the previous one.
|
||||
input_signal_old <= input_signal;
|
||||
|
||||
-- Toggle output_signal if we see a 0 --> 1 transition (or 1 --> 0 for the falling edge case).
|
||||
if (EDGE_RISING = true and input_signal_old = '0' and input_signal = '1') or
|
||||
(EDGE_RISING = false and input_signal_old = '1' and input_signal = '0') then
|
||||
output_signal_int <= not output_signal_int;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
|
||||
@@ -1,34 +1,55 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
--use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if instantiating
|
||||
-- any Xilinx leaf cells in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity effect_selector is
|
||||
generic(
|
||||
JOYSTICK_LENGHT : integer := 10
|
||||
ENTITY effect_selector IS
|
||||
GENERIC (
|
||||
JOYSTICK_LENGHT : INTEGER := 10
|
||||
);
|
||||
Port (
|
||||
aclk : in STD_LOGIC;
|
||||
aresetn : in STD_LOGIC;
|
||||
|
||||
effect : in STD_LOGIC;
|
||||
jstck_x : in STD_LOGIC_VECTOR(JOYSTICK_LENGHT-1 downto 0);
|
||||
jstck_y : in STD_LOGIC_VECTOR(JOYSTICK_LENGHT-1 downto 0);
|
||||
volume : out STD_LOGIC_VECTOR(JOYSTICK_LENGHT-1 downto 0);
|
||||
balance : out STD_LOGIC_VECTOR(JOYSTICK_LENGHT-1 downto 0);
|
||||
lfo_period : out STD_LOGIC_VECTOR(JOYSTICK_LENGHT-1 downto 0)
|
||||
PORT (
|
||||
aclk : IN STD_LOGIC;
|
||||
aresetn : IN STD_LOGIC;
|
||||
|
||||
effect : IN STD_LOGIC;
|
||||
jstck_x : IN STD_LOGIC_VECTOR(JOYSTICK_LENGHT - 1 DOWNTO 0);
|
||||
jstck_y : IN STD_LOGIC_VECTOR(JOYSTICK_LENGHT - 1 DOWNTO 0);
|
||||
volume : OUT STD_LOGIC_VECTOR(JOYSTICK_LENGHT - 1 DOWNTO 0);
|
||||
balance : OUT STD_LOGIC_VECTOR(JOYSTICK_LENGHT - 1 DOWNTO 0);
|
||||
lfo_period : OUT STD_LOGIC_VECTOR(JOYSTICK_LENGHT - 1 DOWNTO 0)
|
||||
);
|
||||
end effect_selector;
|
||||
END effect_selector;
|
||||
|
||||
architecture Behavioral of effect_selector is
|
||||
ARCHITECTURE Behavioral OF effect_selector IS
|
||||
|
||||
begin
|
||||
BEGIN
|
||||
|
||||
end Behavioral;
|
||||
PROCESS (aclk)
|
||||
BEGIN
|
||||
|
||||
IF rising_edge(aclk) THEN
|
||||
|
||||
IF aresetn = '0' THEN
|
||||
volume <= (OTHERS => '0');
|
||||
balance <= (OTHERS => '0');
|
||||
lfo_period <= (OTHERS => '0');
|
||||
|
||||
ELSE
|
||||
balance <= jstck_x;
|
||||
|
||||
IF effect = '0' THEN
|
||||
-- volume/balance control
|
||||
volume <= jstck_y;
|
||||
lfo_period <= (OTHERS => '0');
|
||||
|
||||
ELSE
|
||||
-- LFO control
|
||||
lfo_period <= jstck_y;
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END PROCESS;
|
||||
|
||||
END Behavioral;
|
||||
@@ -1,22 +1,37 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity led_controller is
|
||||
Generic (
|
||||
LED_WIDTH : positive := 8
|
||||
ENTITY led_controller IS
|
||||
GENERIC (
|
||||
LED_WIDTH : POSITIVE := 8
|
||||
);
|
||||
Port (
|
||||
mute_enable : in std_logic;
|
||||
filter_enable : in std_logic;
|
||||
PORT (
|
||||
mute_enable : IN STD_LOGIC;
|
||||
filter_enable : IN STD_LOGIC;
|
||||
|
||||
led_r : out std_logic_vector(LED_WIDTH-1 downto 0);
|
||||
led_g : out std_logic_vector(LED_WIDTH-1 downto 0);
|
||||
led_b : out std_logic_vector(LED_WIDTH-1 downto 0)
|
||||
led_r : OUT STD_LOGIC_VECTOR(LED_WIDTH - 1 DOWNTO 0);
|
||||
led_g : OUT STD_LOGIC_VECTOR(LED_WIDTH - 1 DOWNTO 0);
|
||||
led_b : OUT STD_LOGIC_VECTOR(LED_WIDTH - 1 DOWNTO 0)
|
||||
);
|
||||
end led_controller;
|
||||
END led_controller;
|
||||
|
||||
architecture Behavioral of led_controller is
|
||||
ARCHITECTURE Behavioral OF led_controller IS
|
||||
|
||||
begin
|
||||
-- constant for "ON" and "OFF"
|
||||
CONSTANT ALL_ON : STD_LOGIC_VECTOR(LED_WIDTH - 1 DOWNTO 0) := (OTHERS => '1');
|
||||
CONSTANT ALL_OFF : STD_LOGIC_VECTOR(LED_WIDTH - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
|
||||
end Behavioral;
|
||||
BEGIN
|
||||
|
||||
-- If mute_enable = '1' Red LEDs on, others off
|
||||
-- Else if filter_enable='1' Blue LEDs on, others off
|
||||
-- Else Green LEDs on, others off
|
||||
|
||||
led_r <= ALL_ON WHEN mute_enable = '1' ELSE
|
||||
ALL_OFF;
|
||||
led_b <= ALL_ON WHEN (mute_enable = '0' AND filter_enable = '1') ELSE
|
||||
ALL_OFF;
|
||||
led_g <= ALL_ON WHEN (mute_enable = '0' AND filter_enable = '0') ELSE
|
||||
ALL_OFF;
|
||||
|
||||
END Behavioral;
|
||||
@@ -1,36 +1,7 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 22.05.2021 15:42:35
|
||||
-- Design Name:
|
||||
-- Module Name: led_level_controller - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool Versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if instantiating
|
||||
-- any Xilinx leaf cells in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity led_level_controller is
|
||||
generic(
|
||||
NUM_LEDS : positive := 16;
|
||||
@@ -54,7 +25,83 @@ entity led_level_controller is
|
||||
end led_level_controller;
|
||||
|
||||
architecture Behavioral of led_level_controller is
|
||||
constant REFRESH_CYCLES : natural := (refresh_time_ms * 1_000_000) / clock_period_ns;
|
||||
|
||||
signal volume_value : signed(CHANNEL_LENGHT-1 downto 0) := (others => '0');
|
||||
signal abs_audio : unsigned(CHANNEL_LENGHT-2 downto 0) := (others => '0');
|
||||
signal leds_int : std_logic_vector(NUM_LEDS-1 downto 0) := (others => '0');
|
||||
signal led_update : std_logic := '0';
|
||||
signal refresh_counter : natural range 0 to REFRESH_CYCLES-1 := 0;
|
||||
|
||||
begin
|
||||
led <= leds_int;
|
||||
s_axis_tready <= '1';
|
||||
|
||||
-- Register the audio absolute value
|
||||
|
||||
process(aclk)
|
||||
begin
|
||||
if rising_edge(aclk) then
|
||||
if aresetn = '0' then
|
||||
volume_value <= (others => '0');
|
||||
elsif s_axis_tvalid = '1' then
|
||||
volume_value <= signed(s_axis_tdata);
|
||||
if volume_value(volume_value'high) = '1' then
|
||||
abs_audio <= unsigned(-volume_value(CHANNEL_LENGHT-2 downto 0));
|
||||
else
|
||||
abs_audio <= unsigned(volume_value(CHANNEL_LENGHT-2 downto 0));
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Refresh counter
|
||||
process(aclk)
|
||||
begin
|
||||
if rising_edge(aclk) then
|
||||
if aresetn = '0' then
|
||||
refresh_counter <= 0;
|
||||
led_update <= '0';
|
||||
else
|
||||
if refresh_counter = REFRESH_CYCLES-1 then
|
||||
refresh_counter <= 0;
|
||||
led_update <= '1';
|
||||
else
|
||||
refresh_counter <= refresh_counter + 1;
|
||||
led_update <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Linear scaling of the audio signal to LED levels
|
||||
process(aclk)
|
||||
variable leds_on : natural range 0 to NUM_LEDS;
|
||||
variable temp_led_level : integer range 0 to NUM_LEDS;
|
||||
begin
|
||||
if rising_edge(aclk) then
|
||||
if aresetn = '0' then
|
||||
leds_int <= (others => '0');
|
||||
elsif led_update = '1' then
|
||||
-- Automatic linear scaling calculation:
|
||||
if to_integer(abs_audio) = 0 then
|
||||
temp_led_level := 0;
|
||||
else -- -1 bit for sign, -4 to get 15+1 levels
|
||||
temp_led_level := to_integer(shift_right(abs_audio,CHANNEL_LENGHT-4-1))+1;
|
||||
end if;
|
||||
|
||||
-- Limit to maximum number of LEDs
|
||||
if temp_led_level > NUM_LEDS then
|
||||
leds_on := NUM_LEDS;
|
||||
else
|
||||
leds_on := temp_led_level;
|
||||
end if;
|
||||
|
||||
leds_int <= (others => '0');
|
||||
if leds_on > 0 then
|
||||
leds_int(leds_on-1 downto 0) <= (others => '1');
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
||||
|
||||
@@ -30,14 +30,18 @@ ARCHITECTURE Behavioral OF moving_average_filter IS
|
||||
CONSTANT FILTER_ORDER : INTEGER := 2 ** FILTER_ORDER_POWER;
|
||||
|
||||
TYPE sample_array IS ARRAY (0 TO FILTER_ORDER - 1) OF signed(TDATA_WIDTH - 1 DOWNTO 0);
|
||||
SIGNAL samples : sample_array := (OTHERS => (OTHERS => '0'));
|
||||
SIGNAL sum : signed(TDATA_WIDTH + FILTER_ORDER_POWER - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
SIGNAL wr_ptr : INTEGER RANGE 0 TO FILTER_ORDER - 1 := 0;
|
||||
|
||||
SIGNAL trigger : STD_LOGIC := '0'; -- Used to control when to send data
|
||||
-- DX
|
||||
SIGNAL samples_dx : sample_array := (OTHERS => (OTHERS => '0'));
|
||||
SIGNAL sum_dx : signed(TDATA_WIDTH + FILTER_ORDER_POWER - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
SIGNAL wr_ptr_dx : INTEGER RANGE 0 TO FILTER_ORDER - 1 := 0;
|
||||
|
||||
-- SX
|
||||
SIGNAL samples_sx : sample_array := (OTHERS => (OTHERS => '0'));
|
||||
SIGNAL sum_sx : signed(TDATA_WIDTH + FILTER_ORDER_POWER - 1 DOWNTO 0) := (OTHERS => '0');
|
||||
SIGNAL wr_ptr_sx : INTEGER RANGE 0 TO FILTER_ORDER - 1 := 0;
|
||||
|
||||
SIGNAL s_axis_tready_int : STD_LOGIC := '0';
|
||||
SIGNAL s_axis_tlast_reg : STD_LOGIC := '0';
|
||||
SIGNAL m_axis_tvalid_int : STD_LOGIC := '0';
|
||||
|
||||
BEGIN
|
||||
@@ -52,11 +56,9 @@ BEGIN
|
||||
IF rising_edge(aclk) THEN
|
||||
|
||||
IF aresetn = '0' THEN
|
||||
samples <= (OTHERS => (OTHERS => '0'));
|
||||
sum <= (OTHERS => '0');
|
||||
wr_ptr <= 0;
|
||||
|
||||
trigger <= '0';
|
||||
samples_dx <= (OTHERS => (OTHERS => '0'));
|
||||
sum_dx <= (OTHERS => '0');
|
||||
wr_ptr_dx <= 0;
|
||||
|
||||
s_axis_tready_int <= '0';
|
||||
m_axis_tvalid_int <= '0';
|
||||
@@ -65,39 +67,62 @@ BEGIN
|
||||
m_axis_tdata <= (OTHERS => '0');
|
||||
|
||||
ELSE
|
||||
-- Set the ready signal for the slave interface
|
||||
s_axis_tready_int <= m_axis_tready OR NOT m_axis_tvalid_int;
|
||||
|
||||
-- Get and process input data
|
||||
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
|
||||
-- Circular buffer overwrite oldest saple with the new one from next clk cycle
|
||||
samples(wr_ptr) <= signed(s_axis_tdata);
|
||||
|
||||
-- Update the write pointer
|
||||
wr_ptr <= (wr_ptr + 1) MOD FILTER_ORDER;
|
||||
|
||||
-- Update the sum removing the oldest sample and adding the new one
|
||||
sum <= sum - samples(wr_ptr) + signed(s_axis_tdata);
|
||||
|
||||
s_axis_tlast_reg <= s_axis_tlast; -- Store the last signal
|
||||
trigger <= '1'; -- Trigger the output
|
||||
|
||||
END IF;
|
||||
|
||||
-- Clear valid flag when master interface is ready
|
||||
IF m_axis_tready = '1' THEN
|
||||
m_axis_tvalid_int <= '0';
|
||||
END IF;
|
||||
|
||||
-- Send data when triggered and receiver is ready
|
||||
IF trigger = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
m_axis_tvalid_int <= '1';
|
||||
m_axis_tlast <= s_axis_tlast_reg;
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(sum(sum'high DOWNTO FILTER_ORDER_POWER)); -- Average value
|
||||
|
||||
-- Reset trigger
|
||||
trigger <= '0';
|
||||
|
||||
-- Get and process data
|
||||
IF s_axis_tvalid = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
IF s_axis_tlast = '1' THEN
|
||||
-- Circular buffer overwrite oldest saple with the new one from next clk cycle
|
||||
samples_dx(wr_ptr_dx) <= signed(s_axis_tdata);
|
||||
|
||||
-- Update the write pointer
|
||||
wr_ptr_dx <= (wr_ptr_dx + 1) MOD FILTER_ORDER;
|
||||
|
||||
-- Update the sum_dx removing the oldest sample and adding the new one
|
||||
sum_dx <= sum_dx - samples_dx(wr_ptr_dx) + signed(s_axis_tdata);
|
||||
|
||||
-- Calculate the average and send it to the master interface
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(
|
||||
resize(
|
||||
shift_right(
|
||||
sum_dx - samples_dx(wr_ptr_dx) + signed(s_axis_tdata),
|
||||
FILTER_ORDER_POWER
|
||||
),
|
||||
m_axis_tdata'length
|
||||
)
|
||||
);
|
||||
ELSE
|
||||
-- Circular buffer overwrite oldest saple with the new one from next clk cycle
|
||||
samples_sx(wr_ptr_sx) <= signed(s_axis_tdata);
|
||||
|
||||
-- Update the write pointer
|
||||
wr_ptr_sx <= (wr_ptr_sx + 1) MOD FILTER_ORDER;
|
||||
|
||||
-- Update the sum_dx removing the oldest sample and adding the new one
|
||||
sum_sx <= sum_sx - samples_sx(wr_ptr_sx) + signed(s_axis_tdata);
|
||||
|
||||
-- Calculate the average and send it to the master interface
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(
|
||||
resize(
|
||||
shift_right(
|
||||
sum_sx - samples_sx(wr_ptr_sx) + signed(s_axis_tdata),
|
||||
FILTER_ORDER_POWER
|
||||
),
|
||||
m_axis_tdata'length
|
||||
)
|
||||
);
|
||||
END IF;
|
||||
|
||||
s_axis_tready_int <= '1';
|
||||
m_axis_tvalid_int <= '1';
|
||||
m_axis_tlast <= s_axis_tlast;
|
||||
|
||||
ELSE
|
||||
s_axis_tready_int <= '0';
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
ENTITY moving_average_filter_en IS
|
||||
GENERIC (
|
||||
-- Filter order expressed as 2^(FILTER_ORDER_POWER)
|
||||
FILTER_ORDER_POWER : INTEGER := 5;
|
||||
|
||||
TDATA_WIDTH : POSITIVE := 24
|
||||
);
|
||||
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 DOWNTO 0);
|
||||
m_axis_tlast : OUT STD_LOGIC;
|
||||
m_axis_tready : IN STD_LOGIC;
|
||||
|
||||
enable_filter : IN STD_LOGIC
|
||||
);
|
||||
END moving_average_filter_en;
|
||||
|
||||
ARCHITECTURE Behavioral OF moving_average_filter_en IS
|
||||
|
||||
-- Component declarations
|
||||
COMPONENT all_pass_filter IS
|
||||
GENERIC (
|
||||
TDATA_WIDTH : POSITIVE := 24
|
||||
);
|
||||
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 DOWNTO 0);
|
||||
m_axis_tlast : OUT STD_LOGIC;
|
||||
m_axis_tready : IN STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT moving_average_filter IS
|
||||
GENERIC (
|
||||
FILTER_ORDER_POWER : INTEGER := 5;
|
||||
TDATA_WIDTH : POSITIVE := 24
|
||||
);
|
||||
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 DOWNTO 0);
|
||||
m_axis_tlast : OUT STD_LOGIC;
|
||||
m_axis_tready : IN STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
-- Internal signals for the all-pass filter
|
||||
SIGNAL all_pass_s_tvalid : STD_LOGIC;
|
||||
SIGNAL all_pass_s_tready : STD_LOGIC;
|
||||
|
||||
SIGNAL all_pass_m_tvalid : STD_LOGIC;
|
||||
SIGNAL all_pass_m_tdata : STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0);
|
||||
SIGNAL all_pass_m_tlast : STD_LOGIC;
|
||||
SIGNAL all_pass_m_tready : STD_LOGIC;
|
||||
|
||||
-- Internal signals for the moving average filter
|
||||
SIGNAL moving_avg_s_tvalid : STD_LOGIC;
|
||||
SIGNAL moving_avg_s_tready : STD_LOGIC;
|
||||
|
||||
SIGNAL moving_avg_m_tvalid : STD_LOGIC;
|
||||
SIGNAL moving_avg_m_tdata : STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0);
|
||||
SIGNAL moving_avg_m_tlast : STD_LOGIC;
|
||||
SIGNAL moving_avg_m_tready : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
-- Instantiate the all-pass filter
|
||||
all_pass_inst : all_pass_filter
|
||||
GENERIC MAP(
|
||||
TDATA_WIDTH => TDATA_WIDTH
|
||||
)
|
||||
PORT MAP(
|
||||
aclk => aclk,
|
||||
aresetn => aresetn,
|
||||
|
||||
s_axis_tvalid => all_pass_s_tvalid,
|
||||
s_axis_tdata => s_axis_tdata,
|
||||
s_axis_tlast => s_axis_tlast,
|
||||
s_axis_tready => all_pass_s_tready,
|
||||
|
||||
m_axis_tvalid => all_pass_m_tvalid,
|
||||
m_axis_tdata => all_pass_m_tdata,
|
||||
m_axis_tlast => all_pass_m_tlast,
|
||||
m_axis_tready => all_pass_m_tready
|
||||
);
|
||||
|
||||
-- Instantiate the moving average filter
|
||||
moving_avg_inst : moving_average_filter
|
||||
GENERIC MAP(
|
||||
FILTER_ORDER_POWER => FILTER_ORDER_POWER,
|
||||
TDATA_WIDTH => TDATA_WIDTH
|
||||
)
|
||||
PORT MAP(
|
||||
aclk => aclk,
|
||||
aresetn => aresetn,
|
||||
|
||||
s_axis_tvalid => moving_avg_s_tvalid,
|
||||
s_axis_tdata => s_axis_tdata,
|
||||
s_axis_tlast => s_axis_tlast,
|
||||
s_axis_tready => moving_avg_s_tready,
|
||||
|
||||
m_axis_tvalid => moving_avg_m_tvalid,
|
||||
m_axis_tdata => moving_avg_m_tdata,
|
||||
m_axis_tlast => moving_avg_m_tlast,
|
||||
m_axis_tready => moving_avg_m_tready
|
||||
);
|
||||
|
||||
-- Assign filter control signals based on enable_filter
|
||||
all_pass_s_tvalid <= s_axis_tvalid WHEN enable_filter = '0' ELSE '0';
|
||||
moving_avg_s_tvalid <= s_axis_tvalid WHEN enable_filter = '1' ELSE '0';
|
||||
|
||||
all_pass_m_tready <= m_axis_tready WHEN enable_filter = '0' ELSE '0';
|
||||
moving_avg_m_tready <= m_axis_tready WHEN enable_filter = '1' ELSE '0';
|
||||
|
||||
-- Main AXIS assignments based on enable_filter
|
||||
s_axis_tready <= all_pass_s_tready WHEN enable_filter = '0' ELSE moving_avg_s_tready;
|
||||
m_axis_tvalid <= all_pass_m_tvalid WHEN enable_filter = '0' ELSE moving_avg_m_tvalid;
|
||||
m_axis_tdata <= all_pass_m_tdata WHEN enable_filter = '0' ELSE moving_avg_m_tdata;
|
||||
m_axis_tlast <= all_pass_m_tlast WHEN enable_filter = '0' ELSE moving_avg_m_tlast;
|
||||
|
||||
END Behavioral;
|
||||
@@ -1,31 +1,68 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity mute_controller is
|
||||
Generic (
|
||||
TDATA_WIDTH : positive := 24
|
||||
ENTITY mute_controller IS
|
||||
GENERIC (
|
||||
TDATA_WIDTH : POSITIVE := 24
|
||||
);
|
||||
Port (
|
||||
aclk : in std_logic;
|
||||
aresetn : in std_logic;
|
||||
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;
|
||||
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 downto 0);
|
||||
m_axis_tlast : out std_logic;
|
||||
m_axis_tready : in std_logic;
|
||||
m_axis_tvalid : OUT STD_LOGIC;
|
||||
m_axis_tdata : OUT STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0);
|
||||
m_axis_tlast : OUT STD_LOGIC;
|
||||
m_axis_tready : IN STD_LOGIC;
|
||||
|
||||
mute : in std_logic
|
||||
mute : IN STD_LOGIC
|
||||
);
|
||||
end mute_controller;
|
||||
END mute_controller;
|
||||
|
||||
architecture Behavioral of mute_controller is
|
||||
ARCHITECTURE Behavioral OF mute_controller IS
|
||||
BEGIN
|
||||
|
||||
begin
|
||||
PROCESS (aclk)
|
||||
BEGIN
|
||||
|
||||
end Behavioral;
|
||||
IF rising_edge(aclk) THEN
|
||||
|
||||
IF aresetn = '0' THEN
|
||||
m_axis_tvalid <= '0';
|
||||
m_axis_tdata <= (OTHERS => '0');
|
||||
m_axis_tlast <= '0';
|
||||
s_axis_tready <= '0';
|
||||
|
||||
ELSE
|
||||
IF s_axis_tvalid = '1' AND m_axis_tready = '1' THEN
|
||||
-- Accept input data
|
||||
s_axis_tready <= '1';
|
||||
m_axis_tvalid <= '1';
|
||||
m_axis_tlast <= s_axis_tlast;
|
||||
|
||||
IF mute = '1' THEN
|
||||
m_axis_tdata <= (OTHERS => '0');
|
||||
ELSE
|
||||
m_axis_tdata <= s_axis_tdata;
|
||||
END IF;
|
||||
|
||||
ELSE
|
||||
-- Do not accept new data
|
||||
s_axis_tready <= '0';
|
||||
m_axis_tvalid <= '0';
|
||||
m_axis_tlast <= '0';
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END PROCESS;
|
||||
|
||||
END Behavioral;
|
||||
@@ -1,35 +1,138 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity volume_controller 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
|
||||
HIGHER_BOUND : integer := 2**23-1; -- Inclusive
|
||||
LOWER_BOUND : integer := -2**23 -- Inclusive
|
||||
ENTITY volume_controller 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
|
||||
HIGHER_BOUND : INTEGER := 2 ** 23 - 1; -- Inclusive
|
||||
LOWER_BOUND : INTEGER := - 2 ** 23 -- Inclusive
|
||||
);
|
||||
Port (
|
||||
aclk : in std_logic;
|
||||
aresetn : in std_logic;
|
||||
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;
|
||||
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 downto 0);
|
||||
m_axis_tlast : out std_logic;
|
||||
m_axis_tready : in std_logic;
|
||||
m_axis_tvalid : OUT STD_LOGIC;
|
||||
m_axis_tdata : OUT STD_LOGIC_VECTOR(TDATA_WIDTH - 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)
|
||||
volume : IN STD_LOGIC_VECTOR(VOLUME_WIDTH - 1 DOWNTO 0)
|
||||
);
|
||||
end volume_controller;
|
||||
END volume_controller;
|
||||
|
||||
architecture Behavioral of volume_controller is
|
||||
ARCHITECTURE Behavioral OF volume_controller IS
|
||||
|
||||
begin
|
||||
-- Component declarations
|
||||
COMPONENT 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;
|
||||
|
||||
end Behavioral;
|
||||
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 COMPONENT;
|
||||
|
||||
COMPONENT volume_saturator IS
|
||||
GENERIC (
|
||||
TDATA_WIDTH : POSITIVE := 24;
|
||||
VOLUME_WIDTH : POSITIVE := 10;
|
||||
VOLUME_STEP_2 : POSITIVE := 6; -- i.e., number_of_steps = 2**VOLUME_STEP_2
|
||||
HIGHER_BOUND : INTEGER := 2 ** 15 - 1; -- Inclusive
|
||||
LOWER_BOUND : INTEGER := - 2 ** 15 -- Inclusive
|
||||
);
|
||||
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 + 2 ** (VOLUME_WIDTH - VOLUME_STEP_2 - 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 DOWNTO 0);
|
||||
m_axis_tlast : OUT STD_LOGIC;
|
||||
m_axis_tready : IN STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
-- Internal AXIS signals
|
||||
SIGNAL int_axis_tvalid : STD_LOGIC;
|
||||
SIGNAL int_axis_tready : STD_LOGIC;
|
||||
SIGNAL int_axis_tdata : STD_LOGIC_VECTOR(TDATA_WIDTH - 1 + 2 ** (VOLUME_WIDTH - VOLUME_STEP_2 - 1) DOWNTO 0);
|
||||
SIGNAL int_axis_tlast : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
-- Instantiate volume_multiplier
|
||||
volume_multiplier_inst : volume_multiplier
|
||||
GENERIC MAP(
|
||||
TDATA_WIDTH => TDATA_WIDTH,
|
||||
VOLUME_WIDTH => VOLUME_WIDTH,
|
||||
VOLUME_STEP_2 => VOLUME_STEP_2
|
||||
)
|
||||
PORT MAP(
|
||||
aclk => aclk,
|
||||
aresetn => aresetn,
|
||||
|
||||
s_axis_tvalid => s_axis_tvalid,
|
||||
s_axis_tdata => s_axis_tdata,
|
||||
s_axis_tlast => s_axis_tlast,
|
||||
s_axis_tready => s_axis_tready,
|
||||
|
||||
m_axis_tvalid => int_axis_tvalid,
|
||||
m_axis_tdata => int_axis_tdata,
|
||||
m_axis_tlast => int_axis_tlast,
|
||||
m_axis_tready => int_axis_tready,
|
||||
|
||||
volume => volume
|
||||
);
|
||||
|
||||
-- Instantiate volume_saturator
|
||||
volume_saturator_inst : volume_saturator
|
||||
GENERIC MAP(
|
||||
TDATA_WIDTH => TDATA_WIDTH,
|
||||
VOLUME_WIDTH => VOLUME_WIDTH,
|
||||
VOLUME_STEP_2 => VOLUME_STEP_2,
|
||||
HIGHER_BOUND => HIGHER_BOUND,
|
||||
LOWER_BOUND => LOWER_BOUND
|
||||
)
|
||||
PORT MAP(
|
||||
aclk => aclk,
|
||||
aresetn => aresetn,
|
||||
|
||||
s_axis_tvalid => int_axis_tvalid,
|
||||
s_axis_tdata => int_axis_tdata,
|
||||
s_axis_tlast => int_axis_tlast,
|
||||
s_axis_tready => int_axis_tready,
|
||||
|
||||
m_axis_tvalid => m_axis_tvalid,
|
||||
m_axis_tdata => m_axis_tdata,
|
||||
m_axis_tlast => m_axis_tlast,
|
||||
m_axis_tready => m_axis_tready
|
||||
);
|
||||
|
||||
END Behavioral;
|
||||
@@ -1,33 +1,118 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
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
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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)
|
||||
volume : IN STD_LOGIC_VECTOR(VOLUME_WIDTH - 1 DOWNTO 0)
|
||||
);
|
||||
end volume_multiplier;
|
||||
END volume_multiplier;
|
||||
|
||||
architecture Behavioral of volume_multiplier is
|
||||
ARCHITECTURE Behavioral OF volume_multiplier IS
|
||||
|
||||
begin
|
||||
CONSTANT VOLUME_STEPS : INTEGER := (2 ** VOLUME_WIDTH) / (2 ** (VOLUME_STEP_2 + 1));
|
||||
|
||||
end Behavioral;
|
||||
SIGNAL volume_exp_mult : INTEGER RANGE -VOLUME_STEPS TO VOLUME_STEPS := 0;
|
||||
signal volume_centered : SIGNED(VOLUME_WIDTH - 1 DOWNTO 0);
|
||||
|
||||
SIGNAL s_axis_tready_int : STD_LOGIC;
|
||||
SIGNAL m_axis_tvalid_int : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
-- Assigning the output signals
|
||||
s_axis_tready <= s_axis_tready_int;
|
||||
m_axis_tvalid <= m_axis_tvalid_int;
|
||||
|
||||
-- Volume to signed and centered
|
||||
volume_centered <= signed(unsigned(volume) - to_unsigned(511, VOLUME_WIDTH));
|
||||
|
||||
-- Volume to exp
|
||||
PROCESS (aclk)
|
||||
BEGIN
|
||||
|
||||
IF rising_edge(aclk) THEN
|
||||
|
||||
IF aresetn = '0' THEN
|
||||
volume_exp_mult <= 0;
|
||||
|
||||
ELSE
|
||||
volume_exp_mult <= to_integer(volume_centered(VOLUME_WIDTH - 1 DOWNTO VOLUME_STEP_2));
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END PROCESS;
|
||||
|
||||
-- Handle AXIS stream
|
||||
PROCESS (aclk)
|
||||
BEGIN
|
||||
|
||||
IF rising_edge(aclk) THEN
|
||||
|
||||
IF aresetn = '0' THEN
|
||||
s_axis_tready_int <= '0';
|
||||
m_axis_tvalid_int <= '0';
|
||||
m_axis_tlast <= '0';
|
||||
|
||||
ELSE
|
||||
-- Clear valid flag when master interface is ready
|
||||
IF m_axis_tready = '1' THEN
|
||||
m_axis_tvalid_int <= '0';
|
||||
END IF;
|
||||
|
||||
IF s_axis_tvalid = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
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;
|
||||
s_axis_tready_int <= '1';
|
||||
m_axis_tvalid_int <= '1';
|
||||
m_axis_tlast <= s_axis_tlast;
|
||||
|
||||
ELSE
|
||||
s_axis_tready_int <= '0';
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END PROCESS;
|
||||
|
||||
END Behavioral;
|
||||
@@ -1,33 +1,81 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
entity volume_saturator is
|
||||
Generic (
|
||||
TDATA_WIDTH : positive := 24;
|
||||
VOLUME_WIDTH : positive := 10;
|
||||
VOLUME_STEP_2 : positive := 6; -- i.e., number_of_steps = 2**(VOLUME_STEP_2)
|
||||
HIGHER_BOUND : integer := 2**15-1; -- Inclusive
|
||||
LOWER_BOUND : integer := -2**15 -- Inclusive
|
||||
ENTITY volume_saturator IS
|
||||
GENERIC (
|
||||
TDATA_WIDTH : POSITIVE := 24;
|
||||
VOLUME_WIDTH : POSITIVE := 10;
|
||||
VOLUME_STEP_2 : POSITIVE := 6; -- i.e., number_of_steps = 2**(VOLUME_STEP_2)
|
||||
HIGHER_BOUND : INTEGER := 2 ** 15 - 1; -- Inclusive
|
||||
LOWER_BOUND : INTEGER := - 2 ** 15 -- Inclusive
|
||||
);
|
||||
Port (
|
||||
aclk : in std_logic;
|
||||
aresetn : in std_logic;
|
||||
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 + 2**(VOLUME_WIDTH-VOLUME_STEP_2-1) downto 0);
|
||||
s_axis_tlast : in std_logic;
|
||||
s_axis_tready : out std_logic;
|
||||
s_axis_tvalid : IN STD_LOGIC;
|
||||
s_axis_tdata : IN STD_LOGIC_VECTOR(TDATA_WIDTH - 1 + 2 ** (VOLUME_WIDTH - VOLUME_STEP_2 - 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 downto 0);
|
||||
m_axis_tlast : out std_logic;
|
||||
m_axis_tready : in std_logic
|
||||
m_axis_tvalid : OUT STD_LOGIC;
|
||||
m_axis_tdata : OUT STD_LOGIC_VECTOR(TDATA_WIDTH - 1 DOWNTO 0);
|
||||
m_axis_tlast : OUT STD_LOGIC;
|
||||
m_axis_tready : IN STD_LOGIC
|
||||
);
|
||||
end volume_saturator;
|
||||
END volume_saturator;
|
||||
|
||||
architecture Behavioral of volume_saturator is
|
||||
ARCHITECTURE Behavioral OF volume_saturator IS
|
||||
|
||||
begin
|
||||
SIGNAL s_axis_tready_int : STD_LOGIC;
|
||||
SIGNAL m_axis_tvalid_int : STD_LOGIC;
|
||||
|
||||
end Behavioral;
|
||||
BEGIN
|
||||
-- Output assignments
|
||||
s_axis_tready <= s_axis_tready_int;
|
||||
m_axis_tvalid <= m_axis_tvalid_int;
|
||||
|
||||
PROCESS (aclk)
|
||||
BEGIN
|
||||
|
||||
IF rising_edge(aclk) THEN
|
||||
|
||||
IF aresetn = '0' THEN
|
||||
s_axis_tready_int <= '0';
|
||||
m_axis_tvalid_int <= '0';
|
||||
m_axis_tlast <= '0';
|
||||
m_axis_tdata <= (OTHERS => '0');
|
||||
|
||||
ELSE
|
||||
-- Clear valid flag when master interface is ready
|
||||
IF m_axis_tready = '1' THEN
|
||||
m_axis_tvalid_int <= '0';
|
||||
END IF;
|
||||
|
||||
IF s_axis_tvalid = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
|
||||
-- Check if the input data is within the bounds else saturate
|
||||
IF signed(s_axis_tdata) > to_signed(HIGHER_BOUND, s_axis_tdata'length) THEN
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(to_signed(HIGHER_BOUND, TDATA_WIDTH));
|
||||
ELSIF signed(s_axis_tdata) < to_signed(LOWER_BOUND, s_axis_tdata'length) THEN
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(to_signed(LOWER_BOUND, TDATA_WIDTH));
|
||||
ELSE
|
||||
m_axis_tdata <= STD_LOGIC_VECTOR(resize(signed(s_axis_tdata), TDATA_WIDTH));
|
||||
END IF;
|
||||
|
||||
s_axis_tready_int <= '1';
|
||||
m_axis_tvalid_int <= '1';
|
||||
m_axis_tlast <= s_axis_tlast;
|
||||
|
||||
ELSE
|
||||
s_axis_tready_int <= '0';
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
END PROCESS;
|
||||
|
||||
END Behavioral;
|
||||
Reference in New Issue
Block a user