ApiDetails

See also API concept.

An optionally activatable macro CHECK_RULES(...) is used to check optional some design rules. This makes simulation slower but checks some parameters for correct usage and e.g. checks if there was a completion if needed.

For code documentation see doxygen documentation and code in the svn https://svn.greensocs.com/local/greensocs/packages/greenbus

Example Sender

  1.  // //////// Memory Read ///////////
  2.   dat = new std::vector<gs_uint8>(data_size+100); // +100 for test purpose
  3.  
  4.   ah = mAPI.create_transaction();
  5.   // Make Memory Read TLP
  6.   ah->init_Memory_Read( targetAddr, *dat, data_size ); // read data_size bytes from address targetAddr to vector dat
  7.   mAPI.send_transaction(ah);
  8.  
  9.   PCIeDEBUG("process completion:");
  10.   if (ah->get_Completion_Status() == SuccessfulCompletion) {
  11.     cout << "  Completion status: successfull"<<endl;
  12.     cout << "  Completion answered by completer's function no. "<< (unsigned int) ah->get_completers_Function_Number()<<endl;
  13.  
  14.     PCIeDEBUG("read data:");
  15.     cout << "                            ";
  16.     for (unsigned int i = 0; i < data_size; i++) {
  17.       cout << (unsigned int)(dat->at(i)) << " ";
  18.     }
  19.     cout << endl;
  20.   } else
  21.     cout << "  Completion status: not successfull ("<<(unsigned int)ah->get_Completion_Status() <<dec<<")"<<endl;

Example Receiver

  1. void PCIeRecvDevice::b_transact(PCIeTransactionHandle th) {
  2.   PCIeDEBUG("b_transact: received transaction");
  3.   PCIeSlaveAccessHandle ah = _getSlaveAccessHandle(th);
  4.  
  5.   unsigned int cmd = ah->get_TLP_type();
  6.   switch(cmd) {
  7.  
  8.     case MemRead:
  9.       {
  10.         // Process data
  11.         std::vector<gs_uint8> *dat;
  12.         dat = &(ah->getMData().getData());
  13.         for (unsigned int i = 0; i < ah->getMBurstLength(); i++) {
  14.           dat->at(i) = i+100;
  15.         }
  16.         // Send Completion
  17.         ah->init_Memory_Read_Completion(SuccessfulCompletion, 3);
  18.       }
  19.       break;

Root Complex

The Root Complex is a device with an internal PCIe switch. To help the user with implementing the Root Complex there is a class PCIeRootComplex (see greenbus/api/PCIe/PCIeRootComplex.h). This derives from the PCIeRouter class, accordingly the user is able to connect devices and switches to its Downstream Port. Do not connect the Upstream Port: it is bound internally to the down_to_router_port which is another PCIeAPI port. That port is the connection to PCIe and should be used by the user to implement the Root Complex functionality.

At minimum the user has to implement the method PCIeRootComplex::down_to_router_port_b_transact(PCIeTransactionHandle th). To be able to extend the Root Complex the user should derive from this class, e.g. MyPCIeRootComplex. See greenbus/examples/PCIe/platform for an example.

  • The PCIeRootComplex is a PCIeRouter.
  • Use Downstream Port to connect the PCIe tree topology.
  • Do not use the Upstream Port which is connected internally.
  • Use the port down_to_router_port to access the PCIe topology.
  • Implement down_to_router_port_b_transact to handle incoming TLPs from the PCIe topology.
  • Derive from PCIeRootComplex to extend functionality, e.g. to add a SC_METHOD.