FILES DOWNLOAD
MASTER MODULE PS2 MOUSE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mouse_led is
port (
clk, reset: in std_logic;
ps2d, ps2c : inout std_logic;
led: out std_logic_vector ( 7 downto 0)
) ;
end mouse_led;
architecture arch of mouse_led is
signal p_reg , p_next : unsigned (9 downto 0 ) ;
signal xm: std_logic_vector (8 downto 0 ) ;
signal m_done_tick: std_logic;
signal btnm: std_logic_vector (2 downto 0) ;
begin
-- in s t a n t i a t i o n
mouse_unit: entity work.mouse(arch)
port map(clk=>clk, reset=>reset ,
ps2d=>ps2d, ps2c=>ps2c,
xm=>xm, ym=>open , btnm=>btnm ,
m_done_tick=>m_done_tick);
-- r e g is t e r
process (clk , reset)
begin
if reset= '1' then
p_reg <= ( others => '0' ) ;
elsif (clk'event and clk='1') then
p_reg <= p_next;
end if ;
end process ;
-- c o u n t e r
p_next <= p_reg when m_done_tick= '0' else
"0000000000" when btnm(0)='1' else -- l e f t b u t t o n
"1111111111" when btnm(1)='1' else -- r i g h t b u t t o n
p_reg + unsigned(xm(8) & xm);
with p_reg(9 downto 7) select
led <=
"10000000" when "000",
"01000000" when "001",
"00100000" when "010",
"00010000" when "011",
"00001000" when "100",
"00000100" when "101",
"00000010" when "110",
"00000001" when others;
end arch;
FINITE STATE MACHINE MOUSE MODULE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mouse is
port (
clk, reset: in std_logic;
ps2d, ps2c : inout std_logic ;
xm, ym: out std_logic_vector ( 8 downto 0 ) ;
btnm: out std_logic_vector (2 downto 0 ) ;
m_done_tick : out std_logic
) ;
end mouse;
architecture arch of mouse is
constant STRM: std_logic_vector ( 7 downto 0 ) := "11110100" ;
-- stream command F4
type state_type is (init1, init2, init3,
pack1 , pack2, pack3, done) ;
signal state_reg , state_next : state_type;
signal rx_data: std_logic_vector ( 7 downto 0 ) ;
signal rx_done_tick , tx_done_tick: std_logic;
signal wr_ps2 : std_logic;
signal x_reg , y_reg : std_logic_vector ( 8 downto 0) ;
signal x_next , y_next : std_logic_vector (8 downto 0 ) ;
signal btn_reg , btn_next : std_logic_vector ( 2 downto 0 ) ;
begin
-- in s t a n t i a t i o n
ps2_rxtx_unit : entity work.ps2_rxtx (arch)
port map(clk=>clk , reset=>reset , wr_ps2=>wr_ps2,
din=>STRM , dout=>rx_data ,
ps2d=>ps2d, ps2c=>ps2c,
rx_done_tick=>rx_done_tick,
tx_done_tick=>tx_done_tick);
--s t a t e and d a t a r e g is t e r s
process (clk, reset)
begin
if reset = '1' then
state_reg <= init1;
x_reg <= ( others =>'0' ) ;
y_reg <= ( others => '0' ) ;
btn_reg <= ( others => '0' ) ;
elsif (clk'event and clk='1') then
state_reg <= state_next ;
x_reg <= x_next;
y_reg <= y_next;
btn_reg <= btn_next ;
end if ;
end process ;
-- n e x t - s t a t e 1 o g i c
process (state_reg ,rx_done_tick, tx_done_tick,
x_reg ,y_reg, btn_reg, rx_data)
begin
wr_ps2 <= '0' ;
m_done_tick <= '0' ;
x_next <= x_reg;
y_next <= y_reg;
btn_next <= btn_reg ;
state_next <= state_reg;
case state_reg is
when init1 =>
wr_ps2 <= '1';
state_next <= init2 ;
when init2 => -- w a i t f o r s e n d t o c o m p l e t e
if tx_done_tick = '1' then
state_next <= init3 ;
end if ;
when init3 => -- w a i t f o r a c k n o w l e d g e p a c k e t
if rx_done_tick = '1' then
state_next <= pack1 ;
end if ;
when pack1 => -- w a i t f o r 1 s t d a t a p a c k e t
if rx_done_tick = '1' then
state_next <= pack2 ;
y_next ( 8 ) <= rx_data ( 5 ) ;
x_next (8) <= rx_data ( 4 ) ;
btn_next <= rx_data ( 2 downto 0 ) ;
end if ;
when pack2 => -- w a i t f o r 2 n d d a t a p a c k e t
if rx_done_tick = '1' then
state_next <= pack3 ;
x_next ( 7 downto 0) <= rx_data ;
end if ;
when pack3 => -- w a i t f o r 3 r d d a t a p a c k e t
if rx_done_tick = '1' then
state_next <= done ;
y_next ( 7 downto 0 ) <= rx_data ;
end if ;
when done =>
m_done_tick <= '1' ;
state_next <= pack1 ;
end case ;
end process ;
xm <= x_reg ;
ym <= y_reg ;
btnm <= btn_reg ;
end arch ;
RX TX MODULE
library ieee;
use ieee.std_logic_1164.all;
entity ps2_rxtx is
port (
clk, reset: in std_logic;
wr_ps2 : std_logic;
din: in std_logic_vector ( 7 downto 0) ;
dout : out std_logic_vector ( 7 downto 0 ) ;
rx_done_tick : out std_logic ;
tx_done_tick: out std_logic;
ps2d, ps2c : inout std_logic
);
end ps2_rxtx;
architecture arch of ps2_rxtx is
signal tx_idle : std_logic;
begin
ps2_tx_unit : entity work.ps2_tx
port map(clk=>clk, reset=>reset , wr_ps2=>wr_ps2,
din=>din, ps2d=>ps2d, ps2c=>ps2c,
tx_idle=>tx_idle, tx_done_tick=>tx_done_tick);
ps2_rx_unit : entity work.ps2_rx(arch)
port map(clk=>clk , reset=>reset , rx_en=>tx_idle,
ps2d=>ps2d, ps2c=>ps2c,
rx_done_tick=>rx_done_tick, dout=>dout);
end arch;
TX FSM MODULE
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ps2_tx is
port (
clk, reset: in std_logic;
din: in std_logic_vector (7 downto 0) ;
wr_ps2: std_logic;
ps2d, ps2c : inout std_logic ;
tx_idle: out std_logic;
tx_done_tick: out std_logic
) ;
end ps2_tx;
architecture arch of ps2_tx is
type statetype is (idle, rts, start, data, stop);
signal state_reg , state_next: statetype;
signal filter_reg , filter_next : std_logic_vector ( 7 downto 0 ) ;
signal f_ps2c_reg ,f_ps2c_next: std_logic;
signal b_reg , b_next : std_logic_vector (8 downto 0 ) ;
signal c_reg , c_next : unsigned (12 downto 0) ;
signal n_reg ,n_next : unsigned (3 downto 0) ;
signal par: std_logic;
signal tri_c , tri_d: std_logic ;
signal fall_edge : std_logic ;
signal ps2c_out , ps2d_out : std_logic;
begin --__ ______________________-_--____________________________________________-_--_-_--_--_- _ _ _ ~ ~ ~ ~ ~ _ ~ ~ ~
-- f i l t e r a n d f a l l i n g - e d g e t i c k g e n e r a t i o n f o r ps2c
--. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
process (clk , reset)
begin
if reset= '1' then
filter_reg <= ( others => '0' ) ;
f_ps2c_reg <= '0' ;
elsif (clk'event and clk= '1' ) then
filter_reg <= filter_next;
f_ps2c_reg <= f_ps2c_next;
end if;
end process;
filter_next <= ps2c & filter_reg ( 7 downto 1);
f_ps2c_next <= '1' when filter_reg = "11111111" else
'0' when filter_reg = "00000000" else
f_ps2c_reg ;
fall_edge <= f_ps2c_reg and ( not f_ps2c_next ) ;
-- f s m d
-- registers
process ( clk , reset)
begin
if reset = '1' then
state_reg <= idle ;
c_reg <= ( others => '0' ) ;
n_reg <= ( others => '0' ) ;
b_reg <= ( others => '0' ) ;
elsif ( clk'event and clk = '1' ) then
state_reg <= state_next ;
c_reg <= c_next ;
n_reg <= n_next ;
b_reg <= b_next ;
end if ;
end process ;
-- odd par i t y b i t
par <= not ( din (7) xor din (6) xor din (5) xor din (4) xor
din (3) xor din (2) xor din (1) xor din (0) );
-- f s m d n e x t - s t a t e l o g i c and data p a t h l o g i c
process ( state_reg , n_reg , b_reg , c_reg , wr_ps2 ,
din , par , fall_edge )
begin
state_next <= state_reg ;
c_next <= c_reg ;
n_next <= n_reg ;
b_next <= b_reg ;
tx_done_tick <= '0' ;
ps2c_out <= '1';
ps2d_out <= '1' ;
tri_c <= '0' ;
tri_d <= '0' ;
tx_idle <= '0' ;
case state_reg is
when idle =>
tx_idle <= '1' ;
if wr_ps2 = '1' then
b_next <= par & din ;
c_next <= ( others => '1' ) ; -- 2 * 1 3 - 1
state_next <= rts ;
end if ;
when rts => -- r e q u e s t t o s e n d
ps2c_out <= '0' ;
tri_c <= '1';
c_next <= c_reg - 1;
if(c_reg = 0 ) then
state_next <= start ;
end if ;
when start => -- a s s e rtstart bit
ps2d_out <= '0' ;
tri_d <= '1' ;
if fall_edge = '1' then
n_next <= "1000" ;
state_next <= data ;
end if ;
when data => -- 8 data + I par i t y
ps2d_out <= b_reg (0) ;
tri_d <= '1' ;
if fall_edge = '1' then
b_next <= '0' & b_reg ( 8 downto 1);
if n_reg = 0 then
state_next <= stop ;
else
n_next <= n_reg - 1;
end if ;
end if ;
when stop => -- assume f l o a t i n g h i g h f o r ps2d
if fall_edge = '1' then
state_next <= idle ;
tx_done_tick <='1';
end if ;
end case ;
end process ;
--tri_state_buffers
ps2c <= ps2c_out when tri_c = '1' else 'Z' ;
ps2d <= ps2d_out when tri_d = '1' else 'Z' ;
--
end arch ;
RX FSM MODULE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity ps2_rx is
port (
clk, reset: in std_logic;
ps2d, ps2c: in std_logic; -- k e y d a t a , k e y c l o c k
rx_en : in std_logic ;
rx_done_tick: out std_logic;
dout: out std_logic_vector (7 downto 0)
) ;
end ps2_rx;
architecture arch of ps2_rx is
type statetype is (idle, dps, load);
signal state_reg , state_next : statetype;
signal filter_reg , filter_next : std_logic_vector (7 downto 0 ) ;
signal f_ps2c_reg, f_ps2c_next : std_logic ;
signal n_reg , n_next : unsigned (3 downto 0) ;
signal fall_edge : std_logic ;
signal b_reg , b_next : std_logic_vector (10 downto 0 ) ;
begin
--______________________________________________________________________________________-_-_--_-_--_ __
-- f i l t e r and f a l l i n g e d g e t i c k g e n e r a t i o n f o r ps2c
process ( clk , reset )
begin
if reset = '1' then
filter_reg <= ( others => '0' ) ;
f_ps2c_reg <= '0' ;
elsif ( clk'event and clk = '1' ) then
filter_reg <= filter_next ;
f_ps2c_reg <= f_ps2c_next ;
end if ;
end process ;
filter_next <= ps2c & filter_reg ( 7 downto 1);
f_ps2c_next <= '1' when filter_reg = "11111111" else
'0' when filter_reg = "00000000" else
f_ps2c_reg ;
fall_edge <= f_ps2c_reg and ( not f_ps2c_next ) ;
--______-_______-_-_-_-_-_-_-__-_---_--_------_--_--- --------------
--45 -- f s m d t o e x t r a c t t h e 8 - b i t d a t a
--____ _-______-______-_-________________________-_-______-____-_-__-_--------------- ---------_-_------
---_ r e g is t e r s
process ( clk , reset )
begin
if reset = '1' then
state_reg <= idle ;
n_reg <= ( others => '0' ) ;
b_reg <= ( others => '0' ) ;
elsif ( clk'event and clk = '1' ) then
state_reg <= state_next ;
n_reg <= n_next ;
b_reg <= b_next ;
end if ;
end process ;
-- n e x t - s t a t e l o g i c
process ( state_reg , n_reg,b_reg, fall_edge , rx_en , ps2d )
begin
rx_done_tick <= '0' ;
state_next <= state_reg ;
n_next <= n_reg ;
b_next <= b_reg ;
case state_reg is
when idle =>
if fall_edge = '1' and rx_en = '1' then
--s h if t i n s t a r t b i t
b_next <= ps2d & b_reg ( 10 downto 1);
n_next <= "1001" ;
state_next <= dps ;
end if ;
when dps => -- 8 d a t a + I p a r i t y + 1 s t o p
if fall_edge = '1' then
b_next <= ps2d & b_reg ( 10 downto 1 ) ;
if n_reg = 0 then
state_next <= load ;
else
n_next <= n_reg - 1;
end if ;
end if ;
when load =>
-- I e x t r a c l o c k t o c o m p l e t e f h e l a s t s h if t
state_next <= idle ;
rx_done_tick <='1';
end case ;
end process ;
-- o u t p u t
dout <= b_reg ( 8 downto 1); -- d a t a b i t s
end arch ;
CONSTRAINT FILE
#Created by Constraints Editor (xc3s250e-tq144-4) - 2017/07/29
NET "clk" LOC = "P129"; #TNM_NET = clk;
TIMESPEC TS_clk = PERIOD "clk" 50 MHz HIGH 50%;
#8I/Os_2 (Input)
NET "reset" LOC = "p124" ;
#16I/Os_1 (output)
NET "ps2d" LOC = "p126" ;
NET "ps2c" LOC = "p125" ;
#16I/Os_1 (output)
NET "led[0]" LOC = "p94" ;
NET "led[1]" LOC = "p93" ;
NET "led[2]" LOC = "p92" ;
NET "led[3]" LOC = "p91" ;
NET "led[4]" LOC = "p88" ;
NET "led[5]" LOC = "p87" ;
NET "led[6]" LOC = "p86" ;
NET "led[7]" LOC = "p85" ;
TUTORIAL ON HOW TO ADD CLOCK TIMING CONSTRAINTS IN A MODULE
No comments:
Post a Comment