OpenCores
URL https://opencores.org/ocsvn/usbhostslave/usbhostslave/trunk

Subversion Repositories usbhostslave

[/] [usbhostslave/] [trunk/] [usbDevice/] [RTL/] [EP0.v] - Rev 43

Go to most recent revision | 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

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.