The Verilog utility allows for linting and transformation of gate-level Verilog files. The following arguments exist:
usage: tool_verilog_util.py [-h] --input INPUT_FILE --output OUTPUT_FILE [--step STEPS] [--cell-library LIBRARY]
Verilog transform utility
options:
-h, --help show this help message and exit
--input INPUT_FILE The Verilog input file
--output OUTPUT_FILE The Verilog output file
--step STEPS The steps to apply
--cell-library LIBRARY
Technology library to use
Linting:
check-no-sequential-cells: Reports sequential cells in the circuitcheck-no-latches-cells: Reports latches in the circuitcheck-no-flip-flops-cells: Reports flip-flops in the circuitcheck-no-clock-cells: Reports clock(-gating) cells in the circuitcheck-no-test-cells: Reports DFT cells in the circuitcheck-no-tri-state-cells: Reports tri-state drivers in the circuitcheck-no-constant-cells: Reports constant cells in the circuitcheck-no-fill-cells: Reports filler cells in the circuitcheck-range-endianess: Reports mismatches in endianess of wire/port uses and definitionscheck-range-boundaries: Reports out of bounds in wire/port uses
Transformations:
normalize-combine-constants: Concatenation of constants are merged ({1'b 0, 1'b 1, 1'b 0} -> {3'b 010})normalize-remove-unnecessary-concatenations: Concatenations with one element are removed ({1'b 0} -> 1'b 0)normalize-replace-port-assignments: Port assignments generated by Synopsys are replacedmodule m (.a({a1, a2}), b); input a1, a2; output b; wire a1, a2; assign b = a1; endmodule module m (a, b); input [1:0] a; output b; assign b = a[1]; endmodule
normalize-combine-assignments: Successive assignments are converted to concatenationsassign a[5] = 1'b 0; assign a[4] = 1'b 1; assign a[3] = 1'b 0; assign {a[5], a[4], a[3]} = {1'b 0, 1'b 1, 1'b 0};
normalize-combine-concatenations: Concatenations are combined ({a[5], a[4], a[3], a[2:0]} -> a[5:0])
Example use:
python3 tool_verilog_util.py \
--input ../data/processors/cv32e40p-nangate-original-25.11.2022.v \
--output ../data/processors/cv32e40p-nangate-patched-03.12.2022.v \
--step check-no-latches-cells \
--step check-no-clock-cells \
--step check-no-test-cells \
--step check-no-tri-state-cells \
--step check-no-constant-cells \
--step check-no-fill-cells \
--step check-range-endianess \
--step check-range-boundaries \
--step normalize-replace-port-assignments \
--step normalize-combine-wire-arrays \
--step normalize-combine-assignments \
--step normalize-combine-concatenations \
--step normalize-combine-constants \
--step normalize-remove-unnecessary-concatenations \
--step check-no-latches-cells \
--step check-no-clock-cells \
--step check-no-test-cells \
--step check-no-tri-state-cells \
--step check-no-constant-cells \
--step check-no-fill-cells \
--step check-range-endianess \
--step check-range-boundariesInserts RSN elements into the circuit based on a configuration. The following arguments exist:
usage: tool_rsn_util.py [-h] --input INPUT_FILE [--output OUTPUT_FILE] --target TARGET [--cell-library LIBRARY] --configuration CONFIGURATION --top-module
TOP_MODULE [--exclude-port EXCLUDED_PORTS]
RSN generation utility
options:
-h, --help show this help message and exit
--input INPUT_FILE The Verilog input file
--output OUTPUT_FILE The Verilog output file
--target TARGET Target for this script (create-config, visualize-config, generate-rsn)
--cell-library LIBRARY
Technology library to use
--configuration CONFIGURATION
RSN configuration file
--top-module TOP_MODULE
SoC top level Verilog module
--exclude-port EXCLUDED_PORTS
Port to exclude from boundary scan creation e.g. clock, reset port
Targets:
-
create-config: Creates a new RSN configuration file (specification) for a circuit. The implementation section specifies the ports and implementation details of RSN elements. If the default port names don't match with the implementation they have to be adjusted.The modules section defines configuration for each module in the circuit. The available strategies are listed below.
{ "implementation": { "host-interface": { "name": "rsn_host_port", "rsn-ports": { "host_scan_in": "SI", "host_scan_out": "SO", "host_select": "SEL", "host_reset": "RST", "host_capture_en": "CE", "host_shift_en": "SE", "host_update_en": "UE", "host_clock": "TCK" } }, "client-interface": { ... }, ... }, "modules": { "cv32e40p_sleep_unit_PULP_CLUSTER0": { "name": "cv32e40p_sleep_unit_PULP_CLUSTER0", "excluded-ports": [], "strategy": "internal-scan-sib", "is-top-level": false }, "cv32e40p_aligner": { "name": "cv32e40p_aligner", "excluded-ports": [], "strategy": "internal-scan-sib", "is-top-level": false }, ... } } -
visualize-config: Visualizes the RSN configuration (specification) on the terminal as tree -
apply-config: Inserts the RSN configuration (specification) into the Verilog circuit
The following RSN module strategies exist:
skip: Module is left untouched and no RSN structures are inserted- Has boundary scan chain: no
- Has internal scan chain: no
- Has SIBs for child-elements: no
route-single: Module is used only used for connecting children- Has boundary scan chain: no
- Has internal scan chain: no
- Has SIBs for child-elements: no, single chain for children
route-sib: Module is used only used for connecting children (uses sibs)- Has boundary scan chain: no
- Has internal scan chain: no
- Has SIBs for child-elements: yes, one SIB per child
boundary-scan-single: Module has boundary scan chain- Has boundary scan chain: yes, inputs and then outputs in single chain
- Has internal scan chain: no
- Has SIBs for child-elements: no, single chain for children
boundary-scan-sib: Module has boundary scan chain- Has boundary scan chain: yes, inputs and then outputs in single chain
- Has internal scan chain: no
- Has SIBs for child-elements: yes, one SIB per child
sboundary-scan-single: Module has split boundary scan chain- Has boundary scan chain: yes, inputs and outputs in two chains with each one SIB
- Has internal scan chain: no
- Has SIBs for child-elements: no, single chain for children
sboundary-scan-sib: Module has split boundary scan chain- Has boundary scan chain: yes, inputs and outputs in two chains with each one SIB
- Has internal scan chain: no
- Has SIBs for child-elements: yes, one SIB per child
internal-scan-single: Module has internal scan chain- Has boundary scan chain: no
- Has internal scan chain: yes
- Has SIBs for child-elements: no, single chain for children
internal-scan-sib: Module has internal scan chain- Has boundary scan chain: no
- Has internal scan chain: yes
- Has SIBs for child-elements: yes, one SIB per child
full-scan-single: Module has internal and boundary scan chain- Has boundary scan chain: yes, inputs and then outputs in single chain
- Has internal scan chain: yes
- Has SIBs for child-elements: no, single chain for children
full-scan-sib: Module has internal and boundary scan chain- Has boundary scan chain: yes, inputs and then outputs in single chain
- Has internal scan chain: yes
- Has SIBs for child-elements: yes, one SIB per child
sfull-scan-single: Module has internal and split boundary scan chain- Has boundary scan chain: yes, inputs and outputs in two chains with each one SIB
- Has internal scan chain: yes
- Has SIBs for child-elements: no, single chain for children
sfull-scan-sib: Module has internal and split boundary scan chain- Has boundary scan chain: yes, inputs and outputs in two chains with each one SIB
- Has internal scan chain: yes
- Has SIBs for child-elements: yes, one SIB per child
For making the whole circuit testable:
- Full-Scan: Use
(s)full-scan-single/sibfor top-level module andinternal-scan-single/sibfor children - Exlude: Use
skipfor modules that should not be made testable
This will create a single scan chain that can be connected to a test access port (TAP). All flip-flops will be made testable and with that the circuit can be fully controlled / observed. For caches no scan-chain should be used as other methods like built-in self-test (BIST) / memory BIST (MBIST) are more efficient.
top: (s)full-scan-single/sib
+- processor: internal-scan-single/sib
| +- if_stage: internal-scan-single/sib
| | +- reg: internal-scan-single/sib
| +- id_stage: internal-scan-single/sib
| +- ex_stage: internal-scan-single/sib
| | +- alu: internal-scan-single/sib
| +- mem_stage: internal-scan-single/sib
| +- wb_stage: internal-scan-single/sib
+- cache: skip
Making single module(s) testable:
- Full-Scan module:
route-single/sibfor all parent modules and(s)full-scan-single/sibfor the target module and children,skipfor children that are not part of the targeted module (use for modules that have a mix of combinationtional and sequential behavior) - Functional module:
route-single/sifor all parent modules and(s)boundary-scan-single/sibfor the target modules,skipfor all other modules (use for easy-to-control/observe modules or to test bus interfaces) - Register module:
route-single/sifor all parent modules andinternal-scan-single/sibfor the target modules,skipfor all other modules (use for register-type modules with few login between in/outputs and flip-flops)
Depending on the required testing modules can be equipped with a full-scan configuration which makes all flip-flops testable. The module requires a boundary scan chain in case the input / output ports can not be controlled / observed otherwise. If sequential test is preferred only a boundary scan chain is required. For caches no scan-chain should be used as other methods like built-in self-test (BIST) / memory BIST (MBIST) are more efficient.
top: route-single/sib
+- processor: route-single/sib
| +- if_stage: route-single/sib
| | +- reg: internal-scan-single/sib
| +- id_stage: skip
| +- ex_stage: route-single/sib
| | +- alu: (s)full-scan-single/sib
| +- mem_stage: skip
| +- wb_stage: skip
+- cache: (s)boundary-scan-single/sib