Assemble whole program instead of instruction by instruction
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 25 Mar 2020 21:16:07 +0000 (17:16 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 25 Mar 2020 21:16:07 +0000 (17:16 -0400)
src/soc/simulator/memmap [new file with mode: 0644]
src/soc/simulator/program.py [new file with mode: 0644]
src/soc/simulator/test_sim.py

diff --git a/src/soc/simulator/memmap b/src/soc/simulator/memmap
new file mode 100644 (file)
index 0000000..8cc1a16
--- /dev/null
@@ -0,0 +1,11 @@
+
+MEMORY
+{
+    ram  : ORIGIN = 0x20000000, LENGTH = 128M
+}
+
+SECTIONS
+{
+   .text : { *(.text*) } > ram
+   .bss  : { *(.text*) } > ram
+}
diff --git a/src/soc/simulator/program.py b/src/soc/simulator/program.py
new file mode 100644 (file)
index 0000000..d0b11d6
--- /dev/null
@@ -0,0 +1,56 @@
+import tempfile
+import subprocess
+import struct
+import os
+
+filedir = os.path.dirname(os.path.realpath(__file__))
+memmap = os.path.join(filedir, "memmap")
+
+bigendian = True
+endian_fmt = "elf64-big"
+obj_fmt = "-be"
+
+class Program:
+    def __init__(self, instructions):
+        if isinstance(instructions, list):
+            instructions = '\n'.join(instructions)
+        self.assembly = instructions
+        self._assemble()
+
+    def _get_binary(self, elffile):
+        self.binfile = tempfile.NamedTemporaryFile(suffix=".bin")
+        #self.binfile = open("kernel.bin", "wb+")
+        args = ["powerpc64-linux-gnu-objcopy",
+                "-O", "binary",
+                "-I", endian_fmt,
+                elffile.name,
+                self.binfile.name]
+        subprocess.check_output(args)
+
+    def _link(self, ofile):
+        with tempfile.NamedTemporaryFile(suffix=".elf") as elffile:
+        #with open("kernel.elf", "wb+") as elffile:
+            args = ["powerpc64-linux-gnu-ld",
+                    "-o", elffile.name,
+                    "-T", memmap,
+                    ofile.name]
+            subprocess.check_output(args)
+            self._get_binary(elffile)
+
+    def _assemble(self):
+        with tempfile.NamedTemporaryFile(suffix=".o") as outfile:
+            args = ["powerpc64-linux-gnu-as",
+                    obj_fmt,
+                    "-o",
+                    outfile.name]
+            p = subprocess.Popen(args, stdin=subprocess.PIPE)
+            p.communicate(self.assembly.encode('utf-8'))
+            assert(p.wait() == 0)
+            self._link(outfile)
+
+    def generate_instructions(self):
+        while True:
+            data = self.binfile.read(4)
+            if not data:
+                break
+            yield struct.unpack('<i', data)[0]
index 210141fdbd1262e5e53a3aebbc3768ac01125a26..0e190483791a4756900c898461f35e9af789986c 100644 (file)
@@ -11,6 +11,7 @@ from soc.decoder.power_enums import (Function, InternalOp,
                                      get_signal_name, get_csv)
 from soc.decoder.power_decoder2 import (PowerDecode2)
 from soc.simulator.gas import get_assembled_instruction
+from soc.simulator.program import Program
 
 
 class Register:
@@ -18,13 +19,6 @@ class Register:
         self.num = num
 
 
-class InstrList:
-    def __init__(self, lst):
-        self.instrs = [x + "\n" for x in lst]
-
-    def generate_instructions(self):
-        return iter(self.instrs)
-
 
 class DecoderTestCase(FHDLTestCase):
 
@@ -42,14 +36,12 @@ class DecoderTestCase(FHDLTestCase):
 
         def process():
             for ins in gen:
-                print("instr", ins.strip())
 
-                # turn the instruction into binary data (endian'd)
-                ibin = get_assembled_instruction(ins, 0)
+                print("0x{:X}".format(ins & 0xffffffff))
 
                 # ask the decoder to decode this binary data (endian'd)
                 yield pdecode2.dec.bigendian.eq(0)  # little / big?
-                yield instruction.eq(ibin)          # raw binary instr.
+                yield instruction.eq(ins)          # raw binary instr.
                 yield Delay(1e-6)
                 yield from simulator.execute_op(pdecode2)
 
@@ -63,7 +55,7 @@ class DecoderTestCase(FHDLTestCase):
                "addi 2, 0, 0x5678",
                "add  3, 1, 2",
                "and  4, 1, 2"]
-        gen = InstrList(lst)
+        gen = Program(lst)
 
         simulator = InternalOpSimulator()
 
@@ -79,7 +71,7 @@ class DecoderTestCase(FHDLTestCase):
                "addi 2, 0, 0x5678",
                "stw  1, 0(2)",
                "lwz  3, 0(2)"]
-        gen = InstrList(lst)
+        gen = Program(lst)
 
         simulator = InternalOpSimulator()
 
@@ -95,7 +87,7 @@ class DecoderTestCase(FHDLTestCase):
                "addi 4, 0, 0x40",
                "stw  1, 0x40(2)",
                "lwzx  3, 4, 2"]
-        gen = InstrList(lst)
+        gen = Program(lst)
 
         simulator = InternalOpSimulator()
 
@@ -115,7 +107,7 @@ class DecoderTestCase(FHDLTestCase):
                "ori 5, 0, 0x12",
                "stb 5, 5(2)",
                "ld  5, 0(2)"]
-        gen = InstrList(lst)
+        gen = Program(lst)
         simulator = InternalOpSimulator()
         self.run_tst(gen, simulator)
         simulator.regfile.assert_gprs({