Example #1
0
    def test_flat_makefile(self) -> None:
        """
        Test that a Makefile for a flat design is generated correctly.
        """
        tmpdir = tempfile.mkdtemp()
        proj_config = os.path.join(tmpdir, "config.json")

        settings = {
            "vlsi.core.technology": "nop",
            "vlsi.core.build_system": "make",
            "synthesis.inputs.top_module": "TopMod"
        }
        with open(proj_config, "w") as f:
            f.write(json.dumps(settings, cls=HammerJSONEncoder, indent=4))

        options = HammerDriverOptions(environment_configs=[],
                                      project_configs=[proj_config],
                                      log_file=os.path.join(tmpdir, "log.txt"),
                                      obj_dir=tmpdir)

        self.assertTrue(
            HammerVLSISettings.set_hammer_vlsi_path_from_environment(),
            "hammer_vlsi_path must exist")
        driver = HammerDriver(options)

        CLIDriver.generate_build_inputs(driver, lambda x: None)

        d_file = os.path.join(driver.obj_dir, "hammer.d")
        self.assertTrue(os.path.exists(d_file))

        with open(d_file, "r") as f:
            contents = f.readlines()

        targets = self._read_targets_from_makefile(contents)

        tasks = {"pcb", "syn", "par", "drc", "lvs"}
        expected_targets = tasks.copy()
        expected_targets.update({"redo-" + x for x in tasks if x is not "pcb"})
        expected_targets.update({
            os.path.join(tmpdir, x + "-rundir", x + "-output-full.json")
            for x in tasks
        })
        expected_targets.update({
            os.path.join(tmpdir, x + "-input.json")
            for x in tasks if x not in {"syn", "pcb"}
        })

        self.assertEqual(set(targets.keys()), set(expected_targets))

        # TODO at some point we should add more tests

        # Cleanup
        shutil.rmtree(tmpdir)
Example #2
0
    def test_hier_makefile(self) -> None:
        """
        Test that a Makefile for a hierarchical design is generated correctly.
        """
        tmpdir = tempfile.mkdtemp()
        proj_config = os.path.join(tmpdir, "config.json")

        settings = {
            "vlsi.core.technology":
            "nop",
            "vlsi.core.build_system":
            "make",
            "vlsi.inputs.hierarchical.mode":
            "hierarchical",
            "vlsi.inputs.hierarchical.top_module":
            "TopMod",
            "vlsi.inputs.hierarchical.config_source":
            "manual",
            "vlsi.inputs.hierarchical.manual_modules": [{
                "TopMod": ["SubModA", "SubModB"]
            }],
            "vlsi.inputs.hierarchical.manual_placement_constraints": [{
                "TopMod": [{
                    "path": "top",
                    "type": "toplevel",
                    "x": 0,
                    "y": 0,
                    "width": 1234,
                    "height": 7890,
                    "margins": {
                        "left": 1,
                        "top": 2,
                        "right": 3,
                        "bottom": 4
                    }
                }, {
                    "path": "top/C",
                    "type": "placement",
                    "x": 2,
                    "y": 102,
                    "width": 30,
                    "height": 40
                }, {
                    "path": "top/B",
                    "type": "hierarchical",
                    "x": 10,
                    "y": 30,
                    "master": "SubModB"
                }, {
                    "path": "top/A",
                    "type": "hierarchical",
                    "x": 200,
                    "y": 120,
                    "master": "SubModA"
                }]
            }, {
                "SubModA": [{
                    "path": "a",
                    "type": "toplevel",
                    "x": 0,
                    "y": 0,
                    "width": 100,
                    "height": 200,
                    "margins": {
                        "left": 0,
                        "top": 0,
                        "right": 0,
                        "bottom": 0
                    }
                }]
            }, {
                "SubModB": [{
                    "path": "b",
                    "type": "toplevel",
                    "x": 0,
                    "y": 0,
                    "width": 340,
                    "height": 160,
                    "margins": {
                        "left": 0,
                        "top": 0,
                        "right": 0,
                        "bottom": 0
                    }
                }]
            }]
        }
        with open(proj_config, "w") as f:
            f.write(json.dumps(settings, cls=HammerJSONEncoder, indent=4))

        options = HammerDriverOptions(environment_configs=[],
                                      project_configs=[proj_config],
                                      log_file=os.path.join(tmpdir, "log.txt"),
                                      obj_dir=tmpdir)

        self.assertTrue(
            HammerVLSISettings.set_hammer_vlsi_path_from_environment(),
            "hammer_vlsi_path must exist")
        driver = HammerDriver(options)

        CLIDriver.generate_build_inputs(driver, lambda x: None)

        d_file = os.path.join(driver.obj_dir, "hammer.d")
        self.assertTrue(os.path.exists(d_file))

        with open(d_file, "r") as f:
            contents = f.readlines()

        targets = self._read_targets_from_makefile(contents)

        mods = {"TopMod", "SubModA", "SubModB"}
        expected_targets = {
            "pcb",
            os.path.join(tmpdir, "pcb-rundir", "pcb-output-full.json")
        }
        expected_targets.update({"sim-rtl-" + x for x in mods})
        expected_targets.update({"syn-" + x for x in mods})
        expected_targets.update({"sim-syn-" + x for x in mods})
        expected_targets.update({"par-" + x for x in mods})
        expected_targets.update({"sim-par-" + x for x in mods})
        expected_targets.update({"power-par-" + x for x in mods})
        expected_targets.update({"lvs-" + x for x in mods})
        expected_targets.update({"drc-" + x for x in mods})
        expected_targets.update({"redo-sim-rtl-" + x for x in mods})
        expected_targets.update({"redo-syn-" + x for x in mods})
        expected_targets.update({"redo-sim-syn-" + x for x in mods})
        expected_targets.update({"redo-par-" + x for x in mods})
        expected_targets.update({"redo-sim-par-" + x for x in mods})
        expected_targets.update({"redo-power-par-" + x for x in mods})
        expected_targets.update({"redo-lvs-" + x for x in mods})
        expected_targets.update({"redo-drc-" + x for x in mods})
        expected_targets.update({
            os.path.join(tmpdir, "sim-rtl-" + x, "sim-output-full.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "syn-" + x, "syn-output-full.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "sim-syn-" + x, "sim-output-full.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "par-" + x, "par-output-full.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "sim-par-" + x, "sim-output-full.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "power-par-" + x, "power-output-full.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "lvs-" + x, "lvs-output-full.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "drc-" + x, "drc-output-full.json")
            for x in mods
        })
        # Only non-leafs get a syn-*-input.json target
        expected_targets.update({
            os.path.join(tmpdir, "syn-" + x + "-input.json")
            for x in mods if x in {"TopMod"}
        })
        expected_targets.update({
            os.path.join(tmpdir, "sim-syn-" + x + "-input.json")
            for x in mods
        })
        expected_targets.update(
            {os.path.join(tmpdir, "par-" + x + "-input.json")
             for x in mods})
        expected_targets.update({
            os.path.join(tmpdir, "sim-par-" + x + "-input.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "power-par-" + x + "-input.json")
            for x in mods
        })
        expected_targets.update({
            os.path.join(tmpdir, "power-sim-par-" + x + "-input.json")
            for x in mods
        })
        expected_targets.update(
            {os.path.join(tmpdir, "lvs-" + x + "-input.json")
             for x in mods})
        expected_targets.update(
            {os.path.join(tmpdir, "drc-" + x + "-input.json")
             for x in mods})

        self.assertEqual(set(targets.keys()), expected_targets)

        # TODO at some point we should add more tests

        # Cleanup
        shutil.rmtree(tmpdir)