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

📄 ps2_sie.v

📁 基于Xilinx FPGA实现PS2键盘鼠标接口。版本1.0
💻 V
📖 第 1 页 / 共 2 页
字号:
               else                               rx_ctl_ns <= RX_CTL_IDLE;
               end
    //IDLE -> STARTCNT reset rx_bit_count and q-reg

    //STARTCNT: (an intermediate state) start counting and register rx data
    RX_CTL_STARTCNT:                              rx_ctl_ns <= RX_CTL_GETB1;  

    RX_CTL_GETB1:  begin
               if (rx_bit_count == 11)            rx_ctl_ns <= RX_CTL_CHECKB1;
               else                               rx_ctl_ns <= RX_CTL_GETB1;
               end

    RX_CTL_CHECKB1:  begin
               if (bit_err1)                      rx_ctl_ns <= RX_CTL_ERR1;
               else                               rx_ctl_ns <= RX_CTL_USEB1;
               end

    RX_CTL_ERR1:                                  rx_ctl_ns <= RX_CTL_IDLE;

    RX_CTL_USEB1:                                 rx_ctl_ns <= RX_CTL_IDLE;

    default :                                     rx_ctl_ns <= RX_CTL_IDLE;


    endcase
end

//------------------
//RX shift register & bit counter
//------------------
//IDLE->RSTCNT: clear q-reg, clear rx_bit_count 
//delicate rx_bit_counter
always @(posedge Clk)
begin
  if (Rst || rx_sta_idle) begin                                  
            q             <= 0;
            rx_bit_count  <= 0; 
           end
  else if ( (clk_fall && ~ rx_sta_idle) || rx_sta_startcnt ) begin
            q             <= {rx_2,q[0:9]};
            rx_bit_count  <= rx_bit_count + 1;
            end
  else if (  bit_wdt_done || (clk_fall && rx_sta_idle )) begin
            q             <= 0;
            rx_bit_count  <= 0; 
            end
end

//-----------------------------------
//RX_CTL_CHECKB1 
//-----------------------------------
//Check start/stop/parity bit
//Notice the bit ordering in phsucal SReg is [0:10]
// b0   b1     b2~b9   b10   ; 
// STOP PARITY DATA  START 

assign bit_err1 =  ~  (  (q[10]  == 0)          // start        
                      && (q[0]   == 1)          // stop
                      && (q[1]   == ~^q[2:9])   // odd parity bit
                      );

//wire start_bit = q[10];
//wire stop_bit  = q[0];
//wire odd_parity= q[1];
//wire xnor_data = ~^q[2:9];

//-------------
//RX_CTL_ERR1
//-------------
assign rx_err_set    = rx_sta_err1;

//-------------
//RX_CTL_USEB1
//-------------
assign rx_data       = q[2:9];
assign rx_full_set   = rx_sta_useb1;


//check if previous data has been processed by host software,
//if not, then the new upcomming rx data will cause overflow.

assign rx_ovf_set    = rx_sta_useb1 & rx_full_sta_dly;

always @ (posedge Clk)
begin
  if (Rst)
       rx_full_sta_dly <= 0;
  else rx_full_sta_dly <= rx_full_sta;
  end

//-----------------------------------------------------------------
//This statemachine controls Transmission flow (TX_CTL)
//-----------------------------------------------------------------
always @(posedge Clk)
begin 
  if (Rst) tx_ctl_cs <= TX_CTL_IDLE;   
  else     tx_ctl_cs <= tx_ctl_ns ;
end
always @(posedge Clk)
begin 
  if (Rst)               Txpd      <= 0;
  else if ((clk_fall && tx_busy ) || tx_sta_datapd )     Txpd      <= txpd_i ;
end

always @(tx_ctl_cs    or
         tx_full_sta  or 
         rx_bit_count or 
         rts_cnt_done or 
         clk_fall or 
         tx_data or clk_rise)
