rename bfm to hdd and clean up
This commit is contained in:
parent
0959f5b979
commit
46a39b7d41
|
@ -1,4 +1,4 @@
|
||||||
import random
|
import random, copy
|
||||||
|
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
from migen.genlib.record import *
|
from migen.genlib.record import *
|
||||||
|
@ -9,7 +9,7 @@ from lib.sata.link import SATALink
|
||||||
from lib.sata.transport import SATATransport
|
from lib.sata.transport import SATATransport
|
||||||
from lib.sata.command import SATACommand
|
from lib.sata.command import SATACommand
|
||||||
|
|
||||||
from lib.sata.test.bfm import *
|
from lib.sata.test.hdd import *
|
||||||
from lib.sata.test.common import *
|
from lib.sata.test.common import *
|
||||||
|
|
||||||
class CommandTXPacket(list):
|
class CommandTXPacket(list):
|
||||||
|
@ -34,6 +34,7 @@ class CommandStreamer(Module):
|
||||||
self.length = 0
|
self.length = 0
|
||||||
|
|
||||||
def send(self, packet, blocking=True):
|
def send(self, packet, blocking=True):
|
||||||
|
packet = copy.deepcopy(packet)
|
||||||
self.packets.append(packet)
|
self.packets.append(packet)
|
||||||
if blocking:
|
if blocking:
|
||||||
while packet.done == 0:
|
while packet.done == 0:
|
||||||
|
@ -103,12 +104,13 @@ class CommandLogger(Module):
|
||||||
|
|
||||||
class TB(Module):
|
class TB(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.submodules.bfm = BFM(phy_debug=False,
|
self.submodules.hdd = HDD(
|
||||||
|
phy_debug=False,
|
||||||
link_random_level=0, link_debug=False,
|
link_random_level=0, link_debug=False,
|
||||||
transport_debug=True, transport_loopback=False,
|
transport_debug=False, transport_loopback=False,
|
||||||
command_debug=False,
|
command_debug=False,
|
||||||
hdd_debug=False)
|
mem_debug=True)
|
||||||
self.submodules.link = SATALink(self.bfm.phy)
|
self.submodules.link = SATALink(self.hdd.phy)
|
||||||
self.submodules.transport = SATATransport(self.link)
|
self.submodules.transport = SATATransport(self.link)
|
||||||
self.submodules.command = SATACommand(self.transport)
|
self.submodules.command = SATACommand(self.transport)
|
||||||
|
|
||||||
|
@ -120,25 +122,23 @@ class TB(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
def gen_simulation(self, selfp):
|
def gen_simulation(self, selfp):
|
||||||
self.bfm.hdd.allocate_mem(0x00000000, 64*1024*1024)
|
self.hdd.allocate_mem(0x00000000, 64*1024*1024)
|
||||||
selfp.command.source.ack = 1
|
selfp.command.source.ack = 1
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
yield
|
yield
|
||||||
streamer_packet = CommandTXPacket(write=1, address=1024, length=32, data=[i for i in range(32)])
|
write_data = [i for i in range(128)]
|
||||||
yield from self.streamer.send(streamer_packet)
|
write_packet = CommandTXPacket(write=1, address=1024, length=len(write_data), data=write_data)
|
||||||
|
yield from self.streamer.send(write_packet)
|
||||||
yield from self.logger.receive()
|
yield from self.logger.receive()
|
||||||
for d in self.logger.packet:
|
read_packet = CommandTXPacket(read=1, address=1024, length=len(write_data))
|
||||||
print("%08x" %d)
|
yield from self.streamer.send(read_packet)
|
||||||
for i in range(32):
|
|
||||||
yield
|
|
||||||
streamer_packet = CommandTXPacket(read=1, address=1024, length=32)
|
|
||||||
yield from self.streamer.send(streamer_packet)
|
|
||||||
yield from self.logger.receive()
|
yield from self.logger.receive()
|
||||||
for d in self.logger.packet:
|
read_data = self.logger.packet
|
||||||
print("%08x" %d)
|
|
||||||
yield from self.logger.receive()
|
yield from self.logger.receive()
|
||||||
for d in self.logger.packet:
|
|
||||||
print("%08x" %d)
|
# check results
|
||||||
|
s, l, e = check(write_data, read_data)
|
||||||
|
print("shift "+ str(s) + " / length " + str(l) + " / errors " + str(e))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
run_simulation(TB(), ncycles=512, vcd_name="my.vcd", keep_files=True)
|
run_simulation(TB(), ncycles=512, vcd_name="my.vcd", keep_files=True)
|
||||||
|
|
|
@ -267,9 +267,10 @@ def get_field_data(field, packet):
|
||||||
return (packet[field.dword] >> field.offset) & (2**field.width-1)
|
return (packet[field.dword] >> field.offset) & (2**field.width-1)
|
||||||
|
|
||||||
class FIS:
|
class FIS:
|
||||||
def __init__(self, packet, description):
|
def __init__(self, packet, description, direction="H2D"):
|
||||||
self.packet = packet
|
self.packet = packet
|
||||||
self.description = description
|
self.description = description
|
||||||
|
self.direction = direction
|
||||||
self.decode()
|
self.decode()
|
||||||
|
|
||||||
def decode(self):
|
def decode(self):
|
||||||
|
@ -281,7 +282,10 @@ class FIS:
|
||||||
self.packet[v.dword] |= (getattr(self, k) << v.offset)
|
self.packet[v.dword] |= (getattr(self, k) << v.offset)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
r = "--------\n"
|
if self.direction == "H2D":
|
||||||
|
r = ">>>>>>>>\n"
|
||||||
|
else:
|
||||||
|
r = "<<<<<<<<\n"
|
||||||
for k in sorted(self.description.keys()):
|
for k in sorted(self.description.keys()):
|
||||||
r += k + " : 0x%x" %getattr(self,k) + "\n"
|
r += k + " : 0x%x" %getattr(self,k) + "\n"
|
||||||
return r
|
return r
|
||||||
|
@ -290,6 +294,7 @@ class FIS_REG_H2D(FIS):
|
||||||
def __init__(self, packet=[0]*fis_reg_h2d_cmd_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)
|
||||||
self.type = fis_types["REG_H2D"]
|
self.type = fis_types["REG_H2D"]
|
||||||
|
self.direction = "H2D"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
r = "FIS_REG_H2D\n"
|
r = "FIS_REG_H2D\n"
|
||||||
|
@ -300,6 +305,7 @@ class FIS_REG_D2H(FIS):
|
||||||
def __init__(self, packet=[0]*fis_reg_d2h_cmd_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)
|
||||||
self.type = fis_types["REG_D2H"]
|
self.type = fis_types["REG_D2H"]
|
||||||
|
self.direction = "D2H"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
r = "FIS_REG_D2H\n"
|
r = "FIS_REG_D2H\n"
|
||||||
|
@ -310,6 +316,7 @@ class FIS_DMA_ACTIVATE_D2H(FIS):
|
||||||
def __init__(self, packet=[0]*fis_dma_activate_d2h_cmd_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)
|
||||||
self.type = fis_types["DMA_ACTIVATE_D2H"]
|
self.type = fis_types["DMA_ACTIVATE_D2H"]
|
||||||
|
self.direction = "D2H"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
r = "FIS_DMA_ACTIVATE_D2H\n"
|
r = "FIS_DMA_ACTIVATE_D2H\n"
|
||||||
|
@ -317,8 +324,8 @@ class FIS_DMA_ACTIVATE_D2H(FIS):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
class FIS_DATA(FIS):
|
class FIS_DATA(FIS):
|
||||||
def __init__(self, packet=[0]):
|
def __init__(self, packet=[0], direction="H2D"):
|
||||||
FIS.__init__(self, packet, fis_data_layout)
|
FIS.__init__(self, packet, fis_data_layout, direction)
|
||||||
self.type = fis_types["DATA"]
|
self.type = fis_types["DATA"]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -329,12 +336,15 @@ class FIS_DATA(FIS):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
class FIS_UNKNOWN(FIS):
|
class FIS_UNKNOWN(FIS):
|
||||||
def __init__(self, packet=[0]):
|
def __init__(self, packet=[0], direction="H2D"):
|
||||||
FIS.__init__(self, packet, {})
|
FIS.__init__(self, packet, {}, direction)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
r = "UNKNOWN\n"
|
r = "UNKNOWN\n"
|
||||||
r += "--------\n"
|
if self.direction == "H2D":
|
||||||
|
r += ">>>>>>>>\\n"
|
||||||
|
else:
|
||||||
|
r += "<<<<<<<<\n"
|
||||||
for dword in self.packet:
|
for dword in self.packet:
|
||||||
r += "%08x\n" %dword
|
r += "%08x\n" %dword
|
||||||
return r
|
return r
|
||||||
|
@ -365,9 +375,9 @@ class TransportLayer(Module):
|
||||||
elif fis_type == fis_types["DMA_ACTIVATE_D2H"]:
|
elif fis_type == fis_types["DMA_ACTIVATE_D2H"]:
|
||||||
fis = FIS_DMA_ACTIVATE_D2H(packet)
|
fis = FIS_DMA_ACTIVATE_D2H(packet)
|
||||||
elif fis_type == fis_types["DATA"]:
|
elif fis_type == fis_types["DATA"]:
|
||||||
fis = FIS_DATA(packet)
|
fis = FIS_DATA(packet, direction="H2D")
|
||||||
else:
|
else:
|
||||||
fis = FIS_UNKNOWN(packet)
|
fis = FIS_UNKNOWN(packet, direction="H2D")
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print(fis)
|
print(fis)
|
||||||
if self.loopback:
|
if self.loopback:
|
||||||
|
@ -412,10 +422,22 @@ class HDDMemRegion:
|
||||||
self.data = [0]*(length//4)
|
self.data = [0]*(length//4)
|
||||||
|
|
||||||
class HDD(Module):
|
class HDD(Module):
|
||||||
def __init__(self, command, debug=False):
|
def __init__(self,
|
||||||
self.command = command
|
phy_debug=False,
|
||||||
command.set_hdd(self)
|
link_debug=False, link_random_level=0,
|
||||||
|
transport_debug=False, transport_loopback=False,
|
||||||
|
command_debug=False,
|
||||||
|
mem_debug=False
|
||||||
|
):
|
||||||
|
###
|
||||||
|
self.submodules.phy = PHYLayer(phy_debug)
|
||||||
|
self.submodules.link = LinkLayer(self.phy, link_debug, link_random_level)
|
||||||
|
self.submodules.transport = TransportLayer(self.link, transport_debug, transport_loopback)
|
||||||
|
self.submodules.command = CommandLayer(self.transport, command_debug)
|
||||||
|
|
||||||
|
self.command.set_hdd(self)
|
||||||
|
|
||||||
|
self.mem_debug = mem_debug
|
||||||
self.mem = None
|
self.mem = None
|
||||||
self.wr_address = 0
|
self.wr_address = 0
|
||||||
self.wr_length = 0
|
self.wr_length = 0
|
||||||
|
@ -430,12 +452,12 @@ class HDD(Module):
|
||||||
def read_dma_cmd(self, fis):
|
def read_dma_cmd(self, fis):
|
||||||
packet = self.read_mem(fis.lba_lsb, fis.count*4)
|
packet = self.read_mem(fis.lba_lsb, fis.count*4)
|
||||||
packet.insert(0, 0)
|
packet.insert(0, 0)
|
||||||
return [FIS_DATA(packet), FIS_REG_D2H()]
|
return [FIS_DATA(packet, direction="H2D"), FIS_REG_D2H()]
|
||||||
|
|
||||||
def identify_dma_cmd(self, fis):
|
def identify_dma_cmd(self, fis):
|
||||||
packet = [i for i in range(256)]
|
packet = [i for i in range(256)]
|
||||||
packet.insert(0, 0)
|
packet.insert(0, 0)
|
||||||
return [FIS_DATA(packet), FIS_REG_D2H()]
|
return [FIS_DATA(packet, direction="H2D"), FIS_REG_D2H()]
|
||||||
|
|
||||||
def data_cmd(self, fis):
|
def data_cmd(self, fis):
|
||||||
self.write_mem(self.wr_address, fis.packet[1:])
|
self.write_mem(self.wr_address, fis.packet[1:])
|
||||||
|
@ -446,34 +468,22 @@ class HDD(Module):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def allocate_mem(self, base, length):
|
def allocate_mem(self, base, length):
|
||||||
# XXX add support for multiple memory regions
|
if self.mem_debug:
|
||||||
|
print("[HDD] : Allocating {n} bytes at 0x{a}".format(n=length, a=base))
|
||||||
self.mem = HDDMemRegion(base, length)
|
self.mem = HDDMemRegion(base, length)
|
||||||
|
|
||||||
def write_mem(self, adr, data):
|
def write_mem(self, adr, data):
|
||||||
# XXX test if adr allocated in one memory region
|
if self.mem_debug:
|
||||||
|
print("[HDD] : Writing {n} bytes at 0x{a}".format(n=len(data)*4, a=adr))
|
||||||
current_adr = (adr-self.mem.base)//4
|
current_adr = (adr-self.mem.base)//4
|
||||||
for i in range(len(data)):
|
for i in range(len(data)):
|
||||||
self.mem.data[current_adr+i] = data[i]
|
self.mem.data[current_adr+i] = data[i]
|
||||||
|
|
||||||
def read_mem(self, adr, length=1):
|
def read_mem(self, adr, length=1):
|
||||||
# XXX test if adr allocated in one memory region
|
if self.mem_debug:
|
||||||
|
print("[HDD] : Reading {n} bytes at 0x{a}".format(n=length, a=adr))
|
||||||
current_adr = (adr-self.mem.base)//4
|
current_adr = (adr-self.mem.base)//4
|
||||||
data = []
|
data = []
|
||||||
for i in range(length//4):
|
for i in range(length//4):
|
||||||
data.append(self.mem.data[current_adr+i])
|
data.append(self.mem.data[current_adr+i])
|
||||||
return data
|
return data
|
||||||
|
|
||||||
class BFM(Module):
|
|
||||||
def __init__(self,
|
|
||||||
phy_debug=False,
|
|
||||||
link_debug=False, link_random_level=0,
|
|
||||||
transport_debug=False, transport_loopback=False,
|
|
||||||
command_debug=False,
|
|
||||||
hdd_debug=False
|
|
||||||
):
|
|
||||||
###
|
|
||||||
self.submodules.phy = PHYLayer(phy_debug)
|
|
||||||
self.submodules.link = LinkLayer(self.phy, link_debug, link_random_level)
|
|
||||||
self.submodules.transport = TransportLayer(self.link, transport_debug, transport_loopback)
|
|
||||||
self.submodules.command = CommandLayer(self.transport, command_debug)
|
|
||||||
self.submodules.hdd = HDD(self.command, hdd_debug)
|
|
|
@ -1,4 +1,4 @@
|
||||||
import random
|
import random, copy
|
||||||
|
|
||||||
from migen.fhdl.std import *
|
from migen.fhdl.std import *
|
||||||
from migen.genlib.record import *
|
from migen.genlib.record import *
|
||||||
|
@ -7,7 +7,7 @@ from migen.sim.generic import run_simulation
|
||||||
from lib.sata.common import *
|
from lib.sata.common import *
|
||||||
from lib.sata.link import SATALink
|
from lib.sata.link import SATALink
|
||||||
|
|
||||||
from lib.sata.test.bfm import *
|
from lib.sata.test.hdd import *
|
||||||
from lib.sata.test.common import *
|
from lib.sata.test.common import *
|
||||||
|
|
||||||
class LinkStreamer(Module):
|
class LinkStreamer(Module):
|
||||||
|
@ -19,6 +19,7 @@ class LinkStreamer(Module):
|
||||||
self.packet.done = 1
|
self.packet.done = 1
|
||||||
|
|
||||||
def send(self, packet, blocking=True):
|
def send(self, packet, blocking=True):
|
||||||
|
packet = copy.deepcopy(packet)
|
||||||
self.packets.append(packet)
|
self.packets.append(packet)
|
||||||
if blocking:
|
if blocking:
|
||||||
while packet.done == 0:
|
while packet.done == 0:
|
||||||
|
@ -65,9 +66,11 @@ class LinkLogger(Module):
|
||||||
|
|
||||||
class TB(Module):
|
class TB(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.submodules.bfm = BFM(phy_debug=False,
|
self.submodules.hdd = HDD(
|
||||||
link_random_level=50, transport_debug=False, transport_loopback=True)
|
phy_debug=False,
|
||||||
self.submodules.link = SATALink(self.bfm.phy)
|
link_random_level=50,
|
||||||
|
transport_debug=False, transport_loopback=True)
|
||||||
|
self.submodules.link = SATALink(self.hdd.phy)
|
||||||
|
|
||||||
self.submodules.streamer = LinkStreamer()
|
self.submodules.streamer = LinkStreamer()
|
||||||
streamer_ack_randomizer = AckRandomizer(link_description(32), level=50)
|
streamer_ack_randomizer = AckRandomizer(link_description(32), level=50)
|
||||||
|
@ -83,11 +86,9 @@ class TB(Module):
|
||||||
]
|
]
|
||||||
|
|
||||||
def gen_simulation(self, selfp):
|
def gen_simulation(self, selfp):
|
||||||
for i in range(24):
|
|
||||||
yield
|
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
streamer_packet = LinkTXPacket([i for i in range(64)])
|
streamer_packet = LinkTXPacket([i for i in range(64)])
|
||||||
yield from self.streamer.send(LinkTXPacket([i for i in range(64)]))
|
yield from self.streamer.send(streamer_packet)
|
||||||
yield from self.logger.receive()
|
yield from self.logger.receive()
|
||||||
|
|
||||||
# check results
|
# check results
|
||||||
|
|
Loading…
Reference in New Issue