generated from saji/ecp5-template
cleanup tests, make data address combinational
All checks were successful
Unit Tests / Test (push) Successful in 2m6s
All checks were successful
Unit Tests / Test (push) Successful in 2m6s
This commit is contained in:
parent
7a0f59c9f6
commit
88426ac89a
|
@ -99,7 +99,7 @@ class DisplayClock(wiring.Component):
|
||||||
{
|
{
|
||||||
"start": In(1),
|
"start": In(1),
|
||||||
"done": In(1),
|
"done": In(1),
|
||||||
"clk": Out(1),
|
"display_clk": Out(1),
|
||||||
},
|
},
|
||||||
src_loc_at=src_loc_at,
|
src_loc_at=src_loc_at,
|
||||||
)
|
)
|
||||||
|
@ -111,7 +111,8 @@ class DisplayClock(wiring.Component):
|
||||||
|
|
||||||
with m.FSM():
|
with m.FSM():
|
||||||
with m.State("init"):
|
with m.State("init"):
|
||||||
m.d.sync += [counter.eq(0), self.clk.eq(0)]
|
m.d.sync += [counter.eq(0)]
|
||||||
|
m.d.comb += self.display_clk.eq(0)
|
||||||
with m.If(self.start == 1):
|
with m.If(self.start == 1):
|
||||||
m.next = "warmup"
|
m.next = "warmup"
|
||||||
with m.State("warmup"):
|
with m.State("warmup"):
|
||||||
|
@ -124,13 +125,13 @@ class DisplayClock(wiring.Component):
|
||||||
with m.If(self.done == 1):
|
with m.If(self.done == 1):
|
||||||
m.next = "init"
|
m.next = "init"
|
||||||
if self.double_fetch:
|
if self.double_fetch:
|
||||||
|
m.d.comb += self.display_clk.eq(~counter[1])
|
||||||
m.d.sync += [
|
m.d.sync += [
|
||||||
self.clk.eq(~counter[1]),
|
|
||||||
counter.eq(counter + 1),
|
counter.eq(counter + 1),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
|
m.d.comb += (self.display_clk.eq(counter),)
|
||||||
m.d.sync += [
|
m.d.sync += [
|
||||||
self.clk.eq(~counter),
|
|
||||||
counter.eq(~counter),
|
counter.eq(~counter),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -233,10 +234,10 @@ class Hub75DataDriver(wiring.Component):
|
||||||
m.d.sync += [
|
m.d.sync += [
|
||||||
self.data.rgb0.eq(ram_rgb_slice[0]),
|
self.data.rgb0.eq(ram_rgb_slice[0]),
|
||||||
self.data.rgb1.eq(ram_rgb_slice[1]),
|
self.data.rgb1.eq(ram_rgb_slice[1]),
|
||||||
|
pixnum.eq(pixnum - 1),
|
||||||
]
|
]
|
||||||
with m.If(counter[0] == 1):
|
with m.If(counter[0] == 1):
|
||||||
m.d.sync += [
|
m.d.sync += [
|
||||||
pixnum.eq(pixnum - 1),
|
|
||||||
counter.eq(0),
|
counter.eq(0),
|
||||||
]
|
]
|
||||||
with m.If(pixnum == 0):
|
with m.If(pixnum == 0):
|
||||||
|
|
|
@ -2,6 +2,8 @@ from amaranth import Module
|
||||||
from amaranth.lib import wiring, data
|
from amaranth.lib import wiring, data
|
||||||
from amaranth.lib.memory import Memory
|
from amaranth.lib.memory import Memory
|
||||||
from amaranth.sim import Simulator
|
from amaranth.sim import Simulator
|
||||||
|
import random
|
||||||
|
from random import randrange
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from groovylight.common import Rgb888Layout, Rgb666Layout
|
from groovylight.common import Rgb888Layout, Rgb666Layout
|
||||||
|
@ -13,6 +15,7 @@ from groovylight.hub75 import (
|
||||||
SwapBuffer,
|
SwapBuffer,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
random.seed()
|
||||||
|
|
||||||
def test_swapbuffer():
|
def test_swapbuffer():
|
||||||
dut = SwapBuffer(Rgb666Layout, 512)
|
dut = SwapBuffer(Rgb666Layout, 512)
|
||||||
|
@ -42,12 +45,29 @@ def test_swapbuffer():
|
||||||
sim.run_until(1e-6 * 1000)
|
sim.run_until(1e-6 * 1000)
|
||||||
|
|
||||||
|
|
||||||
def test_datadriver():
|
def randcolor(nbits=8):
|
||||||
# the string driver test must
|
|
||||||
# 1. finish
|
return {
|
||||||
# 2. strobe through all of the data in the array
|
"red": randrange(2**nbits),
|
||||||
# 3. slice the correct bit from the data.
|
"green": randrange(2**nbits),
|
||||||
memdata = [{"red": x, "green": x, "blue": x} for x in range(256)]
|
"blue": randrange(2**nbits),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def make_start(dut, bcm):
|
||||||
|
async def testbench(ctx):
|
||||||
|
# select a bit, strobe start, read values, test against known.
|
||||||
|
ctx.set(dut.bcm_select, bcm)
|
||||||
|
ctx.set(dut.start, 1)
|
||||||
|
await ctx.tick()
|
||||||
|
ctx.set(dut.start, 0)
|
||||||
|
assert ctx.get(dut.bram.en) == 1
|
||||||
|
await ctx.tick().until(dut.done == 1)
|
||||||
|
return testbench
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("bcm", range(8))
|
||||||
|
def test_datadriver(bcm):
|
||||||
|
memdata = [randcolor() for x in range(256)]
|
||||||
m = Module()
|
m = Module()
|
||||||
m.submodules.dut = dut = Hub75DataDriver()
|
m.submodules.dut = dut = Hub75DataDriver()
|
||||||
m.submodules.mem = mem = Memory(shape=Rgb888Layout, depth=256, init=memdata)
|
m.submodules.mem = mem = Memory(shape=Rgb888Layout, depth=256, init=memdata)
|
||||||
|
@ -57,35 +77,69 @@ def test_datadriver():
|
||||||
clocker.done.eq(dut.done),
|
clocker.done.eq(dut.done),
|
||||||
]
|
]
|
||||||
|
|
||||||
port = mem.read_port()
|
wiring.connect(m, mem.read_port(), dut.bram)
|
||||||
|
|
||||||
wiring.connect(m, port, dut.bram)
|
testbench = make_start(dut, bcm)
|
||||||
|
|
||||||
async def testbench(ctx):
|
|
||||||
# select a bit, strobe start, read values, test against known.
|
|
||||||
ctx.set(dut.bcm_select, 7)
|
|
||||||
ctx.set(dut.start, 1)
|
|
||||||
await ctx.tick()
|
|
||||||
ctx.set(dut.start, 0)
|
|
||||||
assert ctx.get(dut.bram.en) == 1
|
|
||||||
await ctx.tick().until(dut.done == 1)
|
|
||||||
|
|
||||||
async def rgbtest(ctx):
|
async def rgbtest(ctx):
|
||||||
await ctx.tick().until(dut.start == 1)
|
await ctx.tick().until(dut.start == 1)
|
||||||
counter = 127
|
counter = 127
|
||||||
bitslice = 7
|
async for _, rgb0, rgb1 in ctx.posedge(clocker.display_clk).sample(
|
||||||
async for _, rgb0, rgb1 in ctx.posedge(clocker.clk).sample(dut.data.rgb0, dut.data.rgb1):
|
dut.data.rgb0, dut.data.rgb1
|
||||||
|
):
|
||||||
assert counter >= 0, "should not do more than 128 clocks"
|
assert counter >= 0, "should not do more than 128 clocks"
|
||||||
e0 = ctx.get(mem.data[counter << 1])
|
e0 = ctx.get(mem.data[counter << 1])
|
||||||
e1 = ctx.get(mem.data[(counter << 1) + 1])
|
e1 = ctx.get(mem.data[(counter << 1) + 1])
|
||||||
print(counter)
|
print(counter)
|
||||||
for r, e in [(rgb0, e0), (rgb1, e1)]:
|
for r, e in [(rgb0, e0), (rgb1, e1)]:
|
||||||
assert r.red == (e.red >> bitslice) & 1
|
assert r.red == (e.red >> bcm) & 1
|
||||||
assert r.green == (e.green >> bitslice) & 1
|
assert r.green == (e.green >> bcm) & 1
|
||||||
assert r.blue == (e.blue >> bitslice) & 1
|
assert r.blue == (e.blue >> bcm) & 1
|
||||||
|
counter = counter - 1
|
||||||
|
|
||||||
|
sim = Simulator(m)
|
||||||
|
sim.add_clock(1e-6)
|
||||||
|
sim.add_testbench(testbench)
|
||||||
|
sim.add_testbench(rgbtest, background=True)
|
||||||
|
|
||||||
|
with sim.write_vcd("output.vcd"):
|
||||||
|
sim.run()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("bcm", range(6))
|
||||||
|
def test_datadriver_single(bcm):
|
||||||
|
memdata = [[randcolor(6), randcolor(6)] for x in range(128)]
|
||||||
|
m = Module()
|
||||||
|
m.submodules.dut = dut = Hub75DataDriver(
|
||||||
|
data_shape=Rgb666Layout, double_fetch=False
|
||||||
|
)
|
||||||
|
mshape = data.ArrayLayout(Rgb666Layout, 2)
|
||||||
|
m.submodules.mem = mem = Memory(shape=mshape, depth=128, init=memdata)
|
||||||
|
m.submodules.clocker = clocker = DisplayClock(double_fetch = False)
|
||||||
|
m.d.comb += [
|
||||||
|
clocker.start.eq(dut.start),
|
||||||
|
clocker.done.eq(dut.done),
|
||||||
|
]
|
||||||
|
|
||||||
|
wiring.connect(m, mem.read_port(), dut.bram)
|
||||||
|
|
||||||
|
testbench = make_start(dut, bcm)
|
||||||
|
|
||||||
|
async def rgbtest(ctx):
|
||||||
|
await ctx.tick().repeat(2)
|
||||||
|
counter = 127
|
||||||
|
async for _, rgb0, rgb1 in ctx.posedge(clocker.display_clk).sample(
|
||||||
|
dut.data.rgb0, dut.data.rgb1
|
||||||
|
):
|
||||||
|
assert counter >= 0, "should not do more than 128 clocks"
|
||||||
|
e0, e1 = ctx.get(mem.data[counter])
|
||||||
|
print(counter)
|
||||||
|
for r, e in [(rgb0, e0), (rgb1, e1)]:
|
||||||
|
assert r.red == (e.red >> bcm) & 1
|
||||||
|
assert r.green == (e.green >> bcm) & 1
|
||||||
|
assert r.blue == (e.blue >> bcm) & 1
|
||||||
counter = counter - 1
|
counter = counter - 1
|
||||||
|
|
||||||
|
|
||||||
sim = Simulator(m)
|
sim = Simulator(m)
|
||||||
sim.add_clock(1e-6)
|
sim.add_clock(1e-6)
|
||||||
sim.add_testbench(testbench)
|
sim.add_testbench(testbench)
|
||||||
|
@ -93,7 +147,6 @@ def test_datadriver():
|
||||||
|
|
||||||
with sim.write_vcd("output.vcd"):
|
with sim.write_vcd("output.vcd"):
|
||||||
sim.run()
|
sim.run()
|
||||||
# sim.run_until(1e-6 * 4000)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip()
|
@pytest.mark.skip()
|
||||||
|
|
Loading…
Reference in a new issue