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)) )
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.
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
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)
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)