欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

【FPGA学习】时钟分频

发布时间:2024/3/26 编程问答 66 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【FPGA学习】时钟分频 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

概况:

用一个频率块的时钟产生一个频率小的时钟

实验目的:

掌握任意就分频的写法

原理:

一般来说 开发板上面只有一个晶振,即只有一种时钟频率,但是我们有时候需要用到不同频率的时钟,若想要更慢的时钟,则可以将该固定的是何种进行分频,若想要更快的时钟,则可以在这个固定的时钟上进行倍频。无论是分频还是倍频,我们都有两种方法,一种你是使用pll核,另外一种是手动用verilog hdl描述。(适用于整数比的分频),只有调用pll核才能进行倍频,一般在进行非整数比的分频或者倍频的情况下都使用pll核pll为专用电路他生成的时钟到每一级寄存器时间延迟是固定的,称这个时钟网络的时钟偏斜比较小

     假如我们要做一个四分频(当前时钟周期的四倍)的时钟,首先我们需要确定是否有四个周期的,然后用一个计数器来记时钟的周期的个数,将连续的一般固定时钟周几设置为高(1),另外连续的一半设置为低(0)。、

四分频

module div_clk_4(input wire clk,input wire rst,//高电平有效,XILINX器件提倡高电平有效output reg clk_4);reg [1:0] div_cnt;always @(posedge clk )begin if(rst == 1'b1)begindiv_cnt <= 'd0;endelse if(div_cnt == 2'd3) begin div_cnt <= 'd0; endelse begindiv_cnt <= div_cnt + 1'b1;end endalways @(posedge clk )begin if(rst == 1'b1)beginclk_4 <= 1'b0;endelse if (div_cnt == 2'd1)beginclk_4 <= 1'b1;endelse if (div_cnt == 2'd3)beginclk_4 <= 1'b0;endend endmodule

tesbench

`timescale 1ns/1ns module tb_div_clk_4();reg clk;reg rst;wire clk_4;div_clk_4 u_div_clk_4(.clk (clk),.rst (rst),.clk_4 (clk_4)); always #10 clk = ~clk;initial beginclk = 0;rst = 1;#100rst = 0;//退出复位end endmodule

 

 十六分频

/* */ module div_clk_16(input wire clk,input wire rst,output reg [1:0] po_cnt = 'd0);reg [1:0] div_cnt;reg clk_4;always @(posedge clk )begin if(rst == 1'b1)begindiv_cnt <= 'd0;endelse if(div_cnt == 2'd3) begindiv_cnt <= 'd0; endelse begindiv_cnt <= div_cnt + 1'b1;end endalways @(posedge clk )begin if(rst == 1'b1)beginclk_4 <= 1'b0;endelse if (div_cnt == 2'd1)beginclk_4 <= 1'b1;endelse if (div_cnt == 2'd3)beginclk_4 <= 1'b0;endendalways @(posedge clk_4 )beginif(rst == 1'b1)beginpo_cnt <= 1'b0;endelse if (po_cnt == 2'd3)beginpo_cnt <= 'd0;endelse beginpo_cnt <= po_cnt + 1'b1;endend endmodule

 tesbench

`timescale 1ns/1ns module tb_div_clk_16();reg clk;reg rst;wire [1:0] po_cnt;div_clk_16 u_div_clk_16(.clk (clk),.rst (rst), .po_cnt (po_cnt)); always #10 clk = ~clk;initial beginclk = 0;rst = 1;#100rst = 0;end endmodule

可见po_cnt信号出现异常,这是由于同步复位所导致的,如果将复位信号“后推”能否解决,答案是不能的因为一旦rst复位信号后延那么div_cnt也随之后延,最后仍然检测不到rst == 1的状态。

 故给po_cnt赋值一个初始值即可解决问题

xilinx建议的复位准则(原文连接xilinx建议的复位准则_leave_her_johnny的博客-CSDN博客_xilinx 复位)

1.尽量少用复位 

FPGA提供专用的全局复位置位信号GSR,在配置结束后,寄存器状态初始化到设定值或者默认逻辑零状态

控制路径可能需要复位,数据路径通常不需要复位

使用功能仿真可判断是否需要复位

少用复位整体上改善性能,减小面积和功耗

 2.必须复位时采用同步复位

同步复位可直接映射到FPGA架构中的更多功能器件

DSP48、块RAM只提供同步复位

3.确保使用高电平有效复位 

​因为XILINX内SLICE和内部逻辑等为高电平复位有效,用低电平需要反相器 ​

 4.避免异步复位

如果使用异步复位,则异步复位同步释放

关于时钟域的一些笔记

        上图可见有两个时钟域,时钟域一是由晶振输入的它所走的是全局时钟网络(这个网络在设计芯片的时候已经布局好了,在未来使用过程中到达每一级寄存器的时间是几乎相等的

对于clk_4的时钟网络,是由我们自己分频出来的,在设计初期没办法设计走线,所以由自己设计出来的分频时钟走的是普通数据线,(到达每一级寄存器的时间延迟是不一样的),延时一旦不一样就会导致时钟的偏斜(Clock Skew))偏大。这种延误会导致时钟的错误。

所以这种自分频的时钟最好不要使用。

总结

以上是生活随笔为你收集整理的【FPGA学习】时钟分频的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。