# decoder2 - an instance of power_decoder2
# regfile - a list of initial values for the registers
# initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
+ # respect_pc - tracks the program counter. requires initial_insns
def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
initial_mem=None, initial_msr=0,
- initial_insns=None):
+ initial_insns=None, respect_pc=False,
+ disassembly=None):
+
+ self.respect_pc = respect_pc
if initial_sprs is None:
initial_sprs = {}
if initial_mem is None:
initial_mem = {}
if initial_insns is None:
initial_insns = {}
- self.respect_pc = False
- else:
- # setup batch of instructions: we want to respect (follow) the PC
- self.respect_pc = True
+ assert self.respect_pc == False, "instructions required to honor pc"
+
+ # "fake program counter" mode (for unit testing)
+ if not respect_pc:
+ if isinstance(initial_mem, tuple):
+ self.fake_pc = initial_mem[0]
+ else:
+ self.fake_pc = 0
+
+ # disassembly: we need this for now (not given from the decoder)
+ self.disassembly = {}
+ if disassembly:
+ for i, code in enumerate(disassembly):
+ self.disassembly[i*4 + self.fake_pc] = code
+ # set up registers, instruction memory, data memory, PC, SPRs, MSR
self.gpr = GPR(decoder2, regfile)
self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
- self.insns = Mem(row_bytes=4, initial_mem=initial_insns)
+ self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
self.pc = PC()
self.spr = SPR(decoder2, initial_sprs)
self.msr = SelectableInt(initial_msr, 64) # underlying reg
+
# TODO, needed here:
# FPR (same as GPR except for FP nums)
# 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
so = so | ov
self.spr['XER'][XER_bits['SO']] = so
-
-
def handle_comparison(self, outputs):
out = outputs[0]
out = exts(out.value, out.bits)
self.namespace['NIA'] = SelectableInt(pc_val, 64)
self.pc.update(self.namespace)
+ def setup_one(self):
+ """set up one instruction
+ """
+ if self.respect_pc:
+ pc = self.pc.CIA.value
+ else:
+ pc = self.fake_pc
+ ins = yield self.imem.ld(pc, 4, False)
+ yield self.pdecode2.dec.raw_opcode_in.eq(ins)
+ yield self.pdecode2.dec.bigendian.eq(0) # little / big?
+ self._pc
+
+ def execute_one(self):
+ """execute one instruction
+ """
+ # get the disassembly code for this instruction
+ code = self.disassembly[self._pc]
+ opname = code.split(' ')[0]
+ yield from call(opname)
+
+ if not self.respect_pc:
+ self.fake_pc += 4
+ #else:
+ #self.pc.CIA.value = self.pc.NIA.value
+
def call(self, name):
# TODO, asmregs is from the spec, e.g. add RT,RA,RB
# see http://bugs.libre-riscv.org/show_bug.cgi?id=282