"""Cascading Power ISA Decoder
-License: LGPLv3
+License: LGPLv3+
# Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
from nmigen.cli import rtlil
from soc.decoder.power_enums import (Function, Form, MicrOp,
In1Sel, In2Sel, In3Sel, OutSel,
- RC, LdstLen, LDSTMode, CryIn, get_csv,
+ SVEXTRA, SVEtype, SVPtype, # Simple-V
+ RC, LdstLen, LDSTMode, CryIn,
single_bit_flags, CRInSel,
CROutSel, get_signal_name,
default_values, insns, asmidx)
from soc.decoder.power_fields import DecodeFields
from soc.decoder.power_fieldsn import SigDecode, SignalBitRange
-
+from soc.decoder.power_svp64 import SVP64RM
# key data structure in which the POWER decoder is specified,
# in a hierarchical fashion
-Subdecoder = namedtuple("Subdecoder",
+Subdecoder = namedtuple( # fix autoformatter
+ "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
'internal_op': MicrOp,
'form': Form,
'asmcode': 8,
+ 'SV_Etype': SVEtype,
+ 'SV_Ptype': SVPtype,
'in1_sel': In1Sel,
'in2_sel': In2Sel,
'in3_sel': In3Sel,
'out_sel': OutSel,
'cr_in': CRInSel,
'cr_out': CROutSel,
+ 'sv_in1': SVEXTRA,
+ 'sv_in2': SVEXTRA,
+ 'sv_in3': SVEXTRA,
+ 'sv_out': SVEXTRA,
+ 'sv_cr_in': SVEXTRA,
+ 'sv_cr_out': SVEXTRA,
'ldst_len': LdstLen,
'upd': LDSTMode,
'rc_sel': RC,
}
power_op_csvmap = {'function_unit': 'unit',
- 'form' : 'form',
- 'internal_op' : 'internal op',
- 'in1_sel' : 'in1',
- 'in2_sel' : 'in2',
- 'in3_sel' : 'in3',
- 'out_sel' : 'out',
- 'cr_in' : 'CR in',
- 'cr_out' : 'CR out',
- 'ldst_len' : 'ldst len',
- 'upd' : 'upd',
- 'rc_sel' : 'rc',
- 'cry_in' : 'cry in',
- }
+ 'form': 'form',
+ 'internal_op': 'internal op',
+ 'in1_sel': 'in1',
+ 'in2_sel': 'in2',
+ 'in3_sel': 'in3',
+ 'out_sel': 'out',
+ 'sv_in1': 'sv_in1',
+ 'sv_in2': 'sv_in2',
+ 'sv_in3': 'sv_in3',
+ 'sv_out': 'sv_out',
+ 'sv_cr_in': 'sv_cr_in',
+ 'sv_cr_out': 'sv_cr_out',
+ 'SV_Etype': 'SV_Etype',
+ 'SV_Ptype': 'SV_Ptype',
+ 'cr_in': 'CR in',
+ 'cr_out': 'CR out',
+ 'ldst_len': 'ldst len',
+ 'upd': 'upd',
+ 'rc_sel': 'rc',
+ 'cry_in': 'cry in',
+ }
def get_pname(field, pname):
about a PowerISA instruction. this is a "micro-code" expanded format
which generates an awful lot of wires, hence the subsetting
"""
+
def __init__(self, incl_asm=True, name=None, subset=None):
self.subset = subset
debug_report = set()
debug_report.add(field)
fname = get_pname(field, name)
setattr(self, field, Signal(reset_less=True, name=fname))
- print ("PowerOp debug", name, debug_report)
- print (" fields", fields)
+ print("PowerOp debug", name, debug_report)
+ print(" fields", fields)
def _eq(self, row=None):
if row is None:
if field not in power_op_csvmap:
continue
csvname = power_op_csvmap[field]
+ print (field, ptype, csvname, row)
val = row[csvname]
- if csvname == 'upd' and isinstance(val, int): # LDSTMode different
+ if csvname == 'upd' and isinstance(val, int): # LDSTMode different
val = ptype(val)
else:
val = ptype[val]
reset_less=True)
eq = []
case_does_something = False
- eq.append(opcode_switch.eq(self.opcode_in[d.bitsel[0]:d.bitsel[1]]))
+ eq.append(opcode_switch.eq(
+ self.opcode_in[d.bitsel[0]:d.bitsel[1]]))
if d.suffix:
opcodes = self.divide_opcodes(d)
opc_in = Signal(d.suffix, reset_less=True)
decs.append(cases)
if case_does_something:
eqs += eq
- print ("submodule eqs", self.pname, eq)
+ print("submodule eqs", self.pname, eq)
- print ("submodules", self.pname, submodules)
+ print("submodules", self.pname, submodules)
gc.collect()
return self.actually_does_something
for dec in d.subdecoders:
if isinstance(dec, list): # XXX HACK: take first pattern
dec = dec[0]
- print ("subdec", dec.pattern, self.pname)
+ print("subdec", dec.pattern, self.pname)
mname = get_pname("dec%d" % dec.pattern, self.pname)
subdecoder = PowerDecoder(self.width, dec,
- name=mname,
- col_subset=self.col_subset,
- row_subset=self.row_subsetfn)
- if not subdecoder.tree_analyse(): # doesn't do anything
+ name=mname,
+ col_subset=self.col_subset,
+ row_subset=self.row_subsetfn)
+ if not subdecoder.tree_analyse(): # doesn't do anything
del subdecoder
continue # skip
submodules[mname] = subdecoder
return eqs
def elaborate(self, platform):
- print ("decoder elaborate", self.pname, self.submodules)
+ print("decoder elaborate", self.pname, self.submodules)
m = Module()
comb = m.d.comb
setattr(self, fname, sig)
# create signals for all field forms
- self.form_names = forms = self.fields.instrs.keys()
+ forms = self.form_names
self.sigforms = {}
for form in forms:
fields = self.fields.instrs[form]
self.tree_analyse()
+ @property
+ def form_names(self):
+ return self.fields.instrs.keys()
+
def elaborate(self, platform):
m = PowerDecoder.elaborate(self, platform)
comb = m.d.comb
+ # sigh duplicated in SVP64PowerDecoder
# raw opcode in assumed to be in LE order: byte-reverse it to get BE
raw_le = self.raw_opcode_in
l = []
subsetting of the PowerOp decoding is possible by setting col_subset
"""
+ # some alteration to the CSV files is required for SV so we use
+ # a class to do it
+ isa = SVP64RM()
+ get_csv = isa.get_svp64_csv
+
# minor 19 has extra patterns
m19 = []
m19.append(Subdecoder(pattern=19, opcodes=get_csv("minor_19.csv"),
bitsel=(0, 32), suffix=None, subdecoders=[]))
return TopPowerDecoder(32, dec, name=name, col_subset=col_subset,
- row_subset=row_subset)
+ row_subset=row_subset)
if __name__ == '__main__':
# row subset
def rowsubsetfn(opcode, row):
- print ("row_subset", opcode, row)
+ print("row_subset", opcode, row)
return row['unit'] == 'ALU'
pdecode = create_pdecode(name="rowsub",
vl = rtlil.convert(pdecode, ports=pdecode.ports())
with open("decoder.il", "w") as f:
f.write(vl)
-