Complete rewrite of the VHDL (Vst) driver. True handling of vectors.

* Bug: In Hurricane, in NetAlias, bad Record construction of the _next
    field.
* New: In CRL Core, in VstDriver complete replacement of the old Vst
    driver. Needed cleaner architecture to manage correctly files
    importeds through the Blif parser, which are Verilog like.
      It is build as an extension trough property and is not kept
    in sync with the Cell. So it's use should be transient only.
* Change: In CRL Core, in NamingScheme forgot to change '.' (dot)
    forbidden character into '_'.
* Change: In Cumulus, in the RSave plugins, remove the VHDL extensions
    after saving.
This commit is contained in:
Jean-Paul Chaput 2015-05-02 18:39:35 +02:00
parent 479429e12d
commit 06e5e3060c
19 changed files with 1943 additions and 61 deletions

View File

@ -68,6 +68,10 @@
crlcore/Ispd04Bookshelf.h
crlcore/Ispd05Bookshelf.h
crlcore/Ioc.h
crlcore/VhdlBit.h
crlcore/VhdlSignal.h
crlcore/VhdlEntity.h
crlcore/VhdlPortMap.h
crlcore/NetExtension.h
crlcore/Measures.h
crlcore/RoutingGauge.h
@ -130,7 +134,12 @@
toolbox/RoutingPads.cpp
toolbox/NamingScheme.cpp
)
set ( vst_driver_cpps alliance/vst/VstDriver.cpp )
set ( vst_driver_cpps alliance/vst/VhdlBit.cpp
alliance/vst/VhdlSignal.cpp
alliance/vst/VhdlPortMap.cpp
alliance/vst/VhdlEntity.cpp
alliance/vst/VstDriver.cpp
)
set ( properties_cpps properties/NetExtension.cpp
properties/Measures.cpp
)

View File

@ -0,0 +1,176 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./alliance/vst/VhdlNetProperty.cpp" |
// +-----------------------------------------------------------------+
#include "crlcore/VhdlBit.h"
#include "crlcore/VhdlSignal.h"
namespace Vhdl {
using namespace std;
using Hurricane::_TName;
using Hurricane::Property;
const size_t Bit::nindex = std::numeric_limits<size_t>::max();
// -------------------------------------------------------------------
// Class : "::Bit" (implementation).
ptrdiff_t Bit::_offset = 0;
Bit::Bit ( BitProperty* property, const Net* net, Signal* signal, size_t index )
: _signal(signal)
, _index (index)
{
if (not _offset) {
//_offset = offsetof(ScalarSignal,_toNet);
_offset = (ptrdiff_t)this - (ptrdiff_t)property;
}
}
Bit::Bit ( size_t index )
: _signal(NULL)
, _index (index)
{ }
Bit::~Bit ()
{ }
bool Bit::isExternal () const { return getNet()->isExternal(); }
bool Bit::isElement () const { return _index != nindex; }
const Signal* Bit::getSignal () const { return _signal; }
size_t Bit::getIndex () const { return _index; }
string Bit::getName () const { return _getString(); }
string Bit::_getString () const
{
string s = getSignal()->getName();
if (_index != nindex) {
if (getSignal()->isContiguous())
s += "(" + getString(_index) + ")";
else
s += "_" + getString(_index);
}
return s;
}
Record* Bit::_getRecord () const
{
Record* record = new Record ( "<Bit " + _getString() + " >" );
if (record != NULL) {
record->add( getSlot("_signal", _signal) );
record->add( getSlot("_index" , _index ) );
}
return record;
}
// -------------------------------------------------------------------
// Class : "BitProperty"
Name BitProperty::_name = "Vhdl::Bit";
BitProperty* BitProperty::create ( Net* owner, Signal* signal, size_t index )
{
BitProperty *property = new BitProperty( owner, signal, index );
property->_postCreate ();
return property;
}
void BitProperty::onReleasedBy ( DBo* owner )
{ PrivateProperty::onReleasedBy( owner ); }
Name BitProperty::getPropertyName ()
{ return _name; }
Name BitProperty::getName () const
{ return getPropertyName(); }
string BitProperty::_getTypeName () const
{ return _TName( "BitProperty" ); }
string BitProperty::_getString () const
{
string s = PrivateProperty::_getString ();
s.insert ( s.length() - 1 , " " + getString(&_bit) );
return s;
}
Record* BitProperty::_getRecord () const
{
Record* record = PrivateProperty::_getRecord();
if ( record ) {
record->add( getSlot( "_name", _name ) );
record->add( getSlot( "_bit" , &_bit ) );
}
return record;
}
// -------------------------------------------------------------------
// Class : "BitExtension"
const Net* BitExtension::_owner = NULL;
Bit* BitExtension::_cache = NULL;
Bit* BitExtension::get ( const Net* net )
{
if (net == _owner) return _cache;
_owner = net;
Property* property = _owner->getProperty( BitProperty::getPropertyName() );
if (property) _cache = static_cast<BitProperty*>(property)->getBit();
else _cache = NULL;
return _cache;
}
Bit* BitExtension::create ( Net* net, Signal* signal, size_t index )
{
get( net );
if (_cache) return _cache;
BitProperty* property = new BitProperty( net, signal, index );
net->put( property );
_cache = property->getBit();
return _cache;
}
} // Vhdl namespace.

View File

