]
class SATALinkTX(Module):
- def __init__(self, phy):
+ def __init__(self, phy, disable_cont=False):
self.sink = Sink(link_description(32))
self.from_rx = Sink(from_rx)
# inserter CONT and scrambled data between
# CONT and next primitive
- self.cont = cont = SATACONTInserter(phy_description(32), disable=True)
+ self.cont = cont = SATACONTInserter(phy_description(32), disable=False)
# datas / primitives mux
insert = Signal(32)
]
class SATALink(Module):
- def __init__(self, phy):
- self.tx = SATALinkTX(phy)
+ def __init__(self, phy, disable_tx_cont=False):
+ self.tx = SATALinkTX(phy, disable_tx_cont)
self.rx = SATALinkRX(phy)
self.comb += Record.connect(self.rx.to_tx, self.tx.from_rx)
self.sink, self.source = self.tx.sink, self.rx.source
selfp.source.stb = 1
if self.source.description.packetized:
selfp.source.sop = 1
- self.source_data = self.packet.pop(0)
if len(self.packet) > 0:
+ self.source_data = self.packet.pop(0)
if hasattr(selfp.source, "data"):
selfp.source.data = self.source_data
else:
def print_transport(s):
print_with_prefix(s, "[TRN]: ")
+def _big2little(v):
+ return int.from_bytes(v.to_bytes(4, byteorder='big'), "little")
+
+def _little2big(v):
+ r = int.from_bytes(v.to_bytes(4, byteorder='little'), "big")
+ return r
+
def get_field_data(field, packet):
- return (packet[field.dword] >> field.offset) & (2**field.width-1)
+ return (_little2big(packet[field.dword]) >> field.offset) & (2**field.width-1)
class FIS:
def __init__(self, packet, description, direction="H2D"):
def encode(self):
for k, v in self.description.items():
- self.packet[v.dword] |= (getattr(self, k) << v.offset)
+ self.packet[v.dword] |= _big2little((getattr(self, k) << v.offset))
def __repr__(self):
if self.direction == "H2D":
def __repr__(self):
r = "UNKNOWN\n"
if self.direction == "H2D":
- r += ">>>>>>>>\\n"
+ r += ">>>>>>>>\n"
else:
r += "<<<<<<<<\n"
for dword in self.packet:
print_transport(fis)
def callback(self, packet):
- fis_type = packet[0] & 0xff
+ fis_type = _little2big(packet[0]) & 0xff
if fis_type == fis_types["REG_H2D"]:
fis = FIS_REG_H2D(packet)
elif fis_type == fis_types["REG_D2H"]:
r.append(signal[start:end].eq(item))
return r
+def _change_endianness(v):
+ r = []
+ for i in range(4):
+ r.append(v[8*(3-i):8*(3-i+1)])
+ return Cat(*r)
+
+def _big2little(v):
+ return _change_endianness(v)
+
+def _little2big(v):
+ return _change_endianness(v)
+
class SATATransportTX(Module):
def __init__(self, link):
self.sink = sink = Sink(transport_tx_description(32))
cmd_cases = {}
for i in range(cmd_ndwords):
- cmd_cases[i] = [link.sink.d.eq(encoded_cmd[32*i:32*(i+1)])]
+ cmd_cases[i] = [link.sink.d.eq(_big2little(encoded_cmd[32*i:32*(i+1)]))]
self.comb += \
If(cmd_send,
data_done = Signal()
def test_type(name):
- return link.source.d[:8] == fis_types[name]
+ return link.source.d[24:] == fis_types[name]
self.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("RECEIVE_REG_D2H_CMD",
cmd_len.eq(fis_reg_d2h_cmd_len-1),
cmd_receive.eq(1),
+ link.source.ack.eq(1),
If(cmd_done,
NextState("PRESENT_REG_D2H_CMD")
)
fsm.act("RECEIVE_DMA_ACTIVATE_D2H_CMD",
cmd_len.eq(fis_dma_activate_d2h_cmd_len-1),
cmd_receive.eq(1),
+ link.source.ack.eq(1),
If(cmd_done,
NextState("PRESENT_DMA_ACTIVATE_D2H_CMD")
)
fsm.act("RECEIVE_DATA_CMD",
cmd_len.eq(fis_data_cmd_len-1),
cmd_receive.eq(1),
+ link.source.ack.eq(1),
If(cmd_done,
NextState("PRESENT_DATA")
)
source.sop.eq(data_sop),
source.eop.eq(link.source.eop),
source.data.eq(link.source.d),
+ link.source.ack.eq(source.ack),
If(source.stb & source.eop & source.ack,
NextState("IDLE")
)
cmd_cases = {}
for i in range(cmd_ndwords):
- cmd_cases[i] = [encoded_cmd[32*i:32*(i+1)].eq(link.source.d)]
+ cmd_cases[i] = [encoded_cmd[32*i:32*(i+1)].eq(_little2big(link.source.d))]
self.comb += \
If(cmd_receive & link.source.stb,
Case(counter.value, cmd_cases),
)
self.comb += cmd_done.eq((counter.value == cmd_len) & link.source.ack)
- self.comb += link.source.ack.eq(cmd_receive | (data_receive & source.ack))
class SATATransport(Module):
def __init__(self, link):