FPGA学习笔记(二)——从计数器到可控线性序列机、阻塞赋值与非阻塞赋值

本文档介绍了一种使用Verilog设计的LED控制器,该控制器能够根据用户指定的亮灭模式和时间值进行循环控制。设计包括四个阶段:1.1实现了0.25s亮,0.75s灭的LED循环;1.2允许用户自定义8状态循环模式;1.3允许用户设定每个状态的持续时间;1.4实现了10ms周期的8状态循环,并处理了状态切换时的延迟问题。文章还探讨了阻塞与非阻塞赋值的区别,并给出了相关设计实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本学习笔记主要参考小梅哥B站教学视频,网址如下:
https://www.bilibili.com/video/BV1va411c7Dz?p=1

使用的编译器为Vivado,HDL语言为verilog

一、从计数器到可控线性序列机

1.1 让LED按照亮0.25s,灭0.75s的状态循环亮灭。

思路:设置计数器计数到1s才清零。不用取反操作,而是在相应位置处拉高或者拉低电平。

设计文件:

module counter_led_0(
    Clk,
    Reset_n,
    Led

    );
    
    input Clk;
    input Reset_n;
    output reg Led;
    
    reg [25:0] counter;
    parameter MCNT = 50000000;
    
    always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            counter <= 0;
        else if(counter == MCNT-1)
            counter <=0;
        else
            counter <= counter + 1'b1;
            
    always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            Led <= 0;
        else if(counter == (MCNT/2+MCNT/4)-1) //0.75s处
            Led <= 1;
        else if(counter == MCNT-1)
            Led <= 0;
        
endmodule

测试文件:

`timescale 1ns/1ns

module counter_led_0_tb;

    reg Clk;
    reg Reset_n;
    wire Led;

    counter_led_1
    #(
    .MCNT(125000) //将参数调小一些
    )
    counter_led_1(
    .Clk(Clk),
    .Reset_n(Reset_n), 
    .Led(Led)

    );
    
    
    initial Clk = 1;
    always #10 Clk = !Clk;  //~按位取反,单位信号时与!等价
    
    initial begin
        Reset_n = 0;
        # 201;  //避开时钟上升沿,方便观察
        Reset_n = 1;
        #2000000000; //两秒钟
        $stop;
    end



endmodule

仿真结果:
在这里插入图片描述
1.2 让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。以0.25s为一个变化周期,8个变化状态为一个循环

思路:2秒为一个循环周期,拿出一个ctrl(输入端口)来控制LED的亮灭模式,

设计文件:

module counter_led_2(
    Clk,
    Reset_n,
    Ctrl,
    Led

    );
    
    input Clk;
    input Reset_n;
    input [7:0]Ctrl;
    output reg Led;
    
    reg [26:0] counter;
    parameter MCNT = 100000000;
    
    always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            counter <= 0;
        else if(counter == MCNT-1)
            counter <=0;
        else
            counter <= counter + 1'b1;
            
//    always@(posedge Clk or negedge Reset_n)
//        if(!Reset_n)
//            Led <= 0;
//        else if(counter == MCNT/8-1)
//            Led <= Ctrl[0];
//        else if(counter == MCNT*2/8-1)
//            Led <= Ctrl[1];
//        else if(counter == MCNT*3/8-1)
//            Led <= Ctrl[2];          
//        else if(counter == MCNT*4/8-1)
//            Led <= Ctrl[3]; 
//         else if(counter == MCNT*5/8-1)
//            Led <= Ctrl[4];
//        else if(counter == MCNT*6/8-1)
//            Led <= Ctrl[5];
//        else if(counter == MCNT*7/8-1)
//            Led <= Ctrl[6];          
//        else if(counter == MCNT-1)
//            Led <= Ctrl[7]; 
 
     always@(posedge Clk or negedge Reset_n)
        if(!Reset_n)
            Led <= 0;
        else case(counter)                                            
            MCNT*1/8-1:Led <= Ctrl[0];
            MCNT*2/8-1:Led <= Ctrl[1];
            MCNT*3
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值