Lab 3: Audio Processing System #3

Merged
PickleRick merged 43 commits from LAB3 into main 2025-06-07 22:18:48 +02:00
Showing only changes of commit 2968db7e3f - Show all commits

View File

@@ -43,7 +43,8 @@ ARCHITECTURE Behavioral OF led_level_controller IS
-- Audio amplitude storage for both stereo channels
-- Stores absolute values (magnitude) of left and right audio channels
SIGNAL abs_l, abs_r : UNSIGNED(CHANNEL_LENGHT - 1 DOWNTO 0) := (OTHERS => '0'); -- Absolute amplitude registers
SIGNAL abs_l : UNSIGNED(CHANNEL_LENGHT - 1 DOWNTO 0) := (OTHERS => '0'); -- Absolute left channel amplitude registers
SIGNAL combined_amp : UNSIGNED(CHANNEL_LENGHT - 1 DOWNTO 0) := (OTHERS => '0'); -- Combined amplitude for LED level calculation
BEGIN
@@ -52,9 +53,6 @@ BEGIN
-- Capture absolute value of input sample for left/right channel
PROCESS (aclk)
VARIABLE signed_sample : SIGNED(CHANNEL_LENGHT - 1 DOWNTO 0);
BEGIN
IF rising_edge(aclk) THEN
@@ -62,20 +60,24 @@ BEGIN
IF aresetn = '0' THEN
-- Reset: Clear both channel amplitude registers
abs_l <= (OTHERS => '0');
abs_r <= (OTHERS => '0');
combined_amp <= (OTHERS => '0');
ELSIF s_axis_tvalid = '1' THEN
-- Valid audio data received: Process the sample
signed_sample := SIGNED(s_axis_tdata); -- Convert input to signed for ABS operation
-- Channel routing based on AXI4-Stream tlast signal
-- tlast = '1' indicates left channel, tlast = '0' indicates right channel
-- tlast = '1' indicates right channel, tlast = '0' indicates left channel
IF s_axis_tlast = '1' THEN
-- Left channel: Store absolute value of audio sample
abs_l <= UNSIGNED(ABS(signed_sample));
-- Right channel: Combine left and right channel amplitudes
-- RESIZE ensures the sum fits within the variable's bit width.
-- There isn't data loss since both abs_l and abs(s_axis_tdata) are one bit shorter than combined_amp,
-- due to the absolute value operation.
combined_amp <= RESIZE(abs_l + UNSIGNED(ABS(SIGNED(s_axis_tdata))), combined_amp'LENGTH);
ELSE
-- Right channel: Store absolute value of audio sample
abs_r <= UNSIGNED(ABS(signed_sample));
-- Left channel: Store absolute value of audio sample
abs_l <= UNSIGNED(ABS(SIGNED(s_axis_tdata)));
END IF;
END IF;
@@ -117,7 +119,6 @@ BEGIN
-- Updates only when refresh_tick is active to maintain stable visual display
PROCESS (aclk)
VARIABLE combined_amp : UNSIGNED(CHANNEL_LENGHT - 1 DOWNTO 0);
VARIABLE led_level : INTEGER RANGE 0 TO 2 ** NUMLEDS_BITS := 0;
BEGIN
@@ -131,29 +132,28 @@ BEGIN
ELSIF refresh_tick = '1' THEN
-- LED update cycle: Calculate new LED pattern based on audio amplitude
-- Combine left and right channel amplitudes
-- RESIZE ensures the sum fits within the variable's bit width.
-- There isn't data loss since both abs_l and abs_r are one bit shorter than combined_amp,
-- due to the absolute value operation.
combined_amp := RESIZE(abs_l + abs_r, combined_amp'LENGTH);
-- Linear scale to LED level conversion to get the best visual effect
IF combined_amp = 0 THEN
led_level := 0; -- No audio signal, turn off all LEDs
ELSE
led_level := 1 + to_integer(shift_right(combined_amp, CHANNEL_LENGHT - NUMLEDS_BITS));
END IF;
-- Saturation protection: Limit LED level to maximum available LEDs
-- Prevents overflow and ensures the LED index stays within bounds.
IF led_level > NUM_LEDS THEN
led_level := NUM_LEDS;
END IF;
-- Update LED output based on calculated level
led <= (OTHERS => '0');
IF led_level > 0 THEN
led(led_level - 1 DOWNTO 0) <= (OTHERS => '1');
END IF;
END IF;