Exemplo n.º 1
0
// --------------------------------------------------------------
//
// We could use print() (from the scv_extensions utility interface)
// in place of this function.  However, the interest in this function
// is not so much what it does, but to demonstrate how to access
// functions within classes from higher levels in the program.
//
void packet::dump(void) const {
  const scv_extensions<packet> p = scv_get_const_extensions(*this);
  cout << "  " << p.ptype.get_enum_string(p.ptype);

  cout << " " << source;
  cout << " " << destination << endl;
}
Exemplo n.º 2
0
void print_fields(const T& data) {

  // need a copy of the extension that persists until the end
  const scv_extensions<T> ext = scv_get_const_extensions(data);

  // print values in the fields
  int size = ext.get_num_fields();
  if (size) {
    cout << "Printing field values..." << endl;
    for (int i=0; i<size; ++i) {
      const scv_extensions_if * field = ext.get_field(i);
      if (field->is_integer())
	cout << "field \"" << field->get_name()
	     << "\" has value " << field->get_integer() << "." << endl;
    }
  }
}
Exemplo n.º 3
0
// ----------------------------------------
// example usage
//
// what the user writing a testbench would manipulate
// their composite types.
// ----------------------------------------
sctop::sctop(sc_module_name name) : sc_module(name)
{

  // tb_startup();

  // ----------------------------------------
  // static extension (does not require extra storage space in a packet)
  // ----------------------------------------
  packet_t p;
  // Define the characteristics for this structure, then make sure introspection agrees
  int numFields = 4;
  std::string fieldNames[] = {
	  "packet_type",
	  "src",
	  "dest",
	  "payload"
  };
  int fieldValues[] = {0, 0, 1, 2};
  int errorCount = 0;

  // Initialize the fields
  p.packet_type = fieldValues[0];
  p.src = fieldValues[1];
  p.dest = fieldValues[2];
  p.payload = fieldValues[3];

  // Check introspection functions
  const scv_extensions<packet_t> ext = scv_get_const_extensions(p);
  int size = ext.get_num_fields();
  if (size != numFields) {
	  errorCount++;
	  cout << TBS_ERROR << "Number of fields is " << size << ", should be " << numFields << endl;
  } else {
	  cout << TBS_INFO << "Number of fields is " << size << endl;
  }
  if (size > 0 && size <= numFields) {
	  for (int i=0; i<size; ++i) {
		  const scv_extensions_if * field = ext.get_field(i);
		  if (field == NULL) {
			  errorCount++;
			  cout << TBS_ERROR << "Field " << i << " not found" << endl;
		  } else if (fieldNames[i] != field->get_name()) {
			  errorCount++;
			  cout << TBS_ERROR << "Field " << i << " should have name " << fieldNames[i] << ", instead has name " << field->get_name() << endl;
		  } else if (!field->is_integer()) {
			  errorCount++;
			  cout << TBS_ERROR << "Expected " << fieldNames[i] << " to be of type integer" << endl;
		  } else {
			  if (field->get_integer() != fieldValues[i]) {
				  errorCount++;
				  cout << TBS_ERROR << "Expected value " << fieldValues[i] << " for field " << fieldNames[i] << " found to instead be " << field->get_integer() << endl;
			  } else {
				  cout << TBS_INFO << "Field " << i << " okay" << endl;
			  }			  
		  }
	  }
  }

  // ----------------------------------------
  // dynamic extension (allow attachment of callbacks,
  // uninitialized values, constraints, etc.)
  //
  // - require the use of scv_smart_ptr template.
  // ----------------------------------------

  // randomization (direct) (VWG R3d, Rb1)
  scv_smart_ptr<packet_t> pp;
  scv_shared_ptr<scv_random> g(new scv_random("gen", RND_SEED));
  pp->set_random(g);

  //
  // Check introspection functions
  //

  fieldValues[0] = 17;
  fieldValues[1] = 34;
  fieldValues[2] = 63;
  fieldValues[3] = -13;
  pp->packet_type = fieldValues[0];
  pp->src = fieldValues[1];
  pp->dest = fieldValues[2];
  pp->payload = fieldValues[3];
  scv_extensions_if *ppExt = pp.get_extensions_ptr();
  size = ppExt->get_num_fields();
  if (size != numFields) {
	  errorCount++;
	  cout << TBS_ERROR << "Number of fields is " << size << ", should be " << numFields << endl;
  } else {
	  cout << TBS_INFO << "Number of fields is " << size << endl;
  }
  if (size > 0 && size <= numFields) {
	  for (int i=0; i<size; ++i) {
		  const scv_extensions_if * field = ppExt->get_field(i);
		  if (field == NULL) {
			  errorCount++;
			  cout << TBS_ERROR << "Field " << i << " not found" << endl;
		  } else if (fieldNames[i] != field->get_name()) {
			  errorCount++;
			  cout << TBS_ERROR << "Field " << i << " should have name " << fieldNames[i] << ", instead has name " << field->get_name() << endl;
		  } else if (!field->is_integer()) {
			  errorCount++;
			  cout << TBS_ERROR << "Expected " << fieldNames[i] << " to be of type integer" << endl;
		  } else {
			  if (field->get_integer() != fieldValues[i]) {
				  errorCount++;
				  cout << TBS_ERROR << "Expected value " << fieldValues[i] << " for field " << fieldNames[i] << " found to instead be " << field->get_integer() << endl;
			  } else {
				  cout << TBS_INFO << "Field " << i << " okay" << endl;
			  }			  
		  }
	  }
  }

  //
  // Check uninitialize, initialize and next
  //

  cout << TBS_INFO << "Check if maintains initial value across consecutive accesses" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  if (fieldValues[0] != pp->packet_type || fieldValues[1] != pp->src ||
	  fieldValues[2] != pp->dest || fieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed across consecutive accesses" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained across consecutive accesses" << endl;
  }

  cout << TBS_INFO << "Make sure they change values after a next" << endl;
  pp->next();
  int newFieldValues[4];
  newFieldValues[0] = pp->packet_type;
  newFieldValues[1] = pp->src;
  newFieldValues[2] = pp->dest;
  newFieldValues[3] = pp->payload;
  if (fieldValues[0] == newFieldValues[0]
      || fieldValues[1] == newFieldValues[1]
      || fieldValues[2] == newFieldValues[2]
      || fieldValues[3] == newFieldValues[3])
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) did not change after next" << endl;
  } else {
	  cout << TBS_INFO << "Values changed after next" << endl;
  }

  cout << TBS_INFO << "Check if maintains next value across multiple consecutive accesses" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed across consecutive accesses" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained across consecutive accesses" << endl;
  }

  cout << TBS_INFO << "Check if maintains value across spurious initialize" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  pp->initialize();
  if (fieldValues[0] != pp->packet_type || fieldValues[1] != pp->src ||
	  fieldValues[2] != pp->dest || fieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed across spurious initialize" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained across spurious initialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after uninitialize" << endl;
  pp->uninitialize();
  if (fieldValues[0] == (newFieldValues[0] = pp->packet_type) || fieldValues[1] == (newFieldValues[1] = pp->src) ||
	  fieldValues[2] == (newFieldValues[2] = pp->dest) || fieldValues[3] == (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) didn't change across uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values changed across uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after 2nd access after uninitialize" << endl;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed after 2nd access after uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained after 2nd access after uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after spurious uninitialize" << endl;
  pp->uninitialize();
  pp->uninitialize();
  if (fieldValues[0] == (newFieldValues[0] = pp->packet_type) || fieldValues[1] == (newFieldValues[1] = pp->src) ||
	  fieldValues[2] == (newFieldValues[2] = pp->dest) || fieldValues[3] == (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) didn't change across uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values changed across uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after 2nd access after spurious uninitialize" << endl;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed after 2nd access after uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained after 2nd access after uninitialize" << endl;
  }

  //
  // Repeat the above checks, but this time only change 1st and 3rd fields
  //

  cout << TBS_INFO << "Repeat above checks, but only changing 1st and 3rd fields" << endl;

  cout << TBS_INFO << "Make sure they change values after a next" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  pp->packet_type.next();
  pp->dest.next();
  if (fieldValues[0] == (newFieldValues[0] = pp->packet_type) || fieldValues[1] != (newFieldValues[1] = pp->src) ||
	  fieldValues[2] == (newFieldValues[2] = pp->dest) || fieldValues[3] != (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value did not change properly after next" << endl;
  } else {
	  cout << TBS_INFO << "Values changed properly after next" << endl;
  }

  cout << TBS_INFO << "Check if maintains next value across multiple consecutive accesses" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed across consecutive accesses" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained across consecutive accesses" << endl;
  }

  cout << TBS_INFO << "Check if maintains value across spurious initialize" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  pp->packet_type.initialize();
  pp->dest.initialize();
  if (fieldValues[0] != pp->packet_type || fieldValues[1] != pp->src ||
	  fieldValues[2] != pp->dest || fieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed across spurious initialize" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained across spurious initialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after uninitialize" << endl;
  pp->packet_type.uninitialize();
  pp->dest.uninitialize();
  if (fieldValues[0] == (newFieldValues[0] = pp->packet_type) || fieldValues[1] != (newFieldValues[1] = pp->src) ||
	  fieldValues[2] == (newFieldValues[2] = pp->dest) || fieldValues[3] != (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) didn't change properly across uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values changed properly across uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after 2nd access after uninitialize" << endl;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed after 2nd access after uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained after 2nd access after uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after spurious uninitialize" << endl;
  pp->packet_type.uninitialize();
  pp->dest.uninitialize();
  pp->packet_type.uninitialize();
  pp->dest.uninitialize();
  if (fieldValues[0] == (newFieldValues[0] = pp->packet_type) || fieldValues[1] != (newFieldValues[1] = pp->src) ||
	  fieldValues[2] == (newFieldValues[2] = pp->dest) || fieldValues[3] != (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) didn't change properly across uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values changed properly across uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after 2nd access after spurious uninitialize" << endl;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed improperly after 2nd access after uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values properly maintained after 2nd access after uninitialize" << endl;
  }

  //
  // Repeat the above checks, but this time only change 2nd and 4th fields
  //

  cout << TBS_INFO << "Repeat above checks, but only changing 1st and 3rd fields" << endl;

  cout << TBS_INFO << "Make sure they change values after a next" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  pp->src.next();
  pp->payload.next();
  if (fieldValues[0] != (newFieldValues[0] = pp->packet_type) || fieldValues[1] == (newFieldValues[1] = pp->src) ||
	  fieldValues[2] != (newFieldValues[2] = pp->dest) || fieldValues[3] == (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value did not change properly after next" << endl;
  } else {
	  cout << TBS_INFO << "Values changed properly after next" << endl;
  }

  cout << TBS_INFO << "Check if maintains next value across multiple consecutive accesses" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed across consecutive accesses" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained across consecutive accesses" << endl;
  }

  cout << TBS_INFO << "Check if maintains value across spurious initialize" << endl;
  fieldValues[0] = pp->packet_type;
  fieldValues[1] = pp->src;
  fieldValues[2] = pp->dest;
  fieldValues[3] = pp->payload;
  pp->src.initialize();
  pp->payload.initialize();
  if (fieldValues[0] != pp->packet_type || fieldValues[1] != pp->src ||
	  fieldValues[2] != pp->dest || fieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed across spurious initialize" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained across spurious initialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after uninitialize" << endl;
  pp->src.uninitialize();
  pp->payload.uninitialize();
  if (fieldValues[0] != (newFieldValues[0] = pp->packet_type) || fieldValues[1] == (newFieldValues[1] = pp->src) ||
	  fieldValues[2] != (newFieldValues[2] = pp->dest) || fieldValues[3] == (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) didn't change properly across uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values changed properly across uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after 2nd access after uninitialize" << endl;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed after 2nd access after uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values maintained after 2nd access after uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after spurious uninitialize" << endl;
  pp->src.uninitialize();
  pp->payload.uninitialize();
  pp->src.uninitialize();
  pp->payload.uninitialize();
  if (fieldValues[0] != (newFieldValues[0] = pp->packet_type) || fieldValues[1] == (newFieldValues[1] = pp->src) ||
	  fieldValues[2] != (newFieldValues[2] = pp->dest) || fieldValues[3] == (newFieldValues[3] = pp->payload))
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) didn't change properly across uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values changed properly across uninitialize" << endl;
  }

  cout << TBS_INFO << "Check behavior after 2nd access after spurious uninitialize" << endl;
  if (newFieldValues[0] != pp->packet_type || newFieldValues[1] != pp->src ||
	  newFieldValues[2] != pp->dest || newFieldValues[3] != pp->payload )
  {
	  errorCount++;
	  cout << TBS_ERROR << "Value(s) changed improperly after 2nd access after uninitialize" << endl;
  } else {
	  cout << TBS_INFO << "Values properly maintained after 2nd access after uninitialize" << endl;
  }

  if (errorCount != 0) {
	  cout << TBS_FAIL << "Encountered " << errorCount << " errors\n";
  } else {
	  cout << TBS_SUCCESS << endl;
  }
}
Exemplo n.º 4
0
void print_number_of_fields(const T& data) {
  cout << "number of fields : " 
       << scv_get_const_extensions(data).get_num_fields() << endl;
}