transport: add transport_tb skeleton and fix compilation

This commit is contained in:
Florent Kermarrec 2014-12-12 00:56:29 +01:00
parent ed9d9e1375
commit 7ea46ed7a6
5 changed files with 86 additions and 38 deletions

View file

@ -17,6 +17,9 @@ scrambler_tb:
link_tb: link_tb:
$(CMD) link_tb.py $(CMD) link_tb.py
transport_tb:
$(CMD) transport_tb.py
all: crc_tb scrambler_tb all: crc_tb scrambler_tb
clean: clean:

View file

@ -285,7 +285,7 @@ class FIS:
return r return r
class FIS_REG_H2D(FIS): 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) FIS.__init__(self, packet,fis_reg_h2d_layout)
def __repr__(self): def __repr__(self):
@ -294,7 +294,7 @@ class FIS_REG_H2D(FIS):
return r return r
class FIS_REG_D2H(FIS): 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) FIS.__init__(self, packet,fis_reg_d2h_layout)
def __repr__(self): def __repr__(self):
@ -303,7 +303,7 @@ class FIS_REG_D2H(FIS):
return r return r
class FIS_DMA_ACTIVATE_D2H(FIS): 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) FIS.__init__(self, packet,fis_dma_activate_d2h_layout)
def __repr__(self): def __repr__(self):
@ -312,7 +312,7 @@ class FIS_DMA_ACTIVATE_D2H(FIS):
return r return r
class FIS_DMA_SETUP(FIS): 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) FIS.__init__(self, packet,fis_dma_setup_layout)
def __repr__(self): def __repr__(self):
@ -330,7 +330,7 @@ class FIS_DATA(FIS):
return r return r
class FIS_PIO_SETUP_D2H(FIS): 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) FIS.__init__(self, packet,fis_pio_setup_d2h_layout)
def __repr__(self): def __repr__(self):

View file

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

