# sigh create little-ended versions of bitfield flags
-def botchify(bekls, lekls):
+from nmigen import Cat
+
+
+def botchify(bekls, lekls, msb=63):
for attr in dir(bekls):
if attr[0] == '_':
continue
- setattr(lekls, attr, 63-getattr(bekls, attr))
+ setattr(lekls, attr, msb-getattr(bekls, attr))
# Can't think of a better place to put these functions.
# Return an arbitrary subfield of a larger field.
-def field_slice(start, end):
- """Answers with a subfield slice of the signal r ("register"),
- where the start and end bits use IBM conventions. start < end.
- The range specified is inclusive on both ends.
+def field_slice(msb0_start, msb0_end, field_width=64):
+ """field_slice
+
+ Answers with a subfield slice of the signal r ("register"),
+ where the start and end bits use IBM "MSB 0" conventions.
+
+ see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
+
+ * assertion: msb0_start < msb0_end.
+ * The range specified is inclusive on both ends.
+ * field_width specifies the total number of bits (note: not bits-1)
"""
- if start >= end:
+ if msb0_start >= msb0_end:
raise ValueError(
- "start ({}) must be less than end ({})".format(start, end)
+ "start ({}) must be less than end ({})".format(msb0_start, msb0_end)
)
- start = 63 - start
- end = 63 - end
- return slice(end, start + 1)
+ # sigh. MSB0 (IBM numbering) is inverted. converting to python
+ # we *swap names* so as not to get confused by having "end, start"
+ lsb0_end = (field_width-1) - msb0_start
+ lsb0_start = (field_width-1) - msb0_end
+
+ return slice(lsb0_start, lsb0_end + 1)
-def field(r, start, end=None):
+def field(r, msb0_start, msb0_end=None, field_width=64):
"""Answers with a subfield of the signal r ("register"), where
the start and end bits use IBM conventions. start < end, if
end is provided. The range specified is inclusive on both ends.
+
+ Answers with a subfield of the signal r ("register"),
+ where the start and end bits use IBM "MSB 0" conventions.
+ If end is not provided, a single bit subfield is returned.
+
+ see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
+
+ * assertion: msb0_start < msb0_end.
+ * The range specified is inclusive on both ends.
+ * field_width specifies the total number of bits (note: not bits-1)
+
+ Example usage:
+
+ comb += field(insn, 0, 6, field_width=32).eq(17)
+ # NOTE: NEVER DIRECTLY ACCESS OPCODE FIELDS IN INSTRUCTIONS.
+ # This example is purely for illustrative purposes only.
+ # Use self.fields.FormXYZ.etcetc instead.
+
+ comb += field(msr, MSRb.TEs, MSRb.TEe).eq(0)
+
+ Proof by substitution:
+
+ field(insn, 0, 6, field_width=32).eq(17)
+ == insn[field_slice(0, 6, field_width=32)].eq(17)
+ == insn[slice((31-6), (31-0)+1)].eq(17)
+ == insn[slice(25, 32)].eq(17)
+ == insn[25:32].eq(17)
+
+ field(msr, MSRb.TEs, MSRb.TEe).eq(0)
+ == field(msr, 53, 54).eq(0)
+ == msr[field_slice(53, 54)].eq(0)
+ == msr[slice((63-54), (63-53)+1)].eq(0) # note cross-over!
+ == msr[slice(9, 11)].eq(0)
+ == msr[9:11].eq(0)
"""
- if end is None:
- return r[63 - start]
+ if msb0_end is None:
+ return r[(field_width - 1) - msb0_start]
else:
- return r[field_slice(start, end)]
+ return r[field_slice(msb0_start, msb0_end, field_width)]
# Listed in V3.0B Book III Chap 4.2.1
# use this in the simulator
class PIb:
+ INVALID = 33 # 1 for an invalid mem err
+ PERMERR = 35 # 1 for an permanent mem err
TM_BAD_THING = 42 # 1 for a TM Bad Thing type interrupt
FP = 43 # 1 if FP exception
ILLEG = 44 # 1 if illegal instruction (not doing hypervisor)
PRIV = 1<<1
TRAP = 1<<2
ADDR = 1<<3
- ILLEG = 1<<4 # currently the max, therefore traptype must be 5 bits
+ EINT = 1<<4 # external interrupt
+ DEC = 1<<5 # decrement counter
+ MEMEXC = 1<<6 # LD/ST exception
+ ILLEG = 1<<7 # currently the max
# TODO: support for TM_BAD_THING (not included yet in trap main_stage.py)
- size = 5 # MUST update this to contain the full number of Trap Types
+ size = 8 # MUST update this to contain the full number of Trap Types
+
+
+# EXTRA3 3-bit subfield (spec)
+class SPECb:
+ VEC = 0 # 1 for vector, 0 for scalar
+ MSB = 1 # augmented register number, MSB
+ LSB = 2 # augmented register number, LSB
+
+
+SPEC_SIZE = 3
+SPEC_AUG_SIZE = 2 # augmented subfield size (MSB+LSB above)
+class SPEC:
+ pass
+botchify(SPECb, SPEC, SPEC_SIZE-1)
+
+
+# EXTRA field, with EXTRA2 subfield encoding
+class EXTRA2b:
+ IDX0_VEC = 0
+ IDX0_MSB = 1
+ IDX1_VEC = 2
+ IDX1_MSB = 3
+ IDX2_VEC = 4
+ IDX2_MSB = 5
+ IDX3_VEC = 6
+ IDX3_MSB = 7
+ RESERVED = 8
+
+
+EXTRA2_SIZE = 9
+class EXTRA2:
+ pass
+botchify(EXTRA2b, EXTRA2, EXTRA2_SIZE-1)
+
+
+# EXTRA field, with EXTRA3 subfield encoding
+class EXTRA3:
+ IDX0 = [0, 1, 2]
+ IDX1 = [3, 4, 5]
+ IDX2 = [6, 7, 8]
+ MASK = [6, 7, 8]
+
+
+EXTRA3_SIZE = 9
+
+
+# SVP64 ReMapped Field (from v3.1 EXT001 Prefix)
+class SVP64P:
+ OPC = range(0, 6)
+ SVP64_7_9 = [7, 9]
+ RM = [6, 8] + list(range(10, 32))
+
+# 24 bits in RM
+SVP64P_SIZE = 24
+
+
+# CR SVP64 offsets
+class SVP64CROffs:
+ CR0 = 0 # TODO: increase when CRs are expanded to 128
+ CR1 = 1 # TODO: increase when CRs are expanded to 128
+ CRPred = 4 # TODO: increase when CRs are expanded to 128
+
+
+class SVP64MODEb:
+ # mode bits
+ MOD2_MSB = 0
+ MOD2_LSB = 1
+ # when predicate not set: 0=ignore/skip 1=zero
+ DZ = 3 # for destination
+ SZ = 4 # for source
+ # reduce mode
+ REDUCE = 2 # 0=normal predication 1=reduce mode
+ SVM = 3 # subvector reduce mode 0=independent 1=horizontal
+ CRM = 4 # CR mode on reduce (Rc=1) 0=some 1=all
+ # saturation mode
+ N = 2 # saturation signed mode 0=signed 1=unsigned
+ # ffirst and predicate result modes
+ INV = 2 # invert CR sense 0=set 1=unset
+ CR_MSB = 3 # CR bit to update (with Rc=1)
+ CR_LSB = 4
+ RC1 = 4 # update CR as if Rc=1 (when Rc=0)
+ # LD immediate els (element-stride) locations, depending on mode
+ ELS_NORMAL = 2
+ ELS_FFIRST_PRED = 3
+ ELS_SAT = 4
+ # BO bits
+ BO_MSB = 2
+ BO_LSB = 4
+
+
+SVP64MODE_SIZE = 5
+
+
+class SVP64MODE:
+ pass
+
+
+botchify(SVP64MODEb, SVP64MODE, SVP64MODE_SIZE-1)
+
+# add subfields to use with nmutil.sel
+SVP64MODE.MOD2 = [0, 1]
+SVP64MODE.CR = [3, 4]
+
+
+# CR sub-fields
+class CRb:
+ LT = 0
+ GT = 1
+ EQ = 2
+ SO = 3
+
+
+CR_SIZE = 4
+
+
+class CR:
+ pass
+
+
+botchify(CRb, CR, CR_SIZE-1)