link: check CRC on RX path
This commit is contained in:
parent
5575ecbcb2
commit
c08c0ffc4e
|
@ -2,14 +2,11 @@ from lib.sata.common import *
|
|||
|
||||
tx_to_rx = [
|
||||
("write", 1),
|
||||
("read", 1),
|
||||
("count", 4)
|
||||
("read", 1)
|
||||
]
|
||||
|
||||
rx_to_tx = [
|
||||
("dma_activate", 1),
|
||||
("data", 1),
|
||||
("reg_d2h", 1)
|
||||
("dma_activate", 1)
|
||||
]
|
||||
|
||||
class SATACommandTX(Module):
|
||||
|
@ -88,8 +85,7 @@ class SATACommandTX(Module):
|
|||
self.comb += [
|
||||
If(sink.stb,
|
||||
to_rx.write.eq(sink.write),
|
||||
to_rx.read.eq(sink.read),
|
||||
to_rx.count.eq(sink.count)
|
||||
to_rx.read.eq(sink.read)
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -139,7 +135,8 @@ class SATACommandRX(Module):
|
|||
fsm.act("PRESENT_WRITE_RESPONSE",
|
||||
cmd_fifo.sink.stb.eq(1),
|
||||
cmd_fifo.sink.write.eq(1),
|
||||
cmd_fifo.sink.success.eq(1),
|
||||
cmd_fifo.sink.success.eq(~transport.source.error),
|
||||
cmd_fifo.sink.failed.eq(transport.source.error),
|
||||
If(cmd_fifo.sink.stb & cmd_fifo.sink.ack,
|
||||
NextState("IDLE")
|
||||
)
|
||||
|
@ -163,6 +160,13 @@ class SATACommandRX(Module):
|
|||
NextState("WAIT_READ_REG_D2H")
|
||||
)
|
||||
)
|
||||
read_error = Signal()
|
||||
self.sync += \
|
||||
If(fsm.ongoing("IDLE"),
|
||||
read_error.eq(1)
|
||||
).Elif(transport.source.stb & transport.source.ack & transport.source.eop,
|
||||
read_error.eq(transport.source.error)
|
||||
)
|
||||
fsm.act("WAIT_READ_REG_D2H",
|
||||
transport.source.ack.eq(1),
|
||||
If(transport.source.stb,
|
||||
|
@ -174,8 +178,8 @@ class SATACommandRX(Module):
|
|||
fsm.act("PRESENT_READ_RESPONSE",
|
||||
cmd_fifo.sink.stb.eq(1),
|
||||
cmd_fifo.sink.read.eq(1),
|
||||
cmd_fifo.sink.success.eq(1),
|
||||
cmd_fifo.sink.failed.eq(0),
|
||||
cmd_fifo.sink.success.eq(~read_error),
|
||||
cmd_fifo.sink.failed.eq(read_error),
|
||||
If(~cmd_fifo.fifo.readable, # Note: simulate a fifo with depth=1
|
||||
If(cmd_fifo.sink.stb & cmd_fifo.sink.ack,
|
||||
If(cmd_fifo.sink.failed,
|
||||
|
|
|
@ -136,7 +136,8 @@ def transport_rx_description(dw):
|
|||
("lba", 48),
|
||||
("device", 8),
|
||||
("count", 16),
|
||||
("data", dw)
|
||||
("data", dw),
|
||||
("error", 1)
|
||||
]
|
||||
return EndpointDescription(layout, packetized=True)
|
||||
|
||||
|
|
|
@ -146,6 +146,12 @@ class SATALinkRX(Module):
|
|||
)
|
||||
self.comb += eop.eq(det == primitives["EOF"])
|
||||
|
||||
crc_error = Signal()
|
||||
self.sync += \
|
||||
If(crc.source.stb & crc.source.eop & crc.source.ack,
|
||||
crc_error.eq(crc.source.error)
|
||||
)
|
||||
|
||||
# small fifo to manage HOLD
|
||||
self.fifo = SyncFIFO(link_description(32), 32)
|
||||
|
||||
|
@ -195,17 +201,31 @@ class SATALinkRX(Module):
|
|||
)
|
||||
)
|
||||
fsm.act("EOF",
|
||||
insert.eq(primitives["R_IP"]),
|
||||
If(det == primitives["WTRM"],
|
||||
NextState("WTRM")
|
||||
)
|
||||
)
|
||||
fsm.act("WTRM",
|
||||
# XXX: check CRC result to return R_ERR or R_OK
|
||||
insert.eq(primitives["R_IP"]),
|
||||
If(~crc_error,
|
||||
NextState("R_OK")
|
||||
).Else(
|
||||
NextState("R_ERR")
|
||||
)
|
||||
)
|
||||
fsm.act("R_OK",
|
||||
insert.eq(primitives["R_OK"]),
|
||||
If(det == primitives["SYNC"],
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
fsm.act("R_ERR",
|
||||
insert.eq(primitives["R_ERR"]),
|
||||
If(det == primitives["SYNC"],
|
||||
NextState("IDLE")
|
||||
)
|
||||
)
|
||||
|
||||
# to TX
|
||||
self.comb += [
|
||||
|
|
|
@ -87,7 +87,7 @@ class SATACRC(Module):
|
|||
width = 32
|
||||
polynom = 0x04C11DB7
|
||||
init = 0x52325032
|
||||
check = 0xC704DD7B
|
||||
check = 0x00000000
|
||||
def __init__(self, dw=32):
|
||||
self.d = Signal(self.width)
|
||||
self.value = Signal(self.width)
|
||||
|
|
|
@ -189,6 +189,7 @@ class LinkLayer(Module):
|
|||
self.tx_packet.done = True
|
||||
elif dword == primitives["R_ERR"]:
|
||||
self.tx_packet.done = True
|
||||
if self.tx_packet.done:
|
||||
self.phy.send(primitives["SYNC"])
|
||||
|
||||
def insert_cont(self):
|
||||
|
|
|
@ -200,6 +200,7 @@ class SATATransportRX(Module):
|
|||
_decode_cmd(encoded_cmd, fis_data_layout, source),
|
||||
source.sop.eq(data_sop),
|
||||
source.eop.eq(link.source.eop),
|
||||
source.error.eq(link.source.error),
|
||||
source.data.eq(link.source.d),
|
||||
link.source.ack.eq(source.ack),
|
||||
If(source.stb & source.eop & source.ack,
|
||||
|
|
Loading…
Reference in New Issue