Begin adding power ISA decoder
authorMichael Nolan <mtnolan2640@gmail.com>
Sat, 29 Feb 2020 19:23:53 +0000 (14:23 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Sat, 29 Feb 2020 19:23:53 +0000 (14:23 -0500)
src/decoder/decoder.py [new file with mode: 0644]
src/decoder/major.csv [new file with mode: 0644]
src/decoder/test/test_decoder.py [new file with mode: 0644]

diff --git a/src/decoder/decoder.py b/src/decoder/decoder.py
new file mode 100644 (file)
index 0000000..65aa333
--- /dev/null
@@ -0,0 +1,36 @@
+from nmigen import Module, Elaboratable, Signal
+import csv
+import os
+from enum import Enum, unique
+
+class Function(Enum):
+    ALU = 0
+    LDST = 1
+
+def get_csv(name):
+    file_dir = os.path.dirname(os.path.realpath(__file__))
+    with open(os.path.join(file_dir, name)) as csvfile:
+        reader = csv.DictReader(csvfile)
+        return list(reader)
+
+major_opcodes = get_csv("major.csv")
+
+class PowerDecoder(Elaboratable):
+    def __init__(self):
+        self.opcode_in = Signal(6, reset_less=True)
+
+        self.function_unit = Signal(Function, reset_less=True)
+    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']])
+        return m
+
+
+
+    
diff --git a/src/decoder/major.csv b/src/decoder/major.csv
new file mode 100644 (file)
index 0000000..f58784a
--- /dev/null
@@ -0,0 +1,35 @@
+opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry out,ldst len,BR,sgn ext,upd,rsrv,32b,sgn,rc,lk,sgl pipe
+12,ALU,OP_ADD,RA,CONST_SI,NONE,RT,0,0,0,0,ZERO,1,NONE,0,0,0,0,0,0,NONE,0,0,addic
+13,ALU,OP_ADD,RA,CONST_SI,NONE,RT,0,0,0,0,ZERO,1,NONE,0,0,0,0,0,0,ONE,0,0,addic.
+14,ALU,OP_ADD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,addi
+15,ALU,OP_ADD,RA_OR_ZERO,CONST_SI_HI,NONE,RT,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,addis
+28,ALU,OP_AND,NONE,CONST_UI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,ONE,0,0,andi.
+29,ALU,OP_AND,NONE,CONST_UI_HI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,ONE,0,0,andis.
+18,ALU,OP_B,NONE,CONST_LI,NONE,NONE,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,1,0,b
+16,ALU,OP_BC,SPR,CONST_BD,NONE,SPR,1,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,1,0,bc
+11,ALU,OP_CMP,RA,CONST_SI,NONE,NONE,0,1,1,0,ONE,0,NONE,0,0,0,0,0,1,NONE,0,0,cmpi
+10,ALU,OP_CMP,RA,CONST_UI,NONE,NONE,0,1,1,0,ONE,0,NONE,0,0,0,0,0,0,NONE,0,0,cmpli
+34,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is1B,0,0,0,0,0,0,NONE,0,1,lbz
+35,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is1B,0,0,1,0,0,0,NONE,0,1,lbzu
+42,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,1,0,0,0,0,NONE,0,1,lha
+43,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,1,1,0,0,0,NONE,0,1,lhau
+40,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,0,0,0,0,0,NONE,0,1,lhz
+41,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,0,1,0,0,0,NONE,0,1,lhzu
+32,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is4B,0,0,0,0,0,0,NONE,0,1,lwz
+33,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is4B,0,0,1,0,0,0,NONE,0,1,lwzu
+7,ALU,OP_MUL_L64,RA,CONST_SI,NONE,RT,0,1,0,0,ZERO,0,NONE,0,0,0,0,0,1,NONE,0,0,mulli
+24,ALU,OP_OR,NONE,CONST_UI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,ori
+25,ALU,OP_OR,NONE,CONST_UI_HI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,oris
+20,ALU,OP_RLC,RA,CONST_SH32,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,rlwimi
+21,ALU,OP_RLC,NONE,CONST_SH32,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,rlwinm
+23,ALU,OP_RLC,NONE,RB,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,rlwnm
+38,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is1B,0,0,0,0,0,0,RC,0,1,stb
+39,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is1B,0,0,1,0,0,0,RC,0,1,stbu
+44,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is2B,0,0,0,0,0,0,NONE,0,1,sth
+45,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is2B,0,0,1,0,0,0,NONE,0,1,sthu
+36,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is4B,0,0,0,0,0,0,NONE,0,1,stw
+37,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is4B,0,0,1,0,0,0,NONE,0,1,stwu
+8,ALU,OP_ADD,RA,CONST_SI,NONE,RT,0,0,1,0,ONE,1,NONE,0,0,0,0,0,0,NONE,0,0,subfic
+2,ALU,OP_TDI,RA,CONST_SI,NONE,NONE,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,1,tdi
+26,ALU,OP_XOR,NONE,CONST_UI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,xori
+27,ALU,OP_XOR,NONE,CONST_UI_HI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,xoris
diff --git a/src/decoder/test/test_decoder.py b/src/decoder/test/test_decoder.py
new file mode 100644 (file)
index 0000000..37faddd
--- /dev/null
@@ -0,0 +1,41 @@
+from nmigen import Module, Elaboratable, Signal
+from nmigen.back.pysim import Simulator, Delay, Settle
+from nmigen.test.utils import FHDLTestCase
+from nmigen.cli import rtlil
+import sys
+import unittest
+sys.path.append("../")
+from decoder import PowerDecoder, Function, major_opcodes
+
+class DecoderTestCase(FHDLTestCase):
+    def test_function_unit(self):
+        m = Module()
+        comb = m.d.comb
+        opcode = Signal(6)
+        function_unit = Signal(Function)
+
+        m.submodules.dut = dut = PowerDecoder()
+        comb += [dut.opcode_in.eq(opcode),
+                 function_unit.eq(dut.function_unit)]
+
+        sim = Simulator(m)
+        def process():
+            for row in major_opcodes:
+                yield opcode.eq(int(row['opcode']))
+                yield Delay(1e-6)
+                result = yield function_unit
+                expected = Function[row['unit']].value
+                self.assertEqual(expected, result)
+        sim.add_process(process)
+        with sim.write_vcd("test.vcd", "test.gtkw", traces=[opcode, function_unit]):
+            sim.run()
+
+    def test_ilang(self):
+        dut = PowerDecoder()
+        vl = rtlil.convert(dut, ports=[dut.opcode_in, dut.function_unit])
+        with open("power_decoder.il", "w") as f:
+            f.write(vl)
+
+if __name__ == "__main__":
+    unittest.main()
+