5 * https://bugs.libre-soc.org/show_bug.cgi?id=363
6 * https://bugs.libre-soc.org/show_bug.cgi?id=686
9 from nmigen
import Module
, Signal
, Cat
10 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
11 from nmutil
.formaltest
import FHDLTestCase
12 from nmigen
.cli
import rtlil
14 from openpower
.test
.state
import (SimState
, teststate_check_regs
,
16 from soc
.simple
.test
.teststate
import HDLState
17 from openpower
.decoder
.isa
.caller
import special_sprs
18 from openpower
.decoder
.power_decoder
import create_pdecode
19 from openpower
.decoder
.power_decoder2
import PowerDecode2
20 from openpower
.decoder
.selectable_int
import SelectableInt
21 from openpower
.decoder
.isa
.all
import ISA
22 from openpower
.decoder
.decode2execute1
import IssuerDecode2ToOperand
23 from openpower
.state
import CoreState
25 # note that using SPRreduced has to be done to match the
26 # PowerDecoder2 SPR map
27 from openpower
.decoder
.power_enums
import SPRreduced
as SPR
28 from openpower
.decoder
.power_enums
import spr_dict
, Function
, XER_bits
29 from soc
.config
.test
.test_loadstore
import TestMemPspec
30 from openpower
.endian
import bigendian
31 from soc
.regfile
.regfiles
import StateRegs
33 from soc
.simple
.core
import NonProductionCore
34 from soc
.experiment
.compalu_multi
import find_ok
# hack
36 from soc
.fu
.compunits
.test
.test_compunit
import (setup_tst_memory
,
39 # test with ALU data and Logical data
40 from soc
.fu
.alu
.test
.test_pipe_caller
import ALUTestCase
41 from soc
.fu
.logical
.test
.test_pipe_caller
import LogicalTestCase
42 from soc
.fu
.shift_rot
.test
.test_pipe_caller
import ShiftRotTestCase
43 from soc
.fu
.cr
.test
.test_pipe_caller
import CRTestCase
44 from soc
.fu
.branch
.test
.test_pipe_caller
import BranchTestCase
45 from soc
.fu
.ldst
.test
.test_pipe_caller
import LDSTTestCase
46 from openpower
.test
.general
.overlap_hazards
import (HazardTestCase
,
48 from openpower
.util
import spr_to_fast_reg
50 from openpower
.consts
import StateRegsEnum
52 # list of SPRs that are controlled and managed by the MMU
53 mmu_sprs
= ["PRTBL", "PIDR"]
54 ldst_sprs
= ["DAR", "DSISR"]
57 def set_mmu_spr(name
, i
, val
, core
): # important keep pep8 formatting
58 fsm
= core
.fus
.get_fu("mmu0").alu
59 yield fsm
.mmu
.l_in
.mtspr
.eq(1)
60 yield fsm
.mmu
.l_in
.sprn
.eq(i
)
61 yield fsm
.mmu
.l_in
.rs
.eq(val
)
63 yield fsm
.mmu
.l_in
.mtspr
.eq(0)
64 print("mmu_spr %s %d was updated %x" % (name
, i
, val
))
67 def set_ldst_spr(name
, i
, val
, core
): # important keep pep8 formatting
68 ldst
= core
.fus
.get_fu("mmu0").alu
.ldst
# awkward to get at but it works
69 yield ldst
.sprval_in
.eq(val
)
70 yield ldst
.mmu_set_spr
.eq(1)
72 yield ldst
.mmu_set_dar
.eq(1)
74 yield ldst
.mmu_set_dar
.eq(0)
76 yield ldst
.mmu_set_dsisr
.eq(1)
78 yield ldst
.mmu_set_dsisr
.eq(0)
79 yield ldst
.mmu_set_spr
.eq(0)
80 print("ldst_spr %s %d was updated %x" % (name
, i
, val
))
83 def setup_regs(pdecode2
, core
, test
):
85 # set up INT regfile, "direct" write (bypass rd/write ports)
86 intregs
= core
.regs
.int
89 yield intregs
.regs
[i
].reg
.eq(test
.regs
[i
])
91 yield intregs
.memory
._array
[i
].eq(test
.regs
[i
])
94 # set up MSR in STATE regfile, "direct" write (bypass rd/write ports)
95 stateregs
= core
.regs
.state
96 yield stateregs
.regs
[StateRegsEnum
.MSR
].reg
.eq(test
.msr
)
98 # set up CR regfile, "direct" write across all CRs
100 crregs
= core
.regs
.cr
101 #cr = int('{:32b}'.format(cr)[::-1], 2)
102 print("setup cr reg", hex(cr
))
105 cri
= (cr
>> (i
* 4)) & 0xf
106 #cri = int('{:04b}'.format(cri)[::-1], 2)
107 print("setup cr reg", hex(cri
), i
,
108 crregs
.regs
[i
].reg
.shape())
109 yield crregs
.regs
[i
].reg
.eq(cri
)
111 # set up XER. "direct" write (bypass rd/write ports)
112 xregs
= core
.regs
.xer
113 print("setup sprs", test
.sprs
)
115 if 'XER' in test
.sprs
:
116 xer
= test
.sprs
['XER']
120 if isinstance(xer
, int):
121 xer
= SelectableInt(xer
, 64)
122 sobit
= xer
[XER_bits
['SO']].value
123 yield xregs
.regs
[xregs
.SO
].reg
.eq(sobit
)
124 cabit
= xer
[XER_bits
['CA']].value
125 ca32bit
= xer
[XER_bits
['CA32']].value
126 yield xregs
.regs
[xregs
.CA
].reg
.eq(Cat(cabit
, ca32bit
))
127 ovbit
= xer
[XER_bits
['OV']].value
128 ov32bit
= xer
[XER_bits
['OV32']].value
129 yield xregs
.regs
[xregs
.OV
].reg
.eq(Cat(ovbit
, ov32bit
))
130 print("setting XER so %d ca %d ca32 %d ov %d ov32 %d" %
131 (sobit
, cabit
, ca32bit
, ovbit
, ov32bit
))
133 yield xregs
.regs
[xregs
.SO
].reg
.eq(0)
134 yield xregs
.regs
[xregs
.OV
].reg
.eq(0)
135 yield xregs
.regs
[xregs
.CA
].reg
.eq(0)
137 # setting both fast and slow SPRs from test data
139 fregs
= core
.regs
.fast
140 sregs
= core
.regs
.spr
141 for sprname
, val
in test
.sprs
.items():
142 if isinstance(val
, SelectableInt
):
144 if isinstance(sprname
, int):
145 sprname
= spr_dict
[sprname
].SPR
148 print ('set spr %s val %x' % (sprname
, val
))
150 fast
= spr_to_fast_reg(sprname
)
153 # match behaviour of SPRMap in power_decoder2.py
154 for i
, x
in enumerate(SPR
):
155 if sprname
== x
.name
:
156 print("setting slow SPR %d (%s) to %x" %
158 if sprname
in mmu_sprs
:
159 yield from set_mmu_spr(sprname
, x
.value
, val
, core
)
160 elif sprname
in ldst_sprs
:
161 yield from set_ldst_spr(sprname
, x
.value
, val
, core
)
163 yield sregs
.memory
._array
[i
].eq(val
)
165 print("setting fast reg %d (%s) to %x" %
166 (fast
, sprname
, val
))
168 rval
= fregs
.int.regs
[fast
].reg
170 rval
= fregs
.memory
._array
[fast
]
173 # allow changes to settle before reporting on XER
177 so
= yield xregs
.regs
[xregs
.SO
].reg
178 ov
= yield xregs
.regs
[xregs
.OV
].reg
179 ca
= yield xregs
.regs
[xregs
.CA
].reg
180 oe
= yield pdecode2
.e
.do
.oe
.oe
181 oe_ok
= yield pdecode2
.e
.do
.oe
.oe_ok
183 print("before: so/ov-32/ca-32", so
, bin(ov
), bin(ca
))
184 print("oe:", oe
, oe_ok
)
187 def check_regs(dut
, sim
, core
, test
, code
):
188 # create the two states and compare
189 testdic
= {'sim': sim
, 'hdl': core
}
190 yield from teststate_check_regs(dut
, testdic
, test
, code
)
193 def check_mem(dut
, sim
, core
, test
, code
):
194 # create the two states and compare mem
195 testdic
= {'sim': sim
, 'hdl': core
}
196 yield from teststate_check_mem(dut
, testdic
, test
, code
)
199 def wait_for_busy_hi(cu
):
201 busy_o
= yield cu
.busy_o
202 terminate_o
= yield cu
.core_terminate_o
204 print("busy/terminate:", busy_o
, terminate_o
)
206 print("!busy", busy_o
, terminate_o
)
210 def set_issue(core
, dec2
, sim
):
211 yield core
.issue_i
.eq(1)
213 yield core
.issue_i
.eq(0)
214 yield from wait_for_busy_hi(core
)
217 def wait_for_busy_clear(cu
):
219 busy_o
= yield cu
.o
.busy_o
220 terminate_o
= yield cu
.o
.core_terminate_o
222 print("busy/terminate:", busy_o
, terminate_o
)
228 class TestRunner(FHDLTestCase
):
229 def __init__(self
, tst_data
):
230 super().__init
__("run_all")
231 self
.test_data
= tst_data
236 instruction
= Signal(32)
238 units
= {'alu': 3, 'cr': 1, 'branch': 1, 'trap': 1,
242 'div': 1, 'shiftrot': 1}
244 pspec
= TestMemPspec(ldst_ifacetype
='testpi',
252 cur_state
= CoreState("cur") # current state (MSR/PC/SVSTATE)
253 pdecode2
= PowerDecode2(None, state
=cur_state
,
254 #opkls=IssuerDecode2ToOperand,
255 svp64_en
=True, # self.svp64_en,
256 regreduce_en
=False, #self.regreduce_en
259 m
.submodules
.core
= core
= NonProductionCore(pspec
)
260 m
.submodules
.pdecode2
= pdecode2
261 core
.pdecode2
= pdecode2
264 comb
+= pdecode2
.dec
.raw_opcode_in
.eq(instruction
)
265 comb
+= pdecode2
.dec
.bigendian
.eq(bigendian
) # little / big?
266 comb
+= core
.i
.e
.eq(pdecode2
.e
)
267 comb
+= core
.i
.state
.eq(cur_state
)
268 comb
+= core
.i
.raw_insn_i
.eq(instruction
)
269 comb
+= core
.i
.bigendian_i
.eq(bigendian
)
271 # set the PC StateRegs read port to always send back the PC
272 stateregs
= core
.regs
.state
273 pc_regnum
= StateRegs
.PC
274 comb
+= stateregs
.r_ports
['cia'].ren
.eq(1<<pc_regnum
)
276 # temporary hack: says "go" immediately for both address gen and ST
277 ldst
= core
.fus
.fus
['ldst0']
278 m
.d
.comb
+= ldst
.ad
.go_i
.eq(ldst
.ad
.rel_o
) # link addr-go to rel
279 m
.d
.comb
+= ldst
.st
.go_i
.eq(ldst
.st
.rel_o
) # link store-go to rel
288 for test
in self
.test_data
:
290 program
= test
.program
291 with self
.subTest(test
.name
):
292 sim
= ISA(pdecode2
, test
.regs
, test
.sprs
, test
.cr
,
296 gen
= program
.generate_instructions()
297 instructions
= list(zip(gen
, program
.assembly
.splitlines()))
299 yield from setup_tst_memory(l0
, test
.mem
)
300 yield from setup_regs(pdecode2
, core
, test
)
302 index
= sim
.pc
.CIA
.value
// 4
303 while index
< len(instructions
):
304 ins
, code
= instructions
[index
]
306 print("instruction: 0x{:X}".format(ins
& 0xffffffff))
309 # ask the decoder to decode this binary data (endian'd)
310 yield instruction
.eq(ins
) # raw binary instr.
314 # call simulated operation
315 opname
= code
.split(' ')[0]
316 yield from sim
.call(opname
)
317 pc
= sim
.pc
.CIA
.value
318 nia
= sim
.pc
.NIA
.value
321 # set the PC to the same simulated value
322 # (core is not able to do this itself, except
324 print ("after call, pc nia", pc
, nia
)
325 yield stateregs
.regs
[pc_regnum
].reg
.eq(pc
)
328 yield core
.p
.i_valid
.eq(1)
330 o_ready
= yield core
.p
.o_ready
335 o_ready
= yield core
.p
.o_ready
336 yield core
.p
.i_valid
.eq(0)
338 # set operand and get inputs
339 yield from wait_for_busy_clear(core
)
341 # synchronised (non-overlap) is fine to check
342 if not core
.allow_overlap
:
344 yield from check_regs(self
, sim
, core
, test
, code
)
347 yield from check_mem(self
, sim
, core
, test
, code
)
349 # non-overlap mode is only fine to check right at the end
350 if core
.allow_overlap
:
351 # wait until all settled
352 # XXX really this should be in DMI, which should in turn
353 # use issuer.any_busy to not send back "stopped" signal
354 while (yield core
.o
.any_busy_o
):
359 yield from check_regs(self
, sim
, core
, test
, code
)
362 yield from check_mem(self
, sim
, core
, test
, code
)
364 # give a couple extra clock cycles for gtkwave display to be happy
368 sim
.add_sync_process(process
)
369 with sim
.write_vcd("core_simulator.vcd", "core_simulator.gtkw",
374 if __name__
== "__main__":
375 unittest
.main(exit
=False)
376 suite
= unittest
.TestSuite()
377 suite
.addTest(TestRunner(HazardTestCase().test_data
))
378 suite
.addTest(TestRunner(RandomHazardTestCase().test_data
))
379 #suite.addTest(TestRunner(LDSTTestCase().test_data))
380 #suite.addTest(TestRunner(CRTestCase().test_data))
381 #suite.addTest(TestRunner(ShiftRotTestCase().test_data))
382 #suite.addTest(TestRunner(LogicalTestCase().test_data))
383 #suite.addTest(TestRunner(ALUTestCase().test_data))
384 #suite.addTest(TestRunner(BranchTestCase().test_data))
386 runner
= unittest
.TextTestRunner()