适用于 Vivado 2021.2,IOSTANDARD 均为 LVCMOS33
约束文件基础
XDC(Xilinx Design Constraints)文件本质是 Tcl 脚本,告诉 Vivado 两件事:
管脚映射:Verilog 端口对应芯片哪个物理引脚
时钟定义:告诉工具时钟频率,用于时序分析
最常用的三条语句
# 1. 指定管脚
set_property PACKAGE_PIN P15 [get_ports sys_clk]
# 2. 指定电平标准(XS7050 统一 3.3V)
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
# 3. 定义时钟(仅时钟信号需要)
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
# ^^^^^^ 单位 ns,20ns = 50MHz约束编写方式
XDC 文件(推荐):直接编辑文本文件,适用于日常开发、版本管理;
I/O Planning:Vivado 图形界面,适用于初次查看管脚分布。
两种方式效果相同,I/O Planning 的修改最终也会写入 XDC。建议以 XDC 文件为主。
注意事项
端口名必须与 Verilog `module` 的端口名 完全一致
数组端口用花括号:
{led[0]},不是led[0]未使用的端口不需要约束
所有用到的端口必须约束,否则 Vivado 会报错或分配随机管脚
完整约束模板
将以下内容保存为 .xdc 文件,按需取消注释。
#==============================================================================
# XS7050 FPGA 板卡约束文件
# IOSTANDARD: LVCMOS33 (3.3V)
#==============================================================================
#------------------------------------------------------------------------------
# 系统时钟 (50 MHz)
#------------------------------------------------------------------------------
set_property PACKAGE_PIN P15 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
create_clock -period 20.000 -name sys_clk -waveform {0.000 10.000} [get_ports sys_clk]
#------------------------------------------------------------------------------
# 复位按钮 KEY1 (Active Low,按下=0,松开=1)
#------------------------------------------------------------------------------
set_property PACKAGE_PIN E18 [get_ports sys_rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n]
#------------------------------------------------------------------------------
# 用户按键 KEY2-KEY4 (Active Low,带上拉电阻)
# Verilog 声明: input [2:0] key_n
#------------------------------------------------------------------------------
set_property PACKAGE_PIN E17 [get_ports {key_n[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key_n[0]}]
set_property PACKAGE_PIN D19 [get_ports {key_n[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key_n[1]}]
set_property PACKAGE_PIN E19 [get_ports {key_n[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key_n[2]}]
#------------------------------------------------------------------------------
# 用户 LED x4 (Active Low,输出 0 = 亮)
# Verilog 声明: output [3:0] led
#------------------------------------------------------------------------------
set_property PACKAGE_PIN F15 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN G14 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property PACKAGE_PIN E16 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property PACKAGE_PIN E15 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
#------------------------------------------------------------------------------
# RGB LED
#------------------------------------------------------------------------------
# set_property PACKAGE_PIN M17 [get_ports rgb_r]
# set_property IOSTANDARD LVCMOS33 [get_ports rgb_r]
# set_property PACKAGE_PIN M18 [get_ports rgb_g]
# set_property IOSTANDARD LVCMOS33 [get_ports rgb_g]
# set_property PACKAGE_PIN K19 [get_ports rgb_b]
# set_property IOSTANDARD LVCMOS33 [get_ports rgb_b]
#------------------------------------------------------------------------------
# 蜂鸣器
#------------------------------------------------------------------------------
# set_property PACKAGE_PIN K18 [get_ports buzzer]
# set_property IOSTANDARD LVCMOS33 [get_ports buzzer]对应 Verilog 端口声明
module my_design (
input sys_clk, // 50MHz 系统时钟
input sys_rst_n, // 复位(KEY1,低有效)
input [2:0] key_n, // 3 个用户按键(低有效)
output [3:0] led // 4 个 LED(低有效)
// output rgb_r, // RGB LED(按需启用)
// output rgb_g,
// output rgb_b
);
// ...
endmodule管脚映射速查表
板载资源 | 信号名 | 管脚 | 方向 | 说明 |
|---|---|---|---|---|
系统时钟 | sys_clk | P15 | input | 50MHz |
复位 KEY1 | sys_rst_n | E18 | input | 低有效,带上拉 |
按键 KEY2 | key_n[0] | E17 | input | 低有效,带上拉 |
按键 KEY3 | key_n[1] | D19 | input | 低有效,带上拉 |
按键 KEY4 | key_n[2] | E19 | input | 低有效,带上拉 |
LED1 | led[0] | F15 | output | 低有效(0=亮) |
LED2 | led[1] | G14 | output | 低有效(0=亮) |
LED3 | led[2] | E16 | output | 低有效(0=亮) |
LED4 | led[3] | E15 | output | 低有效(0=亮) |
RGB LED-R | rgb_r | M17 | output | 高有效(1=亮) |
RGB LED-G | rgb_g | M18 | output | 高有效(1=亮) |
RGB LED-B | rgb_b | K19 | output | 高有效(1=亮) |
有源蜂鸣器 | buzzer | K18 | output | 高有效(1=响) |
常见问题
Q: 约束里端口名写错了会怎样?
Vivado 不会报错(XDC 是 Tcl,get_ports 找不到端口只会静默跳过),但该端口不会被约束。检查方法:综合后查看 I/O Ports 窗口,确认所有端口都有管脚分配。
Q: 为什么数组端口要加花括号?
get_ports led[0] 中的方括号会被 Tcl 解释为命令替换,加 {} 转义:get_ports {led[0]}。
Q: LED 低有效怎么处理?
两种方式:
逻辑中直接取反输出:
assign led = ~led_logic;设计时就按低有效写逻辑:
0表示亮
建议方式 1,逻辑更清晰。
Q: 按键低有效 + 上拉是什么意思?
按键未按时,上拉电阻将引脚拉高(读到 1);按下时引脚接地(读到 0)。所以"按下"对应 key_n == 0。