How it works
Disclaimer, this "How it works" section is generated by AI based on the code comments, and manually checked.
This project implements two CIC (Cascaded Integrator-Comb) filters designed for processing sigma-delta modulator bitstreams. The design features both first-order and second-order CIC filters with comprehensive debugging capabilities.
Normal Operation
The CIC filter takes a sigma-delta modulator bitstream as input and decimates it to produce a lower sample rate digital output. The module includes two different CIC implementations:
- First Order CIC Filter: Uses a 10-bit register width with decimation factor of 10
- Second Order CIC Filter: Uses a 20-bit register width with decimation factor of 10
Input Signals (ui_in)
- ui_in[0]: Modulator data input - the sigma-delta bitstream to be filtered
- ui_in[1]: CIC filter select - selects between first-order (0) and second-order (1) CIC filters
- ui_in[2]: UIO input mode for testing - when high, allows uio pins to be used as inputs for debugging
- ui_in[3]: Reserved for future use
- ui_in[7:4]: Debug select - 4-bit selector providing 16 different debug modes per filter
Output Signals
- uo_out[7:0]: Dedicated outputs - provides filtered data or debug information based on debug select
- uio_out[7:0]: Bidirectional IOs used as outputs - provides additional debug information
- uio_oe[7:0]: IO enable signals - controls direction of uio pins (normally all outputs except in a specific test mode)
Debug System Overview
The debug system is intelligently split based on the CIC filter selection (ui_in[1]):
First Order CIC Debug Modes (ui_in[1] = 0)
When the first-order CIC is selected, the debug modes focus on its internal signals:
- 0x0: CIC1 output data - MSB on uo_out, LSB + clock on uio_out
- 0x1: CIC1 integrator output - MSB on uo_out, LSB + clock on uio_out
- 0x2: CIC1 comb output - MSB on uo_out, LSB + clock on uio_out
- 0x3: Input monitoring - displays ui_in values on both outputs
- 0x4: IO monitoring - displays uio_in on uo_out when in input test mode
- 0x5: Status and control signals - shows rst_n, clk, ena, and cic_output_clk
- 0x8: CIC1 output data LSB - focuses on least significant bits with clock
- 0x9: CIC1 integrator LSB - integrator LSB with clock
- 0xA: CIC1 comb LSB - comb LSB with clock
- 0xB: CIC1 decimation counter - MSBs on uo_out, LSBs + clock on uio_out
- 0x6-0x7, 0xC-0xE: Reserved for future CIC1 debug options
- 0xF: Reserved (0x4B on uo_out, 0x00 on uio_out)
Second Order CIC Debug Modes (ui_in[1] = 1)
When the second-order CIC is selected, the debug modes provide access to its more complex internal state:
- 0x0: CIC2 output data MSB - top 8 bits on uo_out, middle bits + clock on uio_out
- 0x1: CIC2 output data LSB - bits [14:7] on uo_out, bits [6:0] + clock on uio_out
- 0x2: CIC2 integrator1 MSB - first integrator stage MSB + middle bits
- 0x3: CIC2 integrator1 LSB - first integrator stage LSB
- 0x4: CIC2 integrator2 MSB - second integrator stage MSB + middle bits
- 0x5: CIC2 integrator2 LSB - second integrator stage LSB
- 0x6: CIC2 comb1 MSB - first comb stage MSB + middle bits
- 0x7: CIC2 comb1 LSB - first comb stage LSB
- 0x8: CIC2 comb2 MSB - second comb stage MSB + middle bits
- 0x9: CIC2 comb2 LSB - second comb stage LSB
- 0xB: CIC2 decimation counter - MSBs on uo_out, LSBs + clock on uio_out
- 0xA: Reserved for future CIC2 debug options
- 0xC: Reserved (0x4C on uo_out, 0x00 on uio_out)
- 0xD: Reserved (0x69 on uo_out, 0x00 on uio_out)
- 0xE: Reserved (0x6D on uo_out, 0x00 on uio_out)
- 0xF: Reserved (0x65 on uo_out, 0x00 on uio_out)
Filter Architecture
Both CIC filters implement the classic integrator-comb architecture:
- Integrator stages run at the high input sample rate and accumulate the input signal
- Decimation reduces the sample rate by the decimation factor (10)
- Comb stages run at the decimated rate and implement the differentiator function
The first-order CIC has one integrator and one comb stage, while the second-order CIC has two of each, providing better filtering characteristics at the cost of increased bit width requirements.
The filtered output represents the average value of the sigma-delta bitstream over the decimation period, effectively converting the 1-bit high-rate stream into a multi-bit lower-rate digital signal.
How to test
This section I will provide a test plan.
Test 1: Smoke test, bringup
- set 'hF0 on the input, 'h4b will appear on the output
Test 2: Clipping test.
- set 'h01 on the input and let the clock running with reset released
- uo_out will become 'hFF, two MSB's of uoi_out will become 1
- set 'h00 on the input and let the clock running with reset released
- all bits mentioned above will become 0.
Test 3: Static input.
- put a PWM on the input, of which the frequency is higher than f_clk/1024, but lower than f_clk.
- Output will take value between min and max proportional to the duty cycle.
Test 4: Sinewave input.
TBD
External hardware
No external hardware needed.