⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2keyboard.v

📁 Verilog, c and asm source codes of the Minimig system, a fpga implementation of the Amiga computer.
💻 V
📖 第 1 页 / 共 3 页
字号:
// Copyright 2006, 2007 Dennis van Weeren//// This file is part of Minimig//// Minimig is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 3 of the License, or// (at your option) any later version.//// Minimig is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program.  If not, see <http://www.gnu.org/licenses/>.//////// This is the Minimig PS/2 keyboard handler//// 19-11-2006	-started coding// 20-11-2006	-more coding// 21-11-2006	-finished PS/2 state machine, added keymap// 29-11-2006	-keymap is now blockram, saves almost 80 slices!// 04-12-2006	-added keyack signal// 05-12-2006	-more work; cleaning up, optimizing//			-added on-screen-display control// 01-01-2007	-added extra key for on-screen-display control// 11-02-2007	-reset is now ctrl-alt-alt (as in Amiga OS4) instead of ctrl-lgui-rgui // this is the ps2 keyboard module itself// every time a new key is decoded, keystrobe is asserted.// keydat is only valid when keystrobe is asserted// after keystrobe, keyboard controller waits for keyack or timeout// kbdrst is asserted when the control, left gui and right gui keys are hold down together// leda and ledb control the numlock and scrolllock leds//JB:// 2008-03-01	- added support for prtscr and ctrlbrk keys// 		- verilog 2001 style module declarationmodule ps2keyboard(	input 	clk,		   		//bus clock	input 	reset,			   	//reset (system reset in)	inout	ps2kdat,			//keyboard PS/2 data	inout	ps2kclk,			//keyboard PS/2 clk	input	leda,				//keyboard led a in	input	ledb,				//keyboard led b in	output	kbdrst,				//keyboard reset out	output	[7:0]keydat,		//keyboard data out	output	reg keystrobe,		//keyboard data out strobe	input	keyack,				//keyboard data out acknowledge	output	[5:0]osdctrl		//on-screen-display controll);//local signalsreg		pclkout; 				//ps2 clk outwire	pdatout;				//ps2 data outwire	pclkneg;				//negative edge of ps2 clock strobereg		pdatb,pclkb,pclkc;	//input synchronization	reg		[11:0]preceive;		//ps2 receive registerreg		[11:0]psend;			//ps2 send registerreg		[19:0]ptimer;			//ps2 timerreg		[2:0]kstate;			//keyboard controller current statereg		[2:0]knext;			//keyboard controller next statereg		capslock;				//capslock statusreg		prreset;				//ps2 receive resetwire	prbusy;					//ps2 receive busyreg		ptreset;				//ps2 reset timerwire	pto1;					//ps2 timer timeout 1 wire	pto2;					//ps2 timer timeout 2reg		psled1;					//ps2 send led code 1reg		psled2;					//ps2 send led code 2wire	psready;				//ps2 send readywire	valid;					//valid amiga key code at keymap output//bidirectional open collector IO buffersassign ps2kclk=(pclkout)?1'bz:1'b0;assign ps2kdat=(pdatout)?1'bz:1'b0;//input synchronization of external signalsalways @(posedge clk)begin	pdatb<=ps2kdat;	pclkb<=ps2kclk;	pclkc<=pclkb;end						//detect ps2 clock negative edgeassign pclkneg=pclkc&(~pclkb);//PS2 input shifterwire prready;always @(posedge clk)	if(prreset||prready)		preceive[11:0]<=12'b111111111111;	else if(pclkneg)		preceive[11:0]<={1'b0,pdatb,preceive[10:1]};assign prready=~preceive[0];assign prbusy=~preceive[11];//PS2 timeralways @(posedge clk)	if(ptreset)		ptimer[19:0]<=0;	else if(!pto2)		ptimer[19:0]<=ptimer[19:0]+1;assign pto1=ptimer[15];//4.6ms @ 7.09Mhzassign pto2=ptimer[19];//74ms @ 7.09Mhz//PS2 send shifteralways @(posedge clk)	if(psled1)		psend[11:0]<=12'b111111011010;//$ED	else if(psled2)		psend[11:0]<={2'b11,~(capslock^leda^ledb),5'b00000,capslock,leda,ledb,1'b0};//led status	else if(!psready && pclkneg)		psend[11:0]<={1'b0,psend[11:1]};assign psready=(psend[11:0]==12'b000000000001)?1:0;assign pdatout=psend[0];//keyboard state machinealways @(posedge clk)	if(reset)//master reset		kstate<=0;	else 		kstate<=knext;always @(kstate or pto1 or pto2 or psready or prready or prbusy or keystrobe or keyack)begin	case(kstate)		0://reset timer			begin				prreset=1;				ptreset=1;				pclkout=0;				psled1=0;				psled2=0;								knext=1;			end		1://"request-to-send" for led1 code  			begin				prreset=1;				ptreset=0;				pclkout=0;				psled1=1;				psled2=0;								if(pto1)					knext=2;				else					knext=1;			end		2://wait for led1 code to be sent and acknowledge received			begin				prreset=~psready;				ptreset=1;				pclkout=1;				psled1=0;				psled2=0;								if(prready)					knext=3;				else					knext=2;			end		3://"request-to-send" for led2 code			begin				prreset=1;				ptreset=0;				pclkout=0;				psled1=0;				psled2=1;								if(pto1)					knext=4;				else					knext=3;			end		4://wait for led2 code to be sent			begin				prreset=~psready;				ptreset=1;				pclkout=1;				psled1=0;				psled2=0;								if(prready)					knext=5;				else					knext=4;			end		5://wait for valid amiga key code			begin				prreset=0;				ptreset=keystrobe;				pclkout=1;				psled1=0;				psled2=0;				if(keystrobe)//valid amiga key decoded					knext=6;				else if(!prbusy && pto2)//timeout, update leds					knext=0;				else//stay here					knext=5; 			end		6://hold of ps2 keyboard and wait for keyack or timeout			begin				prreset=0;				ptreset=keyack;				pclkout=0;				psled1=0;				psled2=0;				if(keyack || pto2)//keyack or timeout					knext=5;				else//stay here					knext=6; 			end		default://we should never come here			begin				prreset=0;//ps2 receiver reset				ptreset=0;//ps2 timer reset				pclkout=1;//ps2 clock override				psled1=0;//ps2 send led code 1				psled2=0;//ps2 send led code 2				knext=0;//go to reset state 			end	endcaseend//instantiate keymap to convert ps2 scan codes to amiga raw key codeswire ctrl,aleft,aright,caps;ps2keyboardmap km1(	.clk(clk),	.reset(reset),	.enable(prready),	.ps2key(preceive[8:1]),	.valid(valid),	.akey(keydat[7:0]),	.ctrl(ctrl),	.aleft(aleft),	.aright(aright),	.caps(caps),	.osdctrl(osdctrl));//Duplicate key filter and caps lock handling.//A ps/2 keyboard has a future called "typematic".//This means that the last key downstroke event//is repeated (at approx 2Hz default).//An Amiga keyboard does not do this so this filter removes//all duplicate downstroke events://When a duplicate downstroke event is detected, keystrobe is not asserted.//When the event is unique (no duplicate), keystrobe is asserted when valid is asserted.////Capslock on amiga is "remembered" by keyboard. A ps/2 keyboard doesn't do this//therefore, amiga-like caps lock behaviour is simulated herewire keyequal;reg [7:0]keydat2;assign keyequal=(keydat2[6:0]==keydat[6:0])?1:0;//detect if latched key equals new key//latch last key downstroke eventalways @(posedge clk)	if(reset)		keydat2[7:0]<=0;	else if(valid && !keydat[7])//latch downstroke event for last key pressed		keydat2[7:0]<=keydat[7:0];	else if (valid && keydat[7] && keyequal)//upstroke event for latched key received		keydat2[7:0]<=keydat[7:0];//toggle capslock status on capslock downstroke event		always @(posedge clk)	if(reset)		capslock<=0;	else if(valid && !keydat[7] && caps && !(keyequal && (keydat[7]==keydat2[7])))		capslock<=~capslock;//generate keystrobe to indicate valid keycode				//assign keystrobe=(keyequal && (keydat[7]==keydatlatch[7]))?0:keyok;always @(capslock or caps or keyequal or keydat or keydat2 or valid)	if(capslock && caps)//filter out capslock downstroke && capslock upstroke events if capslock is set		keystrobe=0;	else if(keyequal && (keydat[7]==keydat2[7]))//filter out duplicate events		keystrobe=0;	else if(valid)//valid amiga keycode, assert strobe		keystrobe=1;	else		keystrobe=0;//Keyboard reset detector. //Reset is accomplished by holding down the//ctrl, left alt en right alt keys all at the same timereg [2:0]kbdrststatus;always @(posedge clk)begin	//latch status of control key	if(reset)		kbdrststatus[2]<=1;	else if (valid && ctrl)		kbdrststatus[2]<=keydat[7];	//latch status of left alt key

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -