checks.unique: add check.
							parent
							
								
									7114ed807e
								
							
						
					
					
						commit
						fc9feb58cb
					
				@ -0,0 +1 @@
 | 
			
		||||
from .unique import *
 | 
			
		||||
@ -0,0 +1,66 @@
 | 
			
		||||
from amaranth import *
 | 
			
		||||
from amaranth.asserts import *
 | 
			
		||||
 | 
			
		||||
from .. import pfv
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = ["UniquenessCheck", "UniquenessCover"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UniquenessCheck(Elaboratable):
 | 
			
		||||
    """Uniqueness check.
 | 
			
		||||
 | 
			
		||||
    Check that the core cannot retire two instructions with the same `pfv.order` identifier.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.pre  = Signal()
 | 
			
		||||
        self.post = Signal()
 | 
			
		||||
        self.pfv  = pfv.Interface()
 | 
			
		||||
 | 
			
		||||
    def elaborate(self, platform):
 | 
			
		||||
        m = Module()
 | 
			
		||||
 | 
			
		||||
        spec_order = AnyConst(self.pfv.order.shape())
 | 
			
		||||
        duplicate  = Signal()
 | 
			
		||||
 | 
			
		||||
        with m.If(self.pre):
 | 
			
		||||
            m.d.sync += [
 | 
			
		||||
                Assume(self.pfv.stb),
 | 
			
		||||
                Assume(spec_order == self.pfv.order),
 | 
			
		||||
                Assume(~duplicate),
 | 
			
		||||
            ]
 | 
			
		||||
        with m.Elif(self.pfv.stb & (self.pfv.order == spec_order)):
 | 
			
		||||
            m.d.sync += duplicate.eq(1)
 | 
			
		||||
 | 
			
		||||
        with m.If(self.post):
 | 
			
		||||
            m.d.sync += Assert(~duplicate)
 | 
			
		||||
 | 
			
		||||
        return m
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UniquenessCover(Elaboratable):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.pre  = Signal()
 | 
			
		||||
        self.post = Signal()
 | 
			
		||||
        self.pfv  = pfv.Interface()
 | 
			
		||||
 | 
			
		||||
    def elaborate(self, platform):
 | 
			
		||||
        m = Module()
 | 
			
		||||
 | 
			
		||||
        insn_count = Signal(range(4))
 | 
			
		||||
 | 
			
		||||
        with m.If(self.pfv.stb):
 | 
			
		||||
            m.d.sync += insn_count.eq(insn_count + 1)
 | 
			
		||||
 | 
			
		||||
        cover_1 = Signal()
 | 
			
		||||
        cover_2 = Signal()
 | 
			
		||||
 | 
			
		||||
        m.d.comb += [
 | 
			
		||||
            cover_1.eq(insn_count == 1),
 | 
			
		||||
            cover_2.eq(insn_count == 2),
 | 
			
		||||
 | 
			
		||||
            Cover(cover_1),
 | 
			
		||||
            Cover(cover_2),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        return m
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue