⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2_sie.v

📁 基于Xilinx FPGA实现PS2键盘鼠标接口。版本1.0
💻 V
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////
//
//     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
//     SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
//     XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
//     AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
//     OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
//     IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
//     AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
//     FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
//     WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
//     IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
//     REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
//     INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//     FOR A PARTICULAR PURPOSE.
//     
//     (c) Copyright 2004 Xilinx, Inc.
//     All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////
// Filename:        ps2_sie.v
//
// Description:     PS/2 Serial Interface Engine
//  
// Host2Device: Host changes data only when clock line is LOW
//              Device latches data at Rising edge
// Device2Host: Device changes data only when clock line is high
//              Host latches data at falling edge
// Restriction: System Clock (Clk) must be much faster than PS2Clk.
//              Typical usage is 1000x of PS2Clk(10kHz~20kHz). 
//////////////////////////////////////////////////////////////////////////////
// Structure:   
//              
//////////////////////////////////////////////////////////////////////////////
//
// History:
//   wph        10/10/01
//
//////////////////////////////////////////////////////////////////////////////
// Naming Conventions:
//      active low signals:                     "*_n"
//      clock signals:                          "clk", "clk_div#", "clk_#x" 
//      Rst signals:                            "rst", "rst_n" 
//      generics:                               "C_*" 
//      user defined types:                     "*_TYPE" 
//      state machine next state:               "*_ns" 
//      state machine current state:            "*_cs" 
//      combinatorial signals:                  "*_com" 
//      pipelined or register delay signals:    "*_d#" 
//      counter signals:                        "*cnt*"
//      clock enable signals:                   "*_ce" 
//      internal version of output port         "*_i"
//      device pins:                            "*_pin" 
//      ports:                                  - Names begin with Uppercase 
//      processes:                              "*_PROCESS" 
//      component instantiations:               "<ENTITY_>I_<#|FUNC>
//////////////////////////////////////////////////////////////////////////////


module ps2_sie(
  //global signal
  Clk,              // I  system clock
  Rst,              // I  system reset + software reset (offset)
  
  //PS2 interface signal
  Clkin,            // I  PS2 Bi-di Clock in
  Clkpd,            // O  PS2 Bi-di Clock Pull down 
  Rx,               // I  PS2 Bi-di serial data in 
  Txpd,             // O  PS2 Bi-di serial data out pull down 

 
  //interface signal for memory mapped registers
  rx_full_sta,      // I
  rx_full_set,      // O
  rx_err_set,       // O
  rx_ovf_set,       // O

  tx_full_sta,      // I
  tx_full_clr,      // O
  tx_ack_set,       // O
  tx_noack_set,     // O
 
  wdt_tout_set,     // O 

  tx_data,          // I
  rx_data           // O
  
);


  ///////////////////////////////////////////////////////////////////////////////
  // Port Declarations
  //////////////////////////////////////////////////////////////////////////////

  //global signal
  input           Clk;              // I  system clock
  input           Rst;              // I  system reset + software reset (offset)
  
  //PS2 interface signal
  input           Clkin;            // I  PS2 Bi-di Clock in
  output          Clkpd;            // O  PS2 Bi-di Clock Pull down 
  input           Rx;               // I  PS2 Bi-di serial data in 
  output          Txpd;             // O  PS2 Bi-di serial data out pull down 

 
  //interface signal for memory mapped registers
  input           rx_full_sta;      // I
  output          rx_full_set;      // O
  output          rx_err_set;       // O
  output          rx_ovf_set;       // O

  input           tx_full_sta;      // I
  output          tx_full_clr;      // O
  output          tx_ack_set;       // O
  output          tx_noack_set;     // O  
 
  output          wdt_tout_set;      // O 

  input   [0:7]   tx_data;           // I
  output  [0:7]   rx_data;          // O



  ///////////////////////////////////////////////////////////////////////////////
  // Parameter Declarations
  ///////////////////////////////////////////////////////////////////////////////

// Tuning Timer Value
//REAL
parameter BIT_WDT_TMR_VALUE = 40000;     // 400 us
parameter BIT_WDT_TMR_BITS  = 15;    
parameter DBC_TMR_VALUE     = 370;       // 3.7us
parameter DBC_TMR_BITS      = 9;
parameter REQ_SND_VALUE     = 10000;     //at least 100us
parameter REQ_SND_BITS      = 15;

