Verilog实现双向流水灯
实现一个双向流水灯,从右往左流动,到最左边时,再从左边往右流动,然后再从右边开始流动,如此不断反复。灯亮、间隔时间都为0.2s,本实验共有四个LED灯,从左到右依次为LED[3]、LED[2]、LED[1]、LED[0],FPGA输出低电平点亮。
实现思路:
1. 定义一个0.2s的计数器
2. LED[3]、LED[0]作为边界标志位,在被点亮时 ,切换流向,即LED[3]、LED[0]为低电平时,要进行方向转换,所以要定义一个1bit reg变量存储标志
实验代码:
1 //灯亮、间隔时间都为0.2s的双向流水灯 2 module flow_led( 3 input clk, 4 input rst_n, 5 output reg [3:0]led 6 ); 7 8 parameter SYS_FRQ = 50; //时钟输入频率,50MHz 9 parameter LED_FLOW_TIME = 18'd200_000; //LED流水灯亮间隔时间,单位us,这里是0.2s 10 parameter LED_FLOW_CNT_TIME = LED_FLOW_TIME * SYS_FRQ; //LED流水灯,每个灯亮的时钟周期数 11 12 reg [23:0] flow_cnt; //0.2s计数器 13 reg flow_flag; //流向标志,0----从右往左,1----从左往右 14 15 16 //流水灯每个灯亮时间计数器 17 always @(posedge clk or negedge rst_n) 18 if(!rst_n) 19 flow_cnt <= 24'b0; 20 else if(flow_cnt == LED_FLOW_CNT_TIME - 1'b1) 21 flow_cnt <= 24'b0; 22 else 23 flow_cnt <= flow_cnt + 1'b1; 24 25 26 //流水方向边界,分别为四个LED灯的两边,即LED[0]、LED[3],在这两个地方需要转换标志,以改变其流向 27 always @(posedge clk or negedge rst_n) 28 if(!rst_n) 29 flow_flag <= 1'b0; 30 else if(led[0] == 1'b0) 31 flow_flag <= 1'b0; 32 else if(led[3] == 1'b0) 33 flow_flag <= 1'b1; 34 else 35 flow_flag <= flow_flag; 36 37 38 //流水效果实现 39 always @(posedge clk or negedge rst_n) 40 if(!rst_n) 41 led <= 4'b1110; //FPGA输出低电平时,点亮LED 42 else if(flow_flag == 1'b0) //从右往左 43 begin 44 if(flow_cnt == LED_FLOW_CNT_TIME - 1'b1) 45 led <= {led[2:0], led[3]}; 46 else 47 led <= led; 48 end 49 else if(flow_flag == 1'b1) //从左往右 50 begin 51 if(flow_cnt == LED_FLOW_CNT_TIME - 1'b1) 52 led <= {led[0], led[3:1]}; 53 else 54 led <= led; 55 end 56 else 57 led <= led; 58 59 60 endmodule