single_bit_flags, Form, SPR,
get_signal_name, get_csv)
from soc.decoder.power_decoder2 import (PowerDecode2)
-import tempfile
-import subprocess
-import struct
+from soc.simulator.gas import get_assembled_instruction
import random
def __init__(self, num):
self.num = num
+class Checker:
+ def __init__(self):
+ self.imm = 0
+
+ def get_imm(self, in2_sel):
+ if in2_sel == In2Sel.CONST_UI.value:
+ return self.imm & 0xffff
+ if in2_sel == In2Sel.CONST_UI_HI.value:
+ return (self.imm & 0xffff) << 16
+ if in2_sel == In2Sel.CONST_SI.value:
+ sign_bit = 1 << 15
+ return (self.imm & (sign_bit-1)) - (self.imm & sign_bit)
+ if in2_sel == In2Sel.CONST_SI_HI.value:
+ imm = self.imm << 16
+ sign_bit = 1 << 31
+ return (imm & (sign_bit-1)) - (imm & sign_bit)
+
class RegRegOp:
def __init__(self):
assert(rc == 0)
-class RegImmOp:
+class RegImmOp(Checker):
def __init__(self):
+ super().__init__()
self.ops = {
"addi": InternalOp.OP_ADD,
"addis": InternalOp.OP_ADD,
imm = yield pdecode2.e.imm_data.data
in2_sel = yield pdecode2.dec.op.in2_sel
- if in2_sel in [In2Sel.CONST_SI_HI.value, In2Sel.CONST_UI_HI.value]:
- assert(imm == (self.imm << 16))
- else:
- assert(imm == self.imm)
+ imm_expected = self.get_imm(in2_sel)
+ msg = "imm: got {:x}, expected {:x}".format(imm, imm_expected)
+ assert imm == imm_expected, msg
rc = yield pdecode2.e.rc.data
if '.' in self.opcodestr:
assert(rc == 0)
-class LdStOp:
+class LdStOp(Checker):
def __init__(self):
+ super().__init__()
self.ops = {
"lwz": InternalOp.OP_LOAD,
"stw": InternalOp.OP_STORE,
self.opcode = self.ops[self.opcodestr]
self.r1 = Register(random.randrange(32))
self.r2 = Register(random.randrange(1, 32))
+ while self.r2.num == self.r1.num:
+ self.r2 = Register(random.randrange(1, 32))
self.imm = random.randrange(32767)
def generate_instruction(self):
assert(r2sel == self.r2.num)
imm = yield pdecode2.e.imm_data.data
- assert(imm == self.imm)
+ in2_sel = yield pdecode2.dec.op.in2_sel
+ assert(imm == self.get_imm(in2_sel))
update = yield pdecode2.e.update
if "u" in self.opcodestr:
def check_results(self, pdecode2):
r1sel = yield pdecode2.e.read_reg1.data
r2sel = yield pdecode2.e.read_reg2.data
- crsel = yield pdecode2.dec.BF[0:-1]
+ crsel = yield pdecode2.dec.BF
assert(r1sel == self.r1.num)
assert(r2sel == self.r2.num)
dec = pdecode2.dec
if "i" in self.opcodestr:
- shift = yield dec.SH[0:-1]
+ shift = yield dec.SH
else:
shift = yield pdecode2.e.read_reg2.data
- mb = yield dec.MB[0:-1]
- me = yield dec.ME[0:-1]
+ mb = yield dec.MB
+ me = yield dec.ME
assert(r1sel == self.r1.num)
assert(r2sel == self.r2.num)
assert(lk == 1)
else:
assert(lk == 0)
- aa = yield pdecode2.dec.AA[0:-1]
+ aa = yield pdecode2.dec.AA
if "a" in self.opcodestr:
assert(aa == 1)
else:
def check_results(self, pdecode2):
imm = yield pdecode2.e.imm_data.data
- bo = yield pdecode2.dec.BO[0:-1]
- bi = yield pdecode2.dec.BI[0:-1]
+ bo = yield pdecode2.dec.BO
+ bi = yield pdecode2.dec.BI
assert(imm == self.addr)
assert(bo == self.bo)
assert(lk == 1)
else:
assert(lk == 0)
- aa = yield pdecode2.dec.AA[0:-1]
+ aa = yield pdecode2.dec.AA
if "a" in self.opcodestr:
assert(aa == 1)
else:
return string
def check_results(self, pdecode2):
- bo = yield pdecode2.dec.BO[0:-1]
- bi = yield pdecode2.dec.BI[0:-1]
+ bo = yield pdecode2.dec.BO
+ bi = yield pdecode2.dec.BI
assert(bo == self.bo)
assert(bi == self.bi)
class DecoderTestCase(FHDLTestCase):
- def get_assembled_instruction(self, instruction, bigendian=False):
- if bigendian:
- endian_fmt = "elf64-big"
- obj_fmt = "-be"
- else:
- endian_fmt = "elf64-little"
- obj_fmt = "-le"
- with tempfile.NamedTemporaryFile(suffix=".o") as outfile:
- args = ["powerpc64-linux-gnu-as",
- obj_fmt,
- "-o",
- outfile.name]
- p = subprocess.Popen(args, stdin=subprocess.PIPE)
- p.communicate(instruction.encode('utf-8'))
- assert(p.wait() == 0)
-
- with tempfile.NamedTemporaryFile(suffix=".bin") as binfile:
- args = ["powerpc64-linux-gnu-objcopy",
- "-I", endian_fmt,
- "-O", "binary",
- outfile.name,
- binfile.name]
- subprocess.check_output(args)
- binary = struct.unpack('>i', binfile.read(4))[0]
- return binary
-
def run_tst(self, kls, name):
m = Module()
comb = m.d.comb
def process():
for i in range(20):
checker = kls()
- instruction_str = checker.generate_instruction()
- print("instr", instruction_str.strip())
- for endian in [0, 1]:
+ ins = checker.generate_instruction()
+ print("instr", ins.strip())
+ for mode in [0, 1]:
- instruction_bin = self.get_assembled_instruction(
- instruction_str, endian)
- print("code", endian, hex(instruction_bin),
- bin(instruction_bin))
+ # turn the instruction into binary data (endian'd)
+ ibin = get_assembled_instruction(ins, mode)
+ print("code", mode, hex(ibin), bin(ibin))
- yield pdecode2.dec.bigendian.eq(endian)
- yield instruction.eq(instruction_bin)
+ # ask the decoder to decode this binary data (endian'd)
+ yield pdecode2.dec.bigendian.eq(mode) # little / big?
+ yield instruction.eq(ibin) # raw binary instr.
yield Delay(1e-6)
yield from checker.check_results(pdecode2)