forked from M-Labs/artiq-zynq
310 lines
15 KiB
Python
310 lines
15 KiB
Python
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 *
|
|
|
|
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()
|
|
self.pipeline = ROI_Pipeline()
|
|
|
|
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
|
|
self.source = pipeline[-1].source
|
|
|
|
|
|
|
|
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()
|
|
assert True
|
|
|
|
|
|
def testbench():
|
|
paks = [
|
|
{"data": C(0x7C7C7C7C, word_dw), "k" : Replicate(1, 4)},
|
|
{"data": C(0x01010101, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # stream id
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x6AEFACF6, word_dw), "k" : Replicate(0, 4), "eop":0}, # crc
|
|
|
|
{"data": C(0x02020202, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # Xsize[23:16]
|
|
{"data": C(0x09090909, word_dw), "k" : Replicate(0, 4)}, # Xsize[15:8]
|
|
{"data": C(0x90909090, word_dw), "k" : Replicate(0, 4)}, # Xsize[7:0]
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x8EE1DAA1, word_dw), "k" : Replicate(0, 4), "eop":0}, # crc
|
|
|
|
{"data": C(0x08080808, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x08080808, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # DsizeL[23:16]
|
|
{"data": C(0x02020202, word_dw), "k" : Replicate(0, 4)}, # DsizeL[15:8]
|
|
{"data": C(0x64646464, word_dw), "k" : Replicate(0, 4)}, # DsizeL[7:0]
|
|
{"data": C(0x01010101, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x01010101, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x51C243EA, word_dw), "k" : Replicate(0, 4), "eop":0}, # crc
|
|
|
|
# the new line + pixel data
|
|
{"data": C(0x7C7C7C7C, word_dw), "k" : Replicate(1, 4)},
|
|
{"data": C(0x02020202, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0D0D0C0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0C0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0C0B0D, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0D0B0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0C0C0C0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0B0B, 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(0x0B0B0A0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0C0B0B, 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(0x0C0C0B0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0C0B0B0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0C0C0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0C0B0C0B, 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(0x0C0B0B0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0C0B0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0D0A, 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(0x0B0B0C0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0C0C0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0C0C0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0A0B0D, 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(0x0D0C0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0A0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0D0D0B0A, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0C0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0C0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0C0B0B0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0C0C0B, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0B0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x0B0B0B0C, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0xCB5DCDD6, word_dw), "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)
|
|
|
|
|
|
def testbench_fake_data():
|
|
# config
|
|
pix_size = 10
|
|
x_size = 7
|
|
y_size = 3
|
|
|
|
|
|
l_size = ceil(x_size*pix_size/32)
|
|
pix_fmt = {
|
|
8: 0x0101,
|
|
10: 0x0102,
|
|
12: 0x0103,
|
|
14: 0x0104,
|
|
16: 0x0105,
|
|
}
|
|
# frame header
|
|
paks = [
|
|
{"data": C(0x7C7C7C7C, word_dw), "k" : Replicate(1, 4)},
|
|
{"data": C(0x01010101, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # stream id
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x6AEFACF6, word_dw), "k" : Replicate(0, 4), "eop":0}, # fake crc
|
|
|
|
{"data": C(0x02020202, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # Xsize[23:16]
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # Xsize[15:8]
|
|
{"data": Replicate(C(x_size, char_width), 4), "k" : Replicate(0, 4)}, # Xsize[7:0]
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # Ysize[23:16]
|
|
{"data": C(0x8EE1DAA1, word_dw), "k" : Replicate(0, 4), "eop":0}, # fake crc
|
|
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # Ysize[15:8]
|
|
{"data": Replicate(C(y_size, char_width), 4), "k" : Replicate(0, 4)}, # Ysize[7:0]
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x08080808, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # DsizeL[23:16]
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)}, # DsizeL[15:8]
|
|
{"data": Replicate(C(l_size, char_width), 4), "k" : Replicate(0, 4)}, # DsizeL[7:0]
|
|
{"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]
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x00000000, word_dw), "k" : Replicate(0, 4)},
|
|
{"data": C(0x51C243EA, word_dw), "k" : Replicate(0, 4), "eop":0}, # fake crc
|
|
]
|
|
|
|
# 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 += [
|
|
{"data": C(0x7C7C7C7C, word_dw), "k" : Replicate(1, 4)},
|
|
{"data": C(0x02020202, word_dw), "k" : Replicate(0, 4)},
|
|
]
|
|
for i in range(l_size):
|
|
serialized = (packed & (0xFFFF_FFFF << i*word_dw)) >> i*word_dw
|
|
print(f"{serialized:08X}")
|
|
paks.append({"data": C(serialized, word_dw), "k" : Replicate(0, 4)})
|
|
|
|
paks.append({"data": C(0xCB5DCDD6, word_dw), "k" : Replicate(0, 4), "eop": 0}) # fake crc
|
|
|
|
yield from packet_sim(paks)
|
|
|
|
run_simulation(dut, testbench_fake_data(), vcd_name="sim-cxp.vcd")
|