📄 usbhostslavetb.cpp
字号:
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 + -