Lab 3: Audio Processing System #3

Merged
PickleRick merged 43 commits from LAB3 into main 2025-06-07 22:18:48 +02:00
3 changed files with 80 additions and 47 deletions
Showing only changes of commit be88f69202 - Show all commits

View File

@@ -52,6 +52,12 @@ ARCHITECTURE Behavioral OF LFO IS
BEGIN BEGIN
-- Output assignments
s_axis_tready <= s_axis_tready_i;
m_axis_tdata <= m_axis_tdata_i;
m_axis_tvalid <= m_axis_tvalid_i;
m_axis_tlast <= m_axis_tlast_i;
PROCESS (aclk) PROCESS (aclk)
BEGIN BEGIN
IF rising_edge(aclk) THEN IF rising_edge(aclk) THEN
@@ -68,10 +74,13 @@ BEGIN
tri_counter <= (OTHERS => '0'); tri_counter <= (OTHERS => '0');
direction_up <= '1'; direction_up <= '1';
lfo_tick <= '0'; lfo_tick <= '0';
ELSIF lfo_enable = '1' THEN ELSIF lfo_enable = '1' THEN
IF step_counter < lfo_period_int THEN IF step_counter < lfo_period_int THEN
step_counter <= step_counter + 1; step_counter <= step_counter + 1;
lfo_tick <= '0'; lfo_tick <= '0';
ELSE ELSE
step_counter <= 0; step_counter <= 0;
lfo_tick <= '1'; lfo_tick <= '1';
@@ -92,14 +101,19 @@ BEGIN
END IF; END IF;
END IF; END IF;
END IF; END IF;
ELSE ELSE
lfo_tick <= '0'; lfo_tick <= '0';
direction_up <= '1'; direction_up <= '1';
tri_counter <= (OTHERS => '0'); tri_counter <= (OTHERS => '0');
step_counter <= 0; step_counter <= 0;
END IF; END IF;
END IF; END IF;
END PROCESS; END PROCESS;
PROCESS (aclk) PROCESS (aclk)
BEGIN BEGIN
IF rising_edge(aclk) THEN IF rising_edge(aclk) THEN
@@ -146,9 +160,4 @@ BEGIN
END IF; END IF;
END PROCESS; END PROCESS;
s_axis_tready <= s_axis_tready_i;
m_axis_tdata <= m_axis_tdata_i;
m_axis_tvalid <= m_axis_tvalid_i;
m_axis_tlast <= m_axis_tlast_i;
END ARCHITECTURE Behavioral; END ARCHITECTURE Behavioral;

View File

@@ -24,11 +24,18 @@ END all_pass_filter;
ARCHITECTURE Behavioral OF all_pass_filter IS 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 s_axis_tready_int : STD_LOGIC := '0';
SIGNAL m_axis_tvalid_int : STD_LOGIC := '0'; SIGNAL m_axis_tvalid_int : STD_LOGIC := '0';
BEGIN BEGIN
-- This architecture mimics the structure, handshake logic, and timing (clock cycles spent)
-- of the moving_average_filter, but does not process or modify the samples.
-- It simply passes input data to the output unchanged, ensuring the same latency and interface behavior.
-- Output assignments -- Output assignments
s_axis_tready <= s_axis_tready_int; s_axis_tready <= s_axis_tready_int;
m_axis_tvalid <= m_axis_tvalid_int; m_axis_tvalid <= m_axis_tvalid_int;
@@ -42,28 +49,35 @@ BEGIN
m_axis_tvalid_int <= '0'; m_axis_tvalid_int <= '0';
ELSE 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 -- Clear valid flag when master interface is ready
IF m_axis_tready = '1' THEN IF m_axis_tready = '1' THEN
m_axis_tvalid_int <= '0'; m_axis_tvalid_int <= '0';
END IF; END IF;
IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN -- Send data to the master interface
IF m_axis_tvalid_int = '0' OR m_axis_tready = '1' THEN IF trigger = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
s_axis_tready_int <= '1'; -- Keep reading from slave interface
m_axis_tvalid_int <= '1'; -- Set valid flag for master interface m_axis_tvalid_int <= '1'; -- Set valid flag for master interface
m_axis_tlast <= s_axis_tlast_reg;
m_axis_tdata <= s_axis_tdata; m_axis_tdata <= s_axis_tdata;
m_axis_tlast <= s_axis_tlast;
ELSE -- Reset trigger
s_axis_tready_int <= '0'; -- Block slave interface to avoid data loss trigger <= '0';
END IF;
END IF; END IF;
END IF; END IF;
END IF; END IF;
END PROCESS; END PROCESS;
END Behavioral; END Behavioral;

View File

