📄 ps2_sie.v
字号:
////////////////////////////////////////////////////////////////////////////////// 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//REALparameter BIT_WDT_TMR_VALUE = 40000; // 400 usparameter BIT_WDT_TMR_BITS = 15; parameter DBC_TMR_VALUE = 370; // 3.7usparameter DBC_TMR_BITS = 9;parameter REQ_SND_VALUE = 10000; //at least 100usparameter 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;//5parameter DETECT_CLK_FALL = 6'b000010;//4parameter DETECT_CLK_FDBC = 6'b000100;//3parameter DETECT_CLK_LOW = 6'b001000;//2parameter DETECT_CLK_RISE = 6'b010000;//1parameter DETECT_CLK_RDBC = 6'b100000;//0reg [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; //5parameter RX_CTL_STARTCNT = 6'b000010; //4parameter RX_CTL_GETB1 = 6'b000100; //3parameter RX_CTL_CHECKB1 = 6'b001000; //2parameter RX_CTL_ERR1 = 6'b010000; //1 parameter RX_CTL_USEB1 = 6'b100000; //0reg [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; //15parameter TX_CTL_WAIT = 16'b0000000000000010; //14parameter TX_CTL_CLKPD = 16'b0000000000000100; //13parameter TX_CTL_DATAPD = 16'b0000000000001000; //12parameter TX_CTL_SND7 = 16'b0000000000010000; //11parameter TX_CTL_SND6 = 16'b0000000000100000; //10parameter TX_CTL_SND5 = 16'b0000000001000000; //9parameter TX_CTL_SND4 = 16'b0000000010000000; //8parameter TX_CTL_SND3 = 16'b0000000100000000; //7parameter TX_CTL_SND2 = 16'b0000001000000000; //6parameter TX_CTL_SND1 = 16'b0000010000000000; //5parameter TX_CTL_SND0 = 16'b0000100000000000; //4parameter TX_CTL_PRTY = 16'b0001000000000000; //3parameter TX_CTL_STOP = 16'b0010000000000000; //2parameter TX_CTL_WAITFEDGE = 16'b0100000000000000; //1 parameter TX_CTL_CHKACK = 16'b1000000000000000; //0reg [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; endend//-----------------------------------------------------------------// 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;endalways @(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; endcaseend//-----------------------------------------------------------------//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 ;endalways @(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 + -