link: check CRC on RX path

This commit is contained in:
Florent Kermarrec 2014-12-25 13:11:22 +01:00
parent 5575ecbcb2
commit c08c0ffc4e
6 changed files with 42 additions and 15 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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 += [

View File

@ -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)

View File

@ -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):

View File

@ -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,