@ -0,0 +1,526 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./alliance/vst/VhdlEntity.cpp" |
// +-----------------------------------------------------------------+
#include <iomanip>
#include <ctime>
#include "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "crlcore/VhdlPortMap.h"
#include "crlcore/VhdlEntity.h"
namespace {
using Hurricane::Net;
using Hurricane::Instance;
using Vhdl::Signal;
using Vhdl::PortMap;
using Vhdl::Entity;
class ComparePort {
public:
ComparePort ( unsigned int flags ) : _flags(flags) { };
public:
inline bool operator() ( const Signal* lhs, const Signal* rhs ) const
{
bool isSupply1 = lhs->getNet()->isSupply();
bool isSupply2 = rhs->getNet()->isSupply();
if (isSupply1 != isSupply2) return not isSupply1;
if (_flags & Entity::AsPortSignal) {
unsigned int dir1 = (unsigned int)lhs->getDirection() & Net::Direction::INOUT;
unsigned int dir2 = (unsigned int)rhs->getDirection() & Net::Direction::INOUT;
if (dir1 != dir2) {
if (not dir1) return false;
if (not dir2) return true;
return dir1 < dir2;
}
}
bool isV1 = lhs->isVector();
bool isV2 = rhs->isVector();
if (isV1 != isV2) return not isV1;
size_t range1 = lhs->getMax() - lhs->getMin();
size_t range2 = rhs->getMax() - rhs->getMin();
if (range1 != range2) return range1 < range2;
return lhs->getName() < rhs->getName();
}
private:
unsigned int _flags;
};
class ComparePortMap {
public:
ComparePortMap () : _comparePort(Entity::AsPortSignal) { };
public:
inline bool operator() ( const PortMap* lhs, const PortMap* rhs ) const
{ return _comparePort( lhs->getSignal(), rhs->getSignal() ); }
private:
ComparePort _comparePort;
};
}
namespace Vhdl {
using namespace std;
using Hurricane::Warning;
using Hurricane::Property;
using Hurricane::_TName;
using Hurricane::ForEachIterator;
Tabulation tab (" ");
// -------------------------------------------------------------------
// Class : "::Entity".
vector<Entity*> Entity::_entities;
ptrdiff_t Entity::_offset = 0;
Entity::Entity ( EntityProperty* property, Cell* cell, unsigned int flags )
: _signals()
, _globals()
, _flags (flags)
{
if (not _offset) {
//_offset = offsetof(EntityProperty,_entity);
_offset = (ptrdiff_t)this - (ptrdiff_t)property;
}
if (_flags == NoFlags) _flags = EntityMode;
forEach ( Net*, inet, cell->getNets() ) {
if (not inet->isExternal() and (flags & ComponentMode)) continue;
string stem;
size_t index = 0;
if (parseNetName(*inet,stem,index)) {
if (inet->isGlobal()) {
cerr << Warning( "Vhdl::Entity::Entity(): Net is both vectorized and global, this is not allowed.\n"
" On Net <%s> of Cell <%s>."
, getString(inet->getName()).c_str()
, getString(cell->getName()).c_str()
) << endl;
}
VectorSignal* signal = const_cast<VectorSignal*>( dynamic_cast<const VectorSignal*>( getSignal(stem) ) );
if (not signal)
signal = new VectorSignal ( stem );
signal->addNet( index, *inet );
_signals.insert( signal );
} else {
_signals.insert( new ScalarSignal(*inet) );
if (inet->isGlobal())
_globals.insert( new ScalarSignal(*inet) );
}
}
_entities.push_back( this );
}
Entity::~Entity ()
{
for ( auto signal : _signals ) delete signal;
for ( auto ientity=_entities.begin() ; ientity!=_entities.end() ; ++ientity ) {
if (*ientity == this) {
_entities.erase( ientity );
break;
}
}
}
vector<Entity*>& Entity::getAllEntities ()
{ return _entities; }
bool Entity::parseNetName ( const Net* net, string& stem, size_t& index )
{
string error;
string name = getString(net->getName());
size_t leftpar = name.find( '(' );
size_t rightpar = name.find( ')' );
if (leftpar == string::npos) {
stem = name;
index = 0;
if (rightpar != string::npos) error = "unmatched right parenthesis";
} else {
if (rightpar == string::npos)
error = "unmatched left parenthesis";
else if (name.find('(',leftpar+1) != string::npos)
error = "multiple left parenthesis";
else if (name.find(')',rightpar+1) != string::npos)
error = "multiple right parenthesis";
else if (leftpar >= rightpar)
error = "left parenthesis *after* the right one";
else {
size_t endindex = 0;
int value = stoi( name.substr(leftpar+1), &endindex );
if (endindex != rightpar-leftpar-1)
error = "unable to convert index (not a number)";
else if (value < 0)
error = "negative index";
else {
stem = name.substr( 0, leftpar );
index = (size_t)value;
return true;
}
}
}
if (not error.empty()) {
cerr << Warning( "Entity::parseVector() Net has not a valid VHDL name, %s.\n"
" %s\n"
, error.c_str()
, getString(net->getName()).c_str()
) << endl;
}
return false;
}
void Entity::toEntityMode ()
{
if (isEntityMode()) return;
forEach ( Net*, inet, getCell()->getNets() ) {
if (inet->isExternal()) continue;
string stem;
size_t index = 0;
if (parseNetName(*inet,stem,index)) {
VectorSignal* signal = const_cast<VectorSignal*>( dynamic_cast<const VectorSignal*>( getSignal(stem) ) );
if (not signal)
signal = new VectorSignal ( stem );
signal->addNet( index, *inet );
_signals.insert( signal );
} else {
_signals.insert( new ScalarSignal(*inet) );
}
}
}
const Cell* Entity::getCell () const
{
EntityProperty* property = (EntityProperty*)((ptrdiff_t)(this) - _offset);
return (const Cell*)property->getOwner();
}
const SignalSet* Entity::getSignals () const
{ return &_signals; }
const Signal* Entity::getSignal ( string name ) const
{
VectorSignal key ( name );
auto isignal = _signals.find( &key );
if (isignal != _signals.end()) return *isignal;
return NULL;
}
const Signal* Entity::getGlobal ( string name ) const
{
VectorSignal key ( name );
auto isignal = _globals.find( &key );
if (isignal != _globals.end()) return *isignal;
return NULL;
}
void Entity::toSignals ( ostream& out ) const
{
size_t width = 0;
vector<Signal*> internalSignals;
for ( auto isignal=_signals.begin() ; isignal!=_signals.end() ; ++isignal ) {
if (not (*isignal)->isExternal()) {
width = max( width, (*isignal)->getName().size() );
internalSignals.push_back( *isignal );
}
}
sort( internalSignals.begin(), internalSignals.end(), ComparePort(Entity::AsInnerSignal) );
for ( auto isignal=internalSignals.begin(); isignal!=internalSignals.end() ; ++isignal ) {
out << tab;
(*isignal)->toVhdlPort( out, width, Entity::AsInnerSignal );
out << ";\n";
}
out << "\n";
}
void Entity::toPort ( ostream& out ) const
{
out << tab << "port ( ";
size_t width = 0;
vector<Signal*> ioSignals;
for ( auto isignal=_signals.begin() ; isignal!=_signals.end() ; ++isignal ) {
if ((*isignal)->isExternal()) {
width = max( width, (*isignal)->getName().size() );
ioSignals.push_back( *isignal );
}
}
sort( ioSignals.begin(), ioSignals.end(), ComparePort(Entity::AsPortSignal) );
size_t ioCount = 0;
for ( auto isignal=ioSignals.begin(); isignal!=ioSignals.end() ; ++isignal ) {
if (ioCount) out << "\n" << tab << " ; ";
(*isignal)->toVhdlPort( out, width, Entity::AsPortSignal );
++ioCount;
}
out << "\n" << tab << " );";
}
void Entity::toEntity ( ostream& out ) const
{
time_t clock = time( nullptr );
tm tm = *localtime( &clock );
char stamp[1024];
strftime( stamp, 1024, "%b %d, %Y, %H:%M", &tm );
out << "\n";
out << "-- =======================================================================\n";
out << "-- Coriolis Structural VHDL Driver\n";
out << "-- Generated on " << stamp << "\n";
out << "-- \n";
out << "-- To be interoperable with Alliance, it uses it's special VHDL subset.\n";
out << "-- (\"man vhdl\" under Alliance for more informations)\n";
out << "-- =======================================================================\n";
out << "\n";
out << tab++ << "entity " << getCell()->getName() << " is\n";
toPort( out );
out << --tab << "\nend " << getCell()->getName() << ";\n\n";
out << "architecture structural of " << getCell()->getName() << " is\n\n";
++tab;
set<Cell*> masterCells;
forEach ( Instance*, iinstance, getCell()->getInstances() ) {
masterCells.insert( iinstance->getMasterCell() );
}
for ( auto icell : masterCells ) {
Vhdl::Entity* component = Vhdl::EntityExtension::create( icell, Vhdl::Entity::ComponentMode );
component->toComponent( out );
out << "\n";
}
toSignals( out );
out << "\n" << --tab << "begin\n\n";
++tab;
forEach ( Instance*, iinstance, getCell()->getInstances() ) {
toInstance( out, *iinstance );
out << "\n";
}
--tab;
out << "end structural;\n";
}
void Entity::toComponent ( ostream& out ) const
{
out << tab++ << "component " << getCell()->getName() << "\n";
toPort( out );
out << "\n" << --tab << "end component;\n";
}
void Entity::toInstance ( ostream& out, Instance* instance ) const
{
out << tab << instance->getName() << " : " << instance->getMasterCell()->getName() << "\n";
out << tab << "port map ( ";
Entity* masterEntity = EntityExtension::get( instance->getMasterCell() );
if (not masterEntity) {
masterEntity = EntityExtension::create( instance->getMasterCell(), ComponentMode );
}
size_t width = 0;
vector<PortMap*> portMaps;
const SignalSet* masterSignals = masterEntity->getSignals();
for ( auto isignal=masterSignals->begin() ; isignal!=masterSignals->end() ; ++isignal ) {
if ((*isignal)->isExternal()) {
width = max( width, (*isignal)->getName().size() );
portMaps.push_back( PortMap::create(*isignal) );
portMaps.back()->doMapping( instance );
}
}
sort( portMaps.begin(), portMaps.end(), ComparePortMap() );
size_t ioCount = 0;
for ( auto iportmap=portMaps.begin(); iportmap!=portMaps.end() ; ++iportmap ) {
if (ioCount) out << "\n" << tab << " , ";
(*iportmap)->toVhdlPortMap( out, width );
++ioCount;
delete *iportmap;
}
out << "\n" << tab << " );\n";
}
string Entity::_getString () const
{
string s = getString(getCell()->getName());
return s;
}
Record* Entity::_getRecord () const
{
Record* record = new Record ( "<Entity " + _getString() + " >" );
if (record != NULL) {
record->add( getSlot("_signals", _signals) );
record->add( getSlot("_flags" , _flags ) );
}
return record;
}
// -------------------------------------------------------------------
// Class : "EntityProperty"
Name EntityProperty::_name = "Vhdl::Entity";
EntityProperty* EntityProperty::create ( Cell* owner, unsigned int flags )
{
EntityProperty *property = new EntityProperty( owner, flags );
property->_postCreate ();
return property;
}
void EntityProperty::onReleasedBy ( DBo* owner )
{ PrivateProperty::onReleasedBy( owner ); }
Name EntityProperty::getPropertyName ()
{ return _name; }
Name EntityProperty::getName () const
{ return getPropertyName(); }
string EntityProperty::_getTypeName () const
{ return _TName( "EntityProperty" ); }
string EntityProperty::_getString () const
{
string s = PrivateProperty::_getString ();
s.insert ( s.length() - 1 , " " + getString(&_entity) );
return s;
}
Record* EntityProperty::_getRecord () const
{
Record* record = PrivateProperty::_getRecord();
if ( record ) {
record->add( getSlot( "_name" , _name ) );
record->add( getSlot( "_entity", &_entity ) );
}
return record;
}
// -------------------------------------------------------------------
// Class : "EntityExtension"
const Cell* EntityExtension::_owner = NULL;
Entity* EntityExtension::_cache = NULL;
Entity* EntityExtension::get ( const Cell* cell )
{
if (cell != _owner) {
_owner = cell;
Property* property = _owner->getProperty( EntityProperty::getPropertyName() );
if (property) _cache = static_cast<EntityProperty*>(property)->getEntity();
else _cache = NULL;
}
return _cache;
}
Entity* EntityExtension::create ( Cell* cell, unsigned int flags )
{
get( cell );
if (not _cache) {
EntityProperty* property = new EntityProperty( cell, flags );
cell->put( property );
_cache = property->getEntity();
} else {
if ( (flags & Entity::EntityMode) and (not _cache->isEntityMode()) )
_cache->toEntityMode();
}
return _cache;
}
void EntityExtension::destroy ( Cell* cell )
{
Property* property = cell->getProperty( EntityProperty::getPropertyName() );
if (property) static_cast<EntityProperty*>(property)->destroy();
_owner = NULL;
_cache = NULL;
}
void EntityExtension::destroyAll ()
{
vector<Entity*>& entities = Entity::getAllEntities();
while ( not entities.empty() ) destroy( const_cast<Cell*>(entities.back()->getCell()) );
}
} // Vhdl namespace.

View File

@ -0,0 +1,250 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./alliance/vst/VhdlPortMap.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "hurricane/Plug.h"
#include "hurricane/Instance.h"
#include "crlcore/VhdlPortMap.h"
#include "crlcore/VhdlEntity.h"
namespace Vhdl {
using namespace std;
using Hurricane::Error;
using Hurricane::Plug;
// -------------------------------------------------------------------
// Class : "Vhdl::PortMap".
PortMap::PortMap ()
{ }
PortMap::~PortMap ()
{ }
const Bit* PortMap::_lookup ( const Bit* masterBit, Instance* instance )
{
const Net* masterNet = masterBit->getNet();
Plug* plug = instance->getPlug( masterNet );
if (masterNet->isGlobal() and not plug->isConnected()) {
Entity* entity = EntityExtension::get( instance->getCell() );
const Signal* signal = entity->getGlobal( getString(masterNet->getName()) );
if (signal) return signal->getBit();
cerr << Error( "PortMap::_lookup() VHDL extension missing on parent of global <%s>."
, getString(masterNet).c_str()
) << endl;
} else {
Net* net = plug->getNet();
if (net) {
Bit* bit = BitExtension::get( net );
if (bit) return bit;
cerr << Error( "PortMap::_lookup() VHDL extension missing on <%s>."
, getString(net).c_str()
) << endl;
} else {
cerr << Error( "PortMap::_lookup() Unconnected <%s>."
, getString(plug).c_str()
) << endl;
}
}
return NULL;
}
PortMap* PortMap::create ( const Signal* signal )
{
const ScalarSignal* scalarSignal = dynamic_cast<const ScalarSignal*>( signal );
if (not scalarSignal) {
const VectorSignal* vectorSignal = dynamic_cast<const VectorSignal*>( signal );
if (vectorSignal)
return new VectorPortMap ( vectorSignal );
else
throw Error( "PortMap::create() Unable to cast toward <ScalarSignal> or <VectorSignal>." );
}
return new ScalarPortMap ( scalarSignal );
}
// -------------------------------------------------------------------
// Class : "Vhdl::ScalarPortMap".
ScalarPortMap::ScalarPortMap ( const ScalarSignal* signal )
: PortMap ()
, _signal (signal)
, _mapping(NULL)
{ }
ScalarPortMap::~ScalarPortMap ()
{ }
const ScalarSignal* ScalarPortMap::getSignal () const
{ return _signal; }
void ScalarPortMap::doMapping ( Instance* instance )
{ _mapping = _lookup( _signal->getBit(0), instance ); }
void ScalarPortMap::toVhdlPortMap ( ostream& out, size_t width ) const
{
out << setw(width) << left << _signal->getName() << " => ";
if (_mapping) out << _mapping->getName();
else out << "UNCONNECTED";
}
// -------------------------------------------------------------------
// Class : "Vhdl::VectorPortMap".
VectorPortMap::VectorPortMap ( const VectorSignal* signal )
: PortMap ()
, _signal (signal)
, _mapping()
{
for ( size_t index=_signal->getMin() ; index<=_signal->getMax() ; ++index ) {
const Bit* bit = _signal->getBit( index );
if (not bit) continue;
_mapping.insert( pair<size_t,const Bit*>(index,NULL) );
}
}
VectorPortMap::~VectorPortMap ()
{ }
const VectorSignal* VectorPortMap::getSignal () const
{ return _signal; }
void VectorPortMap::doMapping ( Instance* instance )
{
for ( size_t index=_signal->getMin() ; index<=_signal->getMax() ; ++index ) {
if (not _signal->getBit(index)) continue;
_mapping[ index ] = _lookup( _signal->getBit(index), instance );
}
}
void VectorPortMap::toVhdlPortMap ( ostream& out, size_t width ) const
{
if (getSignal()->isContiguous()) {
vector<string> mappedNames;
int begin = -1;
int end = -1;
const Bit* bit = NULL;
const Bit* bitp = NULL;
string name = "UNCONNECTED";
string namep = "UNCONNECTED";
auto imapping = _mapping.rbegin();
auto imappingp = _mapping.rbegin();
for ( ++imapping ; imapping!=_mapping.rend() ; ++imapping, ++imappingp ) {
bit = imapping ->second;
bitp = imappingp->second;
name = (bit ) ? bit ->getSignal()->getName() : "UNCONNECTED";
namep = (bitp) ? bitp->getSignal()->getName() : "UNCONNECTED";
if ( bit
and bitp
and bitp->getSignal()->isVector()
and bitp->getSignal()->isContiguous()
and (name == namep)) {
if (begin < 0) begin = bitp->getIndex();
if (end < 0) end = bit ->getIndex();
int delta = (int)bit->getIndex() - (int)bitp->getIndex();
if ( not ((delta > 0) xor (begin < end)) ) {
end = bit->getIndex();
continue;
}
}
if (begin != end) {
string vdir = (begin < end) ? "to" : "downto";
mappedNames.push_back( namep + "(" + getString(begin) + " " + vdir + " " + getString(end) + ")" );
} else {
if ( (bitp == NULL) or (not bitp->getSignal()->isVector()) ) {
mappedNames.push_back( namep );
} else {
mappedNames.push_back( bitp->getName() );
}
}
begin = -1;
end = -1;
}
bitp = imappingp->second;
namep = (bitp) ? bitp->getSignal()->getName() : "UNCONNECTED";
if (begin != end) {
string vdir = (begin < end) ? "to" : "downto";
mappedNames.push_back( namep + "(" + getString(begin) + " " + vdir + " " + getString(end) + ")" );
} else {
if ( (bitp == NULL) or (not bitp->getSignal()->isVector()) ) {
mappedNames.push_back( namep );
} else {
mappedNames.push_back( bitp->getName() );
}
}
out << setw(width) << left << _signal->getName() << " => ";
size_t lhsWidth = 90 - tab.getWidth() - width - 4;
size_t lhsLength = 0;
bool first = true;
for ( auto name : mappedNames ) {
if (not first) { out << " & "; lhsLength += 3; }
if (lhsLength + name.size() > lhsWidth) {
out << "\n" << tab << setw(width+15) << " ";
lhsLength = 0;
}
lhsLength += name.size();
out << name;
first = false;
}
} else {
auto imapping = _mapping.rbegin();
bool first = true;
for ( ; imapping!=_mapping.rend() ; ++imapping ) {
if (not first) out << "\n" << tab << " , ";
out << setw(width) << left << _signal->getBit(imapping->first)->getName()
<< " => " << imapping->second->getName();
first = false;
}
}
}
} // Vhdl namespace.

