forked from M-Labs/artiq-zynq
pipeline GW: refactor test seq
pipeline GW: refactor test seq pipeline gw: reader clenaup pipeline GW: fix issue pipeline GW: cleanup
This commit is contained in:
parent
faaaa1d135
commit
a363f50357
@ -364,14 +364,14 @@ class Duplicated_Char_Decoder(Module):
|
|||||||
@FullMemoryWE()
|
@FullMemoryWE()
|
||||||
class Control_Packet_Reader(Module):
|
class Control_Packet_Reader(Module):
|
||||||
def __init__(self, buffer_depth, nslot):
|
def __init__(self, buffer_depth, nslot):
|
||||||
self.packet_type = Signal(8)
|
|
||||||
|
|
||||||
self.decode_err = Signal()
|
self.decode_err = Signal()
|
||||||
self.buffer_err = Signal()
|
self.test_err = Signal()
|
||||||
|
self.test_pak = Signal()
|
||||||
|
|
||||||
|
self.buffer_err = Signal()
|
||||||
|
self.write_ptr = Signal(log2_int(nslot))
|
||||||
|
self.read_ptr = Signal.like(self.write_ptr)
|
||||||
|
|
||||||
self.test_err_cnt = Signal(16)
|
|
||||||
self.test_pak_cnt = Signal(16)
|
|
||||||
self.test_cnt_reset = Signal()
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
type = {
|
type = {
|
||||||
@ -387,37 +387,44 @@ class Control_Packet_Reader(Module):
|
|||||||
self.source = stream.Endpoint(word_layout_dchar)
|
self.source = stream.Endpoint(word_layout_dchar)
|
||||||
|
|
||||||
# N buffers for firmware to read packet from
|
# N buffers for firmware to read packet from
|
||||||
|
|
||||||
self.specials.mem = mem = Memory(word_width, nslot*buffer_depth)
|
self.specials.mem = mem = Memory(word_width, nslot*buffer_depth)
|
||||||
self.specials.mem_port = mem_port = mem.get_port(write_capable=True)
|
self.specials.mem_port = mem_port = mem.get_port(write_capable=True)
|
||||||
|
buf_mem_we = Signal.like(mem_port.we)
|
||||||
|
buf_mem_dat_w = Signal.like(mem_port.dat_w)
|
||||||
|
buf_mem_adr = Signal.like(mem_port.adr)
|
||||||
|
|
||||||
|
# buffered mem_port to improve timing
|
||||||
# Data packet parser
|
self.sync += [
|
||||||
|
mem_port.we.eq(buf_mem_we),
|
||||||
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
mem_port.dat_w.eq(buf_mem_dat_w),
|
||||||
|
mem_port.adr.eq(buf_mem_adr)
|
||||||
|
]
|
||||||
|
|
||||||
addr_nbits = log2_int(buffer_depth)
|
addr_nbits = log2_int(buffer_depth)
|
||||||
addr = Signal(addr_nbits)
|
addr = Signal(addr_nbits)
|
||||||
cnt = Signal(max=0x100)
|
self.comb += [
|
||||||
|
buf_mem_adr[:addr_nbits].eq(addr),
|
||||||
|
buf_mem_adr[addr_nbits:].eq(self.write_ptr),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Data packet parser
|
||||||
|
self.submodules.fsm = fsm = FSM(reset_state="IDLE")
|
||||||
|
|
||||||
fsm.act("IDLE",
|
fsm.act("IDLE",
|
||||||
NextValue(addr, addr.reset),
|
|
||||||
NextValue(cnt, cnt.reset),
|
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
If((self.sink.stb & (self.sink.dchar == KCode["pak_start"]) & (self.sink.dchar_k == 1)),
|
If((self.sink.stb & (self.sink.dchar == KCode["pak_start"]) & (self.sink.dchar_k == 1)),
|
||||||
NextState("DECODE"),
|
NextState("DECODE"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
test_pak = Signal()
|
|
||||||
buf_mem_we = Signal.like(mem_port.we)
|
|
||||||
buf_mem_dat_w = Signal.like(mem_port.dat_w)
|
|
||||||
buf_mem_adr = Signal.like(mem_port.adr)
|
|
||||||
fsm.act("DECODE",
|
fsm.act("DECODE",
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
If(self.sink.stb,
|
If(self.sink.stb,
|
||||||
Case(self.sink.dchar, {
|
Case(self.sink.dchar, {
|
||||||
type["data_stream"]: NextState("STREAMING"),
|
type["data_stream"]: NextState("STREAMING"),
|
||||||
type["test_packet"]: [
|
type["test_packet"]: [
|
||||||
test_pak.eq(1),
|
self.test_pak.eq(1),
|
||||||
NextState("VERIFY_TEST_PATTERN"),
|
NextState("VERIFY_TEST_PATTERN"),
|
||||||
],
|
],
|
||||||
type["control_ack_no_tag"]:[
|
type["control_ack_no_tag"]:[
|
||||||
@ -463,64 +470,28 @@ class Control_Packet_Reader(Module):
|
|||||||
# Section 9.9.1 (CXP-001-2021)
|
# Section 9.9.1 (CXP-001-2021)
|
||||||
# the received test data packet (0x00, 0x01 ... 0xFF)
|
# the received test data packet (0x00, 0x01 ... 0xFF)
|
||||||
# need to be compared against the local test sequence generator
|
# need to be compared against the local test sequence generator
|
||||||
# TODO: improve this to avoid tight setup/hold time
|
cnt_bytes = [Signal(char_width, reset=i) for i in range(4)]
|
||||||
test_err = Signal()
|
|
||||||
fsm.act("VERIFY_TEST_PATTERN",
|
fsm.act("VERIFY_TEST_PATTERN",
|
||||||
self.sink.ack.eq(1),
|
self.sink.ack.eq(1),
|
||||||
If(self.sink.stb,
|
If(self.sink.stb,
|
||||||
If(((self.sink.dchar == KCode["pak_end"]) & (self.sink.dchar_k == 1)),
|
If(((self.sink.dchar == KCode["pak_end"]) & (self.sink.dchar_k == 1)),
|
||||||
|
[NextValue(cnt, cnt.reset) for cnt in cnt_bytes],
|
||||||
NextState("IDLE"),
|
NextState("IDLE"),
|
||||||
).Else(
|
).Else(
|
||||||
If(self.sink.data[:8] != cnt,
|
[
|
||||||
test_err.eq(1),
|
If(self.sink.data[8 * i : 8 * (i + 1)] != cnt,
|
||||||
).Elif(self.sink.data[8:16] != cnt + 1,
|
self.test_err.eq(1),
|
||||||
test_err.eq(1),
|
),
|
||||||
).Elif(self.sink.data[16:24] != cnt + 2,
|
If(cnt == 0xFC + i,
|
||||||
test_err.eq(1),
|
NextValue(cnt, cnt.reset),
|
||||||
).Elif(self.sink.data[24:] != cnt + 3,
|
).Else(NextValue(cnt, cnt + 4)),
|
||||||
test_err.eq(1),
|
]
|
||||||
),
|
for i, cnt in enumerate(cnt_bytes)
|
||||||
|
|
||||||
If(cnt == 0xFC,
|
|
||||||
NextValue(cnt, cnt.reset),
|
|
||||||
).Else(
|
|
||||||
NextValue(cnt, cnt + 4)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: move this out of this module
|
|
||||||
self.sync += [
|
|
||||||
If(self.test_cnt_reset,
|
|
||||||
self.test_err_cnt.eq(self.test_err_cnt.reset),
|
|
||||||
).Elif(test_err,
|
|
||||||
self.test_err_cnt.eq(self.test_err_cnt + 1),
|
|
||||||
),
|
|
||||||
If(self.test_cnt_reset,
|
|
||||||
self.test_pak_cnt.eq(self.test_pak_cnt.reset),
|
|
||||||
).Elif(test_pak,
|
|
||||||
self.test_pak_cnt.eq(self.test_pak_cnt + 1),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
# buffered mem_port to improve timing
|
|
||||||
self.sync += [
|
|
||||||
mem_port.we.eq(buf_mem_we),
|
|
||||||
mem_port.dat_w.eq(buf_mem_dat_w),
|
|
||||||
mem_port.adr.eq(buf_mem_adr)
|
|
||||||
]
|
|
||||||
|
|
||||||
# TODO: move write_ptr_sys out of this module
|
|
||||||
write_ptr = Signal(log2_int(nslot))
|
|
||||||
self.write_ptr_sys = Signal.like(write_ptr)
|
|
||||||
self.specials += MultiReg(write_ptr, self.write_ptr_sys),
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
buf_mem_adr[:addr_nbits].eq(addr),
|
|
||||||
buf_mem_adr[addr_nbits:].eq(write_ptr),
|
|
||||||
]
|
|
||||||
|
|
||||||
fsm.act("LOAD_BUFFER",
|
fsm.act("LOAD_BUFFER",
|
||||||
buf_mem_we.eq(0),
|
buf_mem_we.eq(0),
|
||||||
@ -535,21 +506,22 @@ class Control_Packet_Reader(Module):
|
|||||||
If(addr == buffer_depth - 1,
|
If(addr == buffer_depth - 1,
|
||||||
# discard the packet
|
# discard the packet
|
||||||
self.buffer_err.eq(1),
|
self.buffer_err.eq(1),
|
||||||
|
NextValue(addr, addr.reset),
|
||||||
NextState("IDLE"),
|
NextState("IDLE"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.read_ptr_rx = Signal.like(write_ptr)
|
|
||||||
fsm.act("MOVE_BUFFER_PTR",
|
fsm.act("MOVE_BUFFER_PTR",
|
||||||
self.sink.ack.eq(0),
|
self.sink.ack.eq(0),
|
||||||
If(write_ptr + 1 == self.read_ptr_rx,
|
If(self.write_ptr + 1 == self.read_ptr,
|
||||||
# if next one hasn't been read, overwrite the current buffer when new packet comes in
|
# if next one hasn't been read, overwrite the current buffer when new packet comes in
|
||||||
self.buffer_err.eq(1),
|
self.buffer_err.eq(1),
|
||||||
).Else(
|
).Else(
|
||||||
NextValue(write_ptr, write_ptr + 1),
|
NextValue(self.write_ptr, self.write_ptr + 1),
|
||||||
),
|
),
|
||||||
|
NextValue(addr, addr.reset),
|
||||||
NextState("IDLE"),
|
NextState("IDLE"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user