aboutsummaryrefslogtreecommitdiff
path: root/src/intersim2/.svn/pristine/12
diff options
context:
space:
mode:
Diffstat (limited to 'src/intersim2/.svn/pristine/12')
-rw-r--r--src/intersim2/.svn/pristine/12/125686d82b0fb03524a1bd1dc36fd9172006e780.svn-base673
-rw-r--r--src/intersim2/.svn/pristine/12/1260dd25f0b77d1694bc40d60681090fdb77e795.svn-base186
-rw-r--r--src/intersim2/.svn/pristine/12/129d383ada436691b3879ee38f72c6420d1b3b86.svn-base481
3 files changed, 1340 insertions, 0 deletions
diff --git a/src/intersim2/.svn/pristine/12/125686d82b0fb03524a1bd1dc36fd9172006e780.svn-base b/src/intersim2/.svn/pristine/12/125686d82b0fb03524a1bd1dc36fd9172006e780.svn-base
new file mode 100644
index 0000000..f7e44a8
--- /dev/null
+++ b/src/intersim2/.svn/pristine/12/125686d82b0fb03524a1bd1dc36fd9172006e780.svn-base
@@ -0,0 +1,673 @@
+// $Id$
+
+/*
+ Copyright (c) 2007-2012, Trustees of The Leland Stanford Junior University
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "booksim.hpp"
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <cstdlib>
+
+#include "chaos_router.hpp"
+#include "random_utils.hpp"
+#include "globals.hpp"
+
+ChaosRouter::ChaosRouter( const Configuration& config,
+ Module *parent, const string & name, int id,
+ int inputs, int outputs )
+ : Router( config,
+ parent, name,
+ id,
+ inputs, outputs )
+{
+ int i;
+
+ if ( inputs != outputs ) {
+ Error( "Chaos router must have equal number of input and output ports" );
+ }
+
+ _buffer_size = config.GetInt( "vc_buf_size" );
+ assert(_buffer_size >= config.GetInt( "const_flits_per_packet" ));
+
+ _multi_queue_size = config.GetInt( "multi_queue_size" );
+
+ _cur_channel = 0;
+ _read_stall = 0;
+
+ // Routing
+
+ string rf = config.GetStr("routing_function") + "_" + config.GetStr("topology");
+ map<string, tRoutingFunction>::iterator rf_iter = gRoutingFunctionMap.find(rf);
+ if(rf_iter == gRoutingFunctionMap.end()) {
+ Error("Invalid routing function: " + rf);
+ }
+ _rf = rf_iter->second;
+
+ _input_route.resize(_inputs);
+
+ for ( i = 0; i < _inputs; ++i ) {
+ _input_route[i] = new OutputSet( );
+ }
+
+ _mq_route.resize(_multi_queue_size);
+
+ for ( i = 0; i < _multi_queue_size; ++i ) {
+ _mq_route[i] = new OutputSet( );
+ }
+
+ // Alloc pipelines (to simulate processing/transmission delays)
+
+ _crossbar_pipe =
+ new PipelineFIFO<Flit>( this, "crossbar_pipeline", _outputs,
+ _crossbar_delay );
+
+ // Input and output queues
+
+ _input_frame.resize(_inputs);
+ _output_frame.resize(_outputs);
+ _multi_queue.resize(_multi_queue_size);
+
+ _credit_queue.resize(_inputs);
+
+ _input_state.resize(_inputs, empty);
+ _input_output_match.resize(_inputs, -1);
+ _input_mq_match.resize(_inputs, -1);
+
+ _output_matched.resize(_outputs, false);
+ _next_queue_cnt.resize(_outputs, 0);
+
+ _multi_match.resize(_multi_queue_size, -1);
+ _mq_age.resize(_multi_queue_size);
+ _mq_matched.resize(_multi_queue_size, false);
+ _multi_state.resize(_multi_queue_size, empty);
+
+ for ( i = 0; i < _multi_queue_size; ++i ) {
+ _multi_state[i] = empty;
+ _multi_match[i] = -1;
+ _mq_matched[i] = false;
+ }
+}
+
+ChaosRouter::~ChaosRouter( )
+{
+ int i;
+
+ delete _crossbar_pipe;
+
+ for ( i = 0; i < _inputs; ++i ) {
+ delete _input_route[i];
+ }
+
+ for ( i = 0; i < _multi_queue_size; ++i ) {
+ delete _mq_route[i];
+ }
+}
+
+void ChaosRouter::ReadInputs( )
+{
+ Flit *f;
+ Credit *c;
+
+ for ( int input = 0; input < _inputs; ++input ) {
+ f = _input_channels[input]->Receive();
+
+ if ( f ) {
+ _input_frame[input].push( f );
+
+ if ( f->watch ) {
+ *gWatchOut << GetSimTime() << " | " << FullName() << " | "
+ << "Flit arriving at " << FullName()
+ << " on channel " << input << endl
+ << *f;
+ }
+
+ switch( _input_state[input] ) {
+ case empty:
+ if ( f->head ) {
+ if ( f->tail ) {
+ _input_state[input] = full;
+ } else {
+ _input_state[input] = filling;
+ }
+ _rf( this, f, input, _input_route[input], false );
+ } else {
+ cout << *f;
+ Error( "Empty buffer received non-head flit!" );
+ }
+ break;
+
+ case filling:
+ if ( f->tail ) {
+ _input_state[input] = full;
+ } else if ( f->head ) {
+ Error( "Input buffer received another head before previous tail!" );
+ }
+ break;
+
+ case full:
+ Error( "Received flit while full!" );
+ break;
+
+ case leaving:
+ if ( f->head ) {
+ _input_state[input] = shared;
+
+ if ( f->tail ) {
+ Error( "Received single-flit packet in leaving state!" );
+ }
+ } else {
+ cout << *f;
+ Error( "Received non-head flit while packet leaving!" );
+ }
+ break;
+
+ case cut_through:
+ if ( f->tail ) {
+ _input_state[input] = leaving;
+ }
+ if ( f->head ) {
+ cout << *f;
+ Error( "Received head flit in cut through buffer!" );
+ }
+ break;
+
+ case shared:
+ if ( f->head ) {
+ Error( "Shared buffer received another head!" );
+ } else if ( f->tail ) {
+ cout << "Input " << input << endl;
+ cout << *f;
+ Error( "Shared buffer received another tail!" );
+ }
+ break;
+ }
+ }
+ }
+
+ // Process incoming credits
+
+ for ( int output = 0; output < _outputs; ++output ) {
+ c = _output_credits[output]->Receive();
+
+ if ( c ) {
+ _next_queue_cnt[output]--;
+
+ if ( _next_queue_cnt[output] < 0 ) {
+ Error( "Next queue count fell below zero!" );
+ }
+
+ c->Free();
+ }
+ }
+}
+
+void ChaosRouter::_InternalStep( )
+{
+ _NextInterestingChannel( );
+ _OutputAdvance( );
+
+ _crossbar_pipe->Advance( );
+}
+
+void ChaosRouter::WriteOutputs( )
+{
+ _SendFlits( );
+ _SendCredits( );
+}
+
+bool ChaosRouter::_IsInjectionChan( int chan ) const
+{
+ return ( chan == _inputs - 1 );
+}
+
+bool ChaosRouter::_IsEjectionChan( int chan ) const
+{
+ return ( chan == _outputs - 1 );
+}
+
+bool ChaosRouter::_InputReady( int input ) const
+{
+ bool ready = false;
+
+ if ( ( _input_state[input] == filling ) ||
+ ( _input_state[input] == full ) ) {
+ ready = true;
+ }
+
+ return ready;
+}
+
+bool ChaosRouter::_OutputFull( int out ) const
+{
+ return ( _output_frame[out].size( ) >= (size_t)_buffer_size );
+}
+
+bool ChaosRouter::_OutputAvail( int out ) const
+{
+ return ( ( !_output_matched[out] ) && ( _output_frame[out].empty( ) ) );
+ //&& ( _next_queue_cnt[out] == 0 ) );
+ //return ( ( !_output_matched[out] ) && !_OutputFull( out ) );
+}
+
+bool ChaosRouter::_MultiQueueFull( int mq ) const
+{
+ return ( _multi_queue[mq].size( ) >= (size_t)_buffer_size );
+}
+
+int ChaosRouter::_InputForOutput( int output ) const
+{
+ // return an input that prefers this output
+
+ int input;
+ int offset = RandomInt( _inputs - 1 );
+ bool match = false;
+
+ for ( int i = 0; ( i < _inputs ) && ( !match ); ++i ) {
+ input = ( i + offset ) % _inputs;
+
+ if ( _InputReady( input ) &&
+ ( ! _input_route[input]->OutputEmpty( output ) ) ) {
+ match = true;
+ }
+ }
+
+ return match ? input : -1;
+}
+
+int ChaosRouter::_MultiQueueForOutput( int output ) const
+{
+ // return oldest multi queue that prefers the output,
+ // or if none prefer and the multi queue is full,
+ // return a random entry
+
+ int mq_oldest = -1;
+ int mq_age;
+
+ int m, r;
+
+ bool isfull = true;
+
+ for ( int i = 0; i < _multi_queue_size; ++i ) {
+ if ( ( _multi_match[i] == -1 ) &&
+ ( ( _multi_state[i] == full ) ||
+ ( _multi_state[i] == filling ) ) ) {
+
+ if ( ( !_mq_route[i]->OutputEmpty( output ) ) &&
+ ( ( mq_oldest == -1 ) || ( _mq_age[i] > mq_age ) ) ) {
+ mq_oldest = i;
+ mq_age = _mq_age[i];
+ }
+ }
+
+ // deroute only if all queues contain head flits ...
+
+ if ( ( _multi_state[i] != full ) &&
+ ( _multi_state[i] != filling ) &&
+ ( _multi_state[i] != shared ) ) {
+ isfull = false;
+ }
+ }
+
+ // Don't deroute MQs to the ejection channel
+ if ( ( mq_oldest == -1 ) && isfull &&
+ ( !_IsEjectionChan( output ) ) ) {
+ r = RandomInt( _multi_queue_size - 1 );
+
+ // Find first routable multi-queue
+ for ( int i = 0; i < _multi_queue_size; ++i ) {
+ m = ( i + r ) % _multi_queue_size;
+ if ( ( _multi_state[m] == filling ) ||
+ ( _multi_state[m] == full ) ) {
+ mq_oldest = m;
+ //cout << "DEROUTING at " << FullName() << endl;
+ break;
+ }
+ }
+
+ if ( mq_oldest == -1 ) {
+ cout << "write stall" << endl;
+ }
+ }
+
+ return mq_oldest;
+}
+
+int ChaosRouter::_FindAvailMultiQueue( ) const
+{
+ // return any empty multi queue slot
+
+ int avail = -1;
+
+ for ( int i = 0; i < _multi_queue_size; ++i ) {
+ if ( ( !_MultiQueueFull( i ) ) &&
+ ( !_mq_matched[i] ) ) {
+ avail = i;
+ break;
+ }
+ }
+
+ return avail;
+}
+
+void ChaosRouter::_NextInterestingChannel( )
+{
+ bool interesting;
+
+ int mq_index;
+ int in_index;
+ int mq_avail;
+
+ int c;
+
+ interesting = false;
+ mq_index = -1;
+ in_index = -1;
+
+ // A channel is interesting if
+ //
+ // ( output frame available and
+ // ( ( a multiqueue packet wants output channel ) or
+ // ( an input packet wants output channel ) or
+ // ( the multiqueue is full ) ) )
+ // or
+ // ( the packet at the input channel is stalled )
+
+ for ( c = 0; ( c < _inputs ) && ( !interesting ); ++c ) {
+ if ( _OutputAvail( _cur_channel ) ) {
+ mq_index = _MultiQueueForOutput( _cur_channel );
+ in_index = _InputForOutput( _cur_channel );
+
+ if ( ( mq_index != -1 ) || ( in_index != -1 ) ) {
+ interesting = true;
+ }
+ }
+
+ if ( _input_state[_cur_channel] == full ) {
+ interesting = true;
+ }
+
+ if ( !interesting ) {
+ _cur_channel = ( _cur_channel + 1 ) % _inputs;
+ }
+ }
+
+ if ( interesting ) {
+ //cout << _cur_channel << " is interesting at " << FullName() << endl;
+
+ if ( mq_index != -1 ) {
+ //cout << "Match for multi-queue " << mq_index << " at " << FullName()
+ // << ", output matched = " << _output_matched[_cur_channel] << endl;
+
+ _output_matched[_cur_channel] = true;
+ _multi_match[mq_index] = _cur_channel;
+ } else if ( in_index != -1 ) {
+ _output_matched[_cur_channel] = true;
+ _input_output_match[in_index] = _cur_channel;
+
+ //cout << "Match for input " << in_index << " at " << FullName() << endl;
+
+ if ( _input_state[in_index] == full ) {
+ _input_state[in_index] = leaving;
+ } else if ( _input_state[in_index] == filling ) {
+ _input_state[in_index] = cut_through;
+ } else {
+ Error( "Tried to route input through crossbar that was not full or filling!" );
+ }
+ }
+
+ // Any non-injection channel that is routable is
+ // directed to the multi-queue
+ if ( ( ( _input_state[_cur_channel] == filling ) ||
+ ( _input_state[_cur_channel] == full ) ) &&
+ ( !_IsInjectionChan( _cur_channel ) ) ) {
+ ++_read_stall;
+ } else {
+ // go to next channel for the next cycle
+ _cur_channel = ( _cur_channel + 1 ) % _inputs;
+ _read_stall = 0;
+ }
+ }
+
+ if ( _read_stall > 0 ) {
+ mq_avail = _FindAvailMultiQueue( );
+
+ if ( mq_avail != -1 ) {
+ if ( _input_state[_cur_channel] == full ) {
+ _input_state[_cur_channel] = leaving;
+ } else if ( _input_state[_cur_channel] == filling ) {
+ _input_state[_cur_channel] = cut_through;
+ } else {
+ cout << "Input " << _cur_channel << " state = "
+ << _input_state[_cur_channel] << endl;
+ Error( "Tried to route input throught multi-queue that was not full or filling!" );
+ }
+
+ _input_mq_match[_cur_channel] = mq_avail;
+ _mq_matched[mq_avail] = true;
+
+ // go to next channel for the next cycle
+ _cur_channel = ( _cur_channel + 1 ) % _inputs;
+ _read_stall = 0;
+ } else {
+ ++_read_stall;
+ //cout << "stalling at input " << _cur_channel << " (count = " << _read_stall << ")" << endl;
+ }
+ }
+}
+
+void ChaosRouter::_OutputAdvance( )
+{
+ Flit *f, *f2;
+ Credit *c;
+ bool advanced;
+ int mq;
+
+ _crossbar_pipe->WriteAll( 0 );
+
+ for ( int i = 0; i < _inputs; ++i ) {
+ if ( ( ( _input_output_match[i] != -1 ) ||
+ ( _input_mq_match[i] != -1 ) ) &&
+ ( !_input_frame[i].empty( ) ) ) {
+
+ advanced = false;
+ f = _input_frame[i].front( );
+
+ /*if ( ! ) {
+
+ } else {
+ cout << "Input = " << i
+ << ", input_output_match = " << _input_output_match[i]
+ << ", input_mq_match = " << _input_mq_match[i] << endl;
+ Error( "Input queue empty, but matched!" );
+ }*/
+
+ if ( _input_output_match[i] != -1 ) {
+ if ( f->tail ) {
+ _output_matched[_input_output_match[i]] = false;
+ }
+
+ _crossbar_pipe->Write( f, _input_output_match[i] );
+
+ if ( f->watch ) {
+ *gWatchOut << GetSimTime() << " | " << FullName() << " | "
+ << "Flit traversing crossbar from input queue "
+ << i << " at "
+ << FullName() << endl
+ << *f;
+ }
+
+ advanced = true;
+
+ } else if ( !_MultiQueueFull( _input_mq_match[i] ) ) {
+
+ mq = _input_mq_match[i];
+
+ if ( f->head ) {
+ _rf( this, f, i, _mq_route[mq], false );
+ _mq_age[mq] = 0;
+
+ if ( _multi_state[mq] == empty ) {
+ _multi_state[mq] = filling;
+ } else if ( _multi_state[mq] == leaving ) {
+ _multi_state[mq] = shared;
+ } else {
+ Error( "Multi-queue received head while not empty or leaving!" );
+ }
+ }
+
+ if ( f->tail ) {
+ _mq_matched[mq] = false;
+
+ if ( _multi_state[mq] == filling ) {
+ _multi_state[mq] = full;
+ } else if ( _multi_state[mq] == cut_through ) {
+ _multi_state[mq] = leaving;
+ } else {
+ Error( "Multi-queue received tail while not filling or cutting-through!" );
+ }
+ }
+
+ _multi_queue[mq].push( f );
+
+ if ( f->watch ) {
+ *gWatchOut << GetSimTime() << " | " << FullName() << " | "
+ << "Flit stored in multiqueue at "
+ << FullName() << endl
+ << "State = " << _multi_state[mq] << endl
+ << *f;
+ }
+
+ advanced = true;
+ }
+
+ if ( advanced ) {
+ _input_frame[i].pop( );
+
+ if ( f->tail ) { // last in packet, update state
+ if ( _input_state[i] == leaving ) {
+ _input_state[i] = empty;
+ } else if ( _input_state[i] == shared ) {
+ _input_state[i] = filling;
+ f2 = _input_frame[i].front( );
+ // update routes
+ _rf( this, f2, i, _input_route[i], false );
+ }
+
+ _input_output_match[i] = -1;
+ _input_mq_match[i] = -1;
+ }
+
+ c = Credit::New( );
+ c->vc.insert(0);
+ _credit_queue[i].push( c );
+ }
+ }
+ }
+
+ for ( int m = 0; m < _multi_queue_size; ++m ) {
+ if ( _multi_match[m] != -1 ) {
+ if ( _multi_queue[m].empty( ) ) {
+ cout << "State = " << _multi_state[m] << endl;
+ Error( "Multi queue empty, but matched!" );
+ }
+ assert( !_multi_queue[m].empty( ) );
+ f = _multi_queue[m].front( );
+ _multi_queue[m].pop( );
+
+ _crossbar_pipe->Write( f, _multi_match[m] );
+
+ if ( f->watch ) {
+ *gWatchOut << GetSimTime() << " | " << FullName() << " | "
+ << "Flit traversing crossbar from multiqueue slot "
+ << m << " at "
+ << FullName() << endl
+ << *f;
+ }
+
+ if ( f->head ) {
+ if ( _multi_state[m] == filling ) {
+ _multi_state[m] = cut_through;
+ } else if ( _multi_state[m] == full ) {
+ _multi_state[m] = leaving;
+ } else {
+ Error( "Multi-queue sent head while not filling or full!" );
+ }
+ }
+
+ if ( f->tail ) {
+ _output_matched[_multi_match[m]] = false;
+ _multi_match[m] = -1;
+
+ if ( _multi_state[m] == shared ) {
+ _multi_state[m] = filling;
+ } else if ( _multi_state[m] == leaving ) {
+ _multi_state[m] = empty;
+ } else {
+ cout << "State = " << _multi_state[m] << endl;
+ cout << *f;
+ Error( "Multi-queue sent tail while not leaving or shared!" );
+ }
+ }
+ }
+
+ _mq_age[m]++;
+ }
+}
+
+
+void ChaosRouter::_SendFlits( )
+{
+ for ( int output = 0; output < _outputs; ++output ) {
+ Flit *f = _crossbar_pipe->Read( output );
+
+ if ( f ) {
+ _output_frame[output].push( f );
+ f->hops++;
+ }
+
+ if ( ( _next_queue_cnt[output] < _buffer_size ) &&
+ ( !_output_frame[output].empty( ) ) ) {
+ _output_channels[output]->Send( _output_frame[output].front( ) );
+ _output_frame[output].pop( );
+ ++_next_queue_cnt[output];
+ }
+ }
+}
+
+void ChaosRouter::_SendCredits( )
+{
+ for ( int input = 0; input < _inputs; ++input ) {
+ if ( !_credit_queue[input].empty( ) ) {
+ Credit *c = _credit_queue[input].front( );
+ _credit_queue[input].pop( );
+ _input_credits[input]->Send( c );
+ }
+ }
+}
+
+void ChaosRouter::Display( ostream & os ) const
+{
+}
diff --git a/src/intersim2/.svn/pristine/12/1260dd25f0b77d1694bc40d60681090fdb77e795.svn-base b/src/intersim2/.svn/pristine/12/1260dd25f0b77d1694bc40d60681090fdb77e795.svn-base
new file mode 100644
index 0000000..6488ea4
--- /dev/null
+++ b/src/intersim2/.svn/pristine/12/1260dd25f0b77d1694bc40d60681090fdb77e795.svn-base
@@ -0,0 +1,186 @@
+// $Id$
+
+/*
+ Copyright (c) 2007-2012, Trustees of The Leland Stanford Junior University
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _POWER_MODULE_HPP_
+#define _POWER_MODULE_HPP_
+
+#include <map>
+
+#include "module.hpp"
+#include "network.hpp"
+#include "config_utils.hpp"
+#include "flitchannel.hpp"
+#include "switch_monitor.hpp"
+#include "buffer_monitor.hpp"
+
+struct wire{
+ double L;
+ double K;
+ double M;
+ double N;
+};
+
+class Power_Module : public Module {
+
+protected:
+ //network undersimulation
+ Network * net;
+ int classes;
+ //all channels are this width
+ double channel_width;
+ //resimulate all with channel_width decremented by channel_sweep until 0
+ double channel_sweep;
+ //write result to a tabbed format to file
+ string output_file_name;
+
+ //buffer depth
+ double depthVC;
+ //vcs
+ double numVC;
+
+ //store the property of wires based on length
+ map<double, wire> wire_map;
+
+ //////////////////////////////////Constants/////////////////////////////
+ //wire length in (mm)
+ double wire_length;
+ //////////Metal Parameters////////////
+ // Wire left/right coupling capacitance [ F/mm ]
+ double Cw_cpl ;
+ // Wire up/down groudn capacitance [ F/mm ]
+ double Cw_gnd ;
+ double Cw ;
+ double Rw ;
+ // metal pitch [mm]
+ double MetalPitch ;
+
+
+ //////////Device Parameters////////////
+
+ double LAMBDA ; // [um/LAMBDA]
+ double Cd ; // [F/um] (for Delay)
+ double Cg ; // [F/um] (for Delay)
+ double Cgdl ; // [F/um] (for Delay)
+
+ double Cd_pwr; // [F/um] (for Power)
+ double Cg_pwr ; // [F/um] (for Power)
+
+ double IoffN ; // [A/um]
+ double IoffP ; // [A/um]
+ // Leakage from bitlines, two-port cell [A]
+ double IoffSRAM;
+ // [Ohm] ( D1=1um Inverter)
+ double R ;
+ // [F] ( D1=1um Inverter - for Power )
+ double Ci_delay;
+ // [F] ( D1=1um Inverter - for Power )
+ double Co_delay ;
+
+ double Ci ;
+ double Co ;
+ double Vdd ;
+ double FO4 ;
+ double tCLK ;
+ double fCLK ;
+
+ double H_INVD2;
+ double W_INVD2;
+ double H_DFQD1;
+ double W_DFQD1;
+ double H_ND2D1;
+ double W_ND2D1;
+ double H_SRAM;
+ double W_SRAM;
+ double ChannelPitch ;
+ double CrossbarPitch;
+ ////////////////////////////////End of Constants/////////////////////////////
+
+ /////////////results///////////////////
+ double totalTime;
+ double channelWirePower;
+ double channelClkPower;
+ double channelDFFPower;
+ double channelLeakPower;
+ double inputReadPower;
+ double inputWritePower;
+ double inputLeakagePower;
+ double switchPower;
+ double switchPowerCtrl;
+ double switchPowerLeak;
+ double outputPower;
+ double outputPowerClk;
+ double outputCtrlPower;
+ double channelArea;
+ double switchArea;
+ double inputArea;
+ double outputArea;
+ double maxInputPort;
+ double maxOutputPort;
+
+
+ ////////////////////////
+
+ //channels
+ void calcChannel(const FlitChannel * f);
+ wire const & wireOptimize(double l);
+ double powerRepeatedWire(double L, double K, double M, double N);
+ double powerRepeatedWireLeak (double K, double M, double N);
+ double powerWireClk (double M, double W);
+ double powerWireDFF(double M, double W, double alpha);
+
+ //memory
+ void calcBuffer(const BufferMonitor *bm);
+ double powerWordLine(double memoryWidth, double memoryDepth);
+ double powerMemoryBitRead(double memoryDepth);
+ double powerMemoryBitWrite(double memoryDepth);
+ double powerMemoryBitLeak(double memoryDepth );
+
+ //switch
+ void calcSwitch(const SwitchMonitor *sm);
+ double powerCrossbar(double width, double inputs, double outputs, double from, double to);
+ double powerCrossbarCtrl(double width, double inputs, double outputs);
+ double powerCrossbarLeak (double width, double inputs, double outputs);
+
+ //output
+ double powerOutputCtrl(double width);
+
+ //area
+
+ double areaChannel (double K, double N, double M);
+ double areaCrossbar(double Inputs, double Outputs) ;
+ double areaInputModule(double Words) ;
+ double areaOutputModule(double Outputs);
+
+public:
+ Power_Module(Network * net, const Configuration &config);
+ ~Power_Module();
+
+ void run();
+
+
+};
+#endif
diff --git a/src/intersim2/.svn/pristine/12/129d383ada436691b3879ee38f72c6420d1b3b86.svn-base b/src/intersim2/.svn/pristine/12/129d383ada436691b3879ee38f72c6420d1b3b86.svn-base
new file mode 100644
index 0000000..6aa2d53
--- /dev/null
+++ b/src/intersim2/.svn/pristine/12/129d383ada436691b3879ee38f72c6420d1b3b86.svn-base
@@ -0,0 +1,481 @@
+// $Id$
+
+/*
+ Copyright (c) 2007-2012, Trustees of The Leland Stanford Junior University
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "booksim.hpp"
+#include <iostream>
+#include <sstream>
+#include <cassert>
+#include "allocator.hpp"
+
+/////////////////////////////////////////////////////////////////////////
+//Allocator types
+#include "maxsize.hpp"
+#include "pim.hpp"
+#include "islip.hpp"
+#include "loa.hpp"
+#include "wavefront.hpp"
+#include "selalloc.hpp"
+#include "separable_input_first.hpp"
+#include "separable_output_first.hpp"
+//
+/////////////////////////////////////////////////////////////////////////
+
+//==================================================
+// Allocator base class
+//==================================================
+
+Allocator::Allocator( Module *parent, const string& name,
+ int inputs, int outputs ) :
+Module( parent, name ), _inputs( inputs ), _outputs( outputs ), _dirty( false )
+{
+ _inmatch.resize(_inputs, -1);
+ _outmatch.resize(_outputs, -1);
+}
+
+void Allocator::Clear( )
+{
+ if(_dirty) {
+ _inmatch.assign(_inputs, -1);
+ _outmatch.assign(_outputs, -1);
+ _dirty = false;
+ }
+}
+
+void Allocator::AddRequest( int in, int out, int label, int in_pri,
+ int out_pri ) {
+
+ assert( ( in >= 0 ) && ( in < _inputs ) );
+ assert( ( out >= 0 ) && ( out < _outputs ) );
+ assert( label >= 0 );
+ _dirty = true;
+}
+
+int Allocator::OutputAssigned( int in ) const
+{
+ assert( ( in >= 0 ) && ( in < _inputs ) );
+
+ return _inmatch[in];
+}
+
+int Allocator::InputAssigned( int out ) const
+{
+ assert( ( out >= 0 ) && ( out < _outputs ) );
+
+ return _outmatch[out];
+}
+
+void Allocator::PrintGrants( ostream * os ) const
+{
+ if(!os) os = &cout;
+
+ *os << "Input grants = [ ";
+ for ( int input = 0; input < _inputs; ++input ) {
+ if(_inmatch[input] >= 0) {
+ *os << input << " -> " << _inmatch[input] << " ";
+ }
+ }
+ *os << "], output grants = [ ";
+ for ( int output = 0; output < _outputs; ++output ) {
+ if(_outmatch[output] >= 0) {
+ *os << output << " -> " << _outmatch[output] << " ";
+ }
+ }
+ *os << "]." << endl;
+}
+
+//==================================================
+// DenseAllocator
+//==================================================
+
+DenseAllocator::DenseAllocator( Module *parent, const string& name,
+ int inputs, int outputs ) :
+ Allocator( parent, name, inputs, outputs )
+{
+ _request.resize(_inputs);
+
+ for ( int i = 0; i < _inputs; ++i ) {
+ _request[i].resize(_outputs);
+ for ( int j = 0; j < _outputs; ++j ) {
+ _request[i][j].label = -1;
+ }
+ }
+}
+
+void DenseAllocator::Clear( )
+{
+ for ( int i = 0; i < _inputs; ++i ) {
+ for ( int j = 0; j < _outputs; ++j ) {
+ _request[i][j].label = -1;
+ }
+ }
+ Allocator::Clear();
+}
+
+int DenseAllocator::ReadRequest( int in, int out ) const
+{
+ assert( ( in >= 0 ) && ( in < _inputs ) );
+ assert( ( out >= 0 ) && ( out < _outputs ) );
+
+ return _request[in][out].label;
+}
+
+bool DenseAllocator::ReadRequest( sRequest &req, int in, int out ) const
+{
+ assert( ( in >= 0 ) && ( in < _inputs ) );
+ assert( ( out >= 0 ) && ( out < _outputs ) );
+
+ req = _request[in][out];
+
+ return ( req.label >= 0 );
+}
+
+void DenseAllocator::AddRequest( int in, int out, int label,
+ int in_pri, int out_pri )
+{
+ Allocator::AddRequest(in, out, label, in_pri, out_pri);
+ assert( _request[in][out].label == -1 );
+
+ _request[in][out].label = label;
+ _request[in][out].in_pri = in_pri;
+ _request[in][out].out_pri = out_pri;
+}
+
+void DenseAllocator::RemoveRequest( int in, int out, int label )
+{
+ assert( ( in >= 0 ) && ( in < _inputs ) );
+ assert( ( out >= 0 ) && ( out < _outputs ) );
+
+ _request[in][out].label = -1;
+}
+
+bool DenseAllocator::InputHasRequests( int in ) const
+{
+ for(int out = 0; out < _outputs; ++out) {
+ if(_request[in][out].label >= 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool DenseAllocator::OutputHasRequests( int out ) const
+{
+ for(int in = 0; in < _inputs; ++in) {
+ if(_request[in][out].label >= 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int DenseAllocator::NumInputRequests( int in ) const
+{
+ int result = 0;
+ for(int out = 0; out < _outputs; ++out) {
+ if(_request[in][out].label >= 0) {
+ ++result;
+ }
+ }
+ return result;
+}
+
+int DenseAllocator::NumOutputRequests( int out ) const
+{
+ int result = 0;
+ for(int in = 0; in < _inputs; ++in) {
+ if(_request[in][out].label >= 0) {
+ ++result;
+ }
+ }
+ return result;
+}
+
+void DenseAllocator::PrintRequests( ostream * os ) const
+{
+ if(!os) os = &cout;
+
+ *os << "Input requests = [ ";
+ for ( int input = 0; input < _inputs; ++input ) {
+ bool print = false;
+ ostringstream ss;
+ for ( int output = 0; output < _outputs; ++output ) {
+ const sRequest & req = _request[input][output];
+ if ( req.label >= 0 ) {
+ print = true;
+ ss << output << "@" << req.in_pri << " ";
+ }
+ }
+ if(print) {
+ *os << input << " -> [ " << ss.str() << "] ";
+ }
+ }
+ *os << "], output requests = [ ";
+ for ( int output = 0; output < _outputs; ++output ) {
+ bool print = false;
+ ostringstream ss;
+ for ( int input = 0; input < _inputs; ++input ) {
+ const sRequest & req = _request[input][output];
+ if ( req.label >= 0 ) {
+ print = true;
+ ss << input << "@" << req.out_pri << " ";
+ }
+ }
+ if(print) {
+ *os << output << " -> [ " << ss.str() << "] ";
+ }
+ }
+ *os << "]." << endl;
+}
+
+//==================================================
+// SparseAllocator
+//==================================================
+
+SparseAllocator::SparseAllocator( Module *parent, const string& name,
+ int inputs, int outputs ) :
+ Allocator( parent, name, inputs, outputs )
+{
+ _in_req.resize(_inputs);
+ _out_req.resize(_outputs);
+}
+
+
+void SparseAllocator::Clear( )
+{
+ for ( int i = 0; i < _inputs; ++i ) {
+ if(!_in_req[i].empty())
+ _in_req[i].clear( );
+ }
+
+ for ( int j = 0; j < _outputs; ++j ) {
+ if(!_out_req[j].empty())
+ _out_req[j].clear( );
+ }
+
+ _in_occ.clear( );
+ _out_occ.clear( );
+
+ Allocator::Clear();
+}
+
+int SparseAllocator::ReadRequest( int in, int out ) const
+{
+ sRequest r;
+
+ if ( ! ReadRequest( r, in, out ) ) {
+ r.label = -1;
+ }
+
+ return r.label;
+}
+
+bool SparseAllocator::ReadRequest( sRequest &req, int in, int out ) const
+{
+ bool found;
+
+ assert( ( in >= 0 ) && ( in < _inputs ) );
+ assert( ( out >= 0 ) && ( out < _outputs ) );
+
+ map<int, sRequest>::const_iterator match = _in_req[in].find(out);
+ if ( match != _in_req[in].end( ) ) {
+ req = match->second;
+ found = true;
+ } else {
+ found = false;
+ }
+
+ return found;
+}
+
+void SparseAllocator::AddRequest( int in, int out, int label,
+ int in_pri, int out_pri )
+{
+ Allocator::AddRequest(in, out, label, in_pri, out_pri);
+ assert( _in_req[in].count(out) == 0 );
+ assert( _out_req[out].count(in) == 0 );
+
+ // insert into occupied inputs set if
+ // input is currently empty
+ if ( _in_req[in].empty( ) ) {
+ _in_occ.insert(in);
+ }
+
+ // similarly for the output
+ if ( _out_req[out].empty( ) ) {
+ _out_occ.insert(out);
+ }
+
+ sRequest req;
+ req.port = out;
+ req.label = label;
+ req.in_pri = in_pri;
+ req.out_pri = out_pri;
+
+ _in_req[in][out] = req;
+
+ req.port = in;
+
+ _out_req[out][in] = req;
+}
+
+void SparseAllocator::RemoveRequest( int in, int out, int label )
+{
+ assert( ( in >= 0 ) && ( in < _inputs ) );
+ assert( ( out >= 0 ) && ( out < _outputs ) );
+
+ assert( _in_req[in].count( out ) > 0 );
+ assert( _in_req[in][out].label == label );
+ _in_req[in].erase( out );
+
+ // remove from occupied inputs list if
+ // input is now empty
+ if ( _in_req[in].empty( ) ) {
+ _in_occ.erase(in);
+ }
+
+ // similarly for the output
+ assert( _out_req[out].count( in ) > 0 );
+ assert( _out_req[out][in].label == label );
+ _out_req[out].erase( in );
+
+ if ( _out_req[out].empty( ) ) {
+ _out_occ.erase(out);
+ }
+}
+
+bool SparseAllocator::InputHasRequests( int in ) const
+{
+ return _in_occ.count(in) > 0;
+}
+
+bool SparseAllocator::OutputHasRequests( int out ) const
+{
+ return _out_occ.count(out) > 0;
+}
+
+int SparseAllocator::NumInputRequests( int in ) const
+{
+ return _in_occ.count(in);
+}
+
+int SparseAllocator::NumOutputRequests( int out ) const
+{
+ return _out_occ.count(out);
+}
+
+void SparseAllocator::PrintRequests( ostream * os ) const
+{
+ map<int, sRequest>::const_iterator iter;
+
+ if(!os) os = &cout;
+
+ *os << "Input requests = [ ";
+ for ( int input = 0; input < _inputs; ++input ) {
+ if(!_in_req[input].empty()) {
+ *os << input << " -> [ ";
+ for ( iter = _in_req[input].begin( );
+ iter != _in_req[input].end( ); iter++ ) {
+ *os << iter->second.port << "@" << iter->second.in_pri << " ";
+ }
+ *os << "] ";
+ }
+ }
+ *os << "], output requests = [ ";
+ for ( int output = 0; output < _outputs; ++output ) {
+ if(!_out_req[output].empty()) {
+ *os << output << " -> ";
+ *os << "[ ";
+ for ( iter = _out_req[output].begin( );
+ iter != _out_req[output].end( ); iter++ ) {
+ *os << iter->second.port << "@" << iter->second.out_pri << " ";
+ }
+ *os << "] ";
+ }
+ }
+ *os << "]." << endl;
+}
+
+//==================================================
+// Global allocator allocation function
+//==================================================
+
+Allocator *Allocator::NewAllocator( Module *parent, const string& name,
+ const string &alloc_type,
+ int inputs, int outputs,
+ Configuration const * const config )
+{
+ Allocator *a = 0;
+
+ string alloc_name;
+ string param_str;
+ size_t left = alloc_type.find_first_of('(');
+ if(left == string::npos) {
+ alloc_name = alloc_type;
+ } else {
+ alloc_name = alloc_type.substr(0, left);
+ size_t right = alloc_type.find_last_of(')');
+ if(right == string::npos) {
+ param_str = alloc_type.substr(left+1);
+ } else {
+ param_str = alloc_type.substr(left+1, right-left-1);
+ }
+ }
+ if ( alloc_name == "max_size" ) {
+ a = new MaxSizeMatch( parent, name, inputs, outputs );
+ } else if ( alloc_name == "pim" ) {
+ int iters = param_str.empty() ? (config ? config->GetInt("alloc_iters") : 1) : atoi(param_str.c_str());
+ a = new PIM( parent, name, inputs, outputs, iters );
+ } else if ( alloc_name == "islip" ) {
+ int iters = param_str.empty() ? (config ? config->GetInt("alloc_iters") : 1) : atoi(param_str.c_str());
+ a = new iSLIP_Sparse( parent, name, inputs, outputs, iters );
+ } else if ( alloc_name == "loa" ) {
+ a = new LOA( parent, name, inputs, outputs );
+ } else if ( alloc_name == "wavefront" ) {
+ a = new Wavefront( parent, name, inputs, outputs );
+ } else if ( alloc_name == "rr_wavefront" ) {
+ a = new Wavefront( parent, name, inputs, outputs, true );
+ } else if ( alloc_name == "select" ) {
+ int iters = param_str.empty() ? (config ? config->GetInt("alloc_iters") : 1) : atoi(param_str.c_str());
+ a = new SelAlloc( parent, name, inputs, outputs, iters );
+ } else if (alloc_name == "separable_input_first") {
+ string arb_type = param_str.empty() ? (config ? config->GetStr("arb_type") : "round_robin") : param_str;
+ a = new SeparableInputFirstAllocator( parent, name, inputs, outputs,
+ arb_type );
+ } else if (alloc_name == "separable_output_first") {
+ string arb_type = param_str.empty() ? (config ? config->GetStr("arb_type") : "round_robin") : param_str;
+ a = new SeparableOutputFirstAllocator( parent, name, inputs, outputs,
+ arb_type );
+ }
+
+//==================================================
+// Insert new allocators here, add another else if
+//==================================================
+
+
+ return a;
+}
+