command: add robustness and simplify RX path

This commit is contained in:
Florent Kermarrec 2015-01-06 18:17:11 +01:00
parent aed1064465
commit 1c03f72252
2 changed files with 25 additions and 41 deletions

View File

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

View File

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