Just a quick correction. Not all the components need to include a drive() 
function. You might find some components that do not have (need) a drive 
function. FYI.

Javier
________________________________
From: Picorel Javier [[email protected]]
Sent: 22 May 2011 17:36
To: [email protected]
Cc: [email protected]
Subject: RE: doCycle()

Dear Mahmood,

All the components in Flexus need to have a drive() function no matter what 
type of simulation you run. In trace
simulations, this function is called every 1000 cycles (1000 instructions 
because in trace IPC is 1.0 and there are no stalls) and most of the time it 
just updates the counters for statistics. In timing simulations each drive 
function in a timing component is called every cycle. In timing besides 
statistical reasons we use them to model the component itself. At the end of 
each wiring.cpp file we need to specify the drive function of each component in 
a particular order. In trace simulations the order does not matter but in some 
cases you will need to define a precise order for cycle-accurate simulations. 
In the simulator wiring file you may have something like this:

#include FLEXUS_BEGIN_DRIVE_ORDER_SECTION()

DRIVE( theMagicBreak, TickDrive )
, DRIVE( theL1D, UpdateStatsDrive )
, DRIVE( theL1I, UpdateStatsDrive )
, DRIVE( theL2, UpdateStatsDrive )

#include FLEXUS_END_DRIVE_ORDER_SECTION()

In FLEXUS/core/simulator_layout.hpp you will find what 
FLEXUS_BEGIN_DRIVE_ORDER_SECTION() and FLEXUS_END_DRIVE_ORDER_SECTION() do...

#define FLEXUS_BEGIN_DRIVE_ORDER_SECTION()                        
<core/aux_/layout/begin_drive_section.hpp>
#define FLEXUS_END_DRIVE_ORDER_SECTION()                          
<core/aux_/layout/end_drive_section.hpp>

In begin_drive_section.hpp file you will find...

#define DRIVE( Handle, Drive )  \
 Flexus::Core::DriveHandle< Handle, Handle::iface::Drive >

In FLEXUS/core/component.hpp you will see what DriveHandle does but basically 
it saves component information and the drive function of the component. In 
end_drive_section.hpp it creates a list of all the drive
functions and components in the same order that the drive functions were 
defined in the wiring.cpp simulation file.
        Drive< drive_list > drive;

        The class Drive appears in FLEXUS/core/drive.hpp...

        template < class OrderedDriveHandleList >
class Drive : public DriveBase {
  virtual void doCycle() {
    //Through the magic of template expansion and static dispatch, this calls 
every Drive's
    //do_cycle() method in the order specified in OrderedDriveHandleList.
    FLEXUS_PROFILE_N("Drive::doCycle");
    aux_::do_cycle<OrderedDriveHandleList>::doCycle();
  }

};

FLEXUS will call Drive.doCycle() function every cycle. As it was instantiated 
with the drive list it will execute  
aux_::do_cycle<OrderedDriveHandleList>::doCycle() with the list we want. Now we 
are in the part
that you want:

template <int32_t N, class DriveHandleIter>
struct do_cycle_step {
  static void doCycle() {
    {
      FLEXUS_PROFILE_N( mpl::deref<DriveHandleIter>::type::drive::name() );
      for (index_t i = 0; i < mpl::deref<DriveHandleIter>::type::width(); i++) {
        mpl::deref<DriveHandleIter>::type::getReference(i).drive( typename 
mpl::deref<DriveHandleIter>::type::drive () );
      }
    }
    do_cycle_step < N - 1, typename mpl::next<DriveHandleIter>::type 
>::doCycle();
  }
};

template <class DriveHandles>
struct do_cycle {
  static void doCycle() {
    do_cycle_step< mpl::size<DriveHandles>::value, typename 
mpl::begin<DriveHandles>::type>::doCycle();
  }
};
}

Basically it will do this:

1) The bottom doCycle() will be executed and it will call the top doCycle(). It 
will use some boost library to access to the information of each element of the 
list. As some components are not a single unit and they scale to system wide 
(Check the wiring.cpp file of the simulator. L1D caches and L1I are usually 
something instantiated like that FLEXUS_INSTANTIATE_COMPONENT_ARRAY( ...): ) 
your width is larger than one so you want to iterate and call the drive 
function among all the replications of the same component. Basically, the part 
I have just explained to you is done by the following code:
  for (i=0; component_X.width(); i++){
    component_X[i].drive();
  }

2) Recursively you execute the same function (do_cycle) by the following code 
but this time with the next component in the drive list:
          do_cycle(){
           for ...
  do_cycle(component_X -> NextComponent);
}

3) Same behavior continues until all the components and their replications 
execute their drive function.

I hope my response is helpful . You can grep the code and see the code path in 
more details.
Regards,
Javier

Reply via email to