074e628fb89c1710038db74d65493c7bd9a5e9f2
1 from nmigen
import Module
, Signal
2 from nmigen
.back
.pysim
import Simulator
, Delay
3 from nmigen
.test
.utils
import FHDLTestCase
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
)
21 def __init__(self
, num
):
27 "add": InternalOp
.OP_ADD
,
28 "and": InternalOp
.OP_AND
,
29 "or": InternalOp
.OP_OR
,
30 "add.": InternalOp
.OP_ADD
,
32 self
.opcodestr
= random
.choice(list(self
.ops
.keys()))
33 self
.opcode
= self
.ops
[self
.opcodestr
]
34 self
.r1
= Register(random
.randrange(32))
35 self
.r2
= Register(random
.randrange(32))
36 self
.r3
= Register(random
.randrange(32))
38 def generate_instruction(self
):
39 string
= "{} {}, {}, {}\n".format(self
.opcodestr
,
45 def check_results(self
, pdecode2
):
46 r1sel
= yield pdecode2
.e
.write_reg
.data
47 r3sel
= yield pdecode2
.e
.read_reg2
.data
49 # For some reason r2 gets decoded either in read_reg1
51 out_sel
= yield pdecode2
.dec
.op
.out_sel
52 if out_sel
== OutSel
.RA
.value
:
53 r2sel
= yield pdecode2
.e
.read_reg3
.data
55 r2sel
= yield pdecode2
.e
.read_reg1
.data
56 assert(r1sel
== self
.r1
.num
)
57 assert(r3sel
== self
.r3
.num
)
58 assert(r2sel
== self
.r2
.num
)
60 opc_out
= yield pdecode2
.dec
.op
.internal_op
61 assert(opc_out
== self
.opcode
.value
)
62 # check RC value (the dot in the instruction)
63 rc
= yield pdecode2
.e
.rc
.data
64 if '.' in self
.opcodestr
:
74 "addi": InternalOp
.OP_ADD
,
75 "addis": InternalOp
.OP_ADD
,
76 "andi.": InternalOp
.OP_AND
,
77 "ori": InternalOp
.OP_OR
,
79 self
.opcodestr
= random
.choice(list(self
.ops
.keys()))
80 self
.opcode
= self
.ops
[self
.opcodestr
]
81 self
.r1
= Register(random
.randrange(32))
82 self
.r2
= Register(random
.randrange(32))
83 self
.imm
= random
.randrange(32767)
85 def generate_instruction(self
):
86 string
= "{} {}, {}, {}\n".format(self
.opcodestr
,
92 def check_results(self
, pdecode2
):
94 r1sel
= yield pdecode2
.e
.write_reg
.data
95 # For some reason r2 gets decoded either in read_reg1
97 out_sel
= yield pdecode2
.dec
.op
.out_sel
98 if out_sel
== OutSel
.RA
.value
:
99 r2sel
= yield pdecode2
.e
.read_reg3
.data
101 r2sel
= yield pdecode2
.e
.read_reg1
.data
102 assert(r1sel
== self
.r1
.num
)
103 assert(r2sel
== self
.r2
.num
)
105 imm
= yield pdecode2
.e
.imm_data
.data
106 in2_sel
= yield pdecode2
.dec
.op
.in2_sel
107 if in2_sel
in [In2Sel
.CONST_SI_HI
.value
, In2Sel
.CONST_UI_HI
.value
]:
108 assert(imm
== (self
.imm
<< 16))
110 assert(imm
== self
.imm
)
112 rc
= yield pdecode2
.e
.rc
.data
113 if '.' in self
.opcodestr
:
118 class DecoderTestCase(FHDLTestCase
):
120 def get_assembled_instruction(self
, instruction
):
121 with tempfile
.NamedTemporaryFile(suffix
=".o") as outfile
:
122 args
= ["powerpc64-linux-gnu-as",
125 p
= subprocess
.Popen(args
, stdin
=subprocess
.PIPE
)
126 p
.communicate(instruction
.encode('utf-8'))
127 assert(p
.wait() == 0)
129 with tempfile
.NamedTemporaryFile(suffix
=".bin") as binfile
:
130 args
= ["powerpc64-linux-gnu-objcopy",
134 subprocess
.check_output(args
)
135 binary
= struct
.unpack('>i', binfile
.read(4))[0]
138 def run_tst(self
, kls
, name
):
141 instruction
= Signal(32)
143 pdecode
= create_pdecode()
145 m
.submodules
.pdecode2
= pdecode2
= PowerDecode2(pdecode
)
146 comb
+= pdecode2
.dec
.opcode_in
.eq(instruction
)
154 instruction_str
= checker
.generate_instruction()
155 print("instr", instruction_str
.strip())
156 instruction_bin
= self
.get_assembled_instruction(
158 print("code", hex(instruction_bin
), bin(instruction_bin
))
160 yield instruction
.eq(instruction_bin
)
163 yield from checker
.check_results(pdecode2
)
166 sim
.add_process(process
)
167 with sim
.write_vcd("%s.vcd" % name
, "%s.gtkw" % name
,
168 traces
=[pdecode2
.ports()]):
170 def test_reg_reg(self
):
171 self
.run_tst(RegRegOp
, "reg_reg")
173 def test_reg_imm(self
):
174 self
.run_tst(RegImmOp
, "reg_imm")
177 if __name__
== "__main__":