Skip to content

Instantly share code, notes, and snippets.

@brabect1
Last active July 6, 2025 14:41
Show Gist options
  • Select an option

  • Save brabect1/7d76f02f75a8ad88d76f7827400c9e42 to your computer and use it in GitHub Desktop.

Select an option

Save brabect1/7d76f02f75a8ad88d76f7827400c9e42 to your computer and use it in GitHub Desktop.

Revisions

  1. brabect1 revised this gist Jul 6, 2025. 2 changed files with 80 additions and 0 deletions.
    80 changes: 80 additions & 0 deletions delay_annotation_with_sdf.rst
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,83 @@
    SDF Delay Annotation
    ====================

    SDF (Standard Delay Format) is a text format for storing time delays across elements of
    a (digital) circuit. The collection of these delays then represents the timing of the
    circuit. SDF is primarily an interchange format to communicate circuit timing among EDA
    tools, with STA tools being the typical producers and (digital) simulators being the
    typical consumers.

    .. figure:: sdf_annotation_process.png

    SDF syntax and semantics follows the same principles as the other formats for modeling
    delay aspects of (digital) IP cells (incl. standard gates). That is, like Liberty timing
    models and Verilog gate/cell models, SDF represents the delays at the cell level, either
    as wire delays between cells or as (propagation) delays from cell inputs to cell outputs.

    From the many elements that SDF can describe, these are the key ones:

    * *Wire delays* with the ``INTERCONNECT`` construct.
    * *Propagation delays* with the ``IOPATH`` construct.
    * (Cell) *timing constraints* with variety of constructs, ``SETUPHOLD``, ``RECREM``, ``WIDTH``, etc.

    TODO: ... SDF consistency with design data ... SDF consistency with

    IEEE Std 1800-2012:

    | SDF files contain timing values for specify path delays, specparam values, timing check constraints, and interconnect delays.
    SDF Syntax
    ----------

    Example from SDF 3.0 std.::

    (DELAYFILE
    (SDFVERSION "3.0")
    (DESIGN "BIGCHIP")
    (DATE "March 12, 1995 09:46")
    (VENDOR "Southwestern ASIC")
    (PROGRAM "Fast program")
    (VERSION "1.2a")
    (DIVIDER /)
    (VOLTAGE 5.5:5.0:4.5)
    (PROCESS "best:nom:worst")
    (TEMPERATURE -40:25:125)
    (TIMESCALE 100 ps)
    (CELL
    (CELLTYPE "BIGCHIP")
    (INSTANCE top)
    (DELAY
    (ABSOLUTE
    (INTERCONNECT mck b/c/clk (.6:.7:.9))
    (INTERCONNECT d[0] b/c/d (.4:.5:.6))
    )
    )
    )
    (CELL
    (CELLTYPE "AND2")
    (INSTANCE top/b/d)
    (DELAY
    (ABSOLUTE
    (IOPATH a y (1.5:2.5:3.4) (2.5:3.6:4.7))
    (IOPATH b y (1.4:2.3:3.2) (2.3:3.4:4.3))
    )
    )
    )
    (CELL
    (CELLTYPE "DFF")
    (INSTANCE top/b/c)
    (DELAY
    (ABSOLUTE
    (IOPATH (posedge clk) q (2:3:4) (5:6:7))
    (PORT clr (2:3:4) (5:6:7))
    )
    )
    (TIMINGCHECK
    (SETUPHOLD d (posedge clk) (3:4:5) (-1:-1:-1))
    (WIDTH clk (4.4:7.5:11.3))
    )
    )
    )

    Annotating from within Sim
    --------------------------
    @@ -106,6 +179,13 @@ Correlation between Model Elements
    }
    }

    Observations
    ------------

    * Single SDF is typically bound to a specific PVT and RC combination.
    * Multiple SDF files can be annotated to the same design element/module.
    * SDF may act as an input to STA tools for its delays being annotated to timing arcs.

    References
    ----------

    Binary file added sdf_annotation_process.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  2. brabect1 revised this gist Jul 4, 2025. 6 changed files with 35 additions and 5 deletions.
    6 changes: 6 additions & 0 deletions delay_annotation_with_sdf.rst
    Original file line number Diff line number Diff line change
    @@ -105,3 +105,9 @@ Correlation between Model Elements
    fall_constraint(scalar) { values("0.8"); }
    }
    }

    References
    ----------

    https://web.archive.org/web/20190215003139/https://www2.ece.ohio-state.edu/~bibyk/ee683/BolinM_part2_timing.pdf

    11 changes: 11 additions & 0 deletions myip.lib
    Original file line number Diff line number Diff line change
    @@ -92,6 +92,17 @@ library(myip) {
    fall_transition(scalar) { values("0.25"); }
    rise_transition(scalar) { values("0.25"); }
    }
    timing () {
    related_pin : "B" ;
    timing_type : combinational ;
    timing_sense : positive_unate ;
    when: "C";
    sdf_cond: "C==1'b1";
    cell_fall(scalar) { values("3.0"); }
    cell_rise(scalar) { values("3.0"); }
    fall_transition(scalar) { values("0.25"); }
    rise_transition(scalar) { values("0.25"); }
    }
    }
    }

    9 changes: 9 additions & 0 deletions myip.v
    Original file line number Diff line number Diff line change
    @@ -26,5 +26,14 @@ module myip(A, B, C, Y);
    always @(*) #0.5 Y = C ^ n1;

    specify
    specparam td_a2y_hl = 1.0;
    specparam td_a2y_lh = 1.0;
    specparam td_b2y_hl = 1.0;
    specparam td_b2y_lh = 1.0;
    specparam td_c2y = 1.0;

    (A *> Y) = (td_a2y_hl, td_a2y_lh);
    if (C==1'b1) (B *> Y) = (td_b2y_hl, td_b2y_lh);
    (C *> Y) = (td_c2y, td_c2y);
    endspecify
    endmodule
    6 changes: 3 additions & 3 deletions stdlib.lib
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@
    * limitations under the License.
    */

    // copied and edited from https://github.com/brabect1/sta_basics_course/blob/master/src/prime_time/sample_lib1.lib
    /* copied and edited from https://github.com/brabect1/sta_basics_course/blob/master/src/prime_time/sample_lib1.lib */
    library(stdlib) {
    /* general attributes */
    technology (cmos);
    @@ -80,8 +80,8 @@ library(stdlib) {
    related_pin : "A" ;
    timing_type : combinational ;
    timing_sense : positive_unate ;
    cell_fall(scalar) { values("2.0"); }
    cell_rise(scalar) { values("2.0"); }
    cell_fall(scalar) { values("0.0"); }
    cell_rise(scalar) { values("0.0"); }
    fall_transition(scalar) { values("0.3"); }
    rise_transition(scalar) { values("0.3"); }
    }
    4 changes: 4 additions & 0 deletions stdlib.v
    Original file line number Diff line number Diff line change
    @@ -21,4 +21,8 @@ module bufx1(A, Y);
    output Y;

    buf b(Y, A);

    specify
    (A => Y) = (0, 0);
    endspecify
    endmodule
    4 changes: 2 additions & 2 deletions tb.sv
    Original file line number Diff line number Diff line change
    @@ -22,6 +22,8 @@ module tb;
    top dut( .A, .B, .C, .Y );

    initial begin: test
    $timeformat(-9, 5, " ns", 10);

    $display("%t: Stimulus started ...", $realtime);
    A = 0;
    B = 0;
    @@ -39,8 +41,6 @@ module tb;
    $stop;
    end:test

    initial $timeformat(-9, 5, " ns", 10);

    initial begin
    string sdf_file_path;
    int fd;
  3. brabect1 revised this gist Jul 3, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion delay_annotation_with_sdf.rst
    Original file line number Diff line number Diff line change
    @@ -97,7 +97,7 @@ Correlation between Model Elements
    timing_type: hold_rising; (posedge CK) (0.3) (0.7) specparam thr = 0.7;
    rise_constraint(scalar) { values("0.3"); } ) specparam tsf = 0.2;
    fall_constraint(scalar) { values("0.2"); } (SETUPHOLD (negedge D) specparam thf = 0.8;
    } (posedge CK) (0.3) (0.7) $setuphold (posedge CK, posedge D, tsr, thr, ntfr);
    } (posedge CK) (0.2) (0.8) $setuphold (posedge CK, posedge D, tsr, thr, ntfr);
    timing() { ) $setuphold (posedge CK, negedge D, tsf, thf, ntfr);
    related_pin: "CK"; endspecify
    timing_type: setup_rising;
  4. brabect1 revised this gist Jul 3, 2025. 3 changed files with 106 additions and 2 deletions.
    104 changes: 104 additions & 0 deletions delay_annotation_with_sdf.rst
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,107 @@
    SDF Delay Annotation
    ====================

    IEEE Std 1800-2012:

    | SDF files contain timing values for specify path delays, specparam values, timing check constraints, and interconnect delays.

    Annotating from within Sim
    --------------------------

    Using ``$sdf_annotate(<file_path>, <inst_path>, , , "<delay_type>");``, where ``<delay_type>`` is one of ``maximum``, ``minimum`` and ``typical``.

    Questa example::

    ( mkdir -p questa && cd questa && \
    (test -d work || vlib work) && \
    vlog -work work ../myip.v ../stdlib.v && \
    vlog -work work ../top.v && \
    vlog -work work -sv ../tb.sv && \
    vsim -voptargs=+acc \
    -L work work.tb \
    +SDF_PATH=../top.sdf \
    -do "run -all; quit;" \
    -c \
    )

    Annotating through Simulator Options
    ------------------------------------

    Questa example::

    ( mkdir -p questa && cd questa && \
    (test -d work || vlib work) && \
    vlog -work work ../myip.v ../stdlib.v && \
    vlog -work work ../top.v && \
    vlog -work work -sv ../tb.sv && \
    vsim -voptargs=+acc \
    -L work work.tb \
    -sdfmax dut=../top.sdf \
    +sdf_verbose \
    -sdfannotatepercentage \
    -do "run -all; quit;" \
    -c \
    )

    Exporting SDF from STA Tool
    ---------------------------

    PrimeTime script example::

    set link_path [list myip.lib stdlib.lib]
    read_verilog top.v
    link
    if {[file exists constraints.sdc]} {
    source constraints.sdc
    }
    write_sdf \
    -context verilog \
    -no_edge \
    -version 3.0 \
    -exclude {checkpins} \
    -include { SETUPHOLD RECREM } \
    "[get_object_name [current_design]].export.sdf"


    Correlation between Model Elements
    ----------------------------------

    ::

    pin(Y) {
    timing () { specify
    related_pin: "A" ; specparam tdlh = 1.3;
    cell_fall(scalar) { values("1.7"); } ((IOPATH A Y (1.3)(1.7)) specparam tdhl = 1.7;
    cell_rise(scalar) { values("1.3"); } (A => Y) = (tdlh, tdhl);
    } endspecify
    pin(Y) {
    timing () {
    related_pin: "A" ;
    when: "B & !C"; specify
    sdf_cond: "B==1'b1 && C==1'b0"; specparam tdlh = 1.3;
    cell_fall(scalar) { values("1.7"); } (COND (B==1'b1 && C==1'b0 specparam tdhl = 1.7;
    cell_rise(scalar) { values("1.3"); } ((IOPATH A Y (1.3)(1.7)) if (B==1'b1 && C==1'b0) (A => Y) = (tdlh, tdhl);
    } ) endspecify
    pin(D) {
    direction: input;
    capacitance: 0.001; reg ntfr;
    timing() { specify
    related_pin: "CK"; (SETUPHOLD (posedge D) specparam tsr = 0.3;
    timing_type: hold_rising; (posedge CK) (0.3) (0.7) specparam thr = 0.7;
    rise_constraint(scalar) { values("0.3"); } ) specparam tsf = 0.2;
    fall_constraint(scalar) { values("0.2"); } (SETUPHOLD (negedge D) specparam thf = 0.8;
    } (posedge CK) (0.3) (0.7) $setuphold (posedge CK, posedge D, tsr, thr, ntfr);
    timing() { ) $setuphold (posedge CK, negedge D, tsf, thf, ntfr);
    related_pin: "CK"; endspecify
    timing_type: setup_rising;
    rise_constraint(scalar) { values("0.7"); }
    fall_constraint(scalar) { values("0.8"); }
    }
    }
    2 changes: 1 addition & 1 deletion myip.lib
    Original file line number Diff line number Diff line change
    @@ -66,6 +66,7 @@ library(myip) {
    cell(myip) {
    CELL_DESCR: "Custom macro cell.";
    area: 200.0;
    interface_timing: true;
    cell_leakage_power: 1.0;
    pin(A) {
    direction: input;
    @@ -82,7 +83,6 @@ library(myip) {
    pin(Y) {
    direction: output;
    max_capacitance: 0.05;
    function: "A";
    timing () {
    related_pin : "A" ;
    timing_type : combinational ;
    2 changes: 1 addition & 1 deletion tb.sv
    Original file line number Diff line number Diff line change
    @@ -44,7 +44,7 @@ module tb;
    initial begin
    string sdf_file_path;
    int fd;
    if ($value$plusargs("SDF_PATH=%s",tcl_sdf_file_path)) begin
    if ($value$plusargs("SDF_PATH=%s",sdf_file_path)) begin
    fd = $fopen (sdf_file_path, "r");
    if (fd) begin
    $sdf_annotate(sdf_file_path, tb.dut, , , "MAXIMUM");
  5. brabect1 created this gist Jul 3, 2025.
    3 changes: 3 additions & 0 deletions delay_annotation_with_sdf.rst
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    SDF Delay Annotation
    ====================

    98 changes: 98 additions & 0 deletions myip.lib
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,98 @@
    /*
    * Copyright 2025 Tomas Brabec
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    library(myip) {
    /* general attributes */
    technology (cmos);
    delay_model: table_lookup;

    /* units attributes*/
    time_unit: "1ns";
    voltage_unit: "1V";
    current_unit: "1mA";
    pulling_resistance_unit: "1ohm";
    leakage_power_unit: "1nW";
    capacitive_load_unit (1,pf);

    /* thresholds */
    slew_upper_threshold_pct_rise: 80;
    slew_lower_threshold_pct_rise: 20;
    slew_upper_threshold_pct_fall: 80;
    slew_lower_threshold_pct_fall: 20;
    input_threshold_pct_rise: 50;
    input_threshold_pct_fall: 50;
    output_threshold_pct_rise: 50;
    output_threshold_pct_fall: 50;

    /* process attributes */
    nom_process: 1.0;
    nom_voltage: 1.5;
    nom_temperature: 25.0;
    operating_conditions (tc_1p5v_25c) {
    process: 1;
    voltage: 1.5;
    temperature: 25;
    }
    default_operating_conditions : tc_1p5v_25c;

    /* default attributes */
    default_input_pin_cap: 1.0;
    default_inout_pin_cap: 1.0;
    default_output_pin_cap: 1.0;
    default_fanout_load: 1.0;
    default_max_transition: 1.0;
    default_cell_leakage_power: 0.0;
    default_leakage_power_density: 0.0;

    /* declare user attributes */
    define(CELL_DESCR,cell,string);

    /* ---------------- *
    * myip
    * ---------------- */
    cell(myip) {
    CELL_DESCR: "Custom macro cell.";
    area: 200.0;
    cell_leakage_power: 1.0;
    pin(A) {
    direction: input;
    capacitance: 0.001;
    }
    pin(B) {
    direction: input;
    capacitance: 0.001;
    }
    pin(C) {
    direction: input;
    capacitance: 0.001;
    }
    pin(Y) {
    direction: output;
    max_capacitance: 0.05;
    function: "A";
    timing () {
    related_pin : "A" ;
    timing_type : combinational ;
    timing_sense : positive_unate ;
    cell_fall(scalar) { values("2.0"); }
    cell_rise(scalar) { values("2.0"); }
    fall_transition(scalar) { values("0.25"); }
    rise_transition(scalar) { values("0.25"); }
    }
    }
    }

    }
    30 changes: 30 additions & 0 deletions myip.v
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    /*
    * Copyright 2025 Tomas Brabec
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    `timescale 1ns/1ps
    module myip(A, B, C, Y);
    input A, B, C;
    output Y;

    reg Y;
    reg n1;

    always @(*) #0.5 n1 = A ^ B;
    always @(*) #0.5 Y = C ^ n1;

    specify
    endspecify
    endmodule
    91 changes: 91 additions & 0 deletions stdlib.lib
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    /*
    * Copyright 2025 Tomas Brabec
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    // copied and edited from https://github.com/brabect1/sta_basics_course/blob/master/src/prime_time/sample_lib1.lib
    library(stdlib) {
    /* general attributes */
    technology (cmos);
    delay_model: table_lookup;

    /* units attributes*/
    time_unit: "1ns";
    voltage_unit: "1V";
    current_unit: "1mA";
    pulling_resistance_unit: "1ohm";
    leakage_power_unit: "1nW";
    capacitive_load_unit (1,pf);

    /* thresholds */
    slew_upper_threshold_pct_rise: 80;
    slew_lower_threshold_pct_rise: 20;
    slew_upper_threshold_pct_fall: 80;
    slew_lower_threshold_pct_fall: 20;
    input_threshold_pct_rise: 50;
    input_threshold_pct_fall: 50;
    output_threshold_pct_rise: 50;
    output_threshold_pct_fall: 50;

    /* process attributes */
    nom_process: 1.0;
    nom_voltage: 1.5;
    nom_temperature: 25.0;
    operating_conditions (tc_1p5v_25c) {
    process: 1;
    voltage: 1.5;
    temperature: 25;
    }
    default_operating_conditions : tc_1p5v_25c;

    /* default attributes */
    default_input_pin_cap: 1.0;
    default_inout_pin_cap: 1.0;
    default_output_pin_cap: 1.0;
    default_fanout_load: 1.0;
    default_max_transition: 1.0;
    default_cell_leakage_power: 0.0;
    default_leakage_power_density: 0.0;

    /* declare user attributes */
    define(CELL_DESCR,cell,string);

    /* ---------------- *
    * Buffer (x1 drive strength)
    * ---------------- */
    cell(bufx1) {
    CELL_DESCR: "Non-inverting x1 buffer.";
    area: 1.2;
    cell_leakage_power: 0.1;
    pin(A) {
    direction: input;
    capacitance: 0.001;
    }
    pin(Y) {
    direction: output;
    max_capacitance: 0.05;
    function: "A";
    timing () {
    related_pin : "A" ;
    timing_type : combinational ;
    timing_sense : positive_unate ;
    cell_fall(scalar) { values("2.0"); }
    cell_rise(scalar) { values("2.0"); }
    fall_transition(scalar) { values("0.3"); }
    rise_transition(scalar) { values("0.3"); }
    }
    }
    }

    }
    24 changes: 24 additions & 0 deletions stdlib.v
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    /*
    * Copyright 2025 Tomas Brabec
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    `timescale 1ns/1ps

    module bufx1(A, Y);
    input A;
    output Y;

    buf b(Y, A);
    endmodule
    61 changes: 61 additions & 0 deletions tb.sv
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,61 @@
    /*
    * Copyright 2025 Tomas Brabec
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    `timescale 1ns/1ps

    module tb;
    logic A, B, C, Y;

    top dut( .A, .B, .C, .Y );

    initial begin: test
    $display("%t: Stimulus started ...", $realtime);
    A = 0;
    B = 0;
    C = 0;
    #10ns;
    A = 1;
    #10ns;
    C = 1;
    #10ns;
    A = 0;
    #10ns;
    B = 0;
    #10ns;
    $display("%t: Stimulus finished.", $realtime);
    $stop;
    end:test

    initial $timeformat(-9, 5, " ns", 10);

    initial begin
    string sdf_file_path;
    int fd;
    if ($value$plusargs("SDF_PATH=%s",tcl_sdf_file_path)) begin
    fd = $fopen (sdf_file_path, "r");
    if (fd) begin
    $sdf_annotate(sdf_file_path, tb.dut, , , "MAXIMUM");
    end
    $fclose(fd);
    end
    end

    always @(*) $display("%t: A = %b", $realtime, A);
    always @(*) $display("%t: B = %b", $realtime, B);
    always @(*) $display("%t: C = %b", $realtime, C);
    always @(*) $display("%t: Y = %b", $realtime, Y);

    endmodule
    26 changes: 26 additions & 0 deletions top.v
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    /*
    * Copyright 2025 Tomas Brabec
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    module top(A, B, C, Y);
    input A, B, C;
    output Y;

    wire n1;

    myip u_ip( .A(A), .B(B), .C(C), .Y(n1) );
    bufx1 g1( .A(n1), .Y(Y) );

    endmodule