This directory contains comprehensive tests for the 4-point FFT engine using cocotb for simulation.
The test suite is organized by module:
butterfly_unit/- Tests for the butterfly computation unitfft_engine/- Tests for the complete FFT engine coreio_ctrl/- Tests for input/output control logicmemory_ctrl/- Tests for sample memory managementtop_fft/- Full system integration tests
Install required Python packages:
pip install -r requirements.txtThe Makefile provides specific targets for each test module:
# Individual module tests
make test-butterfly # Test butterfly computation units
make test-fft-engine # Test core FFT engine
make test-memory # Test memory controller
make test-io # Test I/O controller
make test-top # Test complete system
# Run all tests sequentially
make all
# Clean build artifacts
make cleanAfter synthesis, test with the gate-level netlist:
make test-top GATES=yesTest File: test_butterfly.py
-
test_neg1_twiddle(TEST_ID=1)- Purpose: Test butterfly with twiddle factor = -1
- Inputs: Various A, B values with W = (-1, 0)
- Verification: Complex multiplication and addition/subtraction accuracy
-
test_negj_twiddle(TEST_ID=2)- Purpose: Test butterfly with twiddle factor = -j
- Inputs: Various A, B values with W = (0, -1)
- Verification: 90-degree phase rotation accuracy
-
test_basic_butterfly(TEST_ID=3)- Purpose: Fundamental butterfly operation validation
- Inputs: Known A, B values with W = (1, 0)
- Verification: Basic add/subtract operations without twiddle effects
-
test_simple_multiply(TEST_ID=4)- Purpose: Complex multiplication verification
- Inputs: Simple multiplicand pairs
- Verification: Product calculation and scaling accuracy
-
test_rand_twiddle(TEST_ID=5)- Purpose: Randomized butterfly testing
- Inputs: Random A, B, W values
- Verification: Statistical validation against reference model
Key Verifications:
- 8-bit signed arithmetic accuracy
- Overflow handling and saturation
- Scaling (right shift by 7 bits)
- Complex multiplication correctness
Test File: test_fft_engine.py
Tests the complete 4-point FFT algorithm implementation with various input patterns to verify frequency domain accuracy.
Test File: test_memory_ctrl.py
- Read/Write Validity: Write known data, read back for verification
- Initial Zero State: Verify memory initializes to zero
- Address Alignment: Test correct addressing for 4 sample locations
- Reset Behavior: Ensure clean state after reset
Test File: test_io_ctrl.py
- Button Press Detection: Verify switch input recognition
- Load Pulse Generation: Test sample loading control signals
- Output Pulse Timing: Verify result output sequencing
- Address Counter: Test 4-step address generation (0→1→2→3)
Test File: test_top_fft.py
-
test_reset_and_initial_state(TEST_ID=1)- Purpose: Verify proper system initialization
- Verification: All registers start at zero, uio_oe low after reset
-
test_full_cycle_complex(TEST_ID=2)- Purpose: End-to-end test with complex input values
- Inputs:
[(16, 32), (-48, -64), (80, -96), (-112, 112)] - Verification: 20-cycle time, output matches reference FFT
-
test_fft_impulse(TEST_ID=3)- Purpose: Impulse response validation
- Inputs:
[(16, 0), (0, 0), (0, 0), (0, 0)](unit impulse) - Expected: Flat frequency response across all bins
- Verification: System frequency characteristics
-
test_fft_dc_input(TEST_ID=4)- Purpose: DC (constant) input validation
- Inputs:
[(16, 0), (16, 0), (16, 0), (16, 0)](constant value) - Expected: Energy only in DC bin (bin 0), other bins ≈ 0
- Verification: Zero-frequency response isolation
-
test_randomized_end_to_end(TEST_ID=5)- Purpose: Stress testing with random inputs
- Inputs: 5 iterations of random complex values
- Range: Values from -128 to 127 in steps of 16
- Verification: Statistical validation against Python reference model
- Clock Frequency: 50 MHz operation
- I/O Timing: Proper setup/hold for bidirectional pins
Each test validates cycle-accurate timing:
- Load 4 samples (4 cycles)
- Output 4 results (4 cycles)
- Total: ~20 cycles end-to-end
All tests include bit-accurate Python models that replicate the hardware behavior, in order to check against randomized test input vectors.
def fft_engine_ref_model(in0, in1, in2, in3):
# Implements exact same algorithm as hardware
# Including 8-bit quantization and overflow behavior
# Returns expected hardware outputs- Input Generation: Create test vectors with known outputs
- Hardware Simulation: Run through RTL simulation
- Bit-Exact Comparison: Match reference model output exactly
- Error Reporting: Detailed mismatch analysis with hex values
Each test generates timestamped VCD files in module-specific wave directories:
# View waveforms with GTKWave
gtkwave butterfly_unit/wave/butterfly_tb_YYYYMMDD_HH:MM:SS.vcd
# Or use Surfer
surfer top_fft/wave/tt_um_FFT_engine_tb_YYYYMMDD_HH:MM:SS.vcdTest results show:
- PASS/FAIL status for each test case
- Detailed timing information
- Input/output values in hex format
- Reference model comparisons
- Error diagnostics for failures
- Timing Issues: Check VCD for 20-cycle processing constraint
- Data Mismatch: Compare hex values between DUT and reference
- Control Logic: Verify switch inputs and uio_oe behavior
- Overflow: Monitor butterfly scaling and saturation
- Reset Problems: Ensure proper initialization sequence
- Processing Cycles: 20 clock cycles from input to valid output
- Test Duration: Each test runs for sufficient cycles to capture full operation