diff --git a/bootstrap/coriolis2.spec.in b/bootstrap/coriolis2.spec.in index f9d864c0..92e0def8 100644 --- a/bootstrap/coriolis2.spec.in +++ b/bootstrap/coriolis2.spec.in @@ -21,7 +21,7 @@ print os.path.join ( pathes[-2], pathes[-1] ) Name: coriolis2 -Summary: Coriolis 2 VLSI CAD Sytem +Summary: Coriolis 2 VLSI CAD System Version: %{coriolisVersion}.%{svntag} Release: 1%{dist} License: BSD/LGPL/GPL/FLUTE @@ -163,6 +163,7 @@ Development files for the Coriolis 2 package. %dir %{coriolisTop}/include/coriolis2 %dir %{coriolisTop}/include/coriolis2/crlcore %dir %{coriolisTop}/include/coriolis2/nimbus +%dir %{coriolisTop}/include/coriolis2/etesian %dir %{coriolisTop}/include/coriolis2/metis %dir %{coriolisTop}/include/coriolis2/mauka %dir %{coriolisTop}/include/coriolis2/knik diff --git a/crlcore/src/ccore/CMakeLists.txt b/crlcore/src/ccore/CMakeLists.txt index 04efbae6..a77b9319 100644 --- a/crlcore/src/ccore/CMakeLists.txt +++ b/crlcore/src/ccore/CMakeLists.txt @@ -22,6 +22,7 @@ ${CRLCORE_SOURCE_DIR}/src/ccore/iccad04 ${CRLCORE_SOURCE_DIR}/src/ccore/cspice ${CRLCORE_SOURCE_DIR}/src/ccore/lefdef + ${CRLCORE_SOURCE_DIR}/src/ccore/blif ${CRLCORE_SOURCE_DIR}/src/ccore/alliance/ap ${CRLCORE_SOURCE_DIR}/src/ccore/alliance/vst ${CRLCORE_SOURCE_DIR}/src/ccore/agds @@ -61,6 +62,7 @@ crlcore/DefImport.h crlcore/DefExport.h crlcore/LefExport.h + crlcore/Blif.h crlcore/AcmSigda.h crlcore/Iccad04Lefdef.h crlcore/Ispd04Bookshelf.h @@ -151,6 +153,7 @@ set ( iccad04_cpps iccad04/Iccad04Lefdef.cpp ) set ( ispd04_cpps ispd04/Ispd04Bookshelf.cpp ) set ( ispd05_cpps ispd05/Ispd05Bookshelf.cpp ) + set ( blif_cpps blif/BlifDriver.cpp ) if ( LEFDEF_FOUND ) include_directories ( ${LEFDEF_INCLUDE_DIR} ) endif ( LEFDEF_FOUND ) @@ -296,6 +299,7 @@ ${iccad04_cpps} ${ispd04_cpps} ${ispd05_cpps} + ${blif_cpps} ${spice_cpps} ${lefdef_cpps} ${openaccess_cpps} diff --git a/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy b/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy index b2b14cf7..b5bcd60d 100644 --- a/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy +++ b/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy @@ -905,7 +905,7 @@ association_element actual_port_name { if (not Vst::states->_firstPass) { if ( Vst::states->_masterNets.size() != Vst::states->_instanceNets.size() ) { - ostringstream message; + ostringstream message; message << "CParsVst() VHDL Parser - File:<" << Vst::states->_vhdFileName.c_str() << "> Line:" << Vst::states->_vhdLineNumber << "\n" << " Port map assignment discrepency " diff --git a/crlcore/src/ccore/blif/BlifDriver.cpp b/crlcore/src/ccore/blif/BlifDriver.cpp new file mode 100644 index 00000000..889e9f5a --- /dev/null +++ b/crlcore/src/ccore/blif/BlifDriver.cpp @@ -0,0 +1,311 @@ +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2014, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | Yacc Grammar for Alliance Structural VHDL | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/UpdateSession.h" +using namespace Hurricane; + +#include "crlcore/Utilities.h" +#include "crlcore/Catalog.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/NetExtension.h" +#include "crlcore/Blif.h" +using namespace CRL; + + +namespace { + using namespace std; + + void addSupplyNets ( Cell* cell ) + { + Net* vss = Net::create ( cell, "vss" ); + vss->setExternal ( true ); + vss->setGlobal ( true ); + vss->setType ( Net::Type::GROUND ); + + Net* vdd = Net::create ( cell, "vdd" ); + vdd->setExternal ( true ); + vdd->setGlobal ( true ); + vdd->setType ( Net::Type::POWER ); + } + + void connectSupplyNets ( Instance * instance, Cell* design ) + { + Cell* instcell = instance->getCell(); + if(instcell == NULL){ + throw Error("Instance's cell is null\n"); + } + Net* vssint = instcell->getNet( "vss" ); + Net* vddint = instcell->getNet( "vdd" ); + cerr << "Got instance nets" << endl; + Net* vssext = design->getNet( "vss" ); + Net* vddext = design->getNet( "vdd" ); + cerr << "Got cell nets" << endl; + auto vssplug = instance->getPlug( vssint ); + auto vddplug = instance->getPlug( vddint ); + cerr << "Got plugs: " << vssplug << " and " << vddplug << endl; + vssplug->setNet( vssext ); + vddplug->setNet( vddext ); + cerr << "Updated nets" << endl; + } + + void SetNetType ( Net* net, AllianceFramework * framework ) + { + if ( framework->isPOWER(net->getName()) ) { + net->setType ( Net::Type::POWER ); + net->setGlobal ( true ); + } else if ( framework->isGROUND(net->getName()) ) { + net->setType ( Net::Type::GROUND ); + net->setGlobal ( true ); + } else if ( framework->isCLOCK(net->getName()) ) { + net->setType ( Net::Type::CLOCK ); + } else + net->setType ( Net::Type::LOGICAL ); + } + + enum ParserState{ + EXT = 0x00, + MODEL = 0x01, + SUBCKT = 0x02, + NAMES = 0x04, + INPUTS = 0x08, + OUTPUTS = 0x16 + }; + + struct subckt{ + string cell; + vector > pins; + }; + + struct model{ + string name; + unordered_map pins; + vector subcircuits; + bool operator<(model const & o) const{ return name < o.name; } + }; + +} // End of anonymous namespace. + + +namespace CRL { + + +// +// Can only parse simple, netlist BLIF files generated by Yosys +// Ignores all ".names" and uses only the .subckt, .model, .input and .output +// + +Cell * Blif::load ( string cellPath ) //, Cell *cell ) +{ + using namespace std; + + auto framework = AllianceFramework::get (); + + std::ifstream ccell ( cellPath+".blif" ); + + cmess2 << " " << tab << "+ " << cellPath << " [BLIF]" << endl; + + std::vector models; + ParserState state = EXT; + bool hasName; + + string line; + while(getline(ccell, line)){ + istringstream linestream(line); + string before_comment; + getline(linestream, before_comment, '#'); + istringstream tokens(before_comment); + string token; + while(tokens>>token){ + assert(not token.empty()); + if(token[0] == '.'){ + if(token == ".model"){ + if(state != EXT) + throw Error("Nested model are not supported\n"); + state = MODEL; + hasName = false; + models.push_back(model()); + } + else if(token == ".subckt"){ + if(state == EXT) + throw Error("Subcircuit without an enclosing model are not supported\n"); + if(state == MODEL and not hasName) + throw Error("Model has no name\n"); + state = SUBCKT; + hasName = false; + models.back().subcircuits.push_back(subckt()); + } + else if(token == ".names"){ + cerr << Warning("BLIF names are ignored\n"); + if(state == EXT) + throw Error("Names without an enclosing model are not supported\n"); + if(state == MODEL and not hasName) + throw Error("Model has no name\n"); + state = NAMES; + hasName = false; + } + else if(token == ".latch"){ + throw Error("Latch constructs are not understood by the parser\n"); + } + else if(token == ".inputs"){ + if(state == EXT) + throw Error("Inputs have been found without an enclosing model\n"); + state = INPUTS; + } + else if(token == ".outputs"){ + if(state == EXT) + throw Error("Outputs have been found without an enclosing model\n"); + state = OUTPUTS; + } + else if(token == ".end"){ + if(state == EXT) + throw Error("A .end has been found out of a model\n"); + state = EXT; + } + else{ + throw Error("Unexpected control token\n"); + } + } + else{ // Either a pin or an input/output definition + if(state == INPUTS or state == OUTPUTS){ + auto it = models.back().pins.find(token); + Net::Direction D = (state == INPUTS)? Net::Direction::DirIn : Net::Direction::DirOut; + if(it != models.back().pins.end()){ + it->second = static_cast(D | it->second); + } + else{ + models.back().pins.insert(pair(token, D)); + } + } + else if(state == SUBCKT){ + if(hasName){ + // Encountered a pin: need to be processed + istringstream token_stream(token); + string before_space, after_space; + getline(token_stream, before_space, '='); + getline(token_stream, after_space, '='); + if(token_stream){ + Error("Encountered more than one '=' in token"); + } + models.back().subcircuits.back().pins.push_back(pair(before_space, after_space)); + } + else{ + models.back().subcircuits.back().cell = token; + hasName = true; + } + } + else if(state == NAMES){ + // TODO; now just ignored + } + else if(state == MODEL){ + if(hasName) + throw Error("Unexpected token after model name\n"); + else{ + models.back().name = token; + hasName = true; + } + } + else{ + throw Error("Unexpected token\n"); + } + } + } + line.clear(); + } + if(state != EXT){ + cerr << Warning("End of model has not been found\n"); + } + + /* + for(auto & M : models){ + cout << "Model: " << M.name << endl; + for(auto & S : M.subcircuits){ + cout << "\tInstance of " << S.cell; + for(auto & P : S.pins){ + cout << " " << P.first << ":" << P.second; + } + cout << endl; + } + } + */ + + if(models.size() > 1){ + cerr << Warning("Several models in the file; only the last was open\n"); + } + + Cell * design = NULL; + for(auto M : models){ + design = framework->createCell(M.name); + addSupplyNets(design); + + unordered_set net_names; + for(auto const & S : M.subcircuits){ + for(auto const & P : S.pins){ + net_names.insert(P.second); + } + } + for(auto const & P : M.pins){ + net_names.insert(P.first); + } + + for(string const & N : net_names){ + Net* new_net = Net::create( design, N ); + auto it = M.pins.find(N); + if(it != M.pins.end()){ + new_net->setExternal( true ); + new_net->setDirection( it->second ); + } + } + + int i=0; + for(auto & S : M.subcircuits){ + ostringstream subckt_name; + subckt_name << "subckt_" << i; + Cell * cell = framework->getCell(S.cell, Catalog::State::Views, 0); + if(cell == NULL){ + cerr << Warning("Cell " + S.cell + "to instanciate hasn't been found\n"); + continue; + } + Instance* instance = Instance::create( design, subckt_name.str(), cell); + + for(auto & P : S.pins){ + Net* internalNet = cell->getNet( P.first ); + Net* externalNet = design->getNet( P.second ); + assert(internalNet != NULL and externalNet != NULL); + instance->getPlug( internalNet )->setNet( externalNet ); + } + //connectSupplyNets(instance, design); + ++i; + } + } + + return design; +} + +} + + diff --git a/crlcore/src/ccore/crlcore/Blif.h b/crlcore/src/ccore/crlcore/Blif.h new file mode 100644 index 00000000..f326f203 --- /dev/null +++ b/crlcore/src/ccore/crlcore/Blif.h @@ -0,0 +1,63 @@ + + +// -*- C++ -*- +// +// This file is part of the Coriolis Project. +// Copyright (C) Laboratoire LIP6 - Departement ASIM +// Universite Pierre et Marie Curie +// +// Main contributors : +// Christophe Alexandre +// Sophie Belloeil +// Hugo Clément +// Jean-Paul Chaput +// Damien Dupuis +// Christian Masson +// Marek Sroka +// +// The Coriolis Project is free software; you can redistribute it +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// The Coriolis Project is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with the Coriolis Project; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// License-Tag +// Authors-Tag +// =================================================================== + + +#ifndef CRL_BLIF_H +#define CRL_BLIF_H + +# include + + +namespace Hurricane { + class Cell; +} + + +namespace CRL { + + using Hurricane::Cell; + + + class Blif { + public: + static Cell* load ( std::string netlist ); + }; + + +} // End of CRL namespace. + + +# endif diff --git a/unicorn/src/UnicornGui.cpp b/unicorn/src/UnicornGui.cpp index 3831a6ac..a5f12fb2 100644 --- a/unicorn/src/UnicornGui.cpp +++ b/unicorn/src/UnicornGui.cpp @@ -28,6 +28,7 @@ #include "crlcore/AcmSigda.h" #include "crlcore/Ispd04Bookshelf.h" #include "crlcore/Ispd05Bookshelf.h" +#include "crlcore/Blif.h" #include "crlcore/Iccad04Lefdef.h" #include "crlcore/DefImport.h" #include "crlcore/DefExport.h" @@ -51,6 +52,7 @@ namespace Unicorn { using CRL::AcmSigda; using CRL::Ispd04; using CRL::Ispd05; + using CRL::Blif; using CRL::Iccad04Lefdef; using CRL::DefImport; using CRL::DefExport; @@ -87,6 +89,7 @@ namespace Unicorn { _importCell.addImporter( "ACM/SIGDA (aka MCNC, .bench)", std::bind( &AcmSigda::load , placeholders::_1 ) ); _importCell.addImporter( "ISPD'04 (Bookshelf)" , std::bind( &Ispd04::load , placeholders::_1 ) ); _importCell.addImporter( "ISPD'05 (Bookshelf)" , std::bind( &Ispd05::load , placeholders::_1 ) ); + _importCell.addImporter( "BLIF (Yosys/ABC)" , std::bind( &Blif::load , placeholders::_1 ) ); _importCell.addImporter( "ICCAD'04 (LEF/DEF)" , std::bind( &Iccad04Lefdef::load, placeholders::_1, 0 ) ); _importCell.addImporter( "Alliance compliant DEF" , std::bind( &DefImport::load , placeholders::_1, DefImport::FitAbOnCells) ); }