summaryrefslogtreecommitdiff
path: root/cocotb_try
diff options
context:
space:
mode:
authorJon Nordby <jononor@gmail.com>2025-04-26 18:13:37 +0200
committerJon Nordby <jononor@gmail.com>2025-04-26 21:33:29 +0200
commitb9d821cb5409a545431d7b34d8df0ad493c26a46 (patch)
tree7e196adc6e8e1548c6643c5e4c25e4fc0259bfd3 /cocotb_try
parentb2b664b2596b48048ba97c5b43f3f29345c6bdb3 (diff)
cocotb: Try to test a CIC filter
Diffstat (limited to 'cocotb_try')
-rw-r--r--cocotb_try/Makefile6
-rw-r--r--cocotb_try/cic3_pdm.v68
-rw-r--r--cocotb_try/test_cic.py32
3 files changed, 103 insertions, 3 deletions
diff --git a/cocotb_try/Makefile b/cocotb_try/Makefile
index 2d4fe2b..6612173 100644
--- a/cocotb_try/Makefile
+++ b/cocotb_try/Makefile
@@ -4,14 +4,14 @@
SIM ?= verilator
TOPLEVEL_LANG ?= verilog
-VERILOG_SOURCES += $(PWD)/my_design.v
+VERILOG_SOURCES += $(PWD)/cic3_pdm.v
# use VHDL_SOURCES for VHDL files
# TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file
-TOPLEVEL = my_design
+TOPLEVEL = cic3_pdm
# MODULE is the basename of the Python test file
-MODULE = test_my_design
+MODULE = test_cic
# include cocotb's make rules to take care of the simulator setup
include $(shell cocotb-config --makefiles)/Makefile.sim
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
diff --git a/cocotb_try/test_cic.py b/cocotb_try/test_cic.py
new file mode 100644
index 0000000..3a4e385
--- /dev/null
+++ b/cocotb_try/test_cic.py
@@ -0,0 +1,32 @@
+
+# https://docs.cocotb.org/en/stable/quickstart.html
+# test_my_design.py (extended)
+
+import cocotb
+from cocotb.triggers import FallingEdge, Timer
+
+
+async def generate_clock(dut):
+ """Generate clock pulses."""
+
+ for cycle in range(10):
+ dut.clk.value = 0
+ await Timer(1, units="ns")
+ dut.clk.value = 1
+ await Timer(1, units="ns")
+
+
+@cocotb.test()
+async def my_second_test(dut):
+ """Try accessing the design."""
+
+ await cocotb.start(generate_clock(dut)) # run the clock "in the background"
+
+ await Timer(5, units="ns") # wait a bit
+ await FallingEdge(dut.clk) # wait for falling edge/"negedge"
+
+ dut._log.info("my_signal_1 is %s", dut.my_signal_1.value)
+ assert dut.my_signal_2.value[0] == 0, "my_signal_2[0] is not 0!"
+
+
+