Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / fpga / ctrls / ps2 /

ps2full_ctrl.vhd

   1  -- ps2full_ctrl.vhd: PS/2 Controller
   2  -- Copyright (C) 2006 Brno University of Technology,
   3  --                    Faculty of Information Technology
   4  -- Author(s): Zdenek Vasicek <xvasic11 AT stud.fit.vutbr.cz>
   5  --
   6  -- LICENSE TERMS
   7  --
   8  -- Redistribution and use in source and binary forms, with or without
   9  -- modification, are permitted provided that the following conditions
  10  -- are met:
  11  -- 1. Redistributions of source code must retain the above copyright
  12  --    notice, this list of conditions and the following disclaimer.
  13  -- 2. Redistributions in binary form must reproduce the above copyright
  14  --    notice, this list of conditions and the following disclaimer in
  15  --    the documentation and/or other materials provided with the
  16  --    distribution.
  17  -- 3. All advertising materials mentioning features or use of this software
  18  --    or firmware must display the following acknowledgement:
  19  --
  20  --      This product includes software developed by the University of
  21  --      Technology, Faculty of Information Technology, Brno and its
  22  --      contributors.
  23  --
  24  -- 4. Neither the name of the Company nor the names of its contributors
  25  --    may be used to endorse or promote products derived from this
  26  --    software without specific prior written permission.
  27  --
  28  -- This software or firmware is provided ``as is'', and any express or implied
  29  -- warranties, including, but not limited to, the implied warranties of
  30  -- merchantability and fitness for a particular purpose are disclaimed.
  31  -- In no event shall the company or contributors be liable for any
  32  -- direct, indirect, incidental, special, exemplary, or consequential
  33  -- damages (including, but not limited to, procurement of substitute
  34  -- goods or services; loss of use, data, or profits; or business
  35  -- interruption) however caused and on any theory of liability, whether
  36  -- in contract, strict liability, or tort (including negligence or
  37  -- otherwise) arising in any way out of the use of this software, even
  38  -- if advised of the possibility of such damage.
  39  --
  40  -- $Id$
  41  --
  42  --
  43  library IEEE;
  44  use IEEE.STD_LOGIC_1164.ALL;
  45  use IEEE.STD_LOGIC_ARITH.ALL;
  46  use IEEE.STD_LOGIC_UNSIGNED.ALL;
  47  
  48  architecture full of PS2_controller is
  49  
  50     type    FSMstate is (SInit, SRcvData, SRcvParity, SRcvStop,
  51                          SStart0, SStart1, SStart2, SSndData,
  52                          SSndParity, SSndStop, SRcvAck);
  53  
  54     signal  pstate      : FSMstate; -- actual state
  55     signal  nstate      : FSMstate; -- next state
  56  
  57     signal  ps2clk_reg  : std_logic;
  58     signal  ps2clk_dreg : std_logic;
  59     signal  ps2data_reg : std_logic;
  60     signal  di_en       : std_logic; --read from PS/2 data
  61     signal  do_en       : std_logic; --write to PS/2 data
  62  
  63     signal cntr_reg     : std_logic_vector(8 downto 0);
  64     signal cntr_en      : std_logic;
  65     signal cntr_rst     : std_logic;
  66     signal cntr_cmp8    : std_logic;
  67     signal cntr_cmp511  : std_logic;
  68  
  69     signal data_reg     : std_logic_vector(7 downto 0);
  70     signal data_en      : std_logic;
  71  
  72     signal parity_reg   : std_logic;
  73     signal parity_en    : std_logic;
  74     signal parity_rst   : std_logic;
  75     signal parity_in    : std_logic;
  76     signal parity_sel   : std_logic;
  77  
  78     signal clk_we       : std_logic;
  79     signal data_sel     : std_logic_vector(1 downto 0);
  80     signal busy         : std_logic;
  81  
  82  begin
  83  
  84     DATA_OUT  <= data_reg;
  85  
  86     -- PS/2 interface
  87     PS2_CLK   <= '0' when clk_we='1' else 'Z' ;
  88  
  89     PS2_DATA  <= data_reg(0) when data_sel="00" else
  90                  parity_reg  when data_sel="01" else
  91                  '0'         when data_sel="10" else
  92                  'Z';
  93  
  94     -- PS/2 CLK edge detector
  95     process (RST, CLK)
  96     begin
  97        if (RST = '1') then
  98           ps2clk_reg  <= '1';
  99           ps2clk_dreg <= '1';
 100           ps2data_reg <= '1';
 101        elsif (CLK'event) and (CLK = '1') then
 102           ps2clk_reg  <= PS2_CLK;
 103           ps2clk_dreg <= ps2clk_reg;
 104           ps2data_reg <= PS2_DATA;
 105        end if;
 106     end process;
 107  
 108     di_en <= ps2clk_dreg and (not ps2clk_reg); --Falling edge
 109     do_en <= (not ps2clk_dreg) and ps2clk_reg; --Rising edge
 110  
 111     -- Bits counter
 112     bitscntr: process(RST, CLK)
 113     begin
 114        if (RST = '1') then
 115           cntr_reg <= (others => '0');
 116        elsif (CLK'event) and (CLK='1') then
 117           if (cntr_rst = '1') then
 118              cntr_reg <= (others => '0');
 119           elsif (cntr_en='1') then
 120              cntr_reg <= cntr_reg + 1;
 121           end if;
 122        end if;
 123     end process;
 124  
 125     -- Comparators
 126     cntr_cmp8   <= '1' when (cntr_reg = 16#008#) else '0';
 127     cntr_cmp511 <= '1' when (cntr_reg = 16#1ff#) else '0';
 128  
 129     --Data IN/OUT shift register
 130     process (RST, CLK)
 131     begin
 132        if (RST = '1') then
 133           --datain_reg <= (others=>'0');
 134        elsif (CLK'event) and (CLK = '1') then
 135           if (WRITE_EN='1') and (busy='0') then --load
 136              data_reg <= DATA_IN;
 137           elsif (data_en='1') then
 138              data_reg <= ps2data_reg & data_reg(7 downto 1);
 139           end if;
 140        end if;
 141     end process;
 142  
 143     --Data ODD parity calculator
 144     process (RST, CLK)
 145     begin
 146        if (RST = '1') then
 147           parity_reg <= '1';
 148        elsif (CLK'event) and (CLK = '1') then
 149           if (parity_rst = '1') then
 150              parity_reg <= '1';
 151           elsif (parity_en='1') then
 152              parity_reg <= parity_reg xor parity_in;
 153           end if;
 154        end if;
 155     end process;
 156  
 157     parity_in <= ps2data_reg when parity_sel='0' else data_reg(0); --data bit mx
 158  
 159     --FSM present state
 160     process (RST, CLK)
 161     begin
 162        if (RST = '1') then
 163           pstate <= sinit;
 164        elsif (CLK'event) and (CLK = '1') then
 165           pstate <= nstate;
 166        end if;
 167     end process;
 168  
 169     --FSM next state logic
 170     process (pstate, di_en, do_en, ps2data_reg, parity_reg, cntr_cmp8, cntr_cmp511, WRITE_EN)
 171     begin
 172        nstate <= SInit;
 173        cntr_rst <= '0';
 174        cntr_en <= '0';
 175        parity_rst <= '0';
 176        parity_sel <= '0';
 177        parity_en <= '0';
 178        data_en <= '0';
 179        data_sel <= "11";
 180        clk_we <= '0';
 181        DATA_ERR <= '0';
 182        DATA_VLD <= '0';
 183        busy <= '1';
 184  
 185        case pstate is
 186           when SInit =>
 187              busy <= '0';
 188              if (di_en='1') and (ps2data_reg='0') then
 189                 nstate <= SRcvData;
 190                 cntr_rst <= '1';
 191                 parity_rst <= '1';
 192              end if;
 193              if (WRITE_EN='1') then
 194                 cntr_rst <= '1';
 195                 nstate <= SStart0;
 196              end if;
 197  
 198           --====================================================================
 199           --Receiver
 200           --====================================================================
 201           -- Receive data bits
 202           when SRcvData =>
 203              if (cntr_cmp8='0') then
 204                 nstate <= SRcvData;
 205                 cntr_en <= di_en;
 206                 data_en <= di_en;
 207                 parity_en <= di_en;
 208              else
 209                 nstate <= SRcvParity;
 210              end if;
 211  
 212           --Receive parity bit
 213           when SRcvParity =>
 214              if (di_en='1') then
 215                 nstate <= SRcvStop;
 216  
 217                 assert (ps2data_reg=parity_reg) report "PS/2 Data Parity Error" severity note;
 218  
 219                 if (ps2data_reg=parity_reg) then
 220                    DATA_VLD <= '1';
 221                 else
 222                    DATA_ERR <= '1';
 223                 end if;
 224              else
 225                 nstate <= SRcvParity;
 226              end if;
 227  
 228           --Receive stop bit
 229           when SRcvStop =>
 230              if (di_en='0') then
 231                 nstate <= SRcvStop;
 232              end if;
 233  
 234           --====================================================================
 235           -- Transmitter
 236           --====================================================================
 237           when SStart0 =>
 238              clk_we <= '1';
 239              if (cntr_cmp511='1') then
 240                 nstate <= SStart1;
 241                 cntr_rst <= '1';
 242              else
 243                 nstate <= SStart0;
 244                 cntr_en <= '1';
 245              end if;
 246  
 247           --Init data transfer
 248           when SStart1 =>
 249              clk_we <= '1';
 250              data_sel <= "10";
 251              if (cntr_cmp511='1') then
 252                 nstate <= SStart2;
 253              else
 254                 nstate <= SStart1;
 255                 cntr_en <= '1';
 256              end if;
 257  
 258           --Release CLK
 259           when SStart2 =>
 260              data_sel <= "10";
 261              if (di_en='1') then
 262                 nstate <= SSndData;
 263                 cntr_rst <= '1';
 264                 parity_rst <= '1';
 265              else
 266                 nstate <= SStart2;
 267              end if;
 268  
 269           --Transmit data bits
 270           when SSndData =>
 271              data_sel <= "00";
 272              if (cntr_cmp8='0') then
 273                 nstate <= SSndData;
 274                 parity_sel <= '1';
 275                 parity_en <= di_en;
 276                 data_en <= di_en;
 277                 cntr_en <= di_en;
 278              else
 279                 nstate <= SSndParity;
 280              end if;
 281  
 282           --Transmit parity bit
 283           when SSndParity =>
 284              data_sel <= "01";
 285              if (di_en='1') then
 286                 nstate <= SSndStop;
 287              else
 288                 nstate <= SSndParity;
 289              end if;
 290  
 291           --Transmit stop bit
 292           when SSndStop =>
 293              data_sel <= "11";
 294              if (di_en='1') then
 295                 nstate <= SRcvAck;
 296              else
 297                 nstate <= SSndStop;
 298              end if;
 299  
 300           --Receive acknowledge
 301           when SRcvAck =>
 302              if (do_en='1') then
 303  
 304                 assert (ps2data_reg='0') report "PS/2 ACK Error" severity note;
 305  
 306                 if (ps2data_reg='1') then
 307                   DATA_ERR <= '1';
 308                 end if;
 309              else
 310                 nstate <= SRcvAck;
 311              end if;
 312  
 313           when others =>
 314              null;
 315        end case;
 316     end process;
 317  end full;
 318  
 319  
Zobrazeno: 679731x Naposledy: 28.6.2022 19:41:12