+
+ 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)
+
+
+def scoreboard_sim(dut, alusim):
+
+ seed(0)
+
+ for i in range(50):
+
+ # set random values in the registers
+ for i in range(1, dut.n_regs):
+ val = randint(0, (1<<alusim.rwidth)-1)
+ #val = 31+i*3
+ #val = i
+ yield dut.intregs.regs[i].reg.eq(val)
+ alusim.setval(i, val)
+
+ # create some instructions (some random, some regression tests)
+ instrs = []
+ if True:
+ instrs = create_random_ops(dut, 15, True, 4)
+
+ if False:
+ instrs.append( (1, 2, 2, 1, 1, 20, (0, 0)) )
+
+ if False:
+ instrs.append( (7, 3, 2, 4, (0, 0)) )
+ instrs.append( (7, 6, 6, 2, (0, 0)) )
+ instrs.append( (1, 7, 2, 2, (0, 0)) )
+
+ if False:
+ instrs.append((2, 3, 3, 0, 0, 0, (0, 0)))
+ instrs.append((5, 3, 3, 1, 0, 0, (0, 0)))
+ instrs.append((3, 5, 5, 2, 0, 0, (0, 0)))
+ instrs.append((5, 3, 3, 3, 0, 0, (0, 0)))
+ instrs.append((3, 5, 5, 0, 0, 0, (0, 0)))
+
+ if False:
+ instrs.append( (3, 3, 4, 0, 0, 13979, (0, 0)))
+ instrs.append( (6, 4, 1, 2, 0, 40976, (0, 0)))
+ instrs.append( (1, 4, 7, 4, 1, 23652, (0, 0)))
+
+ if False:
+ instrs.append((5, 6, 2, 1))
+ instrs.append((2, 2, 4, 0))
+ #instrs.append((2, 2, 3, 1))
+
+ if False:
+ instrs.append((2, 1, 2, 3))
+
+ if False:
+ instrs.append((2, 6, 2, 1))
+ instrs.append((2, 1, 2, 0))
+
+ if False:
+ instrs.append((1, 2, 7, 2))
+ instrs.append((7, 1, 5, 0))
+ instrs.append((4, 4, 1, 1))
+
+ if False:
+ instrs.append((5, 6, 2, 2))
+ instrs.append((1, 1, 4, 1))
+ instrs.append((6, 5, 3, 0))
+
+ if False:
+ # Write-after-Write Hazard
+ instrs.append( (3, 6, 7, 2) )
+ instrs.append( (4, 4, 7, 1) )
+
+ if False:
+ # self-read/write-after-write followed by Read-after-Write
+ instrs.append((1, 1, 1, 1))
+ instrs.append((1, 5, 3, 0))
+
+ if False:
+ # Read-after-Write followed by self-read-after-write
+ instrs.append((5, 6, 1, 2))
+ instrs.append((1, 1, 1, 1))
+
+ if False:
+ # self-read-write sandwich
+ instrs.append((5, 6, 1, 2))
+ instrs.append((1, 1, 1, 1))
+ instrs.append((1, 5, 3, 0))
+
+ if False:
+ # very weird failure
+ instrs.append( (5, 2, 5, 2) )
+ instrs.append( (2, 6, 3, 0) )
+ instrs.append( (4, 2, 2, 1) )
+
+ if False:
+ v1 = 4
+ yield dut.intregs.regs[5].reg.eq(v1)
+ alusim.setval(5, v1)
+ yield dut.intregs.regs[3].reg.eq(5)
+ alusim.setval(3, 5)
+ instrs.append((5, 3, 3, 4, (0, 0)))
+ instrs.append((4, 2, 1, 2, (0, 1)))
+
+ if False:
+ v1 = 6
+ yield dut.intregs.regs[5].reg.eq(v1)
+ alusim.setval(5, v1)
+ yield dut.intregs.regs[3].reg.eq(5)
+ alusim.setval(3, 5)
+ instrs.append((5, 3, 3, 4, (0, 0)))
+ instrs.append((4, 2, 1, 2, (1, 0)))
+
+ if False:
+ instrs.append( (4, 3, 5, 1, 0, (0, 0)) )
+ instrs.append( (5, 2, 3, 1, 0, (0, 0)) )
+ instrs.append( (7, 1, 5, 2, 0, (0, 0)) )
+ instrs.append( (5, 6, 6, 4, 0, (0, 0)) )
+ instrs.append( (7, 5, 2, 2, 0, (1, 0)) )
+ instrs.append( (1, 7, 5, 0, 0, (0, 1)) )
+ instrs.append( (1, 6, 1, 2, 0, (1, 0)) )
+ instrs.append( (1, 6, 7, 3, 0, (0, 0)) )
+ instrs.append( (6, 7, 7, 0, 0, (0, 0)) )
+
+ # issue instruction(s), wait for issue to be free before proceeding
+ for i, instr in enumerate(instrs):
+ src1, src2, dest, op, opi, imm, (br_ok, br_fail) = instr
+
+ print ("instr %d: (%d, %d, %d, %d, %d, %d)" % \
+ (i, src1, src2, dest, op, opi, imm))
+ alusim.op(op, opi, imm, src1, src2, dest)
+ yield from instr_q(dut, op, opi, imm, src1, src2, dest,
+ br_ok, br_fail)
+
+ # wait for all instructions to stop before checking