FPGA自学教程 06 从计数器到可控线性序列机(LED实验进化六部曲)上半部分

本文展示了使用FPGA实现LED灯不同闪烁模式的过程,从简单的0.25秒亮0.75秒灭,到0.25秒亮0.5秒灭0.75秒亮1秒灭,最后实现根据用户输入的8位模式进行随机变化的LED闪烁。代码基于Verilog语言,通过计数器和时钟信号控制LED的状态,并通过仿真验证了设计的正确性。
摘要由CSDN通过智能技术生成

双非硕士 研一下学期视觉转FPGA(在b站跟小梅哥视频)

长路漫漫,但希望前途光明

1.让LED灯亮0.25秒,灭0.75秒的状态

代码如下所示:

module counter_led_1(
    Clk,
    Reset_n,
    Led
);
    input Clk;
    input Reset_n;
    output reg Led;
    reg [25:0]counter1;
    parameter MCNT=50000000;
    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter1 <= 0;
     else if(counter1 == MCNT-1)
        counter1 <= 0;
     else 
        counter1 <= counter1 + 1'b1;
     always@(posedge Clk or negedge Reset_n)
     if(!Reset_n)
        Led <= 0;
     else if(counter1 == (MCNT/2)+(MCNT/4)-1) //将1秒四等分的意思
        Led <= 1;
     else if(counter1 == MCNT-1)
        Led <= 0;               
endmodule

代码思路:

 将一秒分为四等分,等到0.75秒的时候先亮0.25秒,然后再依次循环即可。

模拟仿真代码如下:

`timescale 1ns/1ns

module counter_led_0_tb();
    reg Clk_0;
    reg Reset_n_0;
    wire Led_0;
    counter_led_1 counter_led_0_inst0(
        .Clk(Clk_0),
        .Reset_n(Reset_n_0),
        .Led(Led_0)
    );
    initial Clk_0=1;
    always #10 Clk_0 =!Clk_0;
    defparam counter_led_1.MCNT=50000;
    initial begin
        Reset_n_0 <= 0;
        #201;
        Reset_n_0 <=1;
        #400000000;
        $stop;
    end

endmodule

波形图如下所示:

 2.让LED灯亮0.25秒,灭0.5秒,亮0.75秒,灭1秒

代码内容如下

module counter_led_2(
    Clk,
    Reset_n,
    Led
);
    input Clk;
    input Reset_n;
    output reg Led;
    reg [26:0]counter1;
    parameter MCNT=125000000;
    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter1 <= 0;
     else if(counter1 == MCNT-1)
        counter1 <= 0;
     else 
        counter1 <= counter1 + 1'b1;
     always@(posedge Clk or negedge Reset_n)
     if(!Reset_n)
        Led <= 1;
     else if(counter1 == (MCNT/10)-1)
        Led <= 0;
     else if(counter1 == (MCNT/10 + MCNT/5)-1)
        Led <= 1;
     else if(counter1 == (MCNT/10 + MCNT/5)*2 -1)
        Led <=0;
     else if(counter1 == MCNT-1)
        Led <=1;               
endmodule

仿真验证代码如下:

`timescale 1ns/1ns

module counter_led_0_tb();
    reg Clk_0;
    reg Reset_n_0;
    wire Led_0;
    counter_led_2 counter_led_0_inst0(
        .Clk(Clk_0),
        .Reset_n(Reset_n_0),
        .Led(Led_0)
    );
    initial Clk_0=1;
    always #10 Clk_0 =!Clk_0;
    defparam counter_led_2.MCNT=125000;
    initial begin
        Reset_n_0 <= 0;
        #201;
        Reset_n_0 <=1;
        #400000000;
        $stop;
    end

endmodule

仿真结果如下: 

3.让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。以0.25秒为一个变化周期,8个变化状态为一个循环。

代码内容如下:

module counter_led_3(   
    Clk,
    Reset_n,
    Ctrl_n,
    Led
);
    input Clk;
    input Reset_n;
    input [7:0]Ctrl_n;
    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_n[0];
     else if(counter ==MCNT*2/8-1)
        Led <=Ctrl_n[1];
     else if(counter ==MCNT*3/8-1)
        Led <=Ctrl_n[2];
     else if(counter ==MCNT*4/8-1)
        Led <=Ctrl_n[3];   
     else if(counter ==MCNT*5/8-1)
        Led <=Ctrl_n[4];
     else if(counter ==MCNT*6/8-1)
        Led <=Ctrl_n[5];
     else if(counter ==MCNT*7/8-1)
        Led <=Ctrl_n[6];
     else if(counter ==MCNT*8/8-1)
        Led <=Ctrl_n[7];  
     else
        Led <=Led;                 
endmodule

仿真代码如下:

`timescale 1ns/1ns

module counter_led_3_tb();
    reg Clk_0;
    reg Reset_n_0;
    reg [7:0]Ctrl_n;
    wire Led_0;
    counter_led_3 counter_led_0_inst0(
        .Clk(Clk_0),
        .Reset_n(Reset_n_0),
        .Ctrl_n(Ctrl_n),
        .Led(Led_0)
    );
    initial Clk_0=1;
    always #10 Clk_0 =!Clk_0;
    defparam counter_led_3.MCNT=100000;
    initial begin
        Reset_n_0 <= 0;
        Ctrl_n =0;
        #201;
        Reset_n_0 <=1;
        #2000;
        Ctrl_n=8'b1000_0110;
        #200000000;
        $stop;
    end

endmodule

仿真波形图如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值