FPGA|CPLD|ASIC论坛
直播中

chunfen2634

9年用户 184经验值
擅长:可编程逻辑
私信 关注
[资料]

明德扬至简设计法--分享一份实现矩阵键盘的verilog代码 可直接使用

  1. `define  SCAN

  2. module  key_scan(
  3.                  clk    ,
  4.                  rst_n  ,
  5.                  key_col, //键盘列输入
  6.                  key_row, //键盘行输出
  7.                  key_num, //指示哪一个按键按下,用0~15指示
  8.                  key_vld  //按下有效指示信号,其为1表示按下一次。
  9.                );


  10.     parameter      KEY_W    =   4 ;
  11.     parameter      COL      =   0 ;
  12.     parameter      ROW      =   1 ;
  13.     parameter      DLY      =   2 ;
  14.     parameter      FIN      =   3 ;
  15.     parameter      COL_CNT  =   16;
  16.     parameter      tiME_20MS=   1000000;

  17.     //输入信号定义
  18.     input               clk    ;
  19.     input               rst_n  ;
  20.     input  [3:0]        key_col;

  21.     //输出信号定义
  22.     output              key_vld;
  23.     output[3:0]         key_num;
  24.     output[KEY_W-1:0]   key_row;

  25.     //输出信号reg定义
  26.     reg   [3:0]         key_num;
  27.     reg   [KEY_W-1:0]   key_row;
  28.     reg                 key_vld;


  29.     reg   [ 3:0]        key_col_ff0   ;
  30.     reg   [ 3:0]        key_col_ff1   ;
  31.     reg   [ 1:0]        key_col_get   ;
  32.     reg                 shake_flag    ;
  33.     reg                 shake_flag_ff0;
  34.     reg   [ 3:0]        state_c       ;
  35.     reg   [19:0]        shake_cnt     ;
  36.     reg   [ 3:0]        state_n       ;
  37.     reg   [ 1:0]        row_index     ;
  38.     reg   [15:0]        row_cnt       ;
  39.         reg   [ 2:0]        x             ;


  40. always  @(posedge clk or negedge rst_n)begin
  41.     if(rst_n==1'b0)begin
  42.         key_col_ff0 <= 4'b1111;
  43.         key_col_ff1 <= 4'b1111;
  44.     end
  45.     else begin
  46.         key_col_ff0 <= key_col    ;
  47.         key_col_ff1 <= key_col_ff0;
  48.     end
  49. end


  50. always  @(posedge clk or negedge rst_n)begin
  51.     if(rst_n==1'b0)begin
  52.         shake_cnt <= 0;
  53.     end
  54.     else if(add_shake_cnt)begin
  55.         if(end_shake_cnt)
  56.             shake_cnt <= 0;
  57.         else
  58.             shake_cnt <= shake_cnt + 1;
  59.     end
  60.     else begin
  61.         shake_cnt <= 0;
  62.     end
  63. end

  64. assign  add_shake_cnt = key_col_ff1!=4'hf && shake_flag==0;
  65. assign  end_shake_cnt = add_shake_cnt && shake_cnt==TIME_20MS-1;

  66. always  @(posedge clk or negedge rst_n)begin
  67.     if(rst_n==1'b0)begin
  68.         shake_flag <= 0;
  69.     end
  70.     else if(end_shake_cnt) begin
  71.         shake_flag <= 1'b1;
  72.     end
  73.     else if(key_col_ff1==4'hf) begin
  74.         shake_flag <= 1'b0;
  75.     end
  76. end


  77. `ifdef SCAN
  78. always  @(posedge clk or negedge rst_n)begin
  79.     if(rst_n==1'b0)begin
  80.         state_c <= COL;
  81.     end
  82.     else begin
  83.         state_c <= state_n;
  84.     end
  85. end



  86. always  @(*)begin
  87.     case(state_c)
  88.         COL: begin
  89.                      if(col2row_start)begin
  90.                          state_n = ROW;
  91.                      end
  92.                      else begin
  93.                          state_n = state_c;
  94.                      end
  95.                  end
  96.         ROW: begin
  97.                      if(row2dly_start)begin
  98.                          state_n = DLY;
  99.                      end
  100.                      else begin
  101.                          state_n = state_c;
  102.                      end
  103.                  end
  104.         DLY :  begin
  105.                      if(dly2fin_start)begin
  106.                          state_n = FIN;
  107.                      end
  108.                      else begin
  109.                          state_n = state_c;
  110.                      end
  111.                  end
  112.         FIN: begin
  113.                      if(fin2col_start)begin
  114.                          state_n = COL;
  115.                      end
  116.                      else begin
  117.                          state_n = state_c;
  118.                      end
  119.                   end
  120.        default: state_n = COL;
  121.     endcase
  122. end

  123. assign  col2row_start = state_c==COL && end_shake_cnt;
  124. assign  row2dly_start = state_c==ROW && end_row_index;
  125. assign  dly2fin_start = state_c==DLY && end_row_index;
  126. assign  fin2col_start = state_c==FIN && key_col_ff1==4'hf;





  127. always  @(posedge clk or negedge rst_n)begin
  128.     if(rst_n==1'b0)begin
  129.         key_row <= 4'b0;
  130.     end
  131.     else if(state_c==ROW)begin
  132.         key_row <= ~(1'b1 << row_index);
  133.     end
  134.     else begin
  135.         key_row <= 4'b0;
  136.     end
  137. end


  138. always  @(posedge clk or negedge rst_n)begin
  139.     if(rst_n==1'b0)begin
  140.         row_cnt <= 0;
  141.     end
  142.     else if(add_row_cnt) begin
  143.         if(end_row_cnt)
  144.             row_cnt <= 0;
  145.         else
  146.             row_cnt <= row_cnt + 1;
  147.     end
  148. end
  149. assign add_row_cnt = state_c==ROW || state_c==DLY;
  150. assign end_row_cnt = add_row_cnt && row_cnt==COL_CNT-1;


  151. always  @(posedge clk or negedge rst_n)begin
  152.     if(rst_n==1'b0)begin
  153.         row_index <= 0;
  154.     end
  155.     else if(add_row_index) begin
  156.         if(end_row_index)
  157.             row_index <= 0;
  158.         else
  159.             row_index <= row_index + 1;
  160.     end
  161. end
  162. assign add_row_index = end_row_cnt;
  163. assign end_row_index = add_row_index && row_index==x-1;
  164. always  @(*)begin
  165.     if(state_c==ROW)
  166.         x = 4;
  167.     else
  168.         x = 1;
  169. end


  170. always  @(posedge clk or negedge rst_n)begin
  171.     if(rst_n==1'b0)begin
  172.         key_col_get <= 0;
  173.     end
  174.     else if(col2row_start) begin
  175.         if(key_col_ff1==4'b1110)
  176.             key_col_get <= 0;
  177.         else if(key_col_ff1==4'b1101)
  178.             key_col_get <= 1;
  179.         else if(key_col_ff1==4'b1011)
  180.             key_col_get <= 2;
  181.         else
  182.             key_col_get <= 3;
  183.     end
  184. end


  185. always  @(posedge clk or negedge rst_n)begin
  186.     if(rst_n==1'b0)begin
  187.         key_num <= 0;
  188.     end
  189.     else if(state_c==ROW && end_row_cnt)begin
  190.         key_num <= {row_index,key_col_get};
  191.     end
  192.     else begin
  193.         key_num <= 0;
  194.     end
  195. end

  196. always  @(posedge clk or negedge rst_n)begin
  197.     if(rst_n==1'b0)begin
  198.         key_vld <= 1'b0;
  199.     end
  200.     else if(state_c==ROW && end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin
  201.         key_vld <= 1'b1;
  202.     end
  203.     else begin
  204.         key_vld <= 1'b0;
  205.     end
  206. end

  207. `else
  208.     always  @(posedge clk or negedge rst_n)begin
  209.         if(rst_n==1'b0)begin
  210.             key_vld <= 0;
  211.         end
  212.         else begin
  213.             key_vld <= end_shake_cnt;
  214.         end
  215.     end

  216.     always  @(*)begin
  217.         key_num = 0;
  218.     end



  219. `endif

  220. endmodule


回帖(2)

goodbey155

2017-3-1 09:56:47
谢谢分享,大好人!
举报

chunfen2634

2017-3-23 10:01:16
多谢通过!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分