@ -1,43 +1,18 @@
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import argparse
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import importlib
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import os
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				import multiprocessing
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				from amaranth import *
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				from amaranth.asserts import *
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				from power_fv import pfv
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				from power_fv.checks import *
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				from power_fv.tb import Testbench
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				from power_fv.build import SymbiYosysPlatform
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				from _wrapper import MicrowattWrapper
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				if __name__ == "__main__":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    parser = argparse.ArgumentParser()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    parser.add_argument("check", help="check", type=str, choices=("unique", "ia_fwd", "gpr", "cr", "spr"))
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    parser.add_argument("--mode", help="mode", type=str, choices=("cover", "bmc"), default="bmc")
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    parser.add_argument("--pre",  help="pre-condition step, in clock cycles (default: 15)",  type=int, default=15)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    parser.add_argument("--post", help="post-condition step, in clock cycles (default: 15)", type=int, default=15)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    args = parser.parse_args()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    check = None
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    if args.check == "unique":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        check = UniquenessCheck() if args.mode == "bmc" else UniquenessCover()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    if args.check == "ia_fwd":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        check = IAForwardCheck() if args.mode == "bmc" else IAForwardCover()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    if args.check == "gpr":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        check = GPRCheck()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    if args.check == "cr":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        check = CRCheck()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    if args.check == "spr":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        check = SPRCheck() if args.mode == "bmc" else SPRCover()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    cpu       = MicrowattWrapper()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    testbench = Testbench(check, cpu, t_pre=args.pre, t_post=args.post)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    platform  = SymbiYosysPlatform()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    microwatt_files = [
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				def microwatt_files():
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    _filenames = (
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "cache_ram.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "common.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "control.vhdl",
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -64,28 +39,66 @@ if __name__ == "__main__":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "nonrandom.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "plru.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "pmu.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "powerfv_types.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "powerfv.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "ppc_fx_insns.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "register_file.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "rotator.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "utils.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "wishbone_types.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "writeback.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "powerfv_types.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        "powerfv.vhdl",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    ]
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    for filename in _filenames:
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        contents = open(os.path.join(os.curdir, "microwatt", filename), "r").read()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        yield filename, contents
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    top_filename = "microwatt_top.vhdl"
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    top_contents = open(os.path.join(os.curdir, top_filename), "r").read()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    yield top_filename, top_contents
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    for filename in microwatt_files:
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        file = open(os.path.join(os.curdir, "microwatt", filename), "r")
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        platform.add_file(filename, file.read())
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    platform.add_file("microwatt_top.vhdl", open(os.path.join(os.curdir, "microwatt_top.vhdl"), "r"))
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				def run_check(module_name, pre, post):
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    module = importlib.import_module(f".{module_name}", package="power_fv.checks")
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    check  = module.Check()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    cpu    = MicrowattWrapper()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    top    = Testbench(check, cpu, t_pre=pre, t_post=post)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    platform.build(testbench,
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        name      = f"{args.check}_{args.mode}_tb",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        build_dir = f"build/{args.check}_{args.mode}",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        mode      = args.mode,
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    platform = SymbiYosysPlatform()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    for filename, contents in microwatt_files():
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        platform.add_file(filename, contents)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    top_name  = "{}_tb".format(module_name)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    build_dir = "build/{}".format(top_name)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    platform.build(
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        top       = top,
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        name      = top_name,
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        build_dir = build_dir,
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        mode      = "bmc",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        ghdl_opts = "--std=08",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        # TODO: investigate why combinatorial loops appear with `prep -flatten -nordff`
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        prep_opts = "-nordff",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				if __name__ == "__main__":
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    parser = argparse.ArgumentParser()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    parser.add_argument("-j", "--jobs",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        help="Number of worker processes (default: os.cpu_count())",
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        type=int,
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        default=os.cpu_count(),
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    )
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    args = parser.parse_args()
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    checks = [
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        # name           pre   post
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        ("unique",       12,   15),
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        ("ia_fwd",       None, 15),
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        ("gpr",          None, 15),
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        ("cr",           None, 15),
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        ("spr",          None, 15),
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    ]
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    with multiprocessing.Pool(processes=args.jobs) as pool:
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        pool.starmap(run_check, checks)