集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 4970|回复: 9

各位大侠,我写的4*4矩阵键盘,想实现5ms的延时消抖,出现问题,能帮我看看错误码?

[复制链接]
yyh1910 发表于 2010-11-2 12:02:34 | 显示全部楼层 |阅读模式
module jz_keys(
  input            clk,
  input            rst,
  input      [3:0] row,                 // 矩阵键盘 行
  output reg [3:0] col,                 // 矩阵键盘 列
  output reg [6:0] keyboard_val         // 键盘值      
);
//++++++++++++++++++++++++++++++++++++++
// 状态机部分 开始
//++++++++++++++++++++++++++++++++++++++
// 状态编码
parameter NO_KEY_PRESSED = 6'b000_001;  // 没有按键按下   
parameter SCAN_COL0      = 6'b000_010;  // 扫描第0列  
parameter SCAN_COL1      = 6'b000_100;  // 扫描第1列  
parameter SCAN_COL2      = 6'b001_000;  // 扫描第2列  
parameter SCAN_COL3      = 6'b010_000;  // 扫描第3列  
parameter KEY_PRESSED    = 6'b100_000;  // 有按键按下
parameter delay          = 6'b111_111;  //延时5ms

reg [5:0] current_state, next_state;    // 现态、次态
reg  key_pressed_flag;          // 键盘按下标志
reg [3:0] col_reg, row_reg;             // 列值、行值
reg delay_en;       //延时5ms后使能端为1,否则为0
reg [10:0]c0;
reg clk0;

always @(posedge clk or negedge rst)
   if(!rst)
     current_state=NO_KEY_PRESSED;
   else
     current_state=next_state;  
            
