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 k
Entity 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 Q
DoRead : 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 arrived
2 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. M
signal Bit_Cnt : unsigned (3 downto 0);
6 ~3 t2 |5 M' Y0 x' i9 X; ?, E
signal Parity : std_logic;
, Q( i5 K& Y2 ~: \9 j3 k+ y
signal 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 F
Type State_t is (Idle, Shifting);
& w4 d* L U, c4 k& y1 k4 O; A1 A' h
signal 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 Data
7 v7 r8 S$ m7 g, o- J7 H, f! y4 S
-- Also in charge of the re-synchronization of PS2_Data
8 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 O
if Reset='0' then
4 m. ?( X9 k& ]1 ]7 W/ D2 C
PS2_Datr <= '0';
7 F3 m+ q9 @ P
PS2_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 F
PS2_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& @$ Z
PS2_Clk_f <= '1';
* u7 T. ^. H( }7 g9 B" _- w
elsif Filter = Filter_t'(others=>'0') then
( v5 }" D8 ~2 d0 ]/ ~$ K
PS2_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# v
end 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* C
process(Clk,Reset)
% e* r6 i) g R k' q* {' j
begin
6 Q9 x9 y# W! c! B' V
if 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% f
S_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 L
Scan_Err <= '0';
. D3 f; A3 ^" r: j! r; k5 e* [
elsif rising_edge (Clk) then
$ l, d& j8 H! Z
if DoRead='1' then
% Z; R# ~2 F Y: X
Scan_Davi <= '0'; -- note: this assgnmnt can be overriden
7 e! d) ]- A( g( k# ]: L8 S
end if;
{0 H' i! }% @* `; W* m* m( f
case State is
6 }$ B" H9 D; [# q
when Idle =>
. D1 J$ G) O* ~9 ~! d
Parity <= '0';
+ S2 x& B6 m0 H/ G1 x# X8 h
Bit_Cnt <= (others => '0');
9 g; ?$ K c+ I6 h" {# |8 H& a2 b
-- note that we dont need to clear the Shift Register
4 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; a
Scan_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& G
if Bit_Cnt >= 9 then
0 ]' r* B0 g9 i
if 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 l
Scan_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' ?: i
Bit_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 reached
5 Q L! H! n8 \* m
State <= Idle;
0 Y9 j' x, K9 ~6 F/ y4 O; F
end 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