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

📄 ps2.vhd

📁 用vhdl设计实现的多功能电子钟
💻 VHD
字号:
-- The FPGA-evb-S2 Xilinx Spartan-II evaluation board example
-- This example reads scan codes from a PS/2 keyboard and
-- displays them on LEDs.
-- (C)2001 Jan Pech, j.pech@sh.cvut.cz
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ps2 is
	port (
		resetn: in std_logic; -- active low reset
		clock: in std_logic; -- system clock
		clk_10hz:in std_logic;
		ps2_clk: in std_logic; -- PS/2 clock line
		ps2_dta: in std_logic; -- PS/2 data line
		hit_1: buffer std_logic;
		ascii: out std_logic_vector(7 downto 0)
		); 
end ps2;

architecture behavioral of ps2 is
	type state_type is (IDLE, START, DATA, PARITY);   -- FSM states
	signal ps2_dv: std_logic;                         -- PS/2 data valid
	signal prv_ps2_clk, act_ps2_clk: std_logic;       -- auxiliary signals
	signal recdata: std_logic_vector(7 downto 0);     -- read data
	signal shift: std_logic;                          -- enable for shift reg.
	signal n_shift: std_logic;                        -- auxiliary signal
	signal latch: std_logic;                          -- latch read data
	signal n_latch: std_logic;                        -- auxiliary signal
	signal err: std_logic;                            -- parity or stop error
	signal n_err: std_logic;                          -- auxiliary signal
	signal parset: std_logic;                         -- preset for parity check
	signal n_parset: std_logic;                       -- auxiliary signal
	signal c_state, n_state: state_type;              -- current & next states
	signal cntval: std_logic_vector(2 downto 0);      -- counter of data bits
	signal zero: std_logic;                           -- counter is zero
	signal parbit: std_logic;                         -- odd parity of data
	signal leds,leds_last:std_logic_vector(7 downto 0);
	signal hit_cnt:std_logic_vector(8 downto 0);
	signal hit:std_logic;
begin
-- Provides a one-shot pulse after every falling edge of PS/2 clock
	


	PS_CLK_SYNC: process(clock, resetn)
		begin
			if (resetn = '0') then
				prv_ps2_clk <= '1';
				act_ps2_clk <= '1';
			elsif (clock'event and clock = '1') then
				act_ps2_clk <= ps2_clk;
				prv_ps2_clk <= act_ps2_clk;
			end if;
		end process;
	ps2_dv <= (not act_ps2_clk) and prv_ps2_clk;

-- Serial input, parallel output shift register
	SIPO: process(clock, resetn)
		begin
			if (resetn = '0') then
				recdata <= (others => '0');
			elsif (clock'event and clock = '1') then
				if (shift = '1') then
					recdata <= ps2_dta & recdata(7 downto 1);
				end if;
			end if;
		end process;

-- Counter of data bits
	COUNT8: process(resetn, clock)
		begin
			if (resetn = '0') then
				cntval <= (others => '0');
			elsif (clock'event and clock = '1') then
				if (shift = '1') then
					cntval <= cntval + 1;
				end if;
			end if;
		end process;
	zero <= not (cntval(0) or cntval(1) or cntval(2));

-- Parity check of received data
	PARITY_CHECK: process(clock, parset)
		begin
			if (parset = '1') then
				parbit <= '1';
			elsif (clock'event and clock = '1') then
				if (shift = '1' and ps2_dta = '1') then
					parbit <= not parbit;
				end if;
			end if;
		end process;

-- Synchronous process of control state machine
	FSM_SYNC: process(clock, resetn)
		begin
			if (resetn = '0') then
				c_state <= IDLE;
				shift <= '0';
				latch <= '0';
				err <= '0';
				parset <= '1';
			elsif (clock'event and clock = '1') then
				c_state <= n_state;
				shift <= n_shift;
				latch <= n_latch;
				err <= n_err;
				parset <= n_parset;
			end if;
		end process;

-- Combinatorial process of control state machine
	FSM_COMB: process(c_state, ps2_dv, ps2_dta, zero)
		begin -- default values
			n_shift <= '0';
			n_latch <= '0';
			n_err <= '0';
			n_parset <= '0';
-- wait to receive data			
			case c_state is 
				when IDLE => 
					if ((ps2_dv and (not ps2_dta)) = '1') then
						n_state <= START;
						n_parset <= '1';
					else
						n_state <= IDLE;
					end if;
-- receive first data bit
				when START => 
					if (ps2_dv = '0') then
						n_state <= START;
					else
						n_state <= DATA;
						n_shift <= '1';
					end if;
-- receive remaining data bits and parity
				when DATA => 
					if (ps2_dv = '0') then
						n_state <= DATA;
					elsif (zero = '0') then
						n_state <= DATA;
						n_shift <= '1';
					else
						n_state <= PARITY;
						if (parbit /= ps2_dta) then
							n_err <= '1';
						end if;
					end if;
-- receive stop bit
				when PARITY => 
					if (ps2_dv = '0') then
						n_state <= PARITY;
					else
						n_state <= IDLE;
						n_latch <= '1';
						n_err <= not ps2_dta;
					end if;
			end case;
		end process;

-- Output latch
	LED_OUTPUTS: process(resetn, clock)
		begin
			if (resetn = '0') then
				leds <= (others => '1');
			elsif (clock'event and clock = '1') then
				if (err = '1') then
					leds <= (others => '1');
				elsif (latch = '1') then
					leds <= recdata;
				end if;
			end if;
		end process;
		
	PROCESS(leds)
		BEGIN	
			case leds is
				when "01000101"=> ascii <= "00110000"; hit<='1'; --0
				when "00010110"=> ascii <= "00110001"; hit<='1'; --1 
				when "00011110"=> ascii <= "00110010"; hit<='1'; --2 
				when "00100110"=> ascii <= "00110011"; hit<='1'; --3 
				when "00100101"=> ascii <= "00110100"; hit<='1'; --4 
				when "00101110"=> ascii <= "00110101"; hit<='1'; --5 
				when "00110110"=> ascii <= "00110110"; hit<='1'; --6 
				when "00111101"=> ascii <= "00110111"; hit<='1'; --7 
				when "00111110"=> ascii <= "00111000"; hit<='1'; --8 
				when "01000110"=> ascii <= "00111001"; hit<='1'; --9 

				when others => ascii <= "00100000"; hit<='0'; --' ' for unlisted characters.
			end case;

		END PROCESS;
		
	
	PROCESS(clk_10hz,resetn)
	 begin
	    if (resetn = '0' ) then
	     hit_1<= '0';
	    else
		     if clk_10hz'event and clk_10hz='0' then
                     hit_1 <= hit;
             end if;

		end if;

	END PROCESS;
	
end;

⌨️ 快捷键说明

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