View File

@ -0,0 +1,285 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./alliance/vst/VhdlSignal.cpp" |
// +-----------------------------------------------------------------+
#include <iomanip>
#include "hurricane/Warning.h"
#include "crlcore/VhdlSignal.h"
#include "crlcore/VhdlEntity.h"
namespace Vhdl {
using namespace std;
using Hurricane::Warning;
// -------------------------------------------------------------------
// Class : "Vhdl::Signal".
Signal::Signal ( string name )
: _name(name)
{ }
Signal::~Signal ()
{ }
void Signal::_toVhdlPort ( ostream& out
, int width
, unsigned int flags
, string name
, string range
, Net::Direction direction )
{
//out << tab;
if (flags & Entity::AsInnerSignal) out << "signal ";
out << setw(width) << left << name << " : ";
if (flags & Entity::AsPortSignal) {
switch ( (unsigned int)direction & (Net::Direction::DirIn|Net::Direction::DirOut) ) {
case Net::Direction::IN: out << "in"; break;
case Net::Direction::OUT: out << "out"; break;
case Net::Direction::INOUT: out << "inout"; break;
default: out << "linkage";
}
}
if (not range.empty()) {
switch ( (unsigned int)direction & (Net::Direction::ConnTristate
|Net::Direction::ConnWiredOr) ) {
case Net::Direction::ConnTristate: out << " mux_vector" << range << " bus"; break;
case Net::Direction::ConnWiredOr: out << " wor_vector" << range << " bus"; break;
default: out << " bit_vector" << range;
}
} else {
switch ( (unsigned int)direction & (Net::Direction::ConnTristate
|Net::Direction::ConnWiredOr) ) {
case Net::Direction::ConnTristate: out << " mux_bit bus"; break;
case Net::Direction::ConnWiredOr: out << " wor_bit bus"; break;
default: out << " bit";
}
}
}
Record* Signal::_getRecord () const
{
Record* record = new Record ( getString(this) );
record->add ( getSlot("_name", &_name) );
return record;
}
// -------------------------------------------------------------------
// Class : "Vhdl::ScalarSignal".
ScalarSignal::ScalarSignal ( Net* net )
: Signal(getString(net->getName()))
, _bit (BitExtension::create(net,this))
{ }
ScalarSignal::~ScalarSignal ()
{ }
bool ScalarSignal::isScalar () const { return true; }
bool ScalarSignal::isVector () const { return false; }
bool ScalarSignal::isExternal () const { return _bit->isExternal(); }
bool ScalarSignal::isContiguous () const { return false; }
const Bit* ScalarSignal::getBit () const { return _bit; }
const Bit* ScalarSignal::getBit ( size_t ) const { return _bit; }
const Net* ScalarSignal::getNet () const { return _bit->getNet(); }
const Net* ScalarSignal::getNet ( size_t ) const { return _bit->getNet(); }
size_t ScalarSignal::getMin () const { return Bit::nindex; }
size_t ScalarSignal::getMax () const { return Bit::nindex; }
Net::Direction ScalarSignal::getDirection () const { return getNet(0)->getDirection(); }
void ScalarSignal::toVhdlPort ( ostream& out, int width, unsigned int flags ) const
{ _toVhdlPort( out, width, flags, getName(), string(), getDirection() ); }
string ScalarSignal::_getString () const
{
string s = "<ScalarSignal " + getName() + ">";
return s;
}
Record* ScalarSignal::_getRecord () const
{
Record* record = Signal::_getRecord();
if (record) {
record->add ( getSlot("_bit", _bit) );
}
return record;
}
// -------------------------------------------------------------------
// Class : "Vhdl::VectorSignal".
VectorSignal::VectorSignal ( string name )
: Signal (name)
, _bits ()
, _direction(Net::Direction::UNDEFINED)
, _flags (Contiguous)
{ }
VectorSignal::~VectorSignal ()
{ for ( auto bit : _bits ) bit->getProperty()->destroy(); }
bool VectorSignal::isScalar () const { return false; }
bool VectorSignal::isVector () const { return true; }
bool VectorSignal::isExternal () const { return (*_bits. begin())->isExternal(); }
size_t VectorSignal::getMin () const { return (*_bits.rbegin())->getIndex(); }
size_t VectorSignal::getMax () const { return (*_bits. begin())->getIndex(); }
Net::Direction VectorSignal::getDirection () const { return _direction; }
const Bit* VectorSignal::getBit () const
{ return *_bits.rend(); }
const Bit* VectorSignal::getBit ( size_t index ) const
{
Bit key ( index );
auto inet = _bits.find( &key );
if (inet != _bits.end()) return (*inet);
return NULL;
}
const Net* VectorSignal::getNet () const
{
const Bit* bit = getBit( getMin() );
return (bit) ? bit->getNet() : NULL;
}
const Net* VectorSignal::getNet ( size_t index ) const
{
const Bit* bit = getBit( index );
return (bit) ? bit->getNet() : NULL;
}
bool VectorSignal::isContiguous () const
{
auto inet1 = _bits.rbegin();
auto inet2 = inet1;
for ( ++inet1; inet1!=_bits.rend() ; ++inet1, ++inet2 ) {
if ((*inet1)->getIndex() != (*inet2)->getIndex()+1) return false;
}
return true;
}
void VectorSignal::toVhdlPort ( ostream& out, int width, unsigned int flags ) const
{
if (isContiguous()) {
string range = "(" + getString(getMax()) + " downto " + getString(getMin()) + ")";
_toVhdlPort( out, width, flags, getName(), range, getDirection() );
} else {
bool first = true;
for ( auto bit : _bits ) {
string name = getName() + "_" + getString(bit->getIndex());
if (not first) {
if (flags & Entity::AsPortSignal) out << "\n" << tab << " ; ";
else out << ";\n" << tab;
}
first = false;
_toVhdlPort( out, width, flags, name, string(), getDirection() );
}
if (flags & Entity::AsPortSignal)
out << "\n" << tab << " -- Vector <" << getName() << "> is holed, unvectorized.";
else
out << ";\n" << tab << "-- Vector <" << getName() << "> is holed, unvectorized.";
}
}
bool VectorSignal::addNet ( size_t index, Net* net )
{
const Net* check = getNet( index );
if (check) {
if (check == net) return true;
cerr << Warning( "VectorSignal::addNet() Attempt to create twice index %u for nets:\n"
" %s (previous)\n"
" %s (new)"
, index
, getString(check->getName()).c_str()
, getString(net ->getName()).c_str()
) << endl;
return false;
}
if (_direction == Net::Direction::UNDEFINED)
_direction = net->getDirection();
else {
_direction |= net->getDirection();
}
_bits.insert( BitExtension::create(net,this,index) );
auto inet1 = _bits.rbegin();
auto inet2 = inet1;
_flags |= Contiguous;
for ( ++inet1; inet1!=_bits.rend() ; ++inet1, ++inet2 ) {
if ((*inet1)->getIndex() != (*inet2)->getIndex()+1) {
_flags &= ~Contiguous;
break;
}
}
return true;
}
string VectorSignal::_getString () const
{
string s = "<VectorSignal " + getName()
+ "(" + getString(getMax()) + " downto " + getString(getMin()) + ") ";
s += (_flags & Contiguous) ? 'C' : '-';
s += ">";
return s;
}
Record* VectorSignal::_getRecord () const
{
Record* record = Signal::_getRecord();
if (record) {
record->add ( getSlot("_bits" , &_bits ) );
record->add ( getSlot("_direction", &_direction) );
record->add ( getSlot("_flags" , &_flags ) );
}
return record;
}
} // Vhdl namespace.

