X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fconsts.py;h=f7e55f1a11fe3ec9596b77abaaea2217ef7533a4;hb=cfaec535709d7fe09d861dd0c99d40cd9b52c1d2;hp=c06e6bc76d00ee1721ba269644d57865773592f6;hpb=8fef04dc4954c146277e1534c89d013d7a4174d7;p=soc.git diff --git a/src/soc/consts.py b/src/soc/consts.py index c06e6bc7..f7e55f1a 100644 --- a/src/soc/consts.py +++ b/src/soc/consts.py @@ -5,6 +5,78 @@ def botchify(bekls, lekls): continue setattr(lekls, attr, 63-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(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 msb0_start >= msb0_end: + raise ValueError( + "start ({}) must be less than end ({})".format(msb0_start, msb0_end) + ) + # 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, 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 msb0_end is None: + return r[(field_width - 1) - msb0_start] + else: + return r[field_slice(msb0_start, msb0_end)] + + # Listed in V3.0B Book III Chap 4.2.1 # MSR bit numbers, *bigendian* order (PowerISA format) # use this in the simulator @@ -47,7 +119,7 @@ botchify(MSRb, MSR) # use this in the simulator class PIb: - TM_BAD_THING = 42 # 1 for a TM Bad Thing type interrupt + 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 = 45 # 1 if privileged interrupt @@ -69,6 +141,8 @@ class TT: 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 + ILLEG = 1<<6 # currently the max, therefore traptype must be 5 bits # 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 = 7 # MUST update this to contain the full number of Trap Types