矩阵键盘的verilog代码分享
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
矩阵键盘的verilog代码分享
defineSCAN
modulekey_scan(
clk ,
rst_n,
key_col, //键盘列输入
key_row, //键盘行输出
key_num, //指示哪一个按键按下,用0~15指示
key_vld//按下有效指示信号,其为1表示按下一次。
);
parameter KEY_W = 4 ;
parameter COL = 0 ;
parameter ROW = 1 ;
parameter DLY = 2 ;
parameter FIN = 3 ;
parameter COL_CNT= 16;
parameter TIME_20MS= 1000000;
//输入信号定义
input clk ;
input rst_n;
input[3:0] key_col;
//输出信号定义
output key_vld;
output[3:0] key_num;
output[KEY_W-1:0] key_row;
//输出信号reg定义
reg [3:0] key_num;
reg [KEY_W-1:0] key_row;
reg key_vld;
reg [ 3:0] key_col_ff0 ;
reg [ 3:0] key_col_ff1 ;
reg [ 1:0] key_col_get ;
reg shake_flag ;
reg shake_flag_ff0;
reg [ 3:0] state_c ;
reg [19:0] shake_cnt ;
reg [ 3:0] state_n ;
reg [ 1:0] row_index ;
reg [15:0] row_cnt ;
reg [ 2:0] x ;
always@(posedge clk or negedge rst_n)begin if(rst_n==1b0)begin
key_col_ff0 = 4b1111;
key_col_ff1 = 4b1111;
end
else begin
key_col_ff0 = key_col ;
key_col_ff1 = key_col_ff0;
end
end
always@(posedge clk or negedge rst_n)begin if(rst_n==1b0)begin
shake_cnt = 0;
end
else if(add_shake_cnt)begin
if(end_shake_cnt)
shake_cnt = 0;
else
shake_cnt = shake_cnt + 1;
end
else begin
shake_cnt = 0;
end
assignadd_shake_cnt = key_col_ff1!=4hf shake_flag==0; assignend_shake_cnt = add_shake_cnt shake_cnt==TIME_20MS-1; always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
shake_flag = 0;
end
else if(end_shake_cnt) begin
shake_flag = 1b1;
end
else if(key_col_ff1==4hf) begin
shake_flag = 1b0;
end
end
`ifdef SCAN
always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
state_c = COL;
end
else begin
state_c = state_n;
end
end
always@(*)begin
case(state_c)
COL: begin
if(col2row_start)begin
state_n = ROW;
end
else begin
state_n = state_c;
end
ROW: begin
if(row2dly_start)begin
state_n = DLY;
end
else begin
state_n = state_c;
end
end
DLY :begin
if(dly2fin_start)begin
state_n = FIN;
end
else begin
state_n = state_c;
end
end
FIN: begin
if(fin2col_start)begin
state_n = COL;
end
else begin
state_n = state_c;
end
end
default: state_n = COL;
endcase
end
assigncol2row_start = state_c==COL end_shake_cnt; assignrow2dly_start = state_c==ROW end_row_index; assigndly2fin_start = state_c==DLY end_row_index; assignfin2col_start = state_c==FIN key_col_ff1==4hf; always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
key_row = 4b0;
end
else if(state_c==ROW)begin
key_row = ~(1b1 row_index);
end
else begin
key_row = 4b0;
end
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
row_cnt = 0;
end
else if(add_row_cnt) begin
if(end_row_cnt)
row_cnt = 0;
else
row_cnt = row_cnt + 1;
end
end
assign add_row_cnt = state_c==ROW || state_c==DLY; assign end_row_cnt = add_row_cnt row_cnt==COL_CNT-1; always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
row_index = 0;
end
else if(add_row_index) begin
if(end_row_index)
row_index = 0;
else
row_index = row_index + 1;
end
assign add_row_index = end_row_cnt;
assign end_row_index = add_row_index row_index==x-1; always@(*)begin
if(state_c==ROW)
x = 4;
else
x = 1;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
key_col_get = 0;
end
else if(col2row_start) begin
if(key_col_ff1==4b1110)
key_col_get = 0;
else if(key_col_ff1==4b1101)
key_col_get = 1;
else if(key_col_ff1==4b1011)
key_col_get = 2;
else
key_col_get = 3;
end
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
key_num = 0;
end
else if(state_c==ROW end_row_cnt)begin
key_num = {row_index,key_col_get};
end
else begin
key_num = 0;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
key_vld = 1b0;
end
else if(state_c==ROW end_row_cnt key_col_ff1[key_col_get]==1b0)begin key_vld = 1b1;
end
else begin
key_vld = 1b0;
end
end
`else
always@(posedge clk or negedge rst_n)begin
if(rst_n==1b0)begin
key_vld = 0;
end
else begin
key_vld = end_shake_cnt;
end
end
always@(*)begin
key_num = 0;
end
`endif
endmodule。