EDN首页   博客首页

日志档案

发表于 2007/7/26 14:55:01

4

标签: verilog  

键盘扫描verilog代码

今天,第一次在CPLD板上实现了第一个数字电路4×4键盘扫描的verilog 代码,欢迎大家讨论。

// *********************************************************************
// 键盘扫描VerilogHDL代码
//2007.7.26 by Levension @SCUT
// *********************************************************************

module keypad(keyval,y,x,clk);
   
    output [4:0] keyval; //返回的键值
    output [3:0] x;     //输出,列坐标
    input  [3:0] y;     //输入,行坐标
    input  clk;         //时钟源
   
    reg [4:0] keyval;
    reg [3:0] x;
   
    parameter clkdiv="2048"; 
    parameter S0=4'd0,      //状态机
              S1=4'd1,
              S2=4'd2,
              Wait="4"'d3,
              R0=4'd8,
              R0Temp=4'd9,
              R1=4'd10,
              R1Temp=4'd11,
              R2=4'd12,
              R2Temp=4'd13,
              R3=4'd14,
              R3Temp=4'd15;
             
    reg [3:0] state;
   
    reg [11:0] cnt;                        //2.048MHz,分频因子,分为1000Hz
    always @(posedge clk)
      cnt <= cnt==clkdiv ? 0 : cnt+1;
   
    reg clken;
    always @(posedge clk)
      clken <= cnt==clkdiv;
   
     always @(posedge clk)                 //键盘扫描部分
     if(clken)
       begin
       case(state)
           S0:              //判断是否按键按下
             begin
             x<=4'b0000;
             state="S1";
             end
            S1:
             begin
             if(y==4'b1111)  //无按键,返回
             state="S0";
             else
             x<=4'b0000;
             repeat(204800) @(posedge clk);  //延时100ms,消抖    
             state="S2";            
             end
            S2:
             begin
             if(y==4'b1111)
             state="S0";
             else
             state="R0Temp";                    
             end
            R0Temp:                              //扫描第一列
             begin
             x<=4'b1110;
             state="R0";
             end
            R0:
              case(y)
                  4'b1111:
                     state="R1Temp";
                  4'b0111:
                     begin
                     keyval<=5'd1;
                     state="Wait";
                     end
                  4'b1011:
                     begin
                     keyval<=5'd5;
                     state="Wait";
                     end
                  4'b1101:
                     begin
                     keyval<=5'd9;
                     state="Wait";
                     end
                  4'b1110:
                     begin
                     keyval<=5'd13;
                     state="Wait";
                     end
                   default:
                      state="Wait";  
                   endcase
               R1Temp:                              //扫描第二列
                begin
                x<=4'b1101;
                state="R1";
                end
               R1:
                 case(y)
                  4'b1111:
                     state="R2Temp";
                  4'b0111:
                     begin
                     keyval<=5'd2;
                     state="Wait";
                     end
                  4'b1011:
                     begin
                     keyval<=5'd6;
                     state="Wait";
                     end
                  4'b1101:
                     begin
                     keyval<=5'd10;
                     state="Wait";
                     end
                  4'b1110:
                     begin
                     keyval<=5'd14;
                     state="Wait";
                     end
                   default:
                      state="Wait";  
                    endcase
              R2Temp:                                   //扫描第三列
               begin
               x<=4'b1011;
               state="R2";
               end
               R2:
               case(y)
                  4'b1111:
                     state="R3Temp";
                  4'b0111:
                     begin
                     keyval<=5'd3;
                     state="Wait";
                     end
                  4'b1011:
                     begin
                     keyval<=5'd7;
                     state="Wait";
                     end
                  4'b1101:
                     begin
                     keyval<=5'd11;
                     state="Wait";
                     end
                  4'b1110:
                     begin
                     keyval<=5'd15;
                     state="Wait";
                     end
                   default:
                     state="Wait";  
                   endcase
             R3Temp:                                //扫描第四列
               begin
               x<=4'b0111;
               state="R3";
               end
             R3:
               case(y)
                  4'b1111:
                     state="Wait";
                  4'b0111:
                     begin
                     keyval<=5'd4;
                     state="Wait";
                     end
                  4'b1011:
                     begin
                     keyval<=5'd8;
                     state="Wait";
                     end
                  4'b1101:
                     begin
                     keyval<=5'd12;
                     state="Wait";
                     end
                  4'b1110:
                     begin
                     keyval<=5'd16;
                     state="Wait";
                     end
                   default:
                      state="Wait";
                   endcase
                Wait:                                      //返回S0状态
                   state="S0"; 
                endcase
           end
       
endmodule

系统分类: CPLD/FPGA   |   用户分类: FPGA   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(2351)    回复(5)  

投一票您将和博主都有获奖机会!

最新评论

  • raisin

    2007/8/17 14:51:46

    我怎么运行的时候有问题呢?/

     

    有一列总是扫描不到

  • levension

    2007/8/17 21:24:29

    我用的是ateara的EPM7218,时钟是2.048MHz的,试验过没问题的。你检查一下硬件和引脚设置吧。

  • zealotzy

    2008/2/20 9:56:05

    谢谢共享!正在找这么一段呢,虽然我自己还要改成4*5的。

  • zealotzy

    2008/2/20 12:00:12

    研究了一下,发觉两个问题。先说明我用得是XILINX ISE webpack8.1i.

    1:repeat(204800) @(posedge clk);  //延时100ms,消抖

    这条命令无法通过综合。即使作者用得软件可以综合,但是为了通用性,delay建议改成计数的方式。

     

    2:state="S1";例如这样的命令是不是应该把引号去掉呢?否则赋给state的是“S1”还是4'd1?

  • levension

    2008/2/21 14:34:39

    谢谢你的建议,这是我初学的作品,各方面比较不成熟,希望多指教。

    1、考虑到移植性,同意delay,更好。

    2、这里的“S1”是从文件中张贴时不小心带上的,谢谢你细心的发现呀。