From: Michael Nolan Date: Fri, 15 May 2020 18:01:12 +0000 (-0400) Subject: add branch to absolute address X-Git-Tag: div_pipeline~1187 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=efddc6de86465747b55ff70d50e9d9e074f8bb35;p=soc.git add branch to absolute address --- diff --git a/src/soc/branch/main_stage.py b/src/soc/branch/main_stage.py index e4e522b6..453bab7a 100644 --- a/src/soc/branch/main_stage.py +++ b/src/soc/branch/main_stage.py @@ -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 ##### diff --git a/src/soc/branch/test/test_pipe_caller.py b/src/soc/branch/test/test_pipe_caller.py index dbc96b11..d259c062 100644 --- a/src/soc/branch/test/test_pipe_caller.py +++ b/src/soc/branch/test/test_pipe_caller.py @@ -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__":