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

📄 usbhostslavetb.cpp

📁 包括USB
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  case 0x3: //endpoint enabled, and ready
    readXCReg(SLAVE, tempDataFromHost, endPointStatusRegAddress, dataSeqeunceBit , 0xff);  //expecting no errors at the slave
    if ((endPControlReg & (1 << ENDPOINT_ISO_ENABLE_BIT)) == 0)    //if not iso mode
      readXCReg(HOST, tempDataFromHost, RX_STATUS_REG, (1 << ACK_RXED_BIT), 0xff);  //expecting host to receive ACK
    //if ENDPOINT_ISO_ENABLE_BIT == 1 then no response form slave, no need to check RX_STATUS_REG
    break;
  case 0xb: //endpoint enabled, ready, send stall.
    readXCReg(SLAVE, tempDataFromHost, endPointStatusRegAddress, (1 << SC_STALL_SENT_BIT) | dataSeqeunceBit, 0xff);  //expecting slave to send stall
    readXCReg(HOST, tempDataFromHost, RX_STATUS_REG, (1 << STALL_RXED_BIT), 0xff);  //expecting host to receive STALL
    break;
  default:
    printf("sendTransaction: Umimplemented endPControlReg 0x%0x\n", USBEndPoint);
    quit(1);
    break;
  }
  if (errorDetected == 1) 
    quit(1);
}

/* ------------------------------- rxTransaction ---------------------------------- */

