Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / soc / scoreboard / test_iq.py
1 """ testing of InstructionQ
2 """
3
4 from copy import deepcopy
5 from random import randint
6 from nmigen.compat.sim import run_simulation
7 from nmigen.cli import verilog, rtlil
8
9 from soc.scoreboard.instruction_q import InstructionQ
10 from nmutil.nmoperator import eq
11 import unittest
12
13
14 class IQSim:
15 def __init__(self, dut, iq, n_in, n_out):
16 self.dut = dut
17 self.iq = iq
18 self.oq = []
19 self.n_in = n_in
20 self.n_out = n_out
21
22 def send(self):
23 i = 0
24 while i < len(self.iq):
25 sendlen = randint(1, self.n_in)
26 sendlen = 1
27 sendlen = min(len(self.iq) - i, sendlen)
28 print("sendlen", len(self.iq)-i, sendlen)
29 for idx in range(sendlen):
30 instr = self.iq[i+idx]
31 yield from eq(self.dut.i_data[idx], instr)
32 di = yield self.dut.i_data[idx] # .src1_i
33 print("senddata %d %x" % ((i+idx), di))
34 self.oq.append(di)
35 yield self.dut.p_add_i.eq(sendlen)
36 yield
37 o_p_ready = yield self.dut.p_o_ready
38 while not o_p_ready:
39 yield
40 o_p_ready = yield self.dut.p_o_ready
41
42 yield self.dut.p_add_i.eq(0)
43
44 print("send", len(self.iq), i, sendlen)
45
46 # wait random period of time before queueing another value
47 for j in range(randint(0, 3)):
48 yield
49
50 i += sendlen
51
52 yield self.dut.p_add_i.eq(0)
53 yield
54
55 print("send ended")
56
57 # wait random period of time before queueing another value
58 # for i in range(randint(0, 3)):
59 # yield
60
61 #send_range = randint(0, 3)
62 # if send_range == 0:
63 # send = True
64 # else:
65 # send = randint(0, send_range) != 0
66
67 def rcv(self):
68 i = 0
69 yield
70 yield
71 yield
72 while i < len(self.iq):
73 rcvlen = randint(1, self.n_out)
74 #print ("outreq", rcvlen)
75 yield self.dut.n_sub_i.eq(rcvlen)
76 n_sub_o = yield self.dut.n_sub_o
77 print("recv", n_sub_o)
78 for j in range(n_sub_o):
79 r = yield self.dut.o_data[j] # .src1_i
80 print("recvdata %x %s" % (r, repr(self.iq[i+j])))
81 assert r == self.oq[i+j]
82 yield
83 if n_sub_o == 0:
84 continue
85 yield self.dut.n_sub_i.eq(0)
86
87 i += n_sub_o
88
89 print("recv ended")
90
91
92 def mk_insns(n_insns, wid, opwid):
93 res = []
94 for i in range(n_insns):
95 op1 = randint(0, (1 << wid)-1)
96 opi = randint(0, 1)
97 op2 = randint(0, (1 << wid)-1)
98 dst = randint(0, (1 << wid)-1)
99 oper = randint(0, (1 << opwid)-1)
100 imm = randint(0, (1 << wid)-1)
101 res.append({'oper_i': oper, 'opim_i': opi,
102 'imm_i': imm, 'dest_i': dst,
103 'src1_i': op1, 'src2_i': op2})
104 return res
105
106
107 @unittest.skip("test fails") # FIXME
108 def test_iq():
109 wid = 8
110 opwid = 4
111 qlen = 2
112 n_in = 1
113 n_out = 1
114 dut = InstructionQ(wid, opwid, qlen, n_in, n_out)
115 insns = mk_insns(1000, wid, opwid)
116
117 vl = rtlil.convert(dut, ports=dut.ports())
118 with open("test_iq.il", "w") as f:
119 f.write(vl)
120
121 test = IQSim(dut, insns, n_in, n_out)
122 print(insns)
123 run_simulation(dut, [test.rcv(), test.send()
124 ],
125 vcd_name="test_iq.vcd")
126
127
128 if __name__ == '__main__':
129 test_iq()