The VST driver is now allowed to preserve the case of identifiers.

* New: In CRL::NamingScheme, add a flag VstNoLowerCase, and its
    management it in the Verilog to VHDL converter.
* Change: In CRL::BlifParser::Model::toVhdlModels(), disable the
    lowercasing of identifiers. We shouldn't apply Alliance VHDL
    subset constraits when reading blif files. So we will see
    uppercase identifiers in Coriolis.
* Change: In CRL::VstParser, no longer lowercase identifiers that
    are *not* VHDL keywords. Uppercases are legals in VHDL...
* New: In CRL::Catalog::State, add a new flag VstNoLowerCase to
    tell if the VST driver should keep the uppercases.
* Change: In CRL::VhdlEntity, add a VstNolowerCase flag to disable
    the lowercasing.
* Change: In CRL::vstDriver, lower case the file name if needed.
    remove the previously opened filename if it differs from the
    lowercased one.
* Change: In UnicornGui CTOR, disable VHDL enforcement for the
    Blif parser.
This commit is contained in:
Jean-Paul Chaput 2020-06-08 13:34:25 +02:00
parent f91fc4f927
commit 5d891b2cd8
14 changed files with 114 additions and 68 deletions

View File

@ -105,6 +105,7 @@ namespace Vhdl {
, _globals() , _globals()
, _flags (flags) , _flags (flags)
{ {
if (flags & VstNoLowerCase) _ns.setNoLowerCase( true );
if (not _offset) { if (not _offset) {
//_offset = offsetof(EntityProperty,_entity); //_offset = offsetof(EntityProperty,_entity);
_offset = (ptrdiff_t)this - (ptrdiff_t)property; _offset = (ptrdiff_t)this - (ptrdiff_t)property;
@ -133,7 +134,7 @@ namespace Vhdl {
signal->addNet( index, net ); signal->addNet( index, net );
_signals.insert( signal ); _signals.insert( signal );
} else { } else {
ScalarSignal* signal = new ScalarSignal(net); ScalarSignal* signal = new ScalarSignal(stem,net);
_signals.insert( signal ); _signals.insert( signal );
if (net->isGlobal()) if (net->isGlobal())
_globals.insert( signal ); _globals.insert( signal );
@ -229,7 +230,7 @@ namespace Vhdl {
signal->addNet( index, net ); signal->addNet( index, net );
_signals.insert( signal ); _signals.insert( signal );
} else { } else {
_signals.insert( new ScalarSignal(net) ); _signals.insert( new ScalarSignal(stem,net) );
} }
} }
} }
@ -324,6 +325,12 @@ namespace Vhdl {
out << "-- Coriolis Structural VHDL Driver\n"; out << "-- Coriolis Structural VHDL Driver\n";
out << "-- Generated on " << stamp << "\n"; out << "-- Generated on " << stamp << "\n";
out << "-- \n"; out << "-- \n";
if (_flags & OptionMask) {
out << "-- Genarated with options:\n";
if (_flags & VstUseConcat) out << "-- * VstUseConcat: Use concat (&) in port map.\n";
if (_flags & VstNoLowerCase) out << "-- * VstNoLowerCase: Identifiers are *not* put in lowercase.\n";
out << "-- \n";
}
if (isIeeeMode()) { if (isIeeeMode()) {
out << "-- VHDL IEEE compliant.\n"; out << "-- VHDL IEEE compliant.\n";
} else { } else {

View File

@ -96,8 +96,8 @@ namespace Vhdl {
// Class : "Vhdl::ScalarSignal". // Class : "Vhdl::ScalarSignal".
ScalarSignal::ScalarSignal ( Net* net ) ScalarSignal::ScalarSignal ( string vhdlName, Net* net )
: Signal(getString(net->getName())) : Signal(vhdlName)
, _bit (BitExtension::create(net,this)) , _bit (BitExtension::create(net,this))
{ } { }

View File

@ -15,6 +15,7 @@
#include <cstddef> #include <cstddef>
#include <cstdio>
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/Net.h" #include "hurricane/Net.h"
@ -39,16 +40,36 @@ namespace CRL {
void vstDriver ( const string cellPath, Cell *cell, unsigned int& saveState ) void vstDriver ( const string cellPath, Cell *cell, unsigned int& saveState )
{ {
unsigned int entityFlags = Vhdl::Entity::EntityMode /* | Vhdl::Entity::IeeeMode */; unsigned int entityFlags = Vhdl::Entity::EntityMode /* | Vhdl::Entity::IeeeMode */;
if (saveState & Catalog::State::VstUseConcat) entityFlags |= Vhdl::Entity::VstUseConcat; if (saveState & Catalog::State::VstUseConcat ) entityFlags |= Vhdl::Entity::VstUseConcat;
if (saveState & Catalog::State::VstNoLowerCase) entityFlags |= Vhdl::Entity::VstNoLowerCase;
//NamingScheme::toVhdl( cell, NamingScheme::FromVerilog ); //NamingScheme::toVhdl( cell, NamingScheme::FromVerilog );
Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, entityFlags ); Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, entityFlags );
string celltest = cellPath;
ofstream ccelltest ( celltest.c_str() );
vhdlEntity->toEntity( ccelltest ); string celltest = cellPath;
ccelltest << endl; if (not (saveState & Catalog::State::VstNoLowerCase)) {
ccelltest.close(); size_t slash = cellPath.find_last_of( "/" );
size_t dot = cellPath.find_last_of( "." );
string path = "";
string file = "";
string ext = cellPath.substr( dot+1 );
if (slash != string::npos) {
path = cellPath.substr( 0, slash );
file = cellPath.substr( slash+1, dot-slash-1 );
} else {
file = cellPath;
}
NamingScheme ns (NamingScheme::FromVerilog);
file = getString( ns.convert(file) );
celltest = path + '/' + file + '.' + ext;
if (cellPath != celltest) remove( cellPath.c_str() );
}
ofstream cellStream ( celltest.c_str() );
vhdlEntity->toEntity( cellStream );
cellStream << endl;
cellStream.close();
Vhdl::EntityExtension::destroy( cell ); Vhdl::EntityExtension::destroy( cell );
} }

View File

@ -229,7 +229,10 @@ base_specifier (B|b|O|o|X|x)
\/ { return Slash; } \/ { return Slash; }
{letter}(_?{letter_or_digit})* { {letter}(_?{letter_or_digit})* {
VHDLKeywords::iterator it = vhdlKeywords.find( lower(yytext) ); char keyword[512];
strncpy( keyword, yytext, 511 );
lower( keyword );
VHDLKeywords::iterator it = vhdlKeywords.find( keyword );
if (it != vhdlKeywords.end()) { return it->second; } if (it != vhdlKeywords.end()) { return it->second; }
VSTlval._text = Vst::states->addLexIdentifier( yytext ); VSTlval._text = Vst::states->addLexIdentifier( yytext );
return Identifier; return Identifier;

View File

@ -431,7 +431,9 @@ namespace {
{ {
for ( Model* model : _blifOrder ) for ( Model* model : _blifOrder )
CRL::NamingScheme::toVhdl( model->getCell() CRL::NamingScheme::toVhdl( model->getCell()
, CRL::NamingScheme::Recursive|CRL::NamingScheme::FromVerilog ); , CRL::NamingScheme::Recursive
| CRL::NamingScheme::FromVerilog
| CRL::NamingScheme::NoLowerCase );
} }

View File

@ -87,6 +87,7 @@ namespace CRL {
, InMemory = 1 << 7 , InMemory = 1 << 7
, Foreign = 1 << 8 , Foreign = 1 << 8
, VstUseConcat = 1 << 9 , VstUseConcat = 1 << 9
, VstNoLowerCase = 1 << 10
, Views = Physical|Logical , Views = Physical|Logical
}; };
// Constructors. // Constructors.

View File

@ -65,19 +65,29 @@ namespace CRL {
enum Flag { NoFlags = 0x0000 enum Flag { NoFlags = 0x0000
, Recursive = 0x0001 , Recursive = 0x0001
, FromVerilog = 0x0002 , FromVerilog = 0x0002
, NoLowerCase = 0x0004
}; };
public: public:
typedef std::function< Name(const Name&) > converter_t; typedef std::function< Name(const Name&,uint32_t) > converter_t;
public: public:
static Name vlogToVhdl ( const Name& vlogName ); static Name vlogToVhdl ( const Name& vlogName, uint32_t flags );
static void toVhdl ( Cell* topCell, unsigned int flags ); static void toVhdl ( Cell* topCell, uint32_t flags );
NamingScheme ( unsigned int flags ); NamingScheme ( uint32_t flags );
Name convert ( const Name& ) const; inline void setNoLowerCase ( bool state );
Name convert ( const Name& ) const;
private: private:
uint32_t _flags;
converter_t _converter; converter_t _converter;
}; };
inline void NamingScheme::setNoLowerCase ( bool state )
{
if (state) _flags |= NoLowerCase;
else _flags &= ~NoLowerCase;
}
} // CRL namespace. } // CRL namespace.
#endif // CRL_TOOLBOX_H #endif // CRL_TOOLBOX_H

View File

@ -58,15 +58,17 @@ namespace Vhdl {
class Entity { class Entity {
public: public:
enum Flag { NoFlags = 0x0000 enum Flag { NoFlags = 0x0000
, EntityMode = 0x0001 , EntityMode = 0x0001
, IeeeMode = 0x0002 , IeeeMode = 0x0002
, ComponentMode = 0x0004 , ComponentMode = 0x0004
, AsPortSignal = 0x0008 , AsPortSignal = 0x0008
, AsInnerSignal = 0x0010 , AsInnerSignal = 0x0010
, VstUseConcat = 0x0020 , VstUseConcat = 0x0020
, VstNoLowerCase = 0x0040
, OptionMask = VstUseConcat|VstNoLowerCase
}; };
const unsigned int ModeMask = VstUseConcat; const unsigned int ModeMask = VstUseConcat|VstNoLowerCase;
public: public:
static std::vector<Entity*>& static std::vector<Entity*>&
getAllEntities (); getAllEntities ();

View File

@ -74,7 +74,7 @@ namespace Vhdl {
class ScalarSignal : public Signal { class ScalarSignal : public Signal {
public: public:
ScalarSignal ( Net* ); ScalarSignal ( std::string vhdlName, Net* );
virtual ~ScalarSignal (); virtual ~ScalarSignal ();
virtual bool isScalar () const; virtual bool isScalar () const;
virtual bool isVector () const; virtual bool isVector () const;

View File

@ -29,17 +29,10 @@ namespace CRL {
using Hurricane::Instance; using Hurricane::Instance;
Name NamingScheme::vlogToVhdl ( const Name& vlogName ) Name NamingScheme::vlogToVhdl ( const Name& vlogName, uint32_t flags )
{ {
string vhdlName; string vhdlName;
string loweredName;
// VHDL reserved keywords (scalar).
if (vlogName == Name("in" )) return "in_v";
if (vlogName == Name("out" )) return "out_v";
if (vlogName == Name("inout")) return "inout_v";
if (vlogName == Name("true" )) return "bool_true";
if (vlogName == Name("false")) return "bool_false";
if (vlogName == Name("undef")) return "bool_undef";
size_t parCount = 0; size_t parCount = 0;
size_t posLeftPar = 0; size_t posLeftPar = 0;
@ -49,6 +42,7 @@ namespace CRL {
if (vlogName[i] == '[') { ++parCount; posLeftPar=i; } if (vlogName[i] == '[') { ++parCount; posLeftPar=i; }
if (vlogName[i] == ')') { posRightPar=i; } if (vlogName[i] == ')') { posRightPar=i; }
if (vlogName[i] == ']') { posRightPar=i; } if (vlogName[i] == ']') { posRightPar=i; }
loweredName.push_back( tolower(vlogName[i]) );
} }
char leftPar = (parCount > 1) ? '_' : '('; char leftPar = (parCount > 1) ? '_' : '(';
char rightPar = (parCount > 1) ? '_' : ')'; char rightPar = (parCount > 1) ? '_' : ')';
@ -62,8 +56,17 @@ namespace CRL {
} }
} }
for ( size_t i=0 ; i<vlogName.size() ; ++i ) { // VHDL reserved keywords (scalar).
char translated = tolower( vlogName[i] ); if (loweredName == "in" ) return "in_v";
if (loweredName == "out" ) return "out_v";
if (loweredName == "inout") return "inout_v";
if (loweredName == "true" ) return "bool_true";
if (loweredName == "false") return "bool_false";
if (loweredName == "undef") return "bool_undef";
string refName = (flags & NoLowerCase) ? getString(vlogName) : loweredName;
for ( size_t i=0 ; i<refName.size() ; ++i ) {
char translated = refName[i];
if ( vhdlName.empty() and (isdigit(translated)) ) if ( vhdlName.empty() and (isdigit(translated)) )
vhdlName += 'n'; vhdlName += 'n';
@ -78,7 +81,7 @@ namespace CRL {
if (translated == '_') { if (translated == '_') {
if (vhdlName.empty() ) continue; if (vhdlName.empty() ) continue;
if (i == vlogName.size()-1) break; if (i == refName.size()-1) break;
if (vhdlName.back() == '_') continue; if (vhdlName.back() == '_') continue;
} }
@ -86,18 +89,18 @@ namespace CRL {
} }
// VHDL reserved keywords (vector). // VHDL reserved keywords (vector).
if (vhdlName.substr(0,3) == "in(" ) vhdlName.insert(2,"_v"); if (loweredName.substr(0,3) == "in(" ) vhdlName.insert(2,"_v");
if (vhdlName.substr(0,4) == "out(" ) vhdlName.insert(3,"_v"); if (loweredName.substr(0,4) == "out(" ) vhdlName.insert(3,"_v");
if (vhdlName.substr(0,6) == "inout(") vhdlName.insert(5,"_v"); if (loweredName.substr(0,6) == "inout(") vhdlName.insert(5,"_v");
if (vhdlName == "true" ) vhdlName.insert(0,"value_"); if (loweredName == "true" ) vhdlName.insert(0,"value_");
if (vhdlName == "false" ) vhdlName.insert(0,"value_"); if (loweredName == "false" ) vhdlName.insert(0,"value_");
if (vhdlName == "undef" ) vhdlName.insert(0,"value_"); if (loweredName == "undef" ) vhdlName.insert(0,"value_");
return Name(vhdlName); return Name(vhdlName);
} }
void NamingScheme::toVhdl ( Cell* topCell, unsigned int flags ) void NamingScheme::toVhdl ( Cell* topCell, uint32_t flags )
{ {
if (not topCell) return; if (not topCell) return;
@ -107,11 +110,11 @@ namespace CRL {
if (converter == nullptr) return; if (converter == nullptr) return;
topCell->setName( converter(topCell->getName()) ); topCell->setName( converter(topCell->getName(),flags) );
vector<Net*> nets; vector<Net*> nets;
for ( Net* net : topCell->getNets() ) nets.push_back( net ); for ( Net* net : topCell->getNets() ) nets.push_back( net );
for ( auto net : nets ) net->setName( converter( net->getName() ) ); for ( auto net : nets ) net->setName( converter( net->getName(), flags ) );
vector<Instance*> instances; vector<Instance*> instances;
set<Cell*,Entity::CompareById> models; set<Cell*,Entity::CompareById> models;
@ -119,7 +122,7 @@ namespace CRL {
instances.push_back( inst ); instances.push_back( inst );
models.insert( inst->getMasterCell() ); models.insert( inst->getMasterCell() );
} }
for ( auto inst : instances ) inst->setName( converter( inst->getName() ) ); for ( auto inst : instances ) inst->setName( converter( inst->getName(), flags ) );
if (flags & Recursive) if (flags & Recursive)
for ( auto model : models ) { for ( auto model : models ) {
@ -128,17 +131,18 @@ namespace CRL {
} }
NamingScheme::NamingScheme ( unsigned int flags ) NamingScheme::NamingScheme ( uint32_t flags )
: _converter(nullptr) : _flags (flags)
, _converter(nullptr)
{ {
if (flags & FromVerilog) _converter = vlogToVhdl; if (_flags & FromVerilog) _converter = vlogToVhdl;
} }
Name NamingScheme::convert ( const Name& name ) const Name NamingScheme::convert ( const Name& name ) const
{ {
if (_converter == nullptr) return name; if (_converter == nullptr) return name;
return _converter(name); return _converter(name,_flags);
} }

View File

@ -2,25 +2,17 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved // Copyright (c) SU/LIP6 2010-2020, All Rights Reserved
// //
// =================================================================== // +-----------------------------------------------------------------+
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S | // | C O R I O L I S |
// | Alliance / Hurricane Interface | // | Alliance / Hurricane Interface |
// | | // | |
// | Author : Jean-Paul CHAPUT | // | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Module : "./PyCatalog.cpp" | // | C++ Module : "./PyCatalog.cpp" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "hurricane/isobar/PyCell.h" #include "hurricane/isobar/PyCell.h"

View File

@ -1,14 +1,14 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2010-2018, All Rights Reserved // Copyright (c) UPMC 2010-2020, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
// | Alliance / Hurricane Interface | // | Alliance / Hurricane Interface |
// | | // | |
// | Author : Jean-Paul CHAPUT | // | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Module : "./PyCatalogState.cpp" | // | C++ Module : "./PyCatalogState.cpp" |
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
@ -146,6 +146,7 @@ extern "C" {
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::InMemory ,"InMemory"); LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::InMemory ,"InMemory");
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::Foreign ,"Foreign"); LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::Foreign ,"Foreign");
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::VstUseConcat ,"VstUseConcat"); LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::VstUseConcat ,"VstUseConcat");
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::VstNoLowerCase ,"VstNoLowerCase");
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::Views ,"Views"); LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::Views ,"Views");
} }

View File

@ -48,7 +48,10 @@ def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0 ):
sviews += 'netlist' sviews += 'netlist'
if views & CRL.Catalog.State.VstUseConcat: if views & CRL.Catalog.State.VstUseConcat:
if sviews: sviews += ',' if sviews: sviews += ','
sviews += 'VST uses &' sviews += ' uses &'
if views & CRL.Catalog.State.VstNoLowerCase:
if sviews: sviews += ', no lowercase'
sviews += ''
if views & CRL.Catalog.State.Physical: if views & CRL.Catalog.State.Physical:
if sviews: sviews += ',' if sviews: sviews += ','
sviews += 'layout' sviews += 'layout'

View File

@ -98,7 +98,7 @@ namespace Unicorn {
_importCell.setDialog( _importDialog ); _importCell.setDialog( _importDialog );
_importCell.addImporter<Cell*> ( "JSON (experimental)" , std::bind( &Cell::fromJson , placeholders::_1 ) ); _importCell.addImporter<Cell*> ( "JSON (experimental)" , std::bind( &Cell::fromJson , placeholders::_1 ) );
_importCell.addImporter<Cell*> ( "BLIF (Yosys/ABC)" , std::bind( &Blif::load , placeholders::_1, true ) ); _importCell.addImporter<Cell*> ( "BLIF (Yosys/ABC)" , std::bind( &Blif::load , placeholders::_1, false ) );
_importCell.addImporter<Cell*> ( "ACM/SIGDA (aka MCNC, .bench)", std::bind( &AcmSigda::load , placeholders::_1 ) ); _importCell.addImporter<Cell*> ( "ACM/SIGDA (aka MCNC, .bench)", std::bind( &AcmSigda::load , placeholders::_1 ) );
/* Disabled because this is never the one you want /* Disabled because this is never the one you want
_importCell.addImporter<Cell*> ( "ISPD'04 (Bookshelf)" , std::bind( &Ispd04::load , placeholders::_1 ) ); _importCell.addImporter<Cell*> ( "ISPD'04 (Bookshelf)" , std::bind( &Ispd04::load , placeholders::_1 ) );