void usbHostSlaveTB::rxTransaction(int USBAddress, int USBEndPoint, int transType, int dataSize, int dataGenType, int waitTime, int endPControlReg)
{
  int i;
  int endPointStatusRegAddress;
  int endPointTransTypeRegAddress;
  int endPointControlRegAddress;
  int endPointNAKTransTypeRegAddress;
  int tempDataFromHost;
  int tempDataFromHost2;
  int fifoBaseAddress;
  int expectedTransTypeAtSlave;
  int numOfElementsInRXFifo;
  int data [64];
  int dataSequenceBitAtHost;
  int expectedDataCnt;
  int errorDetected;
  
  
  errorDetected = 0;
  switch (dataGenType)
  {
    case NO_GEN:
      //data payload provided by caller. Do nothing
      break;
    case SEQ_GEN:
      for (i=0;i<dataSize;i++)

        data[i] = i;
      break;
    case RAND_GEN:
      for (i=0;i<dataSize;i++)
        data[i] = rand() & 0xff;
      break;
    default:
      printf("(sendTransaction) dataGenType = 0x%0x not a valid type\n", dataGenType);
      quit(1);
      break;
  }
  expectedTransTypeAtSlave = SC_IN_TRANS;
  PRT("INDATA transaction, with a " << dataSize << " byte data packet\n");
  endPointStatusRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + ENDPOINT_STATUS_REG;
  endPointTransTypeRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + ENDPOINT_TRANSTYPE_STATUS_REG;
  endPointControlRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + ENDPOINT_CONTROL_REG;
  endPointNAKTransTypeRegAddress = (NUM_OF_REGISTERS_PER_ENDPOINT * USBEndPoint) + NAK_TRANSTYPE_STATUS_REG;

  writeXCReg(SLAVE, endPControlReg, endPointControlRegAddress);
  writeXCReg(HOST, USBAddress, TX_ADDR_REG);
  writeXCReg(HOST, USBEndPoint, TX_ENDP_REG);
  writeXCReg(HOST, transType, TX_TRANS_TYPE_REG);
  switch (USBEndPoint)
  {
    case 0:
      fifoBaseAddress = EP0_TX_FIFO_BASE;
      break;
    case 1:
      fifoBaseAddress = EP1_TX_FIFO_BASE;
      break;
    case 2:
      fifoBaseAddress = EP2_TX_FIFO_BASE;
      break;
    case 3:
      fifoBaseAddress = EP3_TX_FIFO_BASE;
      break;
    default:
      printf("Invalid endpoint 0x%0x \n", USBEndPoint);
      quit(1);
      break;
  }

  for (i=0; i<dataSize; i++)
    slaveBusWrite(data[i], fifoBaseAddress + FIFO_DATA_REG);
  writeXCReg(HOST, (1 << TRANS_REQ_BIT), TX_CONTROL_REG);
  waitUSBClockTicks(500+dataSize*100);   //suspend test bench so that DUT can process the packet


  expectedDataCnt = 0;
  if ( (endPControlReg & (1 << ENDPOINT_ENABLE_BIT) ) != 0) {
    if ( (endPControlReg & (1 << ENDPOINT_READY_BIT) ) != 0) {
      expectedDataCnt = dataSize;
      readXCReg(SLAVE, tempDataFromHost, SC_INTERRUPT_STATUS_REG, (1 << SC_TRANS_DONE_BIT), 0xff);
      readXCReg(SLAVE, tempDataFromHost, endPointTransTypeRegAddress, expectedTransTypeAtSlave, 0xff);  //expecting 'expectedTransTypeAtSlave' transaction
    }
    else {
      readXCReg(SLAVE, tempDataFromHost, SC_INTERRUPT_STATUS_REG, (1 << SC_NAK_SENT_INT_BIT), 0xff);
      readXCReg(SLAVE, tempDataFromHost, endPointNAKTransTypeRegAddress, expectedTransTypeAtSlave, 0xff);  //expecting 'expectedTransTypeAtSlave' transaction
    }
  }
  readXCReg(HOST, tempDataFromHost, INTERRUPT_STATUS_REG, (1 << TRANS_DONE_BIT), 0xff);

  hostBusRead(tempDataFromHost, HOST_RX_FIFO_BASE + FIFO_DATA_COUNT_MSB);
  hostBusRead(tempDataFromHost2, HOST_RX_FIFO_BASE + FIFO_DATA_COUNT_LSB);
  numOfElementsInRXFifo = (tempDataFromHost * 256) +  tempDataFromHost2;
  PRT("Host RX FIFO has " << numOfElementsInRXFifo << " elements\n");
  if (expectedDataCnt != numOfElementsInRXFifo) {
    printf("Data packet incorrect size. Expected %d bytes, received %d bytes\n", expectedDataCnt, numOfElementsInRXFifo);
    errorDetected = 1;
  }
  for (i=0;i<numOfElementsInRXFifo;i++) {
    hostBusRead(tempDataFromHost, HOST_RX_FIFO_BASE + FIFO_DATA_REG);
    if (tempDataFromHost != data[i]) {
      printf("Data mismatch.  TX data [0x%0x] = 0x%0x RX data[0x%0x] = 0x%0x. Aborting\n", i, data[i], i, tempDataFromHost);
      errorDetected = 1;
    }
    //printf("RX data[" << i << "] = " << hex << tempDataFromHost << "\n");
  }

  if (numOfElementsInRXFifo > 0 && errorDetected == 0)
    PRT("RX packet matches TX packet\n");
  cancelInterrupt(SLAVE, SC_TRANS_DONE_BIT);

  cancelInterrupt(SLAVE, SC_NAK_SENT_INT_BIT);
  cancelInterrupt(HOST, TRANS_DONE_BIT);
  readXCReg(HOST, tempDataFromHost, TX_CONTROL_REG, 0, (1 << TRANS_REQ_BIT)); //check that the bit was set
  printf("TX_CONTROL_REG = 0x%0x\n", tempDataFromHost);


  if (endPControlReg & (1 << ENDPOINT_OUTDATA_SEQUENCE_BIT) )
    dataSequenceBitAtHost = 1 << DATA_SEQUENCE_BIT;
  else
    dataSequenceBitAtHost = 0;
  switch (endPControlReg & 0xb)
  {
  case 0x0:  //endpoint disabled
  case 0x2:  //endpoint ready, but disabled. Not a valid control state, but disable should pre-dominate
    readXCRegNoQuit(HOST, tempDataFromHost, RX_STATUS_REG, (1 << RX_TIME_OUT_BIT), 0xff, errorDetected);  //expecting host to receive time out
    slaveBusWrite(0x1, fifoBaseAddress + FIFO_CONTROL_REG);     //force the slave tx fifo empty
    break;
  case 0x1:  //endpoint enabled, but not ready
    readXCRegNoQuit(SLAVE, tempDataFromHost, endPointStatusRegAddress, (1 << SC_NAK_SENT_BIT), (1 << SC_NAK_SENT_BIT), errorDetected);  //expecting slave to send NAK
    readXCRegNoQuit(HOST, tempDataFromHost, RX_STATUS_REG, (1 << NAK_RXED_BIT), 0xff, errorDetected);  //expecting NAK at host
    slaveBusWrite(0x1, fifoBaseAddress + FIFO_CONTROL_REG);     //force the slave tx fifo empty
    break;
  case 0x3: //endpoint enabled, and ready
    readXCRegNoQuit(SLAVE, tempDataFromHost, endPointStatusRegAddress, (1 << SC_ACK_RXED_BIT) , 0xff, errorDetected);  //expecting slave to receive ACK
    readXCRegNoQuit(HOST, tempDataFromHost, RX_STATUS_REG, dataSequenceBitAtHost, 0xff, errorDetected);  //expecting no errors at the host
    break;
  case 0xb: //endpoint enabled, ready, send stall.
    printf("rxTransaction: Unexpected endPControlReg = 0x%0x \n", endPControlReg);
    errorDetected = 1;
    break;
  default:
    printf("rxTransaction: Unimplemented endPControlReg 0x%0x \n", USBEndPoint);
    errorDetected = 1;
    break;
  }
  if (errorDetected == 1)
    quit(1);
}

