- comments
- new DELAY_CLK_CYCLES formula
This commit is contained in:
2025-05-28 18:06:01 +02:00
parent 82d76e48d8
commit 92cf8aa5ec
7 changed files with 36 additions and 45 deletions

View File

@@ -1,15 +1,12 @@
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;
-- Entity: LFO (Low Frequency Oscillator) - Alternative Implementation
-- Entity: LFO_1 (Low Frequency Oscillator) - Alternative Implementation
-- Purpose: Applies tremolo effect to audio by modulating amplitude with a triangular wave
-- This is a simplified, single-process implementation compared to the pipelined version
-- Provides real-time audio amplitude modulation for musical effects
ENTITY LFO IS
ENTITY LFO_1 IS
GENERIC (
CHANNEL_LENGHT : INTEGER := 24; -- Bit width of audio samples (24-bit signed)
JOYSTICK_LENGHT : INTEGER := 10; -- Bit width of joystick input (10-bit = 0-1023 range)
@@ -21,9 +18,9 @@ ENTITY LFO IS
aclk : IN STD_LOGIC; -- Main system clock
aresetn : IN STD_LOGIC; -- Active-low asynchronous reset
-- LFO Control inputs
lfo_period : IN STD_LOGIC_VECTOR(JOYSTICK_LENGHT - 1 DOWNTO 0); -- Controls LFO frequency (joystick Y-axis)
lfo_enable : IN STD_LOGIC; -- Enable/bypass LFO effect
-- LFO_1 Control inputs
lfo_period : IN STD_LOGIC_VECTOR(JOYSTICK_LENGHT - 1 DOWNTO 0); -- Controls LFO_1 frequency (joystick Y-axis)
lfo_enable : IN STD_LOGIC; -- Enable/bypass LFO_1 effect
-- Slave AXI Stream interface (audio input)
s_axis_tvalid : IN STD_LOGIC; -- Input data valid signal
@@ -37,26 +34,26 @@ ENTITY LFO IS
m_axis_tlast : OUT STD_LOGIC; -- Channel indicator passthrough
m_axis_tready : IN STD_LOGIC -- Downstream ready signal
);
END ENTITY LFO;
END ENTITY LFO_1;
ARCHITECTURE Behavioral OF LFO IS
ARCHITECTURE Behavioral OF LFO_1 IS
-- LFO timing configuration constants
CONSTANT LFO_COUNTER_BASE_PERIOD_US : INTEGER := 1000; -- Base period: 1ms (1kHz base frequency)
-- LFO_1 timing configuration constants
CONSTANT LFO_1_COUNTER_BASE_PERIOD_US : INTEGER := 1000; -- Base period: 1ms (1kHz base frequency)
CONSTANT ADJUSTMENT_FACTOR : INTEGER := 90; -- Frequency adjustment sensitivity (clock cycles per joystick unit)
CONSTANT JSTK_CENTER_VALUE : INTEGER := 2 ** (JOYSTICK_LENGHT - 1); -- Joystick center position (512 for 10-bit)
-- Calculate base clock cycles for 1ms period at current clock frequency
CONSTANT LFO_COUNTER_BASE_CLK_CYCLES : INTEGER := LFO_COUNTER_BASE_PERIOD_US * 1000 / CLK_PERIOD_NS; -- 1ms = 100,000 clk cycles
CONSTANT LFO_1_COUNTER_BASE_CLK_CYCLES : INTEGER := LFO_1_COUNTER_BASE_PERIOD_US * 1000 / CLK_PERIOD_NS; -- 1ms = 100,000 clk cycles
-- Calculate frequency range limits based on joystick range
CONSTANT LFO_CLK_CYCLES_MIN : INTEGER := LFO_COUNTER_BASE_CLK_CYCLES - ADJUSTMENT_FACTOR * (2 ** (JOYSTICK_LENGHT - 1)); -- 53,920 clk cycles (faster)
CONSTANT LFO_CLK_CYCLES_MAX : INTEGER := LFO_COUNTER_BASE_CLK_CYCLES + ADJUSTMENT_FACTOR * (2 ** (JOYSTICK_LENGHT - 1) - 1); -- 145,990 clk cycles (slower)
CONSTANT LFO_1_CLK_CYCLES_MIN : INTEGER := LFO_1_COUNTER_BASE_CLK_CYCLES - ADJUSTMENT_FACTOR * (2 ** (JOYSTICK_LENGHT - 1)); -- 53,920 clk cycles (faster)
CONSTANT LFO_1_CLK_CYCLES_MAX : INTEGER := LFO_1_COUNTER_BASE_CLK_CYCLES + ADJUSTMENT_FACTOR * (2 ** (JOYSTICK_LENGHT - 1) - 1); -- 145,990 clk cycles (slower)
-- LFO timing control signals
-- LFO_1 timing control signals
SIGNAL step_clk_cycles_delta : INTEGER RANGE - 2 ** (JOYSTICK_LENGHT - 1) * ADJUSTMENT_FACTOR TO (2 ** (JOYSTICK_LENGHT - 1) - 1) * ADJUSTMENT_FACTOR := 0;
SIGNAL step_clk_cycles : INTEGER RANGE LFO_CLK_CYCLES_MIN TO LFO_CLK_CYCLES_MAX := LFO_COUNTER_BASE_CLK_CYCLES;
SIGNAL step_counter : NATURAL RANGE 0 TO LFO_CLK_CYCLES_MAX := 0;
SIGNAL step_clk_cycles : INTEGER RANGE LFO_1_CLK_CYCLES_MIN TO LFO_1_CLK_CYCLES_MAX := LFO_1_COUNTER_BASE_CLK_CYCLES;
SIGNAL step_counter : NATURAL RANGE 0 TO LFO_1_CLK_CYCLES_MAX := 0;
-- Triangular wave generation signals
-- Note: Using signed counter with extra bit to handle full range calculations
@@ -79,29 +76,29 @@ BEGIN
-- Input ready logic: Ready when downstream is ready OR no valid data pending, AND not in reset
s_axis_tready <= (m_axis_tready OR NOT m_axis_tvalid_int) AND aresetn;
-- Optimized single process for LFO timing and triangular waveform generation
-- Optimized single process for LFO_1 timing and triangular waveform generation
-- This process handles both the frequency control and wave shape generation
triangular_wave_lfo_generator : PROCESS (aclk)
BEGIN
IF rising_edge(aclk) THEN
IF aresetn = '0' THEN
-- Reset LFO generator to initial state
step_clk_cycles <= LFO_COUNTER_BASE_CLK_CYCLES; -- Set to base frequency
-- Reset LFO_1 generator to initial state
step_clk_cycles <= LFO_1_COUNTER_BASE_CLK_CYCLES; -- Set to base frequency
step_counter <= 0; -- Clear timing counter
tri_counter <= (OTHERS => '0'); -- Start triangular wave at zero
direction_up <= '1'; -- Start counting up
ELSE
-- Calculate LFO period based on joystick input
-- Calculate LFO_1 period based on joystick input
-- Joystick mapping:
-- 0-511: Faster than base frequency (shorter period, higher frequency)
-- 512: Base frequency (1kHz)
-- 513-1023: Slower than base frequency (longer period, lower frequency)
step_clk_cycles_delta <= (to_integer(unsigned(lfo_period)) - JSTK_CENTER_VALUE) * ADJUSTMENT_FACTOR;
step_clk_cycles <= LFO_COUNTER_BASE_CLK_CYCLES - step_clk_cycles_delta;
step_clk_cycles <= LFO_1_COUNTER_BASE_CLK_CYCLES - step_clk_cycles_delta;
-- Generate triangular wave when LFO is enabled
-- Generate triangular wave when LFO_1 is enabled
IF lfo_enable = '1' THEN
-- Clock divider: Update triangular wave at calculated rate
@@ -140,7 +137,7 @@ BEGIN
END PROCESS triangular_wave_lfo_generator;
-- AXI4-Stream handshake logic and audio processing
-- This process handles input/output data flow and applies the LFO modulation
-- This process handles input/output data flow and applies the LFO_1 modulation
AXIS : PROCESS (aclk)
BEGIN
IF rising_edge(aclk) THEN
@@ -183,15 +180,15 @@ BEGIN
-- Data input logic: Process new audio samples when available and output is ready
IF s_axis_tvalid = '1' AND (m_axis_tready = '1' OR m_axis_tvalid_int = '0') THEN
IF lfo_enable = '1' THEN
-- Apply LFO tremolo effect: multiply audio sample by triangular wave
-- Apply LFO_1 tremolo effect: multiply audio sample by triangular wave
-- This creates amplitude modulation (tremolo effect)
m_axis_tdata_temp <= signed(s_axis_tdata) * tri_counter;
s_axis_tlast_reg <= s_axis_tlast; -- Register channel indicator
ELSE
-- LFO disabled: pass audio through unchanged but maintain bit width
-- LFO_1 disabled: pass audio through unchanged but maintain bit width
-- Left shift compensates for the right shift that occurs during output
-- This ensures unity gain when LFO is bypassed
-- This ensures unity gain when LFO_1 is bypassed
m_axis_tdata_temp <= shift_left(
resize(
signed(s_axis_tdata), -- Convert input to signed
@@ -213,14 +210,14 @@ BEGIN
END PROCESS AXIS;
-- LFO Implementation Summary:
-- LFO_1 Implementation Summary:
-- 1. Generates triangular wave at frequency controlled by joystick input
-- 2. When enabled: multiplies audio samples by triangular wave (tremolo effect)
-- 3. When disabled: passes audio through unchanged (bypass mode)
-- 4. Uses proper AXI4-Stream handshaking for real-time audio processing
--
-- Tremolo Effect Characteristics:
-- - Frequency range: Approximately 0.1Hz to 10Hz (typical for audio LFO)
-- - Frequency range: Approximately 0.1Hz to 10Hz (typical for audio LFO_1)
-- - Modulation depth: Controlled by TRIANGULAR_COUNTER_LENGHT generic
-- - Waveform: Triangular (linear amplitude changes, smooth transitions)
-- - Bypass capability: Clean audio passthrough when disabled