update copyright notices to include additional primary author
[soc.git] / src / soc / decoder / power_decoder.py
index 09cdd41241295d70c41aaab3bc0e8c664d4a950d..e4b87db1ca7debad7764c8318f222facd01f9914 100644 (file)
@@ -1,5 +1,10 @@
 """Cascading Power ISA Decoder
 
+License: LGPLv3
+
+# Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+
 This module uses CSV tables in a hierarchical/peer cascading fashion,
 to create a multi-level instruction decoder by recognising appropriate
 patterns.  The output is a wide, flattened (1-level) series of bitfields,
@@ -77,14 +82,15 @@ Top Level:
       ),
     ]
 
+
 """
 
 from collections import namedtuple
 from nmigen import Module, Elaboratable, Signal, Cat, Mux
 from nmigen.cli import rtlil
-from soc.decoder.power_enums import (Function, Form, InternalOp,
+from soc.decoder.power_enums import (Function, Form, MicrOp,
                                      In1Sel, In2Sel, In3Sel, OutSel,
-                                     RC, LdstLen, CryIn, get_csv,
+                                     RC, LdstLen, LDSTMode, CryIn, get_csv,
                                      single_bit_flags, CRInSel,
                                      CROutSel, get_signal_name,
                                      default_values, insns, asmidx)
@@ -95,14 +101,15 @@ from soc.decoder.power_fieldsn import SigDecode, SignalBitRange
 # key data structure in which the POWER decoder is specified,
 # in a hierarchical fashion
 Subdecoder = namedtuple("Subdecoder",
-        ["pattern",    # the major pattern to search for (e.g. major opcode)
-         "opcodes",    # a dictionary of minor patterns to find
-         "opint",      # true => the pattern must not be in "10----11" format
-         "bitsel",     # the bits (as a range) against which "pattern" matches
-         "suffix",     # shift the opcode down before decoding
-         "subdecoders" # list of further subdecoders for *additional* matches,
-                       # *ONLY* after "pattern" has *ALSO* been matched against.
-        ])
+                        ["pattern",    # the major pattern to search for (e.g. major opcode)
+                         "opcodes",    # a dictionary of minor patterns to find
+                         "opint",      # true => the pattern must not be in "10----11" format
+                         # the bits (as a range) against which "pattern" matches
+                         "bitsel",
+                         "suffix",     # shift the opcode down before decoding
+                         "subdecoders"  # list of further subdecoders for *additional* matches,
+                         # *ONLY* after "pattern" has *ALSO* been matched against.
+                         ])
 
 
 class PowerOp:
@@ -117,9 +124,9 @@ class PowerOp:
 
     def __init__(self, incl_asm=True):
         self.function_unit = Signal(Function, reset_less=True)
-        self.internal_op = Signal(InternalOp, reset_less=True)
+        self.internal_op = Signal(MicrOp, reset_less=True)
         self.form = Signal(Form, reset_less=True)
-        if incl_asm: # for simulator only
+        if incl_asm:  # for simulator only
             self.asmcode = Signal(8, reset_less=True)
         self.in1_sel = Signal(In1Sel, reset_less=True)
         self.in2_sel = Signal(In2Sel, reset_less=True)
@@ -128,6 +135,7 @@ class PowerOp:
         self.cr_in = Signal(CRInSel, reset_less=True)
         self.cr_out = Signal(CROutSel, reset_less=True)
         self.ldst_len = Signal(LdstLen, reset_less=True)
+        self.upd = Signal(LDSTMode, reset_less=True)
         self.rc_sel = Signal(RC, reset_less=True)
         self.cry_in = Signal(CryIn, reset_less=True)
         for bit in single_bit_flags:
@@ -140,17 +148,24 @@ class PowerOp:
         # TODO: this conversion process from a dict to an object
         # should really be done using e.g. namedtuple and then
         # call eq not _eq
-        if False: # debugging
+        if False:  # debugging
             if row['CR in'] == '1':
