Begin implementing conditional branch
authorMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 19:04:22 +0000 (15:04 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 19:06:56 +0000 (15:06 -0400)
src/soc/branch/main_stage.py
src/soc/branch/test/test_pipe_caller.py

index 9bb4b2b5238cc16e9b9673a27f1976926970e240..4e98aff25dac44ea578c5d9310e28dde78df28c4 100644 (file)
@@ -64,8 +64,15 @@ class BranchMainStage(PipeModBase):
         bi = Signal(b_fields['BI'][0:-1].shape())
         comb += bi.eq(b_fields['BI'][0:-1])
 
+        # The bit of CR selected by BI
         cr_bit = Signal(reset_less=True)
-        comb += cr_bit.eq((self.i.cr & (1<<bi)) != 0)
+        comb += cr_bit.eq((self.i.cr & (1<<(31-bi))) != 0)
+
+        # Whether the conditional branch should be taken
+        bc_taken = Signal(reset_less=True)
+        comb += bc_taken.eq(0)
+        with m.If(bo[2]):
+            comb += bc_taken.eq((cr_bit == bo[3]) | bo[4])
 
             
 
@@ -79,7 +86,15 @@ class BranchMainStage(PipeModBase):
                         Repl(li_sgn, 64-(li.width + 2))))
                 comb += branch_taken.eq(1)
             with m.Case(InternalOp.OP_BC):
-                pass
+                bd = Signal(b_fields['BD'][0:-1].shape())
+                comb += bd.eq(b_fields['BD'][0:-1])
+                bd_sgn = bd[-1]
+
+                comb += branch_imm_addr.eq(
+                    Cat(Const(0, 2), bd,
+                        Repl(bd_sgn, 64-(bd.width + 2))))
+                comb += branch_taken.eq(bc_taken)
+
 
         comb += self.o.nia_out.data.eq(branch_addr)
         comb += self.o.nia_out.ok.eq(branch_taken)
index dacc50d994c03d443a4384a8ce258773f1321d8b..347f146fe7b8ba5704fe24fbaad6d14f42494ddd 100644 (file)
@@ -75,10 +75,15 @@ class BranchTestCase(FHDLTestCase):
             initial_regs = [0] * 32
             self.run_tst_program(Program(lst), initial_regs)
 
-    @unittest.skip("broken")
-    def test_bc(self):
-        lst = ["bc 12, 2, 0x1234"]
-        self.run_tst_program(Program(lst), initial_cr=0xffffffff)
+    def test_bc_cr(self):
+        for i in range(20):
+            bc = random.randrange(-1<<13, (1<<13)-1) * 4
+            bo = random.choice([0b01100, 0b00100, 0b10100])
+            bi = random.randrange(0, 31)
+            cr = random.randrange(0, (1<<32)-1)
+            lst = [f"bc {bo}, {bi}, {bc}"]
+            initial_regs = [0] * 32
+            self.run_tst_program(Program(lst), initial_cr=cr)
         
 
     def test_ilang(self):
@@ -140,6 +145,8 @@ class TestRunner(FHDLTestCase):
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
                     yield branch.p.data_i.cia.eq(simulator.pc.CIA.value)
+                    yield branch.p.data_i.cr.eq(simulator.cr.get_range().value)
+                    print(f"cr0: {simulator.crl[0].get_range()}")
                     yield Settle()
                     fn_unit = yield pdecode2.e.fn_unit
                     #self.assertEqual(fn_unit, Function.BRANCH.value, code)