|
CPLD MAXII 1270 PS/2 Keyboard 程式問題
% n5 I2 r* ]0 h$ E( X* C我在網路上收尋到FPGA 收 PS/2 Keyboard程式,將程式套用在CPLD上,Compiler後,無問題,依照程式將Pin腳定義,提供系統CLK,Reset,和PS/2 CLK,PS/2 Data,將DoRead和Scan_DAV(偵測PS/2是否送出信號)相接,Scan_Err接一顆LED(險示Overflow錯誤),Scan_Code接8顆LED(顯示PS/2 8bit Data),但燒錄後,CPLD啟動後,按鍵按下,毫無反應,並且PS/2 CLOCK信號已被降至低準位,似乎鍵盤已被抑制送出信號,請高手們幫忙提供意見好嗎?感謝......8 ^$ {6 H: C. g0 [
程式:
6 s9 A% b% _, w4 v-- PS2_Ctrl.vhd+ d. }, W8 H" j
-- ------------------------------------------------
& Z/ C5 ]. a2 [6 L. Q l4 X+ y-- Simplified PS/2 Controller (kbd, mouse...)5 g) K! L; H: P9 u+ W3 Q
-- ------------------------------------------------2 P2 @6 u7 u3 l
-- Only the Receive function is implemented !0 P1 ~( r: m, b5 O: r$ H& v
-- (c) ALSE. http://www.alse-fr.com
7 {( v$ R( f" Klibrary IEEE;
5 Z u; v9 P" ]7 Z0 X' suse IEEE.STD_LOGIC_1164.all;, d3 Q2 u! a. k1 F9 R
use IEEE.Numeric_std.all;. F" k0 n+ s- j- T! V
-- --------------------------------------3 N, L: [/ |* J5 }) V) z6 ^' j/ |# Z) _
Entity PS2_Ctrl is. Y% u% }8 C* V R; [
-- --------------------------------------
( _' e' ? d* E* N n9 Ngeneric (FilterSize : positive := 8);
- V ?' B" }- c3 Z; Q& X4 {port( Clk : in std_logic; -- System Clock' D! U4 Y) \# P
Reset : in std_logic; -- System Reset. z# \/ F7 N* s
PS2_Clk : in std_logic; -- Keyboard Clock Line
& O' Z' \1 z9 j1 g4 uPS2_Data : in std_logic; -- Keyboard Data Line' L8 A; @( [4 {- r' }8 n# N
DoRead : in std_logic; -- From outside when reading the scan code8 n- d2 ^ _* C2 [( B3 f
Scan_Err : out std_logic; -- To outside : Parity or Overflow error
E! V" x. Z# GScan_DAV : out std_logic; -- To outside when a scan code has arrived
% n, X6 v Y: WScan_Code : out std_logic_vector(7 downto 0) -- Eight bits Data Out
9 L! S! ~/ Q% `, J6 W; x6 ?4 `);
6 G5 {3 R- G/ p% n& q- }end PS2_Ctrl;
% z I/ j2 h% [-- --------------------------------------, h! q& ?8 x/ t# J
Architecture ALSE_RTL of PS2_Ctrl is
3 g9 K$ u- H( r, t2 H-- --------------------------------------
+ t2 [- r" P( b( A' ~9 V" m% V+ `/ @-- (c) ALSE. http://www.alse-fr.com1 g" u }8 ~" r9 J; J& F% x# k
-- Author : Bert Cuzeau.
G& u- r% ?/ t-- Fully synchronous solution, same Filter on PS2_Clk.5 a2 R _0 E4 c% F' q2 D, D4 c% ^; l
-- Still as compact as "Plain_wrong"...1 Y7 q5 @6 _% a8 i! y( a
-- Possible improvement : add TIMEOUT on PS2_Clk while shifting
3 h( @5 n! J0 q( ]' l2 K-- Note: PS2_Data is resynchronized though this should not be& ~# x( ]( m5 p4 G5 b5 @$ j
-- necessary (qualified by Fall_Clk and does not change at that time).
( X# o( D% K. w-- Note the tricks to correctly interpret 'H' as '1' in RTL simulation.
5 f5 `9 H7 {+ u. z' M( fsignal PS2_Datr : std_logic;. }! z( L7 J3 Q7 O' Y }
subtype Filter_t is std_logic_vector(FilterSize-1 downto 0);
' ~1 f* V+ [% Ssignal Filter : Filter_t;6 [, P- a- h/ _: B3 z% f
signal Fall_Clk : std_logic;' z! O/ P5 m" a
signal Bit_Cnt : unsigned (3 downto 0);( U% r7 k, a. r# D" h: S% s4 j! t
signal Parity : std_logic;
2 `' O9 u0 j i' usignal Scan_DAVi : std_logic;
0 ~; s; U! z9 H/ Csignal S_Reg : std_logic_vector(8 downto 0);* s$ E' d! F, T2 A" G0 m, u3 b
signal PS2_Clk_f : std_logic;
, A" Y; s: \' p5 S% p. b* lType State_t is (Idle, Shifting);. F) S0 Q$ d/ }) [2 d F
signal State : State_t;* a) [: v9 w3 ]1 t [; e" Y9 C$ R
begin
; n/ v: \- F% M* H0 |: y0 JScan_DAV <= Scan_DAVi;0 V3 V# K& f: N1 R0 ]
-- This filters digitally the raw clock signal coming from the keyboard :
+ I* H7 p# l- J( m1 t" a' p-- * Eight consecutive PS2_Clk=1 makes the filtered_clock go high
4 z# N9 ^! L Q5 c5 z6 t- }( Q& O-- * Eight consecutive PS2_Clk=0 makes the filtered_clock go low
, }4 p) V7 a" D7 n8 i-- Implies a (FilterSize+1) x Tsys_clock delay on Fall_Clk wrt Data
( a; T6 h$ I" e-- Also in charge of the re-synchronization of PS2_Data, U, k" u- H( g7 z) }/ A
process (Clk,Reset)6 ?/ b; A' G$ p# r
begin/ `0 T( g3 d) l y% V5 u
if Reset='1' then
# z4 ^# q" m( J! |9 q/ f6 |) JPS2_Datr <= '0';" z6 {3 _% ]# U1 U( e9 {/ v
PS2_Clk_f <= '0';
" ?% M, W; S* \# m3 r7 H- u* U' OFilter <= (others=>'0');
6 ~ R- ^! r( @7 t" r: }Fall_Clk <= '0';1 P( w# \7 v6 G4 S x
elsif rising_edge (Clk) then6 [# B8 D9 T% f- O4 Z9 \
PS2_Datr <= PS2_Data and PS2_Data; -- also turns 'H' into '1') J2 {5 o0 z. D5 d2 f5 ]
Fall_Clk <= '0';0 L* N! }9 i8 v$ W. ?, D0 O& F3 O
Filter <= (PS2_Clk and PS2_CLK) & Filter(Filter'high downto 1);
. s. k3 n- N( M2 ~if Filter = Filter_t'(others=>'1') then
( u+ s) Z- Z( @- Y2 `3 MPS2_Clk_f <= '1';6 U# u( f; B: }' v a9 W+ r7 l: ~
elsif Filter = Filter_t'(others=>'0') then6 ^% O" ~6 l# r/ w& V0 r5 H. ?7 j
PS2_Clk_f <= '0';! S. M0 K! Z9 y$ M. W1 W
if PS2_Clk_f = '1' then) G% c- T7 U6 q {' x
Fall_Clk <= '1';
: Y4 L' ]4 @" Q/ K+ qend if;; K j) r# L% q! g# {
end if;2 F$ N/ v. y$ G/ ~4 j1 j
end if;: j( @& p0 ^6 H2 B' o9 @
end process;8 X' z- ~0 Q/ y% ^
-- This simple State Machine reads in the Serial Data
2 I' K D3 q$ B. s$ T7 c& e-- coming from the PS/2 peripheral.% ~7 u7 N0 m" i6 U) b+ d4 b m+ ^% Y
process(Clk,Reset)( U9 B; U0 W5 h% m/ }) n9 L. R6 t
begin+ F1 ]) c2 L/ C8 i
if Reset='1' then/ L0 s' Z7 |2 g7 N# w
State <= Idle;& \( |+ U4 p, G3 _: s! i
Bit_Cnt <= (others => '0');$ s5 `) `( ^) @1 w! ?, f
S_Reg <= (others => '0');" y: o* m9 S. I& L) @# H/ g& _
Scan_Code <= (others => '0');0 g* t8 o1 y+ q. }
Parity <= '0';
1 L0 Y2 \+ o! ~) r3 @% bScan_Davi <= '0';
d: L5 W, ^0 h9 k: t5 gScan_Err <= '0';
+ E1 X! `1 |; h5 Velsif rising_edge (Clk) then6 E. T' |" l, ]6 e6 Q1 I
if DoRead='1' then: }6 ?% G' a. b+ t* l
Scan_Davi <= '0'; -- note: this assgnmnt can be overriden% g6 |+ y% S- ?: g9 a+ N( b$ Y
end if;5 X* C$ m0 H+ h" Z
case State is
( F+ F) ^; ^0 r3 y2 xwhen Idle =>" n+ y- e8 C9 v/ K
Parity <= '0';
! @7 ]2 J" Z0 w- U. W3 rBit_Cnt <= (others => '0');0 C; u- e% ~- n o8 P
-- note that we dont need to clear the Shift Register
1 U* P6 j3 A! Tif Fall_Clk='1' and PS2_Datr='0' then -- Start bit+ F( S- ] s7 s$ K/ A: e
Scan_Err <= '0';
5 g: w: j5 \7 q, D1 e7 T* aState <= Shifting;
6 v: i+ M" O1 f' ]& x& dend if;
: D: X) _! ]4 hwhen Shifting =>8 O3 w* Z. A: y4 x
if Bit_Cnt >= 9 then
7 ~1 f: f! n+ F* y R3 Bif Fall_Clk='1' then -- Stop Bit
8 u- i6 F# w& G [% a-- Error is (wrong Parity) or (Stop='0') or Overflow
. @( Q9 p7 ^2 M$ I2 z: b2 U+ r* B4 x9 sScan_Err <= (not Parity) or (not PS2_Datr) or Scan_DAVi;* S% \( j& s9 z) k1 J2 y
Scan_Davi <= '1';% b0 r2 W; Y% L: m1 G
Scan_Code <= S_Reg(7 downto 0);
, @/ l! o: S, `. VState <= Idle;0 `. Y" i: Z% ^# F6 I
end if;3 p* u3 @, N9 A Q& Z/ O4 {, \+ U, e
elsif Fall_Clk='1' then
$ ]4 G( g7 j( b5 k4 n. PBit_Cnt <= Bit_Cnt + 1;
$ M5 ?3 M" T" u/ K1 [' v( mS_Reg <= PS2_Datr & S_Reg (S_Reg'high downto 1); -- Shift right
, V. {; r% _6 s% ]& H: Y* _Parity <= Parity xor PS2_Datr;
4 b% o! k: Y+ ]end if;
; f/ T% O. m+ W; ]/ k( cwhen others => -- never reached- k- P6 p5 W& g- D0 N v4 e1 ?+ F
State <= Idle;
- \0 Z- r! R7 A0 d: g) i) v$ fend case;
% ]) X" L4 |4 A3 e8 Y# i; R, |end if;$ [9 `7 k9 d* N7 O- m- ]& b
end process;; P/ r. a6 M* o' h5 i/ L4 i) r" _; ^
end ALSE_RTL; |
|