-                import pdb; pdb.set_trace()
+                import pdb
+                pdb.set_trace()
                 print(row)
             if row['CR out'] == '0':
-                import pdb; pdb.set_trace()
+                import pdb
+                pdb.set_trace()
                 print(row)
             print(row)
+        ldst_mode = row['upd']
+        if ldst_mode.isdigit():
+            ldst_mode = LDSTMode(int(ldst_mode))
+        else:
+            ldst_mode = LDSTMode[ldst_mode]
         res = [self.function_unit.eq(Function[row['unit']]),
                self.form.eq(Form[row['form']]),
-               self.internal_op.eq(InternalOp[row['internal op']]),
+               self.internal_op.eq(MicrOp[row['internal op']]),
                self.in1_sel.eq(In1Sel[row['in1']]),
                self.in2_sel.eq(In2Sel[row['in2']]),
                self.in3_sel.eq(In3Sel[row['in3']]),
@@ -158,11 +173,12 @@ class PowerOp:
                self.cr_in.eq(CRInSel[row['CR in']]),
                self.cr_out.eq(CROutSel[row['CR out']]),
                self.ldst_len.eq(LdstLen[row['ldst len']]),
+               self.upd.eq(ldst_mode),
                self.rc_sel.eq(RC[row['rc']]),
                self.cry_in.eq(CryIn[row['cry in']]),
                ]
         if False:
-            print (row.keys())
+            print(row.keys())
         asmcode = row['comment']
         if hasattr(self, "asmcode") and asmcode in asmidx:
             res.append(self.asmcode.eq(asmidx[asmcode]))
@@ -183,6 +199,7 @@ class PowerOp:
                self.cr_out.eq(otherop.cr_out),
                self.rc_sel.eq(otherop.rc_sel),
                self.ldst_len.eq(otherop.ldst_len),
+               self.upd.eq(otherop.upd),
                self.cry_in.eq(otherop.cry_in)]
         for bit in single_bit_flags:
             sig = getattr(self, get_signal_name(bit))
@@ -294,7 +311,7 @@ class PowerDecoder(Elaboratable):
     def handle_subdecoders(self, m, d):
         for dec in d.subdecoders:
             subdecoder = PowerDecoder(self.width, dec)
-            if isinstance(dec, list): # XXX HACK: take first pattern
+            if isinstance(dec, list):  # XXX HACK: take first pattern
                 dec = dec[0]
             setattr(m.submodules, "dec%d" % dec.pattern, subdecoder)
             m.d.comb += subdecoder.opcode_in.eq(self.opcode_in)
@@ -382,9 +399,9 @@ def create_pdecode():
     # minor 19 has extra patterns
     m19 = []
     m19.append(Subdecoder(pattern=19, opcodes=get_csv("minor_19.csv"),
-                   opint=True, bitsel=(1, 11), suffix=None, subdecoders=[]))
+                          opint=True, bitsel=(1, 11), suffix=None, subdecoders=[]))
     m19.append(Subdecoder(pattern=19, opcodes=get_csv("minor_19_00000.csv"),
-                   opint=True, bitsel=(1, 6), suffix=None, subdecoders=[]))
+                          opint=True, bitsel=(1, 6), suffix=None, subdecoders=[]))
 
     # minor opcodes.
     pminor = [
@@ -403,10 +420,10 @@ def create_pdecode():
     dec = []
     opcodes = get_csv("major.csv")
     dec.append(Subdecoder(pattern=None, opint=True, opcodes=opcodes,
-                     bitsel=(26, 32), suffix=None, subdecoders=pminor))
+                          bitsel=(26, 32), suffix=None, subdecoders=pminor))
     opcodes = get_csv("extra.csv")
     dec.append(Subdecoder(pattern=None, opint=False, opcodes=opcodes,
-                     bitsel=(0, 32), suffix=None, subdecoders=[]))
+                          bitsel=(0, 32), suffix=None, subdecoders=[]))
 
     return TopPowerDecoder(32, dec)