FPGA学习篇——Verilog学习之计数器的实现

PS: 目前手上仍然没有板子,按照野火视频的讲解,目前我们只能做到前面六步(其实第一步设计规划也是需要看板子的硬件的,但是现在没有板子就完全与野火传授的板子一致来看)

1 设计规划及波形绘制

**任务要求:**设计一个计数器,使得FPGA中的LED等在点亮0.5s再熄灭0.5s(LED低电平有效),循环往复。

**思路:**利用系统时钟周期来设计计数器(设FPGA的时钟50MHz,即时钟一个周期20ns):

即一个sys_clk图像对应的时间是20ns,那么0.5s就需要 个周期, 设置一个中间计数变量cnt,计数时钟走过的周期数,当时钟 走过了25000个周期后,使得输出取反 从而控制LED的亮灭(注意,由于通常是从0开始计数的,那么要走25000000个周期,即计数cnt为0~24999999)

计数器原理及波形图:

  • sys_clk为系统时钟用于计数

  • sys_rst_n为复位信号,本实验这里没有很大用处,但时序逻辑一般都有复位信号

  • led_out为计数器的输出,直接连接到Led处

可以看到,当复位信号无效且时钟上升沿,cnt开始计数,直到24999999个周期时,计数器cnt清零,重新开始计数,Out控制led灯,低电平点亮高电平熄灭,每0~24999999(即0.5s)可以看到Out取反一次。

2 代码编写

复制代码
module Counter
#(
    parameter cnt_max = 25'd24999999
)
(
    input          sys_clk,
    input          sys_rst_n,
    
    output  reg    Out
);

reg  [24:0]  cnt;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt <= 25'b0;
    else if(cnt == cnt_max)
        cnt <= 25'b0;        
    else
        cnt <= cnt + 25'b1;
        
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        Out <= 1'b0;
    else  if(cnt == cnt_max)
        Out <= ~Out;
   
endmodule
//    else if(cnt == cnt_max)
//        cnt <= 25'b0;

这里使用Quarters编译时出现了报错,以下代码编写方式会报错,详细见这一篇https://blog.csdn.net/weixin_72950851/article/details/146130167?spm=1001.2014.3001.5501

复制代码
always@(posedge sys_clk or negedge sys_rst_n)  // 敏感列表:仅时钟和复位
    if(sys_rst_n == 1'b0 || cnt == cnt_max)    // 条件判断:包含了 cnt 信号

3 逻辑仿真及波形验证

到了时序电路这,不像之前编写组合逻辑电路一般,一开始编写仿真文件时脑子有点空白,现在对仿真文件有了更深的理解。


编写仿真文件其实就相当于给你编写的模块模拟全部输入。

比如计数器我们进行波形图绘制时,输入就时钟信号clk和复位信号rst,因此我们在仿真文件中就要用代码去生成这两个输入信号:

(生成时钟信号)

(生成复位信号)

而此前组合逻辑,我们都是给模拟随机输入的情况,因此使用的是随机数,本质其实仿真文件还是去模拟所有的输入情况:

复制代码
`timescale 1ns/1ns
module tb_Counter();

reg     tb_sys_clk      ;
reg     tb_sys_rst_n    ;

wire    tb_Out          ;

initial begin
    tb_sys_clk      <= 1'b1;
    tb_sys_rst_n    <= 1'b0;
    #10
    tb_sys_rst_n    <= 1'b1;
 end
 
 
 always #10 tb_sys_clk <= ~tb_sys_clk;
 
 Counter 
 #(
    .cnt_max(25'd24999999)
 )Counter_inst(
    .sys_clk    (tb_sys_clk  ),
    .sys_rst_n  (tb_sys_rst_n),
              
    .Out        (tb_Out      )  
 );
 
 endmodule

注意,这里使用了参数parameter,在模块例化时要这样写:

++要例化的模块名++

#(

例化的参数

++给例化的模块重新命名++


. ++子模块的端口名++ ++对应要连接的顶层模块的端口名字++ ),

. ++子模块的端口名++ ++对应要连接的顶层模块的端口名字++ ),

...

);

其中,"."可理解为将两个端口连接的意思。

由于我们仿真的时间比较长,只取1s来看,在modelsim中可以看到,0.5s时输出实现了翻转:

同时,计数器也能够正常的计数,仿真验证通过。


(本贴仅是个人经验,参考哔哩哔野火视频: 16-第十三讲-计数器(二)_哔哩哔哩_bilibili如有侵权请联系我~)

相关推荐
晓幂4 小时前
【2025】HECTF
笔记·学习·web安全
慕云紫英5 小时前
基金申报的一点经验
学习·aigc
微露清风5 小时前
系统性学习C++-第十八讲-封装红黑树实现myset与mymap
java·c++·学习
宝贝儿好5 小时前
【强化学习】第六章:无模型控制:在轨MC控制、在轨时序差分学习(Sarsa)、离轨学习(Q-learning)
人工智能·python·深度学习·学习·机器学习·机器人
大、男人5 小时前
python之asynccontextmanager学习
开发语言·python·学习
做cv的小昊5 小时前
【TJU】信息检索与分析课程笔记和练习(8)(9)发现系统和全文获取、专利与知识产权基本知识
大数据·笔记·学习·全文检索·信息检索
盐焗西兰花6 小时前
鸿蒙学习实战之路-蓝牙设置完全指南
学习·华为·harmonyos
hkNaruto6 小时前
【AI】AI学习笔记:MCP协议与gRPC、OpenAPI的差异
人工智能·笔记·学习
笨鸟笃行6 小时前
0基础小白使用ai能力将本地跑的小应用上云(作为个人记录)
人工智能·学习
Nan_Shu_6146 小时前
学习: Threejs (1)
javascript·学习