@@ -31,25 +31,22 @@ ARCHITECTURE Behavioral OF moving_average_filter IS
TYPE sample_array IS ARRAY (0 TO FILTER_ORDER - 1) OF signed(TDATA_WIDTH - 1 DOWNTO 0); 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 samples : sample_array := (OTHERS => (OTHERS => '0'));
SIGNAL sum : signed(TDATA_WIDTH + FILTER_ORDER_POWER - 1 DOWNTO 0) := (OTHERS => '0'); SIGNAL sum : signed(TDATA_WIDTH + FILTER_ORDER_POWER - 1 DOWNTO 0) := (OTHERS => '0');
SIGNAL sample_count : INTEGER RANGE 0 TO FILTER_ORDER := 0; SIGNAL wr_ptr : INTEGER RANGE 0 TO FILTER_ORDER - 1 := 0;
SIGNAL trigger : STD_LOGIC := '0'; -- Used to control when to send data
SIGNAL s_axis_tready_int : STD_LOGIC := '0';
SIGNAL s_axis_tlast_reg : STD_LOGIC := '0';
SIGNAL m_axis_tvalid_int : STD_LOGIC := '0'; SIGNAL m_axis_tvalid_int : STD_LOGIC := '0';
BEGIN BEGIN
-- Output assignments -- Output assignments
m_axis_tvalid <= m_axis_tvalid_int; m_axis_tvalid <= m_axis_tvalid_int;
s_axis_tready <= m_axis_tready OR NOT m_axis_tvalid_int; s_axis_tready <= s_axis_tready_int;
PROCESS (aclk) PROCESS (aclk)
VARIABLE new_sum : signed(TDATA_WIDTH + FILTER_ORDER_POWER - 1 DOWNTO 0);
VARIABLE oldest_sample : signed(TDATA_WIDTH - 1 DOWNTO 0);
VARIABLE avg : signed(TDATA_WIDTH - 1 DOWNTO 0);
VARIABLE wr_ptr : INTEGER RANGE 0 TO FILTER_ORDER - 1 := 0;
BEGIN BEGIN
IF rising_edge(aclk) THEN IF rising_edge(aclk) THEN
@@ -57,39 +54,52 @@ BEGIN
IF aresetn = '0' THEN IF aresetn = '0' THEN
samples <= (OTHERS => (OTHERS => '0')); samples <= (OTHERS => (OTHERS => '0'));
sum <= (OTHERS => '0'); sum <= (OTHERS => '0');
sample_count <= 0; wr_ptr <= 0;
trigger <= '0';
s_axis_tready_int <= '0';
m_axis_tvalid_int <= '0'; m_axis_tvalid_int <= '0';
m_axis_tlast <= '0'; m_axis_tlast <= '0';
m_axis_tdata <= (OTHERS => '0'); m_axis_tdata <= (OTHERS => '0');
wr_ptr := 0;
ELSE ELSE
m_axis_tvalid_int <= '0'; -- Set the ready signal for the slave interface
m_axis_tlast <= '0'; s_axis_tready_int <= m_axis_tready OR NOT m_axis_tvalid_int;
IF s_axis_tvalid = '1' AND (m_axis_tready = '1' OR m_axis_tvalid_int = '0') THEN -- Get and process input data
-- Circular buffer IF s_axis_tvalid = '1' AND s_axis_tready_int = '1' THEN
oldest_sample := samples(wr_ptr); -- Circular buffer overwrite oldest saple with the new one from next clk cycle
samples(wr_ptr) <= signed(s_axis_tdata); samples(wr_ptr) <= signed(s_axis_tdata);
wr_ptr := (wr_ptr + 1) MOD FILTER_ORDER;
-- Aggiorna la somma -- Update the write pointer
new_sum := sum - oldest_sample + signed(s_axis_tdata); wr_ptr <= (wr_ptr + 1) MOD FILTER_ORDER;
sum <= new_sum;
-- 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
-- Aggiorna il conteggio solo fino a 32
IF sample_count < FILTER_ORDER THEN
sample_count <= sample_count + 1;
END IF; END IF;
-- Calcola la media sempre su 32 (anche se sample_count < 32) -- Clear valid flag when master interface is ready
avg := new_sum(TDATA_WIDTH + FILTER_ORDER_POWER - 1 DOWNTO FILTER_ORDER_POWER); IF m_axis_tready = '1' THEN
m_axis_tvalid_int <= '0';
END IF;
m_axis_tdata <= STD_LOGIC_VECTOR(avg); -- 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_tvalid_int <= '1';
m_axis_tlast <= s_axis_tlast; 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';
END IF; END IF;
END IF; END IF;
END IF; END IF;