Change nia input to cia, implement linking
authorMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 18:33:42 +0000 (14:33 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 18:33:42 +0000 (14:33 -0400)
src/soc/branch/main_stage.py
src/soc/branch/pipe_data.py
src/soc/branch/test/test_pipe_caller.py

index 1e2b3e7192613a0419327d326193c078626b6c8b..b7348ef6adbd5e824c883eb5d72a2e0cdca578ed 100644 (file)
@@ -49,15 +49,11 @@ class BranchMainStage(PipeModBase):
         branch_taken = Signal(reset_less=True)
         comb += branch_taken.eq(0)
 
+        # Handle absolute or relative branches
         with m.If(aa):
             comb += branch_addr.eq(branch_imm_addr)
         with m.Else():
-            comb += branch_addr.eq(branch_imm_addr + self.i.nia)
-            
-        
-
-        ##########################
-        # main switch for logic ops AND, OR and XOR, cmpb, parity, and popcount
+            comb += branch_addr.eq(branch_imm_addr + self.i.cia)
 
         with m.Switch(op.insn_type):
             with m.Case(InternalOp.OP_B):
@@ -69,6 +65,12 @@ class BranchMainStage(PipeModBase):
         comb += self.o.nia_out.data.eq(branch_addr)
         comb += self.o.nia_out.ok.eq(branch_taken)
 
+        with m.If(lk):
+            comb += self.o.lr.data.eq(self.i.cia + 4)
+            comb += self.o.lr.ok.eq(1)
+        with m.Else():
+            comb += self.o.lr.ok.eq(0)
+
 
         ###### sticky overflow and context, both pass-through #####
 
index 4904ba7e4671e4e20a2f14247444801383e74e83..3969e6f9f624206e9c00a443e6d075d9c3ec26af 100644 (file)
@@ -25,19 +25,19 @@ class BranchInputData(IntegerData):
         self.lr = Signal(64, reset_less=True)
         self.spr = Signal(64, reset_less=True)
         self.cr = Signal(32, reset_less=True)
-        self.nia = Signal(64, reset_less=True)
+        self.cia = Signal(64, reset_less=True)
 
     def __iter__(self):
         yield from super().__iter__()
         yield self.lr
         yield self.spr
         yield self.cr
-        yield self.nia
+        yield self.cia
 
     def eq(self, i):
         lst = super().eq(i)
         return lst + [self.lr.eq(i.lr), self.spr.eq(i.lr),
-                      self.cr.eq(i.cr), self.nia.eq(i.nia)]
+                      self.cr.eq(i.cr), self.cia.eq(i.cia)]
 
 
 class BranchOutputData(IntegerData):
index e55a3fbf13034f247d115309a4780a4fb5e43409..cc9f3e08ec60586fcc63c0568fda22441f8cd338 100644 (file)
@@ -69,7 +69,7 @@ class BranchTestCase(FHDLTestCase):
         self.run_tst_program(Program(lst), initial_regs)
 
     def test_b(self):
-        lst = ["b 0x1234"]
+        lst = ["bl 0x1234"]
         initial_regs = [0] * 32
         self.run_tst_program(Program(lst), initial_regs)
 
@@ -131,7 +131,7 @@ class TestRunner(FHDLTestCase):
                     # ask the decoder to decode this binary data (endian'd)
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
-                    yield branch.p.data_i.nia.eq(simulator.pc.CIA.value)
+                    yield branch.p.data_i.cia.eq(simulator.pc.CIA.value)
                     yield Settle()
                     fn_unit = yield pdecode2.e.fn_unit
                     #self.assertEqual(fn_unit, Function.BRANCH.value, code)
@@ -159,6 +159,13 @@ class TestRunner(FHDLTestCase):
             branch_addr = yield branch.n.data_o.nia_out.data
             self.assertEqual(branch_addr, sim.pc.CIA.value)
 
+        lk = yield dec2.e.lk
+        branch_lk = yield branch.n.data_o.lr.ok
+        self.assertEqual(lk, branch_lk)
+        if lk:
+            branch_lr = yield branch.n.data_o.lr.data
+            self.assertEqual(sim.spr['LR'], branch_lr)
+
 
 if __name__ == "__main__":
     unittest.main(exit=False)