From: Luke Kenneth Casson Leighton Date: Thu, 24 Jun 2021 18:19:26 +0000 (+0100) Subject: add PowerDecoder condition switches (untested, doesnt break anything) X-Git-Tag: xlen-bcd~387 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=30adb1eb86638bf606e74ea04ef8c726f9692769;p=openpower-isa.git add PowerDecoder condition switches (untested, doesnt break anything) --- diff --git a/src/openpower/decoder/power_decoder.py b/src/openpower/decoder/power_decoder.py index 8d7fcfa9..517748de 100644 --- a/src/openpower/decoder/power_decoder.py +++ b/src/openpower/decoder/power_decoder.py @@ -319,9 +319,13 @@ class PowerDecoder(Elaboratable): the constructor is called. all quite messy. """ - def __init__(self, width, dec, name=None, col_subset=None, row_subset=None): + def __init__(self, width, dec, name=None, col_subset=None, + row_subset=None, conditions=None): + if conditions is None: + conditions = {} self.actually_does_something = False self.pname = name + self.conditions = conditions self.col_subset = col_subset self.row_subsetfn = row_subset if not isinstance(dec, list): @@ -335,6 +339,22 @@ class PowerDecoder(Elaboratable): d.suffix = None self.width = width + # create some case statement condition patterns for matching + # a single condition. "1----" for the first condition, + # "-1----" for the 2nd etc. + # also create a matching ordered list of conditions, for the switch, + # which will Cat() them together + self.ccases = {} + self.ckeys = list(conditions.keys()) + self.ckeys.sort() + cswitch = [] + for i, ckey in enumerate(self.ckeys): + case = '-' * len(self.ckeys) + case[i] = '1' + self.ccases[ckey] = case + cswitch.append(conditions[ckey]) + self.cswitch = cswitch + def suffix_mask(self, d): return ((1 << d.suffix) - 1) @@ -475,9 +495,25 @@ class PowerDecoder(Elaboratable): with m.Switch(switch): for key, eqs in cases.items(): with m.Case(key): - comb += eqs + # "conditions" are a further switch statement + if isinstance(eqs, dict): + self.condition_switch(m, eqs) + else: + comb += eqs return m + def condition_switch(self, m, cases): + """against the global list of "conditions", having matched against + bits of the opcode, we FINALLY now have to match against some + additional "conditions". this is because there can be **MULTIPLE** + entries for a given opcode match. here we discern them. + """ + comb = m.d.comb + with m.Switch(Cat(*self.ccswitch)): + for ckey, eqs in cases.items(): + with m.Case(self.ccases[key]): + comb += eqs + def ports(self): return [self.opcode_in] + self.op.ports() @@ -490,8 +526,10 @@ class TopPowerDecoder(PowerDecoder): (reverses byte order). See V3.0B p44 1.11.2 """ - def __init__(self, width, dec, name=None, col_subset=None, row_subset=None): - PowerDecoder.__init__(self, width, dec, name, col_subset, row_subset) + def __init__(self, width, dec, name=None, col_subset=None, + row_subset=None, conditions=None): + PowerDecoder.__init__(self, width, dec, name, + col_subset, row_subset, conditions) self.fields = df = DecodeFields(SignalBitRange, [self.opcode_in]) self.fields.create_specs() self.raw_opcode_in = Signal.like(self.opcode_in, reset_less=True)