实验现象:按键控制流水灯启停与移动方向,sw1_n控制流水灯启停,
sw2_n控制流水灯左移,sw3_n控制流水灯右移,间隔1s
module Key_to_LED_verilog(clk,rst_n,sw1_n,sw2_n,sw3_n,led);input clk; //50MHZ时钟input rst_n; //复位input sw1_n,sw2_n,sw3_n; //按键,sw1_n启停,sw2_n左移,sw3_n右移output[7:0] led; //LED 0-亮,1-灭reg led_dir; //1--left, 0--rightreg led_on; //1--on, 0--off////////////////////////////////LED移位控制程序reg [25:0]cnt; //计数寄存器always @(posedge clk or negedge rst_n)beginif(!rst_n) cnt <= 26'd0;else if(cnt == 26'd50000000) cnt <= 26'd0; //如果计数值达到50M(1s),计数归零else cnt <= cnt + 1'b1; //计数值不到50M,自动加1endreg [7:0]led_r;//8位LED状态寄存器always @(posedge clk or negedge rst_n)beginif(!rst_n) led_r <= 8'b11111110; //复位初值else if(cnt == 26'd50000000 && led_on) //如果计数值达到50M(1s)且led_on=1,允许移位beginif(led_dir)led_r <= {led_r[0],led[7:1]}; //LED状态寄存器移位else led_r <= {led_r[6:0],led[7]}; //LED状态寄存器移位endendassign led = led_r;/////////////////////////////////3位按键程序reg[19:0] cntkey; //计数寄存器always @ (posedge clk or negedge rst_n) if (!rst_n) cntkey <= 20'd0; //异步复位 else cntkey <= cntkey + 1'b1; reg [2:0]low_sw;always @(posedge clk or negedge rst_n) if (!rst_n) low_sw <= 3'b111; else if (cntkey == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中cnt == 20'hfffff low_sw <= {sw3_n,sw2_n,sw1_n};reg [2:0]low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中always @ ( posedge clk or negedge rst_n ) if (!rst_n) low_sw_r <= 3'b111; else low_sw_r <= low_sw; wire [2:0]led_ctrl = low_sw_r[2:0] & (~low_sw[2:0]);//////////////////////////////////////
//判断键值与功能always @(posedge clk or negedge rst_n)if (!rst_n)begin led_on = 1'b0;led_dir = 1'b0;endelse beginif(led_ctrl[0]) led_on <= ~led_on; if(led_ctrl[1]) led_dir <= 1'b1;if(led_ctrl[2]) led_dir <= 1'b0;endendmodule
新闻热点
疑难解答