概述
前言
学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。
学习视频:是根据野火FPGA视频教程——第十三讲
https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3
理论学习
计数器在数字系统中主要是对脉冲的个数进行技术,实现测量、计数、控制及分频功能。控制器中的指令地址,运算器做乘法、除法。
基础知识请参考本人《数字电路技术基础》计数器部分:
《数字电子技术基础》6.3 时序逻辑电路——寄存器、计数器及脉冲发生器功能介绍_追逐者-桥的博客-CSDN博客寄存器和移位寄存器、计数器功能介绍https://blog.csdn.net/ARM_qiao/article/details/124415549
实战演练
一、设计规划
1.1 实验目标
让计数器计数1s时间间隔,来实现LED灯每隔1s闪烁一次
1.2 硬件资源
二、程序设计
2.1 模块框图及波形图
2.2 代码编写
//
// Company: 追逐者——桥的小作坊
// Create Date: 2022/05/05 20:35:58
// Module Name: counter
// Tool Versions: Vivado 2018_3
// Description:
// Revision 0.01 - File Created
// Additional Comments:FPGA学习代码
//
module counter
#(
parameter COUNT_MAX = 25'd24_999_999 //作为模块的一个参数,再实例化时可修改
)
(
output reg led_out ,
input wire sys_clk, sys_rst_n
);
// parameter COUNT = 25'd24_999_999; //可用于模块名后,再实例化时可修改
// localparam COUNT = 25'd24_999_999; //只能用于模块内部使用
reg [24:0] count;
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
count <= 25'd0;
else if(count == COUNT_MAX)
count <= 25'd0;
else
count <= count + 25'd1;
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
led_out <= 1'b0;
else if(count == COUNT_MAX)
led_out <= ~led_out;
else
led_out <= led_out;
endmodule
如果计数器结束,不只触发LED灯闪烁,而且还会触发其他输出。当多的时候不如向声明一个常数变量一样,生成一个触发标志,使用标志进行功能的触发,这样在更改调试触发条件时只需要更改标志即可,不需要每个功能的触发都改。
//count_flag:计数到最大值产生标志信号,每当计数满标志信号有效时取反
reg count_flag;
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
count <= 25'd0;
else if(count == OUNT_MAX - 25'd1)
count_flag <= 1'b1;
else
count_flag <= 1'b0;
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
led_out <= 1'b0;
else if(count_flag == 1'b1)
led_out <= ~led_out;
else
led_out <= led_out;
综合后的RTL视图,可以右键点击视图,查看对应的代码。
三、逻辑仿真
3.1 仿真文件的编写
`timescale 1ns / 1ns
//
// Company: 追逐者——桥的小作坊
// Create Date: 2022/05/05 20:35:58
// Module Name: counter
// Tool Versions: Vivado 2018_3
// Description:
// Revision 0.01 - File Created
// Additional Comments:FPGA学习代码
//
module tb_counter();
reg SYS_CLK, SYS_RST_N;
wire LED_OUT;
initial begin
SYS_CLK = 1'b1;
SYS_RST_N <= 1'b0;
#20
SYS_RST_N <= 1'b1;
end
always #10 SYS_CLK = ~SYS_CLK;
counter
#(
.COUNT_MAX (25'd15) //作为模块的一个参数,再实例化时可修改
)
count_inst
(
.led_out( LED_OUT ),
.sys_clk( SYS_CLK ),
.sys_rst_n(SYS_RST_N)
);
endmodule
3.2 仿真波形图对比
对比上面波形图,虽然源代码是0.5s变换一次电平,但是由于仿真代码中设置的最大计数是15,因此再15后,计数器下一个状态变为0,同时改变输出电平。
四、上板验证
4.1 管脚绑定
界面绑定
Ctrl+s保存成XDC文件
编写绑定程序
set_property IOSTANDARD LVCMOS33 [get_ports led_out]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n]
set_property PACKAGE_PIN M21 [get_ports led_out]
set_property PACKAGE_PIN W19 [get_ports sys_clk]
set_property PACKAGE_PIN N15 [get_ports sys_rst_n]
综上所述,目前个人感觉还是界面绑定比较方便。
管脚绑定后硬件的连线图:
五、总结
最后
以上就是矮小发卡为你收集整理的二、11【FPGA】时序逻辑电路——计数器前言理论学习实战演练的全部内容,希望文章能够帮你解决二、11【FPGA】时序逻辑电路——计数器前言理论学习实战演练所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复