parallaxsw / OpenSTA

GNU General Public License v3.0
52 stars 23 forks source link

Setup slack is zero when time borrowing, pessimistic for latches #94

Closed toivoh closed 2 weeks ago

toivoh commented 2 months ago

For latches, OpenSTA considers the normal setup timing case to be that input data should arrive before the event when latch becomes transparent, and that the output data becomes valid triggered by this event. Only if data does not arrive before the latch becomes transparent, time is borrowed from the setup time for the paths starting at the data output, borrowing only as much time as needed to give the input path a setup slack of zero. This causes the setup slack to (sometimes severely) underestimate the setup timing margin, especially when time borrowing, and the latter case causes the OpenLane 2 flow to fail, since it considers a setup slack of zero to be a timing violation.

Setup slack should be a measure of the margin for timing degradation before setup timing constraints start to fail; ideally how much the clock period can be reduced before this happens. From this point of view latches should not borrow as little setup time as needed to reach zero slack. Ideally, they they should borrow so much time that the setup slack over all paths involving the latch is maximized. I realize that implementing such an optimization most likely amounts to a major effort that would not be motivated.

My suggestion is instead to add an option for target minimum setup time for timing paths ending at the D input of latches. If the setup time up to the event when the latch becomes transparent does not reach the target setup time, time borrowing is invoked to try to reach the target time (not borrowing more than available, of course). This would allow the user to find a suitable timing margin to trade off setup slack coming into and out of latches for a given design.

Example: The following module (using the sky130 pdk) causes time borrowing and a setup slack of zero:

module top (
        input wire clk,
        input wire d_in,
        output wire d_out
    );

    reg r_in, r_out;
    wire q;

    sky130_fd_sc_hd__dlxtp_1 latch( .GATE(clk), .D(r_in), .Q(q));

    always @(posedge clk) begin
        r_out <= q;
        r_in <= d_in;
    end
    assign d_out = r_out;
endmodule
parallaxsw commented 2 weeks ago

The existing behavior is consistent with other tools. I am not interested in implementing your vision of latch behavior but since it is open source you can obviously implement it yourself.