Rethink how we run per-pipeline-stage static timing analysis
- Dominant language
- C++
- Stars
- 1.9k
- Forks
- 283
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 135
Description
Currently we use a Yosys script to split the synthesized Verilog into one module per pipeline stage (https://github.com/google/xls/blob/main/xls/synthesis/yosys/synth_by_stage.tcl script). Then, static timing is run on each stage module independently (https://github.com/google/xls/blob/main/xls/synthesis/openroad/sta_by_stage.tcl).
The layer of flops between stages is included at the output of a module. Each module has paths input -> logic -> flop -> output.
We have an example where there is a large fanout from a flop to the logic it drives. This net is at the stage boundary. At the sink side, the delay from the large fanout is not not accounted for correctly. Our STA script does not set input drive strength or delay, so it seems infinite drive strength is assumed. So the large delay contribution from the high fanout is not attributed to any individual stage (but it IS correctly calculated when running STA on the entire design, which is how we noticed this issue).
Two directions for fixing this come to mind:
* for all module input ports, set the drive cell to be a drive-strength-1 flop from the target library (use openSTA command `set_driving_cell`).
* attempt to rewrite the STA script so that it can operate directly on the flattened netlist (no module/stage hierarchy). This might be possible if we restrict the `report_checks` command for each stage to endpoints that match the stage's flop name pattern (e.g. `p6_*`).
Contributor guide
Assessment
This issue has not been assessed yet.