也许我们刚开始用到开发板的时候都会去做跑马灯的程序,后来给我们的要求是,如果硬件接口有限制,只有一个key 或者是button—— 我们的板子上是button,让你用一个button去控制这四个led,那么你应该怎么做呢? —— 之前的跑马灯都是一个key 对应一个led。 或许有其他的解决方案。
这里的解决方案是计数法,按住其中一个button,led 会被循环点亮——每次只有一个是被点亮的。放开button,控制信号就定位在某一个led上。
the first one for the top
module onekey_fourLED ( clock , reset , i_key , o_led ); input clock ,reset ; input i_key ; output [3:0]o_led ; wire temp0,temp1 ; key_edge u0 ( .clock(clock) , .reset (reset ), .i_key (i_key), .counter_en (temp0 ) ); counter0 u1 ( .clock (clock ), .reset (reset), .i_key(i_key), .counter_en(temp0), .counter_full (temp1) ); led_sel u2( .clock(clock), .reset (reset ), .en(temp0), .cnt_full (temp1), .o_led(o_led) ); endmodule
开关边沿检测模块
module key_edge ( clock , reset , i_key , counter_en ); input clock ,reset ; input i_key ; output reg counter_en ; reg r_key0 ,r_key1 ; always @ (posedge clock ) begin if(!reset ) begin r_key0 <= 1'b1 ; r_key1 <= 1'b1 ; end else begin r_key0 <= i_key ; r_key1 <= r_key0 ; if((!r_key0) & (r_key1) ) //开关下降沿到来开始计数使能端打开 counter_en <= 1'b1 ; else if ((r_key0) & (!r_key1)) //开关上升沿到来,证明一次按下动作完毕 counter_en <= 1'b0 ; else ; end end endmodule
对按下的button 时间进行计数
module counter0 ( clock , reset , i_key, counter_en, counter_full ); input clock ,reset ; input i_key ; input counter_en ; output reg counter_full; reg [23:0] cnt ; always @ (posedge clock ) begin if(!reset ) begin cnt <= 24'd0 ; end else begin if((!i_key) & (counter_en)) cnt <= cnt + 24'd1; else cnt <= 24'd0 ; end end always @ (posedge clock ) begin if(!reset ) counter_full <= 1'd0 ; else begin if(cnt == 24'hff_ffff) counter_full <= 1'b1 ; else counter_full <= 1'b0 ; end end endmodule
依据按键按下的时间选择led
module led_sel ( clock, reset , en, cnt_full , o_led ); input clock ,reset ; input en ,cnt_full; output reg [3:0] o_led ; reg [1:0] o_led_cnt; always @ (posedge clock ) begin if(!reset ) o_led_cnt <= 2'd0 ; else if((en) & (cnt_full)) begin if (o_led_cnt <= 2'd3)o_led_cnt <= o_led_cnt + 2'd1 ; else o_led_cnt <= 2'd0 ; end end //reg [3:0] o_led_reg; always @ (posedge clock ) begin if(!reset ) o_led <= 4'b1111 ; else case (o_led_cnt) 2'b00 : o_led <= 4'b1110; 2'b01 : o_led <= 4'b1101; 2'b10 : o_led <= 4'b1011; 2'b11 : o_led <= 4'b0111; default : o_led <= 4'b1111 ; endcase end // assign o_led = o_led_reg; endmodule