키 스캔 및 인코더

디자인 사고

        키보드 스캔과 엔코더는 디지털 시스템에서 키보드로 수동으로 데이터를 입력하는 방식으로, 키가 눌렸는지 여부를 감지하여 해당 키에 해당하는 고유한 스캔코드를 생성하고 16진수 키보드 회로의 키보드 스캔과 엔코더는 설계되었습니다.

                  

        상태 기계를 사용하여 감지 신호의 열 위치를 반복합니다. 여기서 ab/c는 a: S_row(모든 행 신호 AND), b: 행(행 신호), c: Vaild(신호 활성화)로 표현됩니다. S_0은 초기 상태, S_i는 i번째 열의 상태를 감지하는 것을 의미하고 S_5는 열 신호가 발견되었음을 의미합니다. 처음에 S_raw가 유효하다는 것을 감지하면 버튼을 눌렀다는 의미이며, 이때 모든 컬럼 시그널이 설정되면(clo=1111, 즉 15) 차례로 행 시그널을 감지하고, 버튼을 눌렀다는 의미인 S_1 상태의 행이 유효하면 col의 값을 변경하여 열 번호를 기록하고, 그렇지 않으면 순차적으로 다른 상태를 검출한다. .

      이 모듈은 hex_keypad_grayhill로 정의되는데, 입력 신호는 S_row와 row를 포함하고, 출력 신호는 code(keypad letter), vaild, col을 포함한다. 그러면 행과 열을 조합하여 코드(키패드 문자)를 찾습니다. ).

        위의 모듈에서 사용되는 S_row의 경우 각 행의 라인 값의 OR을 감지하여 모듈 싱크로 나이저에서 결정할 수 있습니다. 즉, 디자인 모듈에 행 신호 행이 주어지는 한.

        따라서 최상위 모듈 전체를 키패드로 정의하고 입력 신호 행이 입력되면 열 col과 code를 출력할 수 있다.

        키패드에 초기 행 값을 주는 방법은 테스트 모듈을 통해 행을 생성하기 위해 row_signal 모듈(아날로그 키보드 신호 모듈)을 호출할 수 있습니다.row_signal 모듈의 입력 신호는 열 신호 col과 키(키보드)이고 출력 신호는 col과 key.row 간의 논리적 관계를 통해 이루어집니다.

          row_signal 입력: 키, 열; 출력: 행;

          키패드 입력: 행, 출력: 코드, 열;     

                         동기화 장치 입력: 행, 출력: S_row

                          hex_keypad_grayhill 입력: S_row, 행; 출력: code, col;

        따라서 테스트할 때 먼저 아날로그 키 신호 생성기를 사용하여 키 값(문자)을 설정하고 row_signal을 호출하여 키의 유효성을 감지하고 키가 있는 행을 결정한 다음 파라미터를 키패드에 전달하여 키를 얻습니다. 출력 코드(문자).

        

//顶层模块:
module keypad(clock,reset,row,code,vaild,col);
	input clock,reset;
	input [3:0] row;
	output [3:0] code;
	output vaild;
	output [3:0] col;
	wire s _row;
	hex_keypad_grayhill U1(.code(code),.col(col),.valid(valid),
													.row(row),.s row(s_row),.clock(clock),.reset(reset));
	synchronizer U2(.s_row(s_row),.row(row),.clock(clock),..reset(reset));
endmodule
//编码模块:
module hex_keypad_grayhill(code,col,valid,row,s_row,clock,reset);
	output[3:0] code;
	output valid;
	output[3:0] col;
	input[3:0] row;
	input s_row;
	input clock,reset;
	reg[3:0] col;
	reg[3:0] code;
	reg [5:0] state,next_state;
	parameter s_O=6'b000001,s_1=6'b000010,s_2=6'b000100;
	parameter s_3=6'b001000,s_4=6'b010000,s_5=6'b100000;
	assign valid=((state==s_1)||(state==s_2)||(state==s_3)||(state==s_4))&&row;
 always@(row or col)
		case({row,col})
			8'b0001_0001: code=0;
			8'b0001_0010: code=1;
			8'b0001_0100: code=2;
			8'b0001_1000: code=3;
			8'b0010_0001: code=4;
			8'b0010_0010: code=5;
			8'b0010_0100: code=6;
			8'b0010_1000: code=7;
			8'b0100_0001: code=8;
			8'b0100_0010: code=9;
			8'b0100_0100: code=10;   //A
			8'b0100_1000: code=11;	 //B
			8'b1000_0001: code=12;
			8'b1000_0010: code=13;
			8'b1000_0100: code=14;
			8'b1000_1000: code=15;
      default code=O;
		endcase
	always@(state or s_row or row) //next-state logic
		begin
			next_state=state; col=O;
			case(state)
					s_0:begin 
							col=15;
							if(s_row) next_state=s_1;
							end
					s_1:begin
							col=1;
							if(row) next_state=s_5;
							else next_state=s_2;
							end
					s_2:begin
							col=2;
							if(row) next_state=s_5;
							else next_state=s_3;
							end
					s_3:begin
							col=4;
							if(row) next_state=s_5;
							else next_state=s_4;
							end
					s_4:begin
						  col=8;
							if(row) next_state=s_5;
							else next_state=s_0;
							end
					s_5:begin
						  col=15;
							if(!row) next_state=s_0;
							end
			endcase
		end
	always@(posedge clock or posedge reset)
		if(reset)
			state<=s_o;
		else
			state<=next_state;
