Directly compare simulator with qemu
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 25 Mar 2020 22:38:18 +0000 (18:38 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 25 Mar 2020 22:43:32 +0000 (18:43 -0400)
I'm getting an error where it says some files are still open, but I
can't figure out what they are

src/soc/simulator/internalop_sim.py
src/soc/simulator/program.py
src/soc/simulator/qemu.py
src/soc/simulator/test_sim.py

index f7cd669c8f3a7886ac465660af02ad25275837e6..3345c6b7a4a7dee9370ce38d30c16e749cb651bf 100644 (file)
@@ -1,7 +1,8 @@
 from soc.decoder.power_enums import (Function, Form, InternalOp,
-                         In1Sel, In2Sel, In3Sel, OutSel, RC, LdstLen,
-                         CryIn, get_csv, single_bit_flags,
-                         get_signal_name, default_values)
+                                     In1Sel, In2Sel, In3Sel, OutSel,
+                                     RC, LdstLen, CryIn, get_csv,
+                                     single_bit_flags,
+                                     get_signal_name, default_values)
 import math
 
 
@@ -66,12 +67,15 @@ class RegFile:
         print("Read {:x} from reg r{}".format(val, regnum))
         return val
 
+    def assert_gpr(self, gpr, val):
+        reg_val = self.read_reg(gpr)
+        msg = "reg r{} got {:x}, expecting {:x}".format(
+            gpr, reg_val, val)
+        assert reg_val == val, msg
+
     def assert_gprs(self, gprs):
-        for k,v in list(gprs.items()):
-            reg_val = self.read_reg(k)
-            msg = "reg r{} got {:x}, expecting {:x}".format(
-                k, reg_val, v)
-            assert reg_val == v, msg
+        for k, v in list(gprs.items()):
+            self.assert_gpr(k, v)
 
 
 class InternalOpSimulator:
@@ -121,7 +125,7 @@ class InternalOpSimulator:
         internal_op = yield pdecode2.dec.op.internal_op
         addr_reg = yield pdecode2.e.read_reg1.data
         addr = self.regfile.read_reg(addr_reg)
+
         imm_ok = yield pdecode2.e.imm_data.ok
         r2_ok = yield pdecode2.e.read_reg2.ok
         width = yield pdecode2.e.data_len
index d0b11d670b771b9e110eab5d81ec11c96f4ab4b0..4466f99be87e1d06caa4a905fbd610421b4ba348 100644 (file)
@@ -10,6 +10,7 @@ bigendian = True
 endian_fmt = "elf64-big"
 obj_fmt = "-be"
 
+
 class Program:
     def __init__(self, instructions):
         if isinstance(instructions, list):
@@ -17,9 +18,14 @@ class Program:
         self.assembly = instructions
         self._assemble()
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.close()
+
     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,
@@ -29,7 +35,6 @@ class Program:
 
     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,
@@ -54,3 +59,16 @@ class Program:
             if not data:
                 break
             yield struct.unpack('<i', data)[0]
+
+    def reset(self):
+        self.binfile.seek(0)
+
+    def size(self):
+        curpos = self.binfile.tell()
+        self.binfile.seek(0, 2)  # Seek to end of file
+        size = self.binfile.tell()
+        self.binfile.seek(curpos, 0)
+        return size
+
+    def close(self):
+        self.binfile.close()
index 70e29b0d76b65227a06d3ba3bd95315cf5af37e8..c9b1b573dd22d3da0adb0415a0a6b8bb005c99c6 100644 (file)
@@ -6,6 +6,7 @@ launch_args = ['qemu-system-ppc64',
                '-nographic',
                '-s', '-S']
 
+
 class QemuController:
     def __init__(self, kernel):
         args = launch_args + ['-kernel', kernel]
@@ -14,6 +15,12 @@ class QemuController:
                                            stdin=subprocess.PIPE)
         self.gdb = GdbController(gdb_path='powerpc64-linux-gnu-gdb')
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.exit()
+
     def connect(self):
         return self.gdb.write('-target-select remote localhost:1234')
 
@@ -25,18 +32,28 @@ class QemuController:
         return self.gdb.write('-data-list-register-values x')
 
     def get_register(self, num):
-        return self.gdb.write('-data-list-register-values x {}'.format(num))
+        res = self.gdb.write('-data-list-register-values x {}'.format(num))
+        val = int(res[0]['payload']['register-values'][0]['value'], 0)
+        return val
 
     def step(self):
         return self.gdb.write('-exec-next-instruction')
 
     def gdb_continue(self):
         return self.gdb.write('-exec-continue')
