update tests
Some checks failed
Verilator Unit Tests / Test (push) Failing after 3m9s

This commit is contained in:
saji 2024-09-10 15:19:13 -05:00
parent 386403bd12
commit ca472d7112
3 changed files with 80 additions and 47 deletions

View file

@ -70,6 +70,7 @@ class Hub75Data(wiring.Signature):
} }
) )
class SwapBuffer(wiring.Component): class SwapBuffer(wiring.Component):
"""A pair of BRAMs for holdling line data that are swapped between using an external signal. """A pair of BRAMs for holdling line data that are swapped between using an external signal.
@ -129,7 +130,6 @@ class SwapBuffer(wiring.Component):
# self.write_port.data.eq(Mux(self.selector, write0.data, write1.data)), # self.write_port.data.eq(Mux(self.selector, write0.data, write1.data)),
write0.data.eq(self.write_port.data), write0.data.eq(self.write_port.data),
write1.data.eq(self.write_port.data), write1.data.eq(self.write_port.data),
read0.addr.eq(self.read_port.addr), read0.addr.eq(self.read_port.addr),
read1.addr.eq(self.read_port.addr), read1.addr.eq(self.read_port.addr),
read0.en.eq(~self.selector), read0.en.eq(~self.selector),
@ -141,63 +141,49 @@ class SwapBuffer(wiring.Component):
class Hub75StringDriver(wiring.Component): class Hub75StringDriver(wiring.Component):
"""A data driver for Hub75 panels. This accesses the line memory and feeds out the data""" """A data driver for Hub75 panels. This accesses the line memory and feeds out the data.
It is controlled by a Hub75Coordinator to signal when it should run and what bit of the data
it should send.
"""
bcm_select: In(3) bcm_select: In(3)
done: Out(1) done: Out(1)
start: In(1) start: In(1)
active_bank: In(1) # the bank to use bram_port: In(ReadPort.Signature(addr_width=9, shape=Rgb888Layout))
bram_port: Out(WritePort.Signature(
addr_width=9, shape=Rgb888Layout
)) # the other line to be swapped to.
display_out: Out(Hub75Data()) # data signal output. display_out: Out(Hub75Data()) # data signal output.
def __init__(self, panel_length: int = 128, *, src_loc_at=0):
self.panel_length = panel_length
super().__init__(None, src_loc_at=src_loc_at)
def elaborate(self, platform: Platform) -> Module: def elaborate(self, platform: Platform) -> Module:
m = Module() m = Module()
# add two memories # add two memories
m.submodules.bram0 = bram0 = Memory(shape=Rgb888Layout, depth=512, init=[])
m.submodules.bram1 = bram1 = Memory(shape=Rgb888Layout, depth=512, init=[])
# We use two brams here so we can swap between each - that way we can update the data self._counter = counter = Signal(32)
# while displaying the other line. Switching is controlled by the coordinator.
readports = Mux([bram0.read_port(), bram1.read_port()])
active_readport = readports[self.active_bank]
m.d.comb += active_readport.eq(readports[self.active_bank])
writeports = Array([bram0.write_port(), bram1.write_port()])
m.d.comb += self.bram_port.eq(writeports[~self.active_bank])
# We want to set up the bram ports
port0 = bram0.read_port()
port1 = bram1.read_port()
# the enable for these ports is based on active bank.
m.d.comb += port0.en.eq(self.active_bank)
m.d.comb += port1.en.eq(~self.active_bank)
counter = Signal(32)
m.d.sync += counter.eq(counter + 1) m.d.sync += counter.eq(counter + 1)
ram_rgb_slice = Cat( ram_rgb_slice = Cat(
active_readport.data["red"].bit_select(self.bcm_shift, 1), self.bram_port.data["red"].bit_select(self.bcm_select, 1),
active_readport.data["blue"].bit_select(self.bcm_shift, 1), self.bram_port.data["blue"].bit_select(self.bcm_select, 1),
active_readport.data["green"].bit_select(self.bcm_shift, 1), self.bram_port.data["green"].bit_select(self.bcm_select, 1),
) )
pixnum = Signal(8, reset=127) pixnum = Signal(range(self.panel_length), init=self.panel_length - 1)
pixrow = Signal(1, reset=0) pixrow = Signal(1, init=0)
m.d.comb += self.buf_addr.eq(Cat(pixrow, pixnum)) m.d.comb += self.bram_port.addr.eq(Cat(pixrow, pixnum))
with m.FSM(): with m.FSM():
with m.State("init"): with m.State("init"):
m.d.sync += [ m.d.sync += [
self.done.eq(0), self.done.eq(0),
counter.eq(0), counter.eq(0),
pixnum.eq(127), pixnum.eq(self.panel_length - 1),
pixrow.eq(0), pixrow.eq(0),
] ]
with m.If(self.start == 1): with m.If(self.start == 1):
m.d.sync += active_readport.en.eq(1) m.d.sync += self.bram_port.en.eq(1)
m.next = "prefetch" m.next = "prefetch"
with m.State("prefetch"): with m.State("prefetch"):
with m.If(counter == 0): with m.If(counter == 0):
@ -209,23 +195,32 @@ class Hub75StringDriver(wiring.Component):
with m.Elif(counter == 3): with m.Elif(counter == 3):
m.d.sync += [self.display_out.rgb1.eq(ram_rgb_slice), counter.eq(0)] m.d.sync += [self.display_out.rgb1.eq(ram_rgb_slice), counter.eq(0)]
m.next = "writerow" m.next = "writerow"
with m.State("writerow"):
with m.If(counter[0:1] == 0):
# rising edge of the clock
m.d.sync += pixrow.eq(0)
with m.If(counter[0:1] == 1):
m.d.sync += [
pixrow.eq(1),
self.display_out.rgb0.eq(ram_rgb_slice),
]
with m.If(counter[0:1] == 2):
m.d.sync += [
pixnum.eq(pixnum - 1),
pixrow.eq(0),
self.display_out.rgb1.eq(ram_rgb_slice),
]
with m.If(counter == 128 * 2 + 1):
m.next = "done"
with m.State("done"):
m.d.sync += self.done.eq(1)
m.next = "init"
return m return m
def test_stringdriver():
dut = Hub75StringDriver()
sim = Simulator(dut)
sim.add_clock(1e-6)
async def testbench(ctx):
pass
sim.add_testbench(testbench)
with sim.write_vcd("output.vcd"):
sim.run_until(1e-6 * 1000)
class Hub75Coordinator(wiring.Component): class Hub75Coordinator(wiring.Component):
"""A shared-control hub75 driver""" """A shared-control hub75 driver"""

