X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fexperiment%2Fscore6600.py;h=456bb3ebfa07378682b2a1f4422deeb6b26d4117;hb=5d9f1eab12603ad0f9ce654b114cde087c199ac0;hp=d1c2dbb5a2b949b0ef457bebba2a78d1482bcd7d;hpb=9de787f48a7d97fde79108c147bac8524062ccae;p=soc.git diff --git a/src/experiment/score6600.py b/src/experiment/score6600.py index d1c2dbb5..456bb3eb 100644 --- a/src/experiment/score6600.py +++ b/src/experiment/score6600.py @@ -3,163 +3,319 @@ from nmigen.cli import verilog, rtlil from nmigen import Module, Const, Signal, Array, Cat, Elaboratable from regfile.regfile import RegFileArray, treereduce -from scoreboard.fn_unit import IntFnUnit, FPFnUnit, LDFnUnit, STFnUnit from scoreboard.fu_fu_matrix import FUFUDepMatrix from scoreboard.fu_reg_matrix import FURegDepMatrix from scoreboard.global_pending import GlobalPending from scoreboard.group_picker import GroupPicker -from scoreboard.issue_unit import IntFPIssueUnit, RegDecode +from scoreboard.issue_unit import IssueUnitGroup, IssueUnitArray, RegDecode +from scoreboard.shadow import ShadowMatrix, BranchSpeculationRecord +from scoreboard.instruction_q import Instruction, InstructionQ from compalu import ComputationUnitNoDelay -from alu_hier import ALU +from alu_hier import ALU, BranchALU from nmutil.latch import SRLatch +from nmutil.nmoperator import eq -from random import randint +from random import randint, seed +from copy import deepcopy +from math import log -class CompUnits(Elaboratable): - def __init__(self, rwid, n_units): +class Memory(Elaboratable): + def __init__(self, regwid, addrw): + self.ddepth = regwid/8 + depth = (1<>self.ddepth] + + def st(self, addr, data): + self.mem[addr>>self.ddepth] = data & ((1<> (src2 & maxbits) + elif op == IBGT: + val = int(src1 > src2) + elif op == IBLT: + val = int(src1 < src2) + elif op == IBEQ: + val = int(src1 == src2) + elif op == IBNE: + val = int(src1 != src2) + val &= maxbits + self.setval(dest, val) + return val def setval(self, dest, val): + print ("sim setval", dest, hex(val)) self.regs[dest] = val def dump(self, dut): @@ -394,14 +762,50 @@ class RegSim: yield from self.dump(dut) assert False -def int_instr(dut, alusim, op, src1, src2, dest): - for i in range(len(dut.int_insn_i)): - yield dut.int_insn_i[i].eq(0) +def instr_q(dut, op, op_imm, imm, src1, src2, dest, + branch_success, branch_fail): + instrs = [{'oper_i': op, 'dest_i': dest, 'imm_i': imm, 'opim_i': op_imm, + 'src1_i': src1, 'src2_i': src2}] + + sendlen = 1 + for idx in range(sendlen): + yield from eq(dut.data_i[idx], instrs[idx]) + di = yield dut.data_i[idx] + print ("senddata %d %x" % (idx, di)) + yield dut.p_add_i.eq(sendlen) + yield + o_p_ready = yield dut.p_ready_o + while not o_p_ready: + yield + o_p_ready = yield dut.p_ready_o + + yield dut.p_add_i.eq(0) + + +def int_instr(dut, op, imm, src1, src2, dest, branch_success, branch_fail): + yield from disable_issue(dut) yield dut.int_dest_i.eq(dest) yield dut.int_src1_i.eq(src1) yield dut.int_src2_i.eq(src2) - yield dut.int_insn_i[op].eq(1) - alusim.op(op, src1, src2, dest) + if (op & (0x3<<2)) != 0: # branch + yield dut.brissue.insn_i.eq(1) + yield dut.br_oper_i.eq(Const(op & 0x3, 2)) + yield dut.br_imm_i.eq(imm) + dut_issue = dut.brissue + else: + yield dut.aluissue.insn_i.eq(1) + yield dut.alu_oper_i.eq(Const(op & 0x3, 2)) + yield dut.alu_imm_i.eq(imm) + dut_issue = dut.aluissue + yield dut.reg_enable_i.eq(1) + + # these indicate that the instruction is to be made shadow-dependent on + # (either) branch success or branch fail + yield dut.branch_fail_i.eq(branch_fail) + yield dut.branch_succ_i.eq(branch_success) + + yield + yield from wait_for_issue(dut, dut_issue) def print_reg(dut, rnums): @@ -413,89 +817,310 @@ def print_reg(dut, rnums): print ("reg %s: %s" % (','.join(rnums), ','.join(rs))) -def scoreboard_sim(dut, alusim): - yield dut.int_store_i.eq(0) +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<= 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) - for i in range(5): - src1 = randint(1, dut.n_regs-1) - src2 = randint(1, dut.n_regs-1) + +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<