simulate.cc revision 6216
12817Sksewell@umich.edu/* 22817Sksewell@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 32817Sksewell@umich.edu * All rights reserved. 42817Sksewell@umich.edu * 52817Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 62817Sksewell@umich.edu * modification, are permitted provided that the following conditions are 72817Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 82817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 92817Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 102817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 112817Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 122817Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 132817Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 142817Sksewell@umich.edu * this software without specific prior written permission. 152817Sksewell@umich.edu * 162817Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172817Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182817Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192817Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202817Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212817Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222817Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232817Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242817Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252817Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262817Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272817Sksewell@umich.edu * 282817Sksewell@umich.edu * Authors: Nathan Binkert 292817Sksewell@umich.edu * Steve Reinhardt 302817Sksewell@umich.edu */ 312817Sksewell@umich.edu 322817Sksewell@umich.edu#include "base/misc.hh" 332817Sksewell@umich.edu#include "base/pollevent.hh" 342817Sksewell@umich.edu#include "base/types.hh" 352817Sksewell@umich.edu#include "sim/async.hh" 362817Sksewell@umich.edu#include "sim/eventq.hh" 372834Sksewell@umich.edu#include "sim/sim_events.hh" 382834Sksewell@umich.edu#include "sim/sim_exit.hh" 392834Sksewell@umich.edu#include "sim/simulate.hh" 402834Sksewell@umich.edu#include "sim/stat_control.hh" 412834Sksewell@umich.edu 422834Sksewell@umich.edu/** Simulate for num_cycles additional cycles. If num_cycles is -1 432834Sksewell@umich.edu * (the default), do not limit simulation; some other event must 442817Sksewell@umich.edu * terminate the loop. Exported to Python via SWIG. 452817Sksewell@umich.edu * @return The SimLoopExitEvent that caused the loop to exit. 462817Sksewell@umich.edu */ 472817Sksewell@umich.eduSimLoopExitEvent * 482817Sksewell@umich.edusimulate(Tick num_cycles) 492817Sksewell@umich.edu{ 502817Sksewell@umich.edu inform("Entering event queue @ %d. Starting simulation...\n", curTick); 512817Sksewell@umich.edu 522817Sksewell@umich.edu if (num_cycles < 0) 532817Sksewell@umich.edu fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles); 542817Sksewell@umich.edu else if (curTick + num_cycles < 0) //Overflow 552817Sksewell@umich.edu num_cycles = MaxTick; 562817Sksewell@umich.edu else 572817Sksewell@umich.edu num_cycles = curTick + num_cycles; 582817Sksewell@umich.edu 592817Sksewell@umich.edu Event *limit_event = 602817Sksewell@umich.edu new SimLoopExitEvent("simulate() limit reached", 0); 612817Sksewell@umich.edu mainEventQueue.schedule(limit_event, num_cycles); 622817Sksewell@umich.edu 632817Sksewell@umich.edu while (1) { 642817Sksewell@umich.edu // there should always be at least one event (the SimLoopExitEvent 652817Sksewell@umich.edu // we just scheduled) in the queue 662817Sksewell@umich.edu assert(!mainEventQueue.empty()); 672817Sksewell@umich.edu assert(curTick <= mainEventQueue.nextTick() && 682817Sksewell@umich.edu "event scheduled in the past"); 692817Sksewell@umich.edu 702817Sksewell@umich.edu // forward current cycle to the time of the first event on the 712817Sksewell@umich.edu // queue 722817Sksewell@umich.edu curTick = mainEventQueue.nextTick(); 732817Sksewell@umich.edu Event *exit_event = mainEventQueue.serviceOne(); 742817Sksewell@umich.edu if (exit_event != NULL) { 752817Sksewell@umich.edu // hit some kind of exit event; return to Python 762817Sksewell@umich.edu // event must be subclass of SimLoopExitEvent... 772817Sksewell@umich.edu SimLoopExitEvent *se_event; 782817Sksewell@umich.edu se_event = dynamic_cast<SimLoopExitEvent *>(exit_event); 792817Sksewell@umich.edu 802817Sksewell@umich.edu if (se_event == NULL) 812817Sksewell@umich.edu panic("Bogus exit event class!"); 822817Sksewell@umich.edu 832817Sksewell@umich.edu // if we didn't hit limit_event, delete it 842817Sksewell@umich.edu if (se_event != limit_event) { 852817Sksewell@umich.edu assert(limit_event->scheduled()); 862817Sksewell@umich.edu limit_event->squash(); 872817Sksewell@umich.edu hack_once("be nice to actually delete the event here"); 882817Sksewell@umich.edu } 892817Sksewell@umich.edu 902817Sksewell@umich.edu return se_event; 912817Sksewell@umich.edu } 922817Sksewell@umich.edu 932817Sksewell@umich.edu if (async_event) { 942817Sksewell@umich.edu async_event = false; 952817Sksewell@umich.edu if (async_statdump || async_statreset) { 962817Sksewell@umich.edu Stats::StatEvent(async_statdump, async_statreset); 972817Sksewell@umich.edu async_statdump = false; 982817Sksewell@umich.edu async_statreset = false; 992817Sksewell@umich.edu } 1002817Sksewell@umich.edu 1012817Sksewell@umich.edu if (async_exit) { 1022817Sksewell@umich.edu async_exit = false; 1032817Sksewell@umich.edu exitSimLoop("user interrupt received"); 1042817Sksewell@umich.edu } 1052817Sksewell@umich.edu 1062817Sksewell@umich.edu if (async_io || async_alarm) { 1072817Sksewell@umich.edu async_io = false; 1082817Sksewell@umich.edu async_alarm = false; 1092817Sksewell@umich.edu pollQueue.service(); 1102817Sksewell@umich.edu } 1112817Sksewell@umich.edu 1122817Sksewell@umich.edu if (async_exception) { 1132817Sksewell@umich.edu async_exception = false; 1142817Sksewell@umich.edu return NULL; 1152875Sksewell@umich.edu } 1162817Sksewell@umich.edu } 1172817Sksewell@umich.edu } 1182817Sksewell@umich.edu 1192817Sksewell@umich.edu // not reached... only exit is return on SimLoopExitEvent 1202817Sksewell@umich.edu} 1212817Sksewell@umich.edu 1222817Sksewell@umich.edu