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

📄 mouse.vhd

📁 Its project to move your mouse cursor on a vga monitor. it is very funny -)
💻 VHD
字号:
LIBRARY IEEE;
USE  IEEE.STD_LOGIC_1164.all;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY MOUSE IS


   PORT( clock_48Mhz, reset 			: IN std_logic;
        SIGNAL mouse_data				: INOUT std_logic;
        SIGNAL mouse_clk 				: INOUT std_logic;
        SIGNAL left_button, right_button: OUT std_logic;
		SIGNAL mouse_cursor_row 		: OUT std_logic_vector(9 DOWNTO 0); 
		SIGNAL mouse_cursor_column 		: OUT std_logic_vector(9 DOWNTO 0));       
		
		
END MOUSE;

ARCHITECTURE behavior OF MOUSE IS

TYPE STATE_TYPE IS (INHIBIT_TRANS, LOAD_COMMAND,LOAD_COMMAND2, WAIT_OUTPUT_READY,
					WAIT_CMD_ACK, INPUT_PACKETS);

-- Signals for Mouse
SIGNAL mouse_state							: state_type;
SIGNAL inhibit_wait_count					: std_logic_vector(10 DOWNTO 0);
SIGNAL CHARIN, CHAROUT						: std_logic_vector(7 DOWNTO 0);
SIGNAL new_cursor_row, new_cursor_column 	: std_logic_vector(9 DOWNTO 0);
SIGNAL cursor_row, cursor_column 			: std_logic_vector(9 DOWNTO 0);
SIGNAL INCNT, OUTCNT, mSB_OUT 				: std_logic_vector(3 DOWNTO 0);
SIGNAL PACKET_COUNT 						: std_logic_vector(1 DOWNTO 0);
SIGNAL SHIFTIN 								: std_logic_vector(8 DOWNTO 0);
SIGNAL SHIFTOUT 							: std_logic_vector(10 DOWNTO 0);
SIGNAL PACKET_CHAR1, PACKET_CHAR2, 
		PACKET_CHAR3 						: std_logic_vector(7 DOWNTO 0); 
SIGNAL MOUSE_CLK_BUF, DATA_READY, READ_CHAR	: std_logic;
SIGNAL cursor, iready_set, break, toggle_next, 
		output_ready, send_char, send_data 	: std_logic;
SIGNAL MOUSE_DATA_DIR, MOUSE_DATA_OUT, MOUSE_DATA_BUF, 
		MOUSE_CLK_DIR 						: std_logic;
SIGNAL MOUSE_CLK_FILTER 					: std_logic;
SIGNAL filter 								: std_logic_vector(7 DOWNTO 0);
SIGNAL MOUSE_CLK_RISING_EDGE 				: std_logic;
SIGNAL MOUSE_CLK_FALLING_EDGE 				: std_logic;
SIGNAL Clock_24Mhz							: std_logic;


BEGIN

mouse_cursor_row <= cursor_row;
mouse_cursor_column <= cursor_column;

			-- tri_state control logic for mouse data and clock lines
MOUSE_DATA <= 'Z' WHEN MOUSE_DATA_DIR = '0' ELSE MOUSE_DATA_BUF;
MOUSE_CLK <=  'Z' WHEN MOUSE_CLK_DIR = '0' ELSE MOUSE_CLK_BUF;
			-- Generate slower clock for mouse state machine
	PROCESS 
	BEGIN
		WAIT UNTIL clock_48Mhz'EVENT AND clock_48Mhz = '1';
		clock_24Mhz <= NOT clock_24Mhz;
	END PROCESS;

			-- state machine to send init command and start recv process.
	PROCESS (reset, clock_24Mhz)
	BEGIN
		IF reset = '0' THEN
			mouse_state <= INHIBIT_TRANS;
			inhibit_wait_count <= conv_std_logic_vector(0,11);
			SEND_DATA <= '0';
		ELSIF clock_24Mhz'EVENT AND clock_24Mhz = '1' THEN
			CASE mouse_state IS
-- Mouse powers up and sends self test codes, AA and 00 out before board is downloaded
-- Pull clock line low to inhibit any transmissions from mouse
-- Need at least 60usec to stop a transmission in progress
-- Note: This is perhaps optional since mouse should not be tranmitting
				WHEN INHIBIT_TRANS =>
				inhibit_wait_count <= inhibit_wait_count + 1;
				IF inhibit_wait_count(10 DOWNTO 9) = "11" THEN
						mouse_state <= LOAD_COMMAND;
				END IF;
					-- Enable Streaming Mode Command, F4
						charout <= "11110100";
					-- Pull data low to signal data available to mouse
				WHEN LOAD_COMMAND =>
						SEND_DATA <= '1';
						mouse_state <= LOAD_COMMAND2;
				WHEN LOAD_COMMAND2 =>
						SEND_DATA <= '1';
						mouse_state <= WAIT_OUTPUT_READY;
		-- Wait for Mouse to Clock out all bits in command.
		-- Command sent is F4, Enable Streaming Mode
		-- This tells the mouse to start sending 3-byte packets with movement data
				WHEN WAIT_OUTPUT_READY =>
					SEND_DATA <= '0';
			-- Output Ready signals that all data is clocked out of shift register
					IF OUTPUT_READY='1' THEN
						mouse_state <= WAIT_CMD_ACK;
					ELSE
						mouse_state <= WAIT_OUTPUT_READY;
					END IF;
		-- Wait for Mouse to send back Command Acknowledge, FA
				WHEN WAIT_CMD_ACK =>
					SEND_DATA <= '0';
					IF IREADY_SET='1' THEN
						mouse_state <= INPUT_PACKETS;
					END IF;
		-- Release clock_24Mhz and data lines and go into mouse input mode
		-- Stay in this state and recieve 3-byte mouse data packets forever
		-- Default rate is 100 packets per second
				WHEN INPUT_PACKETS =>
						mouse_state <= INPUT_PACKETS;
			END CASE;
		END IF;
	END PROCESS;

	WITH mouse_state SELECT
