时间:2024-07-26 来源:网络搜集 关于我们 0
文章
简介
本系列文章主要针对FPGA初学者编写,包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解,旨在更快速的提升初学者在FPGA开发方面的能力,每一个章节中都有针对性的代码书写以及代码的讲解,可作为读者参考。
捌
第八章:时钟分频
数字电路中,时钟占有很重要的地位,时间的计算都要以时钟作为基本的单元。一般来说我们使用的开发板上面只有一个晶振,即只有一种频率的时钟,但是有时我们需要用到不同频率的时钟,若是想得到比固定的时钟频率更慢的时钟, 可以将该固定时钟进行分频,若是想得到比固定时钟频率更快的时钟,则可以在固定时钟频率的基础上进行倍频。无论分频和倍频,我们都有两种方式可以选择, 一种是器件厂商提供的 pll 核,另一种是自己动手来用 Verilog HDL 描述,本章中将讲解如何用 Verilog HDL 描述一个分频模块。
假设我们要在给定的时钟频率上,做一个四分频的时钟,首先我们需要确定是否已经有四个周期,这就需要一个计数器来记时钟周期的个数,将连续的一半固定时钟周期置为高(1),另外连续一半置为低(0),波形如图 1 所示。
图 1 分频波形
从图 1 中可以看出 clk_4 的一个周期占了 clk 的四个周期,div_cnt 主要作用是为了计 clk 的周期个数,当计满四个周期(0~3),则从头继续计数。根据图 1 可以得到如下所示的 Verilog HDL 代码。
代码示例 1:
代码解析 1:
①第 8 行定义了一个内部变量,用来计时钟 clk 的周期个数,由于只需要计 4 个周期(0~3)即可,所以位宽为 2;
②第 10~14 行描述了 div_cnt 的产生,在检测到clk上升沿时,div_cnt 加 1,由于 div_cnt 的位宽为 2,所以加到最大值 3 时,再加 1 则会归零;
③第 16~22 行描述了 clk_4 的产生,由图 1 可以看到,当 div_cnt 为 1 时, clk_4 被置高,当 div_cnt 为 3 时,clk_4 被置低,所以用 Verilog HDL 描述时,只需要通过两个 if 条件判定即可。
由于 Verilog HDL 每一条语句都是并行执行的,所以对不同的变量赋值时,可将不同的变量单独放在一个 always 块中执行,这样方便后期我们对代码的维护。
在我们用 Verilog HDL 描述数字电路时,不仅需要考虑功能是否正确,很多时候我们还需要考虑时序是否满足,也就是说我们需要考虑在数字电路中的信号延时问题。例如在代码示例 1 的基础上,我们可以使用分频出来的时钟再次产生一 个从 0~3 的计数器,具体的代码示例如下所所示,always 块中的触发条件改为 clk_4 的上升沿。
代码示例 2:
根据添加新的计数器后的代码,综合器(ISE)可以综合出如图 2 所示的电路。
图 2 ISE 综合电路结构
通过图 2 可以看出 clk 时钟直接控制 div_cnt 和 clk_4,间接控制 cnt,这样的代码书写格式会导致综合器无法保证 clk 到达每一级寄存器的线路长度一样,有可能会造成比较严重的时序问题,所以我们用 Verilog HDL 描述数字电路时,尽量所有寄存器的控制都用同一个时钟,我们只需要在代码中加入一个简单的标志即可完成代码示例 2 的功能一致。具体波形图如图 3 所示。
图 3 加入标志位的四分频计数器
在图 3 中产生四个 clk 周期计数器加 1 的代码需要多加入一个变量 div_flag, 虽然资源多占用了,但是换来的却是时序的稳定。具体 Verilog HDL 的描述如下 所示。
代码示例 3:
在第九章中将对Verilog HDL 中的Top_Down设计进行讲解。
未完待续
关注我们了解更多资讯