A flop entry adds setup and hold limits plus clock-to-Q to cost and load. This lesson reads the real DFF and DFFR groups, then prices a sync-reset register against an async-reset one from the recorded reports.
The DFF entry replaces output arcs with constraint groups on D against CLK plus clock-to-Q on Q, copied exactly from course.lib. Treat both constraint axes as slews: the constrained-data (D) transition down the rows (index_1), the related-clock (CLK) transition across the columns (index_2), exactly as the rise_constraint and fall_constraint groups list them. Real libraries name these axes related_pin_transition and constrained_pin_transition in a dedicated template; course.lib reuses its shared dt template instead, so read the second index as the clock slew, a teaching simplification stated once here.
Constraint (exact from course.lib) | Clock slew 0.01 | Clock slew 0.1 |
|---|---|---|
Setup, rising (data slew 0.01) | 0.05 | 0.06 |
Setup, rising (data slew 0.1) | 0.06 | 0.07 |
Hold, rising (data slew 0.01) | 0.0 | 0.01 |
Hold, rising (data slew 0.1) | 0.01 | 0.02 |
Clock-to-Q is a different shape: clock-pin transition down the rows, output load across the columns, copied from the DFF Q group below.
Clock slew (rows) / output load (cols) | 0.01 | 0.1 |
|---|---|---|
0.01 | 0.15 | 0.17 |
0.1 | 0.18 | 0.21 |
setup check with exact library corners (ns)
clock period = 1.0, data arrival = 0.60, setup = 0.07
required = period - setup = 1.0 - 0.07 = 0.93
slack = required - arrival = 0.93 - 0.60 = 0.33 (met)The DFFR entry repeats the DFF timing groups value for value. Two things differ: an RN pin with clear:!RN, the asynchronous reset, and area 10 instead of 8. A visible reset pin costs 2 units a bit; a synchronous reset needs gating on the D input of a plain DFF instead, as the run below shows, plus one inversion per bit where posedge RTL reset meets the active-low pin.
Two 8-bit registers, sync and async reset: synthesis lowers them to generic flops, dfflegalize shapes them, dfflibmap exchanges them for DFF and DFFR cells, and ABC maps the reset-gating logic under typical.constr, with eight of each flop asserted and no generic flops left.
read_liberty -lib course.lib
read_verilog <<EOV
module top(input clk, input srst, input arst, input [7:0] d1, input [7:0] d2, output reg [7:0] q1, output reg [7:0] q2);
always @(posedge clk) if (srst) q1 <= 8'b0; else q1 <= d1;
always @(posedge clk or posedge arst) if (arst) q2 <= 8'b0; else q2 <= d2;
endmodule
EOV
hierarchy -check -top top
synth -top top
dfflegalize -cell $_DFF_P_ 01 -cell $_DFF_PN0_ 01
dfflibmap -liberty course.lib
tee -o abc_flops.txt abc -liberty course.lib -constr typical.constr -D 1000
tee -o stat_flops.txt stat -liberty course.lib
write_json net_flops.json
select -assert-count 8 t:DFF
select -assert-count 8 t:DFFR
select -assert-none t:$_DFF_P_
select -assert-none t:$_DFF_PN0_
check
log PASS: sync resets map to DFF plus D-input gates, async resets to DFFREight DFF cells plus D-input reset gates for sync, eight DFFR cells for async: 8 DFF against 8 DFFR recorded. Per bit the async flop costs more, 10 against 8, but per register the sync gating costs more still: guess which totals more.
Mapped cells (recorded stat) | Count | Area |
|---|---|---|
DFF | 8 | 64 |
DFFR | 8 | 80 |
INV | 16 | 16 |
NOR2 | 8 | 16 |
The report separates the two styles exactly as the RTL promised. The saved netlist settles the split: every one of the 8 NOR2 cells takes srst straight on one input and inverted data on the other, so each sync bit computes NOR(NOT d, srst): the data is inverted, not the reset, which accounts for 8 of the 16 INVs. The remaining 8 INVs sit between arst and the DFFR RN pins, one per bit: the RTL resets on posedge arst while the library clear is active low. That duplication enters before ABC runs: the generic netlist already holds one $_NOT_ per bit off the shared arst net, and a probe mapping the same netlist with and without typical.constr records the same INV count, so ABC's buffer step under -D is not the cause. Why this ABC script keeps eight identical reset inverters instead of sharing one INV across all eight is not isolated. The sync register is eight DFF cells at 8 units plus 8 NOR2 and 8 INV, 64 + 24 = 88 units; the async register is eight DFFR cells at 10 units plus 8 reset INVs, for 88 units. The pair totals 40 cells at area 176 units. ABC's own summary prices only the cloud it mapped, 24 gates at area 32, and the stat rows agree: flops pass through ABC untouched.
The second script keeps the data paths and deletes the two resets: same widths, same clocks, only the reset style changes.
read_liberty -lib course.lib
read_verilog <<EOV
module top(input clk, input [7:0] d1, input [7:0] d2, output reg [7:0] q1, output reg [7:0] q2);
always @(posedge clk) q1 <= d1;
always @(posedge clk) q2 <= d2;
endmodule
EOV
hierarchy -check -top top
synth -top top
dfflegalize -cell $_DFF_P_ 01 -cell $_DFF_PN0_ 01
dfflibmap -liberty course.lib
tee -o abc_plain.txt abc -liberty course.lib -constr typical.constr -D 1000
tee -o stat_plain.txt stat -liberty course.lib
select -assert-count 16 t:DFF
select -assert-none t:DFFR
check
log PASS: reset-less registers map to sixteen DFF cellsThe reset-less pair maps to 16 DFF cells at area 128, against 40 cells at area 176 with resets. The 48-unit gap is the reset bill: eight 2-unit DFF-to-DFFR upgrades is 16, plus the 24-unit sync cloud, plus 8 async reset inverters.
Mapped cells, no resets (recorded stat) | Count | Area |
|---|---|---|
DFF | 16 | 128 |
Drive strength is the same function in a larger size. The teaching library offers one size per function; sized.lib offers three drive strengths in library units: INV at 1, INV_X2 at 1.6, INV_X4 at 2.6. A Vt flavour is the same trade as a process option: low Vt faster and leakier, high Vt slower and tighter.
Choice | Faster side | Cheaper side |
|---|---|---|
Drive strength | A larger cell drives more load sooner. | A smaller cell costs less area and power. |
Vt flavour | Low Vt switches faster. | High Vt leaks less. |
Real libraries add variants the mapper picks directly:
Variant | What it adds | In course.lib? |
|---|---|---|
Scan flop | A scan-in mux on D plus a scan-out for test shifting. | Not in this library |
Enable flop | A clock-enable term gating the D input. | Not in this library |
ICG cell | A latch plus AND gate that gates the clock cleanly. | Not in this library |
Latch | Level-sensitive storage, transparent while open. | Not in this library |
Library power is leakage per cell plus switching energy per arc. The teaching library omits power tables, so the arithmetic below uses stated example parameters, with alpha as the 0-to-1 transition probability per clock (0.2, no hidden half).
EXAMPLE parameters (not library data): alpha = 0.2 transitions 0-to-1 per clock
C = 10 fF (one teaching-library input pin), V = 1.0 V, f = 100 MHz
P = alpha x C x V^2 x f
= 0.2 x 10e-15 F x (1.0 V)^2 x 100e6 Hz
= 0.2 x 10e-15 x 1.0 x 1e8 W
= 0.2 x 1e-6 W = 0.2 uWReal Liberty writes the same two parts as cell attributes; the excerpt below is syntax shape only, not staged library data:
# not-run: real Liberty power syntax, shape only, not staged files
cell_leakage_power : 0.5;
internal_power() {
related_pin : "CLK";
rise_power(dt) {
index_1("0.01,0.1");
index_2("0.01,0.1");
values("0.02,0.03","0.04,0.05");
}
}Required is 0.93 ns and slack is 0.93 - 0.60 = 0.33 ns. The setup came from the DFF rise_constraint group copied from course.lib, whose corners run 0.05 to 0.07 across the data and clock slews.
Two 8-bit resets: eight DFF-to-DFFR upgrades at 2 units each is 16, plus the recorded sync cloud of 8 NOR2 and 8 INV at 24 units, plus 8 reset inverters on the async side. Same data paths and clocks; the gap is the measured reset bill.
Every number and picture on this page comes from Yosys 0.69 runs of the two scripts shown, recorded by the course checker (scripts/tools/run-rtl-testbenches.mjs with COURSE=synth): sync-plus-async 8-bit registers and reset-less 8-bit registers through synth, dfflegalize, dfflibmap, and abc against course.lib, with stat -liberty areas and a write_json netlist that splits the recorded INVs by fanout between the NOR2 data inputs and the DFFR reset pins. Timing groups are copied exactly from scripts/tools/synth-libs/course.lib; drive strengths quote scripts/tools/synth-libs/sized.lib; power arithmetic uses stated example parameters. The variants table and the power-syntax excerpt are illustrative (none of those cells or attributes are in course.lib), and the reset-duplication cause beyond the probe is stated as not isolated.