From 2746dac2811aef7ca9eff9a0bd2429a0af2c97d4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 30 May 2019 00:39:51 +0100 Subject: [PATCH] remove Shadow class, replace with ShadowFn, use multi-bit SRLatch --- src/experiment/score6600.py | 6 +-- src/scoreboard/shadow.py | 84 +------------------------------------ src/scoreboard/shadow_fn.py | 71 ++++++++++++++++++++----------- 3 files changed, 50 insertions(+), 111 deletions(-) diff --git a/src/experiment/score6600.py b/src/experiment/score6600.py index d9144826..9724210e 100644 --- a/src/experiment/score6600.py +++ b/src/experiment/score6600.py @@ -717,11 +717,11 @@ def scoreboard_branch_sim(dut, alusim): if True: insts = [] - #insts.append( (3, 5, 2, 0, (0, 0)) ) + 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_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)) ) diff --git a/src/scoreboard/shadow.py b/src/scoreboard/shadow.py index 034f34fc..12f20893 100644 --- a/src/scoreboard/shadow.py +++ b/src/scoreboard/shadow.py @@ -6,88 +6,6 @@ from nmigen.lib.coding import Decoder from scoreboard.shadow_fn import ShadowFn -class Shadow(Elaboratable): - """ implements shadowing 11.5.1, p55 - - shadowing can be used for branches as well as exceptions (interrupts), - load/store hold (exceptions again), and vector-element predication - (once the predicate is known, which it may not be at instruction issue) - - Inputs - * :shadow_wid: number of shadow/fail/good/go_die sets - - notes: - * when shadow_wid = 0, recover and shadown are Consts (i.e. do nothing) - """ - def __init__(self, shadow_wid=0, syncreset=False): - self.shadow_wid = shadow_wid - self.syncreset = syncreset - - if shadow_wid: - # inputs - self.issue_i = Signal(reset_less=True) - self.reset_i = Signal(reset_less=True) - self.shadow_i = Signal(shadow_wid, reset_less=True) - self.s_fail_i = Signal(shadow_wid, reset_less=True) - self.s_good_i = Signal(shadow_wid, reset_less=True) - # outputs - self.go_die_o = Signal(reset_less=True) - self.shadown_o = Signal(reset_less=True) - else: - # outputs when no shadowing needed - self.shadown_o = Const(1) - self.go_die_o = Const(0) - - def elaborate(self, platform): - m = Module() - s_latches = [] - for i in range(self.shadow_wid): - sh = ShadowFn(self.syncreset) - setattr(m.submodules, "shadow%d" % i, sh) - s_latches.append(sh) - - # shadow / recover (optional: shadow_wid > 0) - if self.shadow_wid: - i_l = [] - d_l = [] - fail_l = [] - good_l = [] - shi_l = [] - sho_l = [] - rec_l = [] - # get list of latch signals. really must be a better way to do this - for l in s_latches: - i_l.append(l.issue_i) - d_l.append(l.reset_i) - shi_l.append(l.shadow_i) - fail_l.append(l.s_fail_i) - good_l.append(l.s_good_i) - sho_l.append(l.shadow_o) - rec_l.append(l.recover_o) - m.d.comb += Cat(*i_l).eq(Repl(self.issue_i, self.shadow_wid)) - m.d.comb += Cat(*d_l).eq(Repl(self.reset_i, self.shadow_wid)) - m.d.comb += Cat(*fail_l).eq(self.s_fail_i) - m.d.comb += Cat(*good_l).eq(self.s_good_i) - m.d.comb += Cat(*shi_l).eq(self.shadow_i) - m.d.comb += self.shadown_o.eq(~(Cat(*sho_l).bool())) - m.d.comb += self.go_die_o.eq(Cat(*rec_l).bool()) - - return m - - def __iter__(self): - if self.shadow_wid: - yield self.reset_i - yield self.issue_i - yield self.shadow_i - yield self.s_fail_i - yield self.s_good_i - yield self.go_die_o - yield self.shadown_o - - def ports(self): - return list(self) - - class ShadowMatrix(Elaboratable): """ Matrix of Shadow Functions. One per FU. @@ -138,7 +56,7 @@ class ShadowMatrix(Elaboratable): m = Module() shadows = [] for i in range(self.n_fus): - sh = Shadow(self.shadow_wid, self.syncreset) + sh = ShadowFn(self.shadow_wid, self.syncreset) setattr(m.submodules, "sh%d" % i, sh) shadows.append(sh) # connect shadow/fail/good to all shadows diff --git a/src/scoreboard/shadow_fn.py b/src/scoreboard/shadow_fn.py index ae87e614..69a56a5c 100644 --- a/src/scoreboard/shadow_fn.py +++ b/src/scoreboard/shadow_fn.py @@ -1,54 +1,75 @@ from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil -from nmigen import Module, Signal, Cat, Elaboratable +from nmigen import Module, Signal, Cat, Repl, Const, Elaboratable from nmutil.latch import SRLatch class ShadowFn(Elaboratable): """ implements shadowing 11.5.1, p55, just the individual shadow function + + shadowing can be used for branches as well as exceptions (interrupts), + load/store hold (exceptions again), and vector-element predication + (once the predicate is known, which it may not be at instruction issue) + + Inputs + * :shadow_wid: number of shadow/fail/good/go_die sets + + notes: + * when shadow_wid = 0, recover and shadown are Consts (i.e. do nothing) """ - def __init__(self, syncreset=False): + def __init__(self, slen, syncreset=False): + self.slen = slen self.syncreset = syncreset - # inputs - self.issue_i = Signal(reset_less=True) - self.shadow_i = Signal(reset_less=True) - self.reset_i = Signal(reset_less=True) - self.s_fail_i = Signal(reset_less=True) - self.s_good_i = Signal(reset_less=True) - - # outputs - self.shadow_o = Signal(reset_less=True) - self.recover_o = Signal(reset_less=True) + if self.slen: + # inputs + self.issue_i = Signal(reset_less=True) + self.shadow_i = Signal(slen, reset_less=True) + self.reset_i = Signal(reset_less=True) + self.s_fail_i = Signal(slen, reset_less=True) + self.s_good_i = Signal(slen, reset_less=True) + + # outputs + self.shadown_o = Signal(reset_less=True) + self.go_die_o = Signal(reset_less=True) + else: + # outputs when no shadowing needed + self.shadown_o = Const(1) + self.go_die_o = Const(0) def elaborate(self, platform): m = Module() - m.submodules.sl = sl = SRLatch(sync=False) + if self.slen == 0: + return + + m.submodules.sl = sl = SRLatch(sync=False, llen=self.slen) - reset_r = Signal() + r_ext = Repl(self.reset_i, self.slen) + reset_r = Signal(self.slen) if self.syncreset: - m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | self.reset_i) + m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | r_ext) else: - m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | self.reset_i) + m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | r_ext) - m.d.comb += sl.s.eq(self.shadow_i & self.issue_i & \ + i_ext = Repl(self.issue_i, self.slen) + m.d.comb += sl.s.eq(self.shadow_i & i_ext & \ ~self.s_good_i & ~reset_r) - m.d.comb += sl.r.eq(self.reset_i | reset_r | self.s_good_i | \ - (self.issue_i & ~self.shadow_i)) - m.d.comb += self.recover_o.eq(sl.qlq & self.s_fail_i) - m.d.comb += self.shadow_o.eq(sl.qlq) + m.d.comb += sl.r.eq(r_ext | reset_r | self.s_good_i | \ + (i_ext & ~self.shadow_i)) + m.d.comb += self.go_die_o.eq((sl.qlq & self.s_fail_i).bool()) + m.d.comb += self.shadown_o.eq(~sl.qlq.bool()) return m def __iter__(self): yield self.issue_i - yield self.s_reset_i + yield self.reset_i yield self.shadow_i yield self.s_fail_i yield self.s_good_i - yield self.shadow_o - yield self.recover_o + yield self.shadown_o + yield self.go_die_o def ports(self): return list(self) @@ -78,7 +99,7 @@ def shadow_fn_unit_sim(dut): def test_shadow_fn_unit(): - dut = ShadowFn() + dut = ShadowFn(4) vl = rtlil.convert(dut, ports=dut.ports()) with open("test_shadow_fn_unit.il", "w") as f: f.write(vl) -- 2.30.2