Ready-to-run snippets

Code Examples

Ready-to-run Verilog, SystemVerilog, and UVM examples. Click any to open it live in the IDE.

← All examples

STA UART Transmitter: Failing Timing at 3.4 ns

Verilog Static Timing Analysis

A 100 MHz, 115200 baud UART transmitter that fails setup and removal at the slow corner with a 3.4 ns clock

Open in IDE
design.v
module uart_tx (
  input        clk,
  input        rst_n,
  input        start,
  input  [7:0] data,
  output reg   tx,
  output       busy
);
  localparam DIV = 10'd867;            // 100 MHz / 115200 baud
  reg [9:0] cnt;
  reg [3:0] bit_idx;
  reg [7:0] shreg;
  reg       active;
  wire tick = (cnt == DIV);
  assign busy = active;
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      cnt <= 10'd0;
      bit_idx <= 4'd0;
      shreg <= 8'd0;
      active <= 1'b0;
      tx <= 1'b1;
    end
    else begin
      if (!active) begin
        cnt <= 10'd0;
        tx <= 1'b1;
        if (start) begin
          active <= 1'b1;
          shreg <= data;
          bit_idx <= 4'd0;
          tx <= 1'b0;
        end
      end
      else begin
        cnt <= tick ? 10'd0 : cnt + 10'd1;
        if (tick) begin
          if (bit_idx == 4'd8) begin
            tx <= 1'b1;
            bit_idx <= bit_idx + 4'd1;
          end
          else if (bit_idx == 4'd9) begin
            active <= 1'b0;
          end
          else begin
            tx <= shreg[0];
            shreg <= {1'b0, shreg[7:1]};
            bit_idx <= bit_idx + 4'd1;
          end
        end
      end
    end
  end
endmodule
constraints.sdc
# Run synthesis first, then STA. With PRO you can edit this file and run STA again without synthesis,
# and pick another library and corner in the drop-down.
# Article "Debugging a Failing Path": 3.4 ns clock, run at the SLOW corner (PRO) to see the violations.
create_clock -name clk -period 3.4 [get_ports clk]
set_input_delay  0.5 -clock clk [get_ports {rst_n start data*}]
set_output_delay 0.5 -clock clk [get_ports {tx busy}]

# Article "Writing SDC for the UART Project": the 10 ns version. Replace the three lines above by these.
# create_clock -name clk -period 10 [get_ports clk]
# set_clock_uncertainty 0.2 [get_clocks clk]
# set_input_delay  2.0 -clock clk [get_ports {rst_n start data*}]
# set_input_transition 0.2 [get_ports {rst_n start data*}]
# set_output_delay 2.0 -clock clk [get_ports {tx busy}]
# set_load 0.05 [get_ports {tx busy}]
# check_setup -verbose

# Same failures at the typical corner (the default one). Replace the three active lines above by these:
# create_clock -name clk -period 1.7 [get_ports clk]
# set_input_delay 0.5 -clock clk [get_ports {start data*}]
# set_input_delay 0.2 -clock clk [get_ports rst_n]
# set_output_delay 0.5 -clock clk [get_ports {tx busy}]
# Setup fails by -0.0523 ns and the reset removal check by -0.0956 ns.
Admin mode — edit and delete controls are visible on each row. Use the IDE to add new snippets via File → Save as Snippet.