artiq-zynq/sim_roi.py

323 lines
16 KiB
Python
Raw Normal View History

from migen import *
from misoc.interconnect.csr import *
from misoc.interconnect import stream
from src.gateware.cxp_frame_pipeline import *
from src.gateware.cxp_pipeline import *
2025-01-10 15:05:10 +08:00
from math import ceil
class ROI(Module):
def __init__(self):
fifo = stream.SyncFIFO(word_layout, 32) # to avoid data getting eaten and act as delay between eop
dchar_decoder = Duplicated_Char_Decoder()
# self.crc = CXPCRC32_Checker()
2025-01-15 16:21:30 +08:00
self.pipeline = Pixel_Pipeline(24, 32)
pipeline = [fifo, dchar_decoder, self.pipeline]
self.submodules += pipeline
for s, d in zip(pipeline, pipeline[1:]):
self.comb += s.source.connect(d.sink)
self.sink = pipeline[0].sink
2025-01-15 13:21:08 +08:00
# self.source = pipeline[-1].source
# DEBUG: test roi
cfg = self.pipeline.roi.cfg
self.comb += [
cfg.x0.eq(0),
cfg.x1.eq(8),
cfg.y0.eq(0),
cfg.y1.eq(1),
]
dut = ROI()
def packet_sim(packets=[]):
print("=================TEST========================")
sink = dut.sink
cyc = len(packets)
pak = packets
for c in range(cyc):
yield sink.data.eq(pak[c]["data"])
yield sink.k.eq(pak[c]["k"])
yield sink.stb.eq(1)
if "eop" in pak[c]:
yield sink.eop.eq(1)
else:
yield sink.eop.eq(0)
yield
# extra clk cycles
for _ in range(cyc, cyc + 20):
yield sink.data.eq(0)
yield sink.k.eq(0)
yield sink.stb.eq(0)
yield sink.eop.eq(0)
yield
metadata = dut.pipeline.header_decoder.metadata
img_header_layout = [
"stream_id",
"source_tag", # image index since powering on
"x_size",
"x_offset",
"y_size",
"y_offset",
"l_size", # number of data words per image line
"pixel_format",
"tap_geo",
"flag",
]
for name in img_header_layout:
print(f"{name} = {yield getattr(metadata, name):#04X} ", end="")
print()
2025-01-15 16:21:30 +08:00
roi = dut.pipeline.roi
print(f"x0 = {yield roi.cfg.x0} y0 = {yield roi.cfg.y0} | x1 = {yield roi.cfg.x1} y1 = {yield roi.cfg.y1}")
print(f"out count = {yield roi.out.count}")
assert True
def testbench():
paks = [
2025-01-14 15:22:50 +08:00
{"data": C(0x7C7C7C7C, word_width), "k" : Replicate(1, 4)},
{"data": C(0x01010101, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # stream id
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x6AEFACF6, word_width), "k" : Replicate(0, 4), "eop":0}, # crc
2025-01-14 15:22:50 +08:00
{"data": C(0x02020202, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # Xsize[23:16]
{"data": C(0x09090909, word_width), "k" : Replicate(0, 4)}, # Xsize[15:8]
{"data": C(0x90909090, word_width), "k" : Replicate(0, 4)}, # Xsize[7:0]
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x8EE1DAA1, word_width), "k" : Replicate(0, 4), "eop":0}, # crc
2025-01-14 15:22:50 +08:00
{"data": C(0x08080808, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x08080808, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # DsizeL[23:16]
{"data": C(0x02020202, word_width), "k" : Replicate(0, 4)}, # DsizeL[15:8]
{"data": C(0x64646464, word_width), "k" : Replicate(0, 4)}, # DsizeL[7:0]
{"data": C(0x01010101, word_width), "k" : Replicate(0, 4)},
{"data": C(0x01010101, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x51C243EA, word_width), "k" : Replicate(0, 4), "eop":0}, # crc
# the new line + pixel data
2025-01-14 15:22:50 +08:00
{"data": C(0x7C7C7C7C, word_width), "k" : Replicate(1, 4)},
{"data": C(0x02020202, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0D0D0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0B0D, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0D0B0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0C0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0B0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0B0B0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0B0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0A0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0B0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0C0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0B0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0C0B0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0B0B0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0C0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0B0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0C0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0B0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0B0B0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0B0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0D0A, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0B0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0A0B0D, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0B0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0D0C0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0A0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0D0D0B0A, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0C0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0C0B0B0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0C0C0B, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0B0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0x0B0B0B0C, word_width), "k" : Replicate(0, 4)},
{"data": C(0xCB5DCDD6, word_width), "k" : Replicate(0, 4), "eop": 0}, # crc
# {"data": C(0x0C0B0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0B0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0B0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0D0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0C0A, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0D0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0C0D, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0A0C0C0D, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0B0A, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0D0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0B0D0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0D0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0B0A, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0A0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0C0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0D0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0D0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0D0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0D0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0D0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0C0D0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0D0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0C0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0D0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0B0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0B0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0B0C0B, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0B0C0C0D, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0D0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0B0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0C0C0C0C, word_dw), "k" : Replicate(0, 4)},
# {"data": C(0x0BADF020, word_dw), "k" : Replicate(0, 4), "eop":0}, # crc
]
yield from packet_sim(paks)
2025-01-10 15:05:10 +08:00
def testbench_fake_data():
2025-01-13 16:35:34 +08:00
# config
2025-01-15 13:21:08 +08:00
pix_size = 8
x_size = 13
2025-01-10 15:05:10 +08:00
y_size = 3
2025-01-13 16:35:34 +08:00
l_size = ceil(x_size*pix_size/32)
pix_fmt = {
8: 0x0101,
10: 0x0102,
12: 0x0103,
14: 0x0104,
16: 0x0105,
}
2025-01-10 15:05:10 +08:00
# frame header
paks = [
2025-01-14 15:22:50 +08:00
{"data": C(0x7C7C7C7C, word_width), "k" : Replicate(1, 4)},
{"data": C(0x01010101, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # stream id
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x6AEFACF6, word_width), "k" : Replicate(0, 4), "eop":0}, # fake crc
2025-01-10 15:05:10 +08:00
2025-01-14 15:22:50 +08:00
{"data": C(0x02020202, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # Xsize[23:16]
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # Xsize[15:8]
2025-01-10 15:05:10 +08:00
{"data": Replicate(C(x_size, char_width), 4), "k" : Replicate(0, 4)}, # Xsize[7:0]
2025-01-14 15:22:50 +08:00
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # Ysize[23:16]
{"data": C(0x8EE1DAA1, word_width), "k" : Replicate(0, 4), "eop":0}, # fake crc
2025-01-10 15:05:10 +08:00
2025-01-14 15:22:50 +08:00
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # Ysize[15:8]
2025-01-10 15:05:10 +08:00
{"data": Replicate(C(y_size, char_width), 4), "k" : Replicate(0, 4)}, # Ysize[7:0]
2025-01-14 15:22:50 +08:00
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x08080808, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # DsizeL[23:16]
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)}, # DsizeL[15:8]
2025-01-10 15:05:10 +08:00
{"data": Replicate(C(l_size, char_width), 4), "k" : Replicate(0, 4)}, # DsizeL[7:0]
2025-01-13 16:35:34 +08:00
{"data": Replicate(C(pix_fmt[pix_size] >> 8, char_width), 4), "k" : Replicate(0, 4)}, # PixelF[15:8]
{"data": Replicate(C(pix_fmt[pix_size] & 0xFF, char_width), 4), "k" : Replicate(0, 4)}, # PixelF[7:0]
2025-01-14 15:22:50 +08:00
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x00000000, word_width), "k" : Replicate(0, 4)},
{"data": C(0x51C243EA, word_width), "k" : Replicate(0, 4), "eop":0}, # fake crc
2025-01-10 15:05:10 +08:00
]
# pixel data
base = 0
for _ in range(y_size):
pix = []
for _ in range(x_size):
base += 1
pix.append(base)
print(pix)
packed = 0
for i, p in enumerate(pix):
packed += p << i*pix_size
# print(f"{packed:08X}")
# new line indicator
paks += [
2025-01-14 15:22:50 +08:00
{"data": C(0x7C7C7C7C, word_width), "k" : Replicate(1, 4)},
{"data": C(0x02020202, word_width), "k" : Replicate(0, 4)},
2025-01-10 15:05:10 +08:00
]
for i in range(l_size):
2025-01-14 15:22:50 +08:00
serialized = (packed & (0xFFFF_FFFF << i*word_width)) >> i*word_width
2025-01-10 15:05:10 +08:00
print(f"{serialized:08X}")
2025-01-14 15:22:50 +08:00
paks.append({"data": C(serialized, word_width), "k" : Replicate(0, 4)})
2025-01-13 16:35:34 +08:00
2025-01-14 15:22:50 +08:00
paks.append({"data": C(0xCB5DCDD6, word_width), "k" : Replicate(0, 4), "eop": 0}) # fake crc
2025-01-10 15:05:10 +08:00
yield from packet_sim(paks)
run_simulation(dut, testbench_fake_data(), vcd_name="sim-cxp.vcd")