vyges-sdc — SDC constraint checking and writing
Installed with the physical engines. Install it with
vyges install physical(orvyges install sdc), then runvyges physical sdc. It is also a standalonevyges-sdcbinary on your PATH (the integration contract for flow authors).
vyges-sdc answers: are these constraints whole? A timer computes timing on whatever
constraints it is given. A wrong constraint does not produce a wrong-looking report; it produces a
clean one:
- an output with no
set_output_delayis a path nobody checks; - a clock on a port that drives nothing leaves every register untimed while the SDC still looks populated;
- a
set_false_pathwith a typo names nothing and quietly does nothing.
Run it
vyges install physical # one-time
vyges physical sdc check --sdc design.sdc --netlist design.v --lib cells.lib
vyges physical sdc write --sdc design.sdc -o normalised.sdc
check
The constraints are checked against the netlist, with the Liberty to say which cells are registers:
| Check | Finds |
|---|---|
| completeness | inputs and outputs with no I/O delay; registers no clock reaches |
| endpoint coverage | the share of timing endpoints constrained at all, reported on every run, clean ones included |
| consistency | duplicate clock names, clocks on ports the design does not have |
| exception reachability | set_false_path / set_multicycle_path naming no object, or no structural path |
| declared clock domains | with --metadata, each clock_domains entry in vyges-metadata.json against the SDC’s clocks |
Errors (for example, registers no clock reaches) make the exit code 1 and the descriptor’s
clean assertion false. Warnings (for example, an unconstrained output) are reported and
leave both alone.
write
write reads the SDC into the shared constraint model and writes it back out in canonical form:
- in the order a timer writes its own constraint database;
- with each value in the shortest form that reads back to the same number;
- in the units the file declared.
Nothing is dropped silently. If any command would be left out (one the model does not carry,
or one it refused or could not evaluate), write writes no file. It exits 1 and lists every such
command:
{ "command": "write", "status": "refused", "complete": false,
"not_written": [ "not modelled: set_disable_timing" ] }
--partial writes the rest, and each command it left out appears in the file as a
# not written: line. complete stays false, and it is what the sdc.write tool asserts, so an
agent never mistakes a partial file for a whole one.
Object queries that need the design (-filter, -of_objects, -regexp) are evaluated when a
netlist and Liberty are given, and refused (listed as not written) when they are not.
Exit status and events
| Exit | Meaning |
|---|---|
| 0 | check: no errors (with --fail-on-warning, no warnings either); write: written |
| 1 | a finding: check found an error (or a warning with --fail-on-warning), or write refused |
| 2 | usage, or an input that could not be read |
1 and 2 are kept apart so a gate never reads a missing file as a constraint failure, or the
reverse. Every run also leaves a vyges-events trail on stderr (JSONL when piped,
text on a terminal; VYGES_LOG_FORMAT forces either), with the SDC file as each event’s object:
| Code | When |
|---|---|
SDC-<finding> | one per check finding, at its severity (e.g. SDC-UNCONSTRAINED-OUTPUT) |
SDC-CHECK / SDC-WRITE | the command’s summary (write: complete, PARTIAL or REFUSED) |
SDC-NOT-WRITTEN | one per command write left out |
SDC-READ | debug: what the file held (clocks, delays, exceptions, ignored commands) |
SDC-INPUT / SDC-IPMETA | an input could not be read / --metadata could not, other checks still ran |
-q/-v follow the suite’s verbosity contract: -q
warnings, -qq errors, -qqq silent, -v debug, -vv trace; a flag overrides VYGES_LOG.
One implementation
The checker and the writer are the vyges-loom SDC model’s own code, the same code
vyges-sta-si runs. vyges physical sdc check and vyges loom sta-si sdc-lint report
the same findings, and the timer reads a file exactly as sdc does.