transport: add transport_tb skeleton and fix compilation
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 11 Dec 2014 23:56:29 +0000 (00:56 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 11 Dec 2014 23:56:29 +0000 (00:56 +0100)
lib/sata/test/Makefile
lib/sata/test/bfm.py
lib/sata/test/transport_tb.py [new file with mode: 0644]
lib/sata/transport/__init__.py
lib/sata/transport/std.py

index abb4d6053fbbe9c4a5a8663d78bbf9c99ac3d028..3e9abba8ad314b5656dbbdf1caeee4bdbb64a96f 100644 (file)
@@ -17,6 +17,9 @@ scrambler_tb:
 link_tb:
        $(CMD) link_tb.py
 
+transport_tb:
+       $(CMD) transport_tb.py
+
 all: crc_tb scrambler_tb
 
 clean:
index 036bf175b69370d23784c64797848ec09b3b713f..7b5d88192f0c6dcee6a51325c0eb887cc9f733ec 100644 (file)
@@ -285,7 +285,7 @@ class FIS:
                return r
 
 class FIS_REG_H2D(FIS):
-       def __init__(self, packet=[0]*fis_reg_h2d_len):
+       def __init__(self, packet=[0]*fis_reg_h2d_cmd_len):
                FIS.__init__(self, packet,fis_reg_h2d_layout)
 
        def __repr__(self):
@@ -294,7 +294,7 @@ class FIS_REG_H2D(FIS):
                return r
 
 class FIS_REG_D2H(FIS):
-       def __init__(self, packet=[0]*fis_reg_d2h_len):
+       def __init__(self, packet=[0]*fis_reg_d2h_cmd_len):
                FIS.__init__(self, packet,fis_reg_d2h_layout)
 
        def __repr__(self):
@@ -303,7 +303,7 @@ class FIS_REG_D2H(FIS):
                return r
 
 class FIS_DMA_ACTIVATE_D2H(FIS):
-       def __init__(self, packet=[0]*fis_dma_activate_d2h_len):
+       def __init__(self, packet=[0]*fis_dma_activate_d2h_cmd_len):
                FIS.__init__(self, packet,fis_dma_activate_d2h_layout)
 
        def __repr__(self):
@@ -312,7 +312,7 @@ class FIS_DMA_ACTIVATE_D2H(FIS):
                return r
 
 class FIS_DMA_SETUP(FIS):
-       def __init__(self, packet=[0]*fis_dma_setup_len):
+       def __init__(self, packet=[0]*fis_dma_setup_cmd_len):
                FIS.__init__(self, packet,fis_dma_setup_layout)
 
        def __repr__(self):
@@ -330,7 +330,7 @@ class FIS_DATA(FIS):
                return r
 
 class FIS_PIO_SETUP_D2H(FIS):
-       def __init__(self, packet=[0]*fis_pio_setup_d2h_len):
+       def __init__(self, packet=[0]*fis_pio_setup_d2h_cmd_len):
                FIS.__init__(self, packet,fis_pio_setup_d2h_layout)
 
        def __repr__(self):
diff --git a/lib/sata/test/transport_tb.py b/lib/sata/test/transport_tb.py
new file mode 100644 (file)
index 0000000..70104d3
--- /dev/null
@@ -0,0 +1,28 @@
+import random
+
+from migen.fhdl.std import *
+from migen.genlib.record import *
+from migen.sim.generic import run_simulation
+
+from lib.sata.std import *
+from lib.sata.link import SATALinkLayer
+from lib.sata.transport import SATATransportLayer
+
+from lib.sata.test.bfm import *
+from lib.sata.test.common import *
+
+class TB(Module):
+       def __init__(self):
+               self.submodules.bfm = BFM(phy_debug=False,
+                               link_random_level=50, transport_debug=True, transport_loopback=True)
+               self.submodules.link = SATALinkLayer(self.bfm.phy)
+               self.submodules.transport = SATATransportLayer(self.link)
+
+               self.comb += [
+                       self.transport.tx.cmd.stb.eq(1),
+                       self.transport.tx.cmd.type.eq(fis_types["REG_H2D"]),
+                       self.transport.tx.cmd.lba.eq(0x12345678)
+               ]
+
+if __name__ == "__main__":
+       run_simulation(TB(), ncycles=256, vcd_name="my.vcd", keep_files=True)
index 417859057801999a2ae4e4c825d111fbf66a11eb..dff48186d6586bd64ccabf8d8644021c35cdb0e2 100644 (file)
@@ -1,12 +1,21 @@
+from migen.fhdl.std import *
+from migen.genlib.fsm import FSM, NextState
+
 from lib.sata.std import *
 from lib.sata.transport.std import *
 
 def _encode_cmd(obj, layout, signal):
        r = []
        for k, v in sorted(layout.items()):
-               start = v.word*32 + v.offset
+               start = v.dword*32 + v.offset
                end = start + v.width
-               r.append(signal[start:end].eq(getattr(obj, k)))
+               if "_lsb" in k:
+                       item = getattr(obj, k.replace("_lsb", ""))[:v.width]
+               elif "_msb" in k:
+                       item = getattr(obj, k.replace("_msb", ""))[v.width:2*v.width]
+               else:
+                       item = getattr(obj, k)
+               r.append(signal[start:end].eq(item))
        return r
 
 class SATATransportLayerTX(Module):
@@ -31,19 +40,21 @@ class SATATransportLayerTX(Module):
                cmd_done = Signal()
                data_done = Signal()
 
+               def test_type(name):
+                       return cmd.type == fis_types[name]
+
                fsm = FSM(reset_state="IDLE")
                self.submodules += fsm
 
-               # FSM
                fsm.act("IDLE",
                        clr_cnt.eq(1),
                        If(cmd.stb,
-                               If(cmd.type == fis_types["REG_H2D"],
+                               If(test_type("REG_H2D"),
                                        NextState("SEND_REG_H2D_CMD")
-                               ).Elif(cmd.type == "DMA_SETUP_CMD",
-                                       NextState("SEND_DMA_SETUP")
-                               ).Elif(cmd.type == "DATA_CMD"),
-                                       NextState("SEND_DATA")
+                               ).Elif(test_type("DMA_SETUP"),
+                                       NextState("SEND_DMA_SETUP_CMD")
+                               ).Elif(test_type("DATA"),
+                                       NextState("SEND_DATA_CMD")
                                ).Else(
                                        # XXX: Generate error to command layer?
                                        cmd.ack.eq(1)
@@ -53,37 +64,37 @@ class SATATransportLayerTX(Module):
                fsm.act("SEND_REG_H2D_CMD",
                        _encode_cmd(self.cmd, fis_reg_h2d_layout, encoded_cmd),
                        cmd_len.eq(fis_reg_h2d_cmd_len),
-                       cmd_send.eq(1)
-                       If(ack_cmd,
-                               NextState.eq("ACK")
+                       cmd_send.eq(1),
+                       If(cmd_done,
+                               NextState("ACK")
                        )
                )
                fsm.act("SEND_DMA_SETUP_CMD",
                        _encode_cmd(self.cmd, fis_dma_setup_layout, encoded_cmd),
                        cmd_len.eq(fis_dma_setup_cmd_len),
                        cmd_send.eq(1),
-                       If(ack_cmd,
-                               NextState.eq("ACK")
+                       If(cmd_done,
+                               NextState("ACK")
                        )
                )
                fsm.act("SEND_DATA_CMD",
                        _encode_cmd(self.cmd, fis_data_layout, encoded_cmd),
-                       cmd_len.eq(fis_send_data_cmd_len),
-                       cmd_width_data.eq(1),
+                       cmd_len.eq(fis_data_cmd_len),
+                       cmd_with_data.eq(1),
                        cmd_send.eq(1),
                        If(cmd_done,
-                               NextState.eq("SEND_DATA")
+                               NextState("SEND_DATA")
                        )
                )
                fsm.act("SEND_DATA",
                        data_send.eq(1),
                        If(data_done,
-                               NextState.eq("ACK")
+                               NextState("ACK")
                        )
                )
                fsm.act("ACK",
                        cmd.ack.eq(1),
-                       NextState.eq("IDLE")
+                       NextState("IDLE")
                )
 
                cmd_cases = {}
@@ -117,20 +128,26 @@ class SATATransportLayerTX(Module):
 def _decode_cmd(signal, layout, obj):
        r = []
        for k, v in sorted(layout.items()):
-               start = v.word*32+v.offset
+               start = v.dword*32+v.offset
                end = start+v.width
-               r.append(getattr(obj, k).eq(signal[start:end]))
+               if "_lsb" in k:
+                       item = getattr(obj, k.replace("_lsb", ""))[:v.width]
+               elif "_msb" in k:
+                       item = getattr(obj, k.replace("_msb", ""))[v.width:2*v.width]
+               else:
+                       item = getattr(obj, k)
+               r.append(item.eq(signal[start:end]))
        return r
 
 class SATATransportLayerRX(Module):
        def __init__(self, link):
-               self.cmd = Source(transport_cmd_rx_layout())
-               self.data = Source(transport_data_layout(32))
+               self.cmd = cmd = Source(transport_cmd_rx_layout())
+               self.data = data = Source(transport_data_layout(32))
 
                ###
 
                cmd_ndwords = max(fis_reg_d2h_cmd_len, fis_dma_activate_d2h_cmd_len, fis_dma_setup_cmd_len,
-                                               fis_data_cmd_len, fis_pio_setup_d2h_len)
+                                               fis_data_cmd_len, fis_pio_setup_d2h_cmd_len)
                encoded_cmd = Signal(cmd_ndwords*32)
 
                cnt = Signal(max=cmd_ndwords+1)
@@ -144,15 +161,15 @@ class SATATransportLayerRX(Module):
                cmd_done = Signal()
                data_done = Signal()
 
-               fsm = FSM(reset_state="IDLE")
-               self.submodules += fsm
-
                def test_type(name):
                        return link.source.d[:8] == fis_types[name]
 
+               fsm = FSM(reset_state="IDLE")
+               self.submodules += fsm
+
                fsm.act("IDLE",
                        If(link.source.stb & link.source.sop,
-                               If(test_type("REG_D2H"]),
+                               If(test_type("REG_D2H"),
                                        NextState("RECEIVE_REG_D2H_CMD")
                                ).Elif(test_type("DMA_ACTIVATE_D2H"),
                                        NextState("RECEIVE_DMA_ACTIVATE_D2H_CMD")
@@ -225,7 +242,7 @@ class SATATransportLayerRX(Module):
                                NextState("PRESENT_DATA_CMD")
                        )
                )
-               fsm.act("DECODE_DATA",
+               fsm.act("PRESENT_DATA_CMD",
                        cmd.stb.eq(1),
                        _decode_cmd(encoded_cmd, fis_data_layout ,cmd),
                        If(cmd.ack,
@@ -233,7 +250,7 @@ class SATATransportLayerRX(Module):
                        )
                )
                fsm.act("RECEIVE_PIO_SETUP_D2H_CMD",
-                       cmd_len.eq(fis_pio_setup_d2h_len),
+                       cmd_len.eq(fis_pio_setup_d2h_cmd_len),
                        cmd_receive.eq(1),
                        If(cmd_done,
                                NextState("PRESENT_PIO_SETUP_D2H_CMD")
@@ -249,7 +266,7 @@ class SATATransportLayerRX(Module):
 
                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(link.source.d)]
 
                self.sync += \
                        If(cmd_receive,
index a38b45ee000b9207350b5fca27b689e7348a8346..aae053b0300427c24ec2728890596b72f1c22225 100644 (file)
@@ -62,9 +62,9 @@ fis_dma_setup_layout = {
        "i":                  FISField(0, 14, 1),
        "a":                  FISField(0, 15, 1),
 
-       "dma_buffer_id_low":  FISField(1, 0, 32),
+       "dma_buffer_id_lsb":  FISField(1, 0, 32),
 
-       "dma_buffer_id_high": FISField(2, 0, 32),
+       "dma_buffer_id_msb": FISField(2, 0, 32),
 
        "dma_buffer_offset":  FISField(4, 0, 32),
 
@@ -76,7 +76,7 @@ fis_data_layout = {
        "type": FISField(0,  0, 8)
 }
 
-fis_pio_setup_d2h_len = 5
+fis_pio_setup_d2h_cmd_len = 5
 fis_pio_setup_d2h_layout = {
        "type":           FISField(0,  0, 8),
        "pm_port":        FISField(0,  8, 4),