View File

@ -1,52 +1,39 @@
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
// -*- C++ -*-
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// 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
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2004-2015, All Rights Reserved
//
// License-Tag
//
// Date : 01/10/2004
// Author : Christophe Alexandre <Christophe.Alexandre@lip6.fr>
//
// Authors-Tag
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Yosys & Blif / Hurricane Interface |
// | |
// | Author : Christophe Alexandre |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./alliance/vst/VstDriver.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Cell.h"
#include "hurricane/Net.h"
#include "hurricane/Instance.h"
#include "hurricane/Plug.h"
#include <cstddef>
#include "hurricane/Warning.h"
#include "hurricane/Cell.h"
#include "hurricane/Net.h"
#include "hurricane/Instance.h"
#include "hurricane/Plug.h"
using namespace Hurricane;
#include "crlcore/Catalog.h"
#include "crlcore/NetExtension.h"
#include "Vst.h"
#include "crlcore/Catalog.h"
#include "crlcore/NetExtension.h"
#include "crlcore/ToolBox.h"
#include "crlcore/VhdlBit.h"
#include "crlcore/VhdlSignal.h"
#include "crlcore/VhdlEntity.h"
#include "Vst.h"
namespace {
using namespace std;
using namespace CRL;
@ -153,13 +140,16 @@ unsigned FindIndex(const string& stringtosearch, string::size_type openpar)
string getNetDirection(const Net* net)
{
switch ( net->getDirection() & Net::Direction::INOUT ) {
switch ( net->getDirection() & (Net::Direction::INOUT | Net::Direction::UNDEFINED) ) {
case Net::Direction::UNDEFINED: return "linkage";
case Net::Direction::IN: return "in";
case Net::Direction::OUT: return "out";
case Net::Direction::INOUT: return "inout";
default:
throw Error( "Unrecognized direction" );
throw Error( "Unrecognized direction for Net <%s> of Cell <%s> (code:%u)"
, getString(net->getCell()->getName()).c_str()
, getString(net->getName()).c_str()
, (unsigned int)net->getDirection() );
}
}
@ -606,15 +596,13 @@ void DumpConnectionList(ofstream &ccell, Instance*instance)
string connectedNetName;
if (plug1->isConnected())
{
cerr << plug1 << "plug is connected" << endl;
Net* net = plug1->getNet();
if (net->isExternal())
{
const Name& portName = NetExtension::getPort(net);
if (!portName.isEmpty())
connectedNetName = getString(portName);
else
connectedNetName = getString(net->getName());
}
const Name& portName = NetExtension::getPort(net);
if (!portName.isEmpty())
connectedNetName = getString(portName);
else
connectedNetName = getString(net->getName());
}
else
if (plug1->getMasterNet()->isGlobal()) {
@ -659,6 +647,16 @@ namespace CRL {
void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState )
{
NamingScheme::toVhdl( cell, NamingScheme::FromVerilog );
Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, Vhdl::Entity::EntityMode );
string celltest = cellPath;
//celltest.insert( celltest.size()-4, "_test" );
::std::ofstream ccelltest ( celltest.c_str() );
vhdlEntity->toEntity(ccelltest);
ccelltest << endl;
ccelltest.close();
#if 0
__globalNets.clear ();
::std::ofstream ccell ( cellPath.c_str() );
@ -714,6 +712,7 @@ void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState )
}
ccell << "end structural;" << endl;
ccell.close ();
#endif
}
}

