跳转至

电路性能分析

在前面的实验中,我们已经学习了如何使用 Vivado 进行仿真测试和上板。本次实验中,我们将学习如何使用 Vivado 测量电路的时间性能和资源使用情况。

在这里,我们用一个组合逻辑的 16 位乘法器作为例子,来学习如何分析电路的时间性能和资源使用情况,并对比使用超前进位加法器与串行进位加法器作为子模块时乘法器的性能差距。


2.1 预备知识

2.1.1 组合电路:测试模块

电路的时间性能是指从输入端到输出端经过的最长路径所需要的时间。测量电路的时间性能则是通过调整时钟频率来做到的。调整时钟频率,直到电路恰好不会超时,此时得到的时钟频率就是电路的最大工作频率。

Tips:理想与现实

你可能已经经历过了:行为仿真正确的电路上板运行不正常。这是由于行为仿真仅仅考虑到了最基本的电路逻辑是否正确,而忽略了电路中的时序延迟。现实情况下,电路很可能因为延迟问题无法正常工作。

对于时序逻辑电路来说,由于有时钟 clk,我们可以直接测试时钟频率。而组合逻辑电路没有时钟,所以我们需要将组合逻辑电路包裹在一个测试模块中,才能测试组合逻辑模块的延迟。

测试模块的抽象模型大体如下图:

Image title

简单而言,只要将待测试的组合逻辑电路的输入和输出分别连接到两组寄存器上,就能实现其时延的测试。

具体地说,当 clk 到达上升沿时,输入寄存器将值传递给组合逻辑电路进行运算,当下一个 clk 上升沿到来后,如果组合逻辑电路已经完成运算,那么输出寄存器将保存组合逻辑电路的输出值,我们也可以得知待测试电路的延迟不超过当前的时钟周期;否则,输出的寄存器无法按时更新,则产生时序违例。

补充:时序违例与关键路径

时序违例是指,电路的最大延迟大于当前的时钟周期。此时,Vivado 会报出 Critical warning,但仍然可以上板。

Image title
时序违例

所以为什么要尽量避免时序违例呢?首先,如果电路的最大延迟大于时钟周期,这会导致在一个周期内,可能会有若干路径无法完成更新,使得整个电路的功能遭到破坏,行为朝着不可控的方向发展。

关键路径则是指电路中延迟最长的路径。我们知道,信号在电路中实际上是流式传输的,整个电路的最大延迟往往被某一条延迟最大的路径限制住——它往往也是我们优化电路代码,提高时钟频率的抓手之一。

以 16 位单周期组合乘法器的测试为例,测试模块的 Verilog 代码如下:

test
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module test_mult (
    input                   [ 0 : 0]        clk,
    input                   [15 : 0]        a,
    input                   [15 : 0]        b,
    output      reg         [31 : 0]        out
);

reg [15:0]      a_reg;
reg [15:0]      b_reg;
wire [31:0]     out_wire;

always @(posedge clk) begin
    a_reg <= a;
    b_reg <= b;
    sum <= sum_wire;
end

// 下面例化一个组合逻辑乘法器,MUL 模块的具体实现此处省略。
MUL mul(
    .a(a_reg),
    .b(b_reg),
    .res(out_wire)
);
endmodule

2.1.2 时序电路:性能计算公式

时序电路完成某个计算功能往往需要多个周期才能完成,对于它们的时间性能,我们往往使用公式 \(T=N/f_{max}\) 来衡量,其中,\(N\) 为完成运算所需要的时钟周期数,\(f_{max}\) 为电路的最大工作频率,所以,\(T\) 代表的是该时序电路完成一次计算总共需要的最小时间。完成相同任务的电路,\(T\) 越小,说明电路完成任务花费的时间越少,电路的时间性能越好。

时钟周期一般需要通过仿真或分析代码确定,最大工作频率仍然可以类似组合电路的测试方法进行测试。区别是,时序电路由于已经含有 clk,不再需要设计测试模块,可以直接查看时序报告,确定最大工作频率。

Tips

事实上,你可以认为配合测试模块的组合电路就是 \(N=1\) 时的时序电路。

由上面的叙述可见,电路的时间性能主要取决于其完成任务所需的时钟周期数与最大工作频率。所以,我们在优化电路时间性能时,往往可以从这两个方面入手,考虑如何减少其完成任务所需的时钟周期数,或者通过优化电路的结构,提高其最大工作频率。

2.2 调整时钟频率

一般情况下,Vivado 默认采用 100MHz 的时钟频率进行综合。我们可以通过修改 .xdc 文件来调整时钟频率。

## This file is a general .xdc for FPGAOL_BOARD (adopted from Nexys4 DDR Rev. C)
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project

## Clock signal
set_property -dict { PACKAGE_PIN E3    IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];

## ...

值得注意的是,我们打开了 create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}]; 的注释,并将 CLK100MHZ 修改为了 clk。这行代码的意思是,将 clk 端口设置为时钟信号,并将其时钟周期设置为 10ns,即 100MHz 的时钟频率。

Tips:-waveform (x,y)

-waveform {x y} 控制时钟上升沿与下降沿在一个周期中的位置,即上升沿在 \(x\) ns 时刻,而下降沿在 \(y\) ns 时刻。例如,-waveform {2.5 5} 产生的时钟波形如下图:

Image title

虽然我们平常不需要用到 waveform,但是需要注意的是,必须保证 \(x<y\),且均小于时钟周期,否则会导致综合失败。