View 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.std import *
from lib.sata.transport.std import * from lib.sata.transport.std import *
def _encode_cmd(obj, layout, signal): def _encode_cmd(obj, layout, signal):
r = [] r = []
for k, v in sorted(layout.items()): for k, v in sorted(layout.items()):
start = v.word*32 + v.offset start = v.dword*32 + v.offset
end = start + v.width 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 return r
class SATATransportLayerTX(Module): class SATATransportLayerTX(Module):
@ -31,19 +40,21 @@ class SATATransportLayerTX(Module):
cmd_done = Signal() cmd_done = Signal()
data_done = Signal() data_done = Signal()
def test_type(name):
return cmd.type == fis_types[name]
fsm = FSM(reset_state="IDLE") fsm = FSM(reset_state="IDLE")
self.submodules += fsm self.submodules += fsm
# FSM
fsm.act("IDLE", fsm.act("IDLE",
clr_cnt.eq(1), clr_cnt.eq(1),
If(cmd.stb, If(cmd.stb,
If(cmd.type == fis_types["REG_H2D"], If(test_type("REG_H2D"),
NextState("SEND_REG_H2D_CMD") NextState("SEND_REG_H2D_CMD")
).Elif(cmd.type == "DMA_SETUP_CMD", ).Elif(test_type("DMA_SETUP"),
NextState("SEND_DMA_SETUP") NextState("SEND_DMA_SETUP_CMD")
).Elif(cmd.type == "DATA_CMD"), ).Elif(test_type("DATA"),
NextState("SEND_DATA") NextState("SEND_DATA_CMD")
).Else( ).Else(
# XXX: Generate error to command layer? # XXX: Generate error to command layer?
cmd.ack.eq(1) cmd.ack.eq(1)
@ -53,37 +64,37 @@ class SATATransportLayerTX(Module):
fsm.act("SEND_REG_H2D_CMD", fsm.act("SEND_REG_H2D_CMD",
_encode_cmd(self.cmd, fis_reg_h2d_layout, encoded_cmd), _encode_cmd(self.cmd, fis_reg_h2d_layout, encoded_cmd),
cmd_len.eq(fis_reg_h2d_cmd_len), cmd_len.eq(fis_reg_h2d_cmd_len),
cmd_send.eq(1) cmd_send.eq(1),
If(ack_cmd, If(cmd_done,
NextState.eq("ACK") NextState("ACK")
) )
) )
fsm.act("SEND_DMA_SETUP_CMD", fsm.act("SEND_DMA_SETUP_CMD",
_encode_cmd(self.cmd, fis_dma_setup_layout, encoded_cmd), _encode_cmd(self.cmd, fis_dma_setup_layout, encoded_cmd),
cmd_len.eq(fis_dma_setup_cmd_len), cmd_len.eq(fis_dma_setup_cmd_len),
cmd_send.eq(1), cmd_send.eq(1),
If(ack_cmd, If(cmd_done,
NextState.eq("ACK") NextState("ACK")
) )
) )
fsm.act("SEND_DATA_CMD", fsm.act("SEND_DATA_CMD",
_encode_cmd(self.cmd, fis_data_layout, encoded_cmd), _encode_cmd(self.cmd, fis_data_layout, encoded_cmd),
cmd_len.eq(fis_send_data_cmd_len), cmd_len.eq(fis_data_cmd_len),
cmd_width_data.eq(1), cmd_with_data.eq(1),
cmd_send.eq(1), cmd_send.eq(1),
If(cmd_done, If(cmd_done,
NextState.eq("SEND_DATA") NextState("SEND_DATA")
) )
) )
fsm.act("SEND_DATA", fsm.act("SEND_DATA",
data_send.eq(1), data_send.eq(1),
If(data_done, If(data_done,
NextState.eq("ACK") NextState("ACK")
) )
) )
fsm.act("ACK", fsm.act("ACK",
cmd.ack.eq(1), cmd.ack.eq(1),
NextState.eq("IDLE") NextState("IDLE")
) )
cmd_cases = {} cmd_cases = {}
@ -117,20 +128,26 @@ class SATATransportLayerTX(Module):
def _decode_cmd(signal, layout, obj): def _decode_cmd(signal, layout, obj):
r = [] r = []
for k, v in sorted(layout.items()): for k, v in sorted(layout.items()):
start = v.word*32+v.offset start = v.dword*32+v.offset
end = start+v.width 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 return r
class SATATransportLayerRX(Module): class SATATransportLayerRX(Module):
def __init__(self, link): def __init__(self, link):
self.cmd = Source(transport_cmd_rx_layout()) self.cmd = cmd = Source(transport_cmd_rx_layout())
self.data = Source(transport_data_layout(32)) 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, 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) encoded_cmd = Signal(cmd_ndwords*32)
cnt = Signal(max=cmd_ndwords+1) cnt = Signal(max=cmd_ndwords+1)
@ -144,15 +161,15 @@ class SATATransportLayerRX(Module):
cmd_done = Signal() cmd_done = Signal()
data_done = Signal() data_done = Signal()
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
def test_type(name): def test_type(name):
return link.source.d[:8] == fis_types[name] return link.source.d[:8] == fis_types[name]
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
fsm.act("IDLE", fsm.act("IDLE",
If(link.source.stb & link.source.sop, If(link.source.stb & link.source.sop,
If(test_type("REG_D2H"]), If(test_type("REG_D2H"),
NextState("RECEIVE_REG_D2H_CMD") NextState("RECEIVE_REG_D2H_CMD")
).Elif(test_type("DMA_ACTIVATE_D2H"), ).Elif(test_type("DMA_ACTIVATE_D2H"),
NextState("RECEIVE_DMA_ACTIVATE_D2H_CMD") NextState("RECEIVE_DMA_ACTIVATE_D2H_CMD")
@ -225,7 +242,7 @@ class SATATransportLayerRX(Module):
NextState("PRESENT_DATA_CMD") NextState("PRESENT_DATA_CMD")
) )
) )
fsm.act("DECODE_DATA", fsm.act("PRESENT_DATA_CMD",
cmd.stb.eq(1), cmd.stb.eq(1),
_decode_cmd(encoded_cmd, fis_data_layout ,cmd), _decode_cmd(encoded_cmd, fis_data_layout ,cmd),
If(cmd.ack, If(cmd.ack,
@ -233,7 +250,7 @@ class SATATransportLayerRX(Module):
) )
) )
fsm.act("RECEIVE_PIO_SETUP_D2H_CMD", 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), cmd_receive.eq(1),
If(cmd_done, If(cmd_done,
NextState("PRESENT_PIO_SETUP_D2H_CMD") NextState("PRESENT_PIO_SETUP_D2H_CMD")
@ -249,7 +266,7 @@ class SATATransportLayerRX(Module):
cmd_cases = {} cmd_cases = {}
for i in range(cmd_ndwords): 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 += \ self.sync += \
If(cmd_receive, If(cmd_receive,

View file

@ -62,9 +62,9 @@ fis_dma_setup_layout = {
"i": FISField(0, 14, 1), "i": FISField(0, 14, 1),
"a": FISField(0, 15, 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), "dma_buffer_offset": FISField(4, 0, 32),
@ -76,7 +76,7 @@ fis_data_layout = {
"type": FISField(0, 0, 8) "type": FISField(0, 0, 8)
} }
fis_pio_setup_d2h_len = 5 fis_pio_setup_d2h_cmd_len = 5
fis_pio_setup_d2h_layout = { fis_pio_setup_d2h_layout = {
"type": FISField(0, 0, 8), "type": FISField(0, 0, 8),
"pm_port": FISField(0, 8, 4), "pm_port": FISField(0, 8, 4),