Begin adding a test using GNU AS
[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 from nmigen.cli import rtlil
5 import os
6 import unittest
7 from soc.decoder.power_decoder import (create_pdecode)
8 from soc.decoder.power_enums import (Function, InternalOp,
9 In1Sel, In2Sel,In3Sel,
10 OutSel, RC, LdstLen, CryIn, single_bit_flags,
11 get_signal_name, get_csv)
12 from soc.decoder.power_decoder2 import (PowerDecode2)
13 import tempfile
14 import subprocess
15 import struct
16 import random
17
18 ops = {
19 InternalOp.OP_ADD: "add",
20 InternalOp.OP_AND: "and",
21 InternalOp.OP_OR: "or"}
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 dec1 = pdecode2.dec
71 comb += pdecode2.dec.opcode_in.eq(instruction)
72
73 sim = Simulator(m)
74
75 def process():
76 for i in range(10):
77 opcode = random.choice(list(ops.keys()))
78 r1 = Register(random.randrange(32))
79 r2 = Register(random.randrange(32))
80 r3 = Register(random.randrange(32))
81
82 instruction_str = self.generate_opcode_string(opcode, r1, r2, r3)
83 print(instruction_str)
84 instruction_bin = self.get_assembled_instruction(instruction_str)
85
86 yield instruction.eq(instruction_bin)
87 yield Delay(1e-6)
88
89 r1sel = yield pdecode2.e.write_reg.data
90 r2sel = yield pdecode2.e.read_reg2.data
91 r3sel = yield pdecode2.e.read_reg3.data
92 assert(r1sel == r1.num)
93
94 sim.add_process(process)
95 with sim.write_vcd("gas.vcd", "gas.gtkw", traces=[pdecode2.ports()]):
96 sim.run()
97
98
99
100 if __name__ == "__main__":
101 unittest.main()