FPGA流程图说明
没啥好说的,首先你可以从Linux系统下的spyglass完成你RTL的语法检查,或者你可以使用window下的modsim。总之,在使用vivado进行综合之前要保证代码的正确性。
FPGA通过综合后将生成的门级网表进行管脚约束后进行布局布线最终生成比特文件,下载到FPGA中去。下面我将结合Vivado的图形界面展开描述。
一、约束(XDC)
进行综合之前要求,设置一部分的约束(XDC),将pin约束、模块布局即物理约束、时序约束进行设置。
1.管脚(引脚)约束,又称为pin约束
约束文件的书写:(普通IO口只需约束引脚号和电压)
管脚约束:
set_property PACKAGE_PIN 引脚编号 [get_ports 端口名称]
电平信号约束:
set_property IOSTANDARD 电压 [get_ports 端口名称]
!!!此处需要注意大小写,端口名称如果是数组的话用{ }括起来,端口名称必须和源代码中的名字一致,且不能和关键字一样。
在XDC里面,每个完整的XDC约束指令不应当跨行,必须在一行之内表达完毕。同样,在一行之内也只允许存在一个约束指令,不可以把2个约束放在同一行。
以led[0]的约束为例:
set_property PACKAGE_PIN G14 [get_ports {led[0]}]
为了绑定led[0]的管脚
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
为了设置led[0]的电平约束
2.物理约束
主要对于一些特殊模块的位置进行规定
3.时序约束
时序约束简介
时序约束详细讲解
主要分为时钟约束、输入约束、输出约束、其他约束(多周期约束、伪路径约束)。
(1)时钟约束:
1.外部输入时钟clk_in周期为10ns,占空比为25%,相移为90°约束形式为:
create_clock -name clk_in -period 10 -waveform{2.5 5} [get_ports clk_in]
# {2.5 5} 表示一个周期的波形中2.5ns - 5ns 为高。如果没有指定waveform默认为{0,period/2}为高
2.时钟clk_2由时钟clk_in衍生,clk_2频率为clk_in的频率除以2,clk_2表示modu_2模块的clk_out。
create_generated_clock -name clk_2 -source [get_port clk_in] -divide_by 2 [get_pins modu_2/clk_out]
# clk_in 0011001100110011001100
# clk_2 0011110000111100001111
3.时钟clk_3由时钟clk_in衍生,clk_3表示modu_3模块的clk_out。
create_generated_clock -name clk_3 -source [get_ports clk_in] -edges {1 3 5}[get_pins top/modu_3/clk_out]
# edges{1 3 5}表示从上升沿开始算起,在clk_in的第1、3、5时钟沿clk_3时钟沿变化。
# clk_in 001110011100111001110011100
# clk_3 001111100000111110000011111
4.设置clock group来确认各个时钟之间的关系。两个主时钟 clkin_1 和 clkin_2 进入 FPGA由不同的时钟网络传递,这两个时钟及他们的衍生时钟是一组异步时钟。
set_clock_groups -name async_clk -asynchronous \
-group [get_clocks -include_generated_clocks clkin_1] \
-group [get_clocks -include_generated_clocks clkin_2]
# -asynchronous 表示异步
# -include_generated_clocks 表示包括衍生时钟
5.有时同一模块在不同模式需要不同时钟来驱动。例如bufgctrl_i/O可由bufgctrl_i/I0和bufgctrl_i/I1衍生。
create_generated_clock -name clk125_bufgctrl \
-divide_by 1 [get_pins bufgctrl_i/O] \
-source [get_ports bufgctrl_i/I0]
create_generated_clock -name clk250_bufgctrl \
-divide_by 1 [get_pins bufgctrl_i/O] \
-source [get_ports bufgctrl_i/I1] \
-add -master_clock clk125_bufgctrl
# -add -master_clock表示添加时钟,否则是直接覆盖。
set_clock_groups –physically_exclusive \
–group clk125_bufgctrl \
–group clk250_bufgctrl
# -physically_exclusive 表示时钟物理意义上不会同时存在,如果为-logically_exclusive则是逻辑上独立。
(2)输入约束
set_input_delay -clock sysclk -max 4 [get_ports clkin]
set_input_delay -clock sysclk -min 2 [get_ports clkin]
max是建立时间
min是保持时间
DDR input delay示例
set_input_delay 1 -min -clock clk [get_ports data_in]
set_input_delay 2 -max -clock clk [get_ports data_in]
set_input_delay 1 -min -clock clk [get_ports data_in] -clock_fall -add_delay
set_input_delay 2 -max -clock clk [get_ports data_in] -clock_fall -add_delay
clock_fall 告诉分析工具,当前时序分析使用下降沿作为发起沿。
add_delay告诉分析工具,当前语句和前面的语句同时有效,不要进行覆盖。
(3)输出约束
set_output_delay -min -1 -clock clk [get_ports data_out]
set_output_delay -max 3 -clock clk [get_ports data_out]
set_output_delay -min -1 -clock clk [get_ports data_out] -clock_fall -add_delay
set_output_delay -max 3 -clock clk [get_ports data_out] -clock_fall -add_delay
(4)FPGA内部组合逻辑从输入端口到输出端口
set_max_delay 15 -from [get_ports din] to [get_ports dout]
(5)多周期约束
对于多周期路径的约束语法,就一条指令:set_multicycle_path
set_multicycle_path <path_multiplier> [-setup|-hold] [-start|-end] [-from ] [-to ] [-through <pins|cells|nets>]
(6)伪路径约束
- 组合逻辑中的伪路径
set_false_path -through [get_pins MUX0/I0] -through [get_pins MUX1/I1]
- 时序路径中的伪路径
set_false_path -through [get_pins MUX0/I0] -through [get_pins MUX1/I0]
- 跨时钟域中的伪路径
set_false_path -from [get_clocks clka] -to [get_clocks clkb]
set_false_path -from [get_clocks clkb] -to [get_clocks clka]
等价于
set_clock_groups -asynchronous -group [get_clocks clka] -groups [get_clocks clkb]
false path timing report
set_flase_path -from [get_ports rst_pin]
report timing -from [get_ports rst_pin]
将以上约束条件写到.xdc文件中进行综合。