-        
+
     def exit(self):
         self.gdb.exit()
         self.qemu_popen.kill()
-                                 
+
+
+def run_program(program):
+    q = QemuController(program.binfile.name)
+    q.connect()
+    q.break_address(0x20000000 + program.size())
+    q.gdb_continue()
+    return q
+
 
 if __name__ == '__main__':
     q = QemuController("qemu_test/kernel.bin")
@@ -47,5 +64,3 @@ if __name__ == '__main__':
     print(q.step())
     print(q.get_register(1))
     q.exit()
-
-    
index 0e190483791a4756900c898461f35e9af789986c..094f10d53936b3af9ba569b1deb982d90359991b 100644 (file)
@@ -10,8 +10,8 @@ from soc.decoder.power_enums import (Function, InternalOp,
                                      single_bit_flags, Form, SPR,
                                      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
+from soc.simulator.qemu import run_program
 
 
 class Register:
@@ -19,7 +19,6 @@ class Register:
         self.num = num
 
 
-
 class DecoderTestCase(FHDLTestCase):
 
     def run_tst(self, generator, simulator):
@@ -55,31 +54,16 @@ class DecoderTestCase(FHDLTestCase):
                "addi 2, 0, 0x5678",
                "add  3, 1, 2",
                "and  4, 1, 2"]
-        gen = Program(lst)
-
-        simulator = InternalOpSimulator()
-
-        self.run_tst(gen, simulator)
-        simulator.regfile.assert_gprs(
-            {1: 0x1234,
-             2: 0x5678,
-             3: 0x68ac,
-             4: 0x1230})
+        with Program(lst) as program:
+            self.run_test_program(program, [1, 2, 3, 4])
 
     def test_ldst(self):
         lst = ["addi 1, 0, 0x1234",
                "addi 2, 0, 0x5678",
                "stw  1, 0(2)",
                "lwz  3, 0(2)"]
-        gen = Program(lst)
-
-        simulator = InternalOpSimulator()
-
-        self.run_tst(gen, simulator)
-        simulator.regfile.assert_gprs(
-            {1: 0x1234,
-             2: 0x5678,
-             3: 0x1234})
+        with Program(lst) as program:
+            self.run_test_program(program, [1, 2, 3])
 
     def test_ldst_extended(self):
         lst = ["addi 1, 0, 0x1234",
@@ -87,15 +71,9 @@ class DecoderTestCase(FHDLTestCase):
                "addi 4, 0, 0x40",
                "stw  1, 0x40(2)",
                "lwzx  3, 4, 2"]
-        gen = Program(lst)
-
-        simulator = InternalOpSimulator()
+        with Program(lst) as program:
+            self.run_test_program(program, [1, 2, 3])
 
-        self.run_tst(gen, simulator)
-        simulator.regfile.assert_gprs(
-            {1: 0x1234,
-             2: 0x5678,
-             3: 0x1234})
     def test_ldst_widths(self):
         lst = [" lis 1, 0xdead",
                "ori 1, 1, 0xbeef",
@@ -104,17 +82,24 @@ class DecoderTestCase(FHDLTestCase):
                "lbz 1, 5(2)",
                "lhz 3, 4(2)",
                "lwz 4, 4(2)",
-               "ori 5, 0, 0x12",
+               "addi 5, 0, 0x12",
                "stb 5, 5(2)",
                "ld  5, 0(2)"]
-        gen = Program(lst)
+        with Program(lst) as program:
+            self.run_test_program(program, [1, 2, 3, 4, 5])
+
+    def run_test_program(self, prog, reglist):
         simulator = InternalOpSimulator()
-        self.run_tst(gen, simulator)
-        simulator.regfile.assert_gprs({
-            1: 0xad,
-            3: 0xdead,
-            4: 0xdeadbeef,
-            5: 0xffffffffde12beef})  # checked with qemu
+        self.run_tst(prog, simulator)
+        prog.reset()
+        with run_program(prog) as q:
+            qemu_register_compare(simulator, q, reglist)
+
+
+def qemu_register_compare(simulator, qemu, regs):
+    for reg in regs:
+        qemu_val = qemu.get_register(reg)
+        simulator.regfile.assert_gpr(reg, qemu_val)
 
 
 if __name__ == "__main__":