from nmigen import Module, Signal, Cat, Array, Const, Elaboratable, Repl
from nmigen.lib.coding import Decoder
-from nmutil.latch import SRLatch, latchregister
-
from scoreboard.shadow_fn import ShadowFn
self.issue_i = Signal(n_fus, reset_less=True)
self.shadow_i = Array(Signal(shadow_wid, name="sh_i", reset_less=True) \
for f in range(n_fus))
- self.s_fail_i = Signal(shadow_wid, reset_less=True)
- self.s_good_i = Signal(shadow_wid, reset_less=True)
-
+ self.s_fail_i = Array(Signal(shadow_wid, name="fl_i", reset_less=True) \
+ for f in range(n_fus))
+ self.s_good_i = Array(Signal(shadow_wid, name="gd_i", reset_less=True) \
+ for f in range(n_fus))
# outputs
self.go_die_o = Signal(n_fus, reset_less=True)
self.shadown_o = Signal(n_fus, reset_less=True)
setattr(m.submodules, "sh%d" % i, sh)
shadows.append(sh)
# connect shadow/fail/good to all shadows
- m.d.comb += sh.s_fail_i.eq(self.s_fail_i)
- m.d.comb += sh.s_good_i.eq(self.s_good_i)
+ m.d.comb += sh.s_fail_i.eq(self.s_fail_i[i])
+ m.d.comb += sh.s_good_i.eq(self.s_good_i[i])
# this one is the matrix (shadow enables)
m.d.comb += sh.shadow_i.eq(self.shadow_i[i])
def __iter__(self):
yield self.issue_i
yield from self.shadow_i
- yield self.s_fail_i
- yield self.s_good_i
+ yield from self.s_fail_i
+ yield from self.s_good_i
yield self.go_die_o
yield self.shadown_o
def __init__(self, n_fus):
self.n_fus = n_fus
- # inputs
- self.issue_i = Signal(n_fus, reset_less=True)
+ # inputs: record *expected* status
+ self.active_i = Signal(reset_less=True)
self.good_i = Signal(n_fus, reset_less=True)
self.fail_i = Signal(n_fus, reset_less=True)
- self.branch_i = Signal(reset_less=True)
- # outputs
- self.good_o = Signal(n_fus, reset_less=True)
- self.fail_o = Signal(n_fus, reset_less=True)
+ # inputs: status of branch (when result was known)
+ self.br_i = Signal(reset_less=True)
+ self.br_ok_i = Signal(reset_less=True)
+
+ # outputs: true if the *expected* outcome matched the *actual* outcome
+ self.match_f_o = Signal(n_fus, reset_less=True)
+ self.match_g_o = Signal(n_fus, reset_less=True)
def elaborate(self, platform):
m = Module()
+ # registers to record *expected* status
good_r = Signal(self.n_fus)
fail_r = Signal(self.n_fus)
- # sigh, there's a way to do this without if statements, as pure
- # ANDing and ORing...
for i in range(self.n_fus):
- with m.If(self.branch_i):
- with m.If(good_r[i] | fail_r[i]):
- m.d.comb += self.good_o[i].eq(good_r[i] | ~fail_r[i])
- m.d.comb += self.fail_o[i].eq(fail_r[i] | ~good_r[i])
+ with m.If(self.active_i):
+ m.d.sync += good_r[i].eq(good_r[i] | self.good_i[i])
+ m.d.sync += fail_r[i].eq(fail_r[i] | self.fail_i[i])
+ with m.If(self.br_i):
+ with m.If(good_r[i]):
+ # we expected good, return OK that good was EXPECTED
+ m.d.comb += self.match_g_o[i].eq(self.br_ok_i)
+ m.d.comb += self.match_f_o[i].eq(~self.br_ok_i)
+ with m.If(fail_r[i]):
+ # we expected fail, return OK that fail was EXPECTED
+ m.d.comb += self.match_g_o[i].eq(~self.br_ok_i)
+ m.d.comb += self.match_f_o[i].eq(self.br_ok_i)
m.d.sync += good_r[i].eq(0) # might be set if issue set as well
m.d.sync += fail_r[i].eq(0) # might be set if issue set as well
- with m.If(self.issue_i[i]):
- m.d.sync += good_r[i].eq(self.good_i[i])
- m.d.sync += fail_r[i].eq(self.fail_i[i])
return m
def __iter__(self):
- yield self.issue_i
+ yield self.active_i
yield self.good_i
yield self.fail_i
- yield self.branch_i
+ yield self.br_i
+ yield self.br_good_i
+ yield self.br_fail_i
yield self.good_o
yield self.fail_o