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