“My code is perfect, so why doesn’t the chip work?”
Sometimes, a program that appears to work fine in RTL simulation fails to work when synthesized on an actual FPGA or ASIC. More than 90% of the time, this is due to a timing issue.
Synthesis and place-and-route tools basically just try to make the area as small as possible, and they don't know whether you want the circuit to run at 100MHz or 1GHz. The file that tells the tool, "This circuit must run at this speed!" is the SDC (Synopsys Design Constraints). (In Xilinx FPGAs, it's called XDC, but the syntax is almost identical.)
Today, we'll learn about the four core SDC commands, among the hundreds of them, that are impossible to design without.
1. Define a heartbeat: create_clock
The first thing to do is define how fast the chip's heart beats. This will serve as the reference point for all timing calculations.
# Syntax: create_clock -period [period_ns] -name [clock_name] [get_ports port_name]
# Example: Define a 100MHz (10ns period) clock on the 'sys_clk' port.
create_clock -period 10.0 -name clk_100m [get_ports sys_clk]- Meaning: "The signal coming into this sys_clk pin has a rising edge every 10 ns. You must arrange all logic (combinational circuits between F/F) to complete calculations within 10 ns."
- Note: When setting a period, it's common to set it slightly tighter than your actual goal (e.g., 10% margin) (over-constraining technique).
2. Promise with the outside world 1: set_input_delay
This is the command that beginners find most difficult to understand. It's easy to misunderstand, thinking, "Input Delay means the delay from the input pin to the internal signal." However, the opposite is true.
This means “time coming from outside the chip”.
# Syntax: set_input_delay -clock [reference clock] -max [time_ns] [get_ports input pins]
# Example: Data arrives after 6 ns of writing from an external chip (assuming a period of 10 ns).
set_input_delay -clock clk_100m -max 6.0 [get_ports data_in]- Physical situation:
- The time (
T_co) when the register of the external chip (Sender) receives the clock and sends data. - The time it takes to get to our chip through the wiring on the PCB board (
T_trace). - Let's assume that the sum of these two times is 6 ns.
- The time (
- Interpretation of the tool: “The period is 10 ns, but we already spent 6 ns on the outside and came in? Then, we need to satisfy the setup time within the remaining 4ns (10 – 6) inside our chip!”
- Conclusion: The larger the input_delay value, the faster the tool will squeeze its internal logic to run.
3. Promise to the outside world 2: set_output_delay
Conversely, this is a constraint on when our chip sends data outward. This also refers to the "time required outside the chip."
# Syntax: set_output_delay -clock [reference clock] -max [time_ns] [get_ports output pins]
# Example: The following chip requires 3ns to receive data.
set_output_delay -clock clk_100m -max 3.0 [get_ports data_out]- Physical situation:
- PCB wiring delay (
T_trace). - Setup time of the next chip (Receiver) (
T_setup). - The sum of these two times is
3ns.
- PCB wiring delay (
- Interpretation of the tool: "The period is 10ns, but there needs to be a 3ns delay between the data going out and the next chip receiving it? So, within our chip, we need to get the data out of the pin within 7ns (10 – 3) !
4. Exception Handling: set_multicycle_path (CDC handling)
Remember the CDC (Clock Domain Crossing) article we covered earlier? When data crosses between clocks of different frequencies (e.g., 100MHz → 48MHz), timing violations inevitably occur.
If the engineer has implemented a failsafe with a 2-FF Synchronizer or FIFO, he or she should tell the tool, "Don't check timing here! I'll take care of it." Otherwise, the tool will spend the night trying to achieve impossible timing.
# Syntax: set_false_path -from [start clock] -to [arrival clock]
# Example: All paths between clk_a and clk_b are ignored
set_multicycle_path -from [get_clocks clk_a] -to [get_clocks clk_b]
set_multicycle_path -from [get_clocks clk_b] -to [get_clocks clk_a]- Caution: If you accidentally place a false path on a critical path, the tool will fail to optimize, causing the chip to crash. Be sure to place false paths only on paths with a guaranteed CDC.
5. Summary: SDC is a 'time remaining calculator'.
The core of SDC is the battle between Data Required Time and Data Arrival Time.
- create_clock: Sets the full pi (full time, e.g. 10ns).
- set_input_delay: Cuts off the beginning of the pie (the time it takes before input).
- set_output_delay: Cut off the back of the pie (the time needed after output).
- Remainder: You need to implement the RTL logic using only the remaining pieces in the middle.
When designing RTL, the first step to understanding SDC is not simply implementing functions, but rather thinking, “Can my logic actually operate within this remaining time (Slack)?”
References: Synopsys pdf