link: test HOLD on RX path
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 5 Dec 2014 20:27:26 +0000 (21:27 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 5 Dec 2014 20:27:26 +0000 (21:27 +0100)
lib/sata/link/__init__.py
lib/sata/test/bfm.py
lib/sata/test/link_tb.py

index ebbc76b4bd3620a41cd9631fcbc6efd36c9f98a8..2dcc5ab571493b406c10ac179975cc1f39215bf8 100644 (file)
@@ -1,14 +1,12 @@
 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),
@@ -152,6 +150,9 @@ class SATALinkLayerRX(Module):
                                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),
@@ -165,7 +166,8 @@ class SATALinkLayerRX(Module):
                        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
@@ -187,6 +189,8 @@ class SATALinkLayerRX(Module):
                                insert.eq(primitives["HOLDA"])
                        ).Elif(det == primitives["EOF"],
                                NextState("WTRM")
+                       ).Elif(self.fifo.fifo.level > 8,
+                               insert.eq(primitives["HOLD"])
                        )
                )
                fsm.act("EOF",
index 6272dd94e482366df7923ac0d34e4b35c7694f39..4b0b3b344fea1f5075ad3e19cc55bc07675511fa 100644 (file)
@@ -143,6 +143,8 @@ class LinkLayer(Module):
                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
 
@@ -186,6 +188,14 @@ class LinkLayer(Module):
                        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"]:
@@ -194,9 +204,12 @@ class LinkLayer(Module):
                        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"
@@ -209,6 +222,7 @@ class LinkLayer(Module):
 
        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"])
index a8ea97b2fd8c22262e07bc61f04e05fc6fc4e8ef..cff5a5c78d8e8c610b8dffb350d293ac38063fcf 100644 (file)
@@ -57,7 +57,6 @@ class LinkLogger(Module):
                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)
@@ -66,25 +65,28 @@ class LinkLogger(Module):
 
 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("-------")
@@ -93,4 +95,4 @@ class TB(Module):
 
 
 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)