//testmode
//parameter BIT_WDT_TMR_VALUE = 400;     // 400 us
//parameter BIT_WDT_TMR_BITS  = 15;    
//parameter DBC_TMR_VALUE     = 10;      // 3.7us
//parameter DBC_TMR_BITS      = 9;
//parameter REQ_SND_VALUE     = 100;     //at least 100us
//parameter REQ_SND_BITS      = 15;



  ///////////////////////////////////////////////////////////////////////////////
  // Signal Declarations
  ///////////////////////////////////////////////////////////////////////////////

reg         clkin_1, clkin_2;
reg         rx_1,    rx_2;
reg  [0:10] q;
reg  [0:4]  rx_bit_count;
wire        bit_err1;
wire        rx_err_set;
wire [0:7]  rx_data;
wire        rx_full_set;
wire        rx_ovf_set;
reg         rx_full_sta_dly;
reg         Txpd;
reg         txpd_i;
reg         Clkpd;
wire        tx_ack_set;
wire        tx_noack_set;
wire        tx_full_clr;
 
wire        dbc_done;
wire        bit_wdt_done;
wire        wdt_tout_set;
wire        rts_cnt_done;

reg [0: DBC_TMR_BITS - 1]      dbc_counter;
reg [0: BIT_WDT_TMR_BITS - 1]  bit_wdt_counter;
reg [0: REQ_SND_BITS - 1]      rts_counter;

reg tx_ack_set_temp ;  
reg tx_noack_set_temp ;
reg tx_full_clr_temp ; 

 


  ///////////////////////////////////////////////////////////////////////////////
  // Sate Machine Declarations
  ///////////////////////////////////////////////////////////////////////////////

parameter DETECT_CLK_HIGH = 6'b000001;//5
parameter DETECT_CLK_FALL = 6'b000010;//4
parameter DETECT_CLK_FDBC = 6'b000100;//3
parameter DETECT_CLK_LOW  = 6'b001000;//2
parameter DETECT_CLK_RISE = 6'b010000;//1
parameter DETECT_CLK_RDBC = 6'b100000;//0
reg [0:5] detect_clk_cs, detect_clk_ns;
wire clk_fall, clk_rise;  
assign clk_fall = detect_clk_cs[4];
assign clk_rise = detect_clk_cs[1];

parameter RX_CTL_IDLE      = 6'b000001; //5
parameter RX_CTL_STARTCNT  = 6'b000010; //4
parameter RX_CTL_GETB1     = 6'b000100; //3
parameter RX_CTL_CHECKB1   = 6'b001000; //2
parameter RX_CTL_ERR1      = 6'b010000; //1 
parameter RX_CTL_USEB1     = 6'b100000; //0
reg [0:5] rx_ctl_cs, rx_ctl_ns;
wire rx_sta_idle, rx_sta_startcnt, rx_sta_err1, rx_sta_useb1;
assign rx_sta_idle      = rx_ctl_cs[5]; 
assign rx_sta_startcnt  = rx_ctl_cs[4]; 
assign rx_sta_err1      = rx_ctl_cs[1];
assign rx_sta_useb1     = rx_ctl_cs[0]; 


parameter TX_CTL_IDLE        = 16'b0000000000000001; //15
parameter TX_CTL_WAIT        = 16'b0000000000000010; //14
parameter TX_CTL_CLKPD       = 16'b0000000000000100; //13
parameter TX_CTL_DATAPD      = 16'b0000000000001000; //12
parameter TX_CTL_SND7        = 16'b0000000000010000; //11
parameter TX_CTL_SND6        = 16'b0000000000100000; //10
parameter TX_CTL_SND5        = 16'b0000000001000000; //9
parameter TX_CTL_SND4        = 16'b0000000010000000; //8
parameter TX_CTL_SND3        = 16'b0000000100000000; //7
parameter TX_CTL_SND2        = 16'b0000001000000000; //6
parameter TX_CTL_SND1        = 16'b0000010000000000; //5
parameter TX_CTL_SND0        = 16'b0000100000000000; //4
parameter TX_CTL_PRTY        = 16'b0001000000000000; //3
parameter TX_CTL_STOP        = 16'b0010000000000000; //2
parameter TX_CTL_WAITFEDGE   = 16'b0100000000000000; //1 
parameter TX_CTL_CHKACK      = 16'b1000000000000000; //0
reg [0:15] tx_ctl_cs, tx_ctl_ns;
wire tx_sta_idle,tx_busy,tx_sta_clkpd,tx_sta_datapd, 
     tx_sta_chkack, tx_sta_waitfedge, tx_sta_clkpd_next, tx_sta_idle_next;
