diff options
-rw-r--r-- | bindings/sim_cic3_pdm.cc | 2 | ||||
-rw-r--r-- | bindings/test_galearn_pdm.py | 2 | ||||
-rw-r--r-- | cocotb_try/cic3_pdm.v | 63 |
3 files changed, 22 insertions, 45 deletions
diff --git a/bindings/sim_cic3_pdm.cc b/bindings/sim_cic3_pdm.cc index 982581f..4b8ae64 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->hpf_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 6274868..0834f8e 100644 --- a/bindings/test_galearn_pdm.py +++ b/bindings/test_galearn_pdm.py @@ -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, 128, 5) + n_samples = galearn_pdm.process(pdm_input, out, 50, 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 c53e867..adcc74e 100644 --- a/cocotb_try/cic3_pdm.v +++ b/cocotb_try/cic3_pdm.v @@ -2,12 +2,11 @@ module cic3_pdm ( input wire clk, // PDM clock input wire rst, // active-high synchronous reset input wire pdm_in, // 1-bit PDM data input - input wire [7:0] hpf_alpha, // HPF coefficient (0-255, 255=bypass) + input wire [2:0] scale_shift, // Right shift amount (0-7 bits) output reg signed [15:0] pcm_out, // Decimated PCM output output reg pcm_valid // Output valid pulse ); - // CIC filter parameters localparam DECIMATION = 64; localparam CIC_WIDTH = 17; // 17 bits for safe margin against overflow @@ -25,23 +24,10 @@ module cic3_pdm ( reg signed [15:0] scaled_out; reg cic_valid; - // Leaky integrator HPF registers - reg signed [23:0] hpf_integrator; // 24-bit for precision - reg signed [15:0] hpf_output; - - // HPF calculation wires - wire signed [8:0] hpf_complement; - wire signed [23:0] hpf_scaled_input; - wire signed [23:0] hpf_dc_estimate; - /* verilator lint_off UNUSEDSIGNAL */ - wire signed [23:0] hpf_temp_result; - /* verilator lint_on UNUSEDSIGNAL */ + // DC removal filter registers + reg signed [19:0] dc_accumulator; // 20-bit to prevent overflow + reg signed [15:0] dc_estimate; - // HPF wire assignments - assign hpf_complement = 9'd256 - {1'b0, hpf_alpha}; - assign hpf_scaled_input = {{8{scaled_out[15]}}, scaled_out}; - assign hpf_dc_estimate = hpf_integrator >>> 8; - assign hpf_temp_result = hpf_scaled_input - hpf_dc_estimate; wire signed [CIC_WIDTH-1:0] pdm_signed = pdm_in ? 17'sd1 : -17'sd1; // CIC Integrator stages (run at PDM rate) @@ -92,44 +78,35 @@ module cic3_pdm ( case (scale_shift) 3'd0: scaled_out = cic_out[15:0]; 3'd1: scaled_out = cic_out[16:1]; - 3'd2: scaled_out = {{1{cic_out[16]}}, cic_out[16:2]}; // Sign extend from bit 16 - 3'd3: scaled_out = {{2{cic_out[16]}}, cic_out[16:3]}; // Sign extend from bit 16 - 3'd4: scaled_out = {{3{cic_out[16]}}, cic_out[16:4]}; // Sign extend from bit 16 - 3'd5: scaled_out = {{4{cic_out[16]}}, cic_out[16:5]}; // Sign extend from bit 16 - 3'd6: scaled_out = {{5{cic_out[16]}}, cic_out[16:6]}; // Sign extend from bit 16 - 3'd7: scaled_out = {{6{cic_out[16]}}, cic_out[16:7]}; // Sign extend from bit 16 + 3'd2: scaled_out = {{1{cic_out[16]}}, cic_out[16:2]}; + 3'd3: scaled_out = {{2{cic_out[16]}}, cic_out[16:3]}; + 3'd4: scaled_out = {{3{cic_out[16]}}, cic_out[16:4]}; + 3'd5: scaled_out = {{4{cic_out[16]}}, cic_out[16:5]}; + 3'd6: scaled_out = {{5{cic_out[16]}}, cic_out[16:6]}; + 3'd7: scaled_out = {{6{cic_out[16]}}, cic_out[16:7]}; endcase end - // Leaky integrator-based DC blocker - // y[n] = x[n] - dc_estimate - // dc_estimate[n] = alpha/256 * dc_estimate[n-1] + (1-alpha/256) * x[n] + // DC removal filter - runs at decimated rate always @(posedge clk) begin if (rst) begin - hpf_integrator <= 0; - hpf_output <= 0; + dc_accumulator <= 20'sd0; + dc_estimate <= 16'sd0; pcm_out <= 0; pcm_valid <= 0; end else begin pcm_valid <= 0; if (cic_valid) begin - if (hpf_alpha == 8'd255) begin - // Bypass HPF completely - pcm_out <= scaled_out; - end else begin - // Update leaky integrator (DC estimate) - // integrator = alpha * integrator + (256-alpha) * input - hpf_integrator <= (hpf_alpha * hpf_dc_estimate) + - (hpf_complement * hpf_scaled_input); - - // Output = input - DC estimate - hpf_output <= hpf_temp_result[15:0]; - pcm_out <= hpf_output; - end + // 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; pcm_valid <= 1; end end end - endmodule |