1
0
Fork 0

sim: add frame generator & image viewer

This commit is contained in:
morgan 2024-11-11 17:05:57 +08:00
parent 1456010942
commit 6834f136c7
2 changed files with 180 additions and 86 deletions

View File

@ -3,9 +3,14 @@ from misoc.interconnect import stream
from sim_pipeline import * from sim_pipeline import *
from sim_generator import CXPCRC32Inserter from sim_generator import CXPCRC32Inserter
from sim_frame_gen import get_frame_packet
from src.gateware.cxp_pipeline import * from src.gateware.cxp_pipeline import *
import numpy as np
from PIL import Image
class Frame(Module): class Frame(Module):
def __init__(self): def __init__(self):
# to construct correct crc and ack/stb signal # to construct correct crc and ack/stb signal
@ -23,16 +28,17 @@ class Frame(Module):
# no backpressure for sim # no backpressure for sim
self.sync += self.source.ack.eq(1) self.sync += self.source.ack.eq(1)
dut = Frame() dut = Frame()
def check_case(packet=[]): def check_case(packet=[]):
print("=================TEST========================") print("=================TEST========================")
sink = dut.sink sink = dut.sink
stream_pipe = dut.stream_pipe stream_pipe = dut.stream_pipe
for i, p in enumerate(packet): for i, p in enumerate(packet):
yield sink.data.eq(p["data"]) yield sink.data.eq(p["data"])
yield sink.k.eq(p["k"]) yield sink.k.eq(p["k"])
@ -45,23 +51,16 @@ def check_case(packet=[]):
# check cycle result # check cycle result
yield yield
# source = dut.dchar_decoder.source # source = dut.dchar_decoder.source
source = dut.stream_pipe.frame_extractor.sink # source = dut.stream_pipe.frame_extractor.sink
source = dut.sink
print( print(
f"\nCYCLE#{i} : source char = {yield source.data:#X} k = {yield source.k:#X} stb = {yield source.stb} ack = {yield source.ack} eop = {yield source.eop}" f"\nCYCLE#{i} : source char = {yield source.data:#X} k = {yield source.k:#X} stb = {yield source.stb} ack = {yield source.ack} eop = {yield source.eop}"
# f" source dchar = {yield source.dchar:#X} dchar_k = {yield source.dchar_k:#X}"
# f"\nCYCLE#{i} : stream id = {yield decoder.stream_id:#X} pak_tag = {yield decoder.pak_tag:#X}"
# f" stream_pak_size = {yield decoder.stream_pak_size:#X}"
) )
# crc = downconns[1].generator.crc_inserter.crc
# crc = dut.double_buffer.crc
# print(
# f"CYCLE#{i} : crc error = {yield crc.error:#X} crc value = {yield crc.value:#X}"
# f" crc data = {yield crc.data:#X} engine next = {yield crc.engine.next:#X} ce = {yield crc.ce}"
# )
# extra clk cycles # extra clk cycles
cyc = i + 1 cyc = i + 1
img = []
line = -1
for i in range(cyc, cyc + 50): for i in range(cyc, cyc + 50):
yield sink.data.eq(0) yield sink.data.eq(0)
yield sink.k.eq(0) yield sink.k.eq(0)
@ -70,86 +69,61 @@ def check_case(packet=[]):
yield yield
print( print(
f"\nCYCLE#{i} : source char = {yield source.data:#X} k = {yield source.k:#X} stb = {yield source.stb} ack = {yield source.ack} eop = {yield source.eop}" f"\nCYCLE#{i} : source char = {yield source.data:#X} k = {yield source.k:#X} stb = {yield source.stb} ack = {yield source.ack} eop = {yield source.eop}"
# f" source dchar = {yield source.dchar:#X} dchar_k = {yield source.dchar_k:#X}"
# f"\nCYCLE#{i} : stream id = {yield decoder.stream_id:#X} pak_tag = {yield decoder.pak_tag:#X}"
# f" stream_pak_size = {yield decoder.stream_pak_size:#X}"
) )
metadata = dut.stream_pipe.frame_extractor.metadata
img_header_layout = [ frame_extractoer = dut.stream_pipe.frame_extractor
"stream_id", new_line = yield frame_extractoer.new_line
"source_tag", if new_line:
"x_size", img.append([])
"x_offset", line += 1
"y_size",
"y_offset", stb = yield frame_extractoer.source.stb
"l_size", # number of data words per image line data = yield frame_extractoer.source.data
"pixel_format", if stb:
"tap_geo", # CXP use MSB
"flag", img[line].append(np.uint16(data & 0xFFFF))
] img[line].append(np.uint16(data >> 16))
for name in img_header_layout: print(img)
print(f"{name} = {yield getattr(metadata, name):#04X} ", end="")
print() # metadata = dut.stream_pipe.frame_extractor.metadata
# img_header_layout = [
# "stream_id",
# "source_tag",
# "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()
Image.fromarray(np.array(img, dtype=np.uint16)).show()
assert True assert True
def testbench(): def testbench():
# stream_id = 0x01 stream_id = 0x69
streams = [ packet_tag = 0
[ frame_packet = get_frame_packet(stream_id)
{"data": 0x11111111, "k": Replicate(0, 4)}, packet = [
{"data": 0xB105F00D, "k": Replicate(0, 4)}, {"data": Replicate(C(stream_id, char_width), 4), "k": Replicate(0, 4)},
], {"data": Replicate(C(packet_tag, char_width), 4), "k": Replicate(0, 4)},
[ {
{"data": 0x22222222, "k": Replicate(0, 4)}, "data": Replicate(C(len(frame_packet), char_width)[8:], 4),
{"data": 0xC001BEA0, "k": Replicate(0, 4)}, "k": Replicate(0, 4),
], },
[ {
{"data": Replicate(KCode["stream_marker"], 4), "k": Replicate(1, 4)}, "data": Replicate(C(len(frame_packet), char_width)[:8], 4),
{"data": Replicate(C(0x01,char_width), 4), "k": Replicate(0, 4)}, "k": Replicate(0, 4),
},
{"data": Replicate(C(0x02,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x03,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x04,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x05,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x06,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x07,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x08,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x09,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x10,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x11,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x12,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x13,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x14,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x15,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x16,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x17,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x18,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x19,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x20,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x21,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x22,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x23,char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(0x24,char_width), 4), "k": Replicate(0, 4)},
],
] ]
packet += frame_packet
packet = [] packet[-1]["eop"] = 0
for i, s in enumerate(streams):
s[-1]["eop"] = 0
packet += [
{"data": Replicate(C(i % 2, char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(C(i, char_width), 4), "k": Replicate(0, 4)},
{
"data": Replicate(C(len(s) >> 8 & 0xFF, char_width), 4),
"k": Replicate(0, 4),
},
{"data": Replicate(C(len(s) & 0xFF, char_width), 4), "k": Replicate(0, 4)},
*s,
]
yield from check_case(packet) yield from check_case(packet)

120
sim_frame_gen.py Normal file
View File

@ -0,0 +1,120 @@
from migen import *
from misoc.interconnect import stream
from src.gateware.cxp_pipeline import *
from sim_pipeline import *
from PIL import Image
import numpy as np
def get_image_header(
stream_id, source_tag, xsize, xoffset, ysize, yoffset, dsize, pixelF, tag_geo, flag
):
stream_id = C(stream_id, char_width)
source_tag = C(source_tag, 2 * char_width)
xsize = C(xsize, 3 * char_width)
xoffset = C(xoffset, 3 * char_width)
ysize = C(ysize, 3 * char_width)
yoffset = C(yoffset, 3 * char_width)
dsize = C(dsize, 3 * char_width)
pixelF = C(pixelF, 2 * char_width)
tag_geo = C(tag_geo, 2 * char_width)
flag = C(flag, char_width)
assert len(stream_id) == len(flag) == char_width
assert len(source_tag) == len(pixelF) == len(tag_geo) == 2 * char_width
assert len(xsize) == len(xoffset) == len(ysize) == len(yoffset) == 3 * char_width
return [
{"data": Replicate(KCode["stream_marker"], 4), "k": Replicate(1, 4)},
{"data": Replicate(C(0x01, char_width), 4), "k": Replicate(0, 4)},
{"data": Replicate(stream_id, 4), "k": Replicate(0, 4)},
{"data": Replicate(source_tag[8:], 4), "k": Replicate(0, 4)},
{"data": Replicate(source_tag[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(xsize[16:], 4), "k": Replicate(0, 4)},
{"data": Replicate(xsize[8:16], 4), "k": Replicate(0, 4)},
{"data": Replicate(xsize[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(xoffset[16:], 4), "k": Replicate(0, 4)},
{"data": Replicate(xoffset[8:16], 4), "k": Replicate(0, 4)},
{"data": Replicate(xoffset[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(ysize[16:], 4), "k": Replicate(0, 4)},
{"data": Replicate(ysize[8:16], 4), "k": Replicate(0, 4)},
{"data": Replicate(ysize[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(yoffset[16:], 4), "k": Replicate(0, 4)},
{"data": Replicate(yoffset[8:16], 4), "k": Replicate(0, 4)},
{"data": Replicate(yoffset[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(dsize[16:], 4), "k": Replicate(0, 4)},
{"data": Replicate(dsize[8:16], 4), "k": Replicate(0, 4)},
{"data": Replicate(dsize[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(pixelF[8:], 4), "k": Replicate(0, 4)},
{"data": Replicate(pixelF[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(tag_geo[8:], 4), "k": Replicate(0, 4)},
{"data": Replicate(tag_geo[:8], 4), "k": Replicate(0, 4)},
{"data": Replicate(flag, 4), "k": Replicate(0, 4)},
]
def get_line_marker():
return [
{"data": Replicate(KCode["stream_marker"], 4), "k": Replicate(1, 4)},
{"data": Replicate(C(0x02, char_width), 4), "k": Replicate(0, 4)},
]
def get_frame_packet(stream_id, pixel_format="mono16"):
assert pixel_format in ["mono16"]
arr = [[4156, 31078], [65063, 24837]]
source_tag = 0
xsize, ysize = len(arr[0]), len(arr)
xoffset, yoffset = 0, 0
if pixel_format == "mono16":
dsize = xsize // 2
pixelF = 0x0105
tag_geo = 0
flag = 0
packet = []
# Image header
packet += get_image_header(
stream_id,
source_tag,
xsize,
xoffset,
ysize,
yoffset,
dsize,
pixelF,
tag_geo,
flag,
)
for line in arr:
packet += get_line_marker()
if pixel_format == "mono16":
for i in range(len(line)):
if (i % 2) == 0:
if i == len(line) - 1:
print(C(line[i]))
packet += [
{
"data": C(line[i], 4 * char_width),
"k": Replicate(0, 4),
},
]
else:
print(C(line[i], 2 * char_width), C(line[i + 1]))
# CXP use MSB
packet += [
{
"data": Cat(
C(line[i], 2 * char_width),
C(line[i + 1], 2 * char_width),
),
"k": Replicate(0, 4),
},
]
return packet