时序分析是FPGA开发过程中极为重要的一环。在一些简单的工程中时序约束可能会被忽略,但是时序约束仍然是保证系统正常工作的关键因素之一。quartus ii的时序约束可以通过TimeQuest Timing Analyzer来完成。
参考《FPGA现代数字系统设计及应用》
1.TimeQuest基本流程
TimeQuest时序约束是作用在门级网表上的,因此在进行时序约束前应该首先编译一边工程,之后进行时序约束并再次编译进行时序分析,直至无时序错误为止,之后烧写工程下板子。
2.实验代码
所用板子为altera DE2板子,FPGA为Cyclone II:EP2C35F672C6,quartus版本为13.0
实例化的pll,输入时钟为50M的CLOCK_50,输出为25M和10M的clk_25m与clk_10m时钟。
module work (
CLOCK_50, // On Board 50 MHz
KEY, // Pushbutton[3:0]
SW, // Toggle Switch[17:0]
LEDR
);
input CLOCK_50; // On Board 50 MHz
input [3:0] KEY; // Pushbutton[3:0]
input [17:0] SW; // Toggle Switch[17:0]
output [17:0] LEDR; // LED Red[17:0]
wire ret, clk, clk_25m, clk_10m;
pll (
.inclk0(CLOCK_50)
,.c0 (clk_25m)
,.c1 (clk_10m)
);
assign clk = CLOCK_50;
assign rst = !KEY[3];
reg [3:0]counter1, counter2, counter3;
always @(posedge clk or posedge rst) begin
if (rst) begin
// reset
counter1 <= 0;
end
else begin
counter1 <= counter1 + 1;
end
end
always @(posedge clk_25m or posedge rst) begin
if (rst) begin
// reset
counter2 <= 0;
end
else begin
counter2 <= counter2 + 1;
end
end
always @(posedge clk_10m or posedge rst) begin
if (rst) begin
// reset
counter3 <= 0;
end
else begin
counter3 <= counter3 + 1;
end
end
assign LEDR[0] = (counter1==4'b1111) ? 1:0;
assign LEDR[1] = (counter2==4'b1111) ? 1:0;
assign LEDR[2] = (counter3==4'b1111) ? 1:0;
endmodule
1).预编译
建立工程,键入代码,分配管脚,编译工程得到门级网表。
此时编译后,时序约束报表处为红色代表时序有错,不过一般对于这种小程序来说,一样是可以运行的。
此时会报警告:
Critical Warning (332012): Synopsys Design Constraints File file not found: 'work.sdc'. A Synopsys Design Constraints File is required by the TimeQuest Timing Analyzer to get proper timing constraints. Without it, the Compiler will not properly optimize the design.
2).调出TimeQuest工具
Tools->TimeQuest Timing Analyzer打开时序约束工具。
3).创建时序分析网表
点击Netlist->Create Timing Netlist来创建一个新的约束网表,由于输入的门级网表是综合后适配的因此选择post-fit。
当然所有这些任务都可以通过tcl脚本语言来实现,如图中的tcl command。
speed grade应该是跟器件有关。
4).创建时钟
Constraints->Create Clock,在对话框中填写系统时钟信息。
Clock name可以自己命名,之后将其与实际的时钟端口对应就可以。
period是周期,要与实际周期一致,板子上的时钟引脚是50M,因此键入20ns。
waveform edges是上升沿与下降沿。
Targets为对应的时钟管脚,这里对应了CLOCK_50。
之后点击run即可。
5).设置非理想时钟。
我们所使用的时钟都是非理想的,一般要给时钟流出余量。
latency是寄存器时钟信号与时钟源信号之间的相位差;uncertainty是寄存器与寄存器之间的时钟信号相位差,在此对uncertainty进行设置。
constraints->Set Clock Uncertainty,设置时钟源的setup uncertainty为1ns。
6).设置输入延时
模块的输入延时与输出延时都是可以估算的,一般是自行给一个估计的数值,以便工具计算内部逻辑延时约束。
在此,按照书上所建议,对输入端口的时钟预留40%的外部延时时间即8ns。
Constraints->Set Input Delay
7).设置输出延时
Constraints->Set Output Delay
8).设置pll时钟约束
Constraints->Derive PLL Clocks
可直接生成pll时序约束。
9).查看时钟设置。
在tasks页面中的diagnostic-Report Clocks中可以查看时钟约束情况。
10).写出SDC文件。
Constraints->Write SDC Files,保存文件。
11).查看SDC文件
在work文件夹下可以查看.sdc文件,其中为对应的tcl时序约束脚本。
12).添加约束文件
在工程界面右键,Settings->TimeQuest Timing Analyzer,点击添加.sdc文件。
13).编译工程
此时可以看到.sdc文件已经添加,再次编译工程,可以看到时序报告已经不是红色了。
14).查看报告并烧写