Chip123 科技應用創新平台

標題: VHDL PS/2 Keyboard 程式問題..thx [打印本頁]

作者: ghoustchieh    時間: 2008-1-23 05:29 PM
標題: VHDL PS/2 Keyboard 程式問題..thx
目前需要使用MAXII 1270 做PS/2 Keyboard控制,在網路上找到了用VHDL寫PS/2介面,經過測試後正常,但輸出是8個Pin輸出(並聯),但我希望輸出為1個Pin(串聯)輸出,請問我該如果修改程式呢?請大家幫幫忙,給個意見,或者提供任何資料參考...thx
- k2 s2 M. F4 M- H4 Q' u( C3 I, V( Z) t1 h) [
程式如下:! e' E! ~% {+ E  Q0 h9 Y5 u
-- PS2_Ctrl.vhd! `- I4 k8 K. X% {* d
-- ------------------------------------------------% h" E, }! g$ ]) q8 N/ d  N4 z
-- Simplified PS/2 Controller (kbd, mouse...)( G5 v- u" G8 \- ?/ C' L0 ]
-- ------------------------------------------------7 D1 q4 W/ n; D# p
-- Only the Receive function is implemented !( Q/ K2 q# G8 M) n# Q$ y
-- (c) ALSE. http://www.alse-fr.com
1 `( v$ ]1 `$ a; `3 \library IEEE;, Z" `% ]4 R- m/ s0 w  f1 M
use IEEE.STD_LOGIC_1164.all;# _) a+ X( y. c% l7 d
use IEEE.Numeric_std.all;4 `- l" _( {( u) p2 G& W
-- --------------------------------------
  M0 ]2 o1 W, U7 kEntity PS2_Ctrl is
: Q! X) {' e, r( S  u" K-- --------------------------------------1 _5 F4 v) R. [/ \3 D
generic (FilterSize : positive := 8);( v. z* \6 X3 j9 Y: ]
port( Clk : in std_logic; -- System Clock
3 o- ?' T: {: P- V; K' [Reset : in std_logic; -- System Reset' h3 w9 i+ I, Y+ x5 d/ {9 K
PS2_Clk : in std_logic; -- Keyboard Clock Line* B5 u( B& c; @/ \
PS2_Data : in std_logic; -- Keyboard Data Line
, O1 U7 i& r3 o- G9 QDoRead : in std_logic; -- From outside when reading the scan code
3 ^( T" w& l  i$ {Scan_Err : out std_logic; -- To outside : Parity or Overflow error
" o- G3 I' }/ G* T6 B9 \5 N6 a; ?Scan_DAV : out std_logic; -- To outside when a scan code has arrived2 u  ?* R9 e6 Q7 S4 U+ h& Y! L4 E" k
Scan_Code : out std_logic_vector(7 downto 0) -- Eight bits Data Out
$ ?* {% x  f) `( x* h- j);. g# _5 Z0 M( p$ k: H. y. a
end PS2_Ctrl;
+ F/ w/ z1 V9 A-- --------------------------------------
3 @$ j* e' E( Z; L* \5 B7 a0 ^Architecture ALSE_RTL of PS2_Ctrl is
2 a( b- |" A' b: N0 q+ \8 s-- --------------------------------------
. c+ K+ X% p2 }( F, }2 \-- (c) ALSE. http://www.alse-fr.com
  a6 ^1 o0 w) `7 `: G+ `; `-- Author : Bert Cuzeau.& Z. X4 m3 |" ?" R3 Q" G7 U: T
