`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