forked from M-Labs/artiq-zynq
sim: add frame generator & image viewer
This commit is contained in:
parent
1456010942
commit
6834f136c7
146
sim_frame.py
146
sim_frame.py
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue