Fix a couple of bugs with conditional branch with counter
authorMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 20:01:17 +0000 (16:01 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 20:02:44 +0000 (16:02 -0400)
src/soc/branch/main_stage.py
src/soc/branch/test/test_pipe_caller.py

index 341d141bc20a8d675fabe7a08c445bb855729a3d..ebfe5c893952f8254e5871fbc6cda6d240e98b03 100644 (file)
@@ -77,9 +77,10 @@ class BranchMainStage(PipeModBase):
             comb += self.o.spr.data.eq(ctr)
             comb += self.o.spr.ok.eq(1)
             ctr_eq_zero = Signal(reset_less=True)
-            with m.If(bo[3:4] == 0b00):
+            comb += ctr_eq_zero.eq(ctr == 0)
+            with m.If(bo[3:5] == 0b00):
                 comb += bc_taken.eq(~cr_bit & (ctr_eq_zero == bo[1]))
-            with m.Elif(bo[3:4] == 0b01):
+            with m.Elif(bo[3:5] == 0b01):
                 comb += bc_taken.eq(cr_bit & (ctr_eq_zero == bo[1]))
             with m.Elif(bo[4] == 1):
                 comb += bc_taken.eq(ctr_eq_zero == bo[1])
index 347f146fe7b8ba5704fe24fbaad6d14f42494ddd..493a2bb06eecf1b07a792aeb8b0676d7bce3d9d4 100644 (file)
@@ -84,6 +84,19 @@ class BranchTestCase(FHDLTestCase):
             lst = [f"bc {bo}, {bi}, {bc}"]
             initial_regs = [0] * 32
             self.run_tst_program(Program(lst), initial_cr=cr)
+
+    def test_bc_ctr(self):
+        for i in range(20):
+            bc = random.randrange(-1<<13, (1<<13)-1) * 4
+            bo = random.choice([0, 2, 8, 10, 16, 18])
+            bi = random.randrange(0, 31)
+            cr = random.randrange(0, (1<<32)-1)
+            ctr = random.randint(0, (1<<32)-1)
+            lst = [f"bc {bo}, {bi}, {bc}"]
+            initial_sprs={9: SelectableInt(ctr, 64)}
+            self.run_tst_program(Program(lst),
+                                 initial_sprs=initial_sprs,
+                                 initial_cr=cr)
         
 
     def test_ilang(self):
@@ -146,6 +159,8 @@ class TestRunner(FHDLTestCase):
                     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)
+                    yield branch.p.data_i.spr.eq(simulator.spr['CTR'].value)
+                    yield branch.p.data_i.lr.eq(simulator.spr['LR'].value)
                     print(f"cr0: {simulator.crl[0].get_range()}")
                     yield Settle()
                     fn_unit = yield pdecode2.e.fn_unit