您的位置:首页 > 编程语言

Verilog/CPLD代码之按键控制流水灯

2017-03-07 00:09 1691 查看
实验现象:按键控制流水灯启停与移动方向,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--right

reg led_on;  //1--on, 0--off

//////////////////////////////

//LED移位控制程序

reg [25:0]cnt; //计数寄存器

always @(posedge clk or negedge rst_n)

begin
if(!rst_n) cnt <= 26'd0;
else if(cnt == 26'd50000000) cnt <= 26'd0; //如果计数值达到50M(1s),计数归零
else cnt <= cnt + 1'b1;                    //计数值不到50M,自动加1

end

reg [7:0]led_r;//8位LED状态寄存器

always @(posedge clk or negedge rst_n)

begin
if(!rst_n) led_r <= 8'b11111110; //复位初值
else if(cnt == 26'd50000000 && led_on) //如果计数值达到50M(1s)且led_on=1,允许移位
begin
if(led_dir)led_r <= {led_r[0],led[7:1]}; //LED状态寄存器移位
else led_r <= {led_r[6:0],led[7]}; //LED状态寄存器移位
end

end

assign 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;
end
else 
begin
if(led_ctrl[0]) led_on <= ~led_on; 
if(led_ctrl[1]) led_dir <= 1'b1;
if(led_ctrl[2]) led_dir <= 1'b0;
end

endmodule
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息