?? mouse.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 (
clk : in std_logic;
reset : in std_logic;
ps2_clk : inout std_logic;
ps2_data : inout std_logic;
left_button : out std_logic;
right_button : out std_logic;
mov_x : out std_logic_vector(9 downto 0);
mousex: buffer std_logic_vector(9 downto 0);
mousey: buffer std_logic_vector(9 downto 0);
data_ready : out std_logic;-- rx_read_o
error_no_ack : out std_logic
);
end mouse;
architecture Behavioral of mouse is
constant TOTAL_BITS : integer :=33; -- Number of bits in one full packet
-- The timer value can be up to (2^bits) inclusive.
constant WATCHDOG : integer :=320;-- Number of sys_clks for 400usec.160
type m2statetype is (m2_reset, m2_wait, m2_gather, m2_verify, m2_use, m2_hold_clk_l,
m2_data_low_1, m2_data_high_1, m2_data_low_2, m2_data_high_2, m2_data_low_3,
m2_data_high_3, m2_error_no_ack, m2_await_response);
signal m2_state,m2_next_state : m2statetype;
--signal m3_state,m3_next_state : std_logic;
signal watchdog_timer_done : std_logic;--signals of commanding out to mouse
signal q : std_logic_vector(TOTAL_BITS-1 downto 0);--bit sequence
signal bitcount : std_logic_vector(5 downto 0);--bit count
signal watchdog_timer_count : std_logic_vector(8 downto 0); --wait time
signal ps2_clk_hi_z : std_logic; -- Without keyboard, high Z equals 1 due to pullups.
signal ps2_data_hi_z : std_logic; -- Without keyboard, high Z equals 1 due to pullups.
signal fallsig,risesig : std_logic_vector(2 downto 0);
signal clean_clk : std_logic; -- Debounced output from m1, follows ps2_clk.
signal rise,n_rise : std_logic; -- Output from m1 state machine.
signal fall,n_fall : std_logic; -- Output from m1 state machine.
signal output_strobe : std_logic; -- Latches data data into the output registers
signal packet_good : std_logic;--check the whether the data is valid
--signal x_increment : std_logic_vector(8 downto 0);
--signal y_increment : std_logic_vector(7 downto 0);
signal mouseyy,mousexx : std_logic_vector(9 downto 0);
begin
ps2_clk <= '0' when ps2_clk_hi_z='0' else 'Z';
ps2_data <= '0' when ps2_data_hi_z='0' else 'Z';
------------------------------------
--detect ps2clk falling and rising edge
------------------------------------
detect_ps2clkfall : process(clk,reset,ps2_clk)
begin
if reset='0' then
fallsig <= "000";
elsif clk'event and clk='1' then
fallsig(0) <= ps2_clk;
fallsig(1) <= fallsig(0);
fallsig(2) <= fallsig(1);
end if;
end process;
fall <= '1' when fallsig="110" else '0';
detect_ps2clkrise : process(clk,reset,ps2_clk)
begin
if reset='0' then
risesig <= "000";
elsif clk'event and clk='1' then
risesig(0) <= ps2_clk;
risesig(1) <= risesig(0);
risesig(2) <= risesig(1);
end if;
end process;
rise <= '1' when risesig="001" else '0';
--------------------------------------
------------------m2 State
m2statech: process (reset, clk)
begin
if (reset='0') then
m2_state <= m2_reset;
elsif (clk'event and clk='1') then
m2_state <= m2_next_state;
end if;
end process;
--m2 State transition logic
m2statetr: process (m2_state, fall,watchdog_timer_done,bitcount,ps2_data,packet_good)
begin
-- Output signals default to this value, unless changed in a state condition.
ps2_clk_hi_z <= '1';
ps2_data_hi_z <= '1';
error_no_ack <= '0';
output_strobe <= '0';
--data_out <= '0';
case m2_state is
when m2_reset => -- After reset, sends command to mouse.
m2_next_state <= m2_hold_clk_l;
when m2_wait =>
if (fall='1') then
m2_next_state <= m2_gather;
else
m2_next_state <= m2_wait;
end if;
when m2_gather =>
if (watchdog_timer_done='1') then -- and (bitcount=TOTAL_BITS)
m2_next_state <= m2_verify;
else
m2_next_state <= m2_gather;
end if;
when m2_verify =>
--if (bitcount < TOTAL_BITS) then --replace " packet_good='1' "
--m2_next_state <= m2_wait;
--else
m2_next_state <= m2_use;
--end if;
when m2_use =>
output_strobe <= '1';
m2_next_state <= m2_wait;
-- The following sequence of 9 states is designed to transmit the
-- "enable streaming mode" command to the mouse, and then await the
-- response from the mouse.
when m2_hold_clk_l =>
ps2_clk_hi_z <= '0'; -- This starts the watchdog timer!
if (watchdog_timer_done='1') then -- cut "and (clean_clk='0')"
m2_next_state <= m2_data_low_1;
else
m2_next_state <= m2_hold_clk_l;
end if;
when m2_data_low_1 =>
ps2_data_hi_z <= '0'; -- Forms start bit, d[0] and d[1]
--data_out <= '0';
if (fall='1' and (bitcount = 2)) then
m2_next_state <= m2_data_high_1;
else
m2_next_state <= m2_data_low_1;
end if;
when m2_data_high_1 =>
ps2_data_hi_z <= '1'; -- Forms d[2]
--data_out <= '1';
if (fall='1' and (bitcount = 3)) then
m2_next_state <= m2_data_low_2;
else
m2_next_state <= m2_data_high_1;
end if;
when m2_data_low_2 =>
ps2_data_hi_z <= '0'; -- Forms d[3]
--data_out <= '0';
if (fall='1' and (bitcount = 4)) then
m2_next_state <= m2_data_high_2;
else
m2_next_state <= m2_data_low_2;
end if;
when m2_data_high_2 =>
ps2_data_hi_z <= '1'; -- Forms d[4],d[5],d[6],d[7]
--data_out <= '1';
if (fall='1' and (bitcount = 8)) then
m2_next_state <= m2_data_low_3;
else
m2_next_state <= m2_data_high_2;
end if;
when m2_data_low_3 =>
ps2_data_hi_z <= '0'; -- Forms parity bit
--data_out <= '0';
if (fall='1') then
m2_next_state <= m2_data_high_3;
else
m2_next_state <= m2_data_low_3;
end if;
when m2_data_high_3 =>
ps2_data_hi_z <= '1'; -- Allow mouse to pull low (ack pulse)
if (fall='1' and (ps2_data='1')) then
m2_next_state <= m2_error_no_ack;
elsif (fall='1' and (ps2_data='0')) then
m2_next_state <= m2_await_response;
else
m2_next_state <= m2_data_high_3;
end if;
when m2_error_no_ack =>
error_no_ack <= '1';
m2_next_state <= m2_error_no_ack;
-- In order to "cleanly" exit the setting of the mouse into "streaming"
-- data mode, the state machine should wait for a long enough time to
-- ensure the FA response is done being sent by the mouse.
when m2_await_response =>
--if (bitcount = 22) then
m2_next_state <= m2_verify;
--else
-- m2_next_state <= m2_await_response;
--end if;
when others => m2_next_state <= m2_wait;
end case;
end process;
-----------------------------end m2 state
--This is the bit counter
bitcoun: process (reset, clk)
begin
if (reset='0') then
bitcount <= (others=>'0'); -- normal reset
elsif (clk'event and clk='1') then
if (fall='1') then
bitcount <= bitcount + 1;
elsif (watchdog_timer_done='1') then
bitcount <= (others=>'0'); -- rx watchdog timer reset
end if;
end if;
end process;
-- This is the shift data register
dataseq: process (reset, clk)
begin
if (reset='0') then
q <= (others=>'0');
elsif (clk'event and clk='1') then
if (fall='1') then
q <= ps2_data & q(TOTAL_BITS-1 downto 1);
end if;
end if;
end process;
-- This is the watchdog timer counter
-- The watchdog timer is always "enabled" to operate.
watchcount: process (reset,rise,fall, clk)
begin
if ((reset='0') or (rise='1') or (fall='1')) then
watchdog_timer_count <= (others=>'0');
elsif (clk'event and clk='1') then
if (watchdog_timer_done='0') then
watchdog_timer_count <= watchdog_timer_count + 1;
end if;
end if;
end process;
watchdog_timer_done <= '1' when (watchdog_timer_count=WATCHDOG-1) else '0';
--This is the logic to verify that a received data packet is "valid" or good.
packet_good <= '1';
-- Output the special scan code flags, the scan code and the ascii
outdata: process (reset, clk)
begin
if (reset='0') then
left_button <= '0';
right_button <= '0';
--x_increment <= (others=>'0');
--y_increment <= (others=>'0');
elsif (clk'event and clk='1') then
if (output_strobe='1') then
left_button <= q(1);
right_button <= q(2);
--x_increment <= '0' & q(19 downto 12);
mouseyy <= not (q(6) & q(6) & q(30 downto 23)) + "1";
mousexx <= q(5) & q(5) & q(19 downto 12);
end if;
end if;
end process;
cordinatex: process (reset, clk)
begin
if (reset='0') then
mousex <= "0110010000"; -- 400
elsif (clk'event and clk='1') then
if (output_strobe='1') then
if (mousex >= 599 and q(5)='0') then
mousex <= "1001010111";
elsif (mousex <= 40 and q(5)='1') then
mousex <= "0000101000";
else
mousex <= mousex + (q(5) & q(5) & q(19 downto 12));--q(5):xsign q(6):ysign
end if;
end if;
end if;
end process;
cordinatey: process (reset, clk)
begin
if (reset='0') then
mousey <= "0100101100"; -- 300
elsif (clk'event and clk='1') then
if (output_strobe='1') then
if (mousey >= 449 and q(6)='1') then
mousey <= "0111000001";
elsif (mousey <= 30 and q(6)='0') then
mousey <= "0000011110";
else
mousey <= mousey + mouseyy; --(q(6) & q(6) & q(30 downto 23));
end if;
end if;
end if;
end process;
mov_x <= mousexx;
data_ready <= output_strobe;
end Behavioral;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -