ba3c62a6bb8d8fe2e5798a38f2dbda901ef4a7a8
[soc.git] / src / soc / experiment / test / test_compldst_multi.py
1 """Self-contained unit test for the Load/Store CompUnit
2 """
3
4 import unittest
5 from nmigen import Module
6 from nmigen.sim import Simulator
7 from nmutil.gtkw import write_gtkw
8
9 from openpower.consts import MSR
10 from openpower.decoder.power_enums import MicrOp, LDSTMode
11
12 from soc.experiment.compldst_multi import LDSTCompUnit
13 from soc.experiment.pimem import PortInterface
14 from soc.experiment.test.test_compalu_multi import OperandProducer
15 from soc.fu.ldst.pipe_data import LDSTPipeSpec
16
17
18 class OpSim:
19 def __init__(self, dut, sim):
20 self.dut = dut
21 # create one operand producer for each input port
22 self.producers = list()
23 for i in range(len(dut.src_i)):
24 self.producers.append(OperandProducer(sim, dut, i))
25
26 def issue(self, op, ra=None, rb=None, rc=None,
27 zero_a=False, imm=None, update=False,
28 byterev=True, signext=False,
29 data_len=2, msr_pr=0,
30 delays=None):
31 assert zero_a == (ra is None), \
32 "ra and zero_a are mutually exclusive"
33 assert (rb is None) != (imm is None), \
34 "rb and imm are mutually exclusive"
35 if op == MicrOp.OP_STORE:
36 assert rc, "need source operand for store"
37 dut = self.dut
38 pi = dut.pi
39 producers = self.producers
40 if ra:
41 yield from producers[0].send(ra, delays['ra'])
42 if rb:
43 yield from producers[1].send(rb, delays['rb'])
44 if rc:
45 yield from producers[2].send(rc, delays['rc'])
46 yield dut.oper_i.insn_type.eq(op)
47 yield dut.oper_i.data_len.eq(data_len)
48 yield dut.oper_i.zero_a.eq(zero_a)
49 yield dut.oper_i.byte_reverse.eq(byterev)
50 yield dut.oper_i.sign_extend.eq(signext)
51 if imm is not None:
52 yield dut.oper_i.imm_data.data.eq(imm)
53 yield dut.oper_i.imm_data.ok.eq(1)
54 if update:
55 yield dut.oper_i.ldst_mode.eq(LDSTMode.update)
56 yield dut.oper_i.msr[MSR.PR].eq(msr_pr)
57 yield dut.issue_i.eq(1)
58 yield
59 yield dut.issue_i.eq(0)
60 # deactivate decoder inputs along with issue_i, so we can be sure they
61 # were latched at the correct cycle
62 yield dut.oper_i.insn_type.eq(0)
63 yield dut.oper_i.data_len.eq(0)
64 yield dut.oper_i.zero_a.eq(0)
65 yield dut.oper_i.byte_reverse.eq(0)
66 yield dut.oper_i.sign_extend.eq(0)
67 yield dut.oper_i.imm_data.data.eq(0)
68 yield dut.oper_i.imm_data.ok.eq(0)
69 yield dut.oper_i.ldst_mode.eq(LDSTMode.NONE)
70 yield dut.oper_i.msr[MSR.PR].eq(0)
71 while not (yield pi.addr.ok):
72 yield
73
74
75 class TestLDSTCompUnit(unittest.TestCase):
76
77 def test_ldst_compunit(self):
78 m = Module()
79 pi = PortInterface(name="pi")
80 regspec = LDSTPipeSpec.regspec
81 dut = LDSTCompUnit(pi, regspec, name="ldst")
82 m.submodules.dut = dut
83 sim = Simulator(m)
84 sim.add_clock(1e-6)
85 op = OpSim(dut, sim)
86 self.write_gtkw()
87
88 def process():
89 yield from op.issue(MicrOp.OP_STORE, ra=1, rb=2, rc=3,
90 delays={'ra': 1, 'rb': 2, 'rc': 5})
91
92 sim.add_sync_process(process)
93 sim_writer = sim.write_vcd("test_ldst_compunit.vcd")
94 with sim_writer:
95 sim.run()
96
97 @classmethod
98 def write_gtkw(cls):
99 style = {'dec': {'base': 'dec'}}
100 traces = [
101 'clk',
102 ('state latches', [
103 'q_opc',
104 ('q_src[2:0]', {'bit': 2}),
105 ('q_src[2:0]', {'bit': 1}),
106 ('q_src[2:0]', {'bit': 0}),
107 'q_alu', 'q_adr', 'qn_lod', 'q_sto',
108 'q_wri', 'q_upd', 'q_rst', 'q_lsd'
109 ]),
110 ('operation', [
111 ('oper_i_ldst__insn_type', {'display': 'insn_type'}),
112 ('oper_i_ldst__ldst_mode', {'display': 'ldst_mode'}),
113 ('oper_i_ldst__zero_a', {'display': 'zero_a'}),
114 ('oper_i_ldst__imm_data__ok', {'display': 'imm_data_ok'}),
115 ('oper_i_ldst__imm_data__data[63:0]', 'dec',
116 {'display': 'imm_data_data'})
117 ]),
118 'cu_issue_i', 'cu_busy_o',
119 ('address ALU', [
120 ('cu_rd__rel_o[2:0]', {'bit': 2}),
121 ('cu_rd__go_i[2:0]', {'bit': 2}),
122 ('src1_i[63:0]', 'dec'),
123 ('cu_rd__rel_o[2:0]', {'bit': 1}),
124 ('cu_rd__go_i[2:0]', {'bit': 1}),
125 ('src2_i[63:0]', 'dec'),
126 'alu_valid', 'alu_ok', ('alu_o[63:0]', 'dec'),
127 'cu_ad__rel_o', 'cu_ad__go_i',
128 'pi_addr_i_ok', ('pi_addr_i[47:0]', 'dec'),
129 ]),
130 ('store operand', [
131 ('cu_rd__rel_o[2:0]', {'bit': 0}),
132 ('cu_rd__go_i[2:0]', {'bit': 0}),
133 ('src3_i[63:0]', 'dec'),
134 'rd_done',
135 ]),
136 'cu_st__rel_o', 'cu_st__go_i'
137 ]
138 write_gtkw("test_ldst_compunit.gtkw",
139 "test_ldst_compunit.vcd",
140 traces, style, module="top.dut")
141
142
143 if __name__ == '__main__':
144 unittest.main()