Skip to content

write_timing_model: incorrect bit_width for ascending bus ranges (off-by-one in std::abs) #360

@JayPankajPatel

Description

@JayPankajPatel

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions