From c08c0ffc4ec9636882797e7f8c09bd95010d2e0f Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 25 Dec 2014 13:11:22 +0100 Subject: [PATCH] link: check CRC on RX path --- lib/sata/command/__init__.py | 24 ++++++++++++++---------- lib/sata/common.py | 3 ++- lib/sata/link/__init__.py | 22 +++++++++++++++++++++- lib/sata/link/crc.py | 4 ++-- lib/sata/test/hdd.py | 3 ++- lib/sata/transport/__init__.py | 1 + 6 files changed, 42 insertions(+), 15 deletions(-) diff --git a/lib/sata/command/__init__.py b/lib/sata/command/__init__.py index 925ef08f..42ba8931 100644 --- a/lib/sata/command/__init__.py +++ b/lib/sata/command/__init__.py @@ -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, diff --git a/lib/sata/common.py b/lib/sata/common.py index 463e9cd6..98dd3001 100644 --- a/lib/sata/common.py +++ b/lib/sata/common.py @@ -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) diff --git a/lib/sata/link/__init__.py b/lib/sata/link/__init__.py index d4f838cd..e55c2ab2 100644 --- a/lib/sata/link/__init__.py +++ b/lib/sata/link/__init__.py @@ -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 += [ diff --git a/lib/sata/link/crc.py b/lib/sata/link/crc.py index 72157ce5..4d6c67b6 100644 --- a/lib/sata/link/crc.py +++ b/lib/sata/link/crc.py @@ -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) @@ -112,4 +112,4 @@ class SATACRCInserter(CRCInserter): class SATACRCChecker(CRCChecker): def __init__(self, description): - CRCChecker.__init__(self, SATACRC, description) \ No newline at end of file + CRCChecker.__init__(self, SATACRC, description) diff --git a/lib/sata/test/hdd.py b/lib/sata/test/hdd.py index c601c042..8783d069 100644 --- a/lib/sata/test/hdd.py +++ b/lib/sata/test/hdd.py @@ -189,7 +189,8 @@ class LinkLayer(Module): self.tx_packet.done = True elif dword == primitives["R_ERR"]: self.tx_packet.done = True - self.phy.send(primitives["SYNC"]) + if self.tx_packet.done: + self.phy.send(primitives["SYNC"]) def insert_cont(self): self.tx_lasts.pop(0) diff --git a/lib/sata/transport/__init__.py b/lib/sata/transport/__init__.py index f4cb1f6e..6ef14e68 100644 --- a/lib/sata/transport/__init__.py +++ b/lib/sata/transport/__init__.py @@ -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, -- 2.30.2