print("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
print ("NIA, CIA", self.pc.CIA.value, self.pc.NIA.value)
- yield self.dec2.dec.raw_opcode_in.eq(ins)
+ yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
yield self.dec2.dec.bigendian.eq(0) # little / big?
def execute_one(self):
# https://bugs.libre-soc.org/show_bug.cgi?id=390
if int_op == InternalOp.OP_MTCRF.value:
dec_insn = yield self.dec2.e.insn
- print ("mtcrf", bin(dec_insn), (dec_insn & (1<<20)))
- if dec_insn & (1<<21) != 0: # sigh
+ if dec_insn & (1<<20) != 0: # sigh
asmop = 'mtocrf'
else:
asmop = 'mtcrf'
yield from setup_test_memory(l0, sim)
index = sim.pc.CIA.value//4
- while index < len(instructions):
- ins, code = instructions[index]
- yield from sim.setup_one()
+ while True:
+ try:
+ yield from sim.setup_one()
+ except KeyError: # indicates instruction not in imem: stop
+ break
yield Settle()
- print(code)
+ ins, code = instructions[index]
+ print(index, code)
# ask the decoder to decode this binary data (endian'd)
yield pdecode2.dec.bigendian.eq(0) # little / big?
# call simulated operation
yield from sim.execute_one()
+ yield Settle()
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
SRR1 = 6
def __init__(self):
super().__init__(64, 8)
- self.w_ports = {'nia': self.write_port("dest1"),
+ self.w_ports = {'nia': self.write_port("nia"),
'msr': self.write_port("dest2"),
'spr1': self.write_port("dest3"),
'spr2': self.write_port("dest4"),
if __name__ == '__main__':
- dut = TestIssuer()
+ dut = NonProductionCore()
vl = rtlil.convert(dut, ports=dut.ports())
- with open("test_issuer.il", "w") as f:
+ with open("test_core.il", "w") as f:
f.write(vl)
# FAST regfile read /write ports
self.fast_rd1 = self.core.regs.rf['fast'].r_ports['d_rd1']
self.fast_wr1 = self.core.regs.rf['fast'].w_ports['d_wr1']
+ # hack method of keeping an eye on whether branch/trap set the PC
+ self.fast_nia = self.core.regs.rf['fast'].w_ports['nia']
+ self.fast_nia.wen.name = 'fast_nia_wen'
def elaborate(self, platform):
m = Module()
# PC and instruction from I-Memory
current_insn = Signal(32) # current fetched instruction (note sync)
current_pc = Signal(64) # current PC (note it is reset/sync)
+ pc_changed = Signal() # note write to PC
comb += self.pc_o.eq(current_pc)
ilatch = Signal(32)
# waiting (zzz)
with m.State("IDLE"):
+ sync += pc_changed.eq(0)
with m.If(self.go_insn_i):
# instruction allowed to go: start by reading the PC
pc = Signal(64, reset_less=True)
# lookups together. this is Generally Bad.
comb += self.i_rd.addr.eq(pc[2:]) # ignore last 2 bits
comb += current_insn.eq(self.i_rd.data)
- comb += current_pc.eq(pc)
+ sync += current_pc.eq(pc)
m.next = "INSN_READ" # move to "issue" phase
# got the instruction: start issue
comb += core_ivalid_i.eq(1) # say instruction is valid
comb += core_opcode_i.eq(ilatch) # actual opcode
#sync += core_issue_i.eq(0) # issue raises for only one cycle
+ with m.If(self.fast_nia.wen):
+ sync += pc_changed.eq(1)
with m.If(~core_busy_o): # instruction done!
#sync += core_ivalid_i.eq(0) # say instruction is invalid
#sync += core_opcode_i.eq(0) # clear out (no good reason)
# ok here we are not reading the branch unit. TODO
# this just blithely overwrites whatever pipeline updated
# the PC
- comb += self.fast_wr1.wen.eq(1<<FastRegs.PC)
- comb += self.fast_wr1.data_i.eq(nia)
+ with m.If(~pc_changed):
+ comb += self.fast_wr1.wen.eq(1<<FastRegs.PC)
+ comb += self.fast_wr1.data_i.eq(nia)
m.next = "IDLE" # back to idle
return m
from soc.fu.cr.test.test_pipe_caller import CRTestCase
from soc.fu.branch.test.test_pipe_caller import BranchTestCase
from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase
+from soc.simulator.test_sim import GeneralTestCases
def setup_i_memory(imem, startaddr, instructions):
print(test.name)
program = test.program
self.subTest(test.name)
+ print ("regs", test.regs)
+ print ("sprs", test.sprs)
+ print ("cr", test.cr)
+ print ("mem", test.mem)
+ print ("msr", test.msr)
+ print ("assem", program.assembly)
+ gen = list(program.generate_instructions())
+ insncode = program.assembly.splitlines()
+ instructions = list(zip(gen, insncode))
sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
- test.msr)
- gen = program.generate_instructions()
- instructions = list(zip(gen, program.assembly.splitlines()))
+ test.msr,
+ initial_insns=gen, respect_pc=True,
+ disassembly=insncode)
pc = 0 # start address
ins, code = instructions[index]
print("instruction: 0x{:X}".format(ins & 0xffffffff))
- print(code)
+ print(index, code)
# start the instruction
yield go_insn_i.eq(1)
# call simulated operation
opname = code.split(' ')[0]
yield from sim.call(opname)
+ yield Settle()
index = sim.pc.CIA.value//4
# register check
if __name__ == "__main__":
unittest.main(exit=False)
suite = unittest.TestSuite()
+ suite.addTest(TestRunner(GeneralTestCases.test_data))
suite.addTest(TestRunner(LDSTTestCase.test_data))
suite.addTest(TestRunner(CRTestCase.test_data))
suite.addTest(TestRunner(ShiftRotTestCase.test_data))
instructions = '\n'.join(instructions)
self.assembly = instructions + '\n' # plus final newline
self._assemble()
+ self._instructions = list(self._get_instructions())
def __enter__(self):
return self
sys.exit(1)
self._link(outfile)
- def generate_instructions(self):
+ def _get_instructions(self):
while True:
data = self.binfile.read(4)
if not data:
break
yield struct.unpack('<i', data)[0]
+ def generate_instructions(self):
+ yield from self._instructions
+
def reset(self):
self.binfile.seek(0)
from soc.simulator.program import Program
from soc.simulator.qemu import run_program
from soc.decoder.isa.all import ISA
+from soc.fu.test.common import TestCase
class Register:
self.num = num
-class DecoderTestCase(FHDLTestCase):
+class GeneralTestCases(FHDLTestCase):
+ test_data = []
- def run_tst(self, generator, initial_mem=None):
- m = Module()
- comb = m.d.comb
-
- gen = list(generator.generate_instructions())
- insn_code = generator.assembly.splitlines()
- instructions = list(zip(gen, insn_code))
-
- pdecode = create_pdecode()
- m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
-
- simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0,
- initial_insns=gen, respect_pc=True,
- disassembly=insn_code)
-
- sim = Simulator(m)
-
- def process():
- while True:
- try:
- yield from simulator.setup_one()
- except KeyError: # indicates instruction not in imem: stop
- break
- yield Settle()
- yield from simulator.execute_one()
- yield Settle()
-
-
- sim.add_process(process)
- with sim.write_vcd("simulator.vcd", "simulator.gtkw",
- traces=[]):
- sim.run()
-
- return simulator
+ def __init__(self, name="general"):
+ super().__init__(name)
+ self.test_name = name
@unittest.skip("disable")
def test_0_cmp(self):
with Program(lst) as program:
self.run_tst_program(program, [1])
- def tst_2_load_store(self):
+ @unittest.skip("disable")
+ def test_2_load_store(self):
lst = ["addi 1, 0, 0x1004",
"addi 2, 0, 0x1008",
"addi 3, 0, 0x00ee",
with Program(lst) as program:
self.run_tst_program(program, [9], initial_mem={})
+ def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
+ initial_mem=None):
+ initial_regs = [0] * 32
+ tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
+ initial_mem, 0)
+ self.test_data.append(tc)
+
+
+class DecoderTestCase(GeneralTestCases):
+
+ def run_tst(self, generator, initial_mem=None):
+ m = Module()
+ comb = m.d.comb
+
+ gen = list(generator.generate_instructions())
+ insn_code = generator.assembly.splitlines()
+ instructions = list(zip(gen, insn_code))
+
+ pdecode = create_pdecode()
+ m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
+
+ simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0,
+ initial_insns=gen, respect_pc=True,
+ disassembly=insn_code)
+
+ sim = Simulator(m)
+
+ def process():
+ while True:
+ try:
+ yield from simulator.setup_one()
+ except KeyError: # indicates instruction not in imem: stop
+ break
+ yield Settle()
+ yield from simulator.execute_one()
+ yield Settle()
+
+
+ sim.add_process(process)
+ with sim.write_vcd("simulator.vcd", "simulator.gtkw",
+ traces=[]):
+ sim.run()
+
+ return simulator
+
def run_tst_program(self, prog, reglist, initial_mem=None):
import sys
simulator = self.run_tst(prog, initial_mem=initial_mem)