vivado 自定义内部衍生时钟

今天进行ASK信号解调开发的时候,ADDA、判决门限等需要有一个较低的时钟来驱动。但是vivado自带的PLLMMCM出的频率最低是6.25MHz左右,所以比如我这边需要一个100kHz的时钟,这就需要自己利用sys_clk自定义分频生成一个衍生时钟。

分频模块 divi_fre

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: kevin
//
// Create Date: 2023/07/10 10:23:26
// Design Name:
// Module Name: divi_fre
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 分频 用于约束

// 50M/100 目前为时钟为 timer = 500kHz 调整DIVNUM即可
//////////////////////////////////////////////////////////////////////////////////
module divi_fre #(parameter DIVNUM=100,parameter WIDTH=9)(
input clk,
input rst_n,
output reg divi_clk
);
reg [WIDTH-1:0] counter;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
counter <= 'd0;
end
else begin
counter <= counter + 1'b1;
if(counter==DIVNUM/2-1)
counter <= 'd0;
end

end

always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
divi_clk <= 1'b0;
end
else begin
if(counter == DIVNUM/2-1)begin
divi_clk <= ~divi_clk;
end
end
end

endmodule

时钟约束 xdc文件配置

1
2
3
create_clock -period 20.000 -name sys_clk -waveform {0.000 10.000} [get_ports sys_clk]

create_generated_clock -name clk_ASKdemod -source [get_pins divi_fre/divi_clk_reg/C] -divide_by 100 [get_pins divi_fre/divi_clk_reg/Q]
  • 第一个是 sys_clk 系统时钟
  • 第二个是我们需要加入的时钟约束,名字自取;source指向时钟源和输出端口、divide_by 分频系数 输出端口
  • get_ports获取的是FPGA的IO端口。get_pins获取的是FPGA内部子模块的pin。
  • 这边具体的端口可以看看原理连接图进行一步确定,点击对应的分频模块

为什么要进行时钟约束

通俗来说,就是因为我们Verilog写出来后,在FPGA里面是随机分配对应的资源的,也就是说功能块资源、寄存器资源、布线资源等是随机分布的。布线的不同路径将使得延迟时间不同,就会出现竞争冒险的现象,同时如果不加约束时钟稳定性也会有一定影响

关于具体的理论以及分析可以康康这篇

https://zhuanlan.zhihu.com/p/560103525

TOP文件的调用

1
2
3
4
5
6
7
8
9
10
11
12
wire clk_ASKdemod;//定义

divi_fre U1( //时钟分频输出
.clk(sys_clk),
.rst_n(rst_n),
.divi_clk(clk_ASKdemod)
);
Rectifier U2 ( //整流
.clk(clk_ASKdemod), //位同步时钟
.ask_data(adc_data[11:0]), //ASK输入信号
.rec_out(rec_out) //整流后ASK信号
);
  • 在使用的时候直接定义完,在divi_fre引出下定义的时钟信号然后就可以接到对应的模块使用比如这边整流模块

可能遇到的问题:
  • 如果出现上述问题,大概率是top文件调用的时候写的有问题或者是xdc文件里时序约束有点问题(可以康康是不是哪里多了个空格或者括号)

  • top文件里如果不输出信号就不用在module里面添加output接口否则IO口配置将报错

更新完vivado可能遇到的问题

更新完2022.2后,以前在2019.2写的FIR 配置的IP核升级后需要重新配置一遍可以参考我之前博客(配置步骤一致)。不然🤡🤡🤡

查相关资料的时候看到个好玩的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
你在山脚下,你想到达山顶,你的坐骑名字叫EDA。你大喊一声“EDA,带我到山顶!”。
EDA抬头望望你,“给个约束吧”你想了想:“用最短的时间!”,于是EDA扛着你坐上了索道。
“坐索道没意思,我要同时看尽山上的风景”,于是EDA按照景点的分布背着你迂回到顶。
“这山有点险峻了,我怕会掉下去”,于是EDA绕着山,呈螺旋上升状慢慢爬着。。。。。。。
然鹅,你的回答却是:“随便整”
EDA陷入了沉思:这TMD有成千上万种的上山姿势,我选哪种呢?
于是EDA额头上的进度条永远停留在了0%。
FPGA就像在一张纸上预先画好两点(标准器件),作为设计者,你要把两点连起来,
你可以画根直线,也可以画一串折线,也可以画出各种曲线,有无数种可能。
你给出一个约束,EDA就能把大量不符合约束的线放弃掉,你给的约束越多,
它能排除掉的可能就越多,最后剩下寥寥无几的几条可行的线,所以EDA才能综合出最终的电路。
EDA里的布线算法都是各家FPGA厂家不传秘籍,算法的输入包括了电路功能性描述和各种约束,
这些约束包括但不限于:速度,功耗,稳定性等等。某些约束有的是用户可设的,
某些约束是FPGA内器件自身的性能限制。