2014-10-11 23:16:00 +02:00
|
|
|
/* Copyright (c) 2012 Massachusetts Institute of Technology
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2014-10-11 22:02:23 +02:00
|
|
|
#ifndef __DSENT_MODEL_ELECTRICALMODEL_H__
|
|
|
|
#define __DSENT_MODEL_ELECTRICALMODEL_H__
|
|
|
|
|
|
|
|
#include "util/CommonType.h"
|
|
|
|
#include "model/Model.h"
|
|
|
|
#include "model/TransitionInfo.h"
|
|
|
|
|
|
|
|
namespace DSENT
|
|
|
|
{
|
|
|
|
class PortInfo;
|
|
|
|
class EventInfo;
|
|
|
|
class ElectricalDriver;
|
|
|
|
class ElectricalDriverMultiplier;
|
|
|
|
class ElectricalNet;
|
|
|
|
class ElectricalLoad;
|
|
|
|
class ElectricalDelay;
|
|
|
|
|
|
|
|
// A Net index consisting of a start and end index
|
|
|
|
typedef std::pair<int, int> NetIndex;
|
|
|
|
|
|
|
|
// Helper function to make net index
|
|
|
|
inline NetIndex makeNetIndex(int start_index_, int end_index_)
|
|
|
|
{
|
|
|
|
ASSERT((end_index_ >= start_index_), (String)"[Error] Invalid net index range " +
|
|
|
|
|
|
|
|
"[" + (String)start_index_ + ":" + (String)end_index_ + "]");
|
|
|
|
|
|
|
|
return NetIndex(start_index_, end_index_);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper function to make net index
|
|
|
|
inline NetIndex makeNetIndex(int index_)
|
|
|
|
{
|
|
|
|
return makeNetIndex(index_, index_);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper function to trun NetIndex to String
|
|
|
|
inline String toString(const NetIndex& net_index_)
|
|
|
|
{
|
|
|
|
return "[" + String(net_index_.second) + ":" + String(net_index_.first) + "]";
|
|
|
|
}
|
|
|
|
|
|
|
|
// ElectricalModel specifies physical connectivity to other models as well as the port
|
|
|
|
// parameters for the current model
|
|
|
|
class ElectricalModel : public Model
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ElectricalModel(const String& instance_name_, const TechModel* tech_model_);
|
|
|
|
virtual ~ElectricalModel();
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Check if all properties needed exist in the m_properties_
|
|
|
|
virtual void checkProperties() const;
|
|
|
|
// Set available driving strength vector from string
|
|
|
|
void setAvailableDrivingStrengths(const String& driving_strengths_);
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
// Connectivity specification
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
// Net Indices
|
|
|
|
const Map<NetIndex>* getNetReferences() const;
|
|
|
|
const NetIndex getNetReference(const String& name_) const;
|
|
|
|
// Input Ports
|
|
|
|
void createInputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0));
|
|
|
|
const Map<PortInfo*>* getInputs() const;
|
|
|
|
PortInfo* getInputPort(const String& name_);
|
|
|
|
const PortInfo* getInputPort(const String& name_) const;
|
|
|
|
// Output Ports
|
|
|
|
void createOutputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0));
|
|
|
|
const Map<PortInfo*>* getOutputs() const;
|
|
|
|
PortInfo* getOutputPort(const String& name_);
|
|
|
|
const PortInfo* getOutputPort(const String& name_) const;
|
|
|
|
// Electrical Nets
|
|
|
|
void createNet(const String& name_);
|
|
|
|
void createNet(const String& name_, const NetIndex& net_indices_);
|
|
|
|
const Map<ElectricalNet*>* getNets() const;
|
|
|
|
ElectricalNet* getNet(const String& name_);
|
|
|
|
ElectricalNet* getNet(const String& name_, const NetIndex& index_);
|
|
|
|
|
|
|
|
// Assign a net to be downstream from another net
|
|
|
|
// case 1: 'assign downstream_net_name_ = upstream_net_name_'
|
|
|
|
void assign(const String& downstream_net_name_, const String& upstream_net_name_);
|
|
|
|
// case 2: 'assign downstream_net_name_[end:begin] = upstream_net_name_'
|
|
|
|
void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_);
|
|
|
|
// case 3: 'assign downstream_net_name_ = upstream_net_name_[end:begin]'
|
|
|
|
void assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
|
|
|
|
// case 4: 'assign downstream_net_name_[end:begin] = upstream_net_name_[end:begin]'
|
|
|
|
void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
|
|
|
|
|
|
|
|
// Connect a port (input or output) to some ElectricalNet
|
|
|
|
// case 1: .connect_port_name_(connect_net_name_)
|
|
|
|
void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_);
|
|
|
|
// case 2: .connect_port_name_(connect_net_name[end:begin])
|
|
|
|
void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_);
|
|
|
|
|
|
|
|
// Assign a net to be downstream from another net through a driver multipliers
|
|
|
|
void assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_);
|
|
|
|
void assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
|
|
|
|
// Assign a net to be downstream from another net
|
|
|
|
// This is used to enable bit_duplication
|
|
|
|
void assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_);
|
|
|
|
void assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
// Timing Model Components
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
// Electrical Drivers
|
|
|
|
void createDriver(const String& name_, bool sizable_);
|
|
|
|
//void createDriver(const String& name_, bool sizable_, int start_index_, int end_index_);
|
|
|
|
const Map<ElectricalDriver*>* getDrivers() const;
|
|
|
|
ElectricalDriver* getDriver(const String& name_);
|
|
|
|
// Electrical Driver Multipliers
|
|
|
|
void createDriverMultiplier(const String& name_);
|
|
|
|
const Map<ElectricalDriverMultiplier*>* getDriverMultipliers() const;
|
|
|
|
ElectricalDriverMultiplier* getDriverMultiplier(const String& name_);
|
|
|
|
|
|
|
|
|
|
|
|
// Electrical Loads
|
|
|
|
void createLoad(const String& name_);
|
|
|
|
//void createLoad(const String& name_, int start_index_, int end_index_);
|
|
|
|
const Map<ElectricalLoad*>* getLoads() const;
|
|
|
|
ElectricalLoad* getLoad(const String& name_);
|
|
|
|
// Electrical Delay creation
|
|
|
|
void createDelay(const String& name_);
|
|
|
|
//void createDelay(const String& name_, int start_index_, int end_index_);
|
|
|
|
const Map<ElectricalDelay*>* getDelays() const;
|
|
|
|
ElectricalDelay* getDelay(const String& name_);
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
|
|
|
|
// Get current driving strength
|
|
|
|
double getDrivingStrength() const;
|
|
|
|
// Get current driving strength index
|
|
|
|
int getDrivingStrengthIdx() const;
|
|
|
|
// Set driving strength by index
|
|
|
|
void setDrivingStrengthIdx(int idx_);
|
|
|
|
// Set the instance to minimum driving strength
|
|
|
|
void setMinDrivingStrength();
|
|
|
|
// Return true if the instance has minimum driving strength
|
|
|
|
bool hasMinDrivingStrength() const;
|
|
|
|
// Return true if the instance has maximum driving strength
|
|
|
|
bool hasMaxDrivingStrength() const;
|
|
|
|
// Increase driving strength index by 1
|
|
|
|
void increaseDrivingStrength();
|
|
|
|
// Decrease driving strength index by 1
|
|
|
|
void decreaseDrivingStrength();
|
|
|
|
|
|
|
|
// Create the default sets of the electrical results
|
|
|
|
void createElectricalResults();
|
|
|
|
// Add the default sets of the electrical results from a model
|
|
|
|
void addElectricalSubResults(const ElectricalModel* model_, double number_models_);
|
|
|
|
// Add extra wire sub results
|
|
|
|
void addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_);
|
|
|
|
// Create the default sets of the electrical atomic results
|
|
|
|
void createElectricalAtomicResults();
|
|
|
|
// Accumulate the electrical atomic results' values
|
|
|
|
void addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_);
|
|
|
|
// Add extra wire sub results
|
|
|
|
void addElecticalWireAtomicResultValue(const String& wire_layer_, double value_);
|
|
|
|
// Reset the electrical atomic results' values
|
|
|
|
void resetElectricalAtomicResults();
|
|
|
|
// Create an electrical event result. This will add an event associate to all input/output ports
|
|
|
|
void createElectricalEventResult(const String& name_);
|
|
|
|
// Create an electrical event atomic result
|
|
|
|
void createElectricalEventAtomicResult(const String& name_);
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
// Helper functions to propagate transition information
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
void assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_);
|
|
|
|
void propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_);
|
|
|
|
void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_);
|
|
|
|
void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_);
|
|
|
|
void propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_);
|
|
|
|
virtual void propagateTransitionInfo();
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
// Helper functions to insert and remove buffers
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
|
|
|
|
virtual void useModel(const String& event_name_);
|
|
|
|
virtual void useModel();
|
|
|
|
// TODO - add comments
|
|
|
|
void applyTransitionInfo(const String& event_name_);
|
|
|
|
// TODO - add comments
|
|
|
|
EventInfo* getEventInfo(const String& event_name_);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// In an ElectricalModel, the complete port-to-port connectivity
|
|
|
|
// of all sub-instance must be specified. Addition/Removal ports or
|
|
|
|
// port-related nets cannot happen after this step
|
|
|
|
//virtual void constructModel() = 0;
|
|
|
|
// In an ElectricalModel, updateModel MUST finish all necessary
|
|
|
|
// calculations such that a timing model can be run
|
|
|
|
//virtual void updateModel() = 0;
|
|
|
|
// In an ElectricalModel, evaluateModel should calculate all
|
|
|
|
// event energies, now that the connectivity and timing has been
|
|
|
|
// completed
|
|
|
|
//virtual void evaluateModel() = 0;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Private copy constructor. Use clone to perform copy operation.
|
|
|
|
ElectricalModel(const ElectricalModel& model_);
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Contains the driving strengths in increasing order
|
|
|
|
vector<double> m_driving_strengths_;
|
|
|
|
// Driving strength index in the driving strength vector
|
|
|
|
int m_curr_driving_strengths_idx_;
|
|
|
|
|
|
|
|
//Connectivity elements
|
|
|
|
// Nets can come in various bus widths. A net reference is really
|
|
|
|
// just a helper map mapping a referenced map name to a bunch of
|
|
|
|
// net indices. A net index returns the starting and end indices of
|
|
|
|
// a net if the net is a multi-bit bus of some sort
|
|
|
|
Map<NetIndex>* m_net_references_;
|
|
|
|
// Map of the input ports
|
|
|
|
Map<PortInfo*>* m_input_ports_;
|
|
|
|
// Map of the output ports
|
|
|
|
Map<PortInfo*>* m_output_ports_;
|
|
|
|
// Map of all our electrical nets
|
|
|
|
Map<ElectricalNet*>* m_nets_;
|
|
|
|
|
|
|
|
//Timing model elements
|
|
|
|
// Map of all our electrical drivers
|
|
|
|
Map<ElectricalDriver*>* m_drivers_;
|
|
|
|
// Map of all our driver multipliers
|
|
|
|
Map<ElectricalDriverMultiplier*>* m_driver_multipliers_;
|
|
|
|
// Map of all our electrical loads
|
|
|
|
Map<ElectricalLoad*>* m_loads_;
|
|
|
|
// Map of all our idealized delays
|
|
|
|
Map<ElectricalDelay*>* m_delays_;
|
|
|
|
|
|
|
|
// Map of the event infos
|
|
|
|
Map<EventInfo*>* m_event_infos_;
|
|
|
|
|
|
|
|
}; // class ElectricalModel
|
|
|
|
} // namespace DSENT
|
|
|
|
|
|
|
|
#endif // __DSENT_MODEL_ELECTRICALMODEL_H__
|
|
|
|
|