例如,如果想要将时钟频率修改成 500MHZ,则需要将这一行代码修改为 create_clock -add -name sys_clk_pin -period 2.00 -waveform {0 1} [get_ports {clk}];

★ 2.3 测量电路性能

当我们对电路完成实现(Implementation)后,即可查看各种电路性能指标。

Image title

打开左侧边栏,点击 Report Timing Summary 即可查看电路的时序信息,点击 Report Utilization 即可查看电路的资源使用情况。

2.3.1 时间性能

在 .xdc 文件中设置时钟频率为 100MHZ,点击 Report Timing Summary 后,基于超前进位加法器的组合乘法器时序情况如下:

Image title

10ns 时序报告

图中,Worst Negative Slack(WNS) 代表的是电路的最大延迟(即关键路径的延迟)与时钟周期之间的差距。上图中 WNS 为 1.989ns,表明电路最大延迟至少还有 1.989ns 的余裕。Total Negative Slack(TNS) 代表的是电路所有路径的延迟超时之和,表征了电路的整体性能,它只会在 WNS 为负时才会是负的(我们一般不用考虑这个指标)。

如果最大延迟大于时钟周期会产生什么结果呢?下面将时钟频率设置为 172MHZ(即5.8ns),时序情况如下:

Image title

5.8ns 时序报告

可以看到,WNS 是负数,-0.044ns,时序违例。这说明关键路径的延迟比时钟周期多约 0.044ns。

我们可以在左侧选择 Intra-Clock Paths/sys_clk/Setup,这里会将路径按照延迟长短进行排序,Slack 代表的即为对应路径的延迟。

Image title

5.8ns时序报告
Tips:逻辑延迟与线网延迟

Logic Delay 和 Net Delay 分别代表路径的逻辑延迟和线网延迟,其中前者代表路径上的逻辑门导致的延迟之和,后者则表示板上布线带来的延迟。由于信号是以电信号传输的,当线的长度越长,其线网延迟也越大。当电路设计的比较复杂时,Vivado 使用的资源量增多,难以在平面上布线,部分电线的长度较长,线网延迟可能就会升高。

双击路径(比如 Path 1)可以打开该条路径的详细时序信息,包括信号在路径上传输过程中到达各个节点时的总延迟。这可以提示我们电路中最耗时的是哪些部分,指导我们针对哪些部分优化电路。

Image title

5.8ns 时序报告

本节中,我们只要求大家能够通过修改时钟频率,观察时序报告中的 WNS,比较不同电路实现的性能即可。为了测出电路的最大工作频率,你可以参考 WNS,或者采用二分的方法,直到 WNS 为正且较小,即时钟周期恰好大于电路的最大延迟。例如:如果将时钟频率设置为 167MHZ(即 6.0ns),得到的结果如下图所示。

Image title

6.0ns 时序报告

可以看到,WNS 为正且较小,因此我们可认为基于超前进位加法器的组合乘法器的最大工作频率约为 167MHz。你也可以测量得更精准,比如让 WNS 小于 0.05。

同样是 167MHZ,换成基于串行进位加法器的组合乘法器,时序情况如下:

Image title

6.0ns 时序报告

WNS 为负,表明出现时序违例。由此可以看出,超前进位加法器的组合时间性能要好于串行进位加法器。

Tips:WNS 一定准确吗

Vivado 在综合布线时,事实上是使用遗传等启发式算法进行优化的,WNS 并不一定准确,可能会有所波动。当设置的时钟频率较低时,Vivado 不一定会尝试将电路优化到最佳,导致 WNS 一般会偏低,实际的时间余裕可能更大。而当设置的时钟频率较高时,Vivado 在发现时序很难满足时,会想尽一切办法优化时序,直到确定无法解决时序问题,此时的 WNS 更为准确。

总之,尽管我们可以参考公式 \(f_{max}=\frac{1}{T_{clk}-WNS}\) 计算最大工作频率,但是不要过于相信 WNS 的准确性,最好实际跑一遍对应频率的综合实现,实践出真知。

2.3.2 资源占用

点击 Report Utilization 后,基于超前进位加法器的组合乘法器资源使用情况如下图:

Image title

LookAhead_Utilization

具体来说,图中各个指标的含义是:

  1. LUT:查找表(Look-Up-Table),是 FPGA 实现组合逻辑的硬件单元。包括用做逻辑函数发生器的 LUT 和用做存储单元的 LUTRAM,前者与组合电路的逻辑复杂程度成正相关。

  2. LUTRAM:分布式存储器(Look-Up-Table RAM),指设计消耗的 LUT 被用作了存储单元或移位寄存器。(暂未涉及)

  3. FF:触发器(Flip-Flop)边沿敏感的存储硬件单元,可以存储 1bit 数据,多用于表达寄存器。

  4. BRAM:(Block RAM)各种块存储功能的硬件单元。BRAM 通常用于存储大量数据,如作为 CPU 的存储单元。(暂未涉及)

图中没有的部分指标是因为这里的电路中并没有使用到对应的元件。可以观察到,该乘法器(包括其测试模块)使用了 98 个 LUT。

而当我们使用串行进位加法器作为子模块时,资源使用情况如下图:

Image title

Ripper_Utilization

可以观察到,该乘法器(包括其测试模块)使用了 56 个 LUT。由此可以看出,超前进位加法器确实要花费更多的资源(这里仅仅使用了 4 位超前进位)。


最后更新: November 6, 2023

评论