| //===========================================================================// |
| // Purpose : Method definitions for the TCD_CircuitDesign class. |
| // |
| // Public methods include: |
| // - TCD_CircuitDesign_c, ~TCD_CircuitDesign_c |
| // - operator= |
| // - operator==, operator!= |
| // - Print |
| // - PrintBLIF |
| // - InitDefaults |
| // - InitValidate |
| // - IsLegal |
| // - IsValid |
| // |
| // Private methods include: |
| // - InitDefaultsNetList_ |
| // - InitDefaultsNetNameList_ |
| // - InitValidateNetList_ |
| // - InitValidateInstList_ |
| // |
| //===========================================================================// |
| |
| //---------------------------------------------------------------------------// |
| // 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_PrintHandler.h" |
| |
| #include "TCD_CircuitDesign.h" |
| |
| //===========================================================================// |
| // Method : TCD_CircuitDesign_c |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| TCD_CircuitDesign_c::TCD_CircuitDesign_c( |
| void ) |
| : |
| blockList( TCD_BLOCK_LIST_DEF_CAPACITY ), |
| portList( TCD_PORT_LIST_DEF_CAPACITY ), |
| portNameList( TCD_PORT_NAME_LIST_DEF_CAPACITY ), |
| instList( TCD_INST_LIST_DEF_CAPACITY ), |
| instNameList( TCD_INST_NAME_LIST_DEF_CAPACITY ), |
| cellList( TCD_CELL_LIST_DEF_CAPACITY ), |
| netList( TCD_NET_LIST_DEF_CAPACITY ), |
| netNameList( TCD_NET_NAME_LIST_DEF_CAPACITY ), |
| netOrderList( TCD_NET_ORDER_LIST_DEF_CAPACITY ), |
| placeRegionsList( TCD_PLACE_REGIONS_LIST_DEF_CAPACITY ) |
| { |
| } |
| |
| //===========================================================================// |
| TCD_CircuitDesign_c::TCD_CircuitDesign_c( |
| const TCD_CircuitDesign_c& circuitDesign ) |
| : |
| srName( circuitDesign.srName ), |
| blockList( circuitDesign.blockList ), |
| portList( circuitDesign.portList ), |
| portNameList( circuitDesign.portNameList ), |
| instList( circuitDesign.instList ), |
| instNameList( circuitDesign.instNameList ), |
| cellList( circuitDesign.cellList ), |
| netList( circuitDesign.netList ), |
| netNameList( circuitDesign.netNameList ), |
| netOrderList( circuitDesign.netOrderList ), |
| placeRegionsList( circuitDesign.placeRegionsList ) |
| { |
| } |
| |
| //===========================================================================// |
| // Method : ~TCD_CircuitDesign_c |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| TCD_CircuitDesign_c::~TCD_CircuitDesign_c( |
| void ) |
| { |
| } |
| |
| //===========================================================================// |
| // Method : operator= |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| TCD_CircuitDesign_c& TCD_CircuitDesign_c::operator=( |
| const TCD_CircuitDesign_c& circuitDesign ) |
| { |
| if( &circuitDesign != this ) |
| { |
| this->srName = circuitDesign.srName; |
| this->blockList = circuitDesign.blockList; |
| this->portList = circuitDesign.portList; |
| this->portNameList = circuitDesign.portNameList; |
| this->instList = circuitDesign.instList; |
| this->instNameList = circuitDesign.instNameList; |
| this->cellList = circuitDesign.cellList; |
| this->netList = circuitDesign.netList; |
| this->netNameList = circuitDesign.netNameList; |
| this->netOrderList = circuitDesign.netOrderList; |
| this->placeRegionsList = circuitDesign.placeRegionsList; |
| } |
| return( *this ); |
| } |
| |
| //===========================================================================// |
| // Method : operator== |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::operator==( |
| const TCD_CircuitDesign_c& circuitDesign ) const |
| { |
| return(( this->srName == circuitDesign.srName ) && |
| ( this->blockList == circuitDesign.blockList ) && |
| ( this->portList == circuitDesign.portList ) && |
| ( this->portNameList == circuitDesign.portNameList ) && |
| ( this->instList == circuitDesign.instList ) && |
| ( this->instNameList == circuitDesign.instNameList ) && |
| ( this->cellList == circuitDesign.cellList ) && |
| ( this->netList == circuitDesign.netList ) && |
| ( this->netNameList == circuitDesign.netNameList ) && |
| ( this->netOrderList == circuitDesign.netOrderList ) && |
| ( this->placeRegionsList == circuitDesign.placeRegionsList ) ? |
| true : false ); |
| } |
| |
| //===========================================================================// |
| // Method : operator!= |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::operator!=( |
| const TCD_CircuitDesign_c& circuitDesign ) const |
| { |
| return( !this->operator==( circuitDesign ) ? true : false ); |
| } |
| |
| //===========================================================================// |
| // Method : Print |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| void TCD_CircuitDesign_c::Print( |
| FILE* pfile, |
| size_t spaceLen ) const |
| { |
| TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( ); |
| printHandler.Write( pfile, spaceLen, "<circuit name=\"%s\">\n", |
| TIO_SR_STR( this->srName )); |
| spaceLen += 3; |
| |
| if( this->blockList.IsValid( )) |
| { |
| printHandler.Write( pfile, spaceLen, "\n" ); |
| for( size_t i = 0; i < this->blockList.GetLength( ); ++i ) |
| { |
| this->blockList[i]->Print( pfile, spaceLen, "block" ); |
| } |
| } |
| if( this->portNameList.IsValid( ) && this->portList.IsValid( )) |
| { |
| printHandler.Write( pfile, spaceLen, "\n" ); |
| for( size_t i = 0; i < this->portNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& portName = *this->portNameList[i]; |
| const char* pszPortName = portName.GetName( ); |
| const TPO_Port_t& port = *this->portList.Find( pszPortName ); |
| |
| port.Print( pfile, spaceLen, "port" ); |
| } |
| } |
| if( this->instNameList.IsValid( ) && this->instList.IsValid( )) |
| { |
| printHandler.Write( pfile, spaceLen, "\n" ); |
| for( size_t i = 0; i < this->instNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& instName = *this->instNameList[i]; |
| const char* pszInstName = instName.GetName( ); |
| const TPO_Inst_c& inst = *this->instList.Find( pszInstName ); |
| |
| inst.Print( pfile, spaceLen, "inst" ); |
| } |
| } |
| if( this->cellList.IsValid( )) |
| { |
| printHandler.Write( pfile, spaceLen, "\n" ); |
| for( size_t i = 0; i < this->cellList.GetLength( ); ++i ) |
| { |
| this->cellList[i]->Print( pfile, spaceLen ); |
| } |
| } |
| if( this->netList.IsValid( )) |
| { |
| printHandler.Write( pfile, spaceLen, "\n" ); |
| for( size_t i = 0; i < this->netList.GetLength( ); ++i ) |
| { |
| this->netList[i]->Print( pfile, spaceLen ); |
| } |
| } |
| if( this->placeRegionsList.IsValid( )) |
| { |
| printHandler.Write( pfile, spaceLen, "\n" ); |
| for( size_t i = 0; i < this->placeRegionsList.GetLength( ); ++i ) |
| { |
| this->placeRegionsList[i]->Print( pfile, spaceLen ); |
| } |
| } |
| |
| spaceLen -= 3; |
| printHandler.Write( pfile, spaceLen, "\n" ); |
| printHandler.Write( pfile, spaceLen, "</circuit>\n" ); |
| } |
| |
| //===========================================================================// |
| // Method : PrintBLIF |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| void TCD_CircuitDesign_c::PrintBLIF( |
| void ) const |
| { |
| FILE* pfile = 0; |
| size_t spaceLen = 0; |
| |
| this->PrintBLIF( pfile, spaceLen ); |
| } |
| |
| //===========================================================================// |
| void TCD_CircuitDesign_c::PrintBLIF( |
| FILE* pfile, |
| size_t spaceLen ) const |
| { |
| TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( ); |
| printHandler.Write( pfile, spaceLen, ".model %s\n", |
| TIO_SR_STR( this->srName )); |
| |
| printHandler.Write( pfile, spaceLen, ".inputs" ); |
| for( size_t i = 0; i < this->portNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& portName = *this->portNameList[i]; |
| const char* pszPortName = portName.GetName( ); |
| const TPO_Port_t& port = *this->portList.Find( pszPortName ); |
| |
| const TPO_PinList_t& pinList = port.GetPinList( ); |
| const TPO_Pin_t& pin = *pinList[0]; |
| if( pin.GetType( ) == TC_TYPE_OUTPUT ) |
| { |
| printHandler.Write( pfile, spaceLen, " %s", |
| TIO_PSZ_STR( pin.GetName( ))); |
| } |
| } |
| printHandler.Write( pfile, 0, "\n" ); |
| |
| printHandler.Write( pfile, spaceLen, ".outputs" ); |
| for( size_t i = 0; i < this->portNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& portName = *this->portNameList[i]; |
| const char* pszPortName = portName.GetName( ); |
| const TPO_Port_t& port = *this->portList.Find( pszPortName ); |
| |
| const TPO_PinList_t& pinList = port.GetPinList( ); |
| const TPO_Pin_t& pin = *pinList[0]; |
| if( pin.GetType( ) == TC_TYPE_INPUT ) |
| { |
| printHandler.Write( pfile, spaceLen, " %s", |
| TIO_PSZ_STR( pin.GetName( ))); |
| } |
| } |
| printHandler.Write( pfile, 0, "\n" ); |
| |
| for( size_t i = 0; i < this->instNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& instName = *this->instNameList[i]; |
| const char* pszInstName = instName.GetName( ); |
| const TPO_Inst_c& inst = *this->instList.Find( pszInstName ); |
| |
| if( inst.GetSource( ) == TPO_INST_SOURCE_LATCH ) |
| { |
| inst.PrintBLIF( pfile, spaceLen ); |
| } |
| } |
| for( size_t i = 0; i < this->instNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& instName = *this->instNameList[i]; |
| const char* pszInstName = instName.GetName( ); |
| const TPO_Inst_c& inst = *this->instList.Find( pszInstName ); |
| |
| if( inst.GetSource( ) == TPO_INST_SOURCE_NAMES ) |
| { |
| inst.PrintBLIF( pfile, spaceLen ); |
| } |
| } |
| for( size_t i = 0; i < this->instNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& instName = *this->instNameList[i]; |
| const char* pszInstName = instName.GetName( ); |
| const TPO_Inst_c& inst = *this->instList.Find( pszInstName ); |
| |
| if( inst.GetSource( ) == TPO_INST_SOURCE_SUBCKT ) |
| { |
| inst.PrintBLIF( pfile, spaceLen ); |
| } |
| } |
| printHandler.Write( pfile, spaceLen, ".end\n" ); |
| |
| for( size_t i = 0; i < this->cellList.GetLength( ); ++i ) |
| { |
| this->cellList[i]->PrintBLIF( pfile, spaceLen ); |
| } |
| } |
| |
| //===========================================================================// |
| // Method : InitDefaults |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::InitDefaults( |
| const string& srDefaultBaseName ) |
| { |
| bool ok = true; |
| |
| // Set default model name (if no ".model" defined) based on default name |
| // (default name is assumed to be based on the input options file name) |
| if( !this->srName.length( )) |
| { |
| this->srName = srDefaultBaseName; |
| } |
| |
| if( !this->netList.IsValid( )) |
| { |
| this->InitDefaultsNetList_( this->instList, this->portList, this->cellList, |
| &this->netList ); |
| } |
| ok = this->InitValidateNetList_( &this->netList ); |
| if( ok ) |
| { |
| this->InitDefaultsNetNameList_( this->instList, this->portList, |
| &this->netList, &this->netNameList ); |
| } |
| return( ok ); |
| } |
| |
| //===========================================================================// |
| // Method : InitValidate |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::InitValidate( |
| void ) |
| { |
| bool ok = true; |
| |
| if( ok ) |
| { |
| // Validate unique instance names |
| // (based on ".names <input_1> <input_2> <input_3> ... <input_n> <output>") |
| // (based on ".latch <input> <output> [<type> <control>] [<init_val>]") |
| bool uniquifyShowWarning = true; |
| bool uniquifyShowError = false; |
| ok = this->instList.Uniquify( uniquifyShowWarning, uniquifyShowError, |
| "instance list" ); |
| } |
| |
| if( ok ) |
| { |
| ok = this->InitValidateInstList_( this->instList, |
| this->cellList ); |
| } |
| |
| // TBD - Given: .latch <input> <output> [<type> <control>] [<init_val>] |
| // TBD - can we validate input pin name exists in pin list (with matching type)? |
| // TBD - can we validate output pin name exists in pin list (with matching type)? |
| // TBD - can we validate clock pin name exists in pin list (with matching type)? |
| |
| if( ok ) |
| { |
| // Validate unique cell names |
| // (based on ".subckt <model_name> <port>=<input|output> ...") |
| bool uniquifyShowWarning = true; |
| bool uniquifyShowError = false; |
| ok = this->cellList.Uniquify( uniquifyShowWarning, uniquifyShowError, |
| "cell list" ); |
| } |
| |
| if( ok ) |
| { |
| // Validate unique input/output port names |
| // (based on ".inputs <input_1> <input_2> <input_3> ... <input_n>") |
| // (based on ".outputs <output_1> <output_2> <output_3> ... <output_n>") |
| // (based on ".clock <clock_1> <clock_2> <clock_3> ... <clock_n>") |
| bool uniquifyShowWarning = true; |
| bool uniquifyShowError = false; |
| ok = this->portList.Uniquify( uniquifyShowWarning, uniquifyShowError, |
| "port list" ); |
| } |
| |
| if( ok ) |
| { |
| // Validate unique cell pin names |
| for( size_t i = 0; i < this->cellList.GetLength( ); ++i ) |
| { |
| TLO_Cell_c* pcell = this->cellList[i]; |
| const char* pszCellName = pcell->GetName( ); |
| TLO_PinList_t pinList_ = pcell->GetPinList( ); |
| |
| bool uniquifyShowWarning = true; |
| bool uniquifyShowError = false; |
| ok = pinList_.Uniquify( uniquifyShowWarning, uniquifyShowError, |
| "cell", pszCellName, "pin" ); |
| if( !ok ) |
| break; |
| |
| if( pinList_.GetLength( ) != pcell->GetPinList( ).GetLength( )) |
| { |
| pcell->SetPinList( pinList_ ); |
| } |
| } |
| } |
| return( ok ); |
| } |
| |
| //===========================================================================// |
| // Method : IsLegal |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::IsLegal( |
| void ) const |
| { |
| return( this->IsValid( ) && |
| this->blockList.IsValid( ) && |
| this->portList.IsValid( ) && |
| this->instList.IsValid( ) && |
| this->netList.IsValid( ) ? |
| true : false ); |
| } |
| |
| //===========================================================================// |
| // Method : IsValid |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::IsValid( |
| void ) const |
| { |
| return( this->srName.length( ) ? true : false ); |
| } |
| |
| //===========================================================================// |
| // Method : InitDefaultsNetList_ |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 07/25/12 jeffr : Original |
| //===========================================================================// |
| void TCD_CircuitDesign_c::InitDefaultsNetList_( |
| const TPO_InstList_t& instList_, |
| const TPO_PortList_t& portList_, |
| const TLO_CellList_t& cellList_, |
| TNO_NetList_c* pnetList_ ) const |
| { |
| // Estimate initial net list length |
| size_t netEstLength = portList_.GetLength( ); |
| for( size_t i = 0; i < instList_.GetLength( ); ++i ) |
| { |
| const TPO_Inst_c& inst = *instList_[i]; |
| const TPO_PinList_t& pinList_ = inst.GetPinList( ); |
| netEstLength += pinList_.GetLength( ); |
| } |
| |
| // Allocate a local net list used to extract an initial list of net names |
| TNO_NetList_c netList_( netEstLength ); |
| |
| // Load a local net list based on all potential pin-based net names |
| for( size_t i = 0; i < instList_.GetLength( ); ++i ) |
| { |
| const TPO_Inst_c& inst = *instList_[i]; |
| const TPO_PinList_t& pinList_ = inst.GetPinList( ); |
| for( size_t j = 0; j < pinList_.GetLength( ); ++j ) |
| { |
| const TPO_Pin_t& pin = *pinList_[j]; |
| netList_.Add( pin.GetName( )); |
| } |
| } |
| for( size_t i = 0; i < portList_.GetLength( ); ++i ) |
| { |
| const TPO_Port_t& port = *portList_[i]; |
| netList_.Add( port.GetName( )); |
| } |
| |
| // Force unique sort to detect and remove all duplicate net names |
| netList_.Uniquify( ); |
| |
| // Load given (returned) net list based on local (sorted) net list |
| pnetList_->SetCapacity( netList_.GetLength( )); |
| for( size_t i = 0; i < netList_.GetLength( ); ++i ) |
| { |
| TNO_Net_c net = *netList_[i]; |
| pnetList_->Add( net ); |
| } |
| |
| // Finally, repeat instance and port list iteration to update each net |
| for( size_t i = 0; i < instList_.GetLength( ); ++i ) |
| { |
| const TPO_Inst_c& inst = *instList_[i]; |
| const TPO_PinList_t& pinList_ = inst.GetPinList( ); |
| |
| if( inst.GetSource( ) == TPO_INST_SOURCE_NAMES ) |
| { |
| unsigned int inputCount = 0; |
| for( size_t j = 0; j < pinList_.GetLength( ); ++j ) |
| { |
| const TPO_Pin_t& pin = *pinList_[j]; |
| TNO_Net_c* pnet = pnetList_->Find( pin.GetName( )); |
| |
| if( pin.GetType( ) == TC_TYPE_OUTPUT ) |
| { |
| pnet->AddInstPin( inst.GetName( ), "out", TC_TYPE_OUTPUT ); |
| } |
| else if( pin.GetType( ) == TC_TYPE_INPUT ) |
| { |
| char szPinName[TIO_FORMAT_STRING_LEN_DATA]; |
| sprintf( szPinName, "in[%u]", inputCount++ ); |
| pnet->AddInstPin( inst.GetName( ), szPinName, TC_TYPE_INPUT ); |
| } |
| } |
| } |
| else if( inst.GetSource( ) == TPO_INST_SOURCE_LATCH ) |
| { |
| for( size_t j = 0; j < pinList_.GetLength( ); ++j ) |
| { |
| const TPO_Pin_t& pin = *pinList_[j]; |
| TNO_Net_c* pnet = pnetList_->Find( pin.GetName( )); |
| |
| if( pin.GetType( ) == TC_TYPE_OUTPUT ) |
| { |
| pnet->AddInstPin( inst.GetName( ), "Q", TC_TYPE_OUTPUT ); |
| } |
| else if( pin.GetType( ) == TC_TYPE_INPUT ) |
| { |
| pnet->AddInstPin( inst.GetName( ), "D", TC_TYPE_INPUT ); |
| } |
| else if( pin.GetType( ) == TC_TYPE_CLOCK ) |
| { |
| pnet->AddInstPin( inst.GetName( ), "clk", TC_TYPE_CLOCK ); |
| pnet->SetRoutable( false ); |
| } |
| } |
| } |
| else if( inst.GetSource( ) == TPO_INST_SOURCE_SUBCKT ) |
| { |
| const TPO_PinMapList_t& pinMapList_ = inst.GetSubcktPinMapList( ); |
| for( size_t j = 0; j < pinMapList_.GetLength( ); ++j ) |
| { |
| const TPO_PinMap_c& pinMap = *pinMapList_[j]; |
| TNO_Net_c* pnet = pnetList_->Find( pinMap.GetInstPinName( )); |
| |
| const TLO_Cell_c* pcell = cellList_.Find( inst.GetCellName( )); |
| if( !pcell ) |
| continue; |
| |
| const TLO_PortList_t& portList__ = pcell->GetPortList( ); |
| const TLO_Port_c* pport = portList__.Find( pinMap.GetCellPinName( )); |
| if( !pport ) |
| continue; |
| |
| pnet->AddInstPin( pinMap.GetInstPinName( ), pinMap.GetCellPinName( ), |
| pport->GetType( )); |
| } |
| } |
| } |
| |
| for( size_t i = 0; i < portList_.GetLength( ); ++i ) |
| { |
| const TPO_Port_t& port = *portList_[i]; |
| TNO_Net_c* pnet = pnetList_->Find( port.GetName( )); |
| |
| if( port.GetInputOutputType( ) == TC_TYPE_OUTPUT ) |
| { |
| pnet->AddInstPin( port.GetName( ), "inpad", TC_TYPE_OUTPUT ); |
| } |
| else if( port.GetInputOutputType( ) == TC_TYPE_INPUT ) |
| { |
| pnet->AddInstPin( port.GetName( ), "outpad", TC_TYPE_INPUT ); |
| } |
| } |
| } |
| |
| //===========================================================================// |
| // Method : InitDefaultsNetNameList_ |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 07/25/12 jeffr : Original |
| //===========================================================================// |
| void TCD_CircuitDesign_c::InitDefaultsNetNameList_( |
| const TPO_InstList_t& instList_, |
| const TPO_PortList_t& portList_, |
| TNO_NetList_c* pnetList_, |
| TNO_NameList_t* pnetNameList_ ) const |
| { |
| TNO_NetList_c netList_( pnetList_->GetLength( )); |
| for( size_t i = 0; i < pnetList_->GetLength( ); ++i ) |
| { |
| const TNO_Net_c& net = *( *pnetList_ )[i]; |
| netList_.Add( net.GetName( )); |
| } |
| |
| unsigned int netIndex = 0; |
| for( size_t i = 0; i < portList_.GetLength( ); ++i ) |
| { |
| const TPO_Port_t& port = *portList_[i]; |
| TNO_Net_c* pnet = netList_.Find( port.GetName( )); |
| if( pnet && pnet->IsRoutable( )) |
| { |
| pnet->SetRoutable( false ); |
| pnetNameList_->Add( port.GetName( )); |
| |
| pnet = pnetList_->Find( port.GetName( )); |
| pnet->SetIndex( netIndex ); |
| ++netIndex; |
| } |
| } |
| for( size_t i = 0; i < instList_.GetLength( ); ++i ) |
| { |
| const TPO_Inst_c& inst = *instList_[i]; |
| const TPO_PinList_t& pinList_ = inst.GetPinList( ); |
| for( size_t j = 0; j < pinList_.GetLength( ); ++j ) |
| { |
| const TPO_Pin_t& pin = *pinList_[j]; |
| TNO_Net_c* pnet = netList_.Find( pin.GetName( )); |
| if( pnet && pnet->IsRoutable( )) |
| { |
| pnet->SetRoutable( false ); |
| pnetNameList_->Add( pin.GetName( )); |
| |
| pnet = pnetList_->Find( pin.GetName( )); |
| pnet->SetIndex( netIndex ); |
| ++netIndex; |
| } |
| } |
| } |
| } |
| |
| //===========================================================================// |
| // Method : InitValidateNetList_ |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 07/25/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::InitValidateNetList_( |
| TNO_NetList_c* pnetList ) const |
| { |
| TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( ); |
| |
| bool ok = true; |
| |
| size_t zeroInputPinCount = 0; |
| size_t zeroOutputPinCount = 0; |
| size_t multiOutputPinCount = 0; |
| |
| TNO_NameList_t deleteNameList( pnetList->GetLength( )); |
| |
| for( size_t i = 0; i < pnetList->GetLength( ); ++i ) |
| { |
| const TNO_Net_c& net = *( *pnetList )[i]; |
| if( !net.IsRoutable( )) |
| continue; |
| |
| size_t inputPinCount = net.FindInstPinCount( TC_TYPE_INPUT ); |
| if( inputPinCount == 0 ) |
| { |
| // [VPR] If input pad has 0 receivers, then delete from net list |
| // (this includes mcnc circuits, as well as ODIN subckts) |
| ok = printHandler.Warning( "Invalid net \"%s\" detected.\n" |
| "%sNo input pins found.\n" |
| "%sA net with zero signals driving it may be invalid.\n", |
| TIO_PSZ_STR( net.GetName( )), |
| TIO_PREFIX_WARNING_SPACE, |
| TIO_PREFIX_WARNING_SPACE ); |
| if( !ok ) |
| break; |
| |
| ++zeroInputPinCount; |
| deleteNameList.Add( net.GetName( )); |
| } |
| |
| size_t outputPinCount = net.FindInstPinCount( TC_TYPE_OUTPUT ); |
| if( outputPinCount == 0 ) |
| { |
| ok = printHandler.Error( "Invalid net \"%s\" detected!\n" |
| "%sNo output pins found.\n", |
| TIO_PSZ_STR( net.GetName( )), |
| TIO_PREFIX_ERROR_SPACE ); |
| if( !ok ) |
| break; |
| |
| ++zeroOutputPinCount; |
| deleteNameList.Add( net.GetName( )); |
| } |
| else if( outputPinCount > 1 ) |
| { |
| ok = printHandler.Error( "Invalid net \"%s\" detected!\n" |
| "%sToo many output pins founds.\n", |
| TIO_PSZ_STR( net.GetName( )), |
| TIO_PREFIX_ERROR_SPACE ); |
| if( !ok ) |
| break; |
| |
| ++multiOutputPinCount; |
| deleteNameList.Add( net.GetName( )); |
| } |
| } |
| |
| for( size_t i = 0; i < deleteNameList.GetLength( ); ++i ) |
| { |
| const TC_Name_c& deleteName = *deleteNameList[i]; |
| pnetList->Delete( deleteName.GetName( )); |
| } |
| |
| if( ok && zeroInputPinCount ) |
| { |
| ok = printHandler.Warning( "Deleted %d nets with zero input pins.\n", |
| zeroInputPinCount ); |
| } |
| if( ok && zeroOutputPinCount ) |
| { |
| ok = printHandler.Warning( "Deleted %d nets with zero output pins.\n", |
| zeroOutputPinCount ); |
| } |
| if( ok && multiOutputPinCount ) |
| { |
| ok = printHandler.Warning( "Deleted %d nets with multiple output pins.\n", |
| multiOutputPinCount ); |
| } |
| return( ok ); |
| } |
| |
| //===========================================================================// |
| // Method : InitValidateInstList_ |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/15/12 jeffr : Original |
| //===========================================================================// |
| bool TCD_CircuitDesign_c::InitValidateInstList_( |
| const TPO_InstList_t& instList_, |
| const TLO_CellList_t& cellList_ ) const |
| { |
| TIO_PrintHandler_c& printHandler = TIO_PrintHandler_c::GetInstance( ); |
| |
| bool ok = true; |
| |
| for( size_t i = 0; i < instList_.GetLength( ); ++i ) |
| { |
| const TPO_Inst_c& inst = *instList_[i]; |
| |
| if(( inst.GetSource( ) == TPO_INST_SOURCE_NAMES ) && |
| ( cellList_.IsMember( "names" ))) |
| { |
| const TLO_Cell_c* pcell = cellList_.Find( "names" ); |
| size_t cellInputCount = pcell->FindPortCount( TC_TYPE_INPUT ); |
| size_t instInputCount = inst.FindPinCount( TC_TYPE_INPUT, cellList_ ); |
| |
| if( instInputCount > cellInputCount ) |
| { |
| const char* pszInstName = inst.GetName( ); |
| ok = printHandler.Error( "Invalid LUT size for .names \"%s\"!\n" |
| "%sInput pin count exeeds VPR architecture LUT number of pins (%d)\n", |
| TIO_PSZ_STR( pszInstName ), |
| TIO_PREFIX_ERROR_SPACE, |
| cellInputCount ); |
| } |
| if( !ok ) |
| break; |
| } |
| |
| const TPO_PinList_t& pinList = inst.GetPinList( ); |
| for( size_t j = 0; j < pinList.GetLength( ); ++j ) |
| { |
| const TPO_Pin_t& pin = *pinList[j]; |
| const char* pszPinName = pin.GetName( ); |
| |
| if( strcmp( pszPinName, "open" ) == 0 ) |
| { |
| const char* pszSource = "instance"; |
| if( inst.GetSource( ) == TPO_INST_SOURCE_NAMES ) |
| { |
| pszSource = ".names"; |
| } |
| if( inst.GetSource( ) == TPO_INST_SOURCE_LATCH ) |
| { |
| pszSource = ".latch"; |
| } |
| if( inst.GetSource( ) == TPO_INST_SOURCE_SUBCKT ) |
| { |
| pszSource = ".subckt"; |
| } |
| |
| ok = printHandler.Error( "Invalid pin name for %s \"%s\"!\n" |
| "%sPin name \"open\" is a reserved VPR keyword\n", |
| TIO_PSZ_STR( pszSource ), |
| TIO_PSZ_STR( pszPinName ), |
| TIO_PREFIX_ERROR_SPACE ); |
| if( !ok ) |
| break; |
| } |
| } |
| } |
| return( ok ); |
| } |