1908164b1f237b5c6b51d934ebccf4ea6749a9c8
[litex.git] / lib / sata / test / common.py
1 import random, copy
2
3 from migen.fhdl.std import *
4 from migen.genlib.record import *
5 from migen.sim.generic import run_simulation
6
7 from lib.sata.common import *
8
9 def seed_to_data(seed, random=True):
10 if random:
11 return (seed * 0x31415979 + 1) & 0xffffffff
12 else:
13 return seed
14
15 def check(p1, p2):
16 p1 = copy.deepcopy(p1)
17 p2 = copy.deepcopy(p2)
18 if isinstance(p1, int):
19 return 0, 1, int(p1 != p2)
20 else:
21 if len(p1) >= len(p2):
22 ref, res = p1, p2
23 else:
24 ref, res = p2, p1
25 shift = 0
26 while((ref[0] != res[0]) and (len(res)>1)):
27 res.pop(0)
28 shift += 1
29 length = min(len(ref), len(res))
30 errors = 0
31 for i in range(length):
32 if ref.pop(0) != res.pop(0):
33 errors += 1
34 return shift, length, errors
35
36 def randn(max_n):
37 return random.randint(0, max_n-1)
38
39 class PacketStreamer(Module):
40 def __init__(self, description, packet_class):
41 self.source = Source(description)
42 ###
43 self.packets = []
44 self.packet = packet_class()
45 self.packet.done = 1
46
47 def send(self, packet, blocking=True):
48 packet = copy.deepcopy(packet)
49 self.packets.append(packet)
50 if blocking:
51 while packet.done == 0:
52 yield
53
54 def do_simulation(self, selfp):
55 if len(self.packets) and self.packet.done:
56 self.packet = self.packets.pop(0)
57 if not self.packet.ongoing and not self.packet.done:
58 selfp.source.stb = 1
59 selfp.source.sop = 1
60 if len(self.packet) > 0:
61 if hasattr(selfp.source, "data"):
62 selfp.source.data = self.packet.pop(0)
63 else:
64 selfp.source.d = self.packet.pop(0)
65 self.packet.ongoing = True
66 elif selfp.source.stb == 1 and selfp.source.ack == 1:
67 selfp.source.sop = 0
68 selfp.source.eop = (len(self.packet) == 1)
69 if len(self.packet) > 0:
70 selfp.source.stb = 1
71 if hasattr(selfp.source, "data"):
72 selfp.source.data = self.packet.pop(0)
73 else:
74 selfp.source.d = self.packet.pop(0)
75 else:
76 self.packet.done = 1
77 selfp.source.stb = 0
78
79 class PacketLogger(Module):
80 def __init__(self, description, packet_class):
81 self.sink = Sink(description)
82 ###
83 self.packet_class = packet_class
84 self.packet = packet_class()
85
86 def receive(self):
87 self.packet.done = 0
88 while self.packet.done == 0:
89 yield
90
91 def do_simulation(self, selfp):
92 selfp.sink.ack = 1
93 if selfp.sink.stb == 1 and selfp.sink.sop == 1:
94 self.packet = self.packet_class()
95 if selfp.sink.stb:
96 if hasattr(selfp.sink, "data"):
97 self.packet.append(selfp.sink.data)
98 else:
99 self.packet.append(selfp.sink.d)
100 if selfp.sink.stb == 1 and selfp.sink.eop == 1:
101 self.packet.done = True
102
103 class AckRandomizer(Module):
104 def __init__(self, description, level=0):
105 self.level = level
106
107 self.sink = Sink(description)
108 self.source = Source(description)
109
110 self.run = Signal()
111
112 self.comb += \
113 If(self.run,
114 Record.connect(self.sink, self.source)
115 ).Else(
116 self.source.stb.eq(0),
117 self.sink.ack.eq(0),
118 )
119
120 def do_simulation(self, selfp):
121 n = randn(100)
122 if n < self.level:
123 selfp.run = 0
124 else:
125 selfp.run = 1