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
