"""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,
),
]
+
"""
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)
# 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:
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)
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:
# 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']]),
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]))
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))
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)
# 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 = [
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)