summaryrefslogtreecommitdiff
path: root/cocotb_try
diff options
context:
space:
mode:
Diffstat (limited to 'cocotb_try')
-rw-r--r--cocotb_try/cic3_pdm.v185
1 files changed, 106 insertions, 79 deletions
diff --git a/cocotb_try/cic3_pdm.v b/cocotb_try/cic3_pdm.v
index fc5de46..4e8d664 100644
--- a/cocotb_try/cic3_pdm.v
+++ b/cocotb_try/cic3_pdm.v
@@ -1,100 +1,127 @@
-
-
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)
- output wire signed [15:0] pcm_out, // Decimated PCM output
- output wire pcm_valid
-
+ 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
);
- //parameter DECIMATION = 64; // Decimation factor
- parameter OUTPUT_SHIFT = 10; // Can tune this
-
- // Internal registers
- reg signed [38:0] integrator_0 = 0;
- reg signed [38:0] integrator_1 = 0;
- reg signed [38:0] integrator_2 = 0;
-
- reg [5:0] decim_counter = 0;
- reg signed [38:0] comb_0 = 0, comb_1 = 0;
-
- /* verilator lint_off UNUSEDSIGNAL */
- reg signed [38:0] comb_2 = 0;
+ // CIC filter parameters
+ localparam DECIMATION = 64;
+ localparam CIC_WIDTH = 17; // 17 bits for safe margin against overflow
+
+ // CIC integrator and comb stages
+ reg signed [CIC_WIDTH-1:0] integrator1, integrator2;
+ reg signed [CIC_WIDTH-1:0] comb1, comb2;
+ reg signed [CIC_WIDTH-1:0] comb1_d1, comb2_d1;
+
+ // Decimation counter
+ reg [6:0] decim_count; // 7 bits to match DECIMATION width
+
+ // CIC output and scaling
+ reg signed [CIC_WIDTH-1:0] cic_out;
+ reg signed [15:0] scaled_out;
+ reg cic_valid;
+
// HPF registers
- reg signed [15:0] hpf_prev = 0; // Previous input sample
- reg signed [15:0] cic_reg = 0; // Registered CIC output
- reg cic_valid = 0;
-
- // CIC output
- wire signed [15:0] cic_out = comb_2[OUTPUT_SHIFT + 15 : OUTPUT_SHIFT];
-
- reg signed [38:0] delay_0 = 0, delay_1 = 0, delay_2 = 0;
-
- reg signed [15:0] pcm_out_r = 0;
- reg pcm_valid_r = 0;
-
- // Integrator stage (runs every clk)
+ reg signed [15:0] hpf_x_prev;
+ reg signed [15:0] hpf_y_prev;
+
+ // HPF calculation wires
+ /* verilator lint_off UNUSEDSIGNAL */
+ wire signed [23:0] hpf_temp;
+ /* verilator lint_on UNUSEDSIGNAL */
+ wire signed [15:0] hpf_calc;
+
+ // Convert 1-bit PDM to signed
+ wire signed [CIC_WIDTH-1:0] pdm_signed = pdm_in ? 17'sd1 : -17'sd1;
+
+ // CIC Integrator stages (run at PDM rate)
always @(posedge clk) begin
if (rst) begin
- integrator_0 <= 0;
- integrator_1 <= 0;
- integrator_2 <= 0;
+ integrator1 <= 0;
+ integrator2 <= 0;
end else begin
- integrator_0 <= integrator_0 + (pdm_in ? 1 : -1);
- integrator_1 <= integrator_1 + integrator_0;
- integrator_2 <= integrator_2 + integrator_1;
+ integrator1 <= integrator1 + pdm_signed;
+ integrator2 <= integrator2 + integrator1;
end
end
-
- // Decimation counter
- always @(posedge clk) begin
- if (rst)
- decim_counter <= 0;
- else
- decim_counter <= decim_counter + 1;
- end
-
- // Comb stage
+
+ // Decimation counter and CIC comb stages
always @(posedge clk) begin
- cic_valid <= 0;
if (rst) begin
- cic_reg <= 0;
- end else if (decim_counter == 63) begin
- comb_0 <= integrator_2 - delay_0;
- delay_0 <= integrator_2;
- comb_1 <= comb_0 - delay_1;
- delay_1 <= comb_0;
- comb_2 <= comb_1 - delay_2;
- delay_2 <= comb_1;
- end else if (decim_counter == 0) begin
- // CIC output is now stable, register it
- cic_reg <= cic_out;
- cic_valid <= 1;
+ decim_count <= 0;
+ comb1 <= 0;
+ comb2 <= 0;
+ comb1_d1 <= 0;
+ comb2_d1 <= 0;
+ cic_out <= 0;
+ cic_valid <= 0;
+ end else begin
+ cic_valid <= 0;
+
+ if (decim_count == DECIMATION - 1) begin
+ decim_count <= 0;
+
+ // Comb stage 1
+ comb1 <= integrator2 - comb1_d1;
+ comb1_d1 <= integrator2;
+
+ // Comb stage 2
+ comb2 <= comb1 - comb2_d1;
+ comb2_d1 <= comb1;
+
+ cic_out <= comb2;
+ cic_valid <= 1;
+ end else begin
+ decim_count <= decim_count + 1;
+ end
end
end
- // HPF stage (runs after CIC settles)
+ // Output scaling
+ always @(*) begin
+ 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
+ endcase
+ end
+
+ // HPF calculation
+ assign hpf_temp = ((hpf_alpha * hpf_y_prev) + (({8'd0, scaled_out} - {8'd0, hpf_x_prev}) << 8)) >>> 8;
+ assign hpf_calc = hpf_temp[15:0];
+
+ // High-pass filter (1st order IIR: y[n] = alpha/256 * y[n-1] + (x[n] - x[n-1]))
always @(posedge clk) begin
- pcm_valid_r <= 0;
if (rst) begin
- hpf_prev <= 0;
- pcm_out_r <= 0;
- end else if (cic_valid) begin
- if (hpf_alpha == 8'd255) begin
- pcm_out_r <= cic_reg;
- end else begin
- // HPF: y[n] = x[n] - x[n-1] + alpha*y[n-1]
- pcm_out_r <= cic_reg - hpf_prev + ((pcm_out_r * hpf_alpha) >>> 8);
+ hpf_x_prev <= 0;
+ hpf_y_prev <= 0;
+ 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
+ // HPF computation: y[n] = alpha/256 * y[n-1] + (x[n] - x[n-1])
+ pcm_out <= hpf_calc;
+ hpf_x_prev <= scaled_out;
+ hpf_y_prev <= hpf_calc;
+ end
+ pcm_valid <= 1;
end
- hpf_prev <= cic_reg;
- pcm_valid_r <= 1;
end
end
- assign pcm_out = pcm_out_r;
- assign pcm_valid = pcm_valid_r;
-
endmodule