New CRL::SubNetNames class to parse/generate VHDL vectorised subnames.

* New: CRL::SubNetNames (in ToolBox), takes a VHDL signal name, vectorized
   or not and allow to generated sub-net names from it, with respect to
   the original vector name.
     Examples:
       * machin     -> machin_hfns_0, machin_hfns_1, ...
       * bidule(3)  -> bidule_bit3_hfns_0, bidule_bit3_hfns_1, ...
     Makes use of the POSIX regex library to avoid Boost dependencies.
This commit is contained in:
Jean-Paul Chaput 2021-03-23 17:11:56 +01:00
parent 9230d52b64
commit ec96161f0f
2 changed files with 110 additions and 2 deletions

View File

@ -15,6 +15,7 @@
#pragma once
#include <regex.h>
#include <functional>
#include "hurricane/Cell.h"
#include "hurricane/Net.h"
@ -59,6 +60,9 @@ namespace CRL {
void restoreNetsDirection ( Cell* , Cell::Flags );
// -------------------------------------------------------------------
// Class : "CRL::NamingScheme".
class NamingScheme {
public:
enum Flag { NoFlags = 0x0000
@ -87,4 +91,29 @@ namespace CRL {
}
// -------------------------------------------------------------------
// Class : "CRL::SubNetNames".
class SubNetNames {
public:
SubNetNames ();
bool match ( std::string );
inline int32_t getIndex () const;
inline std::string getBase () const;
inline uint32_t nextSubNet ();
std::string getSubNetName () const;
private:
static bool _compiled;
static regex_t _pattern;
std::string _base;
int32_t _index;
uint32_t _count;
};
inline int32_t SubNetNames::getIndex () const { return _index; }
inline std::string SubNetNames::getBase () const { return _base; }
inline uint32_t SubNetNames::nextSubNet () { return ++_count; }
} // CRL namespace.

View File

@ -14,6 +14,12 @@
// +-----------------------------------------------------------------+
#include <sstream>
#include <iostream>
#include <stdexcept>
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Plug.h"
#include "hurricane/Pin.h"
#include "hurricane/Library.h"
@ -23,8 +29,6 @@
#include "hurricane/Instance.h"
#include "hurricane/Segment.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Warning.h"
using namespace Hurricane;
#include "crlcore/Utilities.h"
@ -124,6 +128,9 @@ namespace {
namespace CRL {
using std::string;
using std::ostringstream;
Component* getBestExternalComponent ( Net* net )
{
@ -724,4 +731,76 @@ void ConnectPlugHooks(Cell* cell)
}
// -------------------------------------------------------------------
// Class : "CRL::SubNetNames".
bool SubNetNames::_compiled = false;
regex_t SubNetNames::_pattern;
SubNetNames::SubNetNames ()
: _base ()
, _index(-1)
, _count(0)
{
const char* textPattern = "^([^(]+)\\(([[:digit:]]+)\\)$";
if (not _compiled) {
int code = regcomp( &_pattern, textPattern, REG_EXTENDED );
if (code) {
char cmessage[1024];
regerror( code, &_pattern, cmessage, sizeof(cmessage) );
throw Error( "SubNetNames::SubNetNames(): Pattern compilation error \"%s\"."
, textPattern );
}
_compiled = true;
}
}
bool SubNetNames::match ( string s )
{
_count = 0;
regmatch_t matches[3];
int code = regexec( &_pattern, s.c_str(), 3, matches, 0 );
if (not code) {
_base = s.substr( matches[1].rm_so, matches[1].rm_eo-matches[1].rm_so );
string sindex = s.substr( matches[2].rm_so, matches[2].rm_eo-matches[2].rm_so );
try {
_index = std::stoi( sindex );
}
catch ( std::invalid_argument e ) {
cerr << Error( "SubNetNames::match(): std::stoi() catched an exception on \"%s\"."
, sindex.c_str() ) << endl;
}
return true;
} else {
if (code == REG_NOMATCH) {
size_t pos = s.find( '(' );
if (pos != string::npos) {
cerr << Error( "SubNetNames::match(): Strange CHDL signal name \"%s\"."
, s.c_str() ) << endl;
}
} else {
char cmessage[1024];
regerror( code, &_pattern, cmessage, sizeof(cmessage) );
cerr << "[ERROR] Pattern matching error: " << cmessage << " for " << s << endl;
throw Error( "SubNetNames::match(): Pattern matching error %s on \"%s\"."
, cmessage, s.c_str() );
}
}
_base = s;
_index = -1;
return false;
}
string SubNetNames::getSubNetName () const
{
ostringstream name;
if (_index < 0) name << _base << "_hfns_" << _count;
else name << _base << "_bit" << _index << "_hfns_" << _count;
return name.str();
}
} // End of CRL namespace.