From: Luke Kenneth Casson Leighton Date: Fri, 14 Aug 2020 14:26:10 +0000 (+0100) Subject: move instruction decoder out of core X-Git-Tag: semi_working_ecp5~353 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8d375b8db0fa9ba7ad2898a35bc0a12b1e69857e;p=soc.git move instruction decoder out of core --- diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index 97f2b530..838cb121 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -578,7 +578,6 @@ class PowerDecode2(Elaboratable): self.dec = dec self.e = Decode2ToExecute1Type() - self.valid = Signal() # sync signal # state information needed by the Decoder (TODO: this as a Record) self.state = CoreState("dec2") diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index 477eb78a..19f076ba 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -30,8 +30,8 @@ from nmutil.util import treereduce from soc.fu.compunits.compunits import AllFunctionUnits from soc.regfile.regfiles import RegFiles -from soc.decoder.power_decoder import create_pdecode -from soc.decoder.power_decoder2 import PowerDecode2, get_rdflags +from soc.decoder.decode2execute1 import Decode2ToExecute1Type +from soc.decoder.power_decoder2 import get_rdflags from soc.decoder.decode2execute1 import Data from soc.experiment.l0_cache import TstL0CacheBuffer # test only from soc.config.test.test_loadstore import TestMemPspec @@ -76,18 +76,13 @@ class NonProductionCore(Elaboratable): self.regs = RegFiles() # instruction decoder - pdecode = create_pdecode() - self.pdecode2 = PowerDecode2(pdecode) # instruction decoder + self.e = Decode2ToExecute1Type() # decoded instruction # issue/valid/busy signalling - self.ivalid_i = self.pdecode2.valid # instruction is valid + self.ivalid_i = Signal(reset_less=True) # instruction is valid self.issue_i = Signal(reset_less=True) self.busy_o = Signal(name="corebusy_o", reset_less=True) - # instruction input - self.bigendian_i = self.pdecode2.dec.bigendian - self.raw_opcode_i = self.pdecode2.dec.raw_opcode_in - # start/stop and terminated signalling self.core_stopped_i = Signal(reset_less=True) self.core_reset_i = Signal() @@ -96,7 +91,6 @@ class NonProductionCore(Elaboratable): def elaborate(self, platform): m = Module() - m.submodules.pdecode2 = dec2 = self.pdecode2 m.submodules.fus = self.fus m.submodules.l0 = l0 = self.l0 self.regs.elaborate_into(m, platform) @@ -127,8 +121,7 @@ class NonProductionCore(Elaboratable): """ comb, sync = m.d.comb, m.d.sync fus = self.fus.fus - dec2 = self.pdecode2 - e = dec2.e # to execute + e = self.e # to execute # enable-signals for each FU, get one bit for each FU (by name) fu_enable = Signal(len(fus), reset_less=True) @@ -142,7 +135,7 @@ class NonProductionCore(Elaboratable): for funame, fu in fus.items(): fnunit = fu.fnunit.value enable = Signal(name="en_%s" % funame, reset_less=True) - comb += enable.eq((dec2.e.do.fn_unit & fnunit).bool()) + comb += enable.eq((e.do.fn_unit & fnunit).bool()) comb += fu_bitdict[funame].eq(enable) # sigh - need a NOP counter @@ -152,7 +145,7 @@ class NonProductionCore(Elaboratable): comb += self.busy_o.eq(1) with m.If(self.ivalid_i): # run only when valid - with m.Switch(dec2.e.do.insn_type): + with m.Switch(e.do.insn_type): # check for ATTN: halt if true with m.Case(MicrOp.OP_ATTN): m.d.sync += self.core_terminate_o.eq(1) @@ -169,7 +162,7 @@ class NonProductionCore(Elaboratable): # run this FunctionUnit if enabled with m.If(enable): # route op, issue, busy, read flags and mask to FU - comb += fu.oper_i.eq_from_execute1(dec2.e) + comb += fu.oper_i.eq_from_execute1(e) comb += fu.issue_i.eq(self.issue_i) comb += self.busy_o.eq(fu.busy_o) rdmask = get_rdflags(e, fu) @@ -427,10 +420,9 @@ class NonProductionCore(Elaboratable): def get_byregfiles(self, readmode): mode = "read" if readmode else "write" - dec2 = self.pdecode2 regs = self.regs fus = self.fus.fus - e = dec2.e # decoded instruction to execute + e = self.e # decoded instruction to execute # dictionary of lists of regfile ports byregfiles = {} @@ -479,7 +471,7 @@ class NonProductionCore(Elaboratable): def __iter__(self): yield from self.fus.ports() - yield from self.pdecode2.ports() + yield from self.e.ports() yield from self.l0.ports() # TODO: regs diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index ae6ec356..485d7e00 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -21,6 +21,8 @@ from nmigen.cli import rtlil from nmigen.cli import main import sys +from soc.decoder.power_decoder import create_pdecode +from soc.decoder.power_decoder2 import PowerDecode2 from soc.decoder.decode2execute1 import Data from soc.experiment.testmem import TestMemory # test only for instructions from soc.regfile.regfiles import StateRegs @@ -43,6 +45,10 @@ class TestIssuer(Elaboratable): # main instruction core self.core = core = NonProductionCore(pspec) + # instruction decoder + pdecode = create_pdecode() + self. pdecode2 = PowerDecode2(pdecode) # decoder + # Test Instruction memory self.imem = ConfigFetchUnit(pspec).fu # one-row cache of instruction read @@ -80,6 +86,10 @@ class TestIssuer(Elaboratable): m.submodules.imem = imem = self.imem m.submodules.dbg = dbg = self.dbg + # instruction decoder + pdecode = create_pdecode() + m.submodules.dec2 = pdecode2 = self.pdecode2 + # convenience dmi = dbg.dmi d_reg = dbg.dbg_gpr @@ -101,7 +111,7 @@ class TestIssuer(Elaboratable): # busy/halted signals from core comb += self.busy_o.eq(core.busy_o) - comb += core.bigendian_i.eq(self.core_bigendian_i) + comb += pdecode2.dec.bigendian.eq(self.core_bigendian_i) # current state (MSR/PC at the moment cur_state = CoreState("cur") @@ -147,15 +157,18 @@ class TestIssuer(Elaboratable): comb += dbg.state.pc.eq(pc) comb += dbg.state.msr.eq(cur_state.msr) + # temporarily connect up core execute decode to pdecode2 + comb += core.e.eq(pdecode2.e) + # temporaries - core_busy_o = core.busy_o # core is busy - core_ivalid_i = core.ivalid_i # instruction is valid - core_issue_i = core.issue_i # instruction is issued - core_be_i = core.bigendian_i # bigendian mode - core_opcode_i = core.raw_opcode_i # raw opcode - - insn_type = core.pdecode2.e.do.insn_type - insn_state = core.pdecode2.state + core_busy_o = core.busy_o # core is busy + core_ivalid_i = core.ivalid_i # instruction is valid + core_issue_i = core.issue_i # instruction is issued + core_be_i = pdecode2.dec.bigendian # bigendian mode + core_opcode_i = pdecode2.dec.raw_opcode_in # raw opcode + + insn_type = pdecode2.e.do.insn_type + insn_state = pdecode2.state # actually use a nmigen FSM for the first time (w00t) # this FSM is perhaps unusual in that it detects conditions diff --git a/src/soc/simple/test/test_core.py b/src/soc/simple/test/test_core.py index 21ffa2e8..af748792 100644 --- a/src/soc/simple/test/test_core.py +++ b/src/soc/simple/test/test_core.py @@ -34,7 +34,7 @@ from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase from soc.regfile.util import spr_to_fast_reg -def setup_regs(core, test): +def setup_regs(pdecode2, core, test): # set up INT regfile, "direct" write (bypass rd/write ports) intregs = core.regs.int @@ -112,7 +112,6 @@ def setup_regs(core, test): yield Settle() # XER - pdecode2 = core.pdecode2 so = yield xregs.regs[xregs.SO].reg ov = yield xregs.regs[xregs.OV].reg ca = yield xregs.regs[xregs.CA].reg diff --git a/src/soc/simple/test/test_issuer.py b/src/soc/simple/test/test_issuer.py index f25b61ce..4a34ff17 100644 --- a/src/soc/simple/test/test_issuer.py +++ b/src/soc/simple/test/test_issuer.py @@ -144,7 +144,7 @@ class TestRunner(FHDLTestCase): imem = issuer.imem._get_memory() core = issuer.core dmi = issuer.dbg.dmi - pdecode2 = core.pdecode2 + pdecode2 = issuer.pdecode2 l0 = core.l0 # copy of the decoder for simulator @@ -202,7 +202,7 @@ class TestRunner(FHDLTestCase): yield from setup_i_memory(imem, pc, instructions) yield from setup_test_memory(l0, sim) - yield from setup_regs(core, test) + yield from setup_regs(pdecode2, core, test) yield pc_i.eq(pc) yield issuer.pc_i.ok.eq(1)