zoukankan      html  css  js  c++  java
  • 永远的流水灯(Verilog)

    1. 为了更好地学习FPGA和深入理解Verilog语法,首先从最简单的流水灯做起。虽然简单,但是也包含了不少知识。通过这次实验项目,可以了解开发软件的使用及Verilog的编程方法,熟悉模块化设计的方法。

    2. 该项目主要实现的功能为:

    (1)10位的流水灯

    (2)中间两个led灯每隔100ms闪烁一次

    (3)两边的led灯每隔100ms流动一下,从中间向两边流水。

    3.  具体实现如下

       (1)首先定义一个时间计数寄存器counter,每当达到预定的100ms时,计数寄存器就清零,否则的话寄存器就加1。然后计算计数器计数的最大值。时钟频率为50MHZ,也就是周期为1/50M 为20ns,要计数的最大值为T100MS= 100ms/20ns-1 = 4999_999。

    代码实现为

    always @ (posedge clk or negedge rst)

    if(!rst)      //高电平复位

    counter<=25'd0;

    else if(counter==T100ms)

    counter<=25'd0;

    else

    counter<=counter+1'b1;

       (2)如何控制led的亮灭呢,无非就是给端口赋高低电平,有的是高电平亮,有的是低电平亮,我用的FPGA学习板为高电平亮。每隔100ms对其端口值取反就可以实现闪烁的led

       (3)流水灯的实现。在FPGA中实现流水灯的方法有很多种,我只列取了三种供参考学习。首先是运用FPGA的并行处理特点,建立四个always模块分别对每隔led分别控制,也可以建立四个模块分别对各个灯控制。所对应的时序图如图1-a,每一个模块控制相应的led灯,彼此之间互不影响,依靠总的时钟进行工作。

    图1-a

    这种方法能够充分体现FPGA并行处理的特点,实现起来也很容易。

    顶层代码为

    moduletop_module(CLK, RSTn, LED_Out);

           input CLK;

           input RSTn;

           output [3:0]LED_Out;

           wire LED1_Out;

           led1_module U1

           (

                  .CLK(CLK),

                  .RSTn(RSTn),

                  .LED_Out(LED1_Out)

           );

           wire LED2_Out;

           led2_module U2

           (

                  .CLK(CLK),

                  .RSTn(RSTn),

                  .LED_Out(LED2_Out)

           );

           wire LED3_Out;

           led3_module U3

           (

                  .CLK(CLK),

                  .RSTn(RSTn),

                  .LED_Out(LED3_Out)

           );

           wire LED4_Out;

           led4_module U4

           (

                  .CLK(CLK),

                  .RSTn(RSTn),

                  .LED_Out(LED4_Out)

           );

           assign LED_Out = {LED4_Out, LED3_Out,LED2_Out, LED1_Out};

    第二种方法为循环移位法。通过给led赋初值,然后循环左移或者循环右移,但是需要设置一个条件。否则就会出现溢出的情况。如图2-a设置一个条件当要出现溢出的时候让它回到初始的状态,这样就可以实现流水了。

     

    图2-a

    代码实现为

    always @(posedge clk or negedge rst)

    if(!rst)

    led<=4'b0001;        //初值,最低位led[0]灯亮

    else if(counter==T100ms)

    begin

    if(led==4'b0000)      //当溢出最高位时

    led<=4'b0001;    //回到复位时的状态

    else

    led<=led<<1;     //循环左移一位

    end

    第三种数据拼接法,所谓的数据拼接就把原来的数据拆成一位一位的,在特定位置上拼接上一个数。例如在4位的led的低位拼接一个1. Led[3:0]<={led[2:0],1’b1};接即实现了数据的拼接,当然可以实现任意位,任意bit数的拼。和循环移位类似,数据拼接的实现只是把移位命令改成拼接的命令即可。

     

     

  • 相关阅读:
    [MySQL系列] SELECT STRAIGHT_JOIN优化join查询技巧
    [MySQL系列] 使用STRAIGHT_JOIN 优化inner join查询排序索引问题
    [Golang系列] GOFLY在线客服-代码块和作用域-GO语言实现开源独立部署客服系统
    [Laravel系列] 解决laravel中paginate()与distinct() count语句错误问题
    [Laravel系列] 框架中增加记录access log的日志中间件
    [Laravel系列] 解决Laravel中NotFoundHttpException异常
    [Golang系列] GOFLY在线客服-使用golang中的全局变量-GO语言实现开源独立部署客服系统
    [前端]GOFLY在线客服-使用vh、vw使div元素充满屏幕-GO语言实现开源独立部署客服系统
    [前端] GOFLY在线客服-使用css overflow-y属性实现超出高度出滚动条-GO语言实现开源独立部署客服系统
    GOFLY在线客服-使用reconnect-websocket.js实现断线自动重连机制-GO语言实现开源独立部署客服系统
  • 原文地址:https://www.cnblogs.com/glorfei/p/5924900.html
Copyright © 2011-2022 走看看