mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
link: test HOLD on RX path
This commit is contained in:
parent
c28067d672
commit
21a279af72
3 changed files with 33 additions and 13 deletions
|
@ -1,14 +1,12 @@
|
||||||
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
|
||||||
|
|
||||||
from lib.sata.std import *
|
from lib.sata.std import *
|
||||||
from lib.sata.link.crc import SATACRCInserter, SATACRCChecker
|
from lib.sata.link.crc import SATACRCInserter, SATACRCChecker
|
||||||
from lib.sata.link.scrambler import SATAScrambler
|
from lib.sata.link.scrambler import SATAScrambler
|
||||||
from lib.sata.link.cont import SATACONTInserter, SATACONTRemover
|
from lib.sata.link.cont import SATACONTInserter, SATACONTRemover
|
||||||
|
|
||||||
#TODO:
|
|
||||||
# -Test HOLD on RX path
|
|
||||||
|
|
||||||
from_rx = [
|
from_rx = [
|
||||||
("idle", 1),
|
("idle", 1),
|
||||||
("insert", 32),
|
("insert", 32),
|
||||||
|
@ -152,6 +150,9 @@ class SATALinkLayerRX(Module):
|
||||||
sop.eq(0)
|
sop.eq(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# small fifo to manage HOLD
|
||||||
|
self.submodules.fifo = SyncFIFO(link_layout(32), 32)
|
||||||
|
|
||||||
# graph
|
# graph
|
||||||
self.sync += \
|
self.sync += \
|
||||||
If(fsm.ongoing("COPY") & (det == 0),
|
If(fsm.ongoing("COPY") & (det == 0),
|
||||||
|
@ -165,7 +166,8 @@ class SATALinkLayerRX(Module):
|
||||||
scrambler.sink.eop.eq(det == primitives["EOF"]),
|
scrambler.sink.eop.eq(det == primitives["EOF"]),
|
||||||
cont.source.ack.eq(1),
|
cont.source.ack.eq(1),
|
||||||
Record.connect(scrambler.source, crc.sink),
|
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
|
# FSM
|
||||||
|
@ -187,6 +189,8 @@ class SATALinkLayerRX(Module):
|
||||||
insert.eq(primitives["HOLDA"])
|
insert.eq(primitives["HOLDA"])
|
||||||
).Elif(det == primitives["EOF"],
|
).Elif(det == primitives["EOF"],
|
||||||
NextState("WTRM")
|
NextState("WTRM")
|
||||||
|
).Elif(self.fifo.fifo.level > 8,
|
||||||
|
insert.eq(primitives["HOLD"])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
fsm.act("EOF",
|
fsm.act("EOF",
|
||||||
|
|
|
@ -143,6 +143,8 @@ class LinkLayer(Module):
|
||||||
self.tx_packet = LinkTXPacket()
|
self.tx_packet = LinkTXPacket()
|
||||||
self.rx_packet = LinkRXPacket()
|
self.rx_packet = LinkRXPacket()
|
||||||
self.rx_cont = False
|
self.rx_cont = False
|
||||||
|
self.tx_cont = False
|
||||||
|
self.tx_cont_primitive = 0
|
||||||
|
|
||||||
self.transport_callback = None
|
self.transport_callback = None
|
||||||
|
|
||||||
|
@ -186,6 +188,14 @@ class LinkLayer(Module):
|
||||||
self.rx_packet.ongoing = True
|
self.rx_packet.ongoing = True
|
||||||
|
|
||||||
def send(self, dword):
|
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":
|
if self.send_state == "RDY":
|
||||||
self.phy.send(primitives["X_RDY"])
|
self.phy.send(primitives["X_RDY"])
|
||||||
if dword == primitives["R_RDY"]:
|
if dword == primitives["R_RDY"]:
|
||||||
|
@ -194,9 +204,12 @@ class LinkLayer(Module):
|
||||||
self.phy.send(primitives["SOF"])
|
self.phy.send(primitives["SOF"])
|
||||||
self.send_state = "DATA"
|
self.send_state = "DATA"
|
||||||
elif self.send_state == "DATA":
|
elif self.send_state == "DATA":
|
||||||
self.phy.send(self.tx_packet.pop(0))
|
if dword == primitives["HOLD"]:
|
||||||
if len(self.tx_packet) == 0:
|
self.phy.send(primitives["HOLDA"])
|
||||||
self.send_state = "EOF"
|
else:
|
||||||
|
self.phy.send(self.tx_packet.pop(0))
|
||||||
|
if len(self.tx_packet) == 0:
|
||||||
|
self.send_state = "EOF"
|
||||||
elif self.send_state == "EOF":
|
elif self.send_state == "EOF":
|
||||||
self.phy.send(primitives["EOF"])
|
self.phy.send(primitives["EOF"])
|
||||||
self.send_state = "WTRM"
|
self.send_state = "WTRM"
|
||||||
|
@ -209,6 +222,7 @@ class LinkLayer(Module):
|
||||||
|
|
||||||
def gen_simulation(self, selfp):
|
def gen_simulation(self, selfp):
|
||||||
self.tx_packet.done = True
|
self.tx_packet.done = True
|
||||||
|
self.phy.send(primitives["SYNC"])
|
||||||
while True:
|
while True:
|
||||||
yield from self.phy.receive()
|
yield from self.phy.receive()
|
||||||
self.phy.send(primitives["SYNC"])
|
self.phy.send(primitives["SYNC"])
|
||||||
|
|
|
@ -57,7 +57,6 @@ class LinkLogger(Module):
|
||||||
selfp.sink.ack = 1
|
selfp.sink.ack = 1
|
||||||
if selfp.sink.stb == 1 and selfp.sink.sop == 1:
|
if selfp.sink.stb == 1 and selfp.sink.sop == 1:
|
||||||
self.packet = LinkRXPacket()
|
self.packet = LinkRXPacket()
|
||||||
print("rx : %08x" %selfp.sink.d)
|
|
||||||
self.packet.append(selfp.sink.d)
|
self.packet.append(selfp.sink.d)
|
||||||
elif selfp.sink.stb:
|
elif selfp.sink.stb:
|
||||||
self.packet.append(selfp.sink.d)
|
self.packet.append(selfp.sink.d)
|
||||||
|
@ -66,25 +65,28 @@ class LinkLogger(Module):
|
||||||
|
|
||||||
class TB(Module):
|
class TB(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.submodules.bfm = BFM(phy_debug=False,
|
self.submodules.bfm = BFM(phy_debug=True,
|
||||||
link_random_level=50, transport_debug=False, transport_loopback=True)
|
link_random_level=50, transport_debug=True, transport_loopback=True)
|
||||||
self.submodules.link_layer = SATALinkLayer(self.bfm.phy)
|
self.submodules.link_layer = SATALinkLayer(self.bfm.phy)
|
||||||
|
|
||||||
self.submodules.streamer = LinkStreamer()
|
self.submodules.streamer = LinkStreamer()
|
||||||
streamer_ack_randomizer = AckRandomizer(link_layout(32), level=50)
|
streamer_ack_randomizer = AckRandomizer(link_layout(32), level=50)
|
||||||
self.submodules += streamer_ack_randomizer
|
self.submodules += streamer_ack_randomizer
|
||||||
self.submodules.logger = LinkLogger()
|
self.submodules.logger = LinkLogger()
|
||||||
|
logger_ack_randomizer = AckRandomizer(link_layout(32), level=80)
|
||||||
|
self.submodules += logger_ack_randomizer
|
||||||
self.comb += [
|
self.comb += [
|
||||||
Record.connect(self.streamer.source, streamer_ack_randomizer.sink),
|
Record.connect(self.streamer.source, streamer_ack_randomizer.sink),
|
||||||
Record.connect(streamer_ack_randomizer.source, self.link_layer.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):
|
def gen_simulation(self, selfp):
|
||||||
for i in range(24):
|
for i in range(24):
|
||||||
yield
|
yield
|
||||||
for i in range(8):
|
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()
|
yield from self.logger.receive()
|
||||||
print("Logger:")
|
print("Logger:")
|
||||||
print("-------")
|
print("-------")
|
||||||
|
@ -93,4 +95,4 @@ class TB(Module):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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)
|
||||||
|
|
Loading…
Reference in a new issue