6X6矩阵键盘设计含按键消抖(VERILOG)

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 18:27:54 08/07/2017
// Design Name:
// Module Name: ports_6x6
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ports_6x6(
//-------------------------------------------------------------------
// Local Wires rst and Clock
//-------------------------------------------------------------------
input wire fix_clk,
input wire reset,

	input wire										[5:0]    row,                   // 矩阵键盘 行
	output reg 										[5:0] 	col,                   // 矩阵键盘 列
	
	input wire													in_enable,

	output reg 													in_key_en,            	
	output reg 										[3:0] in_key_data,
	
	output reg 													out_key_en,            	
	output reg 										[3:0] 	out_key_data,
	
	output reg 													safe_en,
	output reg 													lock_en,
	output reg 													take_en

);

	reg 											  [20:0]   	cnt0;                  // 计数子
	reg											  [10:0]		cnt1;
	reg											  [16:0]		cnt2;
	reg 												[3:0] 	state;
	
	reg												[5:0]		row_d1;
	reg												[5:0]		row_d2;
	reg												[5:0]		row_d3;

	reg															cnt1_d1;
	reg															cnt1_d2;
	
	reg															cnt2_d1;
	reg															cnt2_d2;
	
	reg											[7:0]			gen_key_data;
	reg															gen_key_en;
	reg															gen_fn_en;

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
parameter SCAN_COL0		 = 4'b0000;  // 扫描第0列
parameter SCAN_COL1 		 = 4'b0001;  // 扫描第1列
parameter SCAN_COL2		 = 4'b0010;  // 扫描第2列
parameter SCAN_COL3		 = 4'b0011;  // 扫描第3列
parameter SCAN_COL4		 = 4'b0100;  // 扫描第4列
parameter SCAN_COL5		 = 4'b0101;  // 扫描第5列

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
always @ (posedge fix_clk or posedge reset)
begin
if( reset == 1’b1 ) begin
cnt0 <= 21’b0;
end else begin
if ( cnt0>=20’h1ffff)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1’b1 ;
end
end
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
always @(posedge fix_clk or posedge reset)
begin
if (reset == 1’b1) begin
state <= SCAN_COL0;
col <= 6’b111110;
end else begin
if (cnt0>=20’h1ffff) begin
case (state)
SCAN_COL0 : begin // 扫描第0列
if (row_d3 == 6’h3f)begin
state <= SCAN_COL1;
col <= 6’b111110;
end
end

				SCAN_COL1 : begin                          // 扫描第1列
				  if (row_d3 == 6'h3f)begin 
						state <= SCAN_COL2;					  
						col <= 6'b111101;
				  end
				end

				SCAN_COL2 :  begin                         // 扫描第2列
				  if (row_d3 == 6'h3f)begin
						state <= SCAN_COL3;					  
					   col <= 6'b111011;
					end
				end

				SCAN_COL3 :begin									// 扫描第3列
					if (row_d3 == 6'h3f) begin
						state <= SCAN_COL4;					  
						col <= 6'b110111;
					end
				end
				
				SCAN_COL4 :begin									// 扫描第4列
					if (row_d3 == 6'h3f) begin
						state <= SCAN_COL5;				  
						col <= 6'b101111;
					end
				end
				
				SCAN_COL5 :begin									// 扫描第5列
				  if (row_d3 == 6'h3f) begin
						state <= SCAN_COL0;					  
						col <= 6'b011111;
					end
				end					
				
			endcase
		end
	end
end

//-------------------------------------------------------------------
// 扫描行列值部分 开始
//-------------------------------------------------------------------
always @ (posedge fix_clk or posedge reset )
begin
	if (reset == 1'b1 ) begin
		row_d1 <= 6'b0;
		row_d2 <= 6'b0;
		row_d3 <= 6'b0;
		
		cnt1 <= 11'b0;
  end else begin
		row_d1 <= row;
		row_d2 <= row_d1;
		row_d3 <= row_d2;
		
		if ((row_d3 == 6'b111110) || (row_d3 == 6'b111101) || (row_d3 == 6'b111011) || (row_d3 == 6'b110111) || (row_d3 == 6'b101111) || (row_d3 == 6'b011111)) begin
			if (cnt1[10] == 1'b1) 
				cnt1 <= cnt1;
			else 
				cnt1 <= cnt1 + 1'b1;
		end else begin
			cnt1 <= 11'b0;
		end		
	end
end
	
//-------------------------------------------------------------------------------
// 将key_samp1锁存至key_samp1_locked
//-------------------------------------------------------------------------------
always @(posedge fix_clk or posedge reset)
begin
	if (reset == 1'b1) begin
		cnt1_d1 <= 1'b0;
		cnt1_d2 <= 1'b0;

		cnt2_d1 <= 1'b0;
		cnt2_d2 <= 1'b0;
		
		gen_key_en <= 1'b0;
		gen_fn_en <= 1'b0;
	end else begin
		cnt1_d1 <= cnt1[10];
		cnt1_d2 <= cnt1_d1;
		
		if ((cnt1_d1 == 1'b1) && (cnt1_d2 == 1'b0)&&(in_enable ==1'b1))begin
			gen_key_en <= 1'b1;
		end else begin
			gen_key_en <= 1'b0;
		end
		
	end  
end		
	
	
always @(col or row_d2) 
begin
	case ( {col, row_d3} )
		 12'b111110_111110	 :begin  gen_key_data <= 8'h00; end
		 12'b111101_111110	 :begin  gen_key_data <= 8'h01; end
		 12'b111011_111110	 :begin  gen_key_data <= 8'h02; end
		 12'b110111_111110	 :begin  gen_key_data <= 8'h03; end
		 12'b101111_111110	 :begin  gen_key_data <= 8'h04; end
		 12'b011111_111110	 :begin  gen_key_data <= 8'h05; end
                         
		 12'b111110_111101	 :begin  gen_key_data <= 8'h06; end
		 12'b111101_111101	 :begin  gen_key_data <= 8'h07; end
		 12'b111011_111101	 :begin  gen_key_data <= 8'h08; end
		 12'b110111_111101	 :begin  gen_key_data <= 8'h09; end
		 12'b101111_111101	 :begin  gen_key_data <= 8'h0a; end
		 12'b011111_111101	 :begin  gen_key_data <= 8'h0b; end
                         
		 12'b111110_111011	 :begin  gen_key_data <= 8'h0c; end
		 12'b111101_111011	 :begin  gen_key_data <= 8'h0d; end
		 12'b111011_111011	 :begin  gen_key_data <= 8'h0e; end
		 12'b110111_111011	 :begin  gen_key_data <= 8'h0f; end
		 12'b101111_111011	 :begin  gen_key_data <= 8'h10; end
		 12'b011111_111011	 :begin  gen_key_data <= 8'h11; end
			                
		 12'b111110_110111	 :begin  gen_key_data <= 8'h12; end
		 12'b111101_110111	 :begin  gen_key_data <= 8'h13; end
		 12'b111011_110111	 :begin  gen_key_data <= 8'h14; end
		 12'b110111_110111	 :begin  gen_key_data <= 8'h15; end
		 12'b101111_110111	 :begin  gen_key_data <= 8'h16; end
		 12'b011111_110111	 :begin  gen_key_data <= 8'h17; end
                                                    
		 12'b111110_101111	 :begin  gen_key_data <= 8'h18; end
		 12'b111101_101111	 :begin  gen_key_data <= 8'h19; end
		 12'b111011_101111	 :begin  gen_key_data <= 8'h1a; end
		 12'b110111_101111	 :begin  gen_key_data <= 8'h1b; end
		 12'b101111_101111	 :begin  gen_key_data <= 8'h1c; end
		 12'b011111_101111	 :begin  gen_key_data <= 8'h1d; end
                                                    
		 12'b111110_011111	 :begin  gen_key_data <= 8'h1e; end
		 12'b111101_011111	 :begin  gen_key_data <= 8'h1f; end
		 12'b111011_011111	 :begin  gen_key_data <= 8'h20; end  // safe          
		 12'b110111_011111	 :begin  gen_key_data <= 8'h21; end  // lock          
		 12'b101111_011111	 :begin  gen_key_data <= 8'h22; end  // f1          
		 12'b011111_011111	 :begin  gen_key_data <= 8'h23; end  // take          
		 default :				 begin 	gen_key_data <= 8'h0; end 
	endcase
end 

always@(posedge fix_clk or posedge reset) 
begin
	if (reset == 1'b1) begin 
		in_key_data <= 4'b0;
		out_key_data <= 4'b0;
		safe_en <= 1'b0;
		lock_en <= 1'b0;
		take_en <= 1'b0;
	end else begin 
		if ( gen_key_en == 1'b1) begin 
			if (( gen_key_data <= 8'h0f) && (safe_en == 1'b0)) begin // input key data 
					in_key_data <= gen_key_data[3:0];
					in_key_en <= 1'b1;
			end else if (( 8'h10 <= gen_key_data) && (gen_key_data <= 8'h1f) && (safe_en == 1'b0)  )begin  // output key data 
					out_key_data <= gen_key_data - 8'h10;
					out_key_en <= 1'b1;
			end else if ( gen_key_data == 8'h20 )begin 
					safe_en <= ~safe_en;
			end else if (( gen_key_data == 8'h21 ) && (safe_en == 1'b0))begin 	
					lock_en <= 1'b1;
			end else if (( gen_key_data == 8'h23 ) && (safe_en == 1'b0))begin 	
					take_en <= 1'b1;	
			end 	
		end else begin 
			in_key_en <= 1'b0;
			out_key_en <= 1'b0;
			lock_en <= 1'b0;
			safe_en <= safe_en;
			take_en <= 1'b0;
		end 
					
	end
end
			
OBUF
U_en(
	.I ( in_key_en || out_key_en ||gen_key_en),
	.O());
	
OBUF
U_data(
	.I ( |in_key_data || |out_key_data),
	.O());		

endmodule

你可能感兴趣的:(FPGA代码,矩阵按键)