2014-12-14 10:20:22 -05:00
|
|
|
import random, copy
|
2014-12-02 15:34:16 -05:00
|
|
|
|
2014-11-11 12:47:34 -05:00
|
|
|
from migen.fhdl.std import *
|
|
|
|
from migen.genlib.record import *
|
|
|
|
from migen.sim.generic import run_simulation
|
|
|
|
|
2014-12-14 04:45:26 -05:00
|
|
|
from lib.sata.common import *
|
2014-12-12 08:35:48 -05:00
|
|
|
from lib.sata.link import SATALink
|
2014-11-11 12:47:34 -05:00
|
|
|
|
2014-12-14 10:20:22 -05:00
|
|
|
from lib.sata.test.hdd import *
|
2014-12-05 11:48:01 -05:00
|
|
|
from lib.sata.test.common import *
|
2014-11-11 12:47:34 -05:00
|
|
|
|
|
|
|
class LinkStreamer(Module):
|
2014-12-05 14:26:09 -05:00
|
|
|
def __init__(self):
|
2014-12-14 04:52:56 -05:00
|
|
|
self.source = Source(link_description(32))
|
2014-11-11 12:47:34 -05:00
|
|
|
###
|
|
|
|
self.packets = []
|
2014-12-05 12:00:02 -05:00
|
|
|
self.packet = LinkTXPacket()
|
2014-11-11 12:47:34 -05:00
|
|
|
self.packet.done = 1
|
|
|
|
|
|
|
|
def send(self, packet, blocking=True):
|
2014-12-14 10:20:22 -05:00
|
|
|
packet = copy.deepcopy(packet)
|
2014-11-11 12:47:34 -05:00
|
|
|
self.packets.append(packet)
|
|
|
|
if blocking:
|
|
|
|
while packet.done == 0:
|
|
|
|
yield
|
|
|
|
|
|
|
|
def do_simulation(self, selfp):
|
|
|
|
if len(self.packets) and self.packet.done:
|
|
|
|
self.packet = self.packets.pop(0)
|
2014-12-05 12:00:02 -05:00
|
|
|
if not self.packet.ongoing and not self.packet.done:
|
2014-11-11 12:47:34 -05:00
|
|
|
selfp.source.stb = 1
|
|
|
|
selfp.source.sop = 1
|
2014-12-05 12:00:02 -05:00
|
|
|
selfp.source.d = self.packet.pop(0)
|
|
|
|
self.packet.ongoing = True
|
2014-11-11 12:47:34 -05:00
|
|
|
elif selfp.source.stb == 1 and selfp.source.ack == 1:
|
|
|
|
selfp.source.sop = 0
|
2014-12-05 12:00:02 -05:00
|
|
|
selfp.source.eop = (len(self.packet) == 1)
|
|
|
|
if len(self.packet) > 0:
|
2014-11-11 12:47:34 -05:00
|
|
|
selfp.source.stb = 1
|
2014-12-05 12:00:02 -05:00
|
|
|
selfp.source.d = self.packet.pop(0)
|
2014-11-11 12:47:34 -05:00
|
|
|
else:
|
|
|
|
self.packet.done = 1
|
|
|
|
selfp.source.stb = 0
|
|
|
|
|
|
|
|
class LinkLogger(Module):
|
2014-12-05 14:26:09 -05:00
|
|
|
def __init__(self):
|
2014-12-14 04:52:56 -05:00
|
|
|
self.sink = Sink(link_description(32))
|
2014-11-11 12:47:34 -05:00
|
|
|
###
|
2014-12-05 12:00:02 -05:00
|
|
|
self.packet = LinkRXPacket()
|
2014-11-11 12:47:34 -05:00
|
|
|
|
|
|
|
def receive(self):
|
|
|
|
self.packet.done = 0
|
|
|
|
while self.packet.done == 0:
|
|
|
|
yield
|
|
|
|
|
|
|
|
def do_simulation(self, selfp):
|
|
|
|
selfp.sink.ack = 1
|
|
|
|
if selfp.sink.stb == 1 and selfp.sink.sop == 1:
|
2014-12-05 12:00:02 -05:00
|
|
|
self.packet = LinkRXPacket()
|
|
|
|
self.packet.append(selfp.sink.d)
|
2014-11-11 12:47:34 -05:00
|
|
|
elif selfp.sink.stb:
|
2014-12-05 12:00:02 -05:00
|
|
|
self.packet.append(selfp.sink.d)
|
2014-11-11 12:47:34 -05:00
|
|
|
if (selfp.sink.stb ==1 and selfp.sink.eop ==1):
|
2014-12-05 12:00:02 -05:00
|
|
|
self.packet.done = True
|
2014-11-11 12:47:34 -05:00
|
|
|
|
|
|
|
class TB(Module):
|
|
|
|
def __init__(self):
|
2014-12-14 10:20:22 -05:00
|
|
|
self.submodules.hdd = HDD(
|
|
|
|
phy_debug=False,
|
|
|
|
link_random_level=50,
|
|
|
|
transport_debug=False, transport_loopback=True)
|
|
|
|
self.submodules.link = SATALink(self.hdd.phy)
|
2014-11-11 12:47:34 -05:00
|
|
|
|
2014-12-05 14:26:09 -05:00
|
|
|
self.submodules.streamer = LinkStreamer()
|
2014-12-14 04:52:56 -05:00
|
|
|
streamer_ack_randomizer = AckRandomizer(link_description(32), level=50)
|
2014-12-02 15:34:16 -05:00
|
|
|
self.submodules += streamer_ack_randomizer
|
2014-12-05 14:26:09 -05:00
|
|
|
self.submodules.logger = LinkLogger()
|
2014-12-14 04:52:56 -05:00
|
|
|
logger_ack_randomizer = AckRandomizer(link_description(32), level=50)
|
2014-12-05 15:27:26 -05:00
|
|
|
self.submodules += logger_ack_randomizer
|
2014-11-11 12:47:34 -05:00
|
|
|
self.comb += [
|
2014-12-02 15:34:16 -05:00
|
|
|
Record.connect(self.streamer.source, streamer_ack_randomizer.sink),
|
2014-12-12 08:35:48 -05:00
|
|
|
Record.connect(streamer_ack_randomizer.source, self.link.sink),
|
|
|
|
Record.connect(self.link.source, logger_ack_randomizer.sink),
|
2014-12-05 15:27:26 -05:00
|
|
|
Record.connect(logger_ack_randomizer.source, self.logger.sink)
|
2014-11-11 12:47:34 -05:00
|
|
|
]
|
|
|
|
|
|
|
|
def gen_simulation(self, selfp):
|
2014-11-12 12:20:34 -05:00
|
|
|
for i in range(8):
|
2014-12-06 08:35:18 -05:00
|
|
|
streamer_packet = LinkTXPacket([i for i in range(64)])
|
2014-12-14 10:20:22 -05:00
|
|
|
yield from self.streamer.send(streamer_packet)
|
2014-12-05 14:26:09 -05:00
|
|
|
yield from self.logger.receive()
|
2014-12-06 08:35:18 -05:00
|
|
|
|
|
|
|
# check results
|
|
|
|
s, l, e = check(streamer_packet, self.logger.packet)
|
|
|
|
print("shift "+ str(s) + " / length " + str(l) + " / errors " + str(e))
|
2014-12-05 14:26:09 -05:00
|
|
|
|
2014-11-11 12:47:34 -05:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2014-12-05 15:27:26 -05:00
|
|
|
run_simulation(TB(), ncycles=2048, vcd_name="my.vcd", keep_files=True)
|