Add liveness check.
parent
23f503549f
commit
9fde9f9786
@ -0,0 +1,55 @@
|
|||||||
|
from amaranth import *
|
||||||
|
from amaranth.asserts import *
|
||||||
|
|
||||||
|
from power_fv.check import PowerFVCheck
|
||||||
|
from power_fv.check._timer import Timer
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["LivenessCheck"]
|
||||||
|
|
||||||
|
|
||||||
|
class LivenessCheck(PowerFVCheck, name=("liveness",)):
|
||||||
|
"""Liveness check.
|
||||||
|
|
||||||
|
Checks that a core does not hang for the duration of the bounded-model check.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def testbench(self):
|
||||||
|
return LivenessTestbench(self)
|
||||||
|
|
||||||
|
|
||||||
|
class LivenessTestbench(Elaboratable):
|
||||||
|
def __init__(self, check):
|
||||||
|
if not isinstance(check, LivenessCheck):
|
||||||
|
raise TypeError("Check must be an instance of LivenessCheck, not {!r}"
|
||||||
|
.format(check))
|
||||||
|
self.check = check
|
||||||
|
self.name = "liveness_tb"
|
||||||
|
|
||||||
|
def elaborate(self, platform):
|
||||||
|
m = Module()
|
||||||
|
|
||||||
|
m.submodules.t_pre = t_pre = Timer(self.check.skip - 1)
|
||||||
|
m.submodules.t_post = t_post = Timer(self.check.depth - 1)
|
||||||
|
m.submodules.dut = dut = self.check.dut
|
||||||
|
|
||||||
|
curr_order = AnyConst(dut.pfv.order.shape())
|
||||||
|
next_order = curr_order + 1
|
||||||
|
next_retired = Signal()
|
||||||
|
|
||||||
|
with m.If(Rose(t_pre.zero)):
|
||||||
|
m.d.comb += [
|
||||||
|
Assume(dut.pfv.stb),
|
||||||
|
Assume(curr_order == dut.pfv.order),
|
||||||
|
]
|
||||||
|
|
||||||
|
with m.Elif(t_pre.zero):
|
||||||
|
with m.If(dut.pfv.stb & (dut.pfv.order == next_order)):
|
||||||
|
m.d.sync += next_retired.eq(1)
|
||||||
|
|
||||||
|
with m.If(t_post.zero):
|
||||||
|
m.d.comb += Assert(next_retired)
|
||||||
|
|
||||||
|
m.d.comb += Assert(~Past(t_post.zero))
|
||||||
|
|
||||||
|
return m
|
Loading…
Reference in New Issue