diff --git a/LAB3/design/diligent_jstk/diligent_jstk.bd b/LAB3/design/diligent_jstk/diligent_jstk.bd
index dbd3add..d4628ee 100644
--- a/LAB3/design/diligent_jstk/diligent_jstk.bd
+++ b/LAB3/design/diligent_jstk/diligent_jstk.bd
@@ -71,7 +71,7 @@
"proc_sys_reset_0": {
"vlnv": "xilinx.com:ip:proc_sys_reset:5.0",
"xci_name": "diligent_jstk_proc_sys_reset_0_0",
- "xci_path": "ip\\diligent_jstk_proc_sys_reset_0_0_1\\diligent_jstk_proc_sys_reset_0_0.xci",
+ "xci_path": "ip\\diligent_jstk_proc_sys_reset_0_0\\diligent_jstk_proc_sys_reset_0_0.xci",
"inst_hier_path": "proc_sys_reset_0",
"parameters": {
"RESET_BOARD_INTERFACE": {
@@ -85,7 +85,7 @@
"clk_wiz_0": {
"vlnv": "xilinx.com:ip:clk_wiz:6.0",
"xci_name": "diligent_jstk_clk_wiz_0_0",
- "xci_path": "ip\\diligent_jstk_clk_wiz_0_0_1\\diligent_jstk_clk_wiz_0_0.xci",
+ "xci_path": "ip\\diligent_jstk_clk_wiz_0_0\\diligent_jstk_clk_wiz_0_0.xci",
"inst_hier_path": "clk_wiz_0",
"parameters": {
"CLK_IN1_BOARD_INTERFACE": {
@@ -99,7 +99,7 @@
"AXI4Stream_UART_0": {
"vlnv": "DigiLAB:ip:AXI4Stream_UART:1.1",
"xci_name": "diligent_jstk_AXI4Stream_UART_0_0",
- "xci_path": "ip\\diligent_jstk_AXI4Stream_UART_0_0_1\\diligent_jstk_AXI4Stream_UART_0_0.xci",
+ "xci_path": "ip\\diligent_jstk_AXI4Stream_UART_0_0\\diligent_jstk_AXI4Stream_UART_0_0.xci",
"inst_hier_path": "AXI4Stream_UART_0",
"parameters": {
"UART_BAUD_RATE": {
@@ -116,7 +116,7 @@
"jstk_uart_bridge_0": {
"vlnv": "xilinx.com:module_ref:jstk_uart_bridge:1.0",
"xci_name": "diligent_jstk_jstk_uart_bridge_0_0",
- "xci_path": "ip\\diligent_jstk_jstk_uart_bridge_0_0_1\\diligent_jstk_jstk_uart_bridge_0_0.xci",
+ "xci_path": "ip\\diligent_jstk_jstk_uart_bridge_0_0\\diligent_jstk_jstk_uart_bridge_0_0.xci",
"inst_hier_path": "jstk_uart_bridge_0",
"reference_info": {
"ref_type": "hdl",
@@ -330,7 +330,7 @@
"axi4stream_spi_master_0": {
"vlnv": "DigiLAB:ip:axi4stream_spi_master:1.0",
"xci_name": "diligent_jstk_axi4stream_spi_master_0_0",
- "xci_path": "ip\\diligent_jstk_axi4stream_spi_master_0_0_1\\diligent_jstk_axi4stream_spi_master_0_0.xci",
+ "xci_path": "ip\\diligent_jstk_axi4stream_spi_master_0_0\\diligent_jstk_axi4stream_spi_master_0_0.xci",
"inst_hier_path": "axi4stream_spi_master_0",
"parameters": {
"c_sclkfreq": {
@@ -341,7 +341,7 @@
"system_ila_0": {
"vlnv": "xilinx.com:ip:system_ila:1.1",
"xci_name": "diligent_jstk_system_ila_0_0",
- "xci_path": "ip\\diligent_jstk_system_ila_0_0_1\\diligent_jstk_system_ila_0_0.xci",
+ "xci_path": "ip\\diligent_jstk_system_ila_0_0\\diligent_jstk_system_ila_0_0.xci",
"inst_hier_path": "system_ila_0",
"parameters": {
"C_MON_TYPE": {
@@ -377,7 +377,7 @@
"digilent_jstk2_0": {
"vlnv": "xilinx.com:module_ref:digilent_jstk2:1.0",
"xci_name": "diligent_jstk_digilent_jstk2_0_0",
- "xci_path": "ip\\diligent_jstk_digilent_jstk2_0_0_1\\diligent_jstk_digilent_jstk2_0_0.xci",
+ "xci_path": "ip\\diligent_jstk_digilent_jstk2_0_0\\diligent_jstk_digilent_jstk2_0_0.xci",
"inst_hier_path": "digilent_jstk2_0",
"parameters": {
"SPI_SCLKFREQ": {
@@ -591,12 +591,6 @@
}
},
"interface_nets": {
- "AXI4Stream_UART_0_UART": {
- "interface_ports": [
- "usb_uart",
- "AXI4Stream_UART_0/UART"
- ]
- },
"axi4stream_spi_master_0_M_AXIS": {
"interface_ports": [
"axi4stream_spi_master_0/M_AXIS",
@@ -610,10 +604,16 @@
"jstk_uart_bridge_0/s_axis"
]
},
- "jstk_uart_bridge_0_m_axis": {
+ "axi4stream_spi_master_0_SPI_M": {
"interface_ports": [
- "AXI4Stream_UART_0/S00_AXIS_TX",
- "jstk_uart_bridge_0/m_axis"
+ "SPI_M_0",
+ "axi4stream_spi_master_0/SPI_M"
+ ]
+ },
+ "AXI4Stream_UART_0_UART": {
+ "interface_ports": [
+ "usb_uart",
+ "AXI4Stream_UART_0/UART"
]
},
"digilent_jstk2_0_m_axis": {
@@ -623,10 +623,10 @@
"system_ila_0/SLOT_0_AXIS"
]
},
- "axi4stream_spi_master_0_SPI_M": {
+ "jstk_uart_bridge_0_m_axis": {
"interface_ports": [
- "SPI_M_0",
- "axi4stream_spi_master_0/SPI_M"
+ "AXI4Stream_UART_0/S00_AXIS_TX",
+ "jstk_uart_bridge_0/m_axis"
]
}
},
diff --git a/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd b/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd
index 460a63b..39455a0 100644
--- a/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd
+++ b/LAB3/design/diligent_jstk/hdl/diligent_jstk_wrapper.vhd
@@ -1,8 +1,8 @@
--Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.
----------------------------------------------------------------------------------
--Tool Version: Vivado v.2020.2 (win64) Build 3064766 Wed Nov 18 09:12:45 MST 2020
---Date : Sun May 18 23:39:32 2025
---Host : DavideASUS running 64-bit major release (build 9200)
+--Date : Mon May 19 09:11:39 2025
+--Host : Davide-Samsung running 64-bit major release (build 9200)
--Command : generate_target diligent_jstk_wrapper.bd
--Design : diligent_jstk_wrapper
--Purpose : IP block netlist
@@ -29,6 +29,8 @@ architecture STRUCTURE of diligent_jstk_wrapper is
port (
reset : in STD_LOGIC;
sys_clock : in STD_LOGIC;
+ usb_uart_txd : out STD_LOGIC;
+ usb_uart_rxd : in STD_LOGIC;
SPI_M_0_sck_t : out STD_LOGIC;
SPI_M_0_io1_o : out STD_LOGIC;
SPI_M_0_ss_t : out STD_LOGIC;
@@ -40,9 +42,7 @@ architecture STRUCTURE of diligent_jstk_wrapper is
SPI_M_0_sck_o : out STD_LOGIC;
SPI_M_0_ss_i : in STD_LOGIC;
SPI_M_0_io1_i : in STD_LOGIC;
- SPI_M_0_io0_i : in STD_LOGIC;
- usb_uart_txd : out STD_LOGIC;
- usb_uart_rxd : in STD_LOGIC
+ SPI_M_0_io0_i : in STD_LOGIC
);
end component diligent_jstk;
component IOBUF is
diff --git a/LAB3/src/all_pass_filter.vhd b/LAB3/src/all_pass_filter.vhd
index b3bed43..43796f8 100644
--- a/LAB3/src/all_pass_filter.vhd
+++ b/LAB3/src/all_pass_filter.vhd
@@ -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;
diff --git a/LAB3/src/balance_controller.vhd b/LAB3/src/balance_controller.vhd
index 1d5f90c..01b41cd 100644
--- a/LAB3/src/balance_controller.vhd
+++ b/LAB3/src/balance_controller.vhd
@@ -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;
\ No newline at end of file
diff --git a/LAB3/src/edge_detector_toggle.vhd b/LAB3/src/edge_detector_toggle.vhd
index 061c3fa..441a64a 100644
--- a/LAB3/src/edge_detector_toggle.vhd
+++ b/LAB3/src/edge_detector_toggle.vhd
@@ -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;
diff --git a/LAB3/src/effect_selector.vhd b/LAB3/src/effect_selector.vhd
index 4efe6d7..ff97a30 100644
--- a/LAB3/src/effect_selector.vhd
+++ b/LAB3/src/effect_selector.vhd
@@ -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;
\ No newline at end of file
diff --git a/LAB3/src/led_controller.vhd b/LAB3/src/led_controller.vhd
index 023a503..ebeae91 100644
--- a/LAB3/src/led_controller.vhd
+++ b/LAB3/src/led_controller.vhd
@@ -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;
\ No newline at end of file
diff --git a/LAB3/src/led_level_controller.vhd b/LAB3/src/led_level_controller.vhd
index 01f2cf0..69ea691 100644
--- a/LAB3/src/led_level_controller.vhd
+++ b/LAB3/src/led_level_controller.vhd
@@ -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;
diff --git a/LAB3/src/moving_average_filter.vhd b/LAB3/src/moving_average_filter.vhd
index d60c722..c31ab83 100644
--- a/LAB3/src/moving_average_filter.vhd
+++ b/LAB3/src/moving_average_filter.vhd
@@ -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;
diff --git a/LAB3/src/moving_average_filter_en.vhd b/LAB3/src/moving_average_filter_en.vhd
deleted file mode 100644
index e768456..0000000
--- a/LAB3/src/moving_average_filter_en.vhd
+++ /dev/null
@@ -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;
\ No newline at end of file
diff --git a/LAB3/src/mute_controller.vhd b/LAB3/src/mute_controller.vhd
index 2afdbf0..f46eab0 100644
--- a/LAB3/src/mute_controller.vhd
+++ b/LAB3/src/mute_controller.vhd
@@ -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;
\ No newline at end of file
diff --git a/LAB3/src/volume_controller.vhd b/LAB3/src/volume_controller.vhd
index f47429f..f983367 100644
--- a/LAB3/src/volume_controller.vhd
+++ b/LAB3/src/volume_controller.vhd
@@ -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;
\ No newline at end of file
diff --git a/LAB3/src/volume_multiplier.vhd b/LAB3/src/volume_multiplier.vhd
index 34641e2..8aa60fc 100644
--- a/LAB3/src/volume_multiplier.vhd
+++ b/LAB3/src/volume_multiplier.vhd
@@ -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;
\ No newline at end of file
diff --git a/LAB3/src/volume_saturator.vhd b/LAB3/src/volume_saturator.vhd
index ae69f9f..10744c0 100644
--- a/LAB3/src/volume_saturator.vhd
+++ b/LAB3/src/volume_saturator.vhd
@@ -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;
\ No newline at end of file
diff --git a/LAB3/vivado/diligent_jstk/diligent_jstk.xpr b/LAB3/vivado/diligent_jstk/diligent_jstk.xpr
index 66fb777..f06df87 100644
--- a/LAB3/vivado/diligent_jstk/diligent_jstk.xpr
+++ b/LAB3/vivado/diligent_jstk/diligent_jstk.xpr
@@ -95,27 +95,27 @@
-
+
-
-
-
-
+
-
-
-
-
+
-
+
-
+
+
+
+
+
+
+
@@ -164,6 +164,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -176,9 +188,9 @@
-
+
-
+
@@ -188,21 +200,9 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -236,39 +236,11 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ Vivado Synthesis Defaults
+
@@ -278,7 +250,9 @@
-
+
+ Vivado Synthesis Defaults
+
@@ -286,9 +260,23 @@
-
+
-
+
+ Vivado Synthesis Defaults
+
+
+
+
+
+
+
+
+
+
+
+ Vivado Synthesis Defaults
+
@@ -308,6 +296,30 @@
+
+
+
+ Vivado Synthesis Defaults
+
+
+
+
+
+
+
+
+
+
+
+ Vivado Synthesis Defaults
+
+
+
+
+
+
+
+
@@ -326,60 +338,11 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ Default settings for Implementation.
+
@@ -396,7 +359,9 @@
-
+
+ Default settings for Implementation.
+
@@ -411,9 +376,30 @@
-
+
-
+
+ Default settings for Implementation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default settings for Implementation.
+
@@ -447,6 +433,44 @@
+
+
+
+ Default settings for Implementation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default settings for Implementation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LAB3/vivado/lab3/lab3.xpr b/LAB3/vivado/lab3/lab3.xpr
index 0736966..ca8d493 100644
--- a/LAB3/vivado/lab3/lab3.xpr
+++ b/LAB3/vivado/lab3/lab3.xpr
@@ -77,84 +77,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -168,6 +90,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+