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):
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):
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):
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):
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):
--- /dev/null
+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)
+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):
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)
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 = {}
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)
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")
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,
)
)
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")
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,
"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),
"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),