URL
https://opencores.org/ocsvn/usbhostslave/usbhostslave/trunk
Subversion Repositories usbhostslave
[/] [usbhostslave/] [trunk/] [usbDevice/] [RTL/] [EP0.v] - Rev 40
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// EP0.v //// //// //// //// This file is part of the usbHostSlave opencores effort. //// <http://www.opencores.org/cores//> //// //// //// //// Module Description: //// //// Implements EP0 control endpoint //// Responds to 8-byte SETUP packets //// of type GET_STATUS, GET_DESCRIPTOR and //// SET_ADDRESS //// //// //// To Do: //// //// //// //// //// Author(s): //// //// - Steve Fielding, sfielding@base2designs.com //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2008 Steve Fielding and OPENCORES.ORG //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from <http://www.opencores.org/lgpl.shtml> //// //// //// ////////////////////////////////////////////////////////////////////// // `include "timescale.v" `include "usbHostSlaveReg_define.v" `include "usbDevice_define.v" module EP0 (clk, initComplete, memAddr, memData, memRdEn, rst, wb_ack, wb_addr, wb_data_i, wb_data_o, wb_stb, wb_we, wbBusGnt, wbBusReq); input clk; input [7:0]memData; input rst; input wb_ack; input [7:0]wb_data_i; input wbBusGnt; output initComplete; output [7:0]memAddr; output memRdEn; output [7:0]wb_addr; output [7:0]wb_data_o; output wb_stb; output wb_we; output wbBusReq; wire clk; reg initComplete, next_initComplete; reg [7:0]memAddr, next_memAddr; wire [7:0]memData; reg memRdEn, next_memRdEn; wire rst; wire wb_ack; reg [7:0]wb_addr, next_wb_addr; wire [7:0]wb_data_i; reg [7:0]wb_data_o, next_wb_data_o; reg wb_stb, next_wb_stb; reg wb_we, next_wb_we; wire wbBusGnt; reg wbBusReq, next_wbBusReq; // diagram signals declarations reg bm_req_dir, next_bm_req_dir; reg [4:0]bm_req_recp, next_bm_req_recp; reg [1:0]bm_req_type, next_bm_req_type; reg [7:0]bRequest, next_bRequest; reg [7:0]cnt, next_cnt; reg dataSeq, next_dataSeq; reg [7:0]epStatus, next_epStatus; reg [7:0]epTransType, next_epTransType; reg localRst, next_localRst; reg [15:0]rxDataSize, next_rxDataSize; reg transDone, next_transDone; reg [7:0]txDataIndex, next_txDataIndex; reg [7:0]txDataSize, next_txDataSize; reg [7:0]txPacketRemSize, next_txPacketRemSize; reg updateUSBAddress, next_updateUSBAddress; reg [7:0]USBAddress, next_USBAddress; reg [15:0]wIndex, next_wIndex; reg [15:0]wLength, next_wLength; reg [15:0]wValue, next_wValue; // BINARY ENCODED state machine: EP0St // State codes definitions: `define INIT_RST 6'b000000 `define INIT_WT_GNT 6'b000001 `define INIT_WT_RST 6'b000010 `define INIT_WT_VBUS 6'b000011 `define INIT_FIN 6'b000100 `define DO_TRANS_WT_GNT 6'b000101 `define DO_TRANS_TX_EMPTY 6'b000110 `define DO_TRANS_WR_TX_FIFO 6'b000111 `define DO_TRANS_RD_MEM 6'b001000 `define DO_TRANS_CHK_TX_DONE 6'b001001 `define DO_TRANS_TRANS_GO 6'b001010 `define DO_TRANS_WT_TRANS_DONE_WT_GNT 6'b001011 `define DO_TRANS_WT_TRANS_DONE_GET_RDY_STS 6'b001100 `define DO_TRANS_WT_TRANS_DONE_WT_UNGNT 6'b001101 `define DO_TRANS_WT_TRANS_DONE_CHK_DONE 6'b001110 `define CHK_TRANS_RD_STAT 6'b001111 `define CHK_TRANS_WT_GNT 6'b010000 `define CHK_TRANS_RD_RX_SIZE1 6'b010001 `define CHK_TRANS_RD_RX_SIZE2 6'b010010 `define CHK_TRANS_RD_TRANS_TYPE 6'b010011 `define CHK_TRANS_WT_UNGNT 6'b010100 `define SETUP_CHK_ERR 6'b010101 `define SETUP_GET_DATA_DAT1 6'b010110 `define SETUP_GET_DATA_WT_GNT 6'b010111 `define SETUP_GET_DATA_DAT2 6'b011000 `define SETUP_GET_DATA_DAT3 6'b011001 `define SETUP_GET_DATA_DAT4 6'b011010 `define SETUP_GET_DATA_DAT6 6'b011011 `define SETUP_GET_DATA_DAT5 6'b011100 `define SETUP_GET_DATA_DAT8 6'b011101 `define SETUP_GET_DATA_DAT7 6'b011110 `define SETUP_GET_DATA_WT_UNGNT 6'b011111 `define SETUP_GET_STAT 6'b100000 `define SETUP_SET_ADDR 6'b100001 `define SETUP_GET_DESC_S1 6'b100010 `define SETUP_CHK_MAX_LEN 6'b100011 `define OUT_CHK_SEQ 6'b100100 `define IN_CHK_ACK 6'b100101 `define IN_SET_PTR 6'b100110 `define IN_SET_ADDR 6'b100111 `define IN_WT_GNT 6'b101000 `define IN_WT_UNGNT 6'b101001 `define DO_TRANS_RX_EMPTY 6'b101010 `define DO_TRANS_WT_TRANS_DONE_DEL 6'b101011 `define START 6'b101100 `define INIT_CONN 6'b101101 `define INIT_WT_CONN 6'b101110 `define DO_TRANS_DEL 6'b101111 `define SETUP_PTR_SET 6'b110000 reg [5:0]CurrState_EP0St, NextState_EP0St; // Diagram actions (continuous assignments allowed only: assign ...) // diagram ACTION // Machine: EP0St // NextState logic (combinatorial) always @ (wb_ack or wbBusGnt or cnt or wb_data_i or memData or txDataIndex or txDataSize or transDone or epStatus or epTransType or rxDataSize or bRequest or wValue or wLength or dataSeq or updateUSBAddress or txPacketRemSize or USBAddress or wb_addr or wb_data_o or wb_stb or wb_we or wbBusReq or initComplete or memAddr or memRdEn or bm_req_dir or bm_req_type or bm_req_recp or wIndex or CurrState_EP0St) begin NextState_EP0St <= CurrState_EP0St; // Set default values for outputs and signals next_wb_addr <= wb_addr; next_wb_data_o <= wb_data_o; next_wb_stb <= wb_stb; next_wb_we <= wb_we; next_cnt <= cnt; next_wbBusReq <= wbBusReq; next_initComplete <= initComplete; next_memAddr <= memAddr; next_memRdEn <= memRdEn; next_txDataSize <= txDataSize; next_txDataIndex <= txDataIndex; next_transDone <= transDone; next_epStatus <= epStatus; next_rxDataSize <= rxDataSize; next_epTransType <= epTransType; next_bm_req_dir <= bm_req_dir; next_bm_req_type <= bm_req_type; next_bm_req_recp <= bm_req_recp; next_bRequest <= bRequest; next_wValue <= wValue; next_wIndex <= wIndex; next_wLength <= wLength; next_txPacketRemSize <= txPacketRemSize; next_USBAddress <= USBAddress; next_updateUSBAddress <= updateUSBAddress; next_dataSeq <= dataSeq; case (CurrState_EP0St) // synopsys parallel_case full_case `START: begin next_initComplete <= 1'b0; next_wbBusReq <= 1'b0; next_wb_addr <= 8'h00; next_wb_data_o <= 8'h00; next_wb_stb <= 1'b0; next_wb_we <= 1'b0; next_txPacketRemSize <= 8'h00; next_txDataSize <= 8'h00; next_txDataIndex <= 8'h00; next_epTransType <= 8'h00; next_epStatus <= 8'h00; next_rxDataSize <= 16'h0000; next_cnt <= 8'h00; next_memRdEn <= 1'b0; next_memAddr <= 8'h00; next_updateUSBAddress <= 1'b0; next_transDone <= 1'b0; next_bm_req_type <= 2'b00; next_bm_req_dir <= 1'b0; next_bm_req_recp <= 5'b00000; next_bRequest <= 8'h00; next_wLength <= 16'h0000; next_wIndex <= 16'h0000; next_wValue <= 16'h0000; next_dataSeq <= 1'b0; next_USBAddress <= 8'h00; NextState_EP0St <= `INIT_WT_GNT; end `CHK_TRANS_RD_STAT: begin next_wb_addr <= `RA_EP0_STATUS_REG; next_wb_stb <= 1'b1; next_wb_we <= 1'b0; if (wb_ack == 1'b1) begin NextState_EP0St <= `CHK_TRANS_RD_RX_SIZE1; next_wb_stb <= 1'b0; next_epStatus <= wb_data_i; end end `CHK_TRANS_WT_GNT: begin if (wbBusGnt == 1'b1) begin NextState_EP0St <= `CHK_TRANS_RD_STAT; end end `CHK_TRANS_RD_RX_SIZE1: begin next_wb_addr <= `RA_EP0_RX_FIFO_DATA_COUNT_MSB; next_wb_stb <= 1'b1; next_wb_we <= 1'b0; if (wb_ack == 1'b1) begin NextState_EP0St <= `CHK_TRANS_RD_RX_SIZE2; next_wb_stb <= 1'b0; next_rxDataSize[15:8] <= wb_data_i; end end `CHK_TRANS_RD_RX_SIZE2: begin next_wb_addr <= `RA_EP0_RX_FIFO_DATA_COUNT_LSB; next_wb_stb <= 1'b1; next_wb_we <= 1'b0; if (wb_ack == 1'b1) begin NextState_EP0St <= `CHK_TRANS_RD_TRANS_TYPE; next_wb_stb <= 1'b0; next_rxDataSize[7:0] <= wb_data_i; end end `CHK_TRANS_RD_TRANS_TYPE: begin next_wb_addr <= `RA_EP0_TRANSTYPE_STATUS_REG; next_wb_stb <= 1'b1; next_wb_we <= 1'b0; if (wb_ack == 1'b1) begin NextState_EP0St <= `CHK_TRANS_WT_UNGNT; next_wb_stb <= 1'b0; next_epTransType <= wb_data_i; end end `CHK_TRANS_WT_UNGNT: begin next_wbBusReq <= 1'b0; if ((wbBusGnt == 1'b0) && ((epStatus & 8'h0f) != 8'h00)) begin NextState_EP0St <= `DO_TRANS_WT_GNT; end else if ((wbBusGnt == 1'b0) && (epTransType == `SC_SETUP_TRANS)) begin NextState_EP0St <= `SETUP_CHK_ERR; end else if ((wbBusGnt == 1'b0) && (epTransType == `SC_IN_TRANS)) begin NextState_EP0St <= `IN_CHK_ACK; end else if ((wbBusGnt == 1'b0) && (epTransType == `SC_OUTDATA_TRANS)) begin NextState_EP0St <= `OUT_CHK_SEQ; end else if (wbBusGnt == 1'b0) begin NextState_EP0St <= `DO_TRANS_WT_GNT; end end `DO_TRANS_WT_GNT: begin next_wbBusReq <= 1'b1; if (wbBusGnt == 1'b1) begin NextState_EP0St <= `DO_TRANS_TX_EMPTY; end end `DO_TRANS_TX_EMPTY: begin next_wb_addr <= `RA_EP0_TX_FIFO_CONTROL_REG; next_wb_data_o <= 8'h01; //force tx fifo empty next_wb_stb <= 1'b1; next_wb_we <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `DO_TRANS_RX_EMPTY; next_wb_stb <= 1'b0; end end `DO_TRANS_WR_TX_FIFO: begin next_wb_data_o <= memData; next_wb_addr <= `RA_EP0_TX_FIFO_DATA_REG; next_wb_stb <= 1'b1; next_wb_we <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `DO_TRANS_CHK_TX_DONE; next_wb_stb <= 1'b0; end end `DO_TRANS_RD_MEM: begin next_memAddr <= txDataIndex; next_memRdEn <= 1'b1; next_txDataSize <= txDataSize - 1'b1; next_txDataIndex <= txDataIndex + 1'b1; NextState_EP0St <= `DO_TRANS_DEL; end `DO_TRANS_CHK_TX_DONE: begin if (txDataSize == 8'h00) begin NextState_EP0St <= `DO_TRANS_TRANS_GO; end else begin NextState_EP0St <= `DO_TRANS_RD_MEM; end end `DO_TRANS_TRANS_GO: begin next_wb_addr <= `RA_EP0_CONTROL_REG; if (dataSeq == 1'b1) next_wb_data_o <= 8'h07; else next_wb_data_o <= 8'h03; next_wb_stb <= 1'b1; next_wb_we <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `DO_TRANS_WT_TRANS_DONE_WT_GNT; next_wb_stb <= 1'b0; next_transDone <= 1'b0; end end `DO_TRANS_RX_EMPTY: begin next_wb_addr <= `RA_EP0_RX_FIFO_CONTROL_REG; next_wb_data_o <= 8'h01; //force rx fifo empty next_wb_stb <= 1'b1; next_wb_we <= 1'b1; if ((wb_ack == 1'b1) && (txDataSize != 8'h00)) begin NextState_EP0St <= `DO_TRANS_RD_MEM; next_wb_stb <= 1'b0; end else if (wb_ack == 1'b1) begin NextState_EP0St <= `DO_TRANS_TRANS_GO; next_wb_stb <= 1'b0; end end `DO_TRANS_DEL: begin next_memRdEn <= 1'b0; NextState_EP0St <= `DO_TRANS_WR_TX_FIFO; end `DO_TRANS_WT_TRANS_DONE_WT_GNT: begin next_wbBusReq <= 1'b1; if (wbBusGnt == 1'b1) begin NextState_EP0St <= `DO_TRANS_WT_TRANS_DONE_GET_RDY_STS; end end `DO_TRANS_WT_TRANS_DONE_GET_RDY_STS: begin next_wb_addr <= `RA_EP0_CONTROL_REG; next_wb_stb <= 1'b1; next_wb_we <= 1'b0; if (wb_ack == 1'b1) begin NextState_EP0St <= `DO_TRANS_WT_TRANS_DONE_WT_UNGNT; next_wb_stb <= 1'b0; next_transDone <= ~wb_data_i[`ENDPOINT_READY_BIT]; end end `DO_TRANS_WT_TRANS_DONE_WT_UNGNT: begin next_wbBusReq <= 1'b0; if (wbBusGnt == 1'b0) begin NextState_EP0St <= `DO_TRANS_WT_TRANS_DONE_CHK_DONE; end end `DO_TRANS_WT_TRANS_DONE_CHK_DONE: begin if (transDone == 1'b1) begin NextState_EP0St <= `CHK_TRANS_WT_GNT; next_wbBusReq <= 1'b1; end else begin NextState_EP0St <= `DO_TRANS_WT_TRANS_DONE_DEL; next_cnt <= 8'h00; end end `DO_TRANS_WT_TRANS_DONE_DEL: begin next_cnt <= cnt + 1'b1; if (cnt == `ONE_USEC_DEL) begin NextState_EP0St <= `DO_TRANS_WT_TRANS_DONE_WT_GNT; end end `SETUP_CHK_ERR: begin if (rxDataSize != 16'h0008) begin NextState_EP0St <= `DO_TRANS_WT_GNT; end else begin NextState_EP0St <= `SETUP_GET_DATA_WT_GNT; next_wbBusReq <= 1'b1; next_txDataSize <= 8'h00; next_txPacketRemSize <= 8'h00; //default tx packet size next_dataSeq <= 1'b1; next_wb_addr <= `RA_EP0_RX_FIFO_DATA_REG; next_wb_we <= 1'b0; end end `SETUP_GET_STAT: begin if (bm_req_type == 2'b00) begin next_txPacketRemSize <= 8'h02; if (bm_req_recp == 5'b00000) next_txDataIndex <= `ONE_ZERO_STAT_INDEX; else next_txDataIndex <= `ZERO_ZERO_STAT_INDEX; end else if (bm_req_type == 2'b10) begin next_txDataIndex <= `VENDOR_DATA_STAT_INDEX; next_txPacketRemSize <= 8'h02; end NextState_EP0St <= `SETUP_CHK_MAX_LEN; end `SETUP_SET_ADDR: begin if ( (wValue[15:7] == {9{1'b0}}) && (wIndex == 16'h0000) && (wLength == 16'h0000) ) begin next_USBAddress <= wValue[7:0]; next_updateUSBAddress <= 1'b1; end NextState_EP0St <= `SETUP_CHK_MAX_LEN; end `SETUP_CHK_MAX_LEN: begin if (txPacketRemSize > wLength) next_txPacketRemSize <= wLength; NextState_EP0St <= `SETUP_PTR_SET; end `SETUP_PTR_SET: begin if (txPacketRemSize > `MAX_RESP_SIZE) begin next_txDataSize <= `MAX_RESP_SIZE; next_txPacketRemSize <= txPacketRemSize - `MAX_RESP_SIZE; end else begin next_txDataSize <= txPacketRemSize; next_txPacketRemSize <= 8'h00; end NextState_EP0St <= `DO_TRANS_WT_GNT; end `SETUP_GET_DATA_DAT1: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT2; next_wb_stb <= 1'b0; next_bm_req_dir <= wb_data_i[7]; next_bm_req_type <= wb_data_i[6:5]; next_bm_req_recp <= wb_data_i[4:0]; end end `SETUP_GET_DATA_WT_GNT: begin if (wbBusGnt == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT1; end end `SETUP_GET_DATA_DAT2: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT3; next_wb_stb <= 1'b0; next_bRequest <= wb_data_i; end end `SETUP_GET_DATA_DAT3: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT4; next_wb_stb <= 1'b0; next_wValue[7:0] <= wb_data_i; end end `SETUP_GET_DATA_DAT4: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT5; next_wb_stb <= 1'b0; next_wValue[15:8] <= wb_data_i; end end `SETUP_GET_DATA_DAT6: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT7; next_wb_stb <= 1'b0; next_wIndex[15:8] <= wb_data_i; end end `SETUP_GET_DATA_DAT5: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT6; next_wb_stb <= 1'b0; next_wIndex[7:0] <= wb_data_i; end end `SETUP_GET_DATA_DAT8: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_WT_UNGNT; next_wb_stb <= 1'b0; next_wLength[15:8] <= wb_data_i; next_wbBusReq <= 1'b0; end end `SETUP_GET_DATA_DAT7: begin next_wb_stb <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `SETUP_GET_DATA_DAT8; next_wb_stb <= 1'b0; next_wLength[7:0] <= wb_data_i; end end `SETUP_GET_DATA_WT_UNGNT: begin if ((wbBusGnt == 1'b0) && (bRequest == `GET_STATUS)) begin NextState_EP0St <= `SETUP_GET_STAT; end else if ((wbBusGnt == 1'b0) && (bRequest == `GET_DESCRIPTOR)) begin NextState_EP0St <= `SETUP_GET_DESC_S1; end else if ((wbBusGnt == 1'b0) && (bRequest == `SET_ADDRESS)) begin NextState_EP0St <= `SETUP_SET_ADDR; end else if (wbBusGnt == 1'b0) begin NextState_EP0St <= `DO_TRANS_WT_GNT; end end `SETUP_GET_DESC_S1: begin case (wValue[15:8]) `DEV_DESC: begin next_txPacketRemSize <= `DEV_DESC_SIZE; next_txDataIndex <= `DEV_DESC_INDEX; end `CFG_DESC: begin next_txPacketRemSize <= `CFG_DESC_SIZE; next_txDataIndex <= `CFG_DESC_INDEX; end `REP_DESC: begin next_txPacketRemSize <= `REP_DESC_SIZE; next_txDataIndex <= `REP_DESC_INDEX; end `STRING_DESC: begin case (wValue[3:0]) 4'h0: begin next_txPacketRemSize <= `LANGID_DESC_SIZE; next_txDataIndex <= `LANGID_DESC_INDEX; end 4'h1: begin next_txPacketRemSize <= `STRING1_DESC_SIZE; next_txDataIndex <= `STRING1_DESC_INDEX; end 4'h2: begin next_txPacketRemSize <= `STRING2_DESC_SIZE; next_txDataIndex <= `STRING2_DESC_INDEX; end 4'h3: begin next_txPacketRemSize <= `STRING3_DESC_SIZE; next_txDataIndex <= `STRING3_DESC_INDEX; end endcase end endcase NextState_EP0St <= `SETUP_CHK_MAX_LEN; end `IN_CHK_ACK: begin if (epStatus[`SC_ACK_RXED_BIT] != 1'b1) begin NextState_EP0St <= `DO_TRANS_WT_GNT; end else if (updateUSBAddress == 1'b1) begin NextState_EP0St <= `IN_WT_GNT; end else begin NextState_EP0St <= `IN_SET_PTR; end end `IN_SET_PTR: begin if (txPacketRemSize > `MAX_RESP_SIZE) begin next_txDataSize <= `MAX_RESP_SIZE; next_txPacketRemSize <= txPacketRemSize - `MAX_RESP_SIZE; end else begin next_txDataSize <= txPacketRemSize; next_txPacketRemSize <= 8'h00; end NextState_EP0St <= `DO_TRANS_WT_GNT; end `IN_SET_ADDR: begin next_wb_addr <= `RA_SC_ADDRESS; next_wb_data_o <= USBAddress; next_wb_stb <= 1'b1; next_wb_we <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `IN_WT_UNGNT; next_wb_stb <= 1'b0; next_wbBusReq <= 1'b0; end end `IN_WT_GNT: begin next_wbBusReq <= 1'b1; next_updateUSBAddress <= 1'b0; if (wbBusGnt == 1'b1) begin NextState_EP0St <= `IN_SET_ADDR; end end `IN_WT_UNGNT: begin if (wbBusGnt == 1'b0) begin NextState_EP0St <= `IN_SET_PTR; end end `OUT_CHK_SEQ: begin if (epStatus[`SC_DATA_SEQUENCE_BIT] != dataSeq) begin NextState_EP0St <= `DO_TRANS_WT_GNT; end else begin NextState_EP0St <= `DO_TRANS_WT_GNT; next_dataSeq <= ~dataSeq; end end `INIT_RST: begin next_wb_addr <= `RA_HOST_SLAVE_MODE; next_wb_data_o <= 8'h2; //reset usbHostSlave next_wb_stb <= 1'b1; next_wb_we <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `INIT_WT_RST; next_wb_stb <= 1'b0; next_cnt <= 8'h00; end end `INIT_WT_GNT: begin next_wbBusReq <= 1'b1; if (wbBusGnt == 1'b1) begin NextState_EP0St <= `INIT_RST; end end `INIT_WT_RST: begin next_cnt <= cnt + 1'b1; if (cnt == 8'hff) begin NextState_EP0St <= `INIT_WT_VBUS; end end `INIT_WT_VBUS: begin next_wb_addr <= `RA_SC_LINE_STATUS_REG; next_wb_stb <= 1'b1; next_wb_we <= 1'b0; if ((wb_ack == 1'b1) && (wb_data_i[`VBUS_PRES_BIT] == 1'b1)) begin NextState_EP0St <= `INIT_CONN; next_wb_stb <= 1'b0; end end `INIT_FIN: begin next_wbBusReq <= 1'b0; next_initComplete <= 1'b1; if (wbBusGnt == 1'b0) begin NextState_EP0St <= `DO_TRANS_WT_GNT; end end `INIT_CONN: begin next_wb_addr <= `RA_SC_CONTROL_REG; next_wb_data_o <= 8'h71; //connect to host, full speed next_wb_stb <= 1'b1; next_wb_we <= 1'b1; if (wb_ack == 1'b1) begin NextState_EP0St <= `INIT_WT_CONN; next_wb_stb <= 1'b0; end end `INIT_WT_CONN: begin next_wb_addr <= `RA_SC_LINE_STATUS_REG; next_wb_stb <= 1'b1; next_wb_we <= 1'b0; if ((wb_ack == 1'b1) && (wb_data_i[1:0] == `FULL_SPEED_CONNECT)) begin NextState_EP0St <= `INIT_FIN; next_wb_stb <= 1'b0; end end endcase end // Current State Logic (sequential) always @ (posedge clk) begin if (rst == 1'b1) CurrState_EP0St <= `START; else CurrState_EP0St <= NextState_EP0St; end // Registered outputs logic always @ (posedge clk) begin if (rst == 1'b1) begin wb_addr <= 8'h00; wb_data_o <= 8'h00; wb_stb <= 1'b0; wb_we <= 1'b0; wbBusReq <= 1'b0; initComplete <= 1'b0; memAddr <= 8'h00; memRdEn <= 1'b0; cnt <= 8'h00; txDataSize <= 8'h00; txDataIndex <= 8'h00; transDone <= 1'b0; epStatus <= 8'h00; rxDataSize <= 16'h0000; epTransType <= 8'h00; bm_req_dir <= 1'b0; bm_req_type <= 2'b00; bm_req_recp <= 5'b00000; bRequest <= 8'h00; wValue <= 16'h0000; wIndex <= 16'h0000; wLength <= 16'h0000; txPacketRemSize <= 8'h00; USBAddress <= 8'h00; updateUSBAddress <= 1'b0; dataSeq <= 1'b0; end else begin wb_addr <= next_wb_addr; wb_data_o <= next_wb_data_o; wb_stb <= next_wb_stb; wb_we <= next_wb_we; wbBusReq <= next_wbBusReq; initComplete <= next_initComplete; memAddr <= next_memAddr; memRdEn <= next_memRdEn; cnt <= next_cnt; txDataSize <= next_txDataSize; txDataIndex <= next_txDataIndex; transDone <= next_transDone; epStatus <= next_epStatus; rxDataSize <= next_rxDataSize; epTransType <= next_epTransType; bm_req_dir <= next_bm_req_dir; bm_req_type <= next_bm_req_type; bm_req_recp <= next_bm_req_recp; bRequest <= next_bRequest; wValue <= next_wValue; wIndex <= next_wIndex; wLength <= next_wLength; txPacketRemSize <= next_txPacketRemSize; USBAddress <= next_USBAddress; updateUSBAddress <= next_updateUSBAddress; dataSeq <= next_dataSeq; end end endmodule