-from nmigen import Module, Signal
+from nmigen import Module, Signal, ResetSignal
from nmigen.back.pysim import Simulator, Delay, Settle
-from nmigen.test.utils import FHDLTestCase
+from nmutil.formaltest import FHDLTestCase
from nmigen.cli import rtlil
import unittest
-from soc.decoder.isa.caller import ISACaller, special_sprs
from soc.decoder.power_decoder import (create_pdecode)
from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.decoder.power_enums import (XER_bits, Function, InternalOp)
-from soc.decoder.selectable_int import SelectableInt
-from soc.simulator.program import Program
+from soc.decoder.power_enums import Function
from soc.decoder.isa.all import ISA
-from soc.fu.alu.test.test_pipe_caller import TestCase, ALUTestCase, test_data
from soc.experiment.compalu_multi import find_ok # hack
-import random
+
def set_cu_input(cu, idx, data):
rdop = cu.get_in_name(idx)
print ("rd_rel %d wait HI" % idx, rd_rel_o)
yield
yield cu.rd.go[idx].eq(0)
+ yield cu.src_i[idx].eq(0)
def get_cu_output(cu, idx, code):
yield
yield cu.wr.go[idx].eq(0)
print ("result", repr(code), idx, wrop, wrok, hex(result))
+
return result
def get_cu_outputs(cu, code):
res = {}
+ wrmask = yield cu.wrmask
+ print ("get_cu_outputs", cu.n_dst, wrmask)
+ if not wrmask: # no point waiting (however really should doublecheck wr.rel)
+ return {}
+ # wait for at least one result
+ while True:
+ wr_rel_o = yield cu.wr.rel
+ if wr_rel_o:
+ break
+ yield
for i in range(cu.n_dst):
wr_rel_o = yield cu.wr.rel[i]
if wr_rel_o:
return res
-def get_cu_rd_mask(n_src, inp):
- mask = 0 #((1<<n_src)-1)
- for i in inp.keys():
- mask |= 1<<i
- return mask
+def get_inp_indexed(cu, inp):
+ res = {}
+ for i in range(cu.n_src):
+ wrop = cu.get_in_name(i)
+ if wrop in inp:
+ res[i] = inp[wrop]
+ return res
+def setup_test_memory(l0, sim):
+ mem = l0.mem.mem
+ print ("before, init mem", mem.depth, mem.width, mem)
+ for i in range(mem.depth):
+ data = sim.mem.ld(i*8, 8, False)
+ print ("init ", i, hex(data))
+ yield mem._array[i].eq(data)
+ yield Settle()
+ for k, v in sim.mem.mem.items():
+ print (" %6x %016x" % (k, v))
+ print ("before, nmigen mem dump")
+ for i in range(mem.depth):
+ actual_mem = yield mem._array[i]
+ print (" %6i %016x" % (i, actual_mem))
+
+
+def check_sim_memory(dut, l0, sim, code):
+ mem = l0.mem.mem
+ print ("sim mem dump")
+ for k, v in sim.mem.mem.items():
+ print (" %6x %016x" % (k, v))
+ print ("nmigen mem dump")
+ for i in range(mem.depth):
+ actual_mem = yield mem._array[i]
+ print (" %6i %016x" % (i, actual_mem))
+
+ for i in range(mem.depth):
+ expected_mem = sim.mem.ld(i*8, 8, False)
+ actual_mem = yield mem._array[i]
+ dut.assertEqual(expected_mem, actual_mem,
+ "%s %d %x %x" % (code, i,
+ expected_mem, actual_mem))
class TestRunner(FHDLTestCase):
- def __init__(self, test_data, fukls, iodef):
+ def __init__(self, test_data, fukls, iodef, funit):
super().__init__("run_all")
self.test_data = test_data
self.fukls = fukls
- self.iodef = iodef
+ self.iodef = iodef
+ self.funit = funit
def run_all(self):
m = Module()
instruction = Signal(32)
pdecode = create_pdecode()
-
m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
- m.submodules.cu = cu = self.fukls()
+
+ # copy of the decoder for simulator
+ simdec = create_pdecode()
+ simdec2 = PowerDecode2(simdec)
+ m.submodules.simdec2 = simdec2 # pain in the neck
+
+ if self.funit == Function.LDST:
+ from soc.experiment.l0_cache import TstL0CacheBuffer
+ m.submodules.l0 = l0 = TstL0CacheBuffer(n_units=1, regwid=64,
+ addrwid=3)
+ pi = l0.l0.dports[0].pi
+ m.submodules.cu = cu = self.fukls(pi, awid=3)
+ m.d.comb += cu.ad.go.eq(cu.ad.rel) # link addr-go direct to rel
+ m.d.comb += cu.st.go.eq(cu.st.rel) # link store-go direct to rel
+ else:
+ m.submodules.cu = cu = self.fukls()
comb += pdecode2.dec.raw_opcode_in.eq(instruction)
sim = Simulator(m)
print(test.name)
program = test.program
self.subTest(test.name)
- sim = ISA(pdecode2, test.regs, test.sprs, 0)
- gen = program.generate_instructions()
- instructions = list(zip(gen, program.assembly.splitlines()))
+ print ("test", test.name, test.mem)
+ gen = list(program.generate_instructions())
+ insncode = program.assembly.splitlines()
+ instructions = list(zip(gen, insncode))
+ sim = ISA(simdec2, test.regs, test.sprs, test.cr, test.mem,
+ test.msr,
+ initial_insns=gen, respect_pc=False,
+ disassembly=insncode)
+
+ # initialise memory
+ if self.funit == Function.LDST:
+ yield from setup_test_memory(l0, sim)
index = sim.pc.CIA.value//4
while index < len(instructions):
ins, code = instructions[index]
-
- print("0x{:X}".format(ins & 0xffffffff))
+ yield from sim.setup_one()
print(code)
# ask the decoder to decode this binary data (endian'd)
yield instruction.eq(ins) # raw binary instr.
yield Settle()
fn_unit = yield pdecode2.e.fn_unit
- self.assertEqual(fn_unit, Function.ALU.value)
+ fuval = self.funit.value
+ self.assertEqual(fn_unit & fuval, fuval)
# set operand and get inputs
yield from set_operand(cu, pdecode2, sim)
- inp = yield from self.iodef.get_cu_inputs(pdecode2, sim)
+ iname = yield from self.iodef.get_cu_inputs(pdecode2, sim)
+ inp = get_inp_indexed(cu, iname)
# reset read-operand mask
- rdmask = get_cu_rd_mask(cu.n_src, inp)
+ rdmask = pdecode2.rdflags(cu)
+ #print ("hardcoded rdmask", cu.rdflags(pdecode2.e))
+ #print ("decoder rdmask", rdmask)
yield cu.rdmaskn.eq(~rdmask)
# reset write-operand mask
fname = find_ok(wrok.fields)
yield getattr(wrok, fname).eq(0)
+ yield Settle()
+
# set inputs into CU
rd_rel_o = yield cu.rd.rel
wr_rel_o = yield cu.wr.rel
print ("before inputs, rd_rel, wr_rel: ",
bin(rd_rel_o), bin(wr_rel_o))
+ assert wr_rel_o == 0, "wr.rel %s must be zero. "\
+ "previous instr not written all regs\n"\
+ "respec %s" % \
+ (bin(wr_rel_o), cu.rwid[1])
yield from set_cu_inputs(cu, inp)
- yield
rd_rel_o = yield cu.rd.rel
wr_rel_o = yield cu.wr.rel
wrmask = yield cu.wrmask
bin(rd_rel_o), bin(wr_rel_o), bin(wrmask))
# call simulated operation
- opname = code.split(' ')[0]
- yield from sim.call(opname)
+ yield from sim.execute_one()
index = sim.pc.CIA.value//4
+ yield Settle()
# get all outputs (one by one, just "because")
res = yield from get_cu_outputs(cu, code)
+ wrmask = yield cu.wrmask
+ rd_rel_o = yield cu.rd.rel
+ wr_rel_o = yield cu.wr.rel
+ print ("after got outputs, rd_rel, wr_rel, wrmask: ",
+ bin(rd_rel_o), bin(wr_rel_o), bin(wrmask))
+
+ # wait for busy to go low
+ while True:
+ busy_o = yield cu.busy_o
+ print ("busy", busy_o)
+ if not busy_o:
+ break
+ yield
yield from self.iodef.check_cu_outputs(res, pdecode2,
sim, code)
+ # sigh. hard-coded. test memory
+ if self.funit == Function.LDST:
+ yield from check_sim_memory(self, l0, sim, code)
+
+
sim.add_sync_process(process)
- with sim.write_vcd("simulator.vcd", "simulator.gtkw",
+
+ name = self.funit.name.lower()
+ with sim.write_vcd("%s_simulator.vcd" % name,
+ "%s_simulator.gtkw" % name,
traces=[]):
sim.run()