from nmigen import Elaboratable, Module, Signal, ResetSignal, Cat, Mux
from nmigen.cli import rtlil
-from soc.decoder.power_decoder2 import PowerDecode2
+from soc.decoder.power_decoder2 import PowerDecodeSubset
from soc.decoder.power_regspec_map import regspec_decode_read
from soc.decoder.power_regspec_map import regspec_decode_write
from soc.fu.compunits.compunits import AllFunctionUnits
from soc.regfile.regfiles import RegFiles
from soc.decoder.decode2execute1 import Decode2ToExecute1Type
+from soc.decoder.decode2execute1 import IssuerDecode2ToOperand
from soc.decoder.power_decoder2 import get_rdflags
from soc.decoder.decode2execute1 import Data
from soc.experiment.l0_cache import TstL0CacheBuffer # test only
class NonProductionCore(Elaboratable):
def __init__(self, pspec):
+ self.pspec = pspec
# single LD/ST funnel for memory access
self.l0 = TstL0CacheBuffer(pspec, n_units=1)
pi = self.l0.l0.dports[0]
+ if False:
+ # MMU / DCache
+ self.mmu = MMU()
+ self.dcache = DCache()
+
# function units (only one each)
self.fus = AllFunctionUnits(pspec, pilist=[pi])
# register files (yes plural)
self.regs = RegFiles()
- # instruction decoder
- self.e = Decode2ToExecute1Type() # decoded instruction
+ # instruction decoder - needs a Trap-capable Record (captures EINT etc.)
+ self.e = Decode2ToExecute1Type("core", opkls=IssuerDecode2ToOperand)
+
self.state = CoreState("core")
self.raw_insn_i = Signal(32) # raw instruction
self.bigendian_i = Signal() # bigendian
# start/stop and terminated signalling
self.core_stopped_i = Signal(reset_less=True)
- self.core_reset_i = Signal()
self.core_terminate_o = Signal(reset=0) # indicates stopped
# create per-FU instruction decoders (subsetted)
self.decoders = {}
+ self.des = {}
for funame, fu in self.fus.fus.items():
f_name = fu.fnunit.name
fnunit = fu.fnunit.value
opkls = fu.opsubsetkls
- self.decoders[funame] = PowerDecode2(None, opkls, f_name)
+ if f_name == 'TRAP':
+ self.trapunit = funame
+ continue
+ self.decoders[funame] = PowerDecodeSubset(None, opkls, f_name,
+ final=True,
+ state=self.state)
+ self.des[funame] = self.decoders[funame].do
def elaborate(self, platform):
m = Module()
+ # for testing purposes, to cut down on build time in coriolis2
+ if hasattr(self.pspec, "nocore") and self.pspec.nocore == True:
+ return m
comb = m.d.comb
m.submodules.fus = self.fus
regs = self.regs
fus = self.fus.fus
- # connect up Function Units, then read/write ports
- fu_bitdict = self.connect_instruction(m)
- self.connect_rdports(m, fu_bitdict)
- self.connect_wrports(m, fu_bitdict)
-
- # connect up reset
- m.d.comb += ResetSignal().eq(self.core_reset_i)
-
# connect decoders
for k, v in self.decoders.items():
setattr(m.submodules, "dec_%s" % v.fn_name, v)
comb += v.dec.raw_opcode_in.eq(self.raw_insn_i)
comb += v.dec.bigendian.eq(self.bigendian_i)
- comb += v.state.eq(self.state)
+
+ # ssh, cheat: trap uses the main decoder because of the rewriting
+ self.des[self.trapunit] = self.e.do
+
+ # connect up Function Units, then read/write ports
+ fu_bitdict = self.connect_instruction(m)
+ self.connect_rdports(m, fu_bitdict)
+ self.connect_wrports(m, fu_bitdict)
return m
with m.Default():
# connect up instructions. only one enabled at a time
for funame, fu in fus.items():
- e = self.decoders[funame].e
+ do = self.des[funame]
enable = fu_bitdict[funame]
# run this FunctionUnit if enabled
# route op, issue, busy, read flags and mask to FU
with m.If(enable):
# operand comes from the *local* decoder
- comb += fu.oper_i.eq_from(e.do)
+ comb += fu.oper_i.eq_from(do)
#comb += fu.oper_i.eq_from_execute1(e)
comb += fu.issue_i.eq(self.issue_i)
comb += self.busy_o.eq(fu.busy_o)