-- Fully synchronous solution, same Filter on PS2_Clk.
' m* ]2 p: x4 d" |# o-- Still as compact as "Plain_wrong"...
3 `% d. N+ e' c- n3 Z-- Possible improvement : add TIMEOUT on PS2_Clk while shifting/ \# @7 G+ y: \  r, i
-- Note: PS2_Data is resynchronized though this should not be
1 Z/ L  F  q$ n4 b& K1 S5 m/ |-- necessary (qualified by Fall_Clk and does not change at that time).
9 l2 x, d4 I# @2 o8 Y5 B* d) R-- Note the tricks to correctly interpret 'H' as '1' in RTL simulation.: u  N3 E6 r+ F, E4 w( E
signal PS2_Datr : std_logic;$ l* K) A- F' z2 f( S
subtype Filter_t is std_logic_vector(FilterSize-1 downto 0);( u  Q- G0 W0 b/ ^  T. C/ j
signal Filter : Filter_t;& F8 X$ p# _9 z9 ^' f8 P$ J
signal Fall_Clk : std_logic;
& ~, i- F! Q' _! F. Msignal Bit_Cnt : unsigned (3 downto 0);
6 ~3 t2 |5 M' Y0 x' i9 X; ?, Esignal Parity : std_logic;
, Q( i5 K& Y2 ~: \9 j3 k+ ysignal Scan_DAVi : std_logic;/ R8 \  b" x0 J* @
signal S_Reg : std_logic_vector(8 downto 0);- j+ E/ U% w5 P' D3 Y, q5 X9 [6 J
signal PS2_Clk_f : std_logic;
/ ]+ J1 u" O8 {% I3 v6 Q" a5 FType State_t is (Idle, Shifting);
& w4 d* L  U, c4 k& y1 k4 O; A1 A' hsignal State : State_t;1 l: `7 C3 {# R6 p- i1 M, r
begin
8 `( D' X# l- |5 [4 [Scan_DAV <= Scan_DAVi;
# T. k0 g8 W( A" j7 u1 F, g-- This filters digitally the raw clock signal coming from the keyboard :, ^0 Y, E  b1 j0 E5 h' L: r
-- * Eight consecutive PS2_Clk=1 makes the filtered_clock go high
0 B. C7 |8 a% A3 h, N. X8 X% V-- * Eight consecutive PS2_Clk=0 makes the filtered_clock go low
+ I8 w% I. d, i! y-- Implies a (FilterSize+1) x Tsys_clock delay on Fall_Clk wrt Data7 v7 r8 S$ m7 g, o- J7 H, f! y4 S
-- Also in charge of the re-synchronization of PS2_Data8 U3 T2 @% [! V4 \& b( E2 q  t
process (Clk,Reset)/ E. ^0 u7 y- @, Q% T6 ]/ h  u
begin
5 U" ^7 \2 q* m+ q, x5 Oif Reset='0' then4 m. ?( X9 k& ]1 ]7 W/ D2 C
PS2_Datr <= '0';
7 F3 m+ q9 @  PPS2_Clk_f <= '0';( }' ~2 ?4 u; l; y  [, Q
Filter <= (others=>'0');! @8 Z% s* ^4 `' G& w! n7 }
Fall_Clk <= '0';" d: j/ x) T' n2 t0 |+ _( H# P
elsif rising_edge (Clk) then
+ j  X, B1 f4 l3 }7 i. G5 FPS2_Datr <= PS2_Data and PS2_Data; -- also turns 'H' into '1'. O$ f$ I, J% o: j
Fall_Clk <= '0';" q3 o9 t/ q) g: a, [' T
Filter <= (PS2_Clk and PS2_CLK) & Filter(Filter'high downto 1);3 @& ?( Q, D& L4 c9 r( |
if Filter = Filter_t'(others=>'1') then
6 G1 T" x7 B( q& @$ ZPS2_Clk_f <= '1';* u7 T. ^. H( }7 g9 B" _- w
elsif Filter = Filter_t'(others=>'0') then
( v5 }" D8 ~2 d0 ]/ ~$ KPS2_Clk_f <= '0';/ z- `* q7 M; g
if PS2_Clk_f = '1' then: K7 n/ `; @& G
Fall_Clk <= '1';- a% @8 S4 K! I. n2 }
end if;
5 M$ d; {' [5 L, z( P( j% |; f# vend if;1 u& A, t) I/ H
end if;# i" w# {$ S" [. g4 A2 d
end process;
: X) C) Q! A. |; C$ k$ |# G/ F-- This simple State Machine reads in the Serial Data& _6 O8 D! O: X$ w9 C, w
-- coming from the PS/2 peripheral.
8 g( X( z5 j# [# e7 c6 O" \, I& D* Cprocess(Clk,Reset)% e* r6 i) g  R  k' q* {' j
begin
6 Q9 x9 y# W! c! B' Vif Reset='0' then: J1 U: g! W4 s$ L
State <= Idle;. v8 K0 |3 C- `
Bit_Cnt <= (others => '0');
# u) W  k) E9 C. c2 I$ }/ e' r% fS_Reg <= (others => '0');: G" w! d) I6 y; y
Scan_Code <= (others => '0');$ u/ Z0 a% ?' D' }
Parity <= '0';' @- S4 @: k; z; u0 _7 j7 l
Scan_Davi <= '0';
8 F. e5 z. a4 j1 LScan_Err <= '0';. D3 f; A3 ^" r: j! r; k5 e* [
elsif rising_edge (Clk) then
$ l, d& j8 H! Zif DoRead='1' then
% Z; R# ~2 F  Y: XScan_Davi <= '0'; -- note: this assgnmnt can be overriden
7 e! d) ]- A( g( k# ]: L8 Send if;  {0 H' i! }% @* `; W* m* m( f
case State is6 }$ B" H9 D; [# q
when Idle =>
. D1 J$ G) O* ~9 ~! dParity <= '0';
+ S2 x& B6 m0 H/ G1 x# X8 hBit_Cnt <= (others => '0');9 g; ?$ K  c+ I6 h" {# |8 H& a2 b
-- note that we dont need to clear the Shift Register4 i* h+ n; Y9 \3 Y* ~: {) v
if Fall_Clk='1' and PS2_Datr='0' then -- Start bit
( p' J" J2 b5 [5 h. u; aScan_Err <= '0';' ^0 \4 s0 a0 w* W0 o8 l
State <= Shifting;
6 |8 G" Q: X: ~end if;3 r$ r7 Q9 U3 \' N* I* n( X
when Shifting =>
* d" o* ^  {! r& Gif Bit_Cnt >= 9 then
0 ]' r* B0 g9 iif Fall_Clk='1' then -- Stop Bit
  `" I3 w" l. F) ]' B; @-- Error is (wrong Parity) or (Stop='0') or Overflow) H6 w$ ~9 x- U  _
Scan_Err <= (not Parity) or (not PS2_Datr) or Scan_DAVi;
% Y/ ^% L0 Z* B  R7 _* X$ }8 lScan_Davi <= '1';: N8 ]9 A2 J/ J; r8 ~4 N6 Q
Scan_Code <= S_Reg(7 downto 0);0 E* O5 G: \( u; e8 o6 {# O
State <= Idle;# [3 |- x" R  s) S* E& e
end if;$ I$ S7 }" d. }
elsif Fall_Clk='1' then
  Q3 T& p. Z, W' ?: iBit_Cnt <= Bit_Cnt + 1;* P) X: y$ C$ [; K. d* d8 [# Z
S_Reg <= PS2_Datr & S_Reg (S_Reg'high downto 1); -- Shift right& r: n) y. D0 \2 A- Q3 ]( t
Parity <= Parity xor PS2_Datr;" X/ [3 ~/ E+ K4 Z6 T3 b
end if;) o# M' y, `0 t9 ~8 O
when others => -- never reached5 Q  L! H! n8 \* m
State <= Idle;
0 Y9 j' x, K9 ~6 F/ y4 O; Fend case;
0 v: \6 M* g. ]end if;
' y/ R  ~& U  T  C0 ]- `end process;  ]% F4 l9 P- d8 P: Z" L' i4 u
end ALSE_RTL;




歡迎光臨 Chip123 科技應用創新平台 (http://chip123.com/) Powered by Discuz! X3.2