實驗現象:按鍵控制流水燈啟停與移動方向,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
新聞熱點
疑難解答