add with carry cleanup and test case
[soc.git] / src / soc / simulator / test_sim.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay
3 from nmigen.test.utils import FHDLTestCase
4 import unittest
5 from soc.simulator.internalop_sim import InternalOpSimulator
6 from soc.decoder.power_decoder import (create_pdecode)
7 from soc.decoder.power_enums import (Function, InternalOp,
8 In1Sel, In2Sel, In3Sel,
9 OutSel, RC, LdstLen, CryIn,
10 single_bit_flags, Form, SPR,
11 get_signal_name, get_csv)
12 from soc.decoder.power_decoder2 import (PowerDecode2)
13 from soc.simulator.program import Program
14 from soc.simulator.qemu import run_program
15
16
17 class Register:
18 def __init__(self, num):
19 self.num = num
20
21
22 class DecoderTestCase(FHDLTestCase):
23
24 def run_tst(self, generator, simulator):
25 m = Module()
26 comb = m.d.comb
27 instruction = Signal(32)
28
29 pdecode = create_pdecode()
30
31 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
32 comb += pdecode2.dec.raw_opcode_in.eq(instruction)
33 sim = Simulator(m)
34 gen = generator.generate_instructions()
35
36 def process():
37 for ins in gen:
38
39 print("0x{:X}".format(ins & 0xffffffff))
40
41 # ask the decoder to decode this binary data (endian'd)
42 yield pdecode2.dec.bigendian.eq(0) # little / big?
43 yield instruction.eq(ins) # raw binary instr.
44 yield Delay(1e-6)
45 yield from simulator.execute_op(pdecode2)
46
47 sim.add_process(process)
48 with sim.write_vcd("simulator.vcd", "simulator.gtkw",
49 traces=pdecode2.ports()):
50 sim.run()
51
52 def test_example(self):
53 lst = ["addi 1, 0, 0x1234",
54 "addi 2, 0, 0x5678",
55 "add 3, 1, 2",
56 "and 4, 1, 2"]
57 with Program(lst) as program:
58 self.run_tst_program(program, [1, 2, 3, 4])
59
60 def test_ldst(self):
61 lst = ["addi 1, 0, 0x1234",
62 "addi 2, 0, 0x5678",
63 "stw 1, 0(2)",
64 "lwz 3, 0(2)"]
65 with Program(lst) as program:
66 self.run_tst_program(program, [1, 2, 3])
67
68 def test_ldst_extended(self):
69 lst = ["addi 1, 0, 0x1234",
70 "addi 2, 0, 0x5678",
71 "addi 4, 0, 0x40",
72 "stw 1, 0x40(2)",
73 "lwzx 3, 4, 2"]
74 with Program(lst) as program:
75 self.run_tst_program(program, [1, 2, 3])
76
77 def test_ldst_widths(self):
78 lst = [" lis 1, 0xdead",
79 "ori 1, 1, 0xbeef",
80 "addi 2, 0, 0x1000",
81 "std 1, 0(2)",
82 "lbz 1, 5(2)",
83 "lhz 3, 4(2)",
84 "lwz 4, 4(2)",
85 "addi 5, 0, 0x12",
86 "stb 5, 5(2)",
87 "ld 5, 0(2)"]
88 with Program(lst) as program:
89 self.run_tst_program(program, [1, 2, 3, 4, 5])
90
91 def test_sub(self):
92 lst = ["addi 1, 0, 0x1234",
93 "addi 2, 0, 0x5678",
94 "subf 3, 1, 2",
95 "subfic 4, 1, 0x1337",
96 "neg 5, 1"]
97 with Program(lst) as program:
98 self.run_tst_program(program, [1, 2, 3, 4, 5])
99
100 def test_add_with_carry(self):
101 lst = ["addi 1, 0, 5",
102 "neg 1, 1",
103 "addi 2, 0, 7",
104 "neg 2, 2",
105 "addc 3, 2, 1",
106 "addi 3, 3, 1"
107 ]
108 with Program(lst) as program:
109 self.run_tst_program(program, [1, 2, 3])
110
111 def run_tst_program(self, prog, reglist):
112 simulator = InternalOpSimulator()
113 self.run_tst(prog, simulator)
114 prog.reset()
115 with run_program(prog) as q:
116 qemu_register_compare(simulator, q, reglist)
117
118
119 def qemu_register_compare(simulator, qemu, regs):
120 for reg in regs:
121 qemu_val = qemu.get_register(reg)
122 simulator.regfile.assert_gpr(reg, qemu_val)
123
124
125 if __name__ == "__main__":
126 unittest.main()