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 = [ tx_to_rx = [
("write", 1), ("write", 1),
("read", 1), ("read", 1)
("count", 4)
] ]
rx_to_tx = [ rx_to_tx = [
("dma_activate", 1), ("dma_activate", 1)
("data", 1),
("reg_d2h", 1)
] ]
class SATACommandTX(Module): class SATACommandTX(Module):
@ -88,8 +85,7 @@ class SATACommandTX(Module):
self.comb += [ self.comb += [
If(sink.stb, If(sink.stb,
to_rx.write.eq(sink.write), to_rx.write.eq(sink.write),
to_rx.read.eq(sink.read), to_rx.read.eq(sink.read)
to_rx.count.eq(sink.count)
) )
] ]
@ -139,7 +135,8 @@ class SATACommandRX(Module):
fsm.act("PRESENT_WRITE_RESPONSE", fsm.act("PRESENT_WRITE_RESPONSE",
cmd_fifo.sink.stb.eq(1), cmd_fifo.sink.stb.eq(1),
cmd_fifo.sink.write.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, If(cmd_fifo.sink.stb & cmd_fifo.sink.ack,
NextState("IDLE") NextState("IDLE")
) )
@ -163,6 +160,13 @@ class SATACommandRX(Module):
NextState("WAIT_READ_REG_D2H") 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", fsm.act("WAIT_READ_REG_D2H",
transport.source.ack.eq(1), transport.source.ack.eq(1),
If(transport.source.stb, If(transport.source.stb,
@ -174,8 +178,8 @@ class SATACommandRX(Module):
fsm.act("PRESENT_READ_RESPONSE", fsm.act("PRESENT_READ_RESPONSE",
cmd_fifo.sink.stb.eq(1), cmd_fifo.sink.stb.eq(1),
cmd_fifo.sink.read.eq(1), cmd_fifo.sink.read.eq(1),
cmd_fifo.sink.success.eq(1), cmd_fifo.sink.success.eq(~read_error),
cmd_fifo.sink.failed.eq(0), cmd_fifo.sink.failed.eq(read_error),
If(~cmd_fifo.fifo.readable, # Note: simulate a fifo with depth=1 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.stb & cmd_fifo.sink.ack,
If(cmd_fifo.sink.failed, If(cmd_fifo.sink.failed,

View File

@ -136,7 +136,8 @@ def transport_rx_description(dw):
("lba", 48), ("lba", 48),
("device", 8), ("device", 8),
("count", 16), ("count", 16),
("data", dw) ("data", dw),
("error", 1)
] ]
return EndpointDescription(layout, packetized=True) return EndpointDescription(layout, packetized=True)

View File

@ -146,6 +146,12 @@ class SATALinkRX(Module):
) )
self.comb += eop.eq(det == primitives["EOF"]) 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 # small fifo to manage HOLD
self.fifo = SyncFIFO(link_description(32), 32) self.fifo = SyncFIFO(link_description(32), 32)
@ -195,17 +201,31 @@ class SATALinkRX(Module):
) )
) )
fsm.act("EOF", fsm.act("EOF",
insert.eq(primitives["R_IP"]),
If(det == primitives["WTRM"], If(det == primitives["WTRM"],
NextState("WTRM") NextState("WTRM")
) )
) )
fsm.act("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"]), insert.eq(primitives["R_OK"]),
If(det == primitives["SYNC"], If(det == primitives["SYNC"],
NextState("IDLE") NextState("IDLE")
) )
) )
fsm.act("R_ERR",
insert.eq(primitives["R_ERR"]),
If(det == primitives["SYNC"],
NextState("IDLE")
)
)
# to TX # to TX
self.comb += [ self.comb += [

View File

@ -87,7 +87,7 @@ class SATACRC(Module):
width = 32 width = 32
polynom = 0x04C11DB7 polynom = 0x04C11DB7
init = 0x52325032 init = 0x52325032
check = 0xC704DD7B check = 0x00000000
def __init__(self, dw=32): def __init__(self, dw=32):
self.d = Signal(self.width) self.d = Signal(self.width)
self.value = Signal(self.width) self.value = Signal(self.width)
@ -112,4 +112,4 @@ class SATACRCInserter(CRCInserter):
class SATACRCChecker(CRCChecker): class SATACRCChecker(CRCChecker):
def __init__(self, description): def __init__(self, description):
CRCChecker.__init__(self, SATACRC, description) CRCChecker.__init__(self, SATACRC, description)

View File

@ -189,7 +189,8 @@ class LinkLayer(Module):
self.tx_packet.done = True self.tx_packet.done = True
elif dword == primitives["R_ERR"]: elif dword == primitives["R_ERR"]:
self.tx_packet.done = True self.tx_packet.done = True
self.phy.send(primitives["SYNC"]) if self.tx_packet.done:
self.phy.send(primitives["SYNC"])
def insert_cont(self): def insert_cont(self):
self.tx_lasts.pop(0) self.tx_lasts.pop(0)

View File

@ -200,6 +200,7 @@ class SATATransportRX(Module):
_decode_cmd(encoded_cmd, fis_data_layout, source), _decode_cmd(encoded_cmd, fis_data_layout, source),
source.sop.eq(data_sop), source.sop.eq(data_sop),
source.eop.eq(link.source.eop), source.eop.eq(link.source.eop),
source.error.eq(link.source.error),
source.data.eq(link.source.d), source.data.eq(link.source.d),
link.source.ack.eq(source.ack), link.source.ack.eq(source.ack),
If(source.stb & source.eop & source.ack, If(source.stb & source.eop & source.ack,