summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Nordby <jononor@gmail.com>2025-04-27 16:13:33 +0200
committerJon Nordby <jononor@gmail.com>2025-05-02 21:00:12 +0200
commit70818e9a7f83531270382900c54033f27e08c5f4 (patch)
treecb1070d0687af4d91b4d2b1b2207c1f3b719aef7
parentcb019a43f55e08aa4c12573270a32213c823e1cb (diff)
cocotb: Test and fix 1khz sine
-rw-r--r--cocotb_try/cic3_pdm.v5
-rw-r--r--cocotb_try/test_cic.py64
2 files changed, 45 insertions, 24 deletions
diff --git a/cocotb_try/cic3_pdm.v b/cocotb_try/cic3_pdm.v
index 1c8ba25..e350fda 100644
--- a/cocotb_try/cic3_pdm.v
+++ b/cocotb_try/cic3_pdm.v
@@ -7,10 +7,11 @@ module cic3_pdm (
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
- output reg pdm_out
+ output reg pdm_out
);
parameter DECIMATION = 64; // Decimation factor
+ parameter OUTPUT_SHIFT = 8; // Can tune this
// Internal registers
reg signed [31:0] integrator_0 = 0;
@@ -60,7 +61,7 @@ module cic3_pdm (
// Bit-shift down to get 16-bit output (tune shift based on DECIMATION and stage count)
pdm_out <= pdm_in;
- pcm_out_r <= comb_2[31:16];
+ pcm_out_r <= comb_2[OUTPUT_SHIFT + 15 : OUTPUT_SHIFT];
pcm_valid_r <= 1;
end
end
diff --git a/cocotb_try/test_cic.py b/cocotb_try/test_cic.py
index 19a17f9..ea176fc 100644
--- a/cocotb_try/test_cic.py
+++ b/cocotb_try/test_cic.py
@@ -5,46 +5,66 @@
import cocotb
from cocotb.triggers import FallingEdge, RisingEdge, Timer, with_timeout
from cocotb.clock import Clock
+from cocotb.binary import BinaryValue
+import numpy
-async def generate_clock(dut):
- """Generate clock pulses."""
+from pcm2pdm import convert
+from testsignal import generate_test_tone
+from test_pdm import plot_reconstruct
- for cycle in range(10):
- dut.clk.value = 0
- await Timer(1, units="ns")
- dut.clk.value = 1
- await Timer(1, units="ns")
async def drive_waveform(dut, waveform):
+
+ high_delay = Timer(1, units="ns")
+ low_delay = Timer(1, units="ns")
+
for a_val in waveform:
- dut.pdm_in.value = a_val
+ dut.pdm_in.value = bool(a_val)
+
+ #dut.clk.value = 0
+ #await low_delay
+ #dut.clk.value = 1
+ #await high_delay
+
await RisingEdge(dut.clk)
+async def collect_output(dut, samples):
+
+ out = numpy.zeros(samples, dtype=numpy.int16)
+
+ # wait for the PCM output
+ for i in range(samples):
+ await with_timeout(RisingEdge(dut.pcm_valid), 100000, 'ns')
+ #dut._log.info("PCM is %s", dut.pcm_out.value)
+ s = dut.pcm_out.value.signed_integer
+ out[i] = s
+
+ return out
+
+
@cocotb.test()
async def my_second_test(dut):
"""Try running with PDM input"""
- #dut.rst.value = 1
- #await RisingEdge(dut.clk)
- #dut.rst.value = 0
-
- pcm_samples = 10
+ sr = 16000
decimation = 64
- pdm_data = [0, 0, 1] * (pcm_samples*decimation)
+
+ sig = generate_test_tone(duration_sec=0.004,
+ freqs=[1000.0], noise_level=0.0, sample_rate=sr, amplitude=0.9,
+ )
+
+ pdm_data = convert(sig)
cocotb.start_soon(Clock(dut.clk, 10, units="ns").start())
cocotb.start_soon(drive_waveform(dut, pdm_data))
- # wait for the PCM output
- for _ in range(pcm_samples):
- await with_timeout(RisingEdge(dut.pcm_valid), 100000, 'ns')
- dut._log.info("PCM is %s", dut.pcm_out.value)
+ pcm_samples = len(pdm_data)//decimation
+ output = await collect_output(dut, pcm_samples)
- #dut._log.info("pdm_out is %s", dut.pdm_out.value)
- #assert dut.pdm_out.value == 1
+ output = output / 1024
- dut._log.info("my_signal_1 is %s", dut.pcm_out.value)
- assert dut.pcm_out.value == 1212
+ fig = plot_reconstruct(sig, pdm_data, output, sr=sr, aspect=6.0)
+ fig.savefig('pdm_cocotb.png')