X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fsimple%2Fissuer.py;h=3f7ed3a7288ce2d438ccee4ee9771139de9b96f8;hb=4c040d55af86f8cf94bb313aee5c5dece8fed916;hp=7dfa9d6797732a4ed10da59cb4062f29f0f65925;hpb=395c5c33e73359c9e3d9899899a933b1cebbaa49;p=soc.git diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 7dfa9d67..3f7ed3a7 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -18,11 +18,13 @@ improved. from nmigen import Elaboratable, Module, Signal from nmigen.cli import rtlil - from soc.decoder.decode2execute1 import Data from soc.experiment.testmem import TestMemory # test only for instructions from soc.regfile.regfiles import FastRegs from soc.simple.core import NonProductionCore +from soc.config.test.test_loadstore import TestMemPspec +from soc.config.ifetch import ConfigFetchUnit +from soc.decoder.power_enums import MicrOp class TestIssuer(Elaboratable): @@ -30,14 +32,12 @@ class TestIssuer(Elaboratable): efficiency and speed is not the main goal here: functional correctness is. """ - def __init__(self, addrwid=6, idepth=6, ifacetype='testpi'): + def __init__(self, pspec): # main instruction core - self.core = core = NonProductionCore(addrwid, ifacetype=ifacetype) + self.core = core = NonProductionCore(pspec) # Test Instruction memory - self.imemwid = 64 - self.imem = TestMemory(self.imemwid, idepth) - self.i_rd = self.imem.rdport + self.imem = ConfigFetchUnit(pspec).fu # one-row cache of instruction read self.iline = Signal(64) # one instruction line self.iprev_adr = Signal(64) # previous address: if different, do read @@ -49,9 +49,11 @@ class TestIssuer(Elaboratable): self.busy_o = core.busy_o self.memerr_o = Signal(reset_less=True) - # 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'] + # FAST regfile read /write ports for PC and MSR + self.fast_r_pc = self.core.regs.rf['fast'].r_ports['d_rd1'] # PC rd + self.fast_w_pc = self.core.regs.rf['fast'].w_ports['d_wr1'] # PC wr + self.fast_r_msr = self.core.regs.rf['fast'].r_ports['d_rd2'] # MSR rd + # 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' @@ -71,14 +73,18 @@ class TestIssuer(Elaboratable): # 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) + cur_pc = Signal(64) # current PC (note it is reset/sync) pc_changed = Signal() # note write to PC - comb += self.pc_o.eq(current_pc) + comb += self.pc_o.eq(cur_pc) ilatch = Signal(32) + # MSR (temp and latched) + cur_msr = Signal(64) # current MSR (note it is reset/sync) + msr = Signal(64, reset_less=True) + # next instruction (+4 on current) nia = Signal(64, reset_less=True) - comb += nia.eq(current_pc + 4) + comb += nia.eq(cur_pc + 4) # temporaries core_busy_o = core.busy_o # core is busy @@ -87,57 +93,83 @@ class TestIssuer(Elaboratable): core_be_i = core.bigendian_i # bigendian mode core_opcode_i = core.raw_opcode_i # raw opcode - # actually use a nmigen FSM for the first time (w00t) - with m.FSM() as fsm: - - # 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) - with m.If(self.pc_i.ok): - # incoming override (start from pc_i) - comb += pc.eq(self.pc_i.data) + insn_type = core.pdecode2.e.do.insn_type + insn_msr = core.pdecode2.msr + + # only run if not in halted state + with m.If(~core.core_terminated_o): + + # actually use a nmigen FSM for the first time (w00t) + # this FSM is perhaps unusual in that it detects conditions + # then "holds" information, combinatorially, for the core + # (as opposed to using sync - which would be on a clock's delay) + # this includes the actual opcode, valid flags and so on. + with m.FSM() as fsm: + + # 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) + with m.If(self.pc_i.ok): + # incoming override (start from pc_i) + comb += pc.eq(self.pc_i.data) + with m.Else(): + # otherwise read FastRegs regfile for PC + comb += self.fast_r_pc.ren.eq(1<