endmodule
//计算s_row模块
module synchronizer(s_row, row,clock,reset);
	output s_row;
	input [3:0] row;
	input clock,reset;
	reg a_row,s_row;
	always@(negedge clock or posedge reset)
	begin
		if(reset)
			begin
				a_row<=0;s_row<=O;
			end
		else 
			begin
			a_row<=(row[0]||[row[1]||row[2]||row[3]);
			s_row<=a_row;
			end
	end
endmodule
//模拟键盘产生信号
module row_signal(row,key.,col);output [3:0] row;
	input[15:0] key;
	input [3:0] col;
	reg[3:0] row;
	always@(key or col)
	begin
		row[0]=key[0]&&col[0]||key[1]&&col[1]||key[2]&&col[2]||key[3]&&col[3];
		row[1]=key[4]&&col[0]||key[5]&&col[1]||key[6]&&coI[2]||key[7]&&col[3];
		row[2]=key[8]&&col[0]||key[9]&&col[1]||key[10]&&col[2]||key[11]&&col[3];
		row[3]=key[12]&&col[0]||key[13]&&col[1]||key[14]&&col[2]||key[15]&&col[3];
	end
endmodule
//Testbench
module hex_keypad_grayhill_tb;
	wire [3:0] code;
	wire valid;
	wire [3:0] col;
	wire [3:0] row;
	reg clock;
	reg reset;
	reg [15:0] key;
	integer j,k;
	reg [39:0] pressed;
	parameter [39:0] key_0="key_o";
	parameter [39:0] key_1="key_1";
	parameter i39:0] key3="key_a";
	parameter [39:0] key_4="key_4";
	parameter [39:0] key_5="key_5";
	parameter [39:0] key_6="key_6";
	parameter [39:0] key_7="key_7";
	parameter [39:0] key_8="key_8";
	parameter [39:0] key_9="key_9";
	parameter [39:0] key_A="key_A";
	parameter [39:0] key_B="key_B";
	parameter [39:0] key_C="key_c";
	parameter [39:0] key_D="key_D";
	parameter [39:0] key_E="key_E";
	parameter [39:0] key_F="key_F";
	parameter [39:0] None="None";
	keypad U1(.clock(clock),.reset(reset), .row(row),.code(code),.vaild(vaild),.col(col));
//top module
	row_signal U2(.row(row),.key(key),.col(col));// Simulatesignal generation
	always@(key)
	begin
		case(key)
			16'h0000: pressed=None;
			16'h0001: pressed=key_0;
			16'h0002: pressed=key_1;
			16'h0004: pressed=key_2;
			16'h0008: pressed=key_3;
			16'h0010: pressed=key_4;
			16'h0020: pressed=key_5;
			16'h0040: pressed=key_6;
			16'h0080: pressed=key_7;
			16'h0100: pressed=key_8;
			16'h0200: pressed=key_9;
			16'h0400: pressed=key_A;
			16'h0800: pressed=key_B;
			16'h1000: pressed=key_C;
			16'h2000: pressed=key_D;
			16'h4000: pressed=key_E;
			16'h8000: pressed=key_F;
			default:pressed=None;
		endcase
	end
	initial #2000 $stop;
	initial 
		begin 
			clock=O;
			forever #5 clock=~clock;
		end
	initial
		begin 
			reset=1;
			#10 reset=0;
		end
	initial
		begin 
			for(k=O;k<=1;k=k+1)
			begin 
				key=0;
				#20 for(j=0;j<=16;j=j+1)
						begin
								#20 key[j]=1;
								#60 key=0;
							end
			end
		end
endmodule

Supongo que te gusta

Origin blog.csdn.net/Strive_LiJiaLe/article/details/127151620
Recomendado
Clasificación