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: Timing Closed at 3.4 ns

Verilog Static Timing Analysis

The UART with two 5-bit counters, a registered tick and a reset synchronizer; it meets timing at all three corners

Open in IDE
design.v
module uart_tx (
  input        clk,
  input        rst_n,
  input        start,
  input  [7:0] data,
  output reg   tx,
  output       busy
);
  // baud divider: 28 x 31 = 868 clocks per bit (100 MHz / 115200)
  reg [4:0] ca, cb;
  reg [3:0] bit_idx;
  reg [7:0] shreg;
  reg       active;
  reg       tick;                      // registered: high while ca == 27 and cb == 30
  assign busy = active;
  // reset synchronizer: reset asserts at once, releases on a clock edge
  reg rs1, rs2;
  always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin rs1 <= 1'b0; rs2 <= 1'b0; end
    else begin rs1 <= 1'b1; rs2 <= rs1; end
  end
  wire rst_s = rs2;
  always @(posedge clk or negedge rst_s) begin
    if (!rst_s) begin
      ca <= 5'd0; cb <= 5'd0; bit_idx <= 4'd0; shreg <= 8'd0; active <= 1'b0; tx <= 1'b1; tick <= 1'b0;
    end else begin
      tick <= active && (ca == 5'd26) && (cb == 5'd30);
      if (!active) begin
        ca <= 5'd0; cb <= 5'd0; tx <= 1'b1;
        if (start) begin active <= 1'b1; shreg <= data; bit_idx <= 4'd0; tx <= 1'b0; end
      end else begin
        if (ca == 5'd27) begin
          ca <= 5'd0;
          cb <= (cb == 5'd30) ? 5'd0 : cb + 5'd1;
        end else ca <= ca + 5'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.
create_clock -name clk -period 3.4 [get_ports clk]
set_input_delay  0.5 -clock clk [get_ports {start data*}]
set_output_delay 0.5 -clock clk [get_ports {tx busy}]
# The external reset is not timed: the two-flop synchronizer releases it from a clock edge.
set_false_path -from [get_ports rst_n]

# Exercise: lower the period to 3.2 ns at the slow corner and read the new worst path.
# create_clock -name clk -period 3.2 [get_ports clk]
# At the typical corner this design meets 1.7 ns (setup +0.0365 ns) and fails at 1.6 ns (-0.0635 ns).
Admin mode — edit and delete controls are visible on each row. Use the IDE to add new snippets via File → Save as Snippet.