Merge branch 'master' of ssh://git.libre-riscv.org:922/soc
authorJacob Lifshay <programmerjake@gmail.com>
Thu, 18 Jun 2020 22:31:14 +0000 (15:31 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Thu, 18 Jun 2020 22:31:14 +0000 (15:31 -0700)
src/soc/decoder/isa/caller.py
src/soc/fu/compunits/test/test_compunit.py
src/soc/regfile/regfiles.py
src/soc/simple/core.py
src/soc/simple/issuer.py
src/soc/simple/test/test_issuer.py
src/soc/simulator/program.py
src/soc/simulator/test_sim.py

index 8b40a1c821538819eb0a232c8d580f90ad6879a5..e5d14652892e9a3be613e02cbbb79d1078ae6709 100644 (file)
@@ -410,7 +410,7 @@ class ISACaller:
         print("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
         print ("NIA, CIA", self.pc.CIA.value, self.pc.NIA.value)
 
-        yield self.dec2.dec.raw_opcode_in.eq(ins)
+        yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
         yield self.dec2.dec.bigendian.eq(0)  # little / big?
 
     def execute_one(self):
@@ -457,8 +457,7 @@ class ISACaller:
         # https://bugs.libre-soc.org/show_bug.cgi?id=390
         if int_op == InternalOp.OP_MTCRF.value:
             dec_insn = yield self.dec2.e.insn
-            print ("mtcrf", bin(dec_insn), (dec_insn & (1<<20)))
-            if dec_insn & (1<<21) != 0: # sigh
+            if dec_insn & (1<<20) != 0: # sigh
                 asmop = 'mtocrf'
             else:
                 asmop = 'mtcrf'
index 705b18dc5f2daa062239ab80e80399872a03925e..efc8e9d570124a6d405a1dafdcfebb292efe0e25 100644 (file)
@@ -195,11 +195,14 @@ class TestRunner(FHDLTestCase):
                     yield from setup_test_memory(l0, sim)
 
                 index = sim.pc.CIA.value//4
-                while index < len(instructions):
-                    ins, code = instructions[index]
-                    yield from sim.setup_one()
+                while True:
+                    try:
+                        yield from sim.setup_one()
+                    except KeyError: # indicates instruction not in imem: stop
+                        break
                     yield Settle()
-                    print(code)
+                    ins, code = instructions[index]
+                    print(index, code)
 
                     # ask the decoder to decode this binary data (endian'd)
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
@@ -246,9 +249,9 @@ class TestRunner(FHDLTestCase):
 
                     # call simulated operation
                     yield from sim.execute_one()
+                    yield Settle()
                     index = sim.pc.CIA.value//4
 
-                    yield Settle()
                     # get all outputs (one by one, just "because")
                     res = yield from get_cu_outputs(cu, code)
                     wrmask = yield cu.wrmask
index 4a8f5a3fb971b85f439f1e11ef29f900bc7e779e..7ed51a8a11f54cfdeefdc2157d2dbdb4ff51dc90 100644 (file)
@@ -68,7 +68,7 @@ class FastRegs(RegFileArray):
     SRR1 = 6
     def __init__(self):
         super().__init__(64, 8)
-        self.w_ports = {'nia': self.write_port("dest1"),
+        self.w_ports = {'nia': self.write_port("nia"),
                         'msr': self.write_port("dest2"),
                         'spr1': self.write_port("dest3"),
                         'spr2': self.write_port("dest4"),
index 837e1d06481011ae77c82d6575058ab156a0a830..e52aac64079f2a3abba53b589e562de8172144a3 100644 (file)
@@ -310,7 +310,7 @@ class NonProductionCore(Elaboratable):
 
 
 if __name__ == '__main__':
-    dut = TestIssuer()
+    dut = NonProductionCore()
     vl = rtlil.convert(dut, ports=dut.ports())
-    with open("test_issuer.il", "w") as f:
+    with open("test_core.il", "w") as f:
         f.write(vl)
index 62c3b98c1e728b4cb024654ceb10e69758ad4170..e41bc65248c4030bdf80c1b0e079d56f2cb60f5a 100644 (file)
@@ -49,6 +49,9 @@ class TestIssuer(Elaboratable):
         # FAST regfile read /write ports
         self.fast_rd1 = self.core.regs.rf['fast'].r_ports['d_rd1']
         self.fast_wr1 = self.core.regs.rf['fast'].w_ports['d_wr1']
+        # hack method of keeping an eye on whether branch/trap set the PC
+        self.fast_nia = self.core.regs.rf['fast'].w_ports['nia']
+        self.fast_nia.wen.name = 'fast_nia_wen'
 
     def elaborate(self, platform):
         m = Module()
@@ -66,6 +69,7 @@ class TestIssuer(Elaboratable):
         # PC and instruction from I-Memory
         current_insn = Signal(32) # current fetched instruction (note sync)
         current_pc = Signal(64) # current PC (note it is reset/sync)
+        pc_changed = Signal() # note write to PC
         comb += self.pc_o.eq(current_pc)
         ilatch = Signal(32)
 
@@ -85,6 +89,7 @@ class TestIssuer(Elaboratable):
 
             # waiting (zzz)
             with m.State("IDLE"):
+                sync += pc_changed.eq(0)
                 with m.If(self.go_insn_i):
                     # instruction allowed to go: start by reading the PC
                     pc = Signal(64, reset_less=True)
@@ -100,7 +105,7 @@ class TestIssuer(Elaboratable):
                     # lookups together.  this is Generally Bad.
                     comb += self.i_rd.addr.eq(pc[2:]) # ignore last 2 bits
                     comb += current_insn.eq(self.i_rd.data)
-                    comb += current_pc.eq(pc)
+                    sync += current_pc.eq(pc)
                     m.next = "INSN_READ" # move to "issue" phase
 
             # got the instruction: start issue
@@ -118,14 +123,17 @@ class TestIssuer(Elaboratable):
                 comb += core_ivalid_i.eq(1) # say instruction is valid
                 comb += core_opcode_i.eq(ilatch) # actual opcode
                 #sync += core_issue_i.eq(0) # issue raises for only one cycle
+                with m.If(self.fast_nia.wen):
+                    sync += pc_changed.eq(1)
                 with m.If(~core_busy_o): # instruction done!
                     #sync += core_ivalid_i.eq(0) # say instruction is invalid
                     #sync += core_opcode_i.eq(0) # clear out (no good reason)
                     # ok here we are not reading the branch unit.  TODO
                     # this just blithely overwrites whatever pipeline updated
                     # the PC
-                    comb += self.fast_wr1.wen.eq(1<<FastRegs.PC)
-                    comb += self.fast_wr1.data_i.eq(nia)
+                    with m.If(~pc_changed):
+                        comb += self.fast_wr1.wen.eq(1<<FastRegs.PC)
+                        comb += self.fast_wr1.data_i.eq(nia)
                     m.next = "IDLE" # back to idle
 
         return m
index b3a50c0a9c311bb19ac63d01a44ba9ea78f2b86a..0bd2b5adba5c375e0eaff8618edd4232ee6f70f7 100644 (file)
@@ -30,6 +30,7 @@ from soc.fu.shift_rot.test.test_pipe_caller import ShiftRotTestCase
 from soc.fu.cr.test.test_pipe_caller import CRTestCase
 from soc.fu.branch.test.test_pipe_caller import BranchTestCase
 from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase
+from soc.simulator.test_sim import GeneralTestCases
 
 
 def setup_i_memory(imem, startaddr, instructions):
@@ -74,10 +75,19 @@ class TestRunner(FHDLTestCase):
                 print(test.name)
                 program = test.program
                 self.subTest(test.name)
+                print ("regs", test.regs)
+                print ("sprs", test.sprs)
+                print ("cr", test.cr)
+                print ("mem", test.mem)
+                print ("msr", test.msr)
+                print ("assem", program.assembly)
+                gen = list(program.generate_instructions())
+                insncode = program.assembly.splitlines()
+                instructions = list(zip(gen, insncode))
                 sim = ISA(pdecode2, test.regs, test.sprs, test.cr, test.mem,
-                          test.msr)
-                gen = program.generate_instructions()
-                instructions = list(zip(gen, program.assembly.splitlines()))
+                          test.msr,
+                          initial_insns=gen, respect_pc=True,
+                          disassembly=insncode)
 
                 pc = 0 # start address
 
@@ -93,7 +103,7 @@ class TestRunner(FHDLTestCase):
                     ins, code = instructions[index]
 
                     print("instruction: 0x{:X}".format(ins & 0xffffffff))
-                    print(code)
+                    print(index, code)
 
                     # start the instruction
                     yield go_insn_i.eq(1)
@@ -109,6 +119,7 @@ class TestRunner(FHDLTestCase):
                     # call simulated operation
                     opname = code.split(' ')[0]
                     yield from sim.call(opname)
+                    yield Settle()
                     index = sim.pc.CIA.value//4
 
                     # register check
@@ -126,6 +137,7 @@ class TestRunner(FHDLTestCase):
 if __name__ == "__main__":
     unittest.main(exit=False)
     suite = unittest.TestSuite()
+    suite.addTest(TestRunner(GeneralTestCases.test_data))
     suite.addTest(TestRunner(LDSTTestCase.test_data))
     suite.addTest(TestRunner(CRTestCase.test_data))
     suite.addTest(TestRunner(ShiftRotTestCase.test_data))
index cd515a8d0ebd175094913ad2ce1c47a3c481a399..fdcea64201580ab7432f767f6a16c1c6d9580e7a 100644 (file)
@@ -24,6 +24,7 @@ class Program:
             instructions = '\n'.join(instructions)
         self.assembly = instructions + '\n' # plus final newline
         self._assemble()
+        self._instructions = list(self._get_instructions())
 
     def __enter__(self):
         return self
@@ -64,13 +65,16 @@ class Program:
                 sys.exit(1)
             self._link(outfile)
 
-    def generate_instructions(self):
+    def _get_instructions(self):
         while True:
             data = self.binfile.read(4)
             if not data:
                 break
             yield struct.unpack('<i', data)[0]
 
+    def generate_instructions(self):
+        yield from self._instructions
+
     def reset(self):
         self.binfile.seek(0)
 
index cf213f6941073d8795c314d4127d444e708e4fed..9ab807d6094de356427829969d5aa8eea48b90bd 100644 (file)
@@ -12,6 +12,7 @@ from soc.decoder.power_decoder2 import (PowerDecode2)
 from soc.simulator.program import Program
 from soc.simulator.qemu import run_program
 from soc.decoder.isa.all import ISA
+from soc.fu.test.common import TestCase
 
 
 class Register:
@@ -19,42 +20,12 @@ class Register:
         self.num = num
 
 
-class DecoderTestCase(FHDLTestCase):
+class GeneralTestCases(FHDLTestCase):
+    test_data = []
 
-    def run_tst(self, generator, initial_mem=None):
-        m = Module()
-        comb = m.d.comb
-
-        gen = list(generator.generate_instructions())
-        insn_code = generator.assembly.splitlines()
-        instructions = list(zip(gen, insn_code))
-
-        pdecode = create_pdecode()
-        m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
-
-        simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0,
-                        initial_insns=gen, respect_pc=True,
-                        disassembly=insn_code)
-
-        sim = Simulator(m)
-
-        def process():
-            while True:
-                try:
-                    yield from simulator.setup_one()
-                except KeyError: # indicates instruction not in imem: stop
-                    break
-                yield Settle()
-                yield from simulator.execute_one()
-                yield Settle()
-
-
-        sim.add_process(process)
-        with sim.write_vcd("simulator.vcd", "simulator.gtkw",
-                           traces=[]):
-            sim.run()
-
-        return simulator
+    def __init__(self, name="general"):
+        super().__init__(name)
+        self.test_name = name
 
     @unittest.skip("disable")
     def test_0_cmp(self):
@@ -173,7 +144,8 @@ class DecoderTestCase(FHDLTestCase):
         with Program(lst) as program:
             self.run_tst_program(program, [1])
 
-    def tst_2_load_store(self):
+    @unittest.skip("disable")
+    def test_2_load_store(self):
         lst = ["addi 1, 0, 0x1004",
                "addi 2, 0, 0x1008",
                "addi 3, 0, 0x00ee",
@@ -227,6 +199,51 @@ class DecoderTestCase(FHDLTestCase):
         with Program(lst) as program:
             self.run_tst_program(program, [9], initial_mem={})
 
+    def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
+                                    initial_mem=None):
+        initial_regs = [0] * 32
+        tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
+                                            initial_mem, 0)
+        self.test_data.append(tc)
+
+
+class DecoderTestCase(GeneralTestCases):
+
+    def run_tst(self, generator, initial_mem=None):
+        m = Module()
+        comb = m.d.comb
+
+        gen = list(generator.generate_instructions())
+        insn_code = generator.assembly.splitlines()
+        instructions = list(zip(gen, insn_code))
+
+        pdecode = create_pdecode()
+        m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
+
+        simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0,
+                        initial_insns=gen, respect_pc=True,
+                        disassembly=insn_code)
+
+        sim = Simulator(m)
+
+        def process():
+            while True:
+                try:
+                    yield from simulator.setup_one()
+                except KeyError: # indicates instruction not in imem: stop
+                    break
+                yield Settle()
+                yield from simulator.execute_one()
+                yield Settle()
+
+
+        sim.add_process(process)
+        with sim.write_vcd("simulator.vcd", "simulator.gtkw",
+                           traces=[]):
+            sim.run()
+
+        return simulator
+
     def run_tst_program(self, prog, reglist, initial_mem=None):
         import sys
         simulator = self.run_tst(prog, initial_mem=initial_mem)