FPGA_流水灯

FPGA_流水灯


文章目录

  • FPGA_流水灯
  • 前言
    • 时序逻辑
    • 计数器工作原理
    • 闪光灯_设计文件
    • 闪光灯_激励文件
    • 闪光灯_仿真图
    • 闪光灯_上板
    • 流水灯_设计文件
    • 流水灯_激励文件
    • 流水灯_仿真图
    • 流水灯_上板


前言

本文来自《小梅哥FPGA视频》的笔记整理

不要眼高手低,一定一定要实践,自己动手去敲一遍!!!


时序逻辑

时序逻辑电路是指电路任何时刻的稳态输出不仅取决于当前的输入,还与前一时刻输入
形成的状态有关。这跟组合逻辑电路相反,组合逻辑的输出只会跟目前的输入成一种函数关
系。换句话说,时序逻辑拥有储存元件来存储信息,而组合逻辑则没有。

计数器工作原理

计数器的核心元件是触发器,基本功能是对脉冲进行计数,其所能记忆脉冲最大的数目
称为该计数器的模/值。 计数器常用在分频、定时等处。计数器的种类很多,按照计数方式的
不同可以分为二进制计数器、十进制计数器以及任意进制计数器,按照触发器的时钟脉冲信
号来源可分为同步计数器与异步计数器。按照计数增减可分为加法计数器、减法计数器以及
可逆计数器。

闪光灯_设计文件

现象:500毫秒间隔闪烁(低电平点亮)。我使用的板子是ACX720,晶振为50MHZ,20ns为一周期。

module led_flash(
    clk,
    reset_n,
    led
);
    
    input clk;
    input reset_n;
    
    output led;
    reg led;
    
    wire end_flag;
    
    //计数器
    parameter ms500_CNT=25000000;//500 000 000 / 20 = 25000000
    reg [24:0]counter;
    //时钟上升沿有效,复位检测下降沿
    always@(posedge clk or negedge reset_n)begin
        if(!reset_n)
            //时序逻辑赋值  <=是非阻塞赋值的意思
            counter<=0;
        else if(end_flag)
            counter<=0;
        else
            counter<=counter+1'b1;
    end
    assign end_flag= (counter==ms500_CNT-1);
    
    always@(posedge clk or negedge reset_n)begin
        if(!reset_n)
            led<=1;//上电 亮
        else if(end_flag)
            led<=~led;
    end
    
endmodule

闪光灯_激励文件

上板的话500ms完全是可以的,不过如果仿真依旧是500ms,属实没有必要,仿真时我们只需要在激励文件中将设计文件中的参数改为250,也就是5us,led输出反转一次

`timescale 1ns/1ns

module led_flash_tb;

    reg clk;
    reg reset_n;
    
    wire led;

    led_flash 
    #(
        //改变模块里面的参数
        .ms500_CNT(250)
    )
    led_flash(
        .led(led),
        .clk(clk),
        .reset_n(reset_n)
    ); 
    
    initial clk =1;
    always #10 clk = !clk;
    
    initial begin
        reset_n =0;
        #201;
        reset_n=1;
        #50000;
        $stop;
    end
    

endmodule

闪光灯_仿真图

FPGA_流水灯_第1张图片

闪光灯_上板

流水灯_设计文件

八个LED灯以一秒的延迟轮流点亮,我使用的板子是ACX720,晶振为50MHZ,20ns为一周期。

module led_run(
	 clk,
    reset_n,
    led
);
    input clk;
    input reset_n;
    
    output 		led;
    reg   [7:0] led;
    
    //计数器 1s
    parameter MCNT=50000000;//1000000000 / 20 = 50000000
    reg [25:0] counter;
    wire end_cnt;
    always@(posedge clk or negedge reset_n)begin
        if(!reset_n)
            counter<=0;
        else if(end_cnt)
            counter<=0;
        else
            counter<=counter+1'b1;
    end
    assign end_cnt=(counter==MCNT-1);
    
    //流水灯 使用拼接符
    wire add_led;
    always@(posedge clk or negedge reset_n)begin
        if(!reset_n)
            led<=8'b0000_0001;//初始 led0亮,其余led灭
        else if(add_led)
            led<={led[6:0],led[7]};//使用拼接,来切换led
        else
            led<=led;
    end
    assign add_led = end_cnt;
    
    
    /**
   	//流水灯 使用移位运算符
    wire add_led;
    alway@(posedge clk or negedge reset_n)begin
        if(!reset_n)
            led<=8'b0000_0001;//初始 led0亮,其余led灭
        else if(add_led)
            led<=led<<1;
        else
            led<=led;
    end
    assign add_led=end_cnt;
    */
    
endmodule

使用3_8译码器来实现流水灯

注意:在使用38译码器模块之前,需要将之前写好的38译码器模块代码复制到流水灯工程内,并且在软件内部添加到流水灯工程中,才可以使用。

3_8译码器的链接------》FPGA_38译码器_安赫’的博客-CSDN博客

module led_run2(
	clk,
    reset_n,
    led
);
    input clk;
    input reset_n;
    
    output [7:0] led;
    
    
    //计数器 1s
    parameter MCNT=50000000;//1000000000 / 20 = 50000000
    reg [25:0] counter;
    wire end_cnt;
    always@(posedge clk or negedge reset_n)begin
        if(!reset_n)
            counter<=0;
        else if(end_cnt)
            counter<=0;
        else
            counter<=counter+1'b1;
    end
    assign end_cnt=(counter==MCNT-1);
    
    
    //流水灯 使用3_8译码器
    reg [2:0] decoder_3_8_r;
    wire add_led;
    always@(posedge clk or negedge reset_n)begin
        if(!reset_n)
            decoder_3_8_r<=3'b000;//初始 led0亮,其余led灭
        else if(add_led)
            decoder_3_8_r<=decoder_3_8_r+1'b1;
        else
            decoder_3_8_r<=decoder_3_8_r;
    end
    assign add_led=end_cnt;
    //使用38译码器
    decoder_3_8 decoder_3_8(
        .a(decoder_3_8_r[2]),
        .b(decoder_3_8_r[1]),
        .c(decoder_3_8_r[0]),
        .out(led)
    );
endmodule

流水灯_激励文件

仿真时使用5ms,切换led灯,所以MCNT=250

`timescale 1ns/1ns
module led_run_tb;
    reg clk;
    reg reset_n;
    
    wire [7:0] led;
    
    //使用隐身例化
    led_run
    #(
        .MCNT(250)
    )led_run8(
        clk,
        reset_n,
        led
    );
    
    initial clk=1;
    always #10 clk=~clk;
    
    initial begin
        reset_n=0;
        #21;
        reset_n=1;
        #50000;
        $stop;
    end
endmodule

3_8译码器流水灯的激励文件

`timescale 1ns/1ns
module led_run2_tb;
    reg clk;
    reg reset_n;
    
    wire [7:0] led;
    
    //使用隐身例化
    led_run2
    #(
        .MCNT(250)
    )led_run8(
        clk,
        reset_n,
        led
    );
    
    initial clk=1;
    always #10 clk=~clk;
    
    initial begin
        reset_n=0;
        #21;
        reset_n=1;
        #50000;
        $stop;
    end
endmodule

流水灯_仿真图

FPGA_流水灯_第2张图片

3_8译码器流水灯的仿真图

FPGA_流水灯_第3张图片

流水灯_上板

你可能感兴趣的:(FPGA,fpga开发)