onekey_fourLED

  也许我们刚开始用到开发板的时候都会去做跑马灯的程序,后来给我们的要求是,如果硬件接口有限制,只有一个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 
原文地址:https://www.cnblogs.com/sepeng/p/3735763.html