gw: switch to strobe-style control bits for controller
This commit is contained in:
parent
0e3328aac1
commit
8e6e483f92
@ -185,6 +185,7 @@ def main():
|
||||
results.append(run_test("SamplerController", controller.test_bus_access))
|
||||
results.append(run_test("SamplerController", controller.test_simple_waveform))
|
||||
results.append(run_test("SamplerController", controller.test_simple_waveform_capture_offset))
|
||||
results.append(run_test("SamplerController", controller.test_multiple_reads))
|
||||
results.append(run_test("PeakDetector", peak_detector.test_simple_waveform))
|
||||
results.append(run_test("PeakDetector", peak_detector.test_scrunched_simple_waveform))
|
||||
results.append(run_test("PeakDetector", peak_detector.test_decay_simple_waveform))
|
||||
|
@ -27,11 +27,14 @@ class SamplerController(Module):
|
||||
|
||||
Registers
|
||||
--------
|
||||
0x00: Control Register (RW)
|
||||
Bit 0 - Begin capture. Resets all FIFOs and starts the peak detector
|
||||
0x00: Control Register (WO)
|
||||
Bit 0 - Start capture
|
||||
Bit 1 - Stop capture. Does nothing if capture is not ongoing
|
||||
Bit 2 - Clear sample buffers
|
||||
|
||||
0x01: Status Register (RO)
|
||||
Bit 0 - Capture complete. Set by peak detection block and cleared when capture is began
|
||||
Bit 1 - Sampling running
|
||||
|
||||
0x02: trigger_run_len (RW)
|
||||
Number of samples to acquire after triggering sample.
|
||||
@ -138,7 +141,7 @@ class SamplerController(Module):
|
||||
|
||||
# Handle explicit config registers
|
||||
cases = {
|
||||
0: rw_register(control_register),
|
||||
0: rw_register(control_register, read=False),
|
||||
1: rw_register(status_register, write=False),
|
||||
2: rw_register(trigger_run_len),
|
||||
3: rw_register(self.peak_detector.thresh_value),
|
||||
@ -156,6 +159,8 @@ class SamplerController(Module):
|
||||
# Connect up control registers bus
|
||||
self.sync += [
|
||||
self.control_regs_bus.ack.eq(0),
|
||||
# Hold control register low to use as strobe functionality
|
||||
control_register.eq(0),
|
||||
If(self.control_regs_bus.cyc & self.control_regs_bus.stb,
|
||||
self.control_regs_bus.ack.eq(1),
|
||||
Case(self.control_regs_bus.adr, cases)),
|
||||
@ -180,13 +185,20 @@ class SamplerController(Module):
|
||||
# We have sampled enough, update status and stop sampling
|
||||
If(post_trigger_count + 1 >= trigger_run_len,
|
||||
status_register[0].eq(1),
|
||||
control_register[0].eq(0))),
|
||||
sample_enable.eq(0))),
|
||||
]
|
||||
|
||||
# Update register storage
|
||||
self.comb += [
|
||||
sample_enable.eq(control_register[0]),
|
||||
self.sync += [
|
||||
status_register[1].eq(sample_enable),
|
||||
If(control_register[0], sample_enable.eq(1)),
|
||||
If(control_register[1], sample_enable.eq(0)),
|
||||
]
|
||||
for buffer in self.buffers:
|
||||
self.sync += [
|
||||
buffer.clear.eq(0),
|
||||
If(control_register[2], buffer.clear.eq(1)),
|
||||
]
|
||||
|
||||
def write_wishbone(bus, address, value):
|
||||
# Set up bus
|
||||
@ -341,6 +353,11 @@ def test_simple_waveform():
|
||||
sample = (yield dut.bus.dat_r)
|
||||
data.append(sample)
|
||||
|
||||
# Manually validated, this is what we should read on a correct
|
||||
# run
|
||||
assert data[15] == 138
|
||||
assert data[16] == 132
|
||||
|
||||
# Test pass
|
||||
return
|
||||
|
||||
@ -418,3 +435,172 @@ def test_simple_waveform_capture_offset():
|
||||
assert False, "We should have triggered"
|
||||
|
||||
run_simulation(dut, test_fn())
|
||||
|
||||
|
||||
def test_multiple_reads():
|
||||
"""
|
||||
Testing multiple triggers/captures in succession to ensure typical (i.e. repeated) operation
|
||||
works correctly.
|
||||
"""
|
||||
# Enable, trigger works correctly
|
||||
# Enable, tick a bit of data in, should not trigger, and trigger should have reset immediately
|
||||
# Enable again, and tick in lots of data, should trigger again now
|
||||
"""Test a simple waveform captured at an offset"""
|
||||
from .peak_detector import create_waveform
|
||||
_, data = create_waveform()
|
||||
data = [int(d) for d in data]
|
||||
dut = TestSoC(data, buffer_len=32)
|
||||
|
||||
def test_fn():
|
||||
# Set settings
|
||||
yield from write_wishbone(dut.bus, 2, 0) # trigger_run_len = 0
|
||||
yield from write_wishbone(dut.bus, 3, 800) # thresh_value = 800
|
||||
yield from write_wishbone(dut.bus, 4, 10) # thresh_time = 10
|
||||
yield from write_wishbone(dut.bus, 5, 1) # decay_value = 1
|
||||
yield from write_wishbone(dut.bus, 5, 0) # decay_period = 0
|
||||
|
||||
# Start controller
|
||||
yield from write_wishbone(dut.bus, 0, 1)
|
||||
|
||||
triggered_yet = False
|
||||
triggered_num = 0
|
||||
for i in range(1000):
|
||||
(yield dut.samplers[0].index.eq(i))
|
||||
(yield dut.samplers[0].valid.eq(1))
|
||||
yield
|
||||
|
||||
(yield dut.samplers[0].valid.eq(0))
|
||||
yield
|
||||
|
||||
# Total of 6 clocks per sample clock
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
|
||||
if not triggered_yet and (yield dut.controller.peak_detector.triggered) == 1:
|
||||
# Triggered, now we need to run some number of cycles
|
||||
triggered_yet = True
|
||||
|
||||
if triggered_yet:
|
||||
triggered_num += 1
|
||||
if triggered_num > 16:
|
||||
# We should now have collected all our samples
|
||||
yield from read_wishbone(dut.bus, 1)
|
||||
assert (yield dut.bus.dat_r) == 1, "Trigger did not propogate to WB!"
|
||||
|
||||
# Check that length is correct
|
||||
yield from read_wishbone(dut.bus, 0x100)
|
||||
len = (yield dut.bus.dat_r)
|
||||
assert len == 32, f"Len ({len}) not correct!"
|
||||
|
||||
# Read data in
|
||||
data = []
|
||||
for i in range(32):
|
||||
yield from read_wishbone(dut.bus, 0x800 + i)
|
||||
sample = (yield dut.bus.dat_r)
|
||||
data.append(sample)
|
||||
|
||||
|
||||
# Manually validated from test above to be offset into the
|
||||
# data
|
||||
assert data[15] == 138
|
||||
assert data[16] == 132
|
||||
break
|
||||
|
||||
assert triggered_yet, "We should have triggered"
|
||||
|
||||
# Clear out sampler and re-enable
|
||||
yield from write_wishbone(dut.bus, 0, 0b101)
|
||||
yield
|
||||
|
||||
assert (yield dut.controller.peak_detector.triggered) == 0, "Trigger should have been cleared"
|
||||
assert (yield dut.controller.buffers[0].len) == 0, "Buffers should have been cleared"
|
||||
|
||||
# Tick a few clocks through, and we shouldn't have triggered
|
||||
for i in range(10):
|
||||
(yield dut.samplers[0].index.eq(i))
|
||||
(yield dut.samplers[0].valid.eq(1))
|
||||
yield
|
||||
|
||||
(yield dut.samplers[0].valid.eq(0))
|
||||
yield
|
||||
|
||||
# Total of 6 clocks per sample clock
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
|
||||
assert (yield dut.controller.peak_detector.triggered) == 0, "We didn't push enough data through to trigger"
|
||||
|
||||
# Disable sampler, run lots of data through, we should not trigger
|
||||
yield from write_wishbone(dut.bus, 0, 0b010)
|
||||
for i in range(1000):
|
||||
(yield dut.samplers[0].index.eq(i))
|
||||
(yield dut.samplers[0].valid.eq(1))
|
||||
yield
|
||||
|
||||
(yield dut.samplers[0].valid.eq(0))
|
||||
yield
|
||||
|
||||
# Total of 6 clocks per sample clock
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
|
||||
# Enable sampler and run again, we should get another trigger
|
||||
yield from write_wishbone(dut.bus, 2, 16) # trigger_run_len = 16
|
||||
yield from write_wishbone(dut.bus, 0, 1)
|
||||
triggered_yet = False
|
||||
triggered_num = 0
|
||||
for i in range(1000):
|
||||
(yield dut.samplers[0].index.eq(i))
|
||||
(yield dut.samplers[0].valid.eq(1))
|
||||
yield
|
||||
|
||||
(yield dut.samplers[0].valid.eq(0))
|
||||
yield
|
||||
|
||||
# Total of 6 clocks per sample clock
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
yield
|
||||
|
||||
if not triggered_yet and (yield dut.controller.peak_detector.triggered) == 1:
|
||||
# Triggered, now we need to run some number of cycles
|
||||
triggered_yet = True
|
||||
|
||||
if triggered_yet:
|
||||
triggered_num += 1
|
||||
if triggered_num > 16:
|
||||
# We should now have collected all our samples
|
||||
yield from read_wishbone(dut.bus, 1)
|
||||
assert (yield dut.bus.dat_r) == 1, "Trigger did not propogate to WB!"
|
||||
|
||||
# Check that length is correct
|
||||
yield from read_wishbone(dut.bus, 0x100)
|
||||
len = (yield dut.bus.dat_r)
|
||||
assert len == 32, f"Len ({len}) not correct!"
|
||||
|
||||
# Read data in
|
||||
data = []
|
||||
for i in range(32):
|
||||
yield from read_wishbone(dut.bus, 0x800 + i)
|
||||
sample = (yield dut.bus.dat_r)
|
||||
data.append(sample)
|
||||
|
||||
|
||||
# Manually validated from test above to be offset into the
|
||||
# data
|
||||
assert data[0] == 138
|
||||
assert data[1] == 132
|
||||
|
||||
# Test pass
|
||||
return
|
||||
|
||||
assert triggered_yet, "We should have triggered"
|
||||
|
||||
run_simulation(dut, test_fn(), vcd_name="controller.vcd")
|
||||
|
Loading…
Reference in New Issue
Block a user