From: Luke Kenneth Casson Leighton Date: Thu, 18 Nov 2021 21:40:48 +0000 (+0000) Subject: set up a temporary copy of CoreInput X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d9479d82be1007f0d0c2de8b16d2a0fd06615e1a;p=soc.git set up a temporary copy of CoreInput (and fix CoreInput.eq, sigh) --- diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index ecf25644..063beaae 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -116,9 +116,12 @@ class NonProductionCore(ControlBase): # set up input and output: unusual requirement to set data directly # (due to the way that the core is set up in a different domain, # see TestIssuer.setup_peripherals - self.i, self.o = self.new_specs(None) + self.p.i_data, self.n.o_data = self.new_specs(None) self.i, self.o = self.p.i_data, self.n.o_data + # actual internal input data used (captured) + self.ireg = self.ispec() + # create per-FU instruction decoders (subsetted). these "satellite" # decoders reduce wire fan-out from the one (main) PowerDecoder2 # (used directly by the trap unit) to the *twelve* (or more) @@ -138,7 +141,7 @@ class NonProductionCore(ControlBase): continue self.decoders[funame] = PowerDecodeSubset(None, opkls, f_name, final=True, - state=self.i.state, + state=self.ireg.state, svp64_en=self.svp64_en, regreduce_en=self.regreduce_en) self.des[funame] = self.decoders[funame].do @@ -174,11 +177,15 @@ class NonProductionCore(ControlBase): regs = self.regs fus = self.fus.fus + # connect up temporary copy of incoming instruction + print ("connect ireg, i", self.ireg, self.i) + comb += self.ireg.eq(self.i) + # connect decoders self.connect_satellite_decoders(m) # ssh, cheat: trap uses the main decoder because of the rewriting - self.des[self.trapunit] = self.i.e.do + self.des[self.trapunit] = self.ireg.e.do # connect up Function Units, then read/write ports, and hazard conflict issue_conflict = Signal() @@ -204,22 +211,22 @@ class NonProductionCore(ControlBase): # as subset decoders this massively reduces wire fanout given # the large number of ALUs setattr(m.submodules, "dec_%s" % v.fn_name, v) - comb += v.dec.raw_opcode_in.eq(self.i.raw_insn_i) - comb += v.dec.bigendian.eq(self.i.bigendian_i) + comb += v.dec.raw_opcode_in.eq(self.ireg.raw_insn_i) + comb += v.dec.bigendian.eq(self.ireg.bigendian_i) # sigh due to SVP64 RA_OR_ZERO detection connect these too - comb += v.sv_a_nz.eq(self.i.sv_a_nz) + comb += v.sv_a_nz.eq(self.ireg.sv_a_nz) if self.svp64_en: - comb += v.pred_sm.eq(self.i.sv_pred_sm) - comb += v.pred_dm.eq(self.i.sv_pred_dm) + comb += v.pred_sm.eq(self.ireg.sv_pred_sm) + comb += v.pred_dm.eq(self.ireg.sv_pred_dm) if k != self.trapunit: - comb += v.sv_rm.eq(self.i.sv_rm) # pass through SVP64 ReMap - comb += v.is_svp64_mode.eq(self.i.is_svp64_mode) + comb += v.sv_rm.eq(self.ireg.sv_rm) # pass through SVP64 RM + comb += v.is_svp64_mode.eq(self.ireg.is_svp64_mode) # only the LDST PowerDecodeSubset *actually* needs to # know to use the alternative decoder. this is all # a terrible hack if k.lower().startswith("ldst"): comb += v.use_svp64_ldst_dec.eq( - self.i.use_svp64_ldst_dec) + self.ireg.use_svp64_ldst_dec) def connect_instruction(self, m, issue_conflict): """connect_instruction @@ -279,7 +286,7 @@ class NonProductionCore(ControlBase): # instruction. fnunit = fu.fnunit.value en_req = Signal(name="issue_en_%s" % funame, reset_less=True) - fnmatch = (self.i.e.do.fn_unit & fnunit).bool() + fnmatch = (self.ireg.e.do.fn_unit & fnunit).bool() comb += en_req.eq(fnmatch & ~fu.busy_o & self.p.i_valid) i_l.append(en_req) # store in list for doing the Cat-trick # picker output, gated by enable: store in fu_bitdict @@ -302,7 +309,7 @@ class NonProductionCore(ControlBase): comb += busy_o.eq(1) with m.If(self.p.i_valid): # run only when valid - with m.Switch(self.i.e.do.insn_type): + with m.Switch(self.ireg.e.do.insn_type): # check for ATTN: halt if true with m.Case(MicrOp.OP_ATTN): m.d.sync += self.o.core_terminate_o.eq(1) @@ -326,7 +333,7 @@ class NonProductionCore(ControlBase): comb += fu.issue_i.eq(1) # issue when input valid # rdmask, which is for registers, needs to come # from the *main* decoder - rdmask = get_rdflags(self.i.e, fu) + rdmask = get_rdflags(self.ireg.e, fu) comb += fu.rdmaskn.eq(~rdmask) print ("core: overlap allowed", self.allow_overlap) @@ -774,7 +781,7 @@ class NonProductionCore(ControlBase): mode = "read" if readmode else "write" regs = self.regs fus = self.fus.fus - e = self.i.e # decoded instruction to execute + e = self.ireg.e # decoded instruction to execute # dictionary of lists of regfile ports byregfiles = {} diff --git a/src/soc/simple/core_data.py b/src/soc/simple/core_data.py index 325502dd..4146d189 100644 --- a/src/soc/simple/core_data.py +++ b/src/soc/simple/core_data.py @@ -33,9 +33,10 @@ class FetchOutput: self.bigendian_i = Signal() # bigendian - TODO, set by MSR.BE def eq(self, i): - self.state.eq(i.state) - self.raw_insn_i.eq(i.raw_insn_i) - self.bigendian_i.eq(i.bigendian_i) + return [self.state.eq(i.state), + self.raw_insn_i.eq(i.raw_insn_i), + self.bigendian_i.eq(i.bigendian_i), + ] class CoreInput: @@ -77,18 +78,21 @@ class CoreInput: self.sv_pred_dm = Signal() # TODO: SIMD width def eq(self, i): - self.e.eq(i.e) - self.sv_a_nz.eq(i.sv_a_nz) - self.state.eq(i.state) - self.raw_insn_i.eq(i.raw_insn_i) - self.bigendian_i.eq(i.bigendian_i) + res = [self.e.eq(i.e), + self.sv_a_nz.eq(i.sv_a_nz), + self.state.eq(i.state), + self.raw_insn_i.eq(i.raw_insn_i), + self.bigendian_i.eq(i.bigendian_i), + ] if not self.svp64_en: - return - self.sv_rm.eq(i.sv_rm) - self.is_svp64_mode.eq(i.is_svp64_mode) - self.use_svp64_ldst_dec.eq(i.use_svp64_ldst_dec) - self.sv_pred_sm.eq(i.sv_pred_sm) - self.sv_pred_dm.eq(i.sv_pred_dm) + return res + res += [ self.sv_rm.eq(i.sv_rm), + self.is_svp64_mode.eq(i.is_svp64_mode), + self.use_svp64_ldst_dec.eq(i.use_svp64_ldst_dec), + self.sv_pred_sm.eq(i.sv_pred_sm), + self.sv_pred_dm.eq(i.sv_pred_dm), + ] + return res class CoreOutput: @@ -99,8 +103,9 @@ class CoreOutput: self.exc_happened = Signal() # exception happened def eq(self, i): - self.core_terminate_o.eq(i.core_terminate_o) - self.busy_o.eq(i.busy_o) - self.exc_happened.eq(i.exc_happened) + return [self.core_terminate_o.eq(i.core_terminate_o), + self.busy_o.eq(i.busy_o), + self.exc_happened.eq(i.exc_happened), + ]