mirror of
https://github.com/TinyTapeout/tt-support-tools.git
synced 2026-11-03 12:46:08 +01:00
feat(precheck): add Verilog syntax check
This commit is contained in:
@@ -308,6 +308,27 @@ def analog_pin_check(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def verilog_syntax_check(verilog: str):
|
||||||
|
"""Load the Verilog file into Yosys to verify it can be read successfully."""
|
||||||
|
|
||||||
|
logging.info(f"Running Verilog syntax check on {verilog}")
|
||||||
|
verilog_dir = os.path.dirname(verilog)
|
||||||
|
yowasp_env = os.environ.copy()
|
||||||
|
yowasp_env["YOWASP_MOUNT"] = f"{verilog_dir}={verilog_dir}"
|
||||||
|
|
||||||
|
yosys = subprocess.run(
|
||||||
|
[
|
||||||
|
"yowasp-yosys",
|
||||||
|
"-p",
|
||||||
|
f'read_verilog -sv "{verilog}"',
|
||||||
|
],
|
||||||
|
env=yowasp_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
if yosys.returncode != 0:
|
||||||
|
raise PrecheckFailure("Verilog syntax check failed")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
default_tech = PDK_NAME
|
default_tech = PDK_NAME
|
||||||
if default_tech not in tech_names:
|
if default_tech not in tech_names:
|
||||||
@@ -447,6 +468,10 @@ def main():
|
|||||||
),
|
),
|
||||||
"techs": ["sky130A", "ihp-sg13g2"],
|
"techs": ["sky130A", "ihp-sg13g2"],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Verilog syntax check",
|
||||||
|
"check": lambda: verilog_syntax_check(verilog_file),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
testsuite = ET.Element("testsuite", name="Tiny Tapeout Prechecks")
|
testsuite = ET.Element("testsuite", name="Tiny Tapeout Prechecks")
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ dependencies = [
|
|||||||
"numpy<2",
|
"numpy<2",
|
||||||
"pytest",
|
"pytest",
|
||||||
"PyYAML",
|
"PyYAML",
|
||||||
|
"yowasp-yosys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#
|
#
|
||||||
# This file is autogenerated by pip-compile with Python 3.12
|
# This file is autogenerated by pip-compile with Python 3.13
|
||||||
# by the following command:
|
# by the following command:
|
||||||
#
|
#
|
||||||
# pip-compile
|
# pip-compile
|
||||||
#
|
#
|
||||||
|
click==8.3.1
|
||||||
|
# via yowasp-yosys
|
||||||
gdstk==0.9.52
|
gdstk==0.9.52
|
||||||
# via tt-precheck (pyproject.toml)
|
# via tt-precheck (pyproject.toml)
|
||||||
iniconfig==2.0.0
|
iniconfig==2.0.0
|
||||||
@@ -16,9 +18,17 @@ numpy==1.26.4
|
|||||||
# tt-precheck (pyproject.toml)
|
# tt-precheck (pyproject.toml)
|
||||||
packaging==24.1
|
packaging==24.1
|
||||||
# via pytest
|
# via pytest
|
||||||
|
platformdirs==4.9.4
|
||||||
|
# via yowasp-runtime
|
||||||
pluggy==1.5.0
|
pluggy==1.5.0
|
||||||
# via pytest
|
# via pytest
|
||||||
pytest==8.2.2
|
pytest==8.2.2
|
||||||
# via tt-precheck (pyproject.toml)
|
# via tt-precheck (pyproject.toml)
|
||||||
pyyaml==6.0.1
|
pyyaml==6.0.1
|
||||||
# via tt-precheck (pyproject.toml)
|
# via tt-precheck (pyproject.toml)
|
||||||
|
wasmtime==42.0.0
|
||||||
|
# via yowasp-runtime
|
||||||
|
yowasp-runtime==1.88
|
||||||
|
# via yowasp-yosys
|
||||||
|
yowasp-yosys==0.63.0.0.post1107
|
||||||
|
# via tt-precheck (pyproject.toml)
|
||||||
|
|||||||
@@ -537,6 +537,31 @@ def gds_lef_analog_pin_example(tmp_path_factory: pytest.TempPathFactory):
|
|||||||
return str(gds_file), str(lef_file)
|
return str(gds_file), str(lef_file)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def verilog_syntax_ok(tmp_path_factory: pytest.TempPathFactory):
|
||||||
|
"""Creates a Verilog file with correct syntax."""
|
||||||
|
verilog_file = tmp_path_factory.mktemp("verilog") / "TEST_verilog_syntax_ok.v"
|
||||||
|
verilog_data = """
|
||||||
|
module TEST_verilog_syntax_ok ();
|
||||||
|
endmodule
|
||||||
|
"""
|
||||||
|
open(verilog_file, "w").write(textwrap.dedent(verilog_data))
|
||||||
|
return str(verilog_file)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def verilog_syntax_error(tmp_path_factory: pytest.TempPathFactory):
|
||||||
|
"""Creates a Verilog file with incorrect syntax."""
|
||||||
|
verilog_file = tmp_path_factory.mktemp("verilog") / "TEST_verilog_syntax_error.v"
|
||||||
|
verilog_data = """
|
||||||
|
module TEST_verilog_syntax_error ();
|
||||||
|
syntax error
|
||||||
|
endmodule
|
||||||
|
"""
|
||||||
|
open(verilog_file, "w").write(textwrap.dedent(verilog_data))
|
||||||
|
return str(verilog_file)
|
||||||
|
|
||||||
|
|
||||||
def test_magic_drc_pass(gds_valid: str):
|
def test_magic_drc_pass(gds_valid: str):
|
||||||
precheck.magic_drc(gds_valid, "TEST_valid")
|
precheck.magic_drc(gds_valid, "TEST_valid")
|
||||||
|
|
||||||
@@ -822,3 +847,15 @@ def test_analog_more_ua_entries(gds_lef_analog_pin_example: tuple[str, str]):
|
|||||||
2,
|
2,
|
||||||
{"ua[0]": "x", "ua[1]": "x", "ua[2]": "x"},
|
{"ua[0]": "x", "ua[1]": "x", "ua[2]": "x"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_verilog_syntax_ok(verilog_syntax_ok: str):
|
||||||
|
precheck.verilog_syntax_check(verilog_syntax_ok)
|
||||||
|
|
||||||
|
|
||||||
|
def test_verilog_syntax_error(verilog_syntax_error: str):
|
||||||
|
with pytest.raises(
|
||||||
|
precheck.PrecheckFailure,
|
||||||
|
match="Verilog syntax check failed",
|
||||||
|
):
|
||||||
|
precheck.verilog_syntax_check(verilog_syntax_error)
|
||||||
|
|||||||
Reference in New Issue
Block a user