Two numbers decide whether a clock is fast enough: when the data arrives at the capturing flop, and when it is required there. Their difference is the slack. The path lives in vipexp, a launch flop and a capture flop around four combinational stages, mapped below against course.lib with the typical output load and a loose 1000 ps target.
The taps t1 to t4 each export one intermediate net. They are not product features; they pin every stage so the mapper must keep all four cells. Without them ABC would fold the chain, and the path the later lessons price would not exist in the recording.
read_verilog <<EOV
module vipexp(input clk, input a, b, c, d, input din, output reg qout, output t1, t2, t3, t4);
reg q1;
wire s1, s2, s3, s4;
always @(posedge clk) q1 <= din;
assign s1 = ~(q1 & a);
assign s2 = ~(s1 | b);
assign s3 = s2 ^ c;
assign s4 = ~(s3 ^ d);
always @(posedge clk) qout <= s4;
assign t1 = s1;
assign t2 = s2;
assign t3 = s3;
assign t4 = s4;
endmodule
EOV
hierarchy -check -top vipexp
synth -top vipexp -flatten
dfflegalize -cell $_DFF_P_ 01 -cell $_DFF_PN0_ 01
tee -o ltp_generic.txt ltp
design -save generic
dfflibmap -liberty course.lib
tee -o abc_typ.txt abc -liberty course.lib -constr typical.constr -D 1000
clean
tee -o stat_typ.txt stat -liberty course.lib
write_json net_typ.json
select -assert-none t:$not t:$and t:$or t:$xor t:$mux t:$_NOT_ t:$_AND_ t:$_OR_ t:$_XOR_ t:$_NAND_ t:$_NOR_ t:$_DFF_P_ t:$_MUX_
select -assert-count 2 t:DFF
select -assert-count 1 t:NAND2
select -assert-count 1 t:NOR2
select -assert-count 1 t:XOR2
select -assert-count 1 t:XNOR2
check
design -load generic
dfflibmap -liberty course.lib
tee -o abc_tight.txt abc -liberty course.lib -constr typical.constr -D 100
clean
select -assert-none t:$not t:$and t:$or t:$xor t:$mux t:$_NOT_ t:$_AND_ t:$_OR_ t:$_XOR_ t:$_NAND_ t:$_NOR_ t:$_DFF_P_ t:$_MUX_
select -assert-count 2 t:DFF
select -assert-count 1 t:NAND2
select -assert-count 1 t:NOR2
select -assert-count 1 t:XOR2
select -assert-count 1 t:XNOR2
log PASS: launch flop plus four stages plus capture flop mappedThe script elaborates and flattens the RTL, legalizes the flops, saves the generic netlist, then lets ABC cover the rest. The assertions pin the cover: no generic gate survives, and the histogram must read two library flops plus one cell of each combinational kind.
Expect a few hundred picoseconds: four small cells plus the output loads cannot fill a nanosecond. The 100 ps run then reports exactly the same netlist. course.lib offers one size per cell, so a tighter target buys nothing; the table below shows it.
Run | Cells | Area | Delay reached |
|---|---|---|---|
1000 ps target | 4 | 14 | 610 ps |
100 ps target | 4 | 14 | 610 ps |
Both runs report 4 cells at area 14 with arrival 610 ps: the loose run already takes the cheapest cover and the tight run returns it unchanged. The recorded histogram reads DFF x2, NAND2 x1, NOR2 x1, XNOR2 x1, XOR2 x1. A target below what the library can give changes nothing.
The 100 ps line is the break-it: this one-size library has no faster cover to give, so the report is identical down to the picosecond. If tightening a target ever leaves every number frozen, check the library before blaming the tool.
Arrival time is when a transition reaches a node: clock-to-Q, then each stage delay in turn. On the recorded path ABC's number is the combinational part only, 0.61 ns from launch output to endpoint. The full arrival adds the launching flop's clock-to-Q, priced from the DFF table at 0.163 ns, for a model total of 0.781 ns.
Required time is the deadline at that node: the capturing clock edge minus margins. For a setup check with zero skew it is the period minus the capturing flop's setup time, read from the DFF table as 0.058 ns, so against a hand-derived 1.00 ns period the requirement is 0.942 ns, labelled model throughout.
The sign convention for the whole topic is stated here once: slack is required minus arrival, so positive slack meets timing and negative slack violates it by that magnitude. Every later lesson uses this direction without restating it. One reporting habit to know: some tools clamp the reported worst slack at zero when nothing violates, so a clean headline can print 0 where the true margin is positive; read the per-endpoint slacks, not just the headline.
Read the figure left to right. Each segment is one model stage delay from the calculator lesson at its own slew and a 0.06 pF load. The stack ends at the model arrival and the dashed line marks the requirement; the gap is the slack. The figure carries model numbers, not tool output; the only recorded delay on this page is the table value above.
Before any delay arithmetic, the script asks for the shape of the design: ltp walks the generic netlist and prints the longest topological path. The report below names a 6-level path from the clock through the launch flop, one stage per tap, into the capture flop. That count is structure, not time: it ignores cell delays, so it can rank paths differently from timing.
5. Executing LTP pass (find longest path).
Longest topological path in vipexp (length=6):
0: \clk
1: \q1 (via $auto$ff.cc:337:slice$91)
2: \t1 (via $abc$92$blif$92$0)
3: \t2 (via $abc$92$blif$92$1)
4: \t3 (via $abc$92$blif$92$2)
5: \t4 (via $abc$92$blif$92$3)
6: \qout (via $auto$ff.cc:337:slice$90)The excerpt is shown exactly as printed. ltp counts cells along a topological path, not delay, with the taps as waypoints. After mapping, the same command reports zero, because the library cells are unknown modules with no pin directions; read_liberty -lib course.lib first lets it walk mapped cells. A path through a flop is not one timing path, so ltp -noff excludes flop cells. This lesson records the generic depth so nobody quotes the mapped zero as a path.
About 0.77 ns: 0.61 ns recorded plus 0.163 ns of model clock-to-Q. ABC measured launch-output-to-endpoint only; the flop delay is a library-table addition, not tool output.
No. The report is the delay ABC achieved, not the target it accepted: 610 ps of arrival against a 100 ps requirement is a large negative slack. An unchanged report means the library is exhausted, never that the target is met.
Arrival, area and cell counts on this page come from one Yosys run of the script shown, recorded by the course checker (scripts/tools/run-rtl-testbenches.mjs with COURSE=synth): the vipexp block (launch flop, four stages, capture flop, one tap per stage) mapped with ABC against the teaching library course.lib at a 1000 ps target with typical.constr (BUF driver, 0.05 pF load), plus a 100 ps re-run from the saved generic netlist. The ltp excerpt is the recorded generic report. The library is fictional, so absolute delays are teaching values; the slack arithmetic is the point. Stage arrivals and the required time are model numbers interpolated from the exact library rows, labelled so on the page.