from migen.fhdl.std import *
from migen.genlib.fsm import FSM, NextState
+from migen.actorlib.fifo import SyncFIFO
from lib.sata.std import *
from lib.sata.link.crc import SATACRCInserter, SATACRCChecker
from lib.sata.link.scrambler import SATAScrambler
from lib.sata.link.cont import SATACONTInserter, SATACONTRemover
-#TODO:
-# -Test HOLD on RX path
-
from_rx = [
("idle", 1),
("insert", 32),
sop.eq(0)
)
+ # small fifo to manage HOLD
+ self.submodules.fifo = SyncFIFO(link_layout(32), 32)
+
# graph
self.sync += \
If(fsm.ongoing("COPY") & (det == 0),
scrambler.sink.eop.eq(det == primitives["EOF"]),
cont.source.ack.eq(1),
Record.connect(scrambler.source, crc.sink),
- Record.connect(crc.source, self.source)
+ Record.connect(crc.source, self.fifo.sink),
+ Record.connect(self.fifo.source, self.source)
]
# FSM
insert.eq(primitives["HOLDA"])
).Elif(det == primitives["EOF"],
NextState("WTRM")
+ ).Elif(self.fifo.fifo.level > 8,
+ insert.eq(primitives["HOLD"])
)
)
fsm.act("EOF",
self.tx_packet = LinkTXPacket()
self.rx_packet = LinkRXPacket()
self.rx_cont = False
+ self.tx_cont = False
+ self.tx_cont_primitive = 0
self.transport_callback = None
self.rx_packet.ongoing = True
def send(self, dword):
+ if dword == primitives["CONT"]:
+ self.tx_cont = True
+ elif is_primitive(dword):
+ self.tx_cont = False
+ self.tx_cont_primitive = dword
+ if self.tx_cont:
+ dword = self.tx_cont_primitive
+
if self.send_state == "RDY":
self.phy.send(primitives["X_RDY"])
if dword == primitives["R_RDY"]:
self.phy.send(primitives["SOF"])
self.send_state = "DATA"
elif self.send_state == "DATA":
- self.phy.send(self.tx_packet.pop(0))
- if len(self.tx_packet) == 0:
- self.send_state = "EOF"
+ if dword == primitives["HOLD"]:
+ self.phy.send(primitives["HOLDA"])
+ else:
+ self.phy.send(self.tx_packet.pop(0))
+ if len(self.tx_packet) == 0:
+ self.send_state = "EOF"
elif self.send_state == "EOF":
self.phy.send(primitives["EOF"])
self.send_state = "WTRM"
def gen_simulation(self, selfp):
self.tx_packet.done = True
+ self.phy.send(primitives["SYNC"])
while True:
yield from self.phy.receive()
self.phy.send(primitives["SYNC"])
selfp.sink.ack = 1
if selfp.sink.stb == 1 and selfp.sink.sop == 1:
self.packet = LinkRXPacket()
- print("rx : %08x" %selfp.sink.d)
self.packet.append(selfp.sink.d)
elif selfp.sink.stb:
self.packet.append(selfp.sink.d)
class TB(Module):
def __init__(self):
- self.submodules.bfm = BFM(phy_debug=False,
- link_random_level=50, transport_debug=False, transport_loopback=True)
+ self.submodules.bfm = BFM(phy_debug=True,
+ link_random_level=50, transport_debug=True, transport_loopback=True)
self.submodules.link_layer = SATALinkLayer(self.bfm.phy)
self.submodules.streamer = LinkStreamer()
streamer_ack_randomizer = AckRandomizer(link_layout(32), level=50)
self.submodules += streamer_ack_randomizer
self.submodules.logger = LinkLogger()
+ logger_ack_randomizer = AckRandomizer(link_layout(32), level=80)
+ self.submodules += logger_ack_randomizer
self.comb += [
Record.connect(self.streamer.source, streamer_ack_randomizer.sink),
Record.connect(streamer_ack_randomizer.source, self.link_layer.sink),
- Record.connect(self.link_layer.source, self.logger.sink)
+ Record.connect(self.link_layer.source, logger_ack_randomizer.sink),
+ Record.connect(logger_ack_randomizer.source, self.logger.sink)
]
def gen_simulation(self, selfp):
for i in range(24):
yield
for i in range(8):
- yield from self.streamer.send(LinkTXPacket([i for i in range(16)]))
+ yield from self.streamer.send(LinkTXPacket([i for i in range(64)]))
yield from self.logger.receive()
print("Logger:")
print("-------")
if __name__ == "__main__":
- run_simulation(TB(), ncycles=512, vcd_name="my.vcd", keep_files=True)
+ run_simulation(TB(), ncycles=2048, vcd_name="my.vcd", keep_files=True)