forked from M-Labs/artiq-zynq
sim: add proto frame extractor
This commit is contained in:
parent
18c16062b1
commit
bfd901ddc4
105
sim_pipeline.py
105
sim_pipeline.py
|
@ -263,14 +263,108 @@ class Stream_Parser(Module):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Frame_Decoder(Module):
|
class Frame_Extractor(Module):
|
||||||
def __init__(self):
|
def __init__(self, pixel_format="mono16"):
|
||||||
self.sink = stream.Endpoint(word_layout_dchar)
|
assert pixel_format in ["mono16"]
|
||||||
self.source = stream.Endpoint(word_layout_dchar)
|
pixel_format = {
|
||||||
|
"mono16": C(0x0105, 2*char_width)
|
||||||
|
}
|
||||||
|
self.format_error = Signal()
|
||||||
|
self.decode_err = Signal()
|
||||||
|
|
||||||
|
self.new_frame = Signal()
|
||||||
|
self.new_line = Signal()
|
||||||
|
|
||||||
|
n_metadata_chars = 23
|
||||||
|
self.metadata = Record([
|
||||||
|
("stream_id", char_width),
|
||||||
|
("source_tag", 2*char_width),
|
||||||
|
("x_size", 3*char_width),
|
||||||
|
("x_offset", 3*char_width),
|
||||||
|
("y_size", 3*char_width),
|
||||||
|
("y_offset", 3*char_width),
|
||||||
|
("l_size", 3*char_width), # number of data words per image line
|
||||||
|
("pixel_format", 2*char_width),
|
||||||
|
("tap_geo", 2*char_width),
|
||||||
|
("flag", char_width),
|
||||||
|
])
|
||||||
|
assert len(self.metadata.raw_bits()) == n_metadata_chars*char_width
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
# TODO: decode Image header, line break
|
# TODO: decode Image header, line break
|
||||||
|
self.sink = stream.Endpoint(word_layout_dchar)
|
||||||
|
self.source = stream.Endpoint(word_layout_dchar)
|
||||||
|
|
||||||
|
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||||
|
|
||||||
|
# DEBUG: remove this
|
||||||
|
self.fsm_state = Signal()
|
||||||
|
self.comb += self.fsm_state.eq(fsm.ongoing("IDLE"))
|
||||||
|
|
||||||
|
fsm.act("IDLE",
|
||||||
|
self.sink.ack.eq(1),
|
||||||
|
If((self.sink.stb & (self.sink.dchar == KCode["stream_marker"]) & (self.sink.dchar_k == 1)),
|
||||||
|
NextState("DECODE"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fsm.act("COPY",
|
||||||
|
# until for new line or new frame
|
||||||
|
If((self.sink.stb & (self.sink.dchar == KCode["stream_marker"]) & (self.sink.dchar_k == 1)),
|
||||||
|
self.sink.ack.eq(1),
|
||||||
|
NextState("DECODE"),
|
||||||
|
).Else(
|
||||||
|
self.sink.connect(self.source),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
type = {
|
||||||
|
"new_frame": 0x01,
|
||||||
|
"line_break": 0x02,
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt = Signal(max=n_metadata_chars)
|
||||||
|
fsm.act("DECODE",
|
||||||
|
self.sink.ack.eq(1),
|
||||||
|
If(self.sink.stb,
|
||||||
|
Case(self.sink.dchar, {
|
||||||
|
type["new_frame"]: [
|
||||||
|
self.new_frame.eq(1),
|
||||||
|
NextValue(cnt, cnt.reset),
|
||||||
|
NextState("GET_STREAM_ID"),
|
||||||
|
],
|
||||||
|
type["line_break"]: [
|
||||||
|
self.new_line.eq(1),
|
||||||
|
NextState("COPY"),
|
||||||
|
],
|
||||||
|
"default": [
|
||||||
|
self.decode_err.eq(1),
|
||||||
|
# discard all data until valid frame
|
||||||
|
NextState("IDLE"),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
case = dict(
|
||||||
|
(i, NextValue(self.metadata.raw_bits()[8*i:8*(i+1)], self.sink.dchar))
|
||||||
|
for i in range(n_metadata_chars)
|
||||||
|
)
|
||||||
|
fsm.act("GET_STREAM_ID",
|
||||||
|
self.sink.ack.eq(1),
|
||||||
|
If(self.sink.stb,
|
||||||
|
Case(cnt, case),
|
||||||
|
If(cnt == n_metadata_chars - 1,
|
||||||
|
NextState("COPY"),
|
||||||
|
NextValue(cnt, cnt.reset),
|
||||||
|
).Else(
|
||||||
|
NextValue(cnt, cnt + 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Pixel_Decoder(Module):
|
class Pixel_Decoder(Module):
|
||||||
def __init__(self, pixel_format="mono16"):
|
def __init__(self, pixel_format="mono16"):
|
||||||
|
@ -289,8 +383,9 @@ class Stream_Pipeline(Module):
|
||||||
|
|
||||||
self.submodules.double_buffer = double_buffer = Double_Stream_Buffer(size)
|
self.submodules.double_buffer = double_buffer = Double_Stream_Buffer(size)
|
||||||
self.submodules.parser = parser = Stream_Parser()
|
self.submodules.parser = parser = Stream_Parser()
|
||||||
|
self.submodules.frame_extractor = frame_extractor = Frame_Extractor()
|
||||||
|
|
||||||
pipeline = [double_buffer, parser]
|
pipeline = [double_buffer, parser, frame_extractor]
|
||||||
for s, d in zip(pipeline, pipeline[1:]):
|
for s, d in zip(pipeline, pipeline[1:]):
|
||||||
self.comb += s.source.connect(d.sink)
|
self.comb += s.source.connect(d.sink)
|
||||||
self.sink = pipeline[0].sink
|
self.sink = pipeline[0].sink
|
||||||
|
|
|
@ -125,7 +125,7 @@ def testbench():
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{"data": 0x22222222, "k": Replicate(0, 4)},
|
{"data": 0x22222222, "k": Replicate(0, 4)},
|
||||||
{"data": 0xC00010FF, "k": Replicate(0, 4)},
|
{"data": 0xC001BEA0, "k": Replicate(0, 4)},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{"data": 0x33333333, "k": Replicate(0, 4)},
|
{"data": 0x33333333, "k": Replicate(0, 4)},
|
||||||
|
|
Loading…
Reference in New Issue