X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fsimple%2Fissuer.py;h=a273fd1656d2c393116d5c4485ac0c2c7b7591ca;hb=006e364df732d4cff95ddcf948889d5fda8a561a;hp=1af178de78682f142fd5f0b8f9fed7482c6ef42c;hpb=aaebc1ab35f58eaca65b3a8ad1668a197d8f31ea;p=soc.git diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 1af178de..a273fd16 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -17,12 +17,16 @@ improved. from nmigen import Elaboratable, Module, Signal from nmigen.cli import rtlil - +from nmigen.cli import main +import sys 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,27 +34,35 @@ class TestIssuer(Elaboratable): efficiency and speed is not the main goal here: functional correctness is. """ - def __init__(self, addrwid=6, idepth=6): + def __init__(self, pspec): # main instruction core - self.core = core = NonProductionCore(addrwid) + self.core = core = NonProductionCore(pspec) # Test Instruction memory - self.imem = TestMemory(32, idepth) - self.i_rd = self.imem.rdport - #self.i_wr = self.imem.write_port() errr... + 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 # instruction go/monitor - self.go_insn_i = Signal(reset_less=True) + self.go_insn_i = Signal() self.pc_o = Signal(64, reset_less=True) - self.pc_i = Data(64, "pc") # set "ok" to indicate "please change me" - self.busy_o = core.busy_o + self.pc_i = Data(64, "pc_i") # set "ok" to indicate "please change me" + self.core_start_i = Signal() + self.core_stop_i = Signal() + self.core_bigendian_i = Signal() + self.busy_o = Signal(reset_less=True) + self.halted_o = Signal(reset_less=True) 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['cia'] # 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['msr'] # 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' def elaborate(self, platform): m = Module() @@ -59,22 +71,33 @@ class TestIssuer(Elaboratable): m.submodules.core = core = self.core m.submodules.imem = imem = self.imem + # busy/halted signals from core + comb += self.busy_o.eq(core.busy_o) + comb += self.halted_o.eq(core.core_terminated_o) + comb += core.core_start_i.eq(self.core_start_i) + comb += core.core_stop_i.eq(self.core_stop_i) + comb += core.bigendian_i.eq(self.core_bigendian_i) + # temporary hack: says "go" immediately for both address gen and ST l0 = core.l0 ldst = core.fus.fus['ldst0'] - m.d.comb += ldst.ad.go.eq(ldst.ad.rel) # link addr-go direct to rel - m.d.comb += ldst.st.go.eq(ldst.st.rel) # link store-go direct to rel + m.d.comb += ldst.ad.go_i.eq(ldst.ad.rel_o) # link addr-go direct to rel + m.d.comb += ldst.st.go_i.eq(ldst.st.rel_o) # link store-go direct to rel # 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(64) # note write to PC - comb += self.pc_o.eq(current_pc) + cur_pc = Signal(64) # current PC (note it is reset/sync) + pc_changed = Signal() # note write to 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 @@ -83,57 +106,92 @@ 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 + insn_cia = core.pdecode2.cia + + # 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<