summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Nordby <jononor@gmail.com>2025-08-08 23:41:07 +0200
committerJon Nordby <jononor@gmail.com>2025-08-08 23:41:07 +0200
commit5fcbeb9f3d64a5022c81445f5f5052f04a728e6c (patch)
treed0fd983e9b84957de9d28408bf26d2788ba4d1c8
parent3d3727b275ac7b40c31f0791b8a77def77021fb9 (diff)
pdm: Try to bring back alpha setting for DC removal
-rw-r--r--bindings/sim_cic3_pdm.cc2
-rw-r--r--bindings/test_galearn_pdm.py6
-rw-r--r--cocotb_try/cic3_pdm.v30
3 files changed, 27 insertions, 11 deletions
diff --git a/bindings/sim_cic3_pdm.cc b/bindings/sim_cic3_pdm.cc
index 4b8ae64..80b5737 100644
--- a/bindings/sim_cic3_pdm.cc
+++ b/bindings/sim_cic3_pdm.cc
@@ -15,7 +15,7 @@ pdm2pcm_cic3(const uint8_t *pdm, int64_t pdm_length, int16_t *pcm, int32_t pcm_l
Vcic3_pdm *top = new Vcic3_pdm{cp};
- //top->hpf_alpha = hpf_alpha;
+ top->dc_alpha = hpf_alpha;
top->scale_shift = scale_shift;
// Start clock off
diff --git a/bindings/test_galearn_pdm.py b/bindings/test_galearn_pdm.py
index 0834f8e..7975c34 100644
--- a/bindings/test_galearn_pdm.py
+++ b/bindings/test_galearn_pdm.py
@@ -76,8 +76,8 @@ def test_sine_simple(frequency):
out = numpy.zeros(shape=len(pdm_input)//DECIMATION, dtype=numpy.int16)
# Process using filter
- n_samples = galearn_pdm.process(pdm_input, out, 255, 1)
- out = out / (2**15)
+ n_samples = galearn_pdm.process(pdm_input, out, 0, 0)
+ out = out / (2**12)
# Compensate for delay through filter
delay = find_forward_shift(pcm_input, out)
@@ -137,7 +137,7 @@ def test_dc():
out = numpy.zeros(shape=len(pdm_input)//DECIMATION, dtype=numpy.int16)
# Process using filter
- n_samples = galearn_pdm.process(pdm_input, out, 50, 0)
+ n_samples = galearn_pdm.process(pdm_input, out, 100, 0)
out = out / (2**12)
# Compensate for delay through filter
diff --git a/cocotb_try/cic3_pdm.v b/cocotb_try/cic3_pdm.v
index adcc74e..0d7ba18 100644
--- a/cocotb_try/cic3_pdm.v
+++ b/cocotb_try/cic3_pdm.v
@@ -4,6 +4,7 @@ module cic3_pdm (
input wire pdm_in, // 1-bit PDM data input
input wire [2:0] scale_shift, // Right shift amount (0-7 bits)
+ input wire [7:0] dc_alpha, // DC removal alpha (0=bypass, 255=strong removal)
output reg signed [15:0] pcm_out, // Decimated PCM output
output reg pcm_valid // Output valid pulse
);
@@ -27,6 +28,10 @@ module cic3_pdm (
// DC removal filter registers
reg signed [19:0] dc_accumulator; // 20-bit to prevent overflow
reg signed [15:0] dc_estimate;
+ /* verilator lint_off UNUSEDSIGNAL */
+ // Lower 8 bits of alpha_mult unused - we only need [23:8] for division by 256
+ reg signed [23:0] alpha_mult; // For alpha multiplication
+ /* verilator lint_on UNUSEDSIGNAL */
wire signed [CIC_WIDTH-1:0] pdm_signed = pdm_in ? 17'sd1 : -17'sd1;
@@ -92,19 +97,30 @@ module cic3_pdm (
if (rst) begin
dc_accumulator <= 20'sd0;
dc_estimate <= 16'sd0;
+ alpha_mult <= 24'sd0;
pcm_out <= 0;
pcm_valid <= 0;
end else begin
pcm_valid <= 0;
if (cic_valid) begin
- // Update DC estimate using leaky integrator
- // acc = acc - acc/16 + scaled_out
- dc_estimate <= dc_accumulator[19:4]; // Divide by 16
- dc_accumulator <= dc_accumulator - {{4{dc_estimate[15]}}, dc_estimate} + {{4{scaled_out[15]}}, scaled_out};
-
- // Output is scaled CIC output minus DC estimate
- pcm_out <= scaled_out - dc_estimate;
+ // Configurable DC removal using alpha parameter
+ // If dc_alpha = 0, bypass DC removal
+ // If dc_alpha = 255, strong DC removal (original /16 behavior)
+ if (dc_alpha == 8'd0) begin
+ // Bypass DC removal
+ pcm_out <= scaled_out;
+ end else begin
+ // Calculate alpha * dc_estimate / 256
+ alpha_mult <= dc_estimate * dc_alpha;
+ dc_estimate <= dc_accumulator[19:4]; // Current estimate
+
+ // Leaky integrator: acc = acc - (alpha/256)*acc + scaled_out
+ dc_accumulator <= dc_accumulator - {{4{alpha_mult[23]}}, alpha_mult[23:8]} + {{4{scaled_out[15]}}, scaled_out};
+
+ // Output with DC removal
+ pcm_out <= scaled_out - dc_estimate;
+ end
pcm_valid <= 1;
end
end