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
Description
write_timing_modelgenerates incorrectbit_widthvalues in Liberty output for ports declared with ascending bit ranges (e.g.[0:10]). The generated.libis then rejected by Yosys with anIncompatible array typeerror, 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():The
+1is insidestd::abs()instead of outside. This gives the correct result only for descending ranges.One-line fix:
Reproduction
Source Verilog (ascending port, generated by OpenFPGA):
Generated Liberty (incorrect):
Yosys error when consuming this lib:
Yosys validates:
bit_width != (max(bit_from, bit_to) - min(bit_from, bit_to) + 1)→9 != 11→ parse failure.Test Case
run.tcl:Confirmed output against OpenSTA 2.5.0 (efabless/openlane Docker):
Test case archive attached: [opensta_bug_report.tar.gz]
Impact
Blocks use of
write_timing_modeloutput asEXTRA_LIBSin OpenLane for any design with ascending-range ports. Specifically affects OpenFPGA-generated netlists which use[0:N]conventions throughout — the hardened macro.libfiles cannot be fed back into Yosys for top-level chip assembly.Related
write_verilog(ascending ranges incorrectly rewritten to descending)