begin 
    
    case (tx_ctl_cs )
  
    TX_CTL_IDLE   : begin
                                txpd_i <= 1'b0;
          if (tx_full_sta)      tx_ctl_ns <= TX_CTL_WAIT ;
          else                  tx_ctl_ns <= TX_CTL_IDLE ;
          end
    TX_CTL_WAIT   : begin
                                txpd_i <= 1'b0;
          if ( ~(rx_bit_count  == 10) && ~(rx_bit_count  == 11) )
                                tx_ctl_ns <= TX_CTL_CLKPD;
          else                  tx_ctl_ns <= TX_CTL_WAIT;
          end

    TX_CTL_CLKPD : begin
                                txpd_i <= 1'b0;
          if ( rts_cnt_done )   tx_ctl_ns <= TX_CTL_DATAPD; 
          else                  tx_ctl_ns <= TX_CTL_CLKPD;
          end

    TX_CTL_DATAPD : begin
                                txpd_i <= 1'b1;    //Start bit
                                tx_ctl_ns <= TX_CTL_SND7;
                    end

    TX_CTL_SND7  : begin         
                                txpd_i <= ~tx_data[7];    
                   if ( clk_fall ) begin
                                tx_ctl_ns <= TX_CTL_SND6;
                                end
                   else         begin
                              
                                tx_ctl_ns <= TX_CTL_SND7;
                                end
                   end
    TX_CTL_SND6  : begin         
                                txpd_i <= ~tx_data[6];    
                   if ( clk_fall ) begin
                                tx_ctl_ns <= TX_CTL_SND5;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_SND6;
                                end
                   end

    TX_CTL_SND5  : begin         
                                txpd_i <= ~tx_data[5];    
                   if ( clk_fall )begin
                                tx_ctl_ns <= TX_CTL_SND4;
                                end
                   else         begin
                                tx_ctl_ns <= TX_CTL_SND5;
                                end
                   end

    TX_CTL_SND4  : begin         
                                txpd_i <= ~tx_data[4];    
                   if ( clk_fall )begin 
                                tx_ctl_ns <= TX_CTL_SND3;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_SND4;
                                end
                   end

    TX_CTL_SND3  : begin         
                                txpd_i <= ~tx_data[3];    
                   if ( clk_fall )begin 
                                tx_ctl_ns <= TX_CTL_SND2;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_SND3;
                                end
                   end

    TX_CTL_SND2  : begin         
                                txpd_i <= ~tx_data[2];    
                   if ( clk_fall )begin 
                                tx_ctl_ns <= TX_CTL_SND1;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_SND2;
                                end
                   end

    TX_CTL_SND1  : begin         
                                txpd_i <= ~tx_data[1];    
                   if ( clk_fall )begin 
                                tx_ctl_ns <= TX_CTL_SND0;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_SND1;
                                end
                   end

    TX_CTL_SND0  : begin         
                                txpd_i <= ~tx_data[0];    
                   if ( clk_fall )begin 
                                tx_ctl_ns <= TX_CTL_PRTY  ;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_SND0;
                                end
                   end

    TX_CTL_PRTY  : begin         
                                txpd_i <= ^tx_data[0:7];    
                   if ( clk_fall )begin 
                                tx_ctl_ns <= TX_CTL_STOP  ;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_PRTY;
                                end
                   end

   TX_CTL_STOP  : begin         
                                txpd_i <= 1'b0;    
                   if ( clk_fall )begin 
                                tx_ctl_ns <= TX_CTL_WAITFEDGE  ;
                                end
                   else         begin 
                                tx_ctl_ns <= TX_CTL_STOP;
                                end
                   end

    TX_CTL_WAITFEDGE  : begin 
                                  txpd_i <= 1'b0;
          if ( clk_fall )
                                  tx_ctl_ns <= TX_CTL_CHKACK;             
          else                    tx_ctl_ns <= TX_CTL_WAITFEDGE;
          end

              
  
    TX_CTL_CHKACK:    begin       txpd_i <= 1'b0;
          if (clk_rise )                   
                                  tx_ctl_ns <= TX_CTL_IDLE;
          else                    tx_ctl_ns <= TX_CTL_CHKACK;
          end
  
    default:          begin       txpd_i <= 1'b0;
                                  tx_ctl_ns <= TX_CTL_IDLE;
                      end

   
  endcase
end

//-------------
//TX_CTL_CLKPD & TX_CTL_DATAPD
//-------------
//register this to avoid glitch
always @ (posedge Clk)
begin 
   if (Rst)
        Clkpd <= 0;
   else Clkpd <= tx_sta_clkpd || tx_sta_datapd;
end


//------------------
//TX_CTL_CHKACK
//------------------
//Delay tx status update. 
//tx status cannot be updated until state TX_CTL_CHKACK has completed 
always @(posedge Clk)
begin 
  if (Rst || tx_sta_idle) 
     begin 
       tx_ack_set_temp    <= 1'b0;
       tx_noack_set_temp  <= 1'b0;
       tx_full_clr_temp   <= 1'b0;
     end
  else if (tx_sta_waitfedge && clk_fall)
     begin
       tx_ack_set_temp    <= (~ rx_2);
       tx_noack_set_temp  <= (rx_2);
       tx_full_clr_temp   <= 1'b1;
     end
end

//assign tx_ack_set   = tx_sta_chkack & (~ rx_2);
//assign tx_noack_set = tx_sta_chkack & (rx_2);
//assign tx_full_clr  = tx_sta_chkack;
assign tx_ack_set   = ( tx_sta_chkack &&tx_sta_idle_next)? tx_ack_set_temp   :1'b0;
assign tx_noack_set = ( tx_sta_chkack &&tx_sta_idle_next)? tx_noack_set_temp :1'b0;
assign tx_full_clr  = ( tx_sta_chkack &&tx_sta_idle_next)? tx_full_clr_temp  :1'b0;

//----------------------------------------
// Misc counter sections
//----------------------------------------


//------------
// Debounce counter. DBC reset at clock edges
//------------

always @ (posedge Clk)
begin  
  if (Rst || clk_fall || clk_rise)
       dbc_counter <= 0;
  else dbc_counter <= dbc_counter + 1;
end
assign dbc_done = (dbc_counter == DBC_TMR_VALUE -1);

//------------
// WatchDog timer. WTD reset at clock edges
//------------
always @ (posedge Clk)
begin  
  if (Rst || clk_fall|| clk_rise || (rx_sta_idle && tx_sta_idle ))
       bit_wdt_counter <= 0;
  else bit_wdt_counter <= bit_wdt_counter + 1;
end
assign bit_wdt_done = (bit_wdt_counter == BIT_WDT_TMR_VALUE -1);
assign wdt_tout_set = bit_wdt_done ;

//------------
// Request-to-Send timer.
//------------
always @ (posedge Clk)
begin  
  if (Rst || (tx_sta_clkpd_next && tx_sta_wait) )
       rts_counter <= 0;
  else rts_counter <= rts_counter + 1;
end
assign rts_cnt_done = (rts_counter == REQ_SND_VALUE  -1);



endmodule

⌨️ 快捷键说明

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