blob: 171028248c78adaa8a1d9a82b19212ef34dff9d1 [file] [log] [blame] [edit]
//===========================================================================//
// Purpose : Method definitions for the TVPR_Interface_c class.
//
// Public methods include:
// - NewInstance, DeleteInstance, GetInstance
// - Apply
// - Open
// - Execute
// - Close
//
// Protected methods include:
// - TIO_PrintHandler_c, ~TIO_PrintHandler_c
//
// Private methods include:
// - ShowInternalError_
//
//===========================================================================//
//---------------------------------------------------------------------------//
// Copyright (C) 2012-2013 Jeff Rudolph, Texas Instruments (jrudolph@ti.com) //
// //
// 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. //
//---------------------------------------------------------------------------//
#include "TIO_StringText.h"
#include "TIO_PrintHandler.h"
#include "TFH_FabricGridHandler.h"
#include "TFH_FabricBlockHandler.h"
#include "TFH_FabricChannelHandler.h"
#include "TFH_FabricSwitchBoxHandler.h"
#include "TFH_FabricConnectionBlockHandler.h"
#include "TCH_RegionPlaceHandler.h"
#include "TCH_RelativePlaceHandler.h"
#include "TCH_PrePlacedHandler.h"
#include "TCH_PreRoutedHandler.h"
#include "TVPR_OptionsStore.h"
#include "TVPR_ArchitectureSpec.h"
#include "TVPR_FabricModel.h"
#include "TVPR_CircuitDesign.h"
#include "TVPR_Interface.h"
// Initialize the VPR interface "singleton" class, as needed
TVPR_Interface_c* TVPR_Interface_c::pinstance_ = 0;
//===========================================================================//
// Method : TVPR_Interface_c
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
// 08/22/13 jeffr : Added support for TFH_FabricBlockHandler_c::NewInstance
//===========================================================================//
TVPR_Interface_c::TVPR_Interface_c(
void )
:
isAlive_( false )
{
this->vpr_.success = FALSE;
pinstance_ = 0;
// Initialize grid handler 'singleton' prior to placement
// (in order to handle fabric grid overrides, if any)
TFH_FabricGridHandler_c::NewInstance( );
// Initialize block handler 'singleton' prior to placement
// (in order to handle fabric block overrides, if any)
TFH_FabricBlockHandler_c::NewInstance( );
// Initialize channel widths handler 'singleton' prior to placement
// (in order to handle fabric channel width overrides, if any)
TFH_FabricChannelHandler_c::NewInstance( );
// Initialize switch box handler 'singleton' prior to routing
// (in order to handle fabric switch box overrides, if any)
TFH_FabricSwitchBoxHandler_c::NewInstance( );
// Initialize connection block handler 'singleton' prior to routing
// (in order to handle fabric connection block overrides, if any)
TFH_FabricConnectionBlockHandler_c::NewInstance( );
// Initialize region placement handler 'singleton' prior to placement
// (in order to handle region placement constraints, if any)
TCH_RegionPlaceHandler_c::NewInstance( );
// Initialize relative placement handler 'singleton' prior to placement
// (in order to handle relative placement constraints, if any)
TCH_RelativePlaceHandler_c::NewInstance( );
// Initialize pre-placed placement handler 'singleton' prior to placement
// (in order to handle pre-placed placement constraints, if any)
TCH_PrePlacedHandler_c::NewInstance( );
// Initialize pre-routed route handler 'singleton' prior to routing
// (in order to handle pre-routed route constraints, if any)
TCH_PreRoutedHandler_c::NewInstance( );
}
//===========================================================================//
// Method : ~TVPR_Interface_c
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
// 08/22/13 jeffr : Added TFH_FabricBlockHandler_c::DeleteInstance support
//===========================================================================//
TVPR_Interface_c::~TVPR_Interface_c(
void )
{
TCH_PreRoutedHandler_c::DeleteInstance( );
TCH_PrePlacedHandler_c::DeleteInstance( );
TCH_RelativePlaceHandler_c::DeleteInstance( );
TCH_RegionPlaceHandler_c::DeleteInstance( );
TFH_FabricConnectionBlockHandler_c::DeleteInstance( );
TFH_FabricSwitchBoxHandler_c::DeleteInstance( );
TFH_FabricChannelHandler_c::DeleteInstance( );
TFH_FabricBlockHandler_c::DeleteInstance( );
TFH_FabricGridHandler_c::DeleteInstance( );
this->Close( );
}
//===========================================================================//
// Method : NewInstance
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
//===========================================================================//
void TVPR_Interface_c::NewInstance(
void )
{
pinstance_ = new TC_NOTHROW TVPR_Interface_c;
}
//===========================================================================//
// Method : DeleteInstance
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
//===========================================================================//
void TVPR_Interface_c::DeleteInstance(
void )
{
if( pinstance_ )
{
delete pinstance_;
pinstance_ = 0;
}
}
//===========================================================================//
// Method : GetInstance
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
//===========================================================================//
TVPR_Interface_c& TVPR_Interface_c::GetInstance(
void )
{
if( !pinstance_ )
{
NewInstance( );
}
return( *pinstance_ );
}
//===========================================================================//
// Method : Apply
// Reference : See VPR's "main.c" processing source code file
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
// 06/19/13 jeffr : Added try/catch block to detect VPR abort conditions
//===========================================================================//
bool TVPR_Interface_c::Apply(
const TOS_OptionsStore_c& optionsStore,
const TAS_ArchitectureSpec_c& architectureSpec,
TFM_FabricModel_c* pfabricModel,
TCD_CircuitDesign_c* pcircuitDesign )
{
bool ok = true;
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
try
{
if( ok )
{
printHandler.Info( "Opening VPR interface...\n" );
ok = this->Open( optionsStore,
architectureSpec,
*pfabricModel,
*pcircuitDesign );
}
if( ok )
{
printHandler.Info( "Executing VPR interface...\n" );
ok = this->Execute( optionsStore,
*pcircuitDesign );
}
if( ok )
{
printHandler.Info( "Closing VPR interface...\n" );
this->Close( optionsStore,
pfabricModel,
pcircuitDesign );
}
}
catch( t_vpr_error* vpr_error )
{
ok = this->ShowInternalError_( vpr_error );
}
return( ok );
}
//===========================================================================//
// Method : Open
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
//===========================================================================//
bool TVPR_Interface_c::Open(
const TOS_OptionsStore_c& optionsStore,
const TAS_ArchitectureSpec_c& architectureSpec,
const TFM_FabricModel_c& fabricModel,
const TCD_CircuitDesign_c& circuitDesign )
{
bool ok = true;
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
this->Close( );
// VPR snippet copied from VPR's vpr_init function...
memset( &this->vpr_.options, 0, sizeof( t_options ));
memset( &this->vpr_.arch, 0, sizeof( t_arch ));
memset( &this->vpr_.setup, 0, sizeof( t_vpr_setup ));
memset( &this->vpr_.powerOpts, 0, sizeof( t_power_opts ));
// Toro snippet specific to TVPR_Interface_c's initialization
TVPR_OptionsStore_c vpr_optionsStore;
ok = vpr_optionsStore.Export( optionsStore,
&this->vpr_.options );
// VPR snippet copied from VPR's vpr_init function...
this->vpr_.setup.TimingEnabled = this->vpr_.options.TimingAnalysis;
this->vpr_.setup.constant_net_delay = this->vpr_.options.constant_net_delay;
// Toro snippet specific to TVPR_Interface_c's initialization
if( ok && architectureSpec.IsValid( ))
{
printHandler.Info( "Exporting architecture spec to VPR...\n" );
bool isTimingEnabled = ( this->vpr_.setup.TimingEnabled ? true : false );
bool isPowerEnabled = ( this->vpr_.options.Count[OT_POWER] ? true : false );
bool isClocksEnabled = isPowerEnabled;
TVPR_ArchitectureSpec_c vpr_architectureSpec;
ok = vpr_architectureSpec.Export( architectureSpec,
&this->vpr_.arch,
&type_descriptors, // [VPR] global variable
&num_types, // [VPR] global variable
isTimingEnabled,
isPowerEnabled,
isClocksEnabled );
}
if( ok && fabricModel.IsValid( ))
{
printHandler.Info( "Exporting fabric model to VPR...\n" );
const TOS_FabricOptions_c& fabricOptions = optionsStore.GetFabricOptions( );
bool overrideBlocks = fabricOptions.blocks.override;
bool overrideSwitchBoxes = fabricOptions.switchBoxes.override;
bool overrideConnectionBlocks = fabricOptions.connectionBlocks.override;
bool overrideChannels = fabricOptions.channels.override;
TVPR_FabricModel_c vpr_fabricModel;
ok = vpr_fabricModel.Export( fabricModel,
&this->vpr_.arch,
type_descriptors, // [VPR] global variable
num_types, // [VPR] global variable
overrideBlocks,
overrideSwitchBoxes,
overrideConnectionBlocks,
overrideChannels );
}
// VPR snippet copied from VPR's vpr_init function...
if( ok )
{
printHandler.SetPrefix( TIO_SZ_VPR_PREFIX );
boolean readArchFile = static_cast< boolean >( !architectureSpec.IsValid( ));
vpr_setup_vpr( &this->vpr_.options,
this->vpr_.setup.TimingEnabled,
readArchFile,
&this->vpr_.setup.FileNameOpts,
&this->vpr_.arch,
&this->vpr_.setup.Operation,
&this->vpr_.setup.user_models,
&this->vpr_.setup.library_models,
&this->vpr_.setup.PackerOpts,
&this->vpr_.setup.PlacerOpts,
&this->vpr_.setup.AnnealSched,
&this->vpr_.setup.RouterOpts,
&this->vpr_.setup.RoutingArch,
&this->vpr_.setup.PackerRRGraph,
&this->vpr_.setup.Segments,
&this->vpr_.setup.Timing,
&this->vpr_.setup.ShowGraphics,
&this->vpr_.setup.GraphPause,
&this->vpr_.powerOpts );
// VPR snippet copied from VPR's vpr_init function...
vpr_check_options( this->vpr_.options,
this->vpr_.setup.TimingEnabled );
vpr_check_arch( this->vpr_.arch,
this->vpr_.setup.TimingEnabled );
vpr_check_setup( this->vpr_.setup.Operation,
this->vpr_.setup.PlacerOpts,
this->vpr_.setup.AnnealSched,
this->vpr_.setup.RouterOpts,
this->vpr_.setup.RoutingArch,
this->vpr_.setup.Segments,
this->vpr_.setup.Timing,
this->vpr_.arch.Chans );
printHandler.ClearPrefix( );
}
// Toro snippet specific to TVPR_Interface_c's initialization
if( ok && circuitDesign.IsValid( ) && circuitDesign.IsLegal( ))
{
printHandler.Info( "Exporting circuit design to VPR...\n" );
bool deleteInvalidData = ( this->vpr_.setup.PackerOpts.sweep_hanging_nets_and_inputs ? true : false );
TVPR_CircuitDesign_c vpr_circuitDesign;
ok = vpr_circuitDesign.Export( circuitDesign,
this->vpr_.setup.library_models,
this->vpr_.setup.user_models,
&vpack_net,
&num_logical_nets,
&g_atoms_nlist,
&logical_block,
&num_logical_blocks,
&num_p_inputs,
&num_p_outputs,
deleteInvalidData );
}
// VPR snippet copied from VPR's vpr_init function...
if(( ok && !circuitDesign.IsValid( )) ||
( ok && circuitDesign.IsValid( ) && !circuitDesign.IsLegal( )))
{
printHandler.SetPrefix( TIO_SZ_VPR_PREFIX );
boolean readActivityFile = FALSE;
char* pszActivityFileName = 0;
vpr_read_and_process_blif( this->vpr_.setup.PackerOpts.blif_file_name,
this->vpr_.setup.PackerOpts.sweep_hanging_nets_and_inputs,
this->vpr_.setup.user_models,
this->vpr_.setup.library_models,
readActivityFile, pszActivityFileName );
printHandler.ClearPrefix( );
}
if( optionsStore.controlSwitches.messageOptions.trace.vpr.showSetup )
{
printHandler.SetPrefix( TIO_SZ_VPR_PREFIX );
vpr_show_setup( this->vpr_.options, this->vpr_.setup );
printHandler.ClearPrefix( );
}
this->isAlive_ = ok;
return( this->isAlive_ );
}
//===========================================================================//
// Method : Execute
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
//===========================================================================//
bool TVPR_Interface_c::Execute(
const TOS_OptionsStore_c& optionsStore,
const TCD_CircuitDesign_c& circuitDesign ) const
{
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
if( this->isAlive_ )
{
printHandler.SetPrefix( TIO_SZ_VPR_PREFIX );
if( this->vpr_.setup.PackerOpts.doPacking )
{
vpr_pack( this->vpr_.setup, this->vpr_.arch );
}
if( this->vpr_.setup.PlacerOpts.doPlacement ||
this->vpr_.setup.RouterOpts.doRouting )
{
const TOS_PlaceOptions_c& placeOptions = optionsStore.GetPlaceOptions( );
if( placeOptions.regionPlace.enable )
{
TCH_RegionPlaceHandler_c& regionPlaceHandler = TCH_RegionPlaceHandler_c::GetInstance( );
regionPlaceHandler.Configure( circuitDesign.blockList,
circuitDesign.placeRegionsList );
}
if( placeOptions.relativePlace.enable )
{
TCH_RelativePlaceHandler_c& relativePlaceHandler = TCH_RelativePlaceHandler_c::GetInstance( );
relativePlaceHandler.Configure( placeOptions.relativePlace.rotateEnable,
placeOptions.relativePlace.carryChainEnable,
placeOptions.relativePlace.maxPlaceRetryCt,
placeOptions.relativePlace.maxMacroRetryCt,
circuitDesign.blockList );
}
if( placeOptions.prePlaced.enable )
{
TCH_PrePlacedHandler_c& prePlacedHandler = TCH_PrePlacedHandler_c::GetInstance( );
prePlacedHandler.Configure( circuitDesign.blockList );
}
const TOS_RouteOptions_c& routeOptions = optionsStore.GetRouteOptions( );
if( routeOptions.preRouted.enable )
{
TOS_RouteOrderMode_t preRoutedOrder = routeOptions.preRouted.orderMode;
TCH_RouteOrderMode_t preRoutedOrder_ = ( preRoutedOrder == TOS_ROUTE_ORDER_FIRST ?
TCH_ROUTE_ORDER_FIRST : TCH_ROUTE_ORDER_AUTO );
TCH_PreRoutedHandler_c& preRoutedHandler = TCH_PreRoutedHandler_c::GetInstance( );
preRoutedHandler.Configure( circuitDesign.netList,
circuitDesign.netOrderList,
preRoutedOrder_ );
}
vpr_init_pre_place_and_route( this->vpr_.setup, this->vpr_.arch );
boolean success = vpr_place_and_route( this->vpr_.setup,
this->vpr_.arch );
TVPR_Interface_c* pinterface = const_cast< TVPR_Interface_c* >( this );
pinterface->vpr_.success = success;
}
printHandler.ClearPrefix( );
}
return( this->isAlive_ );
}
//===========================================================================//
// Method : Close
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 07/10/12 jeffr : Original
// 07/23/13 jeffr : Added support for "tiClayResyncNets" & "tiClayFreeNets"
// 08/21/13 jeffr : Updated to pass "g_atoms_nlist" to TCH_CircuitDesign_c,
// instead of obsolete "vpack_net" and "num_logical_nets"
//===========================================================================//
bool TVPR_Interface_c::Close(
const TOS_OptionsStore_c& optionsStore,
TFM_FabricModel_c* pfabricModel,
TCD_CircuitDesign_c* pcircuitDesign )
{
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
if( this->isAlive_ )
{
const TOS_OutputOptions_c& outputOptions = optionsStore.GetOutputOptions( );
bool fabricFileEnable = outputOptions.fabricFileEnable;
bool circuitFileEnable = outputOptions.circuitFileEnable;
const TOS_ExecuteOptions_c& executeOptions = optionsStore.GetExecuteOptions( );
bool tiClayResyncNets = executeOptions.tiClay.resyncNets;
bool tiClayFreeNets = executeOptions.tiClay.freeNets;
if( fabricFileEnable && pfabricModel )
{
printHandler.Info( "Importing fabric model from VPR...\n" );
// Extract fabric model from VPR's internal data structures
// (based on VPR's global "grid", "nx", and "ny")
// (and, based on VPR's global "rr_node" and "num_rr_nodes")
TVPR_FabricModel_c vpr_fabricModel;
vpr_fabricModel.Import( grid, nx, ny,
rr_node, num_rr_nodes,
chan_width.x_list, chan_width.y_list,
pfabricModel );
}
if( circuitFileEnable && pcircuitDesign )
{
printHandler.Info( "Importing circuit design from VPR...\n" );
// Extract circuit design from VPR's internal data structures
// (based on VPR's global "block" and "num_blocks")
TVPR_CircuitDesign_c vpr_circuitDesign;
vpr_circuitDesign.Import( &this->vpr_.arch,
g_atoms_nlist,
block, num_blocks,
logical_block,
rr_node,
pcircuitDesign,
tiClayResyncNets );
}
this->Close( tiClayFreeNets );
}
return( this->isAlive_ );
}
//===========================================================================//
bool TVPR_Interface_c::Close(
bool freeDataStructures )
{
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
if( this->isAlive_ )
{
printHandler.SetPrefix( TIO_SZ_VPR_PREFIX );
if( freeDataStructures )
{
vpr_free_vpr_data_structures( this->vpr_.arch,
this->vpr_.options,
this->vpr_.setup );
}
printHandler.ClearPrefix( );
this->isAlive_ = false;
}
return( this->isAlive_ );
}
//===========================================================================//
// Method : ShowInternalError_
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 06/19/13 jeffr : Original
//===========================================================================//
bool TVPR_Interface_c::ShowInternalError_(
t_vpr_error* vpr_error ) const
{
const char* pszErrorType = "?";
switch( vpr_error->type )
{
case VPR_ERROR_UNKNOWN: pszErrorType = "UNKNOWN"; break;
case VPR_ERROR_ARCH: pszErrorType = "ARCH"; break;
case VPR_ERROR_PACK: pszErrorType = "PACK"; break;
case VPR_ERROR_PLACE: pszErrorType = "PLACE"; break;
case VPR_ERROR_ROUTE: pszErrorType = "ROUTE"; break;
case VPR_ERROR_OTHER: pszErrorType = "OTHER"; break;
default: break;
}
const char* pszErrorMessage = vpr_error->message;
const char* pszFileName = vpr_error->file_name;
unsigned int lineNum = vpr_error->line_num;
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
bool ok = printHandler.Fatal( "Terminating execution due to unexpected abort received from VPR.\n" );
if( pszFileName && *pszFileName )
{
printHandler.Error( "[%s:%d] %s",
pszFileName, lineNum,
TIO_PSZ_STR( pszErrorMessage ));
}
else
{
printHandler.Error( "[%s] %s",
TIO_PSZ_STR( pszErrorType ),
TIO_PSZ_STR( pszErrorMessage ));
}
return( ok );
}