command: memorize data on RX path before presenting it to the user
This commit is contained in:
parent
d970bfb140
commit
0a1403cec5
|
@ -1,12 +1,14 @@
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
from migen.genlib.fsm import FSM, NextState
|
from migen.genlib.fsm import FSM, NextState
|
||||||
|
from migen.actorlib.fifo import SyncFIFO as FIFO
|
||||||
|
|
||||||
from lib.sata.common import *
|
from lib.sata.common import *
|
||||||
|
|
||||||
tx_to_rx = [
|
tx_to_rx = [
|
||||||
("write", 1),
|
("write", 1),
|
||||||
("read", 1),
|
("read", 1),
|
||||||
("identify", 1)
|
("identify", 1),
|
||||||
|
("count", 4)
|
||||||
]
|
]
|
||||||
|
|
||||||
rx_to_tx = [
|
rx_to_tx = [
|
||||||
|
@ -108,6 +110,7 @@ class SATACommandTX(Module):
|
||||||
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.identify.eq(sink.identify),
|
to_rx.identify.eq(sink.identify),
|
||||||
|
to_rx.count.eq(sink.count)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -119,6 +122,10 @@ class SATACommandRX(Module):
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
cmd_fifo = FIFO(command_rx_cmd_description(32), 2) # Note: ideally depth=1
|
||||||
|
data_fifo = InsertReset(FIFO(command_rx_data_description(32), sector_size*max_count//4, buffered=True))
|
||||||
|
self.submodules += cmd_fifo, data_fifo
|
||||||
|
|
||||||
def test_type(name):
|
def test_type(name):
|
||||||
return transport.source.type == fis_types[name]
|
return transport.source.type == fis_types[name]
|
||||||
|
|
||||||
|
@ -158,12 +165,10 @@ class SATACommandRX(Module):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("PRESENT_WRITE_RESPONSE",
|
fsm.act("PRESENT_WRITE_RESPONSE",
|
||||||
source.stb.eq(1),
|
cmd_fifo.sink.stb.eq(1),
|
||||||
source.sop.eq(1),
|
cmd_fifo.sink.write.eq(1),
|
||||||
source.eop.eq(1),
|
cmd_fifo.sink.success.eq(1),
|
||||||
source.write.eq(1),
|
If(cmd_fifo.sink.stb & cmd_fifo.sink.ack,
|
||||||
source.success.eq(1),
|
|
||||||
If(source.stb & source.ack,
|
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -177,14 +182,12 @@ class SATACommandRX(Module):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("PRESENT_READ_DATA",
|
fsm.act("PRESENT_READ_DATA",
|
||||||
source.stb.eq(transport.source.stb),
|
data_fifo.sink.stb.eq(transport.source.stb),
|
||||||
source.read.eq(~identify),
|
data_fifo.sink.sop.eq(transport.source.sop),
|
||||||
source.identify.eq(identify),
|
data_fifo.sink.eop.eq(transport.source.eop),
|
||||||
source.sop.eq(transport.source.sop),
|
data_fifo.sink.data.eq(transport.source.data),
|
||||||
source.eop.eq(transport.source.eop),
|
transport.source.ack.eq(data_fifo.sink.ack),
|
||||||
source.data.eq(transport.source.data),
|
If(data_fifo.sink.stb & data_fifo.sink.eop & data_fifo.sink.ack,
|
||||||
transport.source.ack.eq(source.ack),
|
|
||||||
If(source.stb & source.eop & source.ack,
|
|
||||||
NextState("WAIT_READ_REG_D2H")
|
NextState("WAIT_READ_REG_D2H")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -197,13 +200,69 @@ class SATACommandRX(Module):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("PRESENT_READ_RESPONSE",
|
fsm.act("PRESENT_READ_RESPONSE",
|
||||||
|
cmd_fifo.sink.stb.eq(1),
|
||||||
|
cmd_fifo.sink.read.eq(~identify),
|
||||||
|
cmd_fifo.sink.identify.eq(identify),
|
||||||
|
cmd_fifo.sink.success.eq(1),
|
||||||
|
cmd_fifo.sink.failed.eq(0),
|
||||||
|
If(~cmd_fifo.fifo.readable, # Note: simulate a depth=1 fifo
|
||||||
|
If(cmd_fifo.sink.stb & cmd_fifo.sink.ack,
|
||||||
|
If(cmd_fifo.sink.failed,
|
||||||
|
data_fifo.reset.eq(1)
|
||||||
|
),
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
out_fsm = FSM(reset_state="IDLE")
|
||||||
|
self.submodules += out_fsm
|
||||||
|
|
||||||
|
out_fsm.act("IDLE",
|
||||||
|
If(cmd_fifo.source.stb & cmd_fifo.source.write,
|
||||||
|
NextState("PRESENT_WRITE_RESPONSE"),
|
||||||
|
).Elif(cmd_fifo.source.stb & (cmd_fifo.source.read | cmd_fifo.source.identify),
|
||||||
|
If(cmd_fifo.source.success,
|
||||||
|
NextState("PRESENT_READ_RESPONSE_SUCCESS"),
|
||||||
|
).Else(
|
||||||
|
NextState("PRESENT_READ_RESPONSE_FAILED"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
out_fsm.act("PRESENT_WRITE_RESPONSE",
|
||||||
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(~identify),
|
source.write.eq(1),
|
||||||
source.identify.eq(identify),
|
source.success.eq(cmd_fifo.source.success),
|
||||||
source.success.eq(1),
|
|
||||||
If(source.stb & source.ack,
|
If(source.stb & source.ack,
|
||||||
|
cmd_fifo.source.ack.eq(1),
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
out_fsm.act("PRESENT_READ_RESPONSE_SUCCESS",
|
||||||
|
source.stb.eq(data_fifo.source.stb),
|
||||||
|
source.read.eq(cmd_fifo.source.read),
|
||||||
|
source.identify.eq(cmd_fifo.source.identify),
|
||||||
|
source.success.eq(1),
|
||||||
|
source.sop.eq(data_fifo.source.sop),
|
||||||
|
source.eop.eq(data_fifo.source.eop),
|
||||||
|
source.data.eq(data_fifo.source.data),
|
||||||
|
data_fifo.source.ack.eq(source.ack),
|
||||||
|
If(source.stb & source.eop & source.ack,
|
||||||
|
cmd_fifo.source.ack.eq(1),
|
||||||
|
NextState("IDLE")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
out_fsm.act("PRESENT_READ_RESPONSE_FAILED",
|
||||||
|
source.stb.eq(1),
|
||||||
|
source.sop.eq(1),
|
||||||
|
source.eop.eq(1),
|
||||||
|
source.read.eq(cmd_fifo.source.read),
|
||||||
|
source.identify.eq(cmd_fifo.source.identify),
|
||||||
|
source.failed.eq(1),
|
||||||
|
If(source.stb & source.ack,
|
||||||
|
cmd_fifo.source.ack.eq(1),
|
||||||
NextState("IDLE")
|
NextState("IDLE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -213,7 +272,7 @@ class SATACommandRX(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
class SATACommand(Module):
|
class SATACommand(Module):
|
||||||
def __init__(self, transport, sector_size=512, max_count=16):
|
def __init__(self, transport, sector_size=512, max_count=4):
|
||||||
if max_count*sector_size > 8192:
|
if max_count*sector_size > 8192:
|
||||||
raise ValueError("sector_size x max_count must be <= 2048")
|
raise ValueError("sector_size x max_count must be <= 2048")
|
||||||
self.submodules.tx = SATACommandTX(transport, sector_size)
|
self.submodules.tx = SATACommandTX(transport, sector_size)
|
||||||
|
|
|
@ -164,3 +164,19 @@ def command_rx_description(dw):
|
||||||
("data", dw)
|
("data", dw)
|
||||||
]
|
]
|
||||||
return EndpointDescription(layout, packetized=True)
|
return EndpointDescription(layout, packetized=True)
|
||||||
|
|
||||||
|
def command_rx_cmd_description(dw):
|
||||||
|
layout = [
|
||||||
|
("write", 1),
|
||||||
|
("read", 1),
|
||||||
|
("identify", 1),
|
||||||
|
("success", 1),
|
||||||
|
("failed", 1)
|
||||||
|
]
|
||||||
|
return EndpointDescription(layout, packetized=False)
|
||||||
|
|
||||||
|
def command_rx_data_description(dw):
|
||||||
|
layout = [
|
||||||
|
("data", dw)
|
||||||
|
]
|
||||||
|
return EndpointDescription(layout, packetized=True)
|
|
@ -137,7 +137,6 @@ class TB(Module):
|
||||||
yield from self.streamer.send(read_packet)
|
yield from self.streamer.send(read_packet)
|
||||||
yield from self.logger.receive()
|
yield from self.logger.receive()
|
||||||
read_data = self.logger.packet
|
read_data = self.logger.packet
|
||||||
yield from self.logger.receive()
|
|
||||||
|
|
||||||
# check results
|
# check results
|
||||||
s, l, e = check(write_data, read_data)
|
s, l, e = check(write_data, read_data)
|
||||||
|
|
Loading…
Reference in New Issue