Coolquest, Inc. Home Products Support About Contact
cbold_logo_gif C++BOLD Reference Manual cbold_logo_gif

<<< Previous CBOLD Reference Home Next >>>

 

10.2. Inheritance

Inheritance is typically used to derive new classes from the CBOLD base classes. For example, new part types are derived from TPart and new module types are derived from TModule.

On some occasions, the user may find it convenient to derive new types from user types, such as user–defined modules or bundles. In the following example, the designer wanted a new bundle, CB_JTAG_CONF, which contained the same ports as an existing Bundle, CB_JTAG, as well as some additional ports.

class CB_JTAG : public TBundle {  // JTAG bundle
public:
  port TMS;
  port TDI;
  port TDO;
  port TCK;
  virtual void Register() {
    reg( TMS );
    reg( TDI );
    reg( TDO );
    reg( TCK );
  }
};
 
// JTAG bundle that also includes configuration signals for one FPGA
class CB_JTAG_CONF : public CB_JTAG {
public:
  port CCLK;
  port DIN;
  port PROGRAM_N;
  virtual void Register() {
    CB_JTAG::Register();    // register the members of the base class
    reg( CCLK );
    reg( DIN );
    reg( PROGRAM_N );
  }
};

CB_JTAG_CONF::Register() must call CB_JTAG::Register() so that CB_JTAG's members are registered with the underlying TBundle. The CB_JTAG_CONF above is equivalent to the following:

class CB_JTAG_CONF : public CB_JTAG {
public:
  port TMS;
  port TDI;
  port TDO;
  port TCK;
  port CCLK;
  port DIN;
  port PROGRAM_N;
 
  virtual void Register() {
    reg( TMS );
    reg( TDI );
    reg( TDO );
    reg( TCK );
    reg( CCLK );
    reg( DIN );
    reg( PROGRAM_N );
  }
};

In some cases, the designer may create a base class that is not intended to be instantiated as a member of a module, but is meant only to function as a building block for derived classes. The example below implements a power switch. The classes derived from CM_MultiSwitch_Base contain one or more FET power switches (TPS2034D) wired in parallel. Regardless of the number of switches instantiated in derived classes, the base class provides one input capacitor, one output capacitor, and one protection diode.

Some unusual features of the power switch example:

Because the switches are wired in parallel, the base class is able to provide all necessary connections. Thus the derived classes do not implement a Connect()-they inherit the Connect() of the base class.

Access to the base constructor (T_MultiSwitch_Base()) is protected, meaning that the constructor can be accessed by derived classes, but not by any other classes. The compiler will issue an error and the program will not compile if the user attempts to instantiate a CM_MultiSwitch_Base. Though this protection is optional, it prevents a designer unfamiliar with the details of CM_MultiSwitch_Base from instantiating a useless circuit.

The Register() functions in the derived classes (T_MultiSwitch1 and CM_MultiSwitch2) hide the Register() in their base class (T_MultiSwitch_Base), so each derived Register() must call CM_MultiSwitch_Base::Register() to register members of the base class.

class CM_MultiSwitch_Base : public TModule {  // Helper module—not intended for general use
protected:
  CM_MultiSwitch_Base(){};                    // only descendants of this class can be instantiated by user
public:
  port GND;
  port IN;
  port OUT;
  port EN;
 
  CP_MBRS130LT3 Dprotect;   // low–threshold Schottky diode
  CP_CDC_POS   CapI;        // input  cap, one per multiswitch   >>> place near TPS2033D
  CP_CDC_POS   CapO;        // output cap, one per multiswitch   >>> place near TPS2033D
 
public:
  virtual void Register() {
    ...
  }
 
  virtual void Connect() {
    IN  << Dprotect.CATHODE  <<  CapI.POS;
    OUT << Dprotect.ANODE    <<  CapO.POS;
    wireall( GND );          // all switches are wired in parallel
    wireall( IN  );
    wireall( OUT );
    wireall( EN );
    wireall( "/NC", "OC_N" );  // overcurrent flags are not used
  }
};
 
 
class CM_MultiSwitch1 : public CM_MultiSwitch_Base {
public:
// all member ports are in the base class
 
// ***** member modules and parts ***** //
  enum { sw_cnt = 1 };            // number of paralleled switches in this module
  CP_TPS2034D  Switch[ sw_cnt ];  // the power switch(es)
 
  virtual void Register() {
    CM_MultiSwitch_Base::Register();
    rega( Switch, sw_cnt );
  }
 
//  virtual void Connect()  // all connections are made in the base class
};
 
 
class CM_MultiSwitch2 : public CM_MultiSwitch_Base {
public:
// all member ports are in the base class
 
// ***** member modules and parts ***** //
  enum { sw_cnt = 2 };            // number of paralleled switches in this module
  CP_TPS2034D  Switch[ sw_cnt ];  // the power switch(es)
 
  virtual void Register() {
    CM_MultiSwitch_Base::Register();
    rega( Switch, sw_cnt );
  }
 
//  virtual void Connect()  // all connections are made in the base class
};
 
...

The example above is not necessarily the best method of achieving the desired end. Another approach is to code a single class containing a member array of TPS2034D's. The class registers only as many of the elements of the array as requested prior to the call to its Register(). See Selective Registration.

 

<<< Previous CBOLD Reference Home Next >>>

Legal Copyright © 2007 by Coolquest, Inc. Contact