The-OpenROAD-Project / The-OpenROAD-Project/OpenSTA
write_timing_model: incorrect bit_width for ascending bus ranges (off-by-one in std::abs)
Nobody has claimed this yet.
- Dominant language
- Verilog
- Stars
- 619
- Forks
- 270
- Avg merge
- 5d 15h
- Merged PRs (30d)
- 4
Description
Description
write_timing_model generates incorrect bit_width values in Liberty output for ports declared with ascending bit ranges (e.g. [0:10]). The generated .lib is then rejected by Yosys with an Incompatible array type error, blocking top-level assembly of designs with ascending-range ports.
This was discovered while hardening OpenFPGA-generated netlists targeting sky130A via OpenLane. OpenFPGA uses ascending [0:N] port conventions throughout its generated RTL.
Root Cause
In liberty/LibertyWriter.cc, writeBusDcls():
// current (buggy)
sta::print(stream_, " bit_width : {};\n", std::abs(dcl->from() - dcl->to() + 1));
// ascending [0:10]: std::abs(0 - 10 + 1) = std::abs(-9) = 9 ← WRONG, should be 11
// descending [10:0]: std::abs(10 - 0 + 1) = 11 ← correct
The +1 is inside std::abs() instead of outside. This gives the correct result only for descending ranges.
One-line fix:
sta::print(stream_, " bit_width : {};\n", std::abs(dcl->from() - dcl->to()) + 1);
Reproduction
Source Verilog (ascending port, generated by OpenFPGA):
module bug_reproducer (
input prog_clk,
input [0:10] chanx_left_in, // 11-bit ascending
input [10:0] chanx_left_in_desc // 11-bit descending (correct)
);
endmodule
Generated Liberty (incorrect):
type ("chanx_left_in") {
base_type : array;
data_type : bit;
bit_width : 9; /* BUG — should be 11 */
bit_from : 0;
bit_to : 10;
}
Yosys error when consuming this lib:
ERROR: Incompatible array type 'chanx_left_in': bit_width=9, bit_from=0, bit_to=10.
Yosys validates: bit_width != (max(bit_from, bit_to) - min(bit_from, bit_to) + 1) → 9 != 11 → parse failure.
Test Case
run.tcl:
read_liberty macro.lib
read_verilog macro.v
link_design bug_reproducer
write_timing_model out.lib
set f [open out.lib r]
set content [read $f]
close $f
if {[regexp {bit_width\s*:\s*9} $content]} {
puts "BUG CONFIRMED: bit_width : 9 in output (should be 11)"
} elseif {[regexp {bit_width\s*:\s*11} $content]} {
puts "PASS: bit_width : 11 correctly written"
}
Confirmed output against OpenSTA 2.5.0 (efabless/openlane Docker):
BUG CONFIRMED: bit_width : 9 in output (should be 11)
Test case archive attached: [opensta_bug_report.tar.gz]
Impact
Blocks use of write_timing_model output as EXTRA_LIBS in OpenLane for any design with ascending-range ports. Specifically affects OpenFPGA-generated netlists which use [0:N] conventions throughout — the hardened macro .lib files cannot be fed back into Yosys for top-level chip assembly.
Related
- The-OpenROAD-Project/OpenROAD#578 — same root cause in
write_verilog(ascending ranges incorrectly rewritten to descending)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read liberty/LibertyWriter.cc, focusing on writeBusDcls(), then use the supplied run.tcl reproduction with the ascending and descending bus ranges. Done means write_timing_model emits bit_width : 11 for the [0:10] port and the generated Liberty is accepted by the described Yosys validation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100