blob: 61da6b30a9b4a3bb19ee3bd63f8575b315a9325b [file] [log] [blame] [edit]
//===========================================================================//
// Purpose : Method definitions for the TCH_PrePlacedHandler class.
//
// Public methods include:
// - NewInstance, DeleteInstance, GetInstance, HasInstance
// - Configure
// - Set, Reset
// - InitialPlace
// - IsValid
//
// Protected methods include:
// - TCH_PrePlacedHandler_c, ~TCH_PrePlacedHandler_c
//
// Private methods include:
// - ResetPrePlacedBlockList_
// - InitialPlaceBlockList_
// - InitialPlaceBlock_
// - ShowIllegalBlockWarning_
// - ShowMissingBlockNameError_
//
//===========================================================================//
//---------------------------------------------------------------------------//
// Copyright (C) 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 <cstdio>
using namespace std;
#include "TIO_PrintHandler.h"
#include "TGO_StringUtils.h"
#include "TCH_Typedefs.h"
#include "TCH_PrePlacedHandler.h"
// Initialize the pre-placed handler "singleton" class, as needed
TCH_PrePlacedHandler_c* TCH_PrePlacedHandler_c::pinstance_ = 0;
//===========================================================================//
// Method : TCH_PrePlacedHandler_c
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
TCH_PrePlacedHandler_c::TCH_PrePlacedHandler_c(
void )
:
prePlacedBlockList_( TCH_PREPLACED_BLOCK_LIST_DEF_CAPACITY )
{
pinstance_ = 0;
}
//===========================================================================//
// Method : ~TCH_PrePlacedHandler_c
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
TCH_PrePlacedHandler_c::~TCH_PrePlacedHandler_c(
void )
{
}
//===========================================================================//
// Method : NewInstance
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
void TCH_PrePlacedHandler_c::NewInstance(
void )
{
pinstance_ = new TC_NOTHROW TCH_PrePlacedHandler_c;
}
//===========================================================================//
// Method : DeleteInstance
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
void TCH_PrePlacedHandler_c::DeleteInstance(
void )
{
if( pinstance_ )
{
delete pinstance_;
pinstance_ = 0;
}
}
//===========================================================================//
// Method : GetInstance
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
TCH_PrePlacedHandler_c& TCH_PrePlacedHandler_c::GetInstance(
bool newInstance )
{
if( !pinstance_ )
{
if( newInstance )
{
NewInstance( );
}
}
return( *pinstance_ );
}
//===========================================================================//
// Method : HasInstance
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::HasInstance(
void )
{
return( pinstance_ ? true : false );
}
//===========================================================================//
// Method : Configure
// Description : Configure a pre-placed handler (singleton) based on Toro's
// block list and any associated pre-placed options.
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
void TCH_PrePlacedHandler_c::Configure(
const TPO_InstList_t& toro_circuitBlockList ) // Defined by Toro's block list
{
// Begin by first clearing any existing pre-placed block list data
this->prePlacedBlockList_.Clear( );
// Continue by setting pre-placed block estimated capacity
int toro_circuitBlockCount = static_cast< int >( toro_circuitBlockList.GetLength( ));
this->prePlacedBlockList_.SetCapacity( toro_circuitBlockCount );
// Initialize the local pre-placed block list based on Toro's block list
for( size_t i = 0; i < toro_circuitBlockList.GetLength( ); ++i )
{
const TPO_Inst_c& toro_circuitBlock = *toro_circuitBlockList[i];
const char* pszBlockName = toro_circuitBlock.GetName( );
TPO_StatusMode_t placeStatus = toro_circuitBlock.GetPlaceStatus( );
TCH_PlaceStatusMode_t status = TCH_PLACE_STATUS_UNDEFINED;
switch( placeStatus )
{
case TPO_STATUS_FLOAT: status = TCH_PLACE_STATUS_FLOAT; break;
case TPO_STATUS_FIXED: status = TCH_PLACE_STATUS_FIXED; break;
case TPO_STATUS_PLACED: status = TCH_PLACE_STATUS_PLACED; break;
default: break;
}
if(( status != TCH_PLACE_STATUS_FIXED ) && ( status != TCH_PLACE_STATUS_PLACED ))
continue;
const TGO_Point_c& origin = toro_circuitBlock.GetPlaceOrigin( );
if( !origin.IsValid( ))
continue;
TCH_PrePlacedBlock_c prePlacedBlock( pszBlockName, status, origin );
this->prePlacedBlockList_.Add( prePlacedBlock );
}
}
//===========================================================================//
// Method : Set
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
void TCH_PrePlacedHandler_c::Set(
t_grid_tile** vpr_gridArray,
int vpr_nx,
int vpr_ny,
t_block* vpr_blockArray,
int vpr_blockCount,
const t_type_descriptor* vpr_typeArray,
int vpr_typeCount,
int* vpr_freeLocationArray,
t_legal_pos** vpr_legalPosArray )
{
// Set local reference to VPR's grid array and asso. global data structures
this->vpr_data_.Init( vpr_gridArray, vpr_nx, vpr_ny,
vpr_blockArray, vpr_blockCount,
vpr_typeArray, vpr_typeCount,
vpr_freeLocationArray, vpr_legalPosArray );
}
//===========================================================================//
// Method : Reset
// Description : Resets the pre-placed handler in order to clear any
// existing placement information in VPR's grid array or
// in the local pre-placed block list.
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::Reset(
void )
{
bool ok = true;
// Reset local VPR's data placement information
this->vpr_data_.Reset( );
// Reset block index and type information for the pre-placed block list
ok = this->ResetPrePlacedBlockList_( this->vpr_data_.vpr_blockArray,
this->vpr_data_.vpr_blockCount,
&this->prePlacedBlockList_ );
return( ok );
}
//===========================================================================//
// Method : InitialPlace
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::InitialPlace(
t_grid_tile** vpr_gridArray,
int vpr_nx,
int vpr_ny,
t_block* vpr_blockArray,
int vpr_blockCount,
const t_type_descriptor* vpr_typeArray,
int vpr_typeCount,
int* vpr_freeLocationArray,
t_legal_pos** vpr_legalPosArray )
{
bool ok = true;
// At least one pre-placed constraint has been defined
bool placedAllBlocks = true;
// Initialize local VPR grid array and block list structures
this->Set( vpr_gridArray, vpr_nx, vpr_ny,
vpr_blockArray, vpr_blockCount,
vpr_typeArray, vpr_typeCount,
vpr_freeLocationArray, vpr_legalPosArray );
// Reset VPR grid array and pre-placed block list, then initialize place
ok = this->Reset( );
if( ok )
{
ok = this->InitialPlaceBlockList_( &placedAllBlocks );
}
return( ok );
}
//===========================================================================//
// Method : IsValid
// Description : Returns TRUE if at least one pre-placed block exists
// (ie. at least one placement constraint has been defined).
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::IsValid(
void ) const
{
return( this->prePlacedBlockList_.IsValid( ) ? true : false );
}
//===========================================================================//
// Method : ResetPrePlacedBlockList_
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::ResetPrePlacedBlockList_(
t_block* vpr_blockArray,
int vpr_blockCount,
TCH_PrePlacedBlockList_t* pprePlacedBlockList )
{
bool ok = true;
// Reset existing pre-placed block list index and type data
for( size_t i = 0; i < pprePlacedBlockList->GetLength( ); ++i )
{
TCH_PrePlacedBlock_c* pprePlacedBlock = (*pprePlacedBlockList)[i];
pprePlacedBlock->SetVPR_Index( -1 );
pprePlacedBlock->SetVPR_Type( 0 );
}
// Update pre-placed block list based on VPR block array index and type data
for( int blockIndex = 0; blockIndex < vpr_blockCount; ++blockIndex )
{
const char* pszBlockName = vpr_blockArray[blockIndex].name;
const t_type_descriptor* vpr_type = vpr_blockArray[blockIndex].type;
int vpr_index = blockIndex;
TCH_PrePlacedBlock_c* pprePlacedBlock = pprePlacedBlockList->Find( pszBlockName );
if( pprePlacedBlock )
{
pprePlacedBlock->SetVPR_Type( vpr_type );
pprePlacedBlock->SetVPR_Index( vpr_index );
}
}
// Validate that all pre-placed blocks have been updated
for( size_t i = 0; i < pprePlacedBlockList->GetLength( ); ++i )
{
const TCH_PrePlacedBlock_c& prePlacedBlock = *(*pprePlacedBlockList)[i];
if( prePlacedBlock.GetVPR_Index( ) == -1 )
{
const char* pszBlockName = prePlacedBlock.GetName( );
ok = this->ShowMissingBlockNameError_( pszBlockName );
if( !ok )
break;
}
}
return( ok );
}
//===========================================================================//
// Method : InitialPlaceBlockList_
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::InitialPlaceBlockList_(
bool* pplacedAllBlocks )
{
bool ok = true;
bool foundAllPlacements = true;
for( size_t i = 0; i < this->prePlacedBlockList_.GetLength( ); ++i )
{
const TCH_PrePlacedBlock_c& prePlacedBlock = *this->prePlacedBlockList_[i];
bool validPlacement = false;
bool foundPlacement = false;
ok = this->InitialPlaceBlock_( prePlacedBlock,
&validPlacement, &foundPlacement );
if( !ok )
break;
if( validPlacement && !foundPlacement )
{
foundAllPlacements = false;
}
}
if( !foundAllPlacements ) // Failed to place at least one of the pre-placed blocks
{
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
ok = printHandler.Error( "Failed to find initial placement for all pre-placed blocks.\n" );
}
if( *pplacedAllBlocks )
{
*pplacedAllBlocks = foundAllPlacements;
}
return( ok );
}
//===========================================================================//
// Method : InitialPlaceBlock_
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::InitialPlaceBlock_(
const TCH_PrePlacedBlock_c& prePlacedBlock,
bool* pvalidPlacement,
bool* pfoundPlacement )
{
bool ok = true;
*pvalidPlacement = false;
*pfoundPlacement = false;
const TGO_Point_c& gridPoint = prePlacedBlock.GetOrigin( );
int blockIndex = prePlacedBlock.GetVPR_Index( );
TCH_PlaceStatusMode_t blockStatus = prePlacedBlock.GetStatus( );
if( gridPoint.IsValid( ))
{
*pvalidPlacement = true;
const t_block* vpr_blockArray = this->vpr_data_.vpr_blockArray;
const t_type_descriptor* vpr_type = vpr_blockArray[blockIndex].type;
if( this->vpr_data_.IsOpenGridPoint( gridPoint, vpr_type ))
{
// And, update VPR's grid and block arrays based on the pre-placed block
this->vpr_data_.Set( gridPoint, blockIndex, blockStatus );
*pfoundPlacement = true;
}
else
{
const char* pszBlockName = prePlacedBlock.GetBlockName( );
ok = this->ShowIllegalBlockWarning_( pszBlockName, gridPoint );
}
}
return( ok );
}
//===========================================================================//
// Method : ShowIllegalBlockWarning_
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::ShowIllegalBlockWarning_(
const char* pszBlockName,
const TGO_Point_c& origin ) const
{
string srOrigin;
origin.ExtractString( &srOrigin );
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
bool ok = printHandler.Warning( "Failed to place pre-placed block \"%s\".\n",
TIO_PSZ_STR( pszBlockName ));
printHandler.Info( "%sGrid location at (%s) is not open or does not match type.\n",
TIO_PREFIX_WARNING_SPACE,
TIO_SR_STR( srOrigin ));
return( ok );
}
//===========================================================================//
// Method : ShowMissingBlockNameError_
// Author : Jeff Rudolph
//---------------------------------------------------------------------------//
// Version history
// 01/18/13 jeffr : Original
//===========================================================================//
bool TCH_PrePlacedHandler_c::ShowMissingBlockNameError_(
const char* pszBlockName ) const
{
TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( );
bool ok = printHandler.Error( "Invalid pre-placed block \"%s\"!\n",
TIO_PSZ_STR( pszBlockName ));
printHandler.Info( "%sBlock was not found in VPR's block list.\n",
TIO_PREFIX_ERROR_SPACE );
return( ok );
}