From: Luke Kenneth Casson Leighton Date: Thu, 23 May 2019 13:23:32 +0000 (+0100) Subject: add in busy_prev/next signal to work out which unit was activated X-Git-Tag: div_pipeline~1971 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d81c8deca026671d6472a92e3b5e2004d53892f1;p=soc.git add in busy_prev/next signal to work out which unit was activated --- diff --git a/src/experiment/score6600.py b/src/experiment/score6600.py index 60c729ee..b265bf97 100644 --- a/src/experiment/score6600.py +++ b/src/experiment/score6600.py @@ -9,7 +9,7 @@ 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.shadow import ShadowMatrix +from scoreboard.shadow import ShadowMatrix, WaWGrid from compalu import ComputationUnitNoDelay @@ -127,6 +127,8 @@ class FunctionUnits(Elaboratable): self.req_rel_o = Signal(n_int_alus, reset_less=True) self.fn_issue_i = Signal(n_int_alus, reset_less=True) + # Note: FURegs wr_pend_o is also outputted from here, for use in WaWGrid + def elaborate(self, platform): m = Module() @@ -147,6 +149,7 @@ class FunctionUnits(Elaboratable): m.d.comb += intfudeps.rd_pend_i.eq(intregdeps.rd_pend_o) m.d.comb += intfudeps.wr_pend_i.eq(intregdeps.wr_pend_o) + self.wr_pend_o = intregdeps.wr_pend_o # also output for use in WaWGrid m.d.comb += intfudeps.issue_i.eq(self.fn_issue_i) m.d.comb += intfudeps.go_rd_i.eq(self.go_rd_i) @@ -238,6 +241,13 @@ class Scoreboard(Elaboratable): go_rd_rst = Signal(n_int_fus, reset_less=True) go_wr_rst = Signal(n_int_fus, reset_less=True) + # Write-after-Write grid: selects one shadow to enable, based + # on which unit(s) have writes pending and the current instruction + # also needing to write + m.submodules.wawgrid = wawgrid = WaWGrid(n_int_fus, n_int_fus) + busy_prev = Signal(n_int_fus) + busy_curr = Signal(n_int_fus) + #--------- # ok start wiring things together... # "now hear de word of de looord... dem bones dem bones dem dryy bones" @@ -315,6 +325,14 @@ class Scoreboard(Elaboratable): # (instead of e.g. a ring buffer). # XXX TODO + # when written, the shadow can be cancelled (and was good) + m.d.comb += shadows.s_good_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(self.issue_o): # only update busy_prev if instruction issued + m.d.sync += busy_prev.eq(cu.busy_o) + m.d.comb += busy_curr.eq(~busy_prev & cu.busy_o) + #--------- # Connect Register File(s) #--------- diff --git a/src/scoreboard/shadow.py b/src/scoreboard/shadow.py index 95dc4ad2..fd5cb864 100644 --- a/src/scoreboard/shadow.py +++ b/src/scoreboard/shadow.py @@ -1,6 +1,6 @@ from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil -from nmigen import Module, Signal, Cat, Array, Const, Elaboratable +from nmigen import Module, Signal, Cat, Array, Const, Elaboratable, Repl from nmigen.lib.coding import Decoder from nmutil.latch import SRLatch, latchregister @@ -163,6 +163,28 @@ class ShadowMatrix(Elaboratable): return list(self) +class WaWGrid(Elaboratable): + """ An NxM grid-selector which raises a 2D bit selected by N and M + """ + + def __init__(self, n_fus, shadow_wid): + self.n_fus = n_fus + self.shadow_wid = shadow_wid + + self.shadow_i = Signal(shadow_wid, reset_less=True) + self.fu_i = Signal(n_fus, reset_less=True) + + self.waw_o = Array(Signal(shadow_wid, name="waw_o", reset_less=True) \ + for f in range(n_fus)) + + def elaborate(self, platform): + m = Module() + for i in range(self.n_fus): + v = Repl(self.fu_i[i], self.shadow_wid) + m.d.comb += self.waw_o[i].eq(v & self.shadow_i) + return m + + def shadow_sim(dut): yield dut.dest_i.eq(1) yield dut.issue_i.eq(1)