建立余量
![在这里插入图片描述](https://img-blog.csdnimg.cn/592476c3b977446a8684f4f7f5311b6d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/6376ee1194744bc08e0cafbc46ff8ed5.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/21c209bf1f544138a0e06216f21e8ab4.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/7157503769444a1eb4c4dad651e130e5.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
保持余量
![在这里插入图片描述](https://img-blog.csdnimg.cn/4064d25197454e76bf0eb3453fe1924b.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/01506f9280024d95ba13bd92f1dae278.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/ab4cc92e2dc1456886cfcb85c6aa4492.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
实例分析
环境:Vivado 2019.2
芯片型号:xc7z020clg484-2
举例子说明怎么使用Reporte Timing Summary
建立源工程
module timing_analyze (
input wire clk ,
input wire reset ,
input wire [ 4: 0] data_in ,
output reg [ 4: 0] data_out
);
reg [ 4: 0] data_tmp_in ;
wire [ 4: 0] data_tmp_out;
wire [ 4: 0] data_tmp2, data_tmp_3, data_tmp_4, data_tmp_5, data_tmp_6, data_tmp_7;
wire [ 4: 0] data_cal_out;
always @ (posedge clk)
if (reset == 1'b1)
data_tmp_in <= 0;
else
data_tmp_in <= data_in;
// 为了增加经过逻辑门的数量,做连续的乘法
assign data_tmp_2 = data_tmp_in * data_tmp_in;
assign data_tmp_3 = data_tmp_2 * data_tmp_in;
assign data_tmp_4 = data_tmp_3 * data_tmp_2;
assign data_tmp_5 = data_tmp_4 * data_tmp_3;
assign data_tmp_6 = data_tmp_5 * data_tmp_4;
assign data_tmp_7 = data_tmp_6 * data_tmp_5;
assign data_cal_out= data_tmp_7;
always @ (posedge clk)
if (reset == 1'b1)
data_out <= 0;
else
data_out <= data_cal_out;
endmodule
![在这里插入图片描述](https://img-blog.csdnimg.cn/675c84299b2541e99ab0ebecdfaa4dbc.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
添加.xdc文件
设定clk时钟为200MHz,T = 5ns
# create_clock - name clk - period 5.000 [get_ports clk] // err
create_clock -name clk -period 5.000 [get_ports clk]
查看时序报告
Run Systhesis、Run Implementation,可以在Design Runs状态栏看到下面的情况,impl_1一行有红色,表示布线的时序不通过
![](https://img-blog.csdnimg.cn/7ae16bf28b91459ba1fb47f4ec73002d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
WNS 代表最差负时序裕量 (Worst Negative Slack)
TNS 代表总的负时序裕量 (Total Negative Slack),也就是负时序裕量路径之和。
WHS 代表最差保持时序裕量 (Worst Hold Slack)
THS 代表总的保持时序裕量 (Total Hold Slack),也就是负保持时序裕量路径之和。
这些值告诉设计者设计与时序要求相差多少。如果为正值,则说明能达到时序要求,若为负值,则说明时序达不到要求。
点Implementation -> Open Implementation -> Reporte Timing Summary,通过时序报告查看时序问题的产生原因,可以在Timing状态栏看到下面的情况,Design Timing Summary和Intra-Clock Paths时红色的,表示时序不合格的部分就在这里。
![在这里插入图片描述](https://img-blog.csdnimg.cn/c25e894281c24f2a8d26d168b0696676.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
点击红色框中的选项可以看到,时序不合格的地方时clk时钟下的Setup时间不能达到要求,默认情况下最多显示10条每个时钟能显示的问题数量
![在这里插入图片描述](https://img-blog.csdnimg.cn/aa96114c665449a79eed2a99e3f18856.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
时序分析
双击Path1,打开时序报告的界面。
![在这里插入图片描述](https://img-blog.csdnimg.cn/8f0bb148b6404e3684e1ae846a49c690.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/754e21354bb04ffe8d71b4f1768a1caf.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/a90b1ffce5634c0a94609d366cef8b23.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/dd91aa249a784e009ef6e01d724a1dba.jpg?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
Slack为-1.344ns,表示和5ns的建立时间的要求相比,这条线的路还差1.344ns,单击-1.344ns,弹出来一个对话框,可以看到这条线需要数据在9.417ns内到达第二个触发器的输入,但实际到达时间为10.761ns,导致建立时间不够。
![在这里插入图片描述](https://img-blog.csdnimg.cn/b4ae1119f4744c5992d0924f5e6caec8.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
Source Clock Path为时钟到第一级触发器的时间,Data Path为数据经过组合逻辑产生的延迟,Source Clock Path + Data Path算出的是数据延迟的综合,为10.761ns。Destination Clock Path算出的是Clock延迟的总和,为9.417ns
单击Path1,再点Implementation -> Open Implementation -> Schematic查看原理图,原理图中可以看到其经过的逻辑电路(高亮),并且在Divice界面里可以看到在FPGA内部的实际走线。原理图可以看到,最左边和最右边的器件是触发器,两级触发器之间的电路则是经过的逻辑器件。
![在这里插入图片描述](https://img-blog.csdnimg.cn/0ad9524424dd45769852c055ac3106b2.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/5e7745a01ffc4c798595e4d985a513ab.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/344a38868f524bcab2e89fbf1e06b6cc.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
时序优化
根据时序分析已经找到了时序不通过的地方,可以采取三种解决办法,推荐第二种
-
简化逻辑
通过减少器件的数目,来减少逻辑延迟,使之能符合时序要求,
为了能只直观看到减少组合逻辑带来的好处,这里简单粗暴去掉一些乘法器,再运行一遍,可以看到时序直接通过
assign data_tmp_2 = data_tmp_in * data_tmp_in;
assign data_tmp_3 = data_tmp_2 * data_tmp_in;
assign data_tmp_4 = data_tmp_3 * data_tmp_2;
// assign data_tmp_5 = data_tmp_4 * data_tmp_3;
// assign data_tmp_6 = data_tmp_5 * data_tmp_4;
// assign data_tmp_7 = data_tmp_6 * data_tmp_5;
assign data_cal_out= data_tmp_4;
![在这里插入图片描述](https://img-blog.csdnimg.cn/722b76848441464d8bd7d371428f7adf.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/41e39bdf31454e53bac175e35cf04b7a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
-
插入触发器
通过在组合逻辑之间插入触发器,将原本需要一个周期完成的逻辑转换为两个周期完成,分散时序的压力,从而使时序达到要求
有关流水线的优化,可以参考: 四输入乘法器的优化.
always @ (posedge clk)
if (reset == 1'b1) data_tmp_2 <= 0;
else data_tmp_2 <= data_tmp_in * data_tmp_in;
always @ (posedge clk)
if (reset == 1'b1) data_tmp_3 <= 0;
else data_tmp_3 <= data_tmp_2 * data_tmp_in;
always @ (posedge clk)
if (reset == 1'b1) data_tmp_4 <= 0;
else data_tmp_4 <= data_tmp_3 * data_tmp_2;
always @ (posedge clk)
if (reset == 1'b1) data_tmp_5 <= 0;
else data_tmp_5 <= data_tmp_4 * data_tmp_3;
always @ (posedge clk)
if (reset == 1'b1) data_tmp_6 <= 0;
else data_tmp_6 <= data_tmp_5 * data_tmp_4;
always @ (posedge clk)
if (reset == 1'b1) data_tmp_7 <= 0;
else data_tmp_7 <= data_tmp_6 * data_tmp_5;
assign data_cal_out= data_tmp_7;
![在这里插入图片描述](https://img-blog.csdnimg.cn/868a02cc1d1c48f4a4689e7a283b5c04.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/8ac6b1384e8c48f7ad8c3e78ad0c17ec.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)
-
用低频时钟
修改约束文件,频率约束为5mHz,T = 20ns
20230119修改:
修改约束文件,频率约束为50MHz,T = 20ns
create_clock -name clk -period 20.000 [get_ports clk]
![在这里插入图片描述](https://img-blog.csdnimg.cn/1adb476761f34792890ddbf89d379eb9.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQnVubnk5X18=,size_20,color_FFFFFF,t_70,g_se,x_16)