add branch to absolute address
authorMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 18:01:12 +0000 (14:01 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 18:01:12 +0000 (14:01 -0400)
src/soc/branch/main_stage.py
src/soc/branch/test/test_pipe_caller.py

index e4e522b6aaa4621bc69e7a2e3692bcc5c2c1964a..453bab7ac0b4a51c1cc8ec7ef63c29c69ac94d9c 100644 (file)
@@ -38,11 +38,30 @@ class BranchMainStage(PipeModBase):
         comb = m.d.comb
         op = self.i.ctx.op
 
+        i_fields = self.fields.instrs['I']
+        lk = Signal(i_fields['LK'][0:-1].shape())
+        comb += lk.eq(i_fields['LK'][0:-1])
+        aa = Signal(i_fields['AA'][0:-1].shape())
+        comb += aa.eq(i_fields['AA'][0:-1])
+
+        branch_addr = Signal(64, reset_less=True)
+        branch_taken = Signal(reset_less=True)
+        comb += branch_taken.eq(0)
+        
+
         ##########################
         # main switch for logic ops AND, OR and XOR, cmpb, parity, and popcount
 
         with m.Switch(op.insn_type):
-            pass
+            with m.Case(InternalOp.OP_B):
+                li = Signal(i_fields['LI'][0:-1].shape())
+                comb += li.eq(i_fields['LI'][0:-1])
+                with m.If(aa):
+                    comb += branch_addr.eq(Cat(Const(0, 2), li))
+                    comb += branch_taken.eq(1)
+
+        comb += self.o.nia_out.data.eq(branch_addr)
+        comb += self.o.nia_out.ok.eq(branch_taken)
 
 
         ###### sticky overflow and context, both pass-through #####
index dbc96b11b0273656d5f781228f11948d924c4080..d259c062ce95a56ae80c71a079669bf09e155840 100644 (file)
@@ -63,8 +63,8 @@ class LogicalTestCase(FHDLTestCase):
         tc = TestCase(prog, initial_regs, initial_sprs, self.test_name)
         test_data.append(tc)
 
-    def test_cmpb(self):
-        lst = ["b 0x1234"]
+    def test_ba(self):
+        lst = ["ba 0x1234"]
         initial_regs = [0] * 32
         self.run_tst_program(Program(lst), initial_regs)
 
@@ -95,11 +95,11 @@ class TestRunner(FHDLTestCase):
         rec = CompALUOpSubset()
 
         pspec = ALUPipeSpec(id_wid=2, op_wid=get_rec_width(rec))
-        m.submodules.alu = alu = BranchBasePipe(pspec)
+        m.submodules.branch = branch = BranchBasePipe(pspec)
 
-        comb += alu.p.data_i.ctx.op.eq_from_execute1(pdecode2.e)
-        comb += alu.p.valid_i.eq(1)
-        comb += alu.n.ready_i.eq(1)
+        comb += branch.p.data_i.ctx.op.eq_from_execute1(pdecode2.e)
+        comb += branch.p.valid_i.eq(1)
+        comb += branch.n.ready_i.eq(1)
         comb += pdecode2.dec.raw_opcode_in.eq(instruction)
         sim = Simulator(m)
 
@@ -127,21 +127,28 @@ class TestRunner(FHDLTestCase):
                     fn_unit = yield pdecode2.e.fn_unit
                     self.assertEqual(fn_unit, Function.BRANCH.value, code)
                     yield 
+                    yield
                     opname = code.split(' ')[0]
+                    prev_nia = simulator.pc.NIA.value
                     yield from simulator.call(opname)
                     index = simulator.pc.CIA.value//4
 
+                    yield from self.assert_outputs(branch, pdecode2,
+                                                   simulator, prev_nia)
+
 
         sim.add_sync_process(process)
         with sim.write_vcd("simulator.vcd", "simulator.gtkw",
                             traces=[]):
             sim.run()
-    def check_extra_alu_outputs(self, alu, dec2, sim):
-        rc = yield dec2.e.rc.data
-        if rc:
-            cr_expected = sim.crl[0].get_range().value
-            cr_actual = yield alu.n.data_o.cr0
-            self.assertEqual(cr_expected, cr_actual)
+
+    def assert_outputs(self, branch, dec2, sim, prev_nia):
+        branch_taken = yield branch.n.data_o.nia_out.ok
+        sim_branch_taken = prev_nia != sim.pc.CIA
+        self.assertEqual(branch_taken, sim_branch_taken)
+        if branch_taken:
+            branch_addr = yield branch.n.data_o.nia_out.data
+            self.assertEqual(branch_addr, sim.pc.CIA.value)
 
 
 if __name__ == "__main__":