From: Michael Nolan Date: Sat, 29 Feb 2020 21:07:47 +0000 (-0500) Subject: Add decoder/test for minor_19 field X-Git-Tag: div_pipeline~1805 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8d287c2dfc6ab3e364c988f6ee2d5b65fb2ca82a;p=soc.git Add decoder/test for minor_19 field --- diff --git a/src/decoder/.gitignore b/src/decoder/.gitignore new file mode 100644 index 00000000..afed0735 --- /dev/null +++ b/src/decoder/.gitignore @@ -0,0 +1 @@ +*.csv diff --git a/src/decoder/power_decoder.py b/src/decoder/power_decoder.py new file mode 100644 index 00000000..275c85a7 --- /dev/null +++ b/src/decoder/power_decoder.py @@ -0,0 +1,60 @@ +from nmigen import Module, Elaboratable, Signal +from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel, + OutSel, RC, LdstLen, CryIn, get_csv, single_bit_flags, + get_signal_name) + + +class PowerDecoder(Elaboratable): + def __init__(self, width, csvname): + self.opcodes = get_csv(csvname) + self.opcode_in = Signal(width, reset_less=True) + + self.function_unit = Signal(Function, reset_less=True) + self.internal_op = Signal(InternalOp, reset_less=True) + self.in1_sel = Signal(In1Sel, reset_less=True) + self.in2_sel = Signal(In2Sel, reset_less=True) + self.in3_sel = Signal(In3Sel, reset_less=True) + self.out_sel = Signal(OutSel, reset_less=True) + self.ldst_len = Signal(LdstLen, 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: + name = get_signal_name(bit) + setattr(self, name, + Signal(reset_less=True, name=name)) + + def elaborate(self, platform): + m = Module() + comb = m.d.comb + + with m.Switch(self.opcode_in): + for row in self.opcodes: + opcode = int(row['opcode'], 0) + with m.Case(opcode): + comb += self.function_unit.eq(Function[row['unit']]) + comb += self.internal_op.eq(InternalOp[row['internal op']]) + comb += self.in1_sel.eq(In1Sel[row['in1']]) + comb += self.in2_sel.eq(In2Sel[row['in2']]) + comb += self.in3_sel.eq(In3Sel[row['in3']]) + comb += self.out_sel.eq(OutSel[row['out']]) + comb += self.ldst_len.eq(LdstLen[row['ldst len']]) + comb += self.rc_sel.eq(RC[row['rc']]) + comb += self.cry_in.eq(CryIn[row['cry in']]) + for bit in single_bit_flags: + sig = getattr(self, get_signal_name(bit)) + comb += sig.eq(int(row[bit])) + return m + + def ports(self): + regular = [self.opcode_in, + self.function_unit, + self.in1_sel, + self.in2_sel, + self.in3_sel, + self.out_sel, + self.ldst_len, + self.rc_sel, + self.internal_op] + single_bit_ports = [getattr(self, get_signal_name(x)) + for x in single_bit_flags] + return regular + single_bit_ports diff --git a/src/decoder/power_enums.py b/src/decoder/power_enums.py index 66c2029d..fc187dd8 100644 --- a/src/decoder/power_enums.py +++ b/src/decoder/power_enums.py @@ -3,6 +3,7 @@ import csv import os import requests + def get_csv(name): file_dir = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(file_dir, name) @@ -15,6 +16,17 @@ def get_csv(name): reader = csv.DictReader(csvfile) return list(reader) + +# names of the fields in the tables that don't correspond to an enum +single_bit_flags = ['CR in', 'CR out', 'inv A', 'inv out', + 'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b', + 'sgn', 'lk', 'sgl pipe'] + + +def get_signal_name(name): + return name.lower().replace(' ', '_') + + @unique class Function(Enum): ALU = 0 @@ -35,6 +47,10 @@ class InternalOp(Enum): OP_STORE = 9 OP_TDI = 10 OP_XOR = 11 + OP_MCRF = 12 + OP_BCREG = 13 + OP_ISYNC = 14 + OP_ILLEGAL = 15 @unique @@ -55,6 +71,8 @@ class In2Sel(Enum): CONST_BD = 5 CONST_SH32 = 6 RB = 7 + NONE = 8 + SPR = 9 @unique diff --git a/src/decoder/power_major_decoder.py b/src/decoder/power_major_decoder.py deleted file mode 100644 index d7cd6c8b..00000000 --- a/src/decoder/power_major_decoder.py +++ /dev/null @@ -1,73 +0,0 @@ -from nmigen import Module, Elaboratable, Signal -from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel, - OutSel, RC, LdstLen, CryIn, get_csv) - - -# names of the fields in major.csv that don't correspond to an enum -single_bit_flags = ['CR in', 'CR out', 'inv A', 'inv out', - 'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b', - 'sgn', 'lk', 'sgl pipe'] - - -def get_signal_name(name): - return name.lower().replace(' ', '_') - - - - -major_opcodes = get_csv("major.csv") - - -class PowerMajorDecoder(Elaboratable): - def __init__(self): - self.opcode_in = Signal(6, reset_less=True) - - self.function_unit = Signal(Function, reset_less=True) - self.internal_op = Signal(InternalOp, reset_less=True) - self.in1_sel = Signal(In1Sel, reset_less=True) - self.in2_sel = Signal(In2Sel, reset_less=True) - self.in3_sel = Signal(In3Sel, reset_less=True) - self.out_sel = Signal(OutSel, reset_less=True) - self.ldst_len = Signal(LdstLen, 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: - name = get_signal_name(bit) - setattr(self, name, - Signal(reset_less=True, name=name)) - - def elaborate(self, platform): - m = Module() - comb = m.d.comb - - with m.Switch(self.opcode_in): - for row in major_opcodes: - opcode = int(row['opcode']) - with m.Case(opcode): - comb += self.function_unit.eq(Function[row['unit']]) - comb += self.internal_op.eq(InternalOp[row['internal op']]) - comb += self.in1_sel.eq(In1Sel[row['in1']]) - comb += self.in2_sel.eq(In2Sel[row['in2']]) - comb += self.in3_sel.eq(In3Sel[row['in3']]) - comb += self.out_sel.eq(OutSel[row['out']]) - comb += self.ldst_len.eq(LdstLen[row['ldst len']]) - comb += self.rc_sel.eq(RC[row['rc']]) - comb += self.cry_in.eq(CryIn[row['cry in']]) - for bit in single_bit_flags: - sig = getattr(self, get_signal_name(bit)) - comb += sig.eq(int(row[bit])) - return m - - def ports(self): - regular =[self.opcode_in, - self.function_unit, - self.in1_sel, - self.in2_sel, - self.in3_sel, - self.out_sel, - self.ldst_len, - self.rc_sel, - self.internal_op] - single_bit_ports = [getattr(self, get_signal_name(x)) - for x in single_bit_flags] - return regular + single_bit_ports diff --git a/src/decoder/test/test_power_decoder.py b/src/decoder/test/test_power_decoder.py new file mode 100644 index 00000000..5f3f3e2e --- /dev/null +++ b/src/decoder/test/test_power_decoder.py @@ -0,0 +1,89 @@ +from nmigen import Module, Signal +from nmigen.back.pysim import Simulator, Delay +from nmigen.test.utils import FHDLTestCase +from nmigen.cli import rtlil +import sys +import os +import unittest +sys.path.append("../") +from power_decoder import (PowerDecoder) +from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel, + OutSel, RC, LdstLen, CryIn, single_bit_flags, + get_signal_name) + + +class DecoderTestCase(FHDLTestCase): + def run_test(self, width, csvname): + m = Module() + comb = m.d.comb + opcode = Signal(width) + function_unit = Signal(Function) + internal_op = Signal(InternalOp) + in1_sel = Signal(In1Sel) + in2_sel = Signal(In2Sel) + in3_sel = Signal(In3Sel) + out_sel = Signal(OutSel) + rc_sel = Signal(RC) + ldst_len = Signal(LdstLen) + cry_in = Signal(CryIn) + + m.submodules.dut = dut = PowerDecoder(width, csvname) + comb += [dut.opcode_in.eq(opcode), + function_unit.eq(dut.function_unit), + in1_sel.eq(dut.in1_sel), + in2_sel.eq(dut.in2_sel), + in3_sel.eq(dut.in3_sel), + out_sel.eq(dut.out_sel), + rc_sel.eq(dut.rc_sel), + ldst_len.eq(dut.ldst_len), + cry_in.eq(dut.cry_in), + internal_op.eq(dut.internal_op)] + + sim = Simulator(m) + + def process(): + for row in dut.opcodes: + yield opcode.eq(int(row['opcode'], 0)) + yield Delay(1e-6) + signals = [(function_unit, Function, 'unit'), + (internal_op, InternalOp, 'internal op'), + (in1_sel, In1Sel, 'in1'), + (in2_sel, In2Sel, 'in2'), + (in3_sel, In3Sel, 'in3'), + (out_sel, OutSel, 'out'), + (rc_sel, RC, 'rc'), + (cry_in, CryIn, 'cry in'), + (ldst_len, LdstLen, 'ldst len')] + for sig, enm, name in signals: + result = yield sig + expected = enm[row[name]] + msg = f"{sig.name} == {enm(result)}, expected: {expected}" + self.assertEqual(enm(result), expected, msg) + for bit in single_bit_flags: + sig = getattr(dut, get_signal_name(bit)) + result = yield sig + expected = int(row[bit]) + 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=[ + opcode, function_unit, internal_op, + in1_sel, in2_sel]): + sim.run() + + def generate_ilang(self, width, csvname): + prefix = os.path.splitext(csvname)[0] + dut = PowerDecoder(width, csvname) + 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_test(6, "major.csv") + + def test_minor_19(self): + self.run_test(3, "minor_19.csv") + + +if __name__ == "__main__": + unittest.main() diff --git a/src/decoder/test/test_power_major_decoder.py b/src/decoder/test/test_power_major_decoder.py deleted file mode 100644 index 0cc46173..00000000 --- a/src/decoder/test/test_power_major_decoder.py +++ /dev/null @@ -1,81 +0,0 @@ -from nmigen import Module, Signal -from nmigen.back.pysim import Simulator, Delay -from nmigen.test.utils import FHDLTestCase -from nmigen.cli import rtlil -import sys -import unittest -sys.path.append("../") -from power_major_decoder import (PowerMajorDecoder, single_bit_flags, - get_signal_name, major_opcodes) -from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel, - OutSel, RC, LdstLen, CryIn) - - -class DecoderTestCase(FHDLTestCase): - def test_function_unit(self): - m = Module() - comb = m.d.comb - opcode = Signal(6) - function_unit = Signal(Function) - internal_op = Signal(InternalOp) - in1_sel = Signal(In1Sel) - in2_sel = Signal(In2Sel) - in3_sel = Signal(In3Sel) - out_sel = Signal(OutSel) - rc_sel = Signal(RC) - ldst_len = Signal(LdstLen) - cry_in = Signal(CryIn) - - m.submodules.dut = dut = PowerMajorDecoder() - comb += [dut.opcode_in.eq(opcode), - function_unit.eq(dut.function_unit), - in1_sel.eq(dut.in1_sel), - in2_sel.eq(dut.in2_sel), - in3_sel.eq(dut.in3_sel), - out_sel.eq(dut.out_sel), - rc_sel.eq(dut.rc_sel), - ldst_len.eq(dut.ldst_len), - cry_in.eq(dut.cry_in), - internal_op.eq(dut.internal_op)] - - sim = Simulator(m) - - def process(): - for row in major_opcodes: - yield opcode.eq(int(row['opcode'])) - yield Delay(1e-6) - signals = [(function_unit, Function, 'unit'), - (internal_op, InternalOp, 'internal op'), - (in1_sel, In1Sel, 'in1'), - (in2_sel, In2Sel, 'in2'), - (in3_sel, In3Sel, 'in3'), - (out_sel, OutSel, 'out'), - (rc_sel, RC, 'rc'), - (cry_in, CryIn, 'cry in'), - (ldst_len, LdstLen, 'ldst len')] - for sig, enm, name in signals: - result = yield sig - expected = enm[row[name]] - msg = f"{sig.name} == {enm(result)}, expected: {expected}" - self.assertEqual(enm(result), expected, msg) - for bit in single_bit_flags: - sig = getattr(dut, get_signal_name(bit)) - result = yield sig - expected = int(row[bit]) - 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=[ - opcode, function_unit, internal_op, - in1_sel, in2_sel]): - sim.run() - - def test_ilang(self): - dut = PowerMajorDecoder() - vl = rtlil.convert(dut, ports=dut.ports()) - with open("power_major_decoder.il", "w") as f: - f.write(vl) - - -if __name__ == "__main__": - unittest.main()