link: test HOLD on RX path

This commit is contained in:
Florent Kermarrec 2014-12-05 21:27:26 +01:00
parent c28067d672
commit 21a279af72
3 changed files with 33 additions and 13 deletions

View file

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

View file

@ -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,6 +204,9 @@ 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":
if dword == primitives["HOLD"]:
self.phy.send(primitives["HOLDA"])
else:
self.phy.send(self.tx_packet.pop(0)) self.phy.send(self.tx_packet.pop(0))
if len(self.tx_packet) == 0: if len(self.tx_packet) == 0:
self.send_state = "EOF" self.send_state = "EOF"
@ -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"])

View file

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