openlane2 icon indicating copy to clipboard operation
openlane2 copied to clipboard

Time borrowing causes flow to fail

Open toivoh opened this issue 1 year ago • 4 comments

Description

Feeding the data input of a positive level triggered latch with the data output of a positive edge triggered flip-flop causese OpenSTA to invoke time borrowing. The setup path is listed as 0.000000 slack (MET), borrowing only enough time from data output of the latch to achieve a setup slack of zero for the input path. Later in the flow the zero setup slack in all corners uncluding the TT corners causes the flow to fail, claiming setup violations.

Expected Behavior

I would expect the flow not to fail, since OpenSTA used the zero setup slack to communicate a met setup condition.

Environment report

kernel: Linux
kernel_version: 5.15.153.1-microsoft-standard-WSL2
supported: True
distro: ubuntu
distro_version: 22.04
python_version: 3.10.12
python_path:
  - /home/toivo/.local/bin
  - /usr/lib/python310.zip
  - /usr/lib/python3.10
  - /usr/lib/python3.10/lib-dynload
  - /home/toivo/.local/lib/python3.10/site-packages
  - /usr/local/lib/python3.10/dist-packages
  - /usr/lib/python3/dist-packages
tkinter: True
container_info:
  engine: docker
  version: 26.1.2
  conmon: False
  rootless: False
nix_info:
  version_string: nix (Nix) 2.23.1
  channels:
  nix_command: True
  flakes: True

Reproduction material

The error was produced using the Tiny Tapeout 8 local hardening setup, which uses OpenLane 2. The source file contents were

