Refactor to facilitate integration with CLIs and config files.
* Checks are now split in two modules: checks.cons for consistency checks, checks.insn for instructions. * Checks are derived from PowerFVCheck and have a shorthand (e.g. "insn_b"). PowerFVCheck holds a mapping between its subclasses and their shorthands. * Instruction checks definitions have been simplified to one-liners, and grouped into a single file. * A Trigger class has been added to define testbench triggers.main
							parent
							
								
									5c097b9474
								
							
						
					
					
						commit
						9ea58a47a9
					
				| @ -1,5 +1,12 @@ | ||||
| from .cr     import * | ||||
| from .gpr    import * | ||||
| from .ia_fwd import * | ||||
| from .spr    import * | ||||
| from .unique import * | ||||
| class PowerFVCheck: | ||||
|     registry = {} | ||||
|     name     = None | ||||
|  | ||||
|     def __init_subclass__(cls, name): | ||||
|         if name in cls.registry: | ||||
|             raise ValueError("Check name {!r} is already registered".format(name)) | ||||
|         cls.registry[name] = cls | ||||
|         cls.name = name | ||||
|  | ||||
|     def get_testbench(self, dut, *args, **kwargs): | ||||
|         raise NotImplementedError | ||||
|  | ||||
| @ -0,0 +1,2 @@ | ||||
| from .cons.all import * | ||||
| from .insn.all import * | ||||
| @ -0,0 +1,5 @@ | ||||
| from .unique import * | ||||
| from .ia_fwd import * | ||||
| from .gpr    import * | ||||
| from .cr     import * | ||||
| from .spr    import * | ||||
| @ -0,0 +1,49 @@ | ||||
| from amaranth import * | ||||
| from amaranth.asserts import * | ||||
|  | ||||
| from .. import PowerFVCheck | ||||
| from ... import pfv, tb | ||||
|  | ||||
|  | ||||
| __all__ = ["UniquenessSpec", "UniquenessCheck"] | ||||
|  | ||||
|  | ||||
| class UniquenessSpec(Elaboratable): | ||||
|     """Uniqueness specification. | ||||
|  | ||||
|     A core cannot retire two instructions that share the same `pfv.order` identifier. | ||||
|     """ | ||||
|     def __init__(self, pre, post): | ||||
|         self.pfv  = pfv.Interface() | ||||
|         self.pre  = tb.Trigger(cycle=pre) | ||||
|         self.post = tb.Trigger(cycle=post) | ||||
|  | ||||
|     def triggers(self): | ||||
|         yield from (self.pre, self.post) | ||||
|  | ||||
|     def elaborate(self, platform): | ||||
|         m = Module() | ||||
|  | ||||
|         spec_order = AnyConst(self.pfv.order.shape()) | ||||
|         duplicate  = Signal() | ||||
|  | ||||
|         with m.If(self.pre.stb): | ||||
|             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.stb): | ||||
|             m.d.sync += Assert(~duplicate) | ||||
|  | ||||
|         return m | ||||
|  | ||||
|  | ||||
| class UniquenessCheck(PowerFVCheck, name="cons_unique"): | ||||
|     def get_testbench(self, dut, pre, post): | ||||
|         tb_spec = UniquenessSpec(pre, post) | ||||
|         tb_top  = tb.Testbench(tb_spec, dut) | ||||
|         return tb_top | ||||
| @ -0,0 +1,20 @@ | ||||
| from . import _fmt | ||||
|  | ||||
| # Branches | ||||
|  | ||||
| class B      (_fmt.Instruction_I, po=18, aa=0, lk=0): pass | ||||
| class BA     (_fmt.Instruction_I, po=18, aa=1, lk=0): pass | ||||
| class BL     (_fmt.Instruction_I, po=18, aa=0, lk=1): pass | ||||
| class BLA    (_fmt.Instruction_I, po=18, aa=1, lk=1): pass | ||||
|  | ||||
| class BC     (_fmt.Instruction_B, po=16, aa=0, lk=0): pass | ||||
| class BCA    (_fmt.Instruction_B, po=16, aa=1, lk=0): pass | ||||
| class BCL    (_fmt.Instruction_B, po=16, aa=0, lk=1): pass | ||||
| class BCLA   (_fmt.Instruction_B, po=16, aa=1, lk=1): pass | ||||
|  | ||||
| class BCLR   (_fmt.Instruction_XL_bc, po=19, xo= 16, lk=0): pass | ||||
| class BCLRL  (_fmt.Instruction_XL_bc, po=19, xo= 16, lk=1): pass | ||||
| class BCCTR  (_fmt.Instruction_XL_bc, po=19, xo=528, lk=0): pass | ||||
| class BCCTRL (_fmt.Instruction_XL_bc, po=19, xo=528, lk=1): pass | ||||
| class BCTAR  (_fmt.Instruction_XL_bc, po=19, xo=560, lk=0): pass | ||||
| class BCTARL (_fmt.Instruction_XL_bc, po=19, xo=560, lk=1): pass | ||||
| @ -0,0 +1,21 @@ | ||||
| from . import _insn | ||||
| from ._branch import BranchCheck | ||||
|  | ||||
| # Branches | ||||
|  | ||||
| class B      (BranchCheck, name="insn_b",      insn_cls=_insn.B,    ): pass | ||||
| class BA     (BranchCheck, name="insn_ba",     insn_cls=_insn.BA    ): pass | ||||
| class BL     (BranchCheck, name="insn_bl",     insn_cls=_insn.BL    ): pass | ||||
| class BLA    (BranchCheck, name="insn_bla",    insn_cls=_insn.BLA   ): pass | ||||
|  | ||||
| class BC     (BranchCheck, name="insn_bc",     insn_cls=_insn.BC    ): pass | ||||
| class BCA    (BranchCheck, name="insn_bca",    insn_cls=_insn.BCA   ): pass | ||||
| class BCL    (BranchCheck, name="insn_bcl",    insn_cls=_insn.BCL   ): pass | ||||
| class BCLA   (BranchCheck, name="insn_bcla",   insn_cls=_insn.BCLA  ): pass | ||||
|  | ||||
| class BCLR   (BranchCheck, name="insn_bclr",   insn_cls=_insn.BCLR  ): pass | ||||
| class BCLRL  (BranchCheck, name="insn_bclrl",  insn_cls=_insn.BCLRL ): pass | ||||
| class BCCTR  (BranchCheck, name="insn_bcctr",  insn_cls=_insn.BCCTR ): pass | ||||
| class BCCTRL (BranchCheck, name="insn_bcctrl", insn_cls=_insn.BCCTRL): pass | ||||
| class BCTAR  (BranchCheck, name="insn_bctar",  insn_cls=_insn.BCTAR ): pass | ||||
| class BCTARL (BranchCheck, name="insn_bctarl", insn_cls=_insn.BCTARL): pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.B): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BA): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BC): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCA): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCCTR): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCCTRL): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCL): | ||||
|     pass | ||||
| @ -1,10 +0,0 @@ | ||||
| from . import _branch | ||||
|  | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCLA): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCLR): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCLRL): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCTAR): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BCTARL): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BL): | ||||
|     pass | ||||
| @ -1,9 +0,0 @@ | ||||
| from . import _branch | ||||
| from .. import insn | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(_branch.Check, insn_cls=insn.BLA): | ||||
|     pass | ||||
| @ -1,40 +0,0 @@ | ||||
| from amaranth import * | ||||
| from amaranth.asserts import * | ||||
|  | ||||
| from .. import pfv | ||||
|  | ||||
|  | ||||
| __all__ = ["Check"] | ||||
|  | ||||
|  | ||||
| class Check(Elaboratable): | ||||
|     """Uniqueness check. | ||||
|  | ||||
|     Check that the core cannot retire two instructions with the same `pfv.order` identifier. | ||||
|     """ | ||||
|     def __init__(self): | ||||
|         self.pfv  = pfv.Interface() | ||||
|         self.trig = Record([ | ||||
|             ("pre",  1), | ||||
|             ("post", 1), | ||||
|         ]) | ||||
|  | ||||
|     def elaborate(self, platform): | ||||
|         m = Module() | ||||
|  | ||||
|         spec_order = AnyConst(self.pfv.order.shape()) | ||||
|         duplicate  = Signal() | ||||
|  | ||||
|         with m.If(self.trig.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.trig.post): | ||||
|             m.d.sync += Assert(~duplicate) | ||||
|  | ||||
|         return m | ||||
					Loading…
					
					
				
		Reference in New Issue