always @*
     case(current_state)
      NO_KEY_PRESSED:
           if(row!=4'b1111)  next_state=SCAN_COL0;
           else begin next_state=NO_KEY_PRESSED;end
      SCAN_COL0:begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                  next_state=KEY_PRESSED;
                else  next_state=SCAN_COL1; end
      SCAN_COL1: begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                 next_state=KEY_PRESSED;
                else  next_state=SCAN_COL2; end
      SCAN_COL2: begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                  next_state=KEY_PRESSED;
                else  next_state=SCAN_COL3; end
      SCAN_COL3: begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                  next_state=KEY_PRESSED;
                else next_state=NO_KEY_PRESSED; end
      KEY_PRESSED:begin
           if((row!=4'b1111)&&(delay_en==1))
             next_state=KEY_PRESSED;
           else next_state=NO_KEY_PRESSED; end
      default: next_state=NO_KEY_PRESSED;
    endcase   

always @ (posedge clk0 or negedge rst)
  if (!rst)
  begin
    col<= 4'h0; key_pressed_flag<=0;
  end
  else
    case(next_state)
      NO_KEY_PRESSED:begin col<=4'b0000;key_pressed_flag<=0;end   
      SCAN_COL0:  col<=4'b1110;
      SCAN_COL1:  col<=4'b1101;
      SCAN_COL2:  col<=4'b1011;
      SCAN_COL3:  col<=4'b0111;
      KEY_PRESSED: begin
                   col_reg<=col;row_reg<=row;
                   key_pressed_flag<=1;
                   end
    endcase  

always@(posedge clk0 or negedge rst) begin
    if(!rst) keyboard_val<=7'b0000000;
    else if(key_pressed_flag)
      case({col_reg,row_reg})
        8'b1110_1110: keyboard_val<=7'b1111110; //显示"0"
                8'b1110_1101: keyboard_val<=7'b0110011; //显示"4"
                8'b1110_1011: keyboard_val<=7'b1111111; //显示"8"
                8'b1110_0111: keyboard_val<=7'b1001111; //显示"C"
                8'b1101_1110: keyboard_val<=7'b0110000; //显示"1"
                8'b1101_1101: keyboard_val<=7'b1011011; //显示"5"
                8'b1101_1011: keyboard_val<=7'b1110011; //显示"9"
                8'b1101_0110: keyboard_val<=7'b0111101; //显示"d"
                8'b1011_1110: keyboard_val<=7'b1101101; //显示"2"
                8'b1011_1101: keyboard_val<=7'b1011111; //显示"6"
                8'b1011_1011: keyboard_val<=7'b1110111; //显示"A"
                8'b1011_0111: keyboard_val<=7'b1001111; //显示"E"
                8'b0111_1110: keyboard_val<=7'b1111001; //显示"3"
                8'b0111_1101: keyboard_val<=7'b1110000; //显示"7"
                8'b0111_1011: keyboard_val<=7'b0011111; //显示"b"
        8'b0111_0111: keyboard_val<=7'b1000111; //显示"F"
        default: keyboard_val<=7'b0000000;
     endcase end     

always @(posedge clk or negedge rst)begin //分频为5KHz
     if(next_state==delay) begin
       if (!rst) c0<=0;
        else if(c0<2000)begin c0<=c0+1;delay_en=0;end
          else begin clk0=~clk0; c0<=0;delay_en=1;end
     end  end  
endmodule






错误:
Warning (10240): Verilog HDL Always Construct warning at jz_keys.v(106): inferring latch(es) for variable "delay_en", which holds its previous value in one or more paths through the always construct
Info (10041): Verilog HDL or VHDL info at jz_keys.v(107): inferred latch for "delay_en"
Warning (10240): Verilog HDL Always Construct warning at jz_keys.v(106): inferring latch(es) for variable "clk0", which holds its previous value in one or more paths through the always construct
Info (10041): Verilog HDL or VHDL info at jz_keys.v(107): inferred latch for "clk0"
Error: Can't elaborate top-level user hierarchy
Error: Quartus II Analysis & Synthesis was unsuccessful. 2 errors, 4 warnings
        Error: Processing ended: Tue Nov 02 12:00:14 2010
        Error: Elapsed time: 00:00:01
sq87542 发表于 2010-11-2 14:30:18 | 显示全部楼层
回复 1# yyh1910


    这个我就不知道了呵呵希望别人可以帮到你
liqz 发表于 2010-11-2 15:17:06 | 显示全部楼层
第一个always是时序电路,应该用<=赋值
liqz 发表于 2010-11-2 15:19:33 | 显示全部楼层
最后一个always也是,delay_en应该用<=赋值
 楼主| yyh1910 发表于 2010-11-2 19:30:54 | 显示全部楼层
Warning (10240): Verilog HDL Always Construct warning at jz_keys.v(106): inferring latch(es) for variable "delay_en", which holds its previous value in one or more paths through the always construct
Info (10041): Verilog HDL or VHDL info at jz_keys.v(107): inferred latch for "delay_en"
Warning (10240): Verilog HDL Always Construct warning at jz_keys.v(106): inferring latch(es) for variable "clk0", which holds its previous value in one or more paths through the always construct
Info (10041): Verilog HDL or VHDL info at jz_keys.v(107): inferred latch for "clk0"
Error: Can't elaborate top-level user hierarchy
Error: Quartus II Analysis & Synthesis was unsuccessful. 2 errors, 4 warnings
        Error: Processing ended: Tue Nov 02 19:29:10 2010
        Error: Elapsed time: 00:00:01
Info: Generated suppressed messages file D:/My Documents/VerilogHDL程序/4X4矩阵键盘/jz_keys.map.smsg
Error: Quartus II Full Compilation was unsuccessful. 2 errors, 4 warnings
 楼主| yyh1910 发表于 2010-11-2 19:32:03 | 显示全部楼层
现在还是有问题,不知道什么原因?
liqz 发表于 2010-11-2 20:54:25 | 显示全部楼层
clk0的赋值也应该用<=
liqz 发表于 2010-11-2 20:56:41 | 显示全部楼层
在时序电路中,赋值要用<=
组合电路中用=
组合电路赋值要完全以避免latch
这是你学verilog第一课就应该知道的东西
其他的比如说用同一个时钟域我都不说了
liqz 发表于 2010-11-2 21:03:33 | 显示全部楼层
我简单做了下修改,几个always没有begin和end,代码风格一塌糊涂。兄弟,还是从基础学起,一开始就养成良好的代码风格,太乱了,我把一些明显的错误改了,其他的自己看吧

module jz_keys(
  input            clk,
  input            rst,
  input      [3:0] row,                 // 矩阵键盘 行
  output reg [3:0] col,                 // 矩阵键盘 列
  output reg [6:0] keyboard_val         // 键盘值      
);
//++++++++++++++++++++++++++++++++++++++
// 状态机部分 开始
//++++++++++++++++++++++++++++++++++++++
// 状态编码
parameter NO_KEY_PRESSED = 6'b000_001;  // 没有按键按下   
parameter SCAN_COL0      = 6'b000_010;  // 扫描第0列  
parameter SCAN_COL1      = 6'b000_100;  // 扫描第1列  
parameter SCAN_COL2      = 6'b001_000;  // 扫描第2列  
parameter SCAN_COL3      = 6'b010_000;  // 扫描第3列  
parameter KEY_PRESSED    = 6'b100_000;  // 有按键按下
parameter delay          = 6'b111_111;  //延时5ms

reg [5:0] current_state, next_state;    // 现态、次态
reg  key_pressed_flag;          // 键盘按下标志
reg [3:0] col_reg, row_reg;             // 列值、行值
reg delay_en;       //延时5ms后使能端为1,否则为0
reg [10:0]c0;
reg clk0;

always @(posedge clk or negedge rst)
   if(!rst)
     current_state<=NO_KEY_PRESSED;
   else
     current_state<=next_state;  
            
always @*
begin
     case(current_state)
      NO_KEY_PRESSED:
           if(row!=4'b1111)  next_state=SCAN_COL0;
           else begin next_state=NO_KEY_PRESSED;end
      SCAN_COL0:begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                  next_state=KEY_PRESSED;
                else  next_state=SCAN_COL1; end
      SCAN_COL1: begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                 next_state=KEY_PRESSED;
                else  next_state=SCAN_COL2; end
      SCAN_COL2: begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                  next_state=KEY_PRESSED;
                else  next_state=SCAN_COL3; end
      SCAN_COL3: begin
           if(row!=4'b1111) next_state=delay;
           else if((row!=4'b1111)&&(delay_en==1))
                  next_state=KEY_PRESSED;
                else next_state=NO_KEY_PRESSED; end
      KEY_PRESSED:begin
           if((row!=4'b1111)&&(delay_en==1))
             next_state=KEY_PRESSED;
           else next_state=NO_KEY_PRESSED; end
      default: next_state=NO_KEY_PRESSED;
    endcase
end  

always @ (posedge clk0 or negedge rst)
begin
  if (!rst)
  begin
    col<= 4'h0; key_pressed_flag<=0;
  end
  else
    case(next_state)
      NO_KEY_PRESSED:begin col<=4'b0000;key_pressed_flag<=0;end   
      SCAN_COL0:  col<=4'b1110;
      SCAN_COL1:  col<=4'b1101;
      SCAN_COL2:  col<=4'b1011;
      SCAN_COL3:  col<=4'b0111;
      KEY_PRESSED: begin
                   col_reg<=col;row_reg<=row;
                   key_pressed_flag<=1;
                   end
    endcase  
end

always@(posedge clk0 or negedge rst) begin
    if(!rst) keyboard_val<=7'b0000000;
    else if(key_pressed_flag)
    begin
      case({col_reg,row_reg})
        8'b1110_1110: keyboard_val<=7'b1111110; //显示"0"
                8'b1110_1101: keyboard_val<=7'b0110011; //显示"4"
                8'b1110_1011: keyboard_val<=7'b1111111; //显示"8"
                8'b1110_0111: keyboard_val<=7'b1001111; //显示"C"
                8'b1101_1110: keyboard_val<=7'b0110000; //显示"1"
                8'b1101_1101: keyboard_val<=7'b1011011; //显示"5"
                8'b1101_1011: keyboard_val<=7'b1110011; //显示"9"
                8'b1101_0110: keyboard_val<=7'b0111101; //显示"d"
                8'b1011_1110: keyboard_val<=7'b1101101; //显示"2"
                8'b1011_1101: keyboard_val<=7'b1011111; //显示"6"
                8'b1011_1011: keyboard_val<=7'b1110111; //显示"A"
                8'b1011_0111: keyboard_val<=7'b1001111; //显示"E"
                8'b0111_1110: keyboard_val<=7'b1111001; //显示"3"
                8'b0111_1101: keyboard_val<=7'b1110000; //显示"7"
                8'b0111_1011: keyboard_val<=7'b0011111; //显示"b"
        8'b0111_0111: keyboard_val<=7'b1000111; //显示"F"
        default: keyboard_val<=7'b0000000;
     endcase
     end
   
    end  
   

always @(posedge clk or negedge rst)
begin //分频为5KHz
        if(next_state==delay)
        begin
              if (!rst)
               begin
                       c0<=0;
                       clk0<=1'b0;
               end
        else if(c0<2000)begin c0<=c0+1;delay_en>=0;end
          else begin clk0<=~clk0; c0<=0;delay_en=1;end
     end  end  
endmodule
 楼主| yyh1910 发表于 2010-11-2 21:45:09 | 显示全部楼层
大哥,quartus 综合还是有问题?再帮我看看好吗!!!!!!
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-4-20 09:17 , Processed in 0.065643 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表