/* ------------------------------- quit ---------------------------------- */
void usbHostSlaveTB::quit(int errorLevel)
{
  if (errorLevel != 0)
    cout << "Verification ERROR. Simulation stopped\n";
#ifdef SYSTEMC_TB
  sc_stop();
#else
  exit(errorLevel);
#endif
}


/* -------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------------- */
/* ------- SystemC port accesses, and SystemC wait calls are below this line ------ */
/* -------------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------------- */


/* ------------------------------- slaveBusWrite ---------------------------------- */
void usbHostSlaveTB::slaveBusWrite(int data, int regAddress)
{
#ifdef SYSTEMC_TB
  slaveTransPort->busWrite(data, regAddress);
#else  
  busPort->writeSlave(data, regAddress);
#endif
}



/* ------------------------------- hostBusWrite ---------------------------------- */
void usbHostSlaveTB::hostBusWrite(int data, int regAddress)
{
#ifdef SYSTEMC_TB
  hostTransPort->busWrite(data, regAddress);
#else
  busPort->writeHost(data, regAddress);
#endif
}

/* ------------------------------- slaveBusRead ---------------------------------- */
void usbHostSlaveTB::slaveBusRead(int &data, int regAddress)
{
#ifdef SYSTEMC_TB
  slaveTransPort->busRead(data, regAddress);
#else
  busPort->readSlave(data, regAddress);
#endif
}

/* ------------------------------- hostBusRead ---------------------------------- */
void usbHostSlaveTB::hostBusRead(int &data, int regAddress)
{
#ifdef SYSTEMC_TB
  hostTransPort->busRead(data, regAddress);
#else
  busPort->readHost(data, regAddress);
#endif
}

/* ------------------------------- waitUSBClockTicks ---------------------------------- */
void usbHostSlaveTB::waitUSBClockTicks(int waitTicks)
{
  int i;
 
#ifdef SYSTEMC_TB
  //can use the 'hostTransPort' or 'slaveTransPort' does not matter
  hostTransPort->waitUSBClockTicks(waitTicks);
#else
  i=0;
  while (i<waitTicks) {
    i++;
  }
  
#endif
  
}



/* ------------------------------- usbLineControl ---------------------------------- */
void usbHostSlaveTB::usbLineControl(int lineState)
{
#ifdef SYSTEMC_TB
  usbLineDefaultState.write((sc_lv<2>) lineState);

#else
#ifdef UCLINUX_TB
#else
  IOWR_ALTERA_AVALON_PIO_DATA(USB_PU_CTL_BASE, 0x3); 
  IOWR_ALTERA_AVALON_PIO_DIRECTION(USB_PU_CTL_BASE_ADDR, lineState);
#endif 
#endif
}

/* ------------------------------- systemRstCtrl ---------------------------------- */
void usbHostSlaveTB::systemRstCtrl()
{
#ifdef SYSTEMC_TB
  hostTransPort->initialize();
  slaveTransPort->initialize();
#else
#ifdef UCLINUX_TB
#else
#endif 
#endif
}



⌨️ 快捷键说明

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