View File

@ -404,6 +404,7 @@ namespace {
} else {
net->addAlias( name );
if (isExternal) net->setExternal( true );
direction &= ~Net::Direction::UNDEFINED;
direction |= net->getDirection();
net->setDirection( (Net::Direction::Code)direction );
}

View File

@ -0,0 +1,162 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/VhdlBit.h" |
// +-----------------------------------------------------------------+
#ifndef VHDL_BIT_H
#define VHDL_BIT_H
#include <cstddef>
#include <string>
#include "hurricane/Name.h"
#include "hurricane/Property.h"
#include "hurricane/Slot.h"
#include "hurricane/Net.h"
namespace Vhdl {
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::DBo;
using Hurricane::Net;
using Hurricane::PrivateProperty;
class Signal;
class ScalarSignal;
class VectorSignal;
class BitProperty;
// -------------------------------------------------------------------
// Class : "::Bit" (declaration).
class Bit {
public:
static const size_t nindex;
public:
Bit ( BitProperty*
, const Net*
, Signal*
, size_t index );
Bit ( size_t index );
~Bit ();
bool isExternal () const;
bool isElement () const;
inline BitProperty* getProperty () const;
inline const Net* getNet () const;
const Signal* getSignal () const;
std::string getName () const;
size_t getIndex () const;
std::string _getString () const;
Record* _getRecord () const;
private:
static ptrdiff_t _offset;
Signal* _signal;
size_t _index;
};
struct GreaterBitByIndex {
inline bool operator() ( const Bit* lhs, const Bit* rhs ) const
{ return lhs->getIndex() > rhs->getIndex(); }
};
// -------------------------------------------------------------------
// Class : "Vhdl::BitProperty".
class BitProperty : public Hurricane::PrivateProperty {
friend class BitExtension;
public:
static Name _name;
public:
static BitProperty* create ( Net* owner
, Signal* signal
, size_t index );
static Name getPropertyName ();
virtual Name getName () const;
inline Bit* getBit ();
virtual void onReleasedBy ( DBo* owner );
virtual std::string _getTypeName () const;
virtual std::string _getString () const;
virtual Record* _getRecord () const;
protected:
// Attributes.
Bit _bit;
protected:
// Constructor.
inline BitProperty ( Net* owner, Signal*, size_t );
};
inline BitProperty::BitProperty ( Net* owner
, Signal* signal
, size_t index
)
: PrivateProperty(), _bit(this,owner,signal,index)
{ }
inline Bit* BitProperty::getBit () { return &_bit; }
// -------------------------------------------------------------------
// Class : "Vhdl::BitExtension".
class BitExtension {
public:
static inline bool isElement ( const Net* );
static inline const Signal* getSignal ( const Net* );
static inline size_t getIndex ( const Net* );
static Bit* get ( const Net* );
static Bit* create ( Net*, Signal*, size_t index=Bit::nindex );
private:
static const Net* _owner;
static Bit* _cache;
};
inline bool BitExtension::isElement ( const Net* net )
{
Bit* bit = get( net );
return (bit == NULL) ? false : bit->isElement();
}
inline const Signal* BitExtension::getSignal ( const Net* net )
{
Bit* bit = get( net );
return (bit == NULL) ? NULL : bit->getSignal();
}
inline size_t BitExtension::getIndex ( const Net* net )
{
Bit* bit = get( net );
return (bit == NULL) ? false : bit->getIndex();
}
inline BitProperty* Bit::getProperty () const { return (BitProperty*)((ptrdiff_t)(this) - _offset); }
inline const Net* Bit::getNet () const { return (const Net*)getProperty()->getOwner(); }
} // Vhdl Namespace.
INSPECTOR_P_SUPPORT(Vhdl::Bit);
#endif // VHDL_BIT_H

View File