module top (
		input  wire [7:0] ui_in,    // Dedicated inputs
		output wire [7:0] uo_out,   // Dedicated outputs
		input  wire [7:0] uio_in,   // IOs: Input path
		output wire [7:0] uio_out,  // IOs: Output path
		output wire [7:0] uio_oe,   // IOs: Enable path (active high: 0=input, 1=output)
		input  wire       ena,      // always 1 when the design is powered, so you can ignore it
		input  wire       clk,      // clock
		input  wire       rst_n     // reset_n - low to reset
	);

	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 <= ui_in[0];
	end
	assign uo_out = {7'd0, r_out};

	assign uio_out = 0;
	assign uio_oe  = 0;
endmodule

The above code follows the Tiny Tapeout 8 top module template. If you don't have to do that, it should be enough with

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

Relevant log output

Excerpt from 51-openroad-stapostpnr/max_tt_025C_1v80/sta.log:

	======================= max_tt_025C_1v80 Corner ===================================

	Startpoint: _01_ (rising edge-triggered flip-flop clocked by clk)
	Endpoint: latch (positive level-sensitive latch clocked by clk)
	Path Group: clk
	Path Type: max

	Fanout         Cap        Slew       Delay        Time   Description
	---------------------------------------------------------------------------------------------
	                                  0.000000    0.000000   clock clk (rise edge)
	                                  0.000000    0.000000   clock source latency
	     1    0.009281    0.048256    0.031850    0.031850 ^ clk (in)
	                                                         clk (net)
	                      0.048263    0.000000    0.031850 ^ clkbuf_0_clk/A (sky130_fd_sc_hd__clkbuf_16)
	     2    0.018642    0.040678    0.125026    0.156876 ^ clkbuf_0_clk/X (sky130_fd_sc_hd__clkbuf_16)
	                                                         clknet_0_clk (net)
	                      0.040693    0.000967    0.157843 ^ clkbuf_1_0__f_clk/A (sky130_fd_sc_hd__clkbuf_16)
	     2    0.006818    0.030498    0.111099    0.268942 ^ clkbuf_1_0__f_clk/X (sky130_fd_sc_hd__clkbuf_16)
	                                                         clknet_1_0__leaf_clk (net)
	                      0.030499    0.000250    0.269193 ^ _01_/CLK (sky130_fd_sc_hd__dfxtp_1)
	     1    0.003762    0.048524    0.300794    0.569987 ^ _01_/Q (sky130_fd_sc_hd__dfxtp_1)
	                                                         r_in (net)
	                      0.048524    0.000218    0.570205 ^ latch/D (sky130_fd_sc_hd__dlxtp_1)
	                                              0.570205   data arrival time

	                                  0.000000    0.000000   clock clk (rise edge)
	                                  0.000000    0.000000   clock source latency
	     1    0.009281    0.048256    0.031850    0.031850 ^ clk (in)
	                                                         clk (net)
	                      0.048263    0.000000    0.031850 ^ clkbuf_0_clk/A (sky130_fd_sc_hd__clkbuf_16)
	     2    0.018642    0.040678    0.125026    0.156876 ^ clkbuf_0_clk/X (sky130_fd_sc_hd__clkbuf_16)
	                                                         clknet_0_clk (net)
	                      0.040693    0.000960    0.157836 ^ clkbuf_1_1__f_clk/A (sky130_fd_sc_hd__clkbuf_16)
	     1    0.002152    0.026067    0.105543    0.263380 ^ clkbuf_1_1__f_clk/X (sky130_fd_sc_hd__clkbuf_16)
	                                                         clknet_1_1__leaf_clk (net)
	                      0.026067    0.000151    0.263530 ^ latch/GATE (sky130_fd_sc_hd__dlxtp_1)
	                                 -0.250000    0.013530   clock uncertainty
	                                  0.000000    0.013530   clock reconvergence pessimism
	                                  0.556674    0.570205   time borrowed from endpoint
	                                              0.570205   data required time
	---------------------------------------------------------------------------------------------
	                                              0.570205   data required time
	                                             -0.570205   data arrival time
	---------------------------------------------------------------------------------------------
	                                              0.000000   slack (MET)

	Time Borrowing Information
	------------------------------------------------
	clk nominal pulse width                10.000000
	clock latency difference                0.009987
	library setup time                     -0.198930
	------------------------------------------------
	max time borrow                         9.811056
	------------------------------------------------
	actual time borrow                      0.556674
	open edge uncertainty                  -0.250000
	------------------------------------------------
	time given to startpoint                0.306674
	------------------------------------------------

From end of OpenLane2 console output:

	[04:51:50] WARNING  [Checker.SetupViolations] Setup violations found in the following corners:               flow.py:673
	                    * max_ff_n40C_1v95
	                    * max_ss_100C_1v60
	                    * min_ff_n40C_1v95
	                    * min_ss_100C_1v60
	                    * nom_ff_n40C_1v95
	                    * nom_ss_100C_1v60
	[04:51:50] WARNING  [Misc.ReportManufacturability] klayout__drc_error__count not reported. KLayout.DRC may   flow.py:673
	                    have been skipped.
	[04:51:50] ERROR    The following error was encountered while running the flow:                          __main__.py:152
	                    One or more deferred errors were encountered:
	                    Setup violations found in the following corners:
	                    * max_tt_025C_1v80
	                    * min_tt_025C_1v80
	                    * nom_tt_025C_1v80
	[04:51:50] ERROR    OpenLane will now quit.                                                              __main__.py:153
	Classic - Stage 68 - Netgen LVS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸━━━━ 67/75 0:00:312024-07-04 06:51:50,311 - project    - ERROR    - harden failed

toivoh avatar Jul 04 '24 18:07 toivoh

Could you upload the entire raw log file please?

donn avatar Jul 04 '24 20:07 donn

Of course. Which one, sta.log or something else?

toivoh avatar Jul 05 '24 04:07 toivoh

sta.log

donn avatar Jul 05 '24 23:07 donn

sta.log

toivoh avatar Jul 06 '24 05:07 toivoh

My workaround for this was:

diff --git a/openlane/scripts/openroad/sta/corner.tcl b/openlane/scripts/openroad/sta/corner.tcl
index ce3f452..b15b6d0 100644
--- a/openlane/scripts/openroad/sta/corner.tcl
+++ b/openlane/scripts/openroad/sta/corner.tcl
@@ -292,7 +292,7 @@ foreach path $hold_paths {
     }
 }

-set setup_violating_paths [find_timing_paths -unique_paths_to_endpoint -path_delay max -sort_by_slack -group_count $max_violator_count -slack_max 0]
+set setup_violating_paths [find_timing_paths -unique_paths_to_endpoint -path_delay max -sort_by_slack -group_count $max_violator_count -slack_max -0.000001]
 foreach path $setup_violating_paths {
     set start_pin [get_property $path startpoint]
     set end_pin [get_property $path endpoint]

I'm not sure if that's good enough to take as a fix!

MichaelBell avatar Sep 06 '24 19:09 MichaelBell