Ejemplo n.º 1
0
def assert_formal(spec, mode="bmc", depth=1):
    functions = []
    test_class = None
    caller_path = ""
    stack = inspect.stack()
    for frame in stack[1:]:
        if "unittest" in frame.filename:
            filename = "__".join(reversed(functions))
            if test_class:
                filename = f'{test_class}__{filename}'
            break
        functions.append(frame.function)
        try:
            test_class = frame.frame.f_locals['self'].__class__.__name__
        except:
            pass
        caller_path = frame.filename

    target_dir = Path(caller_path).parent / ".sim_results"
    target_dir.mkdir(exist_ok=True)
    if (target_dir / filename).exists():
        rmtree(target_dir / filename)

    if mode == "hybrid":
        # A mix of BMC and k-induction, as per personal communication with Claire Wolf.
        script = "setattr -unset init w:* a:nmigen.sample_reg %d"
        mode = "bmc"
    else:
        script = ""

    config = textwrap.dedent("""\
        [options]
        mode {mode}
        depth {depth}
        wait on
        [engines]
        smtbmc
        [script]
        read_ilang top.il
        prep
        {script}
        [file top.il]
        {rtlil}
    """).format(mode=mode,
                depth=depth,
                script=script,
                rtlil=rtlil.convert(Fragment.get(spec,
                                                 platform=FormalPlatform)))
    with subprocess.Popen([require_tool("sby"), "-f", "-d", filename],
                          cwd=str(target_dir),
                          universal_newlines=True,
                          stdin=subprocess.PIPE,
                          stdout=subprocess.PIPE) as proc:
        stdout, stderr = proc.communicate(config)
        if proc.returncode != 0:
            assert False, "Formal verification failed:\n" + stdout + "\n\n" + f"vcd: {str(target_dir / filename)}/engine_0/trace.vcd"
Ejemplo n.º 2
0
    def assertFormal(self, spec, mode="bmc", depth=1):
        stack = traceback.extract_stack()
        for frame in reversed(stack):
            if os.path.dirname(__file__) not in frame.filename:
                break
            caller = frame

        spec_root, _ = os.path.splitext(caller.filename)
        spec_dir = os.path.dirname(spec_root)
        spec_name = "{}_{}".format(
            os.path.basename(spec_root).replace("test_", "spec_"),
            caller.name.replace("test_", ""))

        # The sby -f switch seems not fully functional when sby is reading from stdin.
        if os.path.exists(os.path.join(spec_dir, spec_name)):
            shutil.rmtree(os.path.join(spec_dir, spec_name))

        if mode == "hybrid":
            # A mix of BMC and k-induction, as per personal communication with Claire Wolf.
            script = "setattr -unset init w:* a:nmigen.sample_reg %d"
            mode = "bmc"
        else:
            script = ""

        config = textwrap.dedent("""\
        [options]
        mode {mode}
        depth {depth}
        wait on

        [engines]
        smtbmc

        [script]
        read_ilang top.il
        prep
        {script}

        [file top.il]
        {rtlil}
        """).format(mode=mode,
                    depth=depth,
                    script=script,
                    rtlil=rtlil.convert(Fragment.get(spec, platform="formal")))
        with subprocess.Popen([require_tool("sby"), "-f", "-d", spec_name],
                              cwd=spec_dir,
                              env={
                                  **os.environ, "PYTHONWARNINGS": "ignore"
                              },
                              universal_newlines=True,
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE) as proc:
            stdout, stderr = proc.communicate(config)
            if proc.returncode != 0:
                self.fail("Formal verification failed:\n" + stdout)
Ejemplo n.º 3
0
    def assertFormal(self, spec, mode="bmc", depth=1):
        """
        mode: bmc, prove
        """

        caller, *_ = traceback.extract_stack(limit=2)
        spec_root, _ = os.path.splitext(caller.filename)
        spec_dir = os.path.dirname(spec_root)
        spec_name = "{}_{}".format(
            os.path.basename(spec_root).replace("test_", "spec_"),
            caller.name.replace("test_", ""))

        # The sby -f switch seems not fully functional when sby is reading from stdin.
        if os.path.exists(os.path.join(spec_dir, spec_name)):
            shutil.rmtree(os.path.join(spec_dir, spec_name))

        config = textwrap.dedent("""\
        [options]
        mode {mode}
        depth {depth}
        wait on

        [engines]
        smtbmc

        [script]
        read_ilang top.il
        prep

        [file top.il]
        {rtlil}
        """).format(mode=mode,
                    depth=depth,
                    rtlil=rtlil.convert(Fragment.get(spec, platform="formal")))
        f = open(os.path.join(spec_dir, spec_name + '.script'), "w")
        f.write(config)
        f.close()
        with subprocess.Popen([require_tool("sby"), "-f", "-d", spec_name],
                              cwd=spec_dir,
                              universal_newlines=True,
                              stdin=subprocess.PIPE,
                              stdout=subprocess.PIPE) as proc:
            stdout, stderr = proc.communicate(config)
            if proc.returncode != 0:
                self.fail("Formal verification failed:\n" + stdout)
Ejemplo n.º 4
0
def synth(core, ports):
    plat = EmptyPlatform()
    frag = Fragment.get(core, plat)
    rtlil_text = rtlil.convert(frag, ports=ports)

    yosys_cmd = ''
    with tempfile.TemporaryDirectory() as temp_dir:
        with open(temp_dir + '/top.il', 'w') as f:
            f.write(rtlil_text)

        for file_name, content in plat.extra_files.items():
            with open(temp_dir + '/' + file_name, 'wb') as f:
                f.write(content)
            yosys_cmd += "read_verilog {}\n".format(file_name)
        yosys_cmd += 'read_ilang {}\n'.format('top.il')
        yosys_cmd += 'synth_xilinx -top top\n'

        with open(temp_dir + '/top.ys', 'w') as f:
            f.write(yosys_cmd)

        subprocess.check_call([require_tool("yosys"), 'top.ys'], cwd=temp_dir)