-- Mouse Data Tri-state control line: '1' FLEX Chip drives, '0'=Mouse Drives
		MOUSE_DATA_DIR 	<=	'0'	WHEN INHIBIT_TRANS,
							'0'	WHEN LOAD_COMMAND,
							'0'	WHEN LOAD_COMMAND2,
							'1'	WHEN WAIT_OUTPUT_READY,
							'0'	WHEN WAIT_CMD_ACK,
							'0'	WHEN INPUT_PACKETS;
-- Mouse Clock Tri-state control line: '1' FLEX Chip drives, '0'=Mouse Drives
	WITH mouse_state SELECT
		MOUSE_CLK_DIR 	<=	'1'	WHEN INHIBIT_TRANS,
							'1'	WHEN LOAD_COMMAND,
							'1'	WHEN LOAD_COMMAND2,
							'0'	WHEN WAIT_OUTPUT_READY,
							'0'	WHEN WAIT_CMD_ACK,
							'0'	WHEN INPUT_PACKETS;
	WITH mouse_state SELECT
-- Input to FLEX chip tri-state buffer mouse clock_24Mhz line
		MOUSE_CLK_BUF 	<=	'0'	WHEN INHIBIT_TRANS,
							'1'	WHEN LOAD_COMMAND,
							'1'	WHEN LOAD_COMMAND2,
							'1'	WHEN WAIT_OUTPUT_READY,
							'1'	WHEN WAIT_CMD_ACK,
							'1'	WHEN INPUT_PACKETS;

-- filter for mouse clock
PROCESS
BEGIN
		WAIT UNTIL clock_24Mhz'event and clock_24Mhz = '1';
		filter(7 DOWNTO 1) <= filter(6 DOWNTO 0);
		filter(0) <= MOUSE_CLK;
		IF filter = "11111111" THEN
------------------  START OF MODIFICATION  -----------------
			IF (MOUSE_CLK_FILTER='0') THEN		
				MOUSE_CLK_RISING_EDGE<='1';
			ELSE
				MOUSE_CLK_RISING_EDGE<='0';
			END IF;
------------------  END OF MODIFICATION  -------------------
			MOUSE_CLK_FILTER <= '1';
		ELSIF filter = "00000000" THEN
------------------  START OF MODIFICATION  -----------------
			IF (MOUSE_CLK_FILTER='1') THEN		
				MOUSE_CLK_FALLING_EDGE<='1';
			ELSE
				MOUSE_CLK_FALLING_EDGE<='0';
			END IF;
------------------  END OF MODIFICATION  -------------------
			MOUSE_CLK_FILTER <= '0';
		END IF;
END PROCESS;

	--This process sends serial data going to the mouse

SEND_UART: PROCESS (send_data, clock_24Mhz, charout)

BEGIN
IF SEND_DATA = '1' THEN
	OUTCNT <= "0000";
    SEND_CHAR <= '1';
	OUTPUT_READY <= '0';
		-- Send out Start Bit(0) + Command(F4) + Parity  Bit(0) + Stop Bit(1)
	SHIFTOUT(8 DOWNTO 1) <= CHAROUT ;
		-- START BIT
	SHIFTOUT(0) <= '0';
		-- COMPUTE ODD PARITY BIT
	SHIFTOUT(9) <=  not (charout(7) xor charout(6) xor charout(5) xor 
		charout(4) xor Charout(3) xor charout(2) xor charout(1) xor 
		charout(0));
		-- STOP BIT 
	SHIFTOUT(10) <= '1';
		-- Data Available Flag to Mouse
		-- Tells mouse to clock out command data (is also start bit)
    MOUSE_DATA_BUF <= '0';


