The-OpenROAD-Project / OpenSTA

OpenSTA engine
GNU General Public License v3.0
404 stars 173 forks source link

Pins that are logically connected don't have the same net and are not equivalent as endpoints #190

Closed smunaut closed 10 months ago

smunaut commented 1 year ago

Let's use this minimal example as a base to illustrate the issue :

module top (
    input  wire pad_in0,
    input  wire pad_in1,
    output wire pad_out
);

    wire int_out;

    sub mux0_I (
        .in0 (pad_in0),
        .in1 (pad_in1),
        .out (pad_out)
    );

    sub mux1_I (
        .in0 (pad_in0),
        .in1 (pad_in1),
        .out (int_out)
    );

endmodule // top

module sub (
    input  wire in0,
    input  wire in1,
    output wire out
);

    sky130_fd_sc_hd__ebufn_8 cell0_I (
        .A    (in0),
        .TE_B (in1),
        .Z    (out)
    );

endmodule // top

Now if I look at the pins of the mux1_I instance and the pins of the library cell output inside of that instance and check which net they are attached to :

% get_nets -of_objects [get_pins mux1_I/cell0_I/Z]
_90596fdd3a560000_p_Net
% get_nets -of_objects [get_pins mux1_I/out]
_60586fdd3a560000_p_Net

They're not the same net ... even though realistically they should be, since it's the same connection.

And if you try to use those pins as endpoints for timing path analysis :

% find_timing_path -from [all_inputs] -to  [get_pins mux1_I/cell0_I/Z]
_207070dd3a560000_p_PathEnd
% find_timing_path -from [all_inputs] -to [get_pins mux1_I/out]
%

And as you see it finds timing path to the first one ... but not the second one ... (edited)

But of course the first name is very impractical to find because it's some random internal name that would be auto-generated by synthesis in a real design.

jjcherry56 commented 1 year ago

The nets for the pins are different because the pins are at different hierarchy levels and the netlist is hierarchical. Exceptions using -through net would not work properly if the nets were the same.

The issue you are seeing is more an artifact of the output of mux_1 not being connected to anything. It works correctly for mux_0, which is connected to an output port.

-to fails because mux1_I/out is not an endpoint puts [find_timing_path -from [all_inputs] -to [get_pins mux1_I/out]]

-through fails because the path is unconstrained puts [find_timing_path -from [all_inputs] -through [get_pins mux1_I/out]]

fails because there are no paths through mux1_I/out because the pin is unconnected and hence has no wire arc from the gate output puts [find_timing_path -from [all_inputs] -through [get_pins mux1_I/out] -unconstrained]

'works puts [find_timing_path -from [all_inputs] -through [get_pins mux0_I/out] -unconstrained]

smunaut commented 1 year ago

Yeah, here it's not connected to anything, in my actual case it's connected to a blackbox component. The idea was to be able to caracterize the timing path from the i/o port up to the pin of the blackbox (independently of what the blackbox is).

But I guess that isn't possible. My best solution ATM is to replace the blackbox component by a dummy one that has dummy drivers / receiver in them and use those as endpoints instead of the pin of the blackbox itself.

jjcherry56 commented 1 year ago

Yes, you need a black box. You just need the verilog instance and it will create a black box (albeit with no input cap etc)