"""
from nmigen import Signal, Record
from nmutil.iocontrol import RecordObject
-from soc.decoder.power_enums import MicrOp, CryIn, Function, SPR, LDSTMode
+from soc.decoder.power_enums import (MicrOp, CryIn, Function,
+ SPRfull, SPRreduced, LDSTMode)
from soc.consts import TT
from soc.experiment.mem_types import LDSTException
class Decode2ToExecute1Type(RecordObject):
- def __init__(self, name=None, asmcode=True, opkls=None, do=None):
+ def __init__(self, name=None, asmcode=True, opkls=None, do=None,
+ regreduce_en=False):
+
+ if regreduce_en:
+ SPR = SPRreduced
+ else:
+ SPR = SPRfull
if do is None and opkls is None:
opkls = Decode2ToOperand
from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
selectconcat)
-from soc.decoder.power_enums import SPR as DEC_SPR
-
from soc.decoder.helpers import exts, gtu, ltu, undefined
import math
import sys
from soc.decoder.power_enums import (MicrOp, CryIn, Function,
CRInSel, CROutSel,
LdstLen, In1Sel, In2Sel, In3Sel,
- OutSel, SPR, RC, LDSTMode,
+ OutSel, SPRfull, SPRreduced,
+ RC, LDSTMode,
SVEXTRA, SVEtype, SVPtype)
from soc.decoder.decode2execute1 import (Decode2ToExecute1Type, Data,
Decode2ToOperand)
"""SPRMap: maps POWER9 SPR numbers to internal enum values, fast and slow
"""
- def __init__(self):
+ def __init__(self, regreduce_en):
+ self.regreduce_en = regreduce_en
+ if regreduce_en:
+ SPR = SPRreduced
+ else:
+ SPR = SPRfull
+
self.spr_i = Signal(10, reset_less=True)
self.spr_o = Data(SPR, name="spr_o")
self.fast_o = Data(3, name="fast_o")
def elaborate(self, platform):
m = Module()
+ if self.regreduce_en:
+ SPR = SPRreduced
+ else:
+ SPR = SPRfull
with m.Switch(self.spr_i):
for i, x in enumerate(SPR):
with m.Case(x.value):
decodes register RA, implicit and explicit CSRs
"""
- def __init__(self, dec):
+ def __init__(self, dec, regreduce_en):
+ self.regreduce_en = regreduce_en
+ if self.regreduce_en:
+ SPR = SPRreduced
+ else:
+ SPR = SPRfull
self.dec = dec
self.sel_in = Signal(In1Sel, reset_less=True)
self.insn_in = Signal(32, reset_less=True)
comb = m.d.comb
op = self.dec.op
reg = self.reg_out
- m.submodules.sprmap = sprmap = SPRMap()
+ m.submodules.sprmap = sprmap = SPRMap(self.regreduce_en)
# select Register A field, if *full 7 bits* are zero (2 more from SVP64)
ra = Signal(5, reset_less=True)
decodes output register RA, RT or SPR
"""
- def __init__(self, dec):
+ def __init__(self, dec, regreduce_en):
+ self.regreduce_en = regreduce_en
+ if self.regreduce_en:
+ SPR = SPRreduced
+ else:
+ SPR = SPRfull
self.dec = dec
self.sel_in = Signal(OutSel, reset_less=True)
self.insn_in = Signal(32, reset_less=True)
def elaborate(self, platform):
m = Module()
comb = m.d.comb
- m.submodules.sprmap = sprmap = SPRMap()
+ m.submodules.sprmap = sprmap = SPRMap(self.regreduce_en)
op = self.dec.op
reg = self.reg_out
only fields actually requested are copied over. hence, "subset" (duh).
"""
def __init__(self, dec, opkls=None, fn_name=None, final=False, state=None,
- svp64_en=True):
+ svp64_en=True, regreduce_en=False):
self.svp64_en = svp64_en
+ self.regreduce_en = regreduce_en
if svp64_en:
self.sv_rm = SVP64Rec(name="dec_svp64") # SVP64 RM field
self.sv_a_nz = Signal(1)
# only needed for "main" PowerDecode2
if not self.final:
- self.e = Decode2ToExecute1Type(name=self.fn_name, do=self.do)
+ self.e = Decode2ToExecute1Type(name=self.fn_name, do=self.do,
+ regreduce_en=regreduce_en)
# create decoder if one not already given
if dec is None:
return getattr(self.dec.op, op_field, None)
def elaborate(self, platform):
+ if self.regreduce_en:
+ SPR = SPRreduced
+ else:
+ SPR = SPRfull
m = Module()
comb = m.d.comb
state = self.state
name = "tmp"
else:
name = self.fn_name + "tmp"
- self.e_tmp = Decode2ToExecute1Type(name=name, opkls=self.opkls)
+ self.e_tmp = Decode2ToExecute1Type(name=name, opkls=self.opkls,
+ regreduce_en=self.regreduce_en)
# set up submodule decoders
m.submodules.dec = self.dec
"""
def __init__(self, dec, opkls=None, fn_name=None, final=False,
- state=None, svp64_en=True):
- super().__init__(dec, opkls, fn_name, final, state, svp64_en)
+ state=None, svp64_en=True, regreduce_en=False):
+ super().__init__(dec, opkls, fn_name, final, state, svp64_en,
+ regreduce_en=False)
self.exc = LDSTException("dec2_exc")
if self.svp64_en:
# copy over if non-exception, non-privileged etc. is detected
# set up submodule decoders
- m.submodules.dec_a = dec_a = DecodeA(self.dec)
+ m.submodules.dec_a = dec_a = DecodeA(self.dec, self.regreduce_en)
m.submodules.dec_b = dec_b = DecodeB(self.dec)
m.submodules.dec_c = dec_c = DecodeC(self.dec)
- m.submodules.dec_o = dec_o = DecodeOut(self.dec)
+ m.submodules.dec_o = dec_o = DecodeOut(self.dec, self.regreduce_en)
m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec)
m.submodules.dec_cr_in = self.dec_cr_in = DecodeCRIn(self.dec)
m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec)
The designated SPR sandbox consists of non-privileged SPRs 704-719 and
privileged SPRs 720-735.
+
+Note: the option exists to select a much shorter list of SPRs, to reduce
+regfile size in HDL. this is SPRreduced and the supported list is in
+get_spr_enum
"""
from enum import Enum, unique
# http://libre-riscv.org/openpower/isatables/sprs.csv
# http://bugs.libre-riscv.org/show_bug.cgi?id=261
-spr_csv = get_csv("sprs.csv")
-spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
-spr_dict = {}
-spr_byname = {}
-for row in spr_csv:
- info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
- priv_mfspr=row['priv_mfspr'], length=int(row['len']),
- idx=int(row['Idx']))
- spr_dict[int(row['Idx'])] = info
- spr_byname[row['SPR']] = info
-fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
-SPR = Enum('SPR', fields)
-
+def get_spr_enum(full_file):
+ """get_spr_enum - creates an Enum of SPRs, dynamically
+ has the option to reduce the enum to a much shorter list.
+ this saves drastically on the size of the regfile
+ """
+ short_list = {'PIDR', 'DAR', 'PRTBL', 'DSIRS', 'SVSRR', 'SVSTATE',
+ 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
+ 'SPRG3'
+ }
+ spr_csv = []
+ for row in get_csv("sprs.csv"):
+ if full_file or row['SPR'] in short_list:
+ spr_csv.append(row)
+
+ spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
+ spr_dict = {}
+ spr_byname = {}
+ for row in spr_csv:
+ info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
+ priv_mfspr=row['priv_mfspr'], length=int(row['len']),
+ idx=int(row['Idx']))
+ spr_dict[int(row['Idx'])] = info
+ spr_byname[row['SPR']] = info
+ fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
+ SPR = Enum('SPR', fields)
+ return SPR, spr_dict, spr_byname
+
+SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
+SPRreduced, _, _ = get_spr_enum(full_file=False)
XER_bits = {
'SO': 32,
if __name__ == '__main__':
# find out what the heck is in SPR enum :)
- print("sprs", len(SPR))
- print(dir(SPR))
+ print("sprs full", len(SPRfull))
+ print(dir(SPRfull))
+ print("sprs reduced", len(SPRreduced))
+ print(dir(SPRreduced))
print(dir(Enum))
- print(SPR.__members__['TAR'])
- for x in SPR:
+ print(SPRfull.__members__['TAR'])
+ for x in SPRfull:
print(x, x.value, str(x), x.name)
print("function", Function.ALU.name)
from soc.decoder.power_fields import DecodeFields
from soc.decoder.power_fieldsn import SignalBitRange
from soc.decoder.power_decoder2 import decode_spr_num
-from soc.decoder.power_enums import MicrOp, SPR, XER_bits
+from soc.decoder.power_enums import MicrOp, XER_bits
from soc.experiment.pimem import PortInterface
from soc.experiment.pimem import PortInterfaceBase
from nmigen import (Module, Signal, Cat)
from nmutil.pipemodbase import PipeModBase
from soc.fu.spr.pipe_data import SPRInputData, SPROutputData
-from soc.decoder.power_enums import MicrOp, SPR, XER_bits
+from soc.decoder.power_enums import MicrOp, SPRfull, SPRreduced, XER_bits
from soc.decoder.power_fields import DecodeFields
from soc.decoder.power_fieldsn import SignalBitRange
class SPRMainStage(PipeModBase):
def __init__(self, pspec):
super().__init__(pspec, "spr_main")
+ # test if regfiles are reduced
+ self.regreduce_en = (hasattr(pspec, "regreduce") and
+ (pspec.regreduce == True))
+
self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
self.fields.create_specs()
return SPROutputData(self.pspec)
def elaborate(self, platform):
+ if self.regreduce_en:
+ SPR = SPRreduced
+ else:
+ SPR = SPRfull
m = Module()
comb = m.d.comb
op = self.i.ctx.op
from soc.regfile.regfile import RegFile, RegFileArray, RegFileMem
from soc.regfile.virtual_port import VirtualRegPort
-from soc.decoder.power_enums import SPR
+from soc.decoder.power_enums import SPRfull, SPRreduced
# "State" Regfile
* write-through capability (read on same cycle as write)
"""
def __init__(self, svp64_en=False, regreduce_en=False):
- n_sprs = len(SPR)
+ if regreduce_en:
+ n_sprs = len(SPRreduced)
+ else:
+ n_sprs = len(SPRfull)
super().__init__(width=64, depth=n_sprs)
self.w_ports = {'spr1': self.write_port("spr1")}
self.r_ports = {'spr1': self.read_port("spr1")}
from soc.regfile.regfiles import FastRegs
-from soc.decoder.power_enums import SPR, spr_dict
+from soc.decoder.power_enums import SPRfull as SPR, spr_dict
+# note that we can get away with using SPRfull here because the values
+# (numerical values) are what is used for lookup.
spr_to_fast = { SPR.CTR: FastRegs.CTR,
SPR.LR: FastRegs.LR,
SPR.TAR: FastRegs.TAR,
# test is SVP64 is to be enabled
self.svp64_en = hasattr(pspec, "svp64") and (pspec.svp64 == True)
+ # and if regfiles are reduced
+ self.regreduce_en = (hasattr(pspec, "regreduce") and
+ (pspec.regreduce == True))
+
# JTAG interface. add this right at the start because if it's
# added it *modifies* the pspec, by adding enable/disable signals
# for parts of the rest of the core
self.cur_state = CoreState("cur") # current state (MSR/PC/SVSTATE)
self.pdecode2 = PowerDecode2(pdecode, state=self.cur_state,
opkls=IssuerDecode2ToOperand,
- svp64_en=self.svp64_en)
+ svp64_en=self.svp64_en,
+ regreduce_en=self.regreduce_en)
if self.svp64_en:
self.svp64 = SVP64PrefixDecoder() # for decoding SVP64 prefix
from soc.decoder.power_decoder2 import PowerDecode2
from soc.decoder.selectable_int import SelectableInt
from soc.decoder.isa.all import ISA
-from soc.decoder.power_enums import SPR, spr_dict, Function, XER_bits
+
+# note that for testing using SPRfull should be ok here
+from soc.decoder.power_enums import SPRfull as SPR, spr_dict, Function, XER_bits
from soc.config.test.test_loadstore import TestMemPspec
from soc.config.endian import bigendian
dmi = issuer.dbg.dmi
pdecode2 = issuer.pdecode2
l0 = core.l0
+ regreduce_en = pspec.regreduce_en == True
# copy of the decoder for simulator
simdec = create_pdecode()
- simdec2 = PowerDecode2(simdec)
+ simdec2 = PowerDecode2(simdec, regreduce_en=regreduce_en)
m.submodules.simdec2 = simdec2 # pain in the neck
# run core clock at same rate as test clock
from soc.decoder.power_enums import (Function, MicrOp,
In1Sel, In2Sel, In3Sel,
OutSel, RC, LdstLen, CryIn,
- single_bit_flags, Form, SPR,
+ single_bit_flags, Form,
get_signal_name, get_csv)
from soc.decoder.power_decoder2 import (PowerDecode2)
from soc.simulator.program import Program