ELSIF(clock_24Mhz'event and clock_24Mhz='1') THEN
	IF MOUSE_CLK_FALLING_EDGE='1' THEN

		IF MOUSE_DATA_DIR='1' THEN
		-- SHIFT OUT NEXT SERIAL BIT
			IF SEND_CHAR = '1' THEN
		-- Loop through all bits in shift register
        		IF OUTCNT <= "1001" THEN
		        	OUTCNT <= OUTCNT + 1;
		-- Shift out next bit to mouse
			        SHIFTOUT(9 DOWNTO 0) <= SHIFTOUT(10 DOWNTO 1);
		 			SHIFTOUT(10) <= '1';
         			MOUSE_DATA_BUF <= SHIFTOUT(1);
		 			OUTPUT_READY <= '0';
		-- END OF CHARACTER
	 			ELSE
     				SEND_CHAR <= '0';
		-- Signal the character has been output
					OUTPUT_READY <= '1';
					OUTCNT <= "0000";
				END IF;
  			END IF;
		END IF;

	END IF;

END IF;
END PROCESS SEND_UART;


RECV_UART: PROCESS(reset, clock_24Mhz)

BEGIN
IF RESET='0' THEN
	INCNT <= "0000";
    READ_CHAR <= '0';
	PACKET_COUNT <= "00";
    LEFT_BUTTON <= '0';
    RIGHT_BUTTON <= '0';
	CHARIN <= "00000000";

ELSIF (clock_24Mhz'event and clock_24Mhz='1') THEN
	IF MOUSE_CLK_RISING_EDGE='1' THEN
		IF MOUSE_DATA_DIR='0' THEN
	 		IF MOUSE_DATA='0' AND READ_CHAR='0' THEN
				READ_CHAR<= '1';
	    		IREADY_SET<= '0';
	 		ELSE
			-- SHIFT IN NEXT SERIAL BIT
		  		IF READ_CHAR = '1' THEN
		        	IF INCNT < "1001" THEN
		         		INCNT <= INCNT + 1;
		         		SHIFTIN(7 DOWNTO 0) <= SHIFTIN(8 DOWNTO 1);
		         		SHIFTIN(8) <= MOUSE_DATA;
			 			IREADY_SET <= '0';
						-- END OF CHARACTER
			 		ELSE
			 			CHARIN <= SHIFTIN(7 DOWNTO 0);
		     			READ_CHAR <= '0';
			 			IREADY_SET <= '1';
		  	 			PACKET_COUNT <= PACKET_COUNT + 1;
						-- PACKET_COUNT = "00" IS ACK COMMAND
						IF PACKET_COUNT = "00" THEN
							-- Set Cursor to middle of screen
						    cursor_column <= CONV_STD_LOGIC_VECTOR(320,10);
		    				cursor_row <= CONV_STD_LOGIC_VECTOR(240,10);
						    NEW_cursor_column <= CONV_STD_LOGIC_VECTOR(320,10);
		    				NEW_cursor_row <= CONV_STD_LOGIC_VECTOR(240,10);
						ELSIF PACKET_COUNT = "01" THEN
							PACKET_CHAR1 <= SHIFTIN(7 DOWNTO 0);
							-- Limit Cursor on Screen Edges	
							-- Check for left screen limit
							-- All numbers are positive only, and need to check for zero wrap around.
							-- Set limits higher since mouse can move up to 128 pixels in one packet
							IF (cursor_row < 128) AND ((NEW_cursor_row > 256) OR
								(NEW_cursor_row < 2)) THEN
								cursor_row <= CONV_STD_LOGIC_VECTOR(0,10);
					-- Check for right screen limit
							ELSIF NEW_cursor_row > 480 THEN
								cursor_row <= CONV_STD_LOGIC_VECTOR(480,10);
							ELSE
								cursor_row <= NEW_cursor_row;
							END IF;
					-- Check for top screen limit
							IF (cursor_column < 128)  AND ((NEW_cursor_column > 256)  OR
								(NEW_cursor_column < 2)) THEN
								cursor_column <= CONV_STD_LOGIC_VECTOR(0,10);
					-- Check for bottom screen limit
							ELSIF NEW_cursor_column > 640 THEN
								cursor_column <= CONV_STD_LOGIC_VECTOR(640,10);
							ELSE
								cursor_column <= NEW_cursor_column;
							END IF;
		  				ELSIF PACKET_COUNT = "10" THEN
							PACKET_CHAR2 <= SHIFTIN(7 DOWNTO 0);
		  				ELSIF PACKET_COUNT = "11" THEN
							PACKET_CHAR3 <= SHIFTIN(7 DOWNTO 0);
		  				END IF;
			 			INCNT <= conv_std_logic_vector(0,4);
		  				IF PACKET_COUNT = "11" THEN
		    				PACKET_COUNT <= "01";
						-- Packet Complete, so process data in packet
						-- Sign extend X AND Y two's complement motion values and 
						-- add to Current Cursor Address
						--
						-- Y Motion is Negative since up is a lower row address
		    				NEW_cursor_row <= cursor_row - (PACKET_CHAR3(7) & 
										PACKET_CHAR3(7) & PACKET_CHAR3);
		    				NEW_cursor_column <= cursor_column + (PACKET_CHAR2(7) & 
										PACKET_CHAR2(7) & PACKET_CHAR2);
		    				LEFT_BUTTON <= PACKET_CHAR1(0);
		    				RIGHT_BUTTON <= PACKET_CHAR1(1);
		  				END IF;
					END IF;
		  		END IF;
		 	END IF;
		END IF;
	END IF;
    END IF;
END PROCESS RECV_UART;

END behavior;

⌨️ 快捷键说明

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