SOC

PS/2 동기화통신 ps/2 keyboard VHDL,MODELSIM

전자자연인 2021. 6. 9. 21:55
반응형

첨부파일 : https://blog.naver.com/aanrt/221515655615

 

1. PS/2 동기화 통신

 

Personal System/2 인터페이스는 양방향 동기식 통신이 가능한 PC port 규격이다.

키보드는 CLOCK DATA라인의 값이 1 상태일 경우에 한하여 데이터를 송신할 수 있다. 클록신호는 유효데이터를 지시하기 위한 동기신호의 개념이다.

키보드에서 키가 눌려지면, 키보드 내부의 원칩 컨트롤러가 DATA(SCAN Code 전송)를 시스템에 보내게 된다.

-키를 누를 때는 11bit 하나의 key code (make code)가 발생하고,

-키가 떨어질 때는 두 개의 Scan code(break code)가 전송된다 (F0->Key code)

-키가 계속 눌려지면 해당 Key code 100ms마다 전송하고, 키가 떨어질 때도 출력하기 때문에 시스템 쪽에서는 키가 계속 눌려지는 것을 인식 할 수가 있다.

 

1. D가 눌렸을 때,

 

CLK(클락)신호가 falling edge일 때 유효데이터 값이고,

D 23 data값을 갖는데, 이는 16진수 값으로 00100011이다.

키가 눌렸을 때의 11bit key code의 구성은 STARTbit(1bit) + DATA(8bit) + PARITY(1bit) + STOP(1bit)로 구성된다.

Start Clk High, Data 1 -> 0 (falling edge) start된다.

Stop bit는 키보드를 안눌렀을 때, High로 되므로 누를시 low되면 다시 시작

Data는 가장 우측값이 LSB로 전송되고 가장 좌측 값이 MSB로 전달

 

 

2-1 ps/2 keyboard VHDL

entity ps2_keyboard is                                                                       

    port (

nRst : in std_logic;

clk : in std_logic;

start_sig : in std_logic;

data : in std_logic_vector( 7 downto 0);

ps2_clk : out std_logic;

ps2_data : out std_logic);

end ps2_keyboard;

 

architecture beh of ps2_keyboard is

type state_type is (IDLE, START, SEND, PARITY, STOP);

signal state : state_type;

signal cnt : std_logic_vector(9 downto 0);

signal pclk : std_logic;

signal pclk_cnt : std_logic_vector(1 downto 0);

signal bit_cnt : std_logic_vector(2 downto 0);

signal temp_data : std_logic_vector(7 downto 0);

signal tx_data : std_logic_vector(7 downto 0);

 

signal start_d : std_logic;

signal flag : std_logic;

 

begin

 

   

process(nRst,clk)

  begin

if(nRst = '0') then

cnt <= (others => '0');

pclk <= '0';

 

 

elsif rising_edge(clk) then

if(cnt=624) then

cnt <= (others => '0');

pclk <= not pclk;

 

else

cnt <= cnt + 1;

end if;

end if;

end process;

 

 

process(nRst,clk)

begin

if(nRst = '0') then

start_d <= '0';

flag <= '0';

 

temp_data <= (others => '0');

elsif rising_edge(clk) then

start_d <= start_sig ;

if(start_d='0') and (start_sig='1') then

flag <= '1';

temp_data <= data;

 

elsif(state = START) then

flag <= '0';

end if;

end if;

end process;

process(nRst,pclk)

   begin

    if(nRst = '0') then

state <= IDLE;

pclk_cnt <= (others => '0');

bit_cnt <= (others => '0');

tx_data <= (others => '0');

elsif rising_edge(pclk) then

case state is

when IDLE =>

     if(flag = '1') then

       state <= START;

               else

       state <= IDLE;

        end if;

        pclk_cnt <=(others=>'0');

        bit_cnt <=(others=>'0');

        tx_data <= (others =>'0');

 

 

when START =>

   if(pclk_cnt = 3) then

     pclk_cnt <= (others => '0');

     state <= SEND;

   else

    pclk_cnt <= pclk_cnt + 1;

    state <= START;

    end if;

  tx_data <= temp_data;

        when SEND =>

if(pclk_cnt =3) then

  pclk_cnt <=(others => '0');

   if(bit_cnt = 7) then

   bit_cnt<=(others=>'0');

   state <= PARITY;

 else

   tx_data<='0' & tx_data ( 7 downto 1);

   bit_cnt <= bit_cnt + 1;

   state <= SEND;

end if;

  else

   pclk_cnt <= pclk_cnt + 1;

   state <= SEND;

   end if;

 

when PARITY =>

  if(pclk_cnt =3)then

    pclk_cnt <= (others => '0');

    state<=STOP;

else

    pclk_cnt <= pclk_cnt + 1;

    state<=PARITY;

 end if;

   

 

when STOP =>

  if(pclk_cnt = 3 ) then

   pclk_cnt<=(others => '0');

   state <= IDLE;

else

   pclk_cnt <= pclk_cnt + 1;

   state <= STOP;

 end if;

when others => state <= STOP;

end case;

end if;

end process;

 

 

ps2_clk <= '0' when pclk_cnt >= 1 and pclk_cnt <=2 else '1';

 <span style="font-family: 함초롬바탕; font-size: 11pt;"> </p>

ps2_data <= tx_data(0) when state = SEND else

 

'0' when state = START or state = PARITY else '1';

 

//ps2_data

​//SEND 상태시 temp_data로부터 전달받은 tx_data값의 0비트를 전달,

//START PARITY상태에선 무조건 0값을 전달(start bit,parity bit 0으로 정함) 나머지 경우(STOP,IDLE) 는 모두 1

   

end beh;

 



 

(0) data값에 23(hex)이 입력되고나서 START 신호를 받기 전 상 태가 IDLE상태에서 START로 넘어감

(1) start_sig start_d에 의해 flag값이 1이되면서 START 시작, startbit,paritybit 0이므로 ps2_data값에 0전달 SNED상태로 넘어감

(2) data 23 2진수로 0010 0011이고,temp_data로 전달된후 tx_data = 0010 0011 로 전달된다.

tx_data(0)비트의 값이 ps2_data의 값에 출력되어 1의 값이 나오고

tx_data의 값은 0010 001x(전달된값 x) 가되는데, 0 & tx_data(7 downto 1)에서

하나씩 우측으로밀려 0001 0001이 되어 저장된다

(3) (2)번과 같은방법으로, ps2_data 값엔 tx_data (=0001 0001)에서 맨우측 비트 1이 전달되어 출력되고, tx_data (=0001 000x)에서 0 & tx_data(7 downto 1)이 되어 0000 1000 tx_data 값에 전달된다.

(4)~(9) (2)번과 같은방법으로 data scan code 8비트가 전달될 동안 총 8번의 과정이 반복된다. 처음 입력받은 scan code의 맨우측이 LSB로 전달되고 입력받은 scan_code의 맨좌측이 MSB로 전달되는 과정! 반복된 후 PARITY 상태로 넘어간다

(10) PARITY 상태에선 parity bit  0 ps2_data에 전달되어 출력되어 STOP으로 넘어감

(11) STOP상태에서 stop bit

ps2_data <= tx_data(0) when state = SEND

else '0'

when state = START or state = PARITY else '1';

코드에 의해 해당하는 1의 값이 출력된다.

 

 

 

반응형