-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: bbrzyski <[email protected]>
- Loading branch information
Showing
11 changed files
with
277 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
# Validation of design | ||
|
||
One of topwrap features is to run validation on user's design which consists of series of checks for errors user may do while creating a design. | ||
|
||
|
||
```{eval-rst} | ||
.. autoclass:: topwrap.kpm_dataflow_validator.DataflowValidator | ||
:members: | ||
``` | ||
|
||
Each check returns the following class: | ||
|
||
```{eval-rst} | ||
.. autoclass:: topwrap.kpm_dataflow_validator.CheckResult | ||
``` | ||
|
||
## Tests for validation checks | ||
|
||
Tests for the `DataflowValidator` class are done using various designs that are valid or have some errors in them with the goal to check everything validation functions can do. | ||
|
||
Below are all the graphs that are used for testing. | ||
|
||
### Duplicate IP names | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_duplicate_ip_names | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_pwm.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_duplicate_ips.json | ||
:preview: True | ||
``` | ||
|
||
### Invalid parameters' values | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_invalid_parameters_values | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_pwm.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_invalid_params.json | ||
:preview: True | ||
``` | ||
|
||
### Connection between external Metanodes | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_ext_in_to_ext_out_connections | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_pwm.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_meta_to_meta_conn.json | ||
:preview: True | ||
``` | ||
|
||
### Ports connected to multiple external Metanodes | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_ports_multiple_external_metanodes | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_pwm.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_port_to_multiple_external_metanodes.json | ||
:preview: True | ||
``` | ||
|
||
### Duplicate Metanode names | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_duplicate_metanode_names | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_pwm.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_duplicate_metanode_names.json | ||
:preview: True | ||
``` | ||
|
||
### Duplicate Metanode connected to interface | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_duplicate_external_input_interfaces | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_pwm.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_duplicate_ext_input_ifaces.json | ||
``` | ||
|
||
### Unnamed Metanodes | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_unnamed_metanodes | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_pwm.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_connected_unnamed_metanode.json | ||
:preview: True | ||
``` | ||
|
||
### Connection between two inout ports | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_inouts_connections | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_inout.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_inouts_connections.json | ||
:preview: True | ||
``` | ||
|
||
### Unconnected ports in subgraph node | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_unconn_hierarchy | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_hierarchy.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_unconn_hierarchy.json | ||
``` | ||
|
||
### Connection of subgraph node to multiple External Metanodes | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_subgraph_multiple_external_metanodes | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_hierarchy.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_subgraph_multiple_external_metanodes.json | ||
``` | ||
|
||
### Connection to subgraph Metanode | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_conn_subgraph_metanode | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_hierarchy.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_conn_subgraph_metanode.json | ||
``` | ||
|
||
### Complex hierarchy graph | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_complex_hierarchy | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../../tests/data/data_kpm/conversions/complex/specification_complex.json | ||
:dataflow: ../../../tests/data/data_kpm/conversions/complex/dataflow_complex.json | ||
``` | ||
|
||
### Duplicate IP cores in subgraph node | ||
```{eval-rst} | ||
.. autofunction:: tests_kpm.test_kpm_validation.dataflow_hier_duplicate_names | ||
``` | ||
|
||
```{kpm_iframe} | ||
:spec: ../../build/kpm_jsons/spec_hierarchy.json | ||
:dataflow: ../../../tests/data/data_kpm/dataflow_tests/dataflow_hierarchical_duplicate_names.json | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# Copyright (C) 2023 Antmicro | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import re | ||
import shutil | ||
import subprocess | ||
import sys | ||
import tempfile | ||
from pathlib import Path | ||
|
||
import pytest | ||
|
||
|
||
class TestInterconnect: | ||
@pytest.mark.skipif( | ||
sys.version_info[:2] < (3, 9) or sys.version_info[:2] > (3, 10), | ||
reason="interconnect test requires Python 3.9 or 3.10 due to litex requiring Python 3.9 or 3.10", | ||
) | ||
@pytest.mark.skipif( | ||
not ( | ||
shutil.which("verilator") | ||
and shutil.which("riscv64-unknown-elf-gcc") | ||
and shutil.which("make") | ||
and shutil.which("meson") | ||
and shutil.which("ninja") | ||
and shutil.which("hexdump") | ||
), | ||
reason="verilator, riscv64-unknown-elf toolchain, make, meson, ninja and hexdump are required to run the interconnect test", | ||
) | ||
def test_interconnect_design(self, request: pytest.FixtureRequest) -> None: | ||
remote_url = "https://github.com/antmicro/soc-generator.git" | ||
commit_sha = "76ac5b3743bea1bb6e5d2ac7ecae31ab39d5e8b3" | ||
data_dir = request.path.parent / Path("../data/data_build/interconnect") | ||
# don't change formatting of the context manager below - this formatting is needed | ||
# for Python 3.8 compatibility, see https://bugs.python.org/issue12782 | ||
# fmt: off | ||
with ( | ||
tempfile.TemporaryDirectory() | ||
) as repo_tmp_dir, ( | ||
tempfile.TemporaryDirectory() | ||
) as build_tmp_dir: | ||
# fmt: on | ||
repo_dir = Path(repo_tmp_dir) | ||
build_dir = Path(build_tmp_dir) | ||
example_dir = repo_dir / Path("examples/simple_soc") | ||
# clone soc generator repo | ||
subprocess.check_call(["git", "clone", "--recurse-submodules", remote_url, repo_dir]) | ||
subprocess.check_call(["git", "checkout", commit_sha], cwd=repo_dir) | ||
subprocess.check_call(["pip", "install", "."], cwd=repo_dir) | ||
subprocess.check_call(["pip", "install", "-r", "requirements.txt"], cwd=example_dir) | ||
subprocess.check_call(["make", "deps"], cwd=example_dir) | ||
|
||
# build topwrap design | ||
subprocess.check_call( | ||
[ | ||
"python", | ||
"-m", | ||
"topwrap", | ||
"build", | ||
"-d", | ||
"project.yaml", | ||
"-b", | ||
build_dir, | ||
"-p", | ||
"xc7k70tfbg484", | ||
], | ||
cwd=data_dir, | ||
) | ||
|
||
# include additional sources in topwrap design | ||
subprocess.check_call( | ||
[ | ||
"sh", | ||
"-c", | ||
f"cat {data_dir}/sources/mem.v {data_dir}/sources/soc.v {data_dir}/sources/crg.v >> {build_dir}/top.v", | ||
] | ||
) | ||
|
||
# move topwrap design to the location expected by soc generator | ||
subprocess.check_call(["mkdir", example_dir / "build"]) | ||
subprocess.check_call(["cp", build_dir / "top.v", example_dir / "build" / "top.v"]) | ||
|
||
# create an empty file that soc generator expects | ||
subprocess.check_call(["touch", example_dir / "build" / "wishbone_interconnect.v"]) | ||
|
||
# run simulation | ||
output = subprocess.check_output(["make", "sim-run"], cwd=example_dir).decode("utf-8") | ||
|
||
# tx_data is a list of all bytes transmitted on TX (in hex, as strings) | ||
tx_data = re.findall(r"(?:\[\d+\] TX: (0x[0-9a-fA-F]+) RX: 0x[0-9a-fA-F]+\n)", output) | ||
# check that "hello world" was transmitted on UART TX | ||
assert "".join(map(lambda v: chr(int(v, base=16)), tx_data)) == "hello world" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters