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