command: add robustness and simplify RX path
This commit is contained in:
parent
aed1064465
commit
1c03f72252
|
@ -107,7 +107,7 @@ class SATABIST(Module, AutoCSR):
|
||||||
def __init__(self, sata_con):
|
def __init__(self, sata_con):
|
||||||
self._start = CSR()
|
self._start = CSR()
|
||||||
self._start_sector = CSRStorage(48)
|
self._start_sector = CSRStorage(48)
|
||||||
self._count = CSRStorage(4)
|
self._count = CSRStorage(16)
|
||||||
self._write_only = CSRStorage()
|
self._write_only = CSRStorage()
|
||||||
self._read_only = CSRStorage()
|
self._read_only = CSRStorage()
|
||||||
|
|
||||||
|
|
|
@ -135,16 +135,16 @@ class SATACommandRX(Module):
|
||||||
If(from_tx.write,
|
If(from_tx.write,
|
||||||
NextState("WAIT_WRITE_ACTIVATE_OR_REG_D2H")
|
NextState("WAIT_WRITE_ACTIVATE_OR_REG_D2H")
|
||||||
).Elif(from_tx.read,
|
).Elif(from_tx.read,
|
||||||
NextState("WAIT_READ_DATA")
|
NextState("WAIT_READ_DATA_OR_REG_D2H")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("WAIT_WRITE_ACTIVATE_OR_REG_D2H",
|
fsm.act("WAIT_WRITE_ACTIVATE_OR_REG_D2H",
|
||||||
# XXX: use status and error fields of REG_D2H
|
|
||||||
transport.source.ack.eq(1),
|
transport.source.ack.eq(1),
|
||||||
If(transport.source.stb,
|
If(transport.source.stb,
|
||||||
If(test_type("DMA_ACTIVATE_D2H"),
|
If(test_type("DMA_ACTIVATE_D2H"),
|
||||||
dma_activate.eq(1),
|
dma_activate.eq(1),
|
||||||
).Elif(test_type("REG_D2H"),
|
).Elif(test_type("REG_D2H"),
|
||||||
|
# XXX: use status and error fields of REG_D2H
|
||||||
NextState("PRESENT_WRITE_RESPONSE")
|
NextState("PRESENT_WRITE_RESPONSE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -159,12 +159,15 @@ class SATACommandRX(Module):
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("WAIT_READ_DATA",
|
fsm.act("WAIT_READ_DATA_OR_REG_D2H",
|
||||||
transport.source.ack.eq(1),
|
transport.source.ack.eq(1),
|
||||||
If(transport.source.stb,
|
If(transport.source.stb,
|
||||||
transport.source.ack.eq(0),
|
transport.source.ack.eq(0),
|
||||||
If(test_type("DATA"),
|
If(test_type("DATA"),
|
||||||
NextState("PRESENT_READ_DATA")
|
NextState("PRESENT_READ_DATA")
|
||||||
|
).Elif(test_type("REG_D2H"),
|
||||||
|
# XXX: use status and error fields of REG_D2H
|
||||||
|
NextState("PRESENT_READ_RESPONSE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -178,7 +181,7 @@ class SATACommandRX(Module):
|
||||||
self.dwords_counter.ce.eq(~read_done),
|
self.dwords_counter.ce.eq(~read_done),
|
||||||
If(data_buffer.sink.eop,
|
If(data_buffer.sink.eop,
|
||||||
If(read_done,
|
If(read_done,
|
||||||
NextState("WAIT_READ_REG_D2H")
|
NextState("WAIT_READ_DATA_OR_REG_D2H")
|
||||||
).Else(
|
).Else(
|
||||||
NextState("PRESENT_READ_RESPONSE")
|
NextState("PRESENT_READ_RESPONSE")
|
||||||
)
|
)
|
||||||
|
@ -187,20 +190,11 @@ class SATACommandRX(Module):
|
||||||
)
|
)
|
||||||
read_error = Signal()
|
read_error = Signal()
|
||||||
self.sync += \
|
self.sync += \
|
||||||
If(fsm.ongoing("WAIT_READ_DATA"),
|
If(fsm.before_entering("PRESENT_READ_DATA"),
|
||||||
read_error.eq(1)
|
read_error.eq(1)
|
||||||
).Elif(transport.source.stb & transport.source.ack & transport.source.eop,
|
).Elif(transport.source.stb & transport.source.ack & transport.source.eop,
|
||||||
read_error.eq(transport.source.error)
|
read_error.eq(transport.source.error)
|
||||||
)
|
)
|
||||||
fsm.act("WAIT_READ_REG_D2H",
|
|
||||||
# XXX: use status and error fields of REG_D2H
|
|
||||||
transport.source.ack.eq(1),
|
|
||||||
If(transport.source.stb,
|
|
||||||
If(test_type("REG_D2H"),
|
|
||||||
NextState("PRESENT_READ_RESPONSE")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
fsm.act("PRESENT_READ_RESPONSE",
|
fsm.act("PRESENT_READ_RESPONSE",
|
||||||
cmd_buffer.sink.stb.eq(1),
|
cmd_buffer.sink.stb.eq(1),
|
||||||
cmd_buffer.sink.read.eq(1),
|
cmd_buffer.sink.read.eq(1),
|
||||||
|
@ -214,57 +208,47 @@ class SATACommandRX(Module):
|
||||||
If(read_done,
|
If(read_done,
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
).Else(
|
).Else(
|
||||||
NextState("WAIT_READ_DATA")
|
NextState("WAIT_READ_DATA_OR_REG_D2H")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.out_fsm = out_fsm = FSM(reset_state="IDLE")
|
self.out_fsm = out_fsm = FSM(reset_state="IDLE")
|
||||||
out_fsm.act("IDLE",
|
out_fsm.act("IDLE",
|
||||||
If(cmd_buffer.source.stb & cmd_buffer.source.write,
|
If(cmd_buffer.source.stb,
|
||||||
NextState("PRESENT_WRITE_RESPONSE"),
|
If(cmd_buffer.source.read & cmd_buffer.source.success,
|
||||||
).Elif(cmd_buffer.source.stb & (cmd_buffer.source.read),
|
NextState("PRESENT_RESPONSE_WITH_DATA"),
|
||||||
If(cmd_buffer.source.success,
|
|
||||||
NextState("PRESENT_READ_RESPONSE_SUCCESS"),
|
|
||||||
).Else(
|
).Else(
|
||||||
NextState("PRESENT_READ_RESPONSE_FAILED"),
|
NextState("PRESENT_RESPONSE_WITHOUT_DATA"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# XXX try to merge PRESENT_XXX states
|
|
||||||
out_fsm.act("PRESENT_WRITE_RESPONSE",
|
self.comb += [
|
||||||
source.stb.eq(1),
|
source.write.eq(cmd_buffer.source.write),
|
||||||
source.sop.eq(1),
|
source.read.eq(cmd_buffer.source.read),
|
||||||
source.eop.eq(1),
|
|
||||||
source.write.eq(1),
|
|
||||||
source.last.eq(cmd_buffer.source.last),
|
source.last.eq(cmd_buffer.source.last),
|
||||||
source.success.eq(cmd_buffer.source.success),
|
source.success.eq(cmd_buffer.source.success),
|
||||||
If(source.stb & source.ack,
|
source.failed.eq(cmd_buffer.source.success),
|
||||||
cmd_buffer.source.ack.eq(1),
|
]
|
||||||
NextState("IDLE")
|
|
||||||
)
|
out_fsm.act("PRESENT_RESPONSE_WITH_DATA",
|
||||||
)
|
|
||||||
out_fsm.act("PRESENT_READ_RESPONSE_SUCCESS",
|
|
||||||
source.stb.eq(data_buffer.source.stb),
|
source.stb.eq(data_buffer.source.stb),
|
||||||
source.read.eq(cmd_buffer.source.read),
|
|
||||||
source.success.eq(1),
|
|
||||||
source.last.eq(cmd_buffer.source.last),
|
|
||||||
source.sop.eq(data_buffer.source.sop),
|
source.sop.eq(data_buffer.source.sop),
|
||||||
source.eop.eq(data_buffer.source.eop),
|
source.eop.eq(data_buffer.source.eop),
|
||||||
|
|
||||||
source.data.eq(data_buffer.source.data),
|
source.data.eq(data_buffer.source.data),
|
||||||
data_buffer.source.ack.eq(source.ack),
|
data_buffer.source.ack.eq(source.ack),
|
||||||
|
|
||||||
If(source.stb & source.eop & source.ack,
|
If(source.stb & source.eop & source.ack,
|
||||||
cmd_buffer.source.ack.eq(1),
|
cmd_buffer.source.ack.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
out_fsm.act("PRESENT_READ_RESPONSE_FAILED",
|
out_fsm.act("PRESENT_RESPONSE_WITHOUT_DATA",
|
||||||
source.stb.eq(1),
|
source.stb.eq(1),
|
||||||
source.sop.eq(1),
|
source.sop.eq(1),
|
||||||
source.eop.eq(1),
|
source.eop.eq(1),
|
||||||
source.read.eq(cmd_buffer.source.read),
|
|
||||||
source.last.eq(cmd_buffer.source.last),
|
|
||||||
source.failed.eq(1),
|
|
||||||
If(source.stb & source.ack,
|
If(source.stb & source.ack,
|
||||||
cmd_buffer.source.ack.eq(1),
|
cmd_buffer.source.ack.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
|
|
Loading…
Reference in New Issue