blob: 43fa67db91e34f0657a20b60bc1754b2fa08ef08 [file] [log] [blame]
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, FallingEdge, ClockCycles, with_timeout
def decode_seg(value):
try:
if value == 0b0111111: return 0
if value == 0b0000110: return 1
if value == 0b1011011: return 2
if value == 0b1001111: return 3
if value == 0b1100110: return 4
if value == 0b1101101: return 5
if value == 0b1111101: return 6
if value == 0b0000111: return 7
if value == 0b1111111: return 8
if value == 0b1101111: return 9
except ValueError:
return '?'
@cocotb.test()
async def test_single(dut):
clock = Clock(dut.clk, 100, units="ns") # 10 MHz
cocotb.fork(clock.start())
dut.reset.value = 1
dut.set_clk_div.value = 0
dut.driver_sel.value = 0b10 # internal controller
dut.inputs.value = 0
dut.active_select.value = 2 # inverter
await ClockCycles(dut.clk, 10)
dut.reset.value = 0
await ClockCycles(dut.clk, 10) # wait until the wait state config is read
dut.inputs.value = 0
await FallingEdge(dut.ready)
await FallingEdge(dut.ready)
for i in range(11):
dut.inputs.value = i
await FallingEdge(dut.ready)
dut._log.info("cycle %d - output state %d", i, int(dut.outputs))
if i > 0:
assert 256 - i == int(dut.outputs)
@cocotb.test()
async def wait_state(dut):
clock = Clock(dut.clk, 100, units="ns") # 10 MHz
cocotb.fork(clock.start())
dut.reset.value = 1
dut.set_clk_div.value = 0
dut.driver_sel.value = 0b11 # internal controller and update wait count
dut.inputs.value = 0x02 # set wait count to be 0x02 - default is 10
dut.active_select.value = 2 # inverter
await ClockCycles(dut.clk, 10)
dut.reset.value = 0
await ClockCycles(dut.clk, 10) # wait until the wait state config is read
dut.inputs.value = 0
await FallingEdge(dut.ready)
await FallingEdge(dut.ready)
for i in range(11):
dut.inputs.value = i
await FallingEdge(dut.ready)
dut._log.info("cycle %d - output state %d", i, int(dut.outputs))
if i > 0:
assert 256 - i == int(dut.outputs)
@cocotb.test()
async def clock_div(dut):
clock = Clock(dut.clk, 100, units="ns") # 10 MHz
cocotb.fork(clock.start())
dut.reset.value = 1
dut.set_clk_div.value = 0
await ClockCycles(dut.clk, 10)
dut.reset.value = 0
# set clock divider
dut.set_clk_div.value = 1 # rising edge to lock in the new clock divider value
dut.inputs.value = 0x02 # set clock divider for 1/2 scan refresh rate
dut.driver_sel.value = 0b10 # internal controller
await ClockCycles(dut.clk, 10)
dut.active_select.value = 2 # inverter
dut.inputs.value = 0
await RisingEdge(dut.ready)
for i in range(2):
await RisingEdge(dut.slow_clk)
assert dut.outputs == 0xFF
await FallingEdge(dut.slow_clk)
assert dut.outputs == 0xFE
@cocotb.test()
async def internal_controller(dut):
clock = Clock(dut.clk, 100, units="ns") # 10 MHz
cocotb.fork(clock.start())
dut._log.info("resetting design")
dut.reset.value = 1
dut.set_clk_div.value = 0
dut.driver_sel.value = 0b10 # internal controller
dut.active_select.value = 1 # 7 seg seconds
await ClockCycles(dut.clk, 10)
dut._log.info("releasing reset")
dut.reset.value = 0
dut.inputs.value = 0
dut.set_clk_div.value = 1 # lock in the new clock divider value
await ClockCycles(dut.clk, 1)
dut.inputs.value = 0
# reset: set bit 1 high, wait for one cycle of slow_clk, then set bit 1 low
dut._log.info("first slow-clock cycle")
dut.inputs.value = 0b10
await RisingEdge(dut.slow_clk)
await RisingEdge(dut.slow_clk)
await FallingEdge(dut.slow_clk)
dut.inputs.value = 0
# sync to display, GL and RTL have different times to start
dut._log.info("sync to 7seg at pos 1")
count = 10
while count > 0:
await FallingEdge(dut.slow_clk)
if decode_seg(dut.seven_seg.value) == 0:
break
count -= 1
# check all segments
for i in range(10):
dut._log.info("clock {:2} 7seg {}".format(i, decode_seg(dut.seven_seg.value)))
assert decode_seg(dut.seven_seg.value) == i
await FallingEdge(dut.slow_clk)
dut._log.info("straight test at pos 0")
dut.set_clk_div.value = 0 # no clock div
dut.active_select.value = 0 # straight
await FallingEdge(dut.ready)
for i in range(11):
dut.inputs.value = i
await FallingEdge(dut.ready)
dut._log.info("cycle %d - output state %d", i, int(dut.outputs))
if i > 0:
assert i == int(dut.outputs) + 1
dut._log.info("invert test at pos 2")
dut.active_select.value = 2 # invert
dut.inputs.value = 0
await FallingEdge(dut.ready)
await FallingEdge(dut.ready)
for i in range(11):
dut.inputs.value = i
await FallingEdge(dut.ready)
dut._log.info("cycle %d - output state %d", i, int(dut.outputs))
if i > 0:
assert 256 - i == int(dut.outputs)
for design in range(3,20): # next designs are all straight
dut._log.info("straight test at pos {}".format(design))
dut.active_select.value = design
await FallingEdge(dut.ready)
for i in range(11):
dut.inputs.value = i
await FallingEdge(dut.ready)
dut._log.info("cycle %d - output state %d", i, int(dut.outputs))
if i > 0:
assert i == int(dut.outputs) + 1