from soc.decoder.power_fieldsn import SignalBitRange
-def array_of(count, bitwidth):
- res = []
- for i in range(count):
- res.append(Signal(bitwidth, reset_less=True))
- return res
-
-
class BranchMainStage(PipeModBase):
def __init__(self, pspec):
super().__init__(pspec, "main")
aa = Signal(i_fields['AA'][0:-1].shape())
comb += aa.eq(i_fields['AA'][0:-1])
- branch_imm_addr = Signal(64, reset_less=True)
- branch_addr = Signal(64, reset_less=True)
- branch_taken = Signal(reset_less=True)
- comb += branch_taken.eq(0)
+ br_imm_addr = Signal(64, reset_less=True)
+ br_addr = Signal(64, reset_less=True)
+ br_taken = Signal(reset_less=True)
+ comb += br_taken.eq(0)
# Handle absolute or relative branches
with m.If(aa):
- comb += branch_addr.eq(branch_imm_addr)
+ comb += br_addr.eq(br_imm_addr)
with m.Else():
- comb += branch_addr.eq(branch_imm_addr + self.i.cia)
+ comb += br_addr.eq(br_imm_addr + self.i.cia)
# handle conditional branches (BO and BI are same for BC and
with m.If(bo[2]):
comb += bc_taken.eq((cr_bit == bo[3]) | bo[4])
-
+ ######## main switch statement ########
with m.Switch(op.insn_type):
with m.Case(InternalOp.OP_B):
li = Signal(i_fields['LI'][0:-1].shape())
comb += li.eq(i_fields['LI'][0:-1])
li_sgn = li[-1]
- comb += branch_imm_addr.eq(
+ comb += br_imm_addr.eq(
Cat(Const(0, 2), li,
Repl(li_sgn, 64-(li.width + 2))))
- comb += branch_taken.eq(1)
+ comb += br_taken.eq(1)
with m.Case(InternalOp.OP_BC):
bd = Signal(b_fields['BD'][0:-1].shape())
comb += bd.eq(b_fields['BD'][0:-1])
comb += branch_taken.eq(bc_taken)
- comb += self.o.nia_out.data.eq(branch_addr)
- comb += self.o.nia_out.ok.eq(branch_taken)
+ comb += self.o.nia_out.data.eq(br_addr)
+ comb += self.o.nia_out.ok.eq(br_taken)
with m.If(lk):
comb += self.o.lr.data.eq(self.i.cia + 4)
- comb += self.o.lr.ok.eq(1)
- with m.Else():
- comb += self.o.lr.ok.eq(0)
-
- ###### sticky overflow and context, both pass-through #####
+ ###### link register and context #####
comb += self.o.ctx.eq(self.i.ctx)
+ comb += self.o.lr.ok.eq(lk)
return m