目录
一、前言
二、Report CDC
2.1 Report CDC
2.2 配置界面
2.3 CDC报告
2.3.1 General Information
2.3.2 Summary
2.3.3 CDC Details
2.4 Waiver
2.4.1 设置Waiver
2.4.2 报告查看
2.4.3 去除Waiver设置
三、工程设计
四、参考资料
一、前言
前面已经针对Vivado时序Timing报告相关的如Minimum pulse width,datasheet等进行了详解,本文再对其中的Report CDC使用进行解说。
二、Report CDC
2.1 Report CDC
CDC(Clock Domain Crossings)中文含义为跨时钟域,也即时序路径的launch clock和capture clock为不同的时钟,可以报告潜在的不安全的跨时钟域路径(如可能导致亚稳态或数据一致性问题)。在生成CDC报告前,必须确保设计约束合理,无缺失的时钟约束,Report CDC只会分析和报告源时钟和目的时钟被约束了的路径。
2.2 配置界面
通过菜单栏“Reports->Timing->Report CDC”进入到Report CDC界面
配置界面如下图
相关配置项的含义如下
Results name(报告名称):为CDC报告设置一个名称,将在Vivado的结果窗口显示
Clocks(时钟):设置要进行跨时钟分析的时钟
a)From(起点): 指定分析的发起时钟,双击后面的选择图标(三个点)可以进入到发起时钟的设置窗口
b)To:指定分析的捕获时钟,双击后面的选择图标(三个点)可以进入到捕获时钟的设置窗口,同发起时钟类似
Report from Cells(报告单元): 限制CDC报告中分析包含指定单元cells的时序路径。
File Output(文件输出):将CDC报告结果以txt文件导出到指定路径下,默认是Overwrite,即覆盖已存在的报告文件,如果选择Append则是将新的报告结果追加到已有内容的后面
Options(选项):
a)Suspend message limits during command:勾选则表示忽略Messages数量限制。
b)Ignore command errors (quiet mode): 勾选表示当执行Report CDC命令时忽略错误。
Apply Waivers(使用Waivers): 该设置为默认配置,当生成CDC报告时,会将所有Waivers用于设计中,也可以使用Create Waiver命令将Waivers添加到设计中。
Report only waived paths: 执行CDC报告时仅有CDC路径中创建了Waiver的路径
Ignore waivers(忽略Waivers): 分析所有的CDC路径时忽略设计中所有定义的Waivers。
Open in a new tab: 执行时序报告后是否在一个新的标签中打开,如果没有勾选,新的报告结果将会覆盖旧的结果
Open in Timing Analysis layout: 执行完CDC分析后是否打开布局窗口(Device窗口)
2.3 CDC报告
CDC报告内容由General Information,Summary,CDC Detail三个部分组成
2.3.1 General Information
General Information中包含了报告类型,设计名称,器件,Vivado版本,报告运行时间,以及生成CDC报告的命令。
2.3.2 Summary
Summary分Clock pair,Type,waived三个方向来展示CDC报告
1) clock pair
Clock pair是根据时序对来分析跨时钟域路径。详细内容表格如下图
Severity:对CDC路径的风险等级分类,有Critical和Warning和Info三个级别
Source Clock:源时钟
Destination Clock:目的时钟
CDC Type:CDC类型,No common primary clock表示无共同的主时钟,Safely Timed表示有共同的主时钟,如生成时钟与主时钟的关系
Exceptions:显示源时钟与目的时钟间是否存在时序例外约束,Exceptions对应的值含义如下图
Endpoints:源时钟与目的时钟的路径上终点的数目
2) By type
Summary(by type)展示的报告如下图
Severity:跨时钟域影响大小,分为Info(信息级), Warning(告警级), Critical(严重级)
ID:不同的ID代表不同的类型,如CDC-1表示1比特跨时钟域,CDC-4表示多比特跨时钟域,CDC-10表示在同步器前检测到组合逻辑。
Count:对应CDC ID的跨时钟域数量
Description:对CDC类型含义进行说明
常见的CDC类型见下图,CDC1-3为单比特场景,CDC4-6为多比特场景,CDC7-9为异步复位,CDC10为组合逻辑等
默认情况下,Report CDC仅报告每个终点和时钟对的单个违例,当一个终点存在多个违例时,优先报告优先级更高的CDC,不同CDC的优先级如下图,从上往下优先级依次降低。
2.3.3 CDC Details
CDC Details报告了设计中所有的跨时钟域路径,按照时钟对来展示
Severity/ID/Description:解释同上
Depth:同步器的数量
Exception: CDC路径上的时序例外约束,如下图设置了false path
Source/Destination:源时钟和目标单元
Category:CDC路径的安全性分类,分为安全safe,不安全unsafe,未知Unknown,No Async_Reg等
2.4 Waiver
在前面的小节中提到了Waiver相关的设置项,Waiver不仅针对CDC路径有效,对设计规则检查DRC,检查违例的方法也有效。如果路径被设置了Waiver,在report_cdc,report_drc, or report_methodology结果中不会被分析
在未对路径设置Waiver时,CDC报告中Summary(by waived endpoints) 中内容为空
2.4.1 设置Waiver
在设置Waiver前可以先查看CDC路径的方案图Schematic,进入CDC Details中
选中路径后可以通过Schemaic或快捷键F4进入方案图中,看出clk_group2和clk_group1的关系
设置Waiver同样在选中路径后的右键菜单中进行
进入Create Waiver,user为用户名,Description为创建的waiver设置说明
设置完后该路径自动置灰
点击rerun后,该路径将不会存在CDC Details中,将出现在Summary(by waiver)中
Create Waiver也支持同时对多条CDC设置,只要在CDC Details中同时选中多条路径即可
tcl command preview中同时显示了两条create_waiver命令
Summary(by waived endpoints)中Waived endpoints为2。
2.4.2 报告查看
方法1:在tcl console中执行report_cdc -waiver可以查看设置的waiver详情
也可使用report_waiver命令
方法2:执行Report CDC时Waivers中勾选Report only waived paths
此时Summary或CDC Details中都只会报告设置了waivers的路径
方法3:tcl console中使用report_cdc -details -show_waiver,无论CDC是否设置Waiver都会被报告
2.4.3 去除Waiver设置
在设置了waiver后会发现菜单栏和工具栏都没有相关的取消Waiver的操作,此时须在tcl console使用命令delete_waivers [get_waivers -type cdc]可以移除所有设置的waiver
也可只移除指定CDC类型的Waiver,如移除类型为CDC-1中设置的Waiver
命令为:delete_waivers [get_waivers -filter {ID == CDC-1}]
三、工程设计
module all_timing(CLKIN1,CLKIN2,CLKINSEL,CLKFBIN,d1,rst,clk_group1,clk_group2,ff_group2_a,clk_false,clk_max,clk_multi,ff_false,ff_group,ff_group2,ff_pll,ff_max,ff_multi);
input CLKIN1,CLKIN2,CLKINSEL,CLKFBIN,d1,rst;
input clk_group1,clk_group2,clk_false,clk_max,clk_multi;
output reg ff_false,ff_group,ff_group2,ff_group2_a,ff_pll,ff_max,ff_multi;
reg ff1;
wire CLKOUT0;
PLLE2_ADV #(
.BANDWIDTH("OPTIMIZED"), // OPTIMIZED, HIGH, LOW
.CLKFBOUT_MULT(8), // Multiply value for all CLKOUT, (2-64)
.CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB, (-360.000-360.000).
// CLKIN_PERIOD: Input clock period in nS to ps resolution (i.e. 33.333 is 30 MHz).
.CLKIN1_PERIOD(0.0),
.CLKIN2_PERIOD(0.0),
// CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: Divide amount for CLKOUT (1-128)
.CLKOUT0_DIVIDE(1),
.CLKOUT1_DIVIDE(2),
.CLKOUT2_DIVIDE(4),
.CLKOUT3_DIVIDE(5),
.CLKOUT4_DIVIDE(1),
.CLKOUT5_DIVIDE(1),
// CLKOUT0_DUTY_CYCLE - CLKOUT5_DUTY_CYCLE: Duty cycle for CLKOUT outputs (0.001-0.999).
.CLKOUT0_DUTY_CYCLE(0.4),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT5_DUTY_CYCLE(0.5),
// CLKOUT0_PHASE - CLKOUT5_PHASE: Phase offset for CLKOUT outputs (-360.000-360.000).
.CLKOUT0_PHASE(0.0),
.CLKOUT1_PHASE(0.0),
.CLKOUT2_PHASE(0.0),
.CLKOUT3_PHASE(0.0),
.CLKOUT4_PHASE(0.0),
.CLKOUT5_PHASE(0.0),
.COMPENSATION("EXTERNAL"), // ZHOLD, BUF_IN, EXTERNAL, INTERNAL
.DIVCLK_DIVIDE(1), // Master division value (1-56)
// REF_JITTER: Reference input jitter in UI (0.000-0.999).
.REF_JITTER1(0.0),
.REF_JITTER2(0.0),
.STARTUP_WAIT("FALSE") // Delay DONE until PLL Locks, ("TRUE"/"FALSE")
)
PLLE2_ADV_inst (
// Clock Outputs: 1-bit (each) output: User configurable clock outputs
.CLKOUT0(CLKOUT0), // 1-bit output: CLKOUT0
.CLKOUT1(CLKOUT1), // 1-bit output: CLKOUT1
.CLKOUT2(CLKOUT2), // 1-bit output: CLKOUT2
// Feedback Clocks: 1-bit (each) output: Clock feedback ports
.CLKFBOUT(CLKFBOUT), // 1-bit output: Feedback clock
// Clock Inputs: 1-bit (each) input: Clock inputs
.CLKIN1(CLKIN1), // 1-bit input: Primary clock
.CLKIN2(CLKIN2), // 1-bit input: Secondary clock
// Control Ports: 1-bit (each) input: PLL control ports
.CLKINSEL(CLKINSEL), // 1-bit input: Clock select, High=CLKIN1 Low=CLKIN2
.RST(rst), // 1-bit input: Reset
// Feedback Clocks: 1-bit (each) input: Clock feedback ports
.CLKFBIN(CLKFBIN) // 1-bit input: Feedback clock
);
// End of PLLE2_ADV_inst instantiation
always@(posedge CLKOUT0,negedge rst)
if(!rst)
begin
ff1<=1'b0;
end
else begin
ff1<=d1;
end
always@(posedge CLKIN1,negedge rst)
if(!rst)
ff_pll<=1'b0;
else begin
ff_pll<=ff1;
end
always@(posedge clk_group1,negedge rst)
if(!rst)
ff_group<=1'b0;
else begin
ff_group<=d1;
end
always@(posedge clk_group2,negedge rst)
if(!rst)
ff_group2<=1'b0;
else begin
ff_group2<=ff_group;
end
always@(posedge clk_group2)
if(rst)
ff_group2_a<=1'b0;
else begin
ff_group2_a<=ff_group;
end
always@(posedge clk_false,negedge rst)
if(!rst)
ff_false<=1'b0;
else begin
ff_false<=ff_group2;
end
always@(posedge clk_max,negedge rst)
if(!rst)
ff_max<=1'b0;
else begin
ff_max<=ff_group2;
end
always@(posedge clk_multi,negedge rst)
if(!rst)
ff_multi<=1'b0;
else begin
ff_multi<=ff_group2;
end
endmodule
四、参考资料
《ug906-vivado-design-analysis-en-2023.2.pdf》