summaryrefslogtreecommitdiff
path: root/cocotb_try/cic3_pdm.v
diff options
context:
space:
mode:
Diffstat (limited to 'cocotb_try/cic3_pdm.v')
-rw-r--r--cocotb_try/cic3_pdm.v68
1 files changed, 68 insertions, 0 deletions
diff --git a/cocotb_try/cic3_pdm.v b/cocotb_try/cic3_pdm.v
new file mode 100644
index 0000000..f572d64
--- /dev/null
+++ b/cocotb_try/cic3_pdm.v
@@ -0,0 +1,68 @@
+
+// XXX: A chatbot wrote this, might be complete crack
+
+module cic3_pdm (
+ input wire clk, // PDM clock
+ input wire rst, // active-high synchronous reset
+ input wire pdm_in, // 1-bit PDM data input
+ output wire signed [15:0] pcm_out, // Decimated PCM output
+ output wire pcm_valid // High when pcm_out is valid
+);
+ parameter DECIMATION = 64; // Decimation factor
+
+ // Internal registers
+ reg signed [31:0] integrator_0 = 0;
+ reg signed [31:0] integrator_1 = 0;
+ reg signed [31:0] integrator_2 = 0;
+
+ reg [5:0] decim_counter = 0;
+ reg signed [31:0] comb_0 = 0, comb_1 = 0, comb_2 = 0;
+ reg signed [31: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)
+ always @(posedge clk) begin
+ if (rst) begin
+ integrator_0 <= 0;
+ integrator_1 <= 0;
+ integrator_2 <= 0;
+ end else begin
+ integrator_0 <= integrator_0 + (pdm_in ? 1 : -1);
+ integrator_1 <= integrator_1 + integrator_0;
+ integrator_2 <= integrator_2 + integrator_1;
+ end
+ end
+
+ // Decimation counter
+ always @(posedge clk) begin
+ if (rst)
+ decim_counter <= 0;
+ else
+ decim_counter <= decim_counter + 1;
+ end
+
+ // Comb stage (runs every DECIMATION clocks)
+ always @(posedge clk) begin
+ pcm_valid_r <= 0;
+ if (decim_counter == DECIMATION[5:0] - 1) 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;
+
+ // Bit-shift down to get 16-bit output (tune shift based on DECIMATION and stage count)
+ pcm_out_r <= comb_2[31:16];
+ pcm_valid_r <= 1;
+ end
+ end
+
+ assign pcm_out = pcm_out_r;
+ assign pcm_valid = pcm_valid_r;
+
+endmodule