wire tx_sta_wait;
assign tx_sta_wait = tx_ctl_cs[14];
assign tx_sta_idle = tx_ctl_cs[15];
assign tx_sta_idle_next = tx_ctl_ns[15];
assign tx_busy = (~ tx_ctl_cs[15]) && (~ tx_ctl_cs[14]);
assign tx_sta_clkpd = tx_ctl_cs[13];
assign tx_sta_clkpd_next = tx_ctl_ns[13];
assign tx_sta_datapd = tx_ctl_cs[12];
assign tx_sta_waitfedge = tx_ctl_cs[1];
assign tx_sta_chkack    = tx_ctl_cs[0];


///////////////////////////////////////////////////////////////////////////////
//begin
///////////////////////////////////////////////////////////////////////////////


//-----------------------------------------------------------------
//Receiving serial rx and Clkin,reisters to avoid metastability
//-----------------------------------------------------------------
always @(posedge Clk)
begin
  if (Rst)
    begin
    clkin_1 <= 1'b1;
    clkin_2 <= 1'b1;
    rx_1    <= 1'b1;
    rx_2    <= 1'b1;
    end
  else 
    begin
    clkin_1 <= Clkin;
    clkin_2 <= clkin_1 ;
    rx_1    <= Rx;
    rx_2    <= rx_1;
    end
end

//-----------------------------------------------------------------
// This State machine - Detect Clock basically detects 
// the clock edges and wait for debouncing done.
//-----------------------------------------------------------------
  
always @(posedge Clk)
begin 
  if (Rst) detect_clk_cs <= DETECT_CLK_HIGH;
  else     detect_clk_cs <= detect_clk_ns;
end

always @(detect_clk_cs or 
         clkin_2       or
         dbc_done   )
begin 
    case (detect_clk_cs)
  
    DETECT_CLK_HIGH:  begin
               if (~ clkin_2)    detect_clk_ns <= DETECT_CLK_FALL;
               else             detect_clk_ns <= DETECT_CLK_HIGH;
               end
      
    DETECT_CLK_FALL:            detect_clk_ns <= DETECT_CLK_FDBC;
 

     
    DETECT_CLK_FDBC:  begin
               if (dbc_done)    detect_clk_ns <= DETECT_CLK_LOW;
               else             detect_clk_ns <= DETECT_CLK_FDBC;
               end

    DETECT_CLK_LOW:  begin
               if (clkin_2)     detect_clk_ns <= DETECT_CLK_RISE;
               else             detect_clk_ns <= DETECT_CLK_LOW;
               end

    DETECT_CLK_RISE:            detect_clk_ns <= DETECT_CLK_RDBC;




    DETECT_CLK_RDBC:  begin
               if (dbc_done)    detect_clk_ns <= DETECT_CLK_HIGH;
               else             detect_clk_ns <= DETECT_CLK_RDBC;
               end

    default :                   detect_clk_ns <= DETECT_CLK_HIGH;



    endcase
end

//-----------------------------------------------------------------
//This statemachine performs RX flow control. 
//-----------------------------------------------------------------
//If Host is transmitting command (tx_busy), 
//RX statemachine has to be forced to be WAIT status.
always @(posedge Clk)
begin 
  if (Rst || tx_busy || bit_wdt_done || tx_sta_clkpd_next) 
                                      rx_ctl_cs <= RX_CTL_IDLE;   
  else                                rx_ctl_cs <= rx_ctl_ns ;
end

always @(rx_ctl_cs    or 
         clk_fall     or
         tx_sta_idle  or
         rx_bit_count or
         bit_err1 )
begin 
    case (rx_ctl_cs)
   
    RX_CTL_IDLE:  begin
               if (clk_fall && tx_sta_idle)       rx_ctl_ns <= RX_CTL_STARTCNT;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -