simulate.cc revision 4123
14123Sbinkertn@umich.edu/* 24123Sbinkertn@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 34123Sbinkertn@umich.edu * All rights reserved. 44123Sbinkertn@umich.edu * 54123Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 64123Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are 74123Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright 84123Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 94123Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 104123Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 114123Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution; 124123Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its 134123Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from 144123Sbinkertn@umich.edu * this software without specific prior written permission. 154123Sbinkertn@umich.edu * 164123Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174123Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184123Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194123Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204123Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214123Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224123Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234123Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244123Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254123Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264123Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274123Sbinkertn@umich.edu * 284123Sbinkertn@umich.edu * Authors: Nathan Binkert 294123Sbinkertn@umich.edu * Steve Reinhardt 304123Sbinkertn@umich.edu */ 314123Sbinkertn@umich.edu 324123Sbinkertn@umich.edu#include "base/misc.hh" 334123Sbinkertn@umich.edu#include "base/pollevent.hh" 344123Sbinkertn@umich.edu#include "sim/stat_control.hh" 354123Sbinkertn@umich.edu#include "sim/async.hh" 364123Sbinkertn@umich.edu#include "sim/eventq.hh" 374123Sbinkertn@umich.edu#include "sim/host.hh" 384123Sbinkertn@umich.edu#include "sim/sim_events.hh" 394123Sbinkertn@umich.edu#include "sim/sim_exit.hh" 404123Sbinkertn@umich.edu#include "sim/simulate.hh" 414123Sbinkertn@umich.edu 424123Sbinkertn@umich.edu/** Simulate for num_cycles additional cycles. If num_cycles is -1 434123Sbinkertn@umich.edu * (the default), do not limit simulation; some other event must 444123Sbinkertn@umich.edu * terminate the loop. Exported to Python via SWIG. 454123Sbinkertn@umich.edu * @return The SimLoopExitEvent that caused the loop to exit. 464123Sbinkertn@umich.edu */ 474123Sbinkertn@umich.eduSimLoopExitEvent * 484123Sbinkertn@umich.edusimulate(Tick num_cycles) 494123Sbinkertn@umich.edu{ 504123Sbinkertn@umich.edu warn("Entering event queue @ %d. Starting simulation...\n", curTick); 514123Sbinkertn@umich.edu 524123Sbinkertn@umich.edu if (num_cycles < 0) 534123Sbinkertn@umich.edu fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles); 544123Sbinkertn@umich.edu else if (curTick + num_cycles < 0) //Overflow 554123Sbinkertn@umich.edu num_cycles = MaxTick; 564123Sbinkertn@umich.edu else 574123Sbinkertn@umich.edu num_cycles = curTick + num_cycles; 584123Sbinkertn@umich.edu 594123Sbinkertn@umich.edu Event *limit_event; 604123Sbinkertn@umich.edu limit_event = schedExitSimLoop("simulate() limit reached", num_cycles); 614123Sbinkertn@umich.edu 624123Sbinkertn@umich.edu while (1) { 634123Sbinkertn@umich.edu // there should always be at least one event (the SimLoopExitEvent 644123Sbinkertn@umich.edu // we just scheduled) in the queue 654123Sbinkertn@umich.edu assert(!mainEventQueue.empty()); 664123Sbinkertn@umich.edu assert(curTick <= mainEventQueue.nextTick() && 674123Sbinkertn@umich.edu "event scheduled in the past"); 684123Sbinkertn@umich.edu 694123Sbinkertn@umich.edu // forward current cycle to the time of the first event on the 704123Sbinkertn@umich.edu // queue 714123Sbinkertn@umich.edu curTick = mainEventQueue.nextTick(); 724123Sbinkertn@umich.edu Event *exit_event = mainEventQueue.serviceOne(); 734123Sbinkertn@umich.edu if (exit_event != NULL) { 744123Sbinkertn@umich.edu // hit some kind of exit event; return to Python 754123Sbinkertn@umich.edu // event must be subclass of SimLoopExitEvent... 764123Sbinkertn@umich.edu SimLoopExitEvent *se_event; 774123Sbinkertn@umich.edu se_event = dynamic_cast<SimLoopExitEvent *>(exit_event); 784123Sbinkertn@umich.edu 794123Sbinkertn@umich.edu if (se_event == NULL) 804123Sbinkertn@umich.edu panic("Bogus exit event class!"); 814123Sbinkertn@umich.edu 824123Sbinkertn@umich.edu // if we didn't hit limit_event, delete it 834123Sbinkertn@umich.edu if (se_event != limit_event) { 844123Sbinkertn@umich.edu assert(limit_event->scheduled()); 854123Sbinkertn@umich.edu limit_event->deschedule(); 864123Sbinkertn@umich.edu delete limit_event; 874123Sbinkertn@umich.edu } 884123Sbinkertn@umich.edu 894123Sbinkertn@umich.edu return se_event; 904123Sbinkertn@umich.edu } 914123Sbinkertn@umich.edu 924123Sbinkertn@umich.edu if (async_event) { 934123Sbinkertn@umich.edu async_event = false; 944123Sbinkertn@umich.edu if (async_statdump || async_statreset) { 954123Sbinkertn@umich.edu async_statdump = false; 964123Sbinkertn@umich.edu async_statreset = false; 974123Sbinkertn@umich.edu 984123Sbinkertn@umich.edu Stats::StatEvent(async_statdump, async_statreset); 994123Sbinkertn@umich.edu } 1004123Sbinkertn@umich.edu 1014123Sbinkertn@umich.edu if (async_exit) { 1024123Sbinkertn@umich.edu async_exit = false; 1034123Sbinkertn@umich.edu exitSimLoop("user interrupt received"); 1044123Sbinkertn@umich.edu } 1054123Sbinkertn@umich.edu 1064123Sbinkertn@umich.edu if (async_io || async_alarm) { 1074123Sbinkertn@umich.edu async_io = false; 1084123Sbinkertn@umich.edu async_alarm = false; 1094123Sbinkertn@umich.edu pollQueue.service(); 1104123Sbinkertn@umich.edu } 1114123Sbinkertn@umich.edu 1124123Sbinkertn@umich.edu if (async_exception) { 1134123Sbinkertn@umich.edu async_exception = false; 1144123Sbinkertn@umich.edu return NULL; 1154123Sbinkertn@umich.edu } 1164123Sbinkertn@umich.edu } 1174123Sbinkertn@umich.edu } 1184123Sbinkertn@umich.edu 1194123Sbinkertn@umich.edu // not reached... only exit is return on SimLoopExitEvent 1204123Sbinkertn@umich.edu} 1214123Sbinkertn@umich.edu 122