From: Michael Nolan Date: Fri, 15 May 2020 18:20:14 +0000 (-0400) Subject: Implement relative branches, add explicit NIA input to pipe_data X-Git-Tag: div_pipeline~1186 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0c76cb510f9d06ff34ddf60f6e649dbfcd0b5b12;p=soc.git Implement relative branches, add explicit NIA input to pipe_data --- diff --git a/src/soc/alu/alu_input_record.py b/src/soc/alu/alu_input_record.py index 2c3dcc48..41a40ebf 100644 --- a/src/soc/alu/alu_input_record.py +++ b/src/soc/alu/alu_input_record.py @@ -13,7 +13,6 @@ class CompALUOpSubset(Record): def __init__(self, name=None): layout = (('insn_type', InternalOp), ('fn_unit', Function), - ('nia', 64), ('imm_data', Layout((("imm", 64), ("imm_ok", 1)))), #'cr = Signal(32, reset_less=True) # NO: this is from the CR SPR #'xerc = XerBits() # NO: this is from the XER SPR @@ -38,7 +37,6 @@ class CompALUOpSubset(Record): # grrr. Record does not have kwargs self.insn_type.reset_less = True self.fn_unit.reset_less = True - self.nia.reset_less = True #self.cr = Signal(32, reset_less = True #self.xerc = XerBits( self.lk.reset_less = True @@ -65,7 +63,6 @@ class CompALUOpSubset(Record): def ports(self): return [self.insn_type, - self.nia, #self.cr, #self.xerc, self.lk, diff --git a/src/soc/branch/main_stage.py b/src/soc/branch/main_stage.py index 453bab7a..02731da6 100644 --- a/src/soc/branch/main_stage.py +++ b/src/soc/branch/main_stage.py @@ -59,6 +59,9 @@ class BranchMainStage(PipeModBase): with m.If(aa): comb += branch_addr.eq(Cat(Const(0, 2), li)) comb += branch_taken.eq(1) + with m.Else(): + comb += branch_addr.eq(Cat(Const(0, 2), li) + self.i.nia) + comb += branch_taken.eq(1) comb += self.o.nia_out.data.eq(branch_addr) comb += self.o.nia_out.ok.eq(branch_taken) diff --git a/src/soc/branch/pipe_data.py b/src/soc/branch/pipe_data.py index 26a4aae4..2b3f7c4f 100644 --- a/src/soc/branch/pipe_data.py +++ b/src/soc/branch/pipe_data.py @@ -25,18 +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) - # NIA not needed, it's already part of ctx + self.nia = Signal(64, reset_less=True) def __iter__(self): yield from super().__iter__() yield self.lr yield self.spr yield self.cr + yield self.nia 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.cr.eq(i.cr), self.nia.eq(i.nia)] class BranchOutputData(IntegerData): diff --git a/src/soc/branch/test/test_pipe_caller.py b/src/soc/branch/test/test_pipe_caller.py index d259c062..4f68c56b 100644 --- a/src/soc/branch/test/test_pipe_caller.py +++ b/src/soc/branch/test/test_pipe_caller.py @@ -55,7 +55,7 @@ def get_rec_width(rec): test_data = [] -class LogicalTestCase(FHDLTestCase): +class BranchTestCase(FHDLTestCase): def __init__(self, name): super().__init__(name) self.test_name = name @@ -68,6 +68,11 @@ class LogicalTestCase(FHDLTestCase): initial_regs = [0] * 32 self.run_tst_program(Program(lst), initial_regs) + def test_b(self): + lst = ["b 0x1234"] + initial_regs = [0] * 32 + self.run_tst_program(Program(lst), initial_regs) + def test_ilang(self): rec = CompALUOpSubset() @@ -110,11 +115,14 @@ class TestRunner(FHDLTestCase): program = test.program self.subTest(test.name) simulator = ISA(pdecode2, test.regs, test.sprs) + initial_cia = 0x2000 + simulator.set_pc(initial_cia) gen = program.generate_instructions() instructions = list(zip(gen, program.assembly.splitlines())) - index = simulator.pc.CIA.value//4 + index = (simulator.pc.CIA.value - initial_cia)//4 while index < len(instructions): + print(index) ins, code = instructions[index] print("0x{:X}".format(ins & 0xffffffff)) @@ -123,15 +131,16 @@ 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 Settle() fn_unit = yield pdecode2.e.fn_unit - self.assertEqual(fn_unit, Function.BRANCH.value, code) + #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 + index = (simulator.pc.CIA.value - initial_cia)//4 yield from self.assert_outputs(branch, pdecode2, simulator, prev_nia) diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index b521108b..53b29c09 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -260,6 +260,10 @@ class ISACaller: SO = SelectableInt(0, 1) cr_field = selectconcat(negative, positive, zero, SO) self.crl[0].eq(cr_field) + + def set_pc(self, pc_val): + self.namespace['NIA'] = SelectableInt(pc_val, 64) + self.pc.update(self.namespace) def call(self, name):