+def create_random_ops(dut, n_ops, shadowing=False, max_opnums=3):
+ insts = []
+ for i in range(n_ops):
+ src1 = randint(1, dut.n_regs-1)
+ src2 = randint(1, dut.n_regs-1)
+ imm = randint(1, (1<<dut.rwid)-1)
+ dest = randint(1, dut.n_regs-1)
+ op = randint(0, max_opnums)
+ opi = 0 if randint(0, 2) else 1 # set true if random is nonzero
+
+ if shadowing:
+ insts.append((src1, src2, dest, op, opi, imm, (0, 0)))
+ else:
+ insts.append((src1, src2, dest, op, opi, imm))
+ return insts
+
+
+def wait_for_busy_clear(dut):
+ while True:
+ busy_o = yield dut.busy_o
+ if not busy_o:
+ break
+ print ("busy",)
+ yield
+
+def disable_issue(dut):
+ yield dut.aluissue.insn_i.eq(0)
+ yield dut.brissue.insn_i.eq(0)
+
+
+def wait_for_issue(dut, dut_issue):
+ while True:
+ issue_o = yield dut_issue.fn_issue_o
+ if issue_o:
+ yield from disable_issue(dut)
+ yield dut.reg_enable_i.eq(0)
+ break
+ print ("busy",)
+ #yield from print_reg(dut, [1,2,3])
+ yield
+ #yield from print_reg(dut, [1,2,3])
+
+def scoreboard_branch_sim(dut, alusim):
+
+ iseed = 3
+
+ for i in range(1):
+
+ print ("rseed", iseed)
+ seed(iseed)
+ iseed += 1
+
+ yield dut.branch_direction_o.eq(0)
+
+ # set random values in the registers
+ for i in range(1, dut.n_regs):
+ val = 31+i*3
+ val = randint(0, (1<<alusim.rwidth)-1)
+ yield dut.intregs.regs[i].reg.eq(val)
+ alusim.setval(i, val)
+
+ if False:
+ # create some instructions: branches create a tree
+ insts = create_random_ops(dut, 1, True, 1)
+ #insts.append((6, 6, 1, 2, (0, 0)))
+ #insts.append((4, 3, 3, 0, (0, 0)))
+
+ src1 = randint(1, dut.n_regs-1)
+ src2 = randint(1, dut.n_regs-1)
+ #op = randint(4, 7)
+ op = 4 # only BGT at the moment
+
+ branch_ok = create_random_ops(dut, 1, True, 1)
+ branch_fail = create_random_ops(dut, 1, True, 1)
+
+ insts.append((src1, src2, (branch_ok, branch_fail), op, (0, 0)))
+
+ if True:
+ insts = []
+ insts.append( (3, 5, 2, 0, (0, 0)) )
+ branch_ok = []
+ branch_fail = []
+ #branch_ok.append ( (5, 7, 5, 1, (1, 0)) )
+ branch_ok.append( None )
+ branch_fail.append( (1, 1, 2, 0, (0, 1)) )
+ #branch_fail.append( None )
+ insts.append( (6, 4, (branch_ok, branch_fail), 4, (0, 0)) )
+
+ siminsts = deepcopy(insts)
+
+ # issue instruction(s)
+ i = -1
+ instrs = insts
+ branch_direction = 0
+ while instrs:
+ yield
+ yield
+ i += 1
+ branch_direction = yield dut.branch_direction_o # way branch went
+ (src1, src2, dest, op, (shadow_on, shadow_off)) = insts.pop(0)
+ if branch_direction == 1 and shadow_on:
+ print ("skip", i, src1, src2, dest, op, shadow_on, shadow_off)
+ continue # branch was "success" and this is a "failed"... skip
+ if branch_direction == 2 and shadow_off:
+ print ("skip", i, src1, src2, dest, op, shadow_on, shadow_off)
+ continue # branch was "fail" and this is a "success"... skip
+ if branch_direction != 0:
+ shadow_on = 0
+ shadow_off = 0
+ is_branch = op >= 4
+ if is_branch:
+ branch_ok, branch_fail = dest
+ dest = src2
+ # ok zip up the branch success / fail instructions and
+ # drop them into the queue, one marked "to have branch success"
+ # the other to be marked shadow branch "fail".
+ # one out of each of these will be cancelled
+ for ok, fl in zip(branch_ok, branch_fail):
+ if ok:
+ instrs.append((ok[0], ok[1], ok[2], ok[3], (1, 0)))
+ if fl:
+ instrs.append((fl[0], fl[1], fl[2], fl[3], (0, 1)))
+ print ("instr %d: (%d, %d, %d, %d, (%d, %d))" % \
+ (i, src1, src2, dest, op, shadow_on, shadow_off))
+ yield from int_instr(dut, op, src1, src2, dest,
+ shadow_on, shadow_off)
+
+ # wait for all instructions to stop before checking
+ yield
+ yield from wait_for_busy_clear(dut)
+
+ i = -1
+ while siminsts:
+ instr = siminsts.pop(0)
+ if instr is None:
+ continue
+ (src1, src2, dest, op, (shadow_on, shadow_off)) = instr
+ i += 1
+ is_branch = op >= 4
+ if is_branch:
+ branch_ok, branch_fail = dest
+ dest = src2
+ print ("sim %d: (%d, %d, %d, %d, (%d, %d))" % \
+ (i, src1, src2, dest, op, shadow_on, shadow_off))
+ branch_res = alusim.op(op, src1, src2, dest)
+ if is_branch:
+ if branch_res:
+ siminsts += branch_ok
+ else:
+ siminsts += branch_fail
+
+ # check status
+ yield from alusim.check(dut)
+ yield from alusim.dump(dut)
+
+