@ -0,0 +1,210 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/VhdlEntity.h" |
// +-----------------------------------------------------------------+
#ifndef VHDL_ENTITY_H
#define VHDL_ENTITY_H
#include <string>
#include "hurricane/Name.h"
#include "hurricane/Property.h"
#include "hurricane/Slot.h"
namespace Hurricane {
class Net;
class Instance;
}
#include "crlcore/VhdlSignal.h"
namespace Vhdl {
using Hurricane::Tabulation;
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::DBo;
using Hurricane::Net;
using Hurricane::Cell;
using Hurricane::Instance;
using Hurricane::PrivateProperty;
class Signal;
class ScalarSignal;
class VectorSignal;
class EntityProperty;
extern Tabulation tab;
// -------------------------------------------------------------------
// Class : "Vhdl::Entity".
typedef std::set<Signal*,GreaterSignalByName> SignalSet;
class Entity {
public:
enum Flag { NoFlags = 0x0000
, EntityMode = 0x0001
, ComponentMode = 0x0002
, AsPortSignal = 0x0004
, AsInnerSignal = 0x0008
};
public:
static bool parseNetName ( const Net*, std::string& stem, size_t& index );
static std::vector<Entity*>&
getAllEntities ();
public:
Entity ( EntityProperty*, Cell*, unsigned int flags );
~Entity ();
inline bool isEntityMode () const;
inline bool isComponentMode () const;
const Cell* getCell () const;
const Signal* getSignal ( std::string name ) const;
const Signal* getGlobal ( std::string name ) const;
const SignalSet* getSignals () const;
void toEntityMode ();
void toSignals ( std::ostream& ) const;
void toPort ( std::ostream& ) const;
void toComponent ( std::ostream& ) const;
void toInstance ( std::ostream&, Instance* ) const;
void toEntity ( std::ostream& ) const;
std::string _getString () const;
Record* _getRecord () const;
private:
static std::vector<Entity*> _entities;
static std::ptrdiff_t _offset;
SignalSet _signals;
SignalSet _globals;
unsigned int _flags;
};
inline bool Entity::isEntityMode () const { return _flags & EntityMode; }
inline bool Entity::isComponentMode () const { return _flags & ComponentMode; }
// -------------------------------------------------------------------
// Class : "Vhdl::EntityProperty".
class EntityProperty : public Hurricane::PrivateProperty {
friend class EntityExtension;
public:
static Name _name;
public:
static EntityProperty* create ( Cell* owner, unsigned int flags );
static Name getPropertyName ();
virtual Name getName () const;
inline Entity* getEntity ();
virtual void onReleasedBy ( DBo* owner );
virtual std::string _getTypeName () const;
virtual std::string _getString () const;
virtual Record* _getRecord () const;
protected:
// Attributes.
Entity _entity;
protected:
// Constructor.
inline EntityProperty ( Cell* owner, unsigned int flags );
};
inline EntityProperty::EntityProperty ( Cell* owner, unsigned int flags )
: PrivateProperty(), _entity(this,owner,flags)
{ }
inline Entity* EntityProperty::getEntity () { return &_entity; }
// -------------------------------------------------------------------
// Class : "Vhdl::EntityExtension".
class EntityExtension {
public:
static void destroyAll ();
static inline const SignalSet* getSignals ( const Cell* );
static inline const Signal* getSignal ( const Cell*, std::string name );
static inline void toSignals ( const Cell*, std::ostream& );
static inline void toPort ( const Cell*, std::ostream& );
static inline void toComponent ( const Cell*, std::ostream& );
static inline void toInstance ( const Cell*, std::ostream&, Instance* );
static inline void toEntity ( const Cell*, std::ostream& );
static Entity* get ( const Cell* );
static Entity* create ( Cell*, unsigned int flags );
static void destroy ( Cell* );
private:
static const Cell* _owner;
static Entity* _cache;
};
inline const SignalSet* EntityExtension::getSignals ( const Cell* cell )
{
Entity* entity = get( cell );
return (entity == NULL) ? NULL : entity->getSignals();
}
inline const Signal* EntityExtension::getSignal ( const Cell* cell, std::string name )
{
Entity* entity = get( cell );
return (entity == NULL) ? NULL : entity->getSignal(name);
}
inline void EntityExtension::toSignals ( const Cell* cell, std::ostream& out )
{
Entity* entity = get( cell );
if (entity) entity->toSignals(out);
}
inline void EntityExtension::toPort ( const Cell* cell, std::ostream& out )
{
Entity* entity = get( cell );
if (entity) entity->toPort(out);
}
inline void EntityExtension::toComponent ( const Cell* cell, std::ostream& out )
{
Entity* entity = get( cell );
if (entity) entity->toComponent(out);
}
inline void EntityExtension::toInstance ( const Cell* cell, std::ostream& out, Instance* instance )
{
Entity* entity = get( cell );
if (entity) entity->toInstance(out,instance);
}
inline void EntityExtension::toEntity ( const Cell* cell, std::ostream& out )
{
Entity* entity = get( cell );
if (entity) entity->toEntity(out);
}
} // Vhdl Namespace.
INSPECTOR_P_SUPPORT(Vhdl::Entity);
#endif // VHDL_ENTITY_H

View File

@ -0,0 +1,84 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/VhdlPortMap.h" |
// +-----------------------------------------------------------------+
#ifndef VHDL_PORTMAP_H
#define VHDL_PORTMAP_H
#include <set>
#include <iostream>
#include "hurricane/Net.h"
#include "crlcore/VhdlBit.h"
#include "crlcore/VhdlSignal.h"
namespace Vhdl {
using Hurricane::Net;
using Hurricane::Instance;
// -------------------------------------------------------------------
// Class : "Vhdl::PortMap".
class PortMap {
public:
static PortMap* create ( const Signal* );
virtual const Signal* getSignal () const = 0;
virtual void doMapping ( Instance* ) = 0;
virtual void toVhdlPortMap ( std::ostream&, size_t ) const = 0;
PortMap ();
virtual ~PortMap ();
protected:
static const Bit* _lookup ( const Bit* masterBit, Instance* );
};
// -------------------------------------------------------------------
// Class : "Vhdl::ScalarPortMap".
class ScalarPortMap : public PortMap {
public:
ScalarPortMap ( const ScalarSignal* );
virtual ~ScalarPortMap ();
virtual const ScalarSignal* getSignal () const;
virtual void doMapping ( Instance* );
virtual void toVhdlPortMap ( std::ostream&, size_t ) const;
private:
const ScalarSignal* _signal;
const Bit* _mapping;
};
// -------------------------------------------------------------------
// Class : "Vhdl::VectorPortMap".
class VectorPortMap : public PortMap {
public:
VectorPortMap ( const VectorSignal* );
virtual ~VectorPortMap ();
virtual const VectorSignal* getSignal () const;
virtual void doMapping ( Instance* );
virtual void toVhdlPortMap ( std::ostream&, size_t ) const;
private:
const VectorSignal* _signal;
std::map<size_t,const Bit*> _mapping;
};
} // Vhdl namespace.
#endif // VHDL_PORTMAP_H

View File