View file

@ -0,0 +1,37 @@
from amaranth import Array, Module, Cat, Signal, Assert, unsigned
from amaranth.build import Platform
from amaranth.lib import wiring, data
from amaranth.lib.wiring import In, Out
from amaranth.lib.memory import Memory, WritePort
from amaranth.sim import Simulator
from .bitslicer import Hub75StringDriver, Rgb888Layout
def test_stringdriver():
# the string driver test must
# 1. finish
# 2. strobe through all of the data in the array
# 3. slice the correct bit from the data.
m = Module()
m.submodules.dut = dut = Hub75StringDriver()
m.submodules.mem = mem = Memory(shape=Rgb888Layout, depth=512, init=[])
port = mem.read_port()
wiring.connect(m, port, dut.bram_port)
async def testbench(ctx):
# select a bit, strobe start, read values, test against known.
ctx.set(dut.bcm_select, 5)
ctx.set(dut.start, 1)
await ctx.tick()
ctx.set(dut.start, 0)
assert(ctx.get(dut.bram_port.en) == 1)
pass
sim = Simulator(m)
sim.add_clock(1e-6)
with sim.write_vcd("output.vcd"):
sim.run_until(1e-6 * 1000)

View file

@ -27,7 +27,8 @@ def test_swapbuffer():
ctx.set(dut.selector, 1) ctx.set(dut.selector, 1)
await ctx.tick().repeat(2) # takes two clocks after switching selector to output data. await ctx.tick().repeat(2) # takes two clocks after switching selector to output data.
assert ctx.get(dut.read_port.data) == test_color assert ctx.get(dut.read_port.data) == test_color
# TODO: add more assertions/verification
sim.add_testbench(testbench) sim.add_testbench(testbench)
with sim.write_vcd("output.vcd"): with sim.write_vcd("output.vcd"):
sim.run_until(1e-6 * 1000) sim.run_until(1e-6 * 1000)