差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 后一修订版 两侧同时换到之后的修订记录 | ||
5._时钟分频 [2017/03/05 01:09] zhijun [小结] |
5._时钟分频 [2017/03/07 21:23] zhijun [Verilog代码] |
||
---|---|---|---|
行 44: | 行 44: | ||
output clkout; //输出信号,可以连接到LED观察分频的时钟 | output clkout; //输出信号,可以连接到LED观察分频的时钟 | ||
| | ||
- | | + | //parameter是verilog里常数语句 |
parameter WIDTH = 3; //计数器的位数,计数的最大值为 2**WIDTH-1 | parameter WIDTH = 3; //计数器的位数,计数的最大值为 2**WIDTH-1 | ||
parameter N = 5; //分频系数,请确保 N < 2**WIDTH-1,否则计数会溢出 | parameter N = 5; //分频系数,请确保 N < 2**WIDTH-1,否则计数会溢出 | ||
行 67: | 行 67: | ||
if(!rst_n) | if(!rst_n) | ||
clk_p<=0; | clk_p<=0; | ||
- | else if (cnt_p<(N>>1)) //N>>1表示左移一位,相当于除以2去掉余数 | + | else if (cnt_p<(N>>1)) //N>>1表示右移一位,相当于除以2去掉余数 |
clk_p<=0; | clk_p<=0; | ||
else | else | ||
行 103: | 行 103: | ||
\\ | \\ | ||
\\ | \\ | ||
+ | |||
+ | 测试文件,进行功能仿真时需要编写testbench测试文件。verilog里的testbench文件和源文件一样也是.v文件,仿真能让我们更直观的观察信号波形,可以先阅读[[lattice_diamond的使用|Diamond的使用]]了解如何使用Diamond中集成的仿真工具。 | ||
+ | |||
+ | <code verilog> | ||
+ | |||
+ | // ******************************************************************** | ||
+ | // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< | ||
+ | // ******************************************************************** | ||
+ | // File name : divide_tb.v | ||
+ | // Module name : divide_tb | ||
+ | // Author : STEP | ||
+ | // Description : clock divider | ||
+ | // Web : www.stepfpga.com | ||
+ | // | ||
+ | // -------------------------------------------------------------------- | ||
+ | // Code Revision History : | ||
+ | // -------------------------------------------------------------------- | ||
+ | // Version: |Mod. Date: |Changes Made: | ||
+ | // V1.0 |2017/03/02 |Initial ver | ||
+ | // -------------------------------------------------------------------- | ||
+ | // Module Function:divide.v时钟分频器的测试文件 | ||
+ | |||
+ | `timescale 1ns/100ps //仿真时间单位/时间精度,时间单位要大于或者等于时间精度 | ||
+ | | ||
+ | module divide_tb(); //测试文件也是一个module,因为用于仿真所以无需输入输出信号 | ||
+ | |||
+ | reg clk,rst_n; //需要产生的激励信号定义,激励信号需要过程块产生所以定义为reg型变量 | ||
+ | wire clkout; //需要观察的输出信号定义,定义为wire型变量 | ||
+ | |||
+ | //初始化过程块 | ||
+ | initial | ||
+ | begin | ||
+ | clk = 0; | ||
+ | rst_n = 0; | ||
+ | #25 //#表示延时25个时间单位 | ||
+ | rst_n = 1; //产生了一个初始25ns低电平,然后变高电平的复位信号 | ||
+ | end | ||
+ | |||
+ | always #10 clk = ~clk; //每隔10ns翻转一次clk信号,也就是产生一个时钟周期20ns的clk,频率为50MHz | ||
+ | |||
+ | //module调用例化格式 | ||
+ | divide #(.WIDTH(4),.N(11)) u1 ( //#后面的()中为参数传递,如果不传递参数就是所调用模块中的参数默认值 | ||
+ | //divide表示所要例化的module名称,u1是我们定义的例化名称,必须以字母开头 | ||
+ | .clk (clk), //输入输出信号连接。 .clk表示module本身定义的信号名称;(clk)表示我们在这里定义的激励信号 | ||
+ | .rst_n (rst_n), //在testbench里定义的信号名称可以与所要调用module的端口信号名称不同 | ||
+ | .clkout (clkout) | ||
+ | ); | ||
+ | endmodule | ||
+ | |||
+ | </code> | ||
+ | |||
====引脚分配==== | ====引脚分配==== | ||
------- | ------- | ||
- | 小脚丫上的系统时钟连接到FPGA的C1脚,时钟为12MHz。如果我们想得到1秒周期的时钟那么需要设置N=12000000,WIDTH至少为24 | + | 小脚丫上的系统时钟连接到FPGA的C1脚,时钟为12MHz。你可以通过仿真波形观察分频时钟(注意仿真的时间是有限的,所以分频时钟频率需要较高)。如果我们想通过眼睛观察LED的闪烁,那么需要设置参数N和WIDTH得到一个频率较低的时钟(例如N=12000000,WIDTH=24,分频时钟周期为1秒)。 |
\\ | \\ | ||
^信号 ^引脚 ^ | ^信号 ^引脚 ^ | ||
行 113: | 行 164: | ||
\\ | \\ | ||
- | 分频时钟输出到小脚丫上的LED,如果时钟周期够大将能够看到LED闪烁。修改程序中的分频系数和计数器位数就能够调整LED闪烁速度(注意计数的最大值一定要保证超过分频系数N)。 | + | 修改程序中的分频系数和计数器位数就能够调整LED闪烁速度(注意计数的最大值一定要保证超过分频系数N)。 |
\\ | \\ | ||
====小结==== | ====小结==== | ||
------ | ------ | ||
- | 在本实验学习了如何进行任意整数的分频设计,我们产生各种时钟,通过修改程序还能实验调整输出时钟的频率、相位以及占空比,非常灵活。在下个实验我们将进一步了解时序逻辑,如何利用时钟来进一步设计,请看最常见的[[6.LED流水灯|流水灯]]。 | + | 在本实验学习了如何进行任意整数的分频设计,我们产生各种时钟,通过修改程序还能实验调整输出时钟的频率、相位以及占空比,非常灵活。同时学习了如何编写testbench文件,了解verilog中如何例化module,在后面的学习中将会经常用到。在下个实验我们将进一步了解时序逻辑,如何利用时钟来进一步设计,请看最常见的[[6. LED流水灯|流水灯]]。 |