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==1'b0)begin
key_col_ff0 <= 4'b1111;
key_col_ff1 <= 4'b1111;
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==1'b0)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
end
assignadd_shake_cnt = key_col_ff1!=4'hf && 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==1'b0)begin
shake_flag <= 0;
end
else if(end_shake_cnt) begin
shake_flag <= 1'b1;
end
else if(key_col_ff1==4'hf) begin
shake_flag <= 1'b0;
end
end
`ifdef scan
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)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
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==4'hf;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_row <= 4'b0;
end
else if(state_c==row)begin
key_row <= ~(1'b1 << row_index);
end
else begin
key_row <= 4'b0;
end
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)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==1'b0)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
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==1'b0)begin
key_col_get <= 0;
end
else if(col2row_start) begin
if(key_col_ff1==4'b1110)
key_col_get <= 0;
else if(key_col_ff1==4'b1101)
key_col_get <= 1;
else if(key_col_ff1==4'b1011)
key_col_get <= 2;
else
key_col_get <= 3;
end
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)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
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_vld <= 1'b0;
end
else if(state_c==row && end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin
key_vld <= 1'b1;
end
else begin
key_vld <= 1'b0;
end
end
`else
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_vld <= 0;
end
else begin
key_vld <= end_shake_cnt;
end
end
always@(*)begin
key_num = 0;
end
`endif
endmodule
哪些物联网工具可以保护连网汽车的安全性
iphone8什么时候上市最新消息:iphone8售价曝光,一个肾可能不够了!新功能双卡双待到底有没有?
多声道喇叭摆置法
三星电子开发新一代LPDDR3移动DRAM技术
才茂城市排水自动化监测方案保障排水管网稳定运行
矩阵键盘的verilog代码分享
戴尔PowerEdge T40服务器具有哪些优势
MTK平台发展及各芯片功能介绍
中美贸易战“暂停”之后 LED屏企需要看得更远!
光信号怎么变成电信号
毫米波的5G芯片是否能在国内正常使用
如何判断变频抽油烟机在实际应用中是否达到了要求
灭蚊灯有用吗?找对方式灭蚊有妙招
地面数字电视接收机帧与载波的同步模块设计与仿真
初级模拟电路共基、共射、共集组态re模型解析
电源管理的原理和方法
金属卤素灯工作原理_金属卤素灯寿命
单片机解密到底是什么
磷酸铁锂电池耐过充吗?锂电池耐过充过放,短期内过放能修复80%之上的特性
海思的手机芯片若是对外销售 将会面对两大挑战