二、11【FPGA】时序逻辑电路——计数器

前言

学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。

学习视频:是根据野火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 硬件资源

二、11【FPGA】时序逻辑电路——计数器_第1张图片

二、程序设计

2.1 模块框图及波形图  

二、11【FPGA】时序逻辑电路——计数器_第2张图片

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视图,可以右键点击视图,查看对应的代码。

二、11【FPGA】时序逻辑电路——计数器_第3张图片

三、逻辑仿真

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 仿真波形图对比

二、11【FPGA】时序逻辑电路——计数器_第4张图片二、11【FPGA】时序逻辑电路——计数器_第5张图片 对比上面波形图,虽然源代码是0.5s变换一次电平,但是由于仿真代码中设置的最大计数是15,因此再15后,计数器下一个状态变为0,同时改变输出电平。

四、上板验证

4.1 管脚绑定

二、11【FPGA】时序逻辑电路——计数器_第6张图片

界面绑定

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】时序逻辑电路——计数器_第7张图片

二、11【FPGA】时序逻辑电路——计数器_第8张图片

五、总结 

新语法总结
重点掌握
1 paramter 的用法 (出现在模块内部的局部定义)
知识点总结
1 、能够通过自己慢慢的分析绘制出时序逻辑电路的波形;
2 、学会根据计数器的计数时钟来精确计算我们要想计数的时间和个数,熟练的控制计数
器;
3 、能够了解 flag 脉冲标志信号的意义,如何精确产生,以及应用场景;
4 、学会分析简单时序逻辑的 RTL 视图,理解设计的 RTL 代码就是硬件的思想。

你可能感兴趣的:(#,二,Xilinx,Artix-7基础教程(完),Verilog,HDL,FPGA开发,硬件描述语言,数字电子技术基础)