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()
, _flags (flags)
{
if (flags & VstNoLowerCase) _ns.setNoLowerCase( true );
if (not _offset) {
//_offset = offsetof(EntityProperty,_entity);
_offset = (ptrdiff_t)this - (ptrdiff_t)property;
@ -133,7 +134,7 @@ namespace Vhdl {
signal->addNet( index, net );
_signals.insert( signal );
} else {
ScalarSignal* signal = new ScalarSignal(net);
ScalarSignal* signal = new ScalarSignal(stem,net);
_signals.insert( signal );
if (net->isGlobal())
_globals.insert( signal );
@ -229,7 +230,7 @@ namespace Vhdl {
signal->addNet( index, net );
_signals.insert( signal );
} 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 << "-- Generated on " << stamp << "\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()) {
out << "-- VHDL IEEE compliant.\n";
} else {

View File

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

View File

@ -15,6 +15,7 @@
#include <cstddef>
#include <cstdio>
#include "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "hurricane/Net.h"
@ -39,16 +40,36 @@ namespace CRL {
void vstDriver ( const string cellPath, Cell *cell, unsigned int& saveState )
{
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 );
Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, entityFlags );
string celltest = cellPath;
ofstream ccelltest ( celltest.c_str() );
vhdlEntity->toEntity( ccelltest );
ccelltest << endl;
ccelltest.close();
string celltest = cellPath;
if (not (saveState & Catalog::State::VstNoLowerCase)) {
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 );
}

View File

@ -229,7 +229,10 @@ base_specifier (B|b|O|o|X|x)
\/ { return Slash; }
{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; }
VSTlval._text = Vst::states->addLexIdentifier( yytext );
return Identifier;

View File

@ -431,7 +431,9 @@ namespace {
{
for ( Model* model : _blifOrder )
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
, Foreign = 1 << 8
, VstUseConcat = 1 << 9
, VstNoLowerCase = 1 << 10
, Views = Physical|Logical
};
// Constructors.

View File

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

View File

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

View File

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

View File

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

View File

@ -2,25 +2,17 @@
// -*- C++ -*-
//
// 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 |
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyCatalog.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyCell.h"

View File

@ -1,14 +1,14 @@
// -*- C++ -*-
//
// 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 |
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyCatalogState.cpp" |
// +-----------------------------------------------------------------+
@ -146,6 +146,7 @@ extern "C" {
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::InMemory ,"InMemory");
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::Foreign ,"Foreign");
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::VstUseConcat ,"VstUseConcat");
LoadObjectConstant(PyTypeCatalogState.tp_dict,Catalog::State::VstNoLowerCase ,"VstNoLowerCase");
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'
if views & CRL.Catalog.State.VstUseConcat:
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 sviews: sviews += ','
sviews += 'layout'

View File

@ -98,7 +98,7 @@ namespace Unicorn {
_importCell.setDialog( _importDialog );
_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 ) );
/* Disabled because this is never the one you want
_importCell.addImporter<Cell*> ( "ISPD'04 (Bookshelf)" , std::bind( &Ispd04::load , placeholders::_1 ) );