X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fexperiment%2Fscore6600.py;h=ed953e8b71a3b80ff82fde4c93a115d8fcd39303;hb=9160489ce48a008af3e07fdc81d458a0b366f997;hp=eca0ae22486490ff0e3a8713edf7a4d170c27a5d;hpb=298b4165b1a7eafff5c5b93bc926f6736899c8be;p=soc.git diff --git a/src/experiment/score6600.py b/src/experiment/score6600.py index eca0ae22..ed953e8b 100644 --- a/src/experiment/score6600.py +++ b/src/experiment/score6600.py @@ -1,38 +1,110 @@ from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil -from nmigen import Module, Const, Signal, Array, Cat, Elaboratable +from nmigen import Module, Const, Signal, Array, Cat, Elaboratable, Memory from regfile.regfile import RegFileArray, treereduce 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 scoreboard.memfu import MemFunctionUnits from compalu import ComputationUnitNoDelay +from compldst import LDSTCompUnit from alu_hier import ALU, BranchALU from nmutil.latch import SRLatch +from nmutil.nmoperator import eq from random import randint, seed from copy import deepcopy +from math import log -class CompUnits(Elaboratable): +class TestMemory(Elaboratable): + def __init__(self, regwid, addrw): + self.ddepth = 1 # regwid //8 + depth = (1<>self.ddepth] + + def st(self, addr, data): + self.mem[addr>>self.ddepth] = data & ((1< Mem FUs + comb += memfus.addr_we_i.eq(cul.adr_rel_o) # Match enable on adr rel + + comb += memfus.addrs_i[0].eq(cul.units[0].data_o) + comb += memfus.addrs_i[1].eq(cul.units[1].data_o) + + #comb += cu.go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) + #comb += cu.go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) + #comb += cu.issue_i[0:n_intfus].eq(fn_issue_o[0:n_intfus]) + #--------- # merge shadow matrices outputs #--------- - + # these are explained in ShadowMatrix docstring, and are to be # connected to the FUReg and FUFU Matrices, to get them to reset - anydie = Signal(n_int_fus, reset_less=True) - allshadown = Signal(n_int_fus, reset_less=True) - shreset = Signal(n_int_fus, reset_less=True) + anydie = Signal(n_intfus, reset_less=True) + allshadown = Signal(n_intfus, reset_less=True) + shreset = Signal(n_intfus, reset_less=True) comb += allshadown.eq(shadows.shadown_o & bshadow.shadown_o) comb += anydie.eq(shadows.go_die_o | bshadow.go_die_o) comb += shreset.eq(bspec.match_g_o | bspec.match_f_o) @@ -343,31 +570,32 @@ class Scoreboard(Elaboratable): go_wr_i = intfus.go_wr_i go_die_i = intfus.go_die_i # NOTE: connect to the shadowed versions so that they can "die" (reset) - comb += go_rd_i[0:n_int_fus].eq(go_rd_o[0:n_int_fus]) # rd - comb += go_wr_i[0:n_int_fus].eq(go_wr_o[0:n_int_fus]) # wr - comb += go_die_i[0:n_int_fus].eq(anydie[0:n_int_fus]) # die + comb += go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) # rd + comb += go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) # wr + comb += go_die_i[0:n_intfus].eq(anydie[0:n_intfus]) # die # Connect Picker #--------- - comb += intpick1.rd_rel_i[0:n_int_fus].eq(cu.rd_rel_o[0:n_int_fus]) - comb += intpick1.req_rel_i[0:n_int_fus].eq(cu.req_rel_o[0:n_int_fus]) + comb += intpick1.rd_rel_i[0:n_intfus].eq(cu.rd_rel_o[0:n_intfus]) + comb += intpick1.req_rel_i[0:n_intfus].eq(cu.req_rel_o[0:n_intfus]) int_rd_o = intfus.readable_o int_wr_o = intfus.writable_o - comb += intpick1.readable_i[0:n_int_fus].eq(int_rd_o[0:n_int_fus]) - comb += intpick1.writable_i[0:n_int_fus].eq(int_wr_o[0:n_int_fus]) + comb += intpick1.readable_i[0:n_intfus].eq(int_rd_o[0:n_intfus]) + comb += intpick1.writable_i[0:n_intfus].eq(int_wr_o[0:n_intfus]) #--------- # Shadow Matrix #--------- comb += shadows.issue_i.eq(fn_issue_o) - comb += shadows.reset_i[0:n_int_fus].eq(shreset[0:n_int_fus]) + #comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus]) + comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus]) #--------- # NOTE; this setup is for the instruction order preservation... # connect shadows / go_dies to Computation Units - comb += cu.shadown_i[0:n_int_fus].eq(allshadown) - comb += cu.go_die_i[0:n_int_fus].eq(anydie) + comb += cu.shadown_i[0:n_intfus].eq(allshadown) + comb += cu.go_die_i[0:n_intfus].eq(anydie) # ok connect first n_int_fu shadows to busy lines, to create an # instruction-order linked-list-like arrangement, using a bit-matrix @@ -375,31 +603,30 @@ class Scoreboard(Elaboratable): # XXX TODO # when written, the shadow can be cancelled (and was good) - for i in range(n_int_fus): - comb += shadows.s_good_i[i][0:n_int_fus].eq(go_wr_o[0:n_int_fus]) - - # work out the current-activated busy unit (by recording the old one) - with m.If(fn_issue_o): # only update prev bit if instruction issued - sync += fn_issue_prev.eq(fn_issue_o) + for i in range(n_intfus): + comb += shadows.s_good_i[i][0:n_intfus].eq(go_wr_o[0:n_intfus]) # *previous* instruction shadows *current* instruction, and, obviously, # if the previous is completed (!busy) don't cast the shadow! - comb += prev_shadow.eq(~fn_issue_o & fn_issue_prev & cu.busy_o) - for i in range(n_int_fus): - comb += shadows.shadow_i[i][0:n_int_fus].eq(prev_shadow) + comb += prev_shadow.eq(~fn_issue_o & cu.busy_o) + for i in range(n_intfus): + comb += shadows.shadow_i[i][0:n_intfus].eq(prev_shadow) #--------- # ... and this is for branch speculation. it uses the extra bit - # tacked onto the ShadowMatrix (hence shadow_wid=n_int_fus+1) + # tacked onto the ShadowMatrix (hence shadow_wid=n_intfus+1) # only needs to set shadow_i, s_fail_i and s_good_i # issue captures shadow_i (if enabled) - comb += bshadow.issue_i.eq(fn_issue_o) - comb += bshadow.reset_i[0:n_int_fus].eq(shreset[0:n_int_fus]) + comb += bshadow.reset_i[0:n_intfus].eq(shreset[0:n_intfus]) + + bactive = Signal(reset_less=True) + comb += bactive.eq((bspec.active_i | br1.issue_i) & ~br1.go_wr_i) # instruction being issued (fn_issue_o) has a shadow cast by the branch - with m.If(self.branch_succ_i | self.branch_fail_i): - for i in range(n_int_fus): + with m.If(bactive & (self.branch_succ_i | self.branch_fail_i)): + comb += bshadow.issue_i.eq(fn_issue_o) + for i in range(n_intfus): with m.If(fn_issue_o & (Const(1<= 4 if is_branch: branch_ok, branch_fail = dest @@ -633,28 +1049,32 @@ def scoreboard_branch_sim(dut, alusim): # 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): - instrs.append((ok[0], ok[1], ok[2], ok[3], (1, 0))) - instrs.append((fl[0], fl[1], fl[2], fl[3], (0, 1))) + 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) - yield - yield from wait_for_issue(dut) - branch_direction = yield dut.branch_direction_o # way branch went # wait for all instructions to stop before checking yield yield from wait_for_busy_clear(dut) i = -1 - for (src1, src2, dest, op, (shadow_on, shadow_off)) in siminsts: + 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)" % (i, src1, src2, dest, op)) + 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: @@ -669,25 +1089,45 @@ def scoreboard_branch_sim(dut, alusim): def scoreboard_sim(dut, alusim): - yield dut.int_store_i.eq(1) + seed(0) for i in range(1): # set random values in the registers for i in range(1, dut.n_regs): - val = 31+i*3 val = randint(0, (1<