"""PowerDecoder - decodes an incoming opcode into the type of operation
"""
- def __init__(self, width, opcodes, opint=True, suffix=None):
+ def __init__(self, width, opcodes, *,
+ bitsel, subdecoders=[],
+ opint=True,
+ suffix=None):
self.opint = opint # true if the opcode needs to be converted to int
self.opcodes = opcodes
self.opcode_in = Signal(width, reset_less=True)
self.suffix = suffix
if suffix is not None and suffix[1] - suffix[0] >= width:
self.suffix = None
+ self.bitsel = bitsel
+ self.subdecoders = subdecoders
self.width = width
def suffix_mask(self):
m = Module()
comb = m.d.comb
- if self.suffix:
- opcodes = self.divide_opcodes()
- opc_in = Signal(self.suffix[1] - self.suffix[0], reset_less=True)
- comb += opc_in.eq(self.opcode_in[self.suffix[0]:self.suffix[1]])
- with m.Switch(opc_in):
- for key, row in opcodes.items():
- subdecoder = PowerDecoder(width=self.width - opc_in.width,
- opcodes=row,
- opint=False,
- suffix=self.suffix)
- setattr(m.submodules, "dec%d" % key, subdecoder)
- comb += subdecoder.opcode_in.eq(self.opcode_in[self.suffix[1]:])
- with m.Case(key):
- comb += self.op.eq(subdecoder.op)
-
- else:
- with m.Switch(self.opcode_in):
- for row in self.opcodes:
- opcode = row['opcode']
- if self.opint and '-' not in opcode:
- opcode = int(opcode, 0)
- if not row['unit']:
- continue
- with m.Case(opcode):
- comb += self.op._eq(row)
- with m.Default():
- comb += self.op._eq(None)
+ # if self.suffix:
+ # opcodes = self.divide_opcodes()
+ # opc_in = Signal(self.suffix[1] - self.suffix[0], reset_less=True)
+ # comb += opc_in.eq(self.opcode_in[self.suffix[0]:self.suffix[1]])
+ # with m.Switch(opc_in):
+ # for key, row in opcodes.items():
+ # subdecoder = PowerDecoder(width=self.width - opc_in.width,
+ # opcodes=row,
+ # opint=False,
+ # suffix=self.suffix)
+ # setattr(m.submodules, "dec%d" % key, subdecoder)
+ # comb += subdecoder.opcode_in.eq(self.opcode_in[self.suffix[1]:])
+ # with m.Case(key):
+ # comb += self.op.eq(subdecoder.op)
+
+ # else:
+ opcode = Signal(self.bitsel[1] - self.bitsel[0], reset_less=True)
+ comb += opcode.eq(self.opcode_in[self.bitsel[0]:self.bitsel[1]])
+ with m.Switch(opcode):
+ for row in self.opcodes:
+ opcode = row['opcode']
+ if self.opint and '-' not in opcode:
+ opcode = int(opcode, 0)
+ if not row['unit']:
+ continue
+ with m.Case(opcode):
+ comb += self.op._eq(row)
+ with m.Default():
+ comb += self.op._eq(None)
return m
+
def ports(self):
return [self.opcode_in] + self.op.ports()
class DecoderTestCase(FHDLTestCase):
- def run_tst(self, width, csvname, suffix=None, opint=True):
+ def run_tst(self, bitsel, csvname, suffix=None, opint=True):
m = Module()
comb = m.d.comb
- opcode = Signal(width)
+ opcode = Signal(32)
function_unit = Signal(Function)
internal_op = Signal(InternalOp)
in1_sel = Signal(In1Sel)
cry_in = Signal(CryIn)
opcodes = get_csv(csvname)
- m.submodules.dut = dut = PowerDecoder(width, opcodes, opint, suffix=suffix)
+ m.submodules.dut = dut = PowerDecoder(32, opcodes, bitsel=bitsel,
+ opint=opint, suffix=suffix)
comb += [dut.opcode_in.eq(opcode),
function_unit.eq(dut.op.function_unit),
in1_sel.eq(dut.op.in1_sel),
if not opint: # HACK: convert 001---10 to 0b00100010
op = "0b" + op.replace('-', '0')
print ("opint", opint, row['opcode'], op)
- yield opcode.eq(int(op, 0))
+ yield opcode.eq(0)
+ yield opcode[bitsel[0]:bitsel[1]].eq(int(op, 0))
yield Delay(1e-6)
signals = [(function_unit, Function, 'unit'),
(internal_op, InternalOp, 'internal op'),
msg = f"{sig.name} == {result}, expected: {expected}"
self.assertEqual(expected, result, msg)
sim.add_process(process)
- with sim.write_vcd("test.vcd", "test.gtkw", traces=[
+ prefix = os.path.splitext(csvname)[0]
+ with sim.write_vcd("%s.vcd" % prefix, "%s.gtkw" % prefix, traces=[
opcode, function_unit, internal_op,
in1_sel, in2_sel]):
sim.run()
- def generate_ilang(self, width, csvname, opint=True, suffix=None):
+ def generate_ilang(self, bitsel, csvname, opint=True, suffix=None):
prefix = os.path.splitext(csvname)[0]
if suffix:
prefix += ".%s" % str(suffix).replace(" ", "")[1:-1]
- dut = PowerDecoder(width, get_csv(csvname), opint, suffix=suffix)
+ dut = PowerDecoder(32, get_csv(csvname), bitsel=bitsel,
+ opint=opint, suffix=suffix)
vl = rtlil.convert(dut, ports=dut.ports())
with open("%s_decoder.il" % prefix, "w") as f:
f.write(vl)
def test_major(self):
- self.run_tst(6, "major.csv")
- self.generate_ilang(6, "major.csv")
+ self.run_tst((26, 32), "major.csv")
+ self.generate_ilang((26, 32), "major.csv")
- def test_minor_19(self):
- self.run_tst(10, "minor_19.csv", suffix=(0, 5))
- self.generate_ilang(10, "minor_19.csv", suffix=(0, 5))
+ # def test_minor_19(self):
+ # self.run_tst(10, "minor_19.csv", suffix=(0, 5))
+ # self.generate_ilang(10, "minor_19.csv", suffix=(0, 5))
- def test_minor_19_00000(self):
- self.run_tst(10, "minor_19_00000.csv")
- self.generate_ilang(10, "minor_19_00000.csv")
+ # def test_minor_19_00000(self):
+ # self.run_tst(10, "minor_19_00000.csv")
+ # self.generate_ilang(10, "minor_19_00000.csv")
- def test_minor_30(self):
- self.run_tst(4, "minor_30.csv")
- self.generate_ilang(4, "minor_30.csv")
+ # def test_minor_30(self):
+ # self.run_tst(4, "minor_30.csv")
+ # self.generate_ilang(4, "minor_30.csv")
- def test_minor_31(self):
- self.run_tst(10, "minor_31.csv", suffix=(0, 5))
- self.generate_ilang(10, "minor_31.csv", suffix=(0, 5))
+ # def test_minor_31(self):
+ # self.run_tst(10, "minor_31.csv", suffix=(0, 5))
+ # self.generate_ilang(10, "minor_31.csv", suffix=(0, 5))
- #def test_minor_31_prefix(self):
- # self.run_tst(10, "minor_31.csv", suffix=(5, 10))
- # self.generate_ilang(10, "minor_31.csv", suffix=(5, 10))
+ # #def test_minor_31_prefix(self):
+ # # self.run_tst(10, "minor_31.csv", suffix=(5, 10))
+ # # self.generate_ilang(10, "minor_31.csv", suffix=(5, 10))
- def test_extra(self):
- self.run_tst(32, "extra.csv", opint=False)
- self.generate_ilang(32, "extra.csv", opint=False)
+ # def test_extra(self):
+ # self.run_tst(32, "extra.csv", opint=False)
+ # self.generate_ilang(32, "extra.csv", opint=False)
if __name__ == "__main__":