Expert skill for developing and validating timing constraints. Writes SDC (Synopsys Design Constraints) and XDC files for FPGA timing closure.
Generates and validates SDC/XDC timing constraints for FPGA timing closure.
npx claudepluginhub a5c-ai/babysitterThis skill is limited to using the following tools:
README.mdExpert skill for FPGA timing constraint development following SDC (Synopsys Design Constraints) and Xilinx XDC standards. Provides deep expertise in clock definition, I/O timing, false paths, multicycle paths, and constraint validation.
The Timing Constraints skill enables comprehensive timing constraint development for FPGA designs, supporting:
Define primary clocks entering the FPGA:
# Primary clock on input pin
create_clock -name sys_clk -period 10.000 [get_ports clk_100mhz]
# Clock with duty cycle specification
create_clock -name sys_clk -period 10.000 -waveform {0 5} [get_ports clk_100mhz]
# Multiple primary clocks
create_clock -name clk_a -period 8.000 [get_ports clk_125mhz]
create_clock -name clk_b -period 6.667 [get_ports clk_150mhz]
# Clock on GT/transceiver reference
create_clock -name gt_refclk -period 6.400 [get_ports gt_refclk_p]
# Virtual clock (for I/O timing without physical pin)
create_clock -name virt_clk -period 10.000
Define clocks derived from primary clocks:
# MMCM/PLL output clocks (auto-derived in Vivado)
create_generated_clock -name clk_200mhz \
-source [get_pins mmcm_inst/CLKIN1] \
-master_clock sys_clk \
-divide_by 1 -multiply_by 2 \
[get_pins mmcm_inst/CLKOUT0]
# Clock divider in logic
create_generated_clock -name clk_div2 \
-source [get_pins clk_div_reg/C] \
-divide_by 2 \
[get_pins clk_div_reg/Q]
# Clock multiplexer output
create_generated_clock -name clk_mux_a \
-source [get_pins clk_mux/I0] \
-master_clock clk_a \
-add \
[get_pins clk_mux/O]
create_generated_clock -name clk_mux_b \
-source [get_pins clk_mux/I1] \
-master_clock clk_b \
-add \
[get_pins clk_mux/O]
Constrain timing for input signals:
# System synchronous input (source synchronous)
# Data arrives after clock edge
set_input_delay -clock sys_clk -max 3.0 [get_ports data_in[*]]
set_input_delay -clock sys_clk -min 1.0 [get_ports data_in[*]]
# DDR input (double data rate)
set_input_delay -clock ddr_clk -max 2.5 [get_ports ddr_data[*]]
set_input_delay -clock ddr_clk -min 0.5 [get_ports ddr_data[*]]
set_input_delay -clock ddr_clk -max 2.5 [get_ports ddr_data[*]] -clock_fall -add_delay
set_input_delay -clock ddr_clk -min 0.5 [get_ports ddr_data[*]] -clock_fall -add_delay
# Input relative to virtual clock
set_input_delay -clock virt_clk -max 4.0 [get_ports async_data[*]]
set_input_delay -clock virt_clk -min 0.0 [get_ports async_data[*]]
# Source synchronous interface with forwarded clock
set_input_delay -clock rx_clk -max 2.0 [get_ports rx_data[*]]
set_input_delay -clock rx_clk -min 0.5 [get_ports rx_data[*]]
Constrain timing for output signals:
# System synchronous output
# Downstream device setup time: 2ns, hold time: 0.5ns
# Board delay: 0.5ns
set_output_delay -clock sys_clk -max 2.5 [get_ports data_out[*]]
set_output_delay -clock sys_clk -min -0.5 [get_ports data_out[*]]
# DDR output
set_output_delay -clock ddr_clk -max 1.5 [get_ports ddr_out[*]]
set_output_delay -clock ddr_clk -min 0.0 [get_ports ddr_out[*]]
set_output_delay -clock ddr_clk -max 1.5 [get_ports ddr_out[*]] -clock_fall -add_delay
set_output_delay -clock ddr_clk -min 0.0 [get_ports ddr_out[*]] -clock_fall -add_delay
# Source synchronous output with generated clock
set_output_delay -clock tx_clk -max 1.0 [get_ports tx_data[*]]
set_output_delay -clock tx_clk -min -0.5 [get_ports tx_data[*]]
Identify and constrain paths that don't need timing analysis:
# Asynchronous reset - no timing requirement
set_false_path -from [get_ports rst_n]
# Static configuration registers
set_false_path -from [get_cells config_reg[*]]
# Clock domain crossing (handled by synchronizers)
set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]
set_false_path -from [get_clocks clk_b] -to [get_clocks clk_a]
# Specific CDC path (more precise)
set_false_path -from [get_cells -hier -filter {NAME =~ *cdc_src_reg*}] \
-to [get_cells -hier -filter {NAME =~ *cdc_dst_sync_reg[0]*}]
# Mutually exclusive clock mux paths
set_false_path -from [get_clocks clk_mux_a] -to [get_clocks clk_mux_b]
set_false_path -from [get_clocks clk_mux_b] -to [get_clocks clk_mux_a]
# Debug signals
set_false_path -to [get_ports debug_*]
Define paths that require multiple clock cycles:
# 2-cycle path for slow operation
# Data is valid for 2 clock cycles
set_multicycle_path 2 -setup -from [get_cells slow_src_reg] -to [get_cells slow_dst_reg]
set_multicycle_path 1 -hold -from [get_cells slow_src_reg] -to [get_cells slow_dst_reg]
# Multicycle based on enable signal
# Data changes every 4 cycles when enable asserts
set_multicycle_path 4 -setup -from [get_cells data_reg[*]] -to [get_cells proc_reg[*]]
set_multicycle_path 3 -hold -from [get_cells data_reg[*]] -to [get_cells proc_reg[*]]
# Phase-shifted clock multicycle
# Source clock leads destination by 90 degrees
set_multicycle_path 1 -setup -start -from [get_clocks clk_0] -to [get_clocks clk_90]
# Multicycle for wide bus operations
set_multicycle_path 2 -setup -from [get_pins wide_reg[*]/C] -to [get_pins result_reg[*]/D]
set_multicycle_path 1 -hold -from [get_pins wide_reg[*]/C] -to [get_pins result_reg[*]/D]
Define relationships between clocks:
# Asynchronous clock groups - no timing between them
set_clock_groups -asynchronous \
-group [get_clocks clk_100mhz] \
-group [get_clocks clk_125mhz] \
-group [get_clocks gt_refclk]
# Physically exclusive clocks (mux-selected)
set_clock_groups -physically_exclusive \
-group [get_clocks clk_mux_a] \
-group [get_clocks clk_mux_b]
# Logically exclusive clocks (runtime selected)
set_clock_groups -logically_exclusive \
-group [get_clocks pll_config_a] \
-group [get_clocks pll_config_b]
Constrain max delay for CDC paths (alternative to false path):
# Max delay constraint for CDC synchronizer
# Ensures data is stable before next clock edge
set_max_delay -datapath_only -from [get_cells cdc_src_reg] \
-to [get_cells cdc_sync_reg[0]] 5.0
# CDC FIFO gray code pointers
set_max_delay -datapath_only \
-from [get_cells wr_ptr_gray_reg[*]] \
-to [get_cells rd_ptr_sync_reg[0][*]] \
[expr {$period_clk_wr * 0.8}]
Xilinx-specific physical constraints:
# I/O standard
set_property IOSTANDARD LVCMOS33 [get_ports gpio[*]]
set_property IOSTANDARD LVDS_25 [get_ports {lvds_p lvds_n}]
# Pin location
set_property PACKAGE_PIN H16 [get_ports clk_100mhz]
set_property PACKAGE_PIN R14 [get_ports rst_n]
# I/O drive strength
set_property DRIVE 8 [get_ports data_out[*]]
set_property SLEW FAST [get_ports high_speed_out]
# Input termination
set_property PULLUP TRUE [get_ports config_pin]
set_property IBUF_LOW_PWR FALSE [get_ports high_speed_in]
# Clock input buffer type
set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_nets clk_100mhz_IBUF]
This skill integrates with the following processes:
| Process | Integration Point |
|---|---|
timing-constraints.js | Primary constraint development |
timing-closure.js | Constraint refinement for closure |
synthesis-optimization.js | Constraint-aware synthesis |
cdc-design.js | CDC constraint generation |
## Clock Domain Analysis
| Clock | Frequency | Source | Domain |
|-------|-----------|--------|--------|
| sys_clk | 100 MHz | External | Primary |
| clk_200 | 200 MHz | MMCM | Processing |
| rx_clk | 125 MHz | PHY | RX path |
| tx_clk | 125 MHz | MMCM | TX path |
## Clock Relationships
- sys_clk -> clk_200: synchronous (MMCM)
- sys_clk <-> rx_clk: asynchronous
- tx_clk -> rx_clk: asynchronous
# Output files generated:
# - constraints/clocks.xdc - Clock definitions
# - constraints/io_timing.xdc - I/O delay constraints
# - constraints/cdc.xdc - CDC constraints
# - constraints/exceptions.xdc - False/multicycle paths
# - constraints/physical.xdc - Pin assignments
# In Vivado
report_clocks
report_clock_interaction
report_timing_summary -delay_type min_max
check_timing
report_methodology
{
"constraints": {
"clocks": {
"primary": [
{ "name": "sys_clk", "period": 10.0, "port": "clk_100mhz" }
],
"generated": [
{ "name": "clk_200", "source": "sys_clk", "multiply": 2, "divide": 1 }
]
},
"ioTiming": {
"inputs": [
{ "port": "data_in[*]", "clock": "sys_clk", "maxDelay": 3.0, "minDelay": 1.0 }
],
"outputs": [
{ "port": "data_out[*]", "clock": "sys_clk", "maxDelay": 2.5, "minDelay": -0.5 }
]
},
"exceptions": {
"falsePaths": [
{ "from": "rst_n", "reason": "Asynchronous reset" }
],
"multicyclePaths": [
{ "from": "slow_reg", "to": "proc_reg", "setup": 2, "hold": 1 }
]
},
"clockGroups": [
{ "type": "asynchronous", "clocks": ["sys_clk", "rx_clk"] }
]
},
"validation": {
"allClocksConstrained": true,
"allIOConstrained": true,
"noUnconstrainedPaths": true,
"cdcCovered": true
},
"artifacts": [
"constraints/clocks.xdc",
"constraints/io_timing.xdc",
"constraints/cdc.xdc",
"constraints/exceptions.xdc"
]
}
# Source synchronous input (clock forwarded with data)
create_clock -name rx_clk -period 8.000 [get_ports rx_clk]
set_input_delay -clock rx_clk -max 2.5 [get_ports rx_data[*]]
set_input_delay -clock rx_clk -min 0.5 [get_ports rx_data[*]]
# Source synchronous output (FPGA generates clock)
create_generated_clock -name tx_clk \
-source [get_pins mmcm/CLKOUT1] \
[get_ports tx_clk]
set_output_delay -clock tx_clk -max 1.0 [get_ports tx_data[*]]
set_output_delay -clock tx_clk -min -0.5 [get_ports tx_data[*]]
# FIFO gray code pointer crossing
set_max_delay -datapath_only \
-from [get_cells fifo_inst/wr_ptr_gray_reg[*]] \
-to [get_cells fifo_inst/wr_ptr_sync_reg[0][*]] 8.0
set_max_delay -datapath_only \
-from [get_cells fifo_inst/rd_ptr_gray_reg[*]] \
-to [get_cells fifo_inst/rd_ptr_sync_reg[0][*]] 10.0
# Async reset input
set_false_path -from [get_ports rst_n]
# Reset synchronizer - allow 2 clock cycles
set_max_delay -from [get_cells rst_sync_reg[0]] \
-to [get_cells rst_sync_reg[1]] \
[get_property PERIOD [get_clocks sys_clk]]
report_clocksset_max_delay -datapath_only over set_false_pathreport_cdc to verify coveragecheck_timing before implementationreport_timing_summary for unconstrained pathsreport_methodology for DRC checkstiming-constraints.js - Timing constraint development processtiming-closure.js - Timing closure methodologyActivates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.