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.
- class DataflowValidator(dataflow: Dict[str, Any])¶
The main class that contains all the validation checks. The purpose of validation is to check for common errors the user may make while creating the design and make sure the design can be saved in topwrap yaml format. These functions are called in two cases:
When there is a call from KPM for dataflow_validate (the user has clicked Validate in GUI)
When a user tries to save the design
- check_connection_to_subgraph_metanodes() CheckResult ¶
Check for any connections to exposed subgraph metanode ports.
In this context:
Exposed port: A port on a subgraph metanode that represents the interface of the subgraph to the external graph. It is visible and accessible from outside the subgraph.
Unexposed port: An internal port on a subgraph metanode that is used for internal connections within the subgraph but is not accessible from the external graph.
These metanodes are meant to represent ports of subgraph nodes. Connections to these metanodes should only occur via the unexposed ports. Any connection to an exposed port is considered an error because such connections cannot be represented in the design.
- check_duplicate_metanode_names() CheckResult ¶
Check for duplicate names of external metanodes. The name of metanode is in “External Name” property. In design, these external metanodes are referenced by this name so if there are multiple metanodes with the same name it will not be possible to represent them, hence the error.
- check_duplicate_node_names() CheckResult ¶
Check for any duplicate IP instance names in the graph (graph represents a hierarchy level). This check prevents from creating multiple nodes with the same “instanceName” in a given graph, since this is invalid in design. There can be multiple nodes with the same “instanceName” in the whole design (on various hierarchy levels).
- check_external_in_to_external_out_connections() CheckResult ¶
Check for connections between two external metanodes. In our design format (YAML), connections to external nodes are always represented as port: external, regardless of whether the external node is an input or output. Therefore, connections directly between two external metanodes cannot be represented within this format and are invalid by design.
- check_inouts_connections() CheckResult ¶
Check for connections between ports where one of them has an inout direction. Return a warning if such connections exist because in Amaranth inout ports are automatically propagated to the top-level module. This forces us to make a quirky design decisions that have to work around this fact, such as inverting the way inout ports are connected in YAML description.
- check_parameters_values() CheckResult ¶
Check if parameters in IP nodes are valid.
This check ensures users are informed of any errors in parameter definitions. While it is possible to save the design with invalid parameters (e.g. save to YAML), such a design cannot be successfully built into Verilog because integer widths of all parameters must be determined during the build process.
A parameter is considered valid if it meets any of the following conditions:
It is an instance of
int
.It has a correct value format, e.g.:
16'h5A5A
.- It can be evaluated based on other parameters, e.g.:
ADDR_WIDTH
:32
DATA_WIDTH
:ADDR_WIDTH/4
(evaluates to 8, which is valid).
- check_port_to_multiple_external_metanodes() CheckResult ¶
Check for ports that have connections to multiple external metanodes. Design schema allows only one connection between an IPcore/hierarchy port and an external metanode. The connection between the port and external metanode is a single entry, not a list that’s why we can’t add more connections.
- check_unconnected_ports_interfaces() CheckResult ¶
Check for unconnected ports or interfaces. This check helps identify any unconnected elements, warning the user about potential oversights or missed connections.
- check_unnamed_external_metanodes_with_multiple_conn() CheckResult ¶
Check for external metanodes that are connected to more than one port and don’t have a user-specified name. This is important to check because it is an undefined behavior when saving a design. Currently, when there is a connection to an unnamed metanode in design this metanode will have the name of the port it’s connected to.
- validate_kpm_design() Dict[str, List[str]] ¶
Run checks to validate the user-created design in KPM. Checks are designed to inform the user about errors present in his design that make it impossible to save and display warnings about potential issues in the design.
Each check returns the following class:
- class CheckResult(check_name: str, status: MessageType, error_count: int = 0, message: str | None = None)¶
Return type of each validation check
- Parameters:¶
- check_name : str¶
Name of the check
- status : MessageType¶
Check can be return one of three MessageTypes (OK, ERROR, WARNING)
OK - this status is set when check was successful
WARNING - check have failed but it is possible to represent the graph in design yaml
ERROR - it is not possible to represent graph in design yaml
- error_count : int¶
Number of errors if status is not OK
- message : str | None¶
Message describing errors
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¶
- dataflow_duplicate_ip_names()¶
Dataflow containing two IP cores with the same instance name. This is considered as not possible to represent in design yaml since we can’t distinguish them.
Invalid parameters’ values¶
- dataflow_invalid_parameters_values()¶
Dataflow containing an IP core with multiple parameters, but it’s impossible to resolve the INVALID NAME!!!.
Connection between external Metanodes¶
- dataflow_ext_in_to_ext_out_connections()¶
Dataflow containing Metanode<->Metanode connection.
Ports connected to multiple external Metanodes¶
- dataflow_ports_multiple_external_metanodes()¶
Dataflow containing a port connected to two External Metanodes.
Duplicate Metanode names¶
- dataflow_duplicate_metanode_names()¶
Dataflow containing two External Output Metanodes with the same “External Name” value.
Duplicate Metanode connected to interface¶
- dataflow_duplicate_external_input_interfaces()¶
Dataflow containing two External Input Metanodes with the same name. Here connection is to interface instead of port as in the example above.
Unnamed Metanodes¶
- dataflow_unnamed_metanodes()¶
Dataflow containing unnamed External Input Metanode with multiple connections to it.
Connection between two inout ports¶
- dataflow_inouts_connections()¶
Dataflow containing a connection between two inout ports.
Unconnected ports in subgraph node¶
- dataflow_unconn_hierarchy()¶
Dataflow containing subgraph node with two unconnected interfaces.
Connection of subgraph node to multiple External Metanodes¶
- dataflow_subgraph_multiple_external_metanodes()¶
Dataflow containing subgraph node with connection to two External Output Metanodes.
Connection to subgraph Metanode¶
- dataflow_conn_subgraph_metanode()¶
Dataflow containing subgraph metanode with connection to exposed interface. It can be seen by selecting the “Edit Subgraph” on subgraph node.
Complex hierarchy graph¶
- dataflow_complex_hierarchy()¶
Dataflow containing many edge cases such as duplicate subgraph node names, stressing out the capabilities of saving a design.
Duplicate IP cores in subgraph node¶
- dataflow_hier_duplicate_names()¶
Dataflow containing subgraph node inside which are duplicate IP’s.