@ -0,0 +1,139 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2015-2015, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance VHDL / Hurricane Interface |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/VhdlSignal.h" |
// +-----------------------------------------------------------------+
#ifndef VHDL_SIGNAL_H
#define VHDL_SIGNAL_H
#include <set>
#include "hurricane/Net.h"
#include "crlcore/VhdlBit.h"
namespace Vhdl {
using Hurricane::Net;
// -------------------------------------------------------------------
// Class : "Vhdl::Signal".
class Signal {
public:
enum Flag { Contiguous = 0x0001 };
public:
Signal ( std::string name );
virtual ~Signal ();
virtual bool isScalar () const = 0;
virtual bool isVector () const = 0;
virtual bool isExternal () const = 0;
virtual bool isContiguous () const = 0;
inline std::string getName () const;
virtual const Bit* getBit () const = 0;
virtual const Bit* getBit ( size_t ) const = 0;
virtual const Net* getNet () const = 0;
virtual const Net* getNet ( size_t index ) const = 0;
virtual Net::Direction getDirection () const = 0;
virtual size_t getMin () const = 0;
virtual size_t getMax () const = 0;
virtual void toVhdlPort ( std::ostream&, int width, unsigned int flags ) const = 0;
virtual std::string _getString () const = 0;
virtual Record* _getRecord () const;
protected:
static void _toVhdlPort ( std::ostream&
, int width
, unsigned int flags
, std::string name
, std::string range
, Net::Direction );
protected:
std::string _name;
};
struct GreaterSignalByName {
inline bool operator() ( const Signal* lhs, const Signal* rhs ) const
{ return lhs->getName() < rhs->getName(); }
};
// -------------------------------------------------------------------
// Class : "Vhdl::ScalarSignal".
class ScalarSignal : public Signal {
public:
ScalarSignal ( Net* );
virtual ~ScalarSignal ();
virtual bool isScalar () const;
virtual bool isVector () const;
virtual bool isExternal () const;
virtual bool isContiguous () const;
virtual const Bit* getBit () const;
virtual const Bit* getBit ( size_t ) const;
virtual const Net* getNet () const;
virtual const Net* getNet ( size_t ) const;
virtual size_t getMin () const;
virtual size_t getMax () const;
virtual Net::Direction getDirection () const;
virtual void toVhdlPort ( std::ostream&, int width, unsigned int flags ) const;
virtual std::string _getString () const;
virtual Record* _getRecord () const;
protected:
Bit* _bit;
};
// -------------------------------------------------------------------
// Class : "Vhdl::VectorSignal".
class VectorSignal : public Signal {
public:
VectorSignal ( std::string );
virtual ~VectorSignal ();
virtual bool isScalar () const;
virtual bool isVector () const;
virtual bool isExternal () const;
virtual bool isContiguous () const;
virtual const Bit* getBit () const;
virtual const Bit* getBit ( size_t ) const;
virtual const Net* getNet () const;
virtual const Net* getNet ( size_t ) const;
virtual Net::Direction getDirection () const;
virtual size_t getMin () const;
virtual size_t getMax () const;
bool addNet ( size_t index, Net* );
virtual void toVhdlPort ( std::ostream&, int width, unsigned int flags ) const;
virtual std::string _getString () const;
virtual Record* _getRecord () const;
protected:
std::set<Bit*,GreaterBitByIndex> _bits;
Net::Direction _direction;
unsigned int _flags;
};
// -------------------------------------------------------------------
// Inline methods.
inline std::string Signal::getName () const { return _name; }
}
INSPECTOR_P_SUPPORT(Vhdl::Signal);
INSPECTOR_P_SUPPORT(Vhdl::ScalarSignal);
INSPECTOR_P_SUPPORT(Vhdl::VectorSignal);
#endif // VHDL_SIGNAL_H

View File

@ -32,11 +32,13 @@ namespace CRL {
{
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";
size_t parCount = 0;
size_t posLeftPar = 0;
@ -66,6 +68,7 @@ namespace CRL {
vhdlName += 'n';
if (translated == '\\') translated = '_';
if (translated == '.' ) translated = '_';
if (translated == '$' ) translated = '_';
if (translated == '?' ) translated = '_';
if (translated == ':' ) translated = '_';
@ -85,6 +88,9 @@ namespace CRL {
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_");
return Name(vhdlName);
}

View File

@ -31,6 +31,7 @@
#include "crlcore/PyAcmSigda.h"
#include "crlcore/PyIspd05.h"
#include "crlcore/PyBlif.h"
#include "crlcore/VhdlEntity.h"
namespace CRL {
@ -39,27 +40,47 @@ namespace CRL {
using std::endl;
using Hurricane::tab;
using Hurricane::in_trace;
using Hurricane::Error;
using Hurricane::Warning;
using Isobar::ProxyProperty;
using Isobar::ProxyError;
using Isobar::ConstructorError;
using Isobar::HurricaneError;
using Isobar::HurricaneWarning;
using Isobar::__cs;
using Vhdl::EntityExtension;
#if !defined(__PYTHON_MODULE__)
// x=================================================================x
// +=================================================================+
// | "PyCRL" Shared Library Code Part |
// x=================================================================x
// +=================================================================+
# else // End of PyHurricane Shared Library Code Part.
// x=================================================================x
// +=================================================================+
// | "PyCRL" Python Module Code Part |
// x=================================================================x
// +=================================================================+
extern "C" {
static PyObject* PyVhdl_destroyAllVHDL ( PyObject* module )
{
trace << "PyVhdl_destroyAllVHDL()" << endl;
HTRY
EntityExtension::destroyAll();
HCATCH
Py_RETURN_NONE;
}
// x-------------------------------------------------------------x
// | "PyCRL" Module Methods |
// x-------------------------------------------------------------x
@ -68,6 +89,8 @@ extern "C" {
static PyMethodDef PyCRL_Methods[] =
{ { "createPartRing" , (PyCFunction)PyToolBox_createPartRing, METH_VARARGS
, "Partial build of a ring" }
, { "destroyAllVHDL" , (PyCFunction)PyVhdl_destroyAllVHDL, METH_NOARGS
, "Clear all VHDL informations on all cells." }
, {NULL, NULL, 0, NULL} /* sentinel */
};

View File

@ -88,6 +88,7 @@ def ScriptMain ( **kw ):
return 0
rsave( cell )
CRL.destroyAllVHDL()
except ErrorMessage, e:
print e; errorCode = e.code

View File

@ -94,6 +94,7 @@ def ScriptMain ( **kw ):
return 0
rsave( cell )
CRL.destroyAllVHDL()
except ErrorMessage, e:
print e; errorCode = e.code

View File

@ -800,6 +800,13 @@ Net::Direction& Net::Direction::operator=(const Direction& direction)
return *this;
}
Net::Direction& Net::Direction::operator|=(const Direction& direction)
// ******************************************************************
{
_code = (Code)((unsigned int)_code | (unsigned int)direction._code);
return *this;
}
string Net::Direction::_getString() const
// **************************************
{

View File

@ -119,7 +119,7 @@ namespace Hurricane {
Record* NetAliasHook::_getRecord () const
{
Record* record = new Record ( getString(this) );
record->add ( getSlot("_next", &_next) );
record->add ( getSlot("_next", _next) );
return record;
}
@ -169,7 +169,7 @@ namespace Hurricane {
NetAliasName::NetAliasName ( Name name )
: NetAliasHook()
, _name (name)
, _name (name)
{ }

View File

@ -81,9 +81,9 @@ class Net : public Entity {
public: class Direction {
// ********************
public: enum Code { DirUndefined = 0x0000
, DirIn = 0x0001
public: enum Code { DirIn = 0x0001
, DirOut = 0x0002
, DirUndefined = 0x0000
, ConnTristate = 0x0100
, ConnWiredOr = 0x0200
, UNDEFINED = DirUndefined
@ -94,6 +94,7 @@ class Net : public Entity {
, TRANSCV = DirIn | DirOut | ConnTristate
, WOR_OUT = DirOut | ConnWiredOr
, WOR_INOUT = DirIn | DirOut | ConnWiredOr
, DirMask = DirIn | DirOut | DirUndefined
};
private: Code _code;
@ -101,7 +102,8 @@ class Net : public Entity {
public: Direction(const Code& code = UNDEFINED);
public: Direction(const Direction& direction);
public: Direction& operator=(const Direction& direction);
public: Direction& operator =(const Direction& direction);
public: Direction& operator|=(const Direction& direction);
public: operator const Code&() const {return _code;};

View File

@ -68,6 +68,7 @@ class Tabulation {
// Others
// ******
public: unsigned getWidth() const { return _s.size()*_n; };
public: string _getTypeName() const { return _TName("Tabulation"); };
public: string _getString() const;
public: Record* _getRecord() const { return NULL; };