observerw's picture
download
raw
7.42 kB
AUTO_BUILD_ARGS = []
#!/usr/bin/env python3
"""
Testbench for pattern_vg module.
"""
import random
import sys
from pathlib import Path
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotb_tools.runner import get_runner
@cocotb.test()
async def test_reset(dut):
"""Test that reset clears the internal ramp_values register."""
# Create clock
clock = Clock(dut.clk_in, 10, unit="ns")
cocotb.start_soon(clock.start())
# Apply reset
dut.reset.value = 1
await RisingEdge(dut.clk_in)
await RisingEdge(dut.clk_in)
# Check that control signals pass through
dut.vn_in.value = 1
dut.hn_in.value = 0
dut.dn_in.value = 1
await RisingEdge(dut.clk_in)
assert dut.vn_out.value == 1, "vn_out should follow vn_in"
assert dut.hn_out.value == 0, "hn_out should follow hn_in"
assert dut.den_out.value == 1, "den_out should follow dn_in"
# Release reset
dut.reset.value = 0
await RisingEdge(dut.clk_in)
# Set pattern to 4 (RAMP) and check initial behavior
dut.pattern.value = 4
dut.ramp_step.value = 256 # 1.0 in 8.12 fixed point
dut.x.value = 0
dut.y.value = 0
dut.dn_in.value = 1
await RisingEdge(dut.clk_in)
# With pattern 4 and x=0, dn_in=1, ramp_values should be set to ramp_step
# Output should be ramp_values[19:12] = 256 >> 12 = 0
assert dut.r_out.value == 0, f"r_out should be 0 after reset, got {dut.r_out.value}"
assert dut.g_out.value == 0, f"g_out should be 0 after reset, got {dut.g_out.value}"
assert dut.b_out.value == 0, f"b_out should be 0 after reset, got {dut.b_out.value}"
@cocotb.test()
async def test_pattern_border(dut):
"""Test pattern 1 (border) functionality."""
clock = Clock(dut.clk_in, 10, unit="ns")
cocotb.start_soon(clock.start())
# Initialize
dut.reset.value = 1
await RisingEdge(dut.clk_in)
dut.reset.value = 0
await RisingEdge(dut.clk_in)
# Set display parameters
dut.total_active_pix.value = 640
dut.total_active_lines.value = 480
# Set pattern to border
dut.pattern.value = 1
dut.dn_in.value = 1
dut.r_in.value = 0x12
dut.g_in.value = 0x34
dut.b_in.value = 0x56
# Test top border (y=0)
dut.x.value = 100
dut.y.value = 0
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0xFF, f"Top border should be white, got {dut.r_out.value}"
assert dut.g_out.value == 0xFF, f"Top border should be white, got {dut.g_out.value}"
assert dut.b_out.value == 0xFF, f"Top border should be white, got {dut.b_out.value}"
# Test left border (x=0)
dut.x.value = 0
dut.y.value = 100
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0xFF, f"Left border should be white, got {dut.r_out.value}"
assert dut.g_out.value == 0xFF, f"Left border should be white, got {dut.g_out.value}"
assert dut.b_out.value == 0xFF, f"Left border should be white, got {dut.b_out.value}"
# Test right border (x = total_active_pix - 1)
dut.x.value = 639
dut.y.value = 100
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0xFF, f"Right border should be white, got {dut.r_out.value}"
assert dut.g_out.value == 0xFF, f"Right border should be white, got {dut.g_out.value}"
assert dut.b_out.value == 0xFF, f"Right border should be white, got {dut.b_out.value}"
# Test bottom border (y = total_active_lines - 1)
dut.x.value = 100
dut.y.value = 479
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0xFF, f"Bottom border should be white, got {dut.r_out.value}"
assert dut.g_out.value == 0xFF, f"Bottom border should be white, got {dut.g_out.value}"
assert dut.b_out.value == 0xFF, f"Bottom border should be white, got {dut.b_out.value}"
# Test non-border area
dut.x.value = 100
dut.y.value = 100
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0x12, f"Non-border should pass through r_in, got {dut.r_out.value}"
assert dut.g_out.value == 0x34, f"Non-border should pass through g_in, got {dut.g_out.value}"
assert dut.b_out.value == 0x56, f"Non-border should pass through b_in, got {dut.b_out.value}"
@cocotb.test()
async def test_pattern_moirex(dut):
"""Test pattern 2 (moireX) functionality."""
clock = Clock(dut.clk_in, 10, unit="ns")
cocotb.start_soon(clock.start())
# Initialize
dut.reset.value = 1
await RisingEdge(dut.clk_in)
dut.reset.value = 0
await RisingEdge(dut.clk_in)
# Set pattern to moireX
dut.pattern.value = 2
dut.dn_in.value = 1
# Test with odd x (LSB = 1)
dut.x.value = 5 # binary 101, LSB = 1
dut.y.value = 10
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0xFF, f"Odd x should be white, got {dut.r_out.value}"
assert dut.g_out.value == 0xFF, f"Odd x should be white, got {dut.g_out.value}"
assert dut.b_out.value == 0xFF, f"Odd x should be white, got {dut.b_out.value}"
# Test with even x (LSB = 0)
dut.x.value = 4 # binary 100, LSB = 0
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0x00, f"Even x should be black, got {dut.r_out.value}"
assert dut.g_out.value == 0x00, f"Even x should be black, got {dut.g_out.value}"
assert dut.b_out.value == 0x00, f"Even x should be black, got {dut.b_out.value}"
# Test with dn_in = 0 (should output black regardless of x)
dut.dn_in.value = 0
dut.x.value = 5 # odd x
await RisingEdge(dut.clk_in)
assert dut.r_out.value == 0x00, f"With dn_in=0 should be black, got {dut.r_out.value}"
assert dut.g_out.value == 0x00, f"With dn_in=0 should be black, got {dut.g_out.value}"
assert dut.b_out.value == 0x00, f"With dn_in=0 should be black, got {dut.b_out.value}"
@cocotb.test()
async def test_pattern_ramp(dut):
"""Test pattern 4 (RAMP) functionality."""
clock = Clock(dut.clk_in, 10, unit="ns")
cocotb.start_soon(clock.start())
# Initialize
dut.reset.value = 1
await RisingEdge(dut.clk_in)
dut.reset.value = 0
await RisingEdge(dut.clk_in)
# Set display parameters
dut.total_active_pix.value = 10 # Small value for testing
dut.dn_in.value = 1
# Set pattern to RAMP
dut.pattern.value = 4
dut.ramp_step.value = 4096 # 1.0 in 8.12 fixed point (1 << 12)
# Start at x=0, should set ramp_values to ramp_step
dut.x.value = 0
dut.y.value = 0
await RisingEdge(dut.clk_in)
# ramp_values = 4096, output = 4096[19:12] = 4096 >> 12 = 1
assert dut.r_out.value == 1, f"At x=0, r_out should be 1, got {dut.r_out.value}"
assert dut.g_out.value == 1, f"At x=0, g_out should be 1, got {dut.g_out.value}"
assert dut.b_out.value == 1, f"At x=0, b_out should be 1, got {dut.b_out.value}"
# Move to x=1, should
if __name__ == "__main__":
from pathlib import Path
from cocotb_tools.runner import get_runner
project_root = Path(__file__).resolve().parents[1]
sources = [
project_root / "reference" / "top.v"
]
runner = get_runner("icarus")
runner.build(
sources=[str(path) for path in sources],
hdl_toplevel='pattern_vg',
build_args=AUTO_BUILD_ARGS,
always=True,
)
runner.test(
hdl_toplevel='pattern_vg',
test_module="tb",
waves=False,
)

Xet Storage Details

Size:
7.42 kB
·
Xet hash:
f10cfb2bdbd64b993d0b3d2a4f4ac1aabdb6088971a59b2f4070a9b1ca3c57ef

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.