X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fsimple%2Fissuer.py;h=9b7ed9c59d4f23a4ecfe37ef9e48137c5d1e98bb;hb=b3a125fac4792231aac25b022028401b7ba6ae6c;hp=c8dac1475873a21ec38cd85c6ea3b4e28b6f8bc7;hpb=dbb140cd79611e59071d40416cd975f0f524faf2;p=soc.git diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index c8dac147..9b7ed9c5 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -16,7 +16,7 @@ improved. """ from nmigen import (Elaboratable, Module, Signal, ClockSignal, ResetSignal, - ClockDomain, DomainRenamer, Mux) + ClockDomain, DomainRenamer, Mux, Const, Repl) from nmigen.cli import rtlil from nmigen.cli import main import sys @@ -30,15 +30,18 @@ from soc.regfile.regfiles import StateRegs, 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 +from soc.decoder.power_enums import (MicrOp, SVP64PredInt, SVP64PredCR, + SVP64PredMode) from soc.debug.dmi import CoreDebug, DMIInterface from soc.debug.jtag import JTAG from soc.config.pinouts import get_pinspecs from soc.config.state import CoreState from soc.interrupts.xics import XICS_ICP, XICS_ICS from soc.bus.simple_gpio import SimpleGPIO +from soc.bus.SPBlock512W64B8W import SPBlock512W64B8W from soc.clock.select import ClockSelect from soc.clock.dummypll import DummyPLL +from soc.sv.svstate import SVSTATERec from nmutil.util import rising_edge @@ -50,14 +53,115 @@ def get_insn(f_instr_o, pc): # 64-bit: bit 2 of pc decides which word to select return f_instr_o.word_select(pc[2], 32) +# gets state input or reads from state regfile +def state_get(m, state_i, name, regfile, regnum): + comb = m.d.comb + sync = m.d.sync + # read the PC + res = Signal(64, reset_less=True, name=name) + res_ok_delay = Signal(name="%s_ok_delay" % name) + sync += res_ok_delay.eq(~state_i.ok) + with m.If(state_i.ok): + # incoming override (start from pc_i) + comb += res.eq(state_i.data) + with m.Else(): + # otherwise read StateRegs regfile for PC... + comb += regfile.ren.eq(1<1 loop + with m.If(~dbg.core_stop_o & ~core_rst): + comb += exec_pc_ready_i.eq(1) + with m.If(exec_pc_valid_o): + + # was this the last loop iteration? + is_last = Signal() + cur_vl = cur_state.svstate.vl + comb += is_last.eq(next_srcstep == cur_vl) + + # if either PC or SVSTATE were changed by the previous + # instruction, go directly back to Fetch, without + # updating either PC or SVSTATE + with m.If(pc_changed | sv_changed): + m.next = "ISSUE_START" + + # also return to Fetch, when no output was a vector + # (regardless of SRCSTEP and VL), or when the last + # instruction was really the last one of the VL loop + with m.Elif((~pdecode2.loop_continue) | is_last): + # before going back to fetch, update the PC state + # register with the NIA. + # ok here we are not reading the branch unit. + # TODO: this just blithely overwrites whatever + # pipeline updated the PC + comb += self.state_w_pc.wen.eq(1 << StateRegs.PC) + comb += self.state_w_pc.data_i.eq(nia) + # reset SRCSTEP before returning to Fetch + with m.If(pdecode2.loop_continue): + comb += new_svstate.srcstep.eq(0) + comb += new_svstate.dststep.eq(0) + comb += update_svstate.eq(1) + m.next = "ISSUE_START" + + # returning to Execute? then, first update SRCSTEP + with m.Else(): + comb += new_svstate.srcstep.eq(next_srcstep) + comb += new_svstate.dststep.eq(next_dststep) + comb += update_svstate.eq(1) + m.next = "DECODE_SV" + + with m.Else(): + comb += core.core_stopped_i.eq(1) + comb += dbg.core_stopped_i.eq(1) + # while stopped, allow updating the PC and SVSTATE + with m.If(self.pc_i.ok): + comb += self.state_w_pc.wen.eq(1 << StateRegs.PC) + comb += self.state_w_pc.data_i.eq(self.pc_i.data) + sync += pc_changed.eq(1) + with m.If(self.svstate_i.ok): + comb += new_svstate.eq(self.svstate_i.data) + comb += update_svstate.eq(1) + sync += sv_changed.eq(1) + + # check if svstate needs updating: if so, write it to State Regfile + with m.If(update_svstate): + comb += self.state_w_sv.wen.eq(1<