Cleanup test_decoder_gas.py
[soc.git] / src / soc / decoder / test / test_decoder_gas.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.decoder.power_decoder import (create_pdecode)
6 from soc.decoder.power_enums import (Function, InternalOp,
7 In1Sel, In2Sel, In3Sel,
8 OutSel, RC, LdstLen, CryIn,
9 single_bit_flags, Form,
10 get_signal_name, get_csv)
11 from soc.decoder.power_decoder2 import (PowerDecode2)
12 import tempfile
13 import subprocess
14 import struct
15 import random
16
17 ops = {
18 InternalOp.OP_ADD: "add",
19 InternalOp.OP_AND: "and",
20 InternalOp.OP_OR: "or"}
21
22
23 class Register:
24 def __init__(self, num):
25 self.num = num
26
27
28 class DecoderTestCase(FHDLTestCase):
29 def generate_opcode_string(self, internalop, r1, r2, op3):
30 opcodestr = ops[internalop]
31 if isinstance(op3, Register):
32 immstring = ""
33 op3str = op3.num
34 else:
35 immstring = "i"
36 op3str = str(op3)
37 string = "{}{} {}, {}, {}\n".format(opcodestr,
38 immstring,
39 r1.num,
40 r2.num,
41 op3str)
42 return string
43
44 def get_assembled_instruction(self, instruction):
45 with tempfile.NamedTemporaryFile(suffix=".o") as outfile:
46 args = ["powerpc64-linux-gnu-as",
47 "-o",
48 outfile.name]
49 p = subprocess.Popen(args, stdin=subprocess.PIPE)
50 p.communicate(instruction.encode('utf-8'))
51 assert(p.wait() == 0)
52
53 with tempfile.NamedTemporaryFile(suffix=".bin") as binfile:
54 args = ["powerpc64-linux-gnu-objcopy",
55 "-O", "binary",
56 outfile.name,
57 binfile.name]
58 subprocess.check_output(args)
59 binary = struct.unpack('>i', binfile.read(4))[0]
60 return binary
61
62 def test_decoder(self):
63 m = Module()
64 comb = m.d.comb
65 instruction = Signal(32)
66
67 pdecode = create_pdecode()
68
69 m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
70 comb += pdecode2.dec.opcode_in.eq(instruction)
71
72 sim = Simulator(m)
73
74 def process():
75 for i in range(10):
76 opcode = random.choice(list(ops.keys()))
77 r1 = Register(random.randrange(32))
78 r2 = Register(random.randrange(32))
79 r3 = Register(random.randrange(32))
80
81 instruction_str = self.generate_opcode_string(
82 opcode, r1, r2, r3)
83 print("instr", instruction_str.strip())
84 instruction_bin = self.get_assembled_instruction(
85 instruction_str)
86 print("code", hex(instruction_bin), bin(instruction_bin))
87
88 yield instruction.eq(instruction_bin)
89 yield Delay(1e-6)
90
91 r1sel = yield pdecode2.e.write_reg.data
92 r3sel = yield pdecode2.e.read_reg2.data
93
94 # For some reason r2 gets decoded either in read_reg1
95 # or read_reg3
96 form = yield pdecode2.dec.op.form
97 if form == Form.X.value:
98 r2sel = yield pdecode2.e.read_reg3.data
99 else:
100 r2sel = yield pdecode2.e.read_reg1.data
101 assert(r1sel == r1.num)
102 assert(r3sel == r3.num)
103 assert(r2sel == r2.num)
104
105 sim.add_process(process)
106 with sim.write_vcd("gas.vcd", "gas.gtkw", traces=[pdecode2.ports()]):
107 sim.run()
108
109
110 if __name__ == "__main__":
111 unittest.main()