Added Verilog driver for netlist export (#80)
CRL.Verilog.save(cell, 0) -> exports cell into Verilog netlist file Co-authored-by: Serge Rabyking <serge.rabyking@chipflow.io>
This commit is contained in:
parent
f840563712
commit
44ce8dd162
|
@ -106,6 +106,8 @@
|
|||
spice/SpiceParser.cpp
|
||||
spice/SpiceDriver.cpp
|
||||
)
|
||||
set ( verilog_cpps verilog/VerilogDriver.cpp
|
||||
)
|
||||
set ( bookshelf_cpps bookshelf/BookshelfParser.cpp
|
||||
bookshelf/BookshelfDriver.cpp
|
||||
)
|
||||
|
@ -299,6 +301,7 @@
|
|||
${ispd05_cpps}
|
||||
${blif_cpps}
|
||||
${spice_cpps}
|
||||
${verilog_cpps}
|
||||
${lefdef_cpps}
|
||||
${openaccess_cpps}
|
||||
)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) SU/LIP6 2021-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | Verilog / Hurricane Interface |
|
||||
// | |
|
||||
// | Authors : Jean-Paul CHAPUT, Serge Rabyking |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./crlcore/Verilog.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace Hurricane {
|
||||
class Cell;
|
||||
class Library;
|
||||
}
|
||||
|
||||
namespace CRL {
|
||||
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Library;
|
||||
|
||||
class Verilog {
|
||||
public:
|
||||
static const uint64_t TopCell = (1 << 0);
|
||||
public:
|
||||
static bool save ( Cell*, uint64_t flags );
|
||||
};
|
||||
|
||||
} // CRL namespace.
|
|
@ -3,6 +3,7 @@ crlcore_includes = include_directories(
|
|||
'acmsigda',
|
||||
'iccad04',
|
||||
'spice',
|
||||
'verilog',
|
||||
'lefdef',
|
||||
'blif',
|
||||
'alliance/ap',
|
||||
|
@ -85,6 +86,7 @@ crlcore = shared_library(
|
|||
'spice/SpiceEntity.cpp',
|
||||
'spice/SpiceParser.cpp',
|
||||
'spice/SpiceDriver.cpp',
|
||||
'verilog/VerilogDriver.cpp',
|
||||
'alliance/ap/ApParser.cpp',
|
||||
'alliance/ap/ApDriver.cpp',
|
||||
'gds/GdsDriver.cpp',
|
||||
|
|
|
@ -0,0 +1,371 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) SU 2021-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | Verilog / Hurricane Interface |
|
||||
// | |
|
||||
// | Authors : Jean-Paul CHAPUT, Serge Rabyking |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./verilog/VerilogDriver.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cfenv>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
using namespace std;
|
||||
|
||||
#include "hurricane/configuration/Configuration.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Diagonal.h"
|
||||
#include "hurricane/Rectilinear.h"
|
||||
#include "hurricane/Polygon.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Instance.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "crlcore/NetExtension.h"
|
||||
#include "crlcore/ToolBox.h"
|
||||
#include "crlcore/Verilog.h"
|
||||
//#include "crlcore/VerilogBit.h"
|
||||
//#include "crlcore/VerilogEntity.h"
|
||||
|
||||
using namespace CRL;
|
||||
|
||||
namespace CRL {
|
||||
|
||||
static void _write_hdr(ofstream &out)
|
||||
{
|
||||
time_t clock = time( nullptr );
|
||||
tm tm = *localtime( &clock );
|
||||
char stamp[1024];
|
||||
strftime( stamp, 1024, "%b %d, %Y, %H:%M", &tm );
|
||||
|
||||
out << "/* Coriolis Verilog Driver */" << std::endl;
|
||||
out << "/* Generated on " << stamp << " */" << std::endl;
|
||||
}
|
||||
|
||||
static void _populate_non_terminal_cells(Cell* cell, std::set<Cell*> &cells)
|
||||
{
|
||||
if(!cells.insert(cell).second)
|
||||
{
|
||||
// insertion not happend because it was there already
|
||||
return;
|
||||
}
|
||||
for(Occurrence occurrence: cell->getNonTerminalNetlistInstanceOccurrences())
|
||||
{
|
||||
Cell* mod = static_cast<Instance*>( occurrence.getEntity() )->getMasterCell();
|
||||
// recursively find all related Non-terminal cells (part of the user's design hierarchy)
|
||||
_populate_non_terminal_cells(mod, cells);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<std::string, int> _wire2bus(std::string name)
|
||||
{
|
||||
std::pair<std::string, int> bus(name, -1);
|
||||
int i = name.size() - 1;
|
||||
while (std::isspace(name[i])) --i;// remove trailing spaces just in case
|
||||
if(name[i] == ')') // name ends with bracket so is in the form "some_wire_name(index)"
|
||||
{
|
||||
for(int j = i;;)
|
||||
{
|
||||
if(--j < 0)
|
||||
{
|
||||
// didn't find starting bracket
|
||||
// this should never happen
|
||||
std::cerr << "Wrongly formatted net name: " << name << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
if(name[j] == '(') // find starting bracket
|
||||
{
|
||||
bus.second = std::stoi(name.substr(j+1, i-j-1)); // get index
|
||||
while (std::isspace(name[j-1])) --j; // ignore spaces before starting bracket
|
||||
bus.first.erase(j); // trim name to not include index part with brackets
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bus;
|
||||
}
|
||||
|
||||
static void _write_cell(ofstream &out, Cell* cell)
|
||||
{
|
||||
out << std::endl;
|
||||
std::set<Net*> nets;
|
||||
std::vector<Net*> ports, wires;
|
||||
for(Instance* instance: cell->getInstances()) // go through all cells instances that form our cell
|
||||
{
|
||||
for(Plug* plug: instance->getPlugs()) // plugs are connect points of the cells
|
||||
{
|
||||
Net* net = plug->getMasterNet();
|
||||
if(net->isPower() || net->isGround()) // VDD and VSS are not part of Verilog netlist
|
||||
{
|
||||
continue;
|
||||
}
|
||||
net = plug->getNet();
|
||||
if(net->isExternal()) // propogates through ports
|
||||
{
|
||||
ports.push_back(net);
|
||||
nets.insert(net); // collect all nets we use
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!nets.insert(net).second) // the insertion not happend as it was already there
|
||||
{
|
||||
// this net was already enumerated in some other cell
|
||||
// so this wire used at least between two cells and need to be declared
|
||||
wires.push_back(net);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::map<Net*, std::pair<std::string, int> > net2bus;
|
||||
for(Net *net: nets)
|
||||
{
|
||||
net2bus.insert(std::make_pair(net, _wire2bus(getString(net->getName()))));
|
||||
}
|
||||
std::vector<std::string> names;
|
||||
// collect all port names without indexes in ordered way
|
||||
for(Net *net: ports)
|
||||
{
|
||||
std::string &name = net2bus[net].first;
|
||||
auto it = std::lower_bound(names.begin(), names.end(), name);
|
||||
if(it == names.end() || (*it) != name) // name not in the list yet
|
||||
{
|
||||
names.insert(it, name);
|
||||
}
|
||||
}
|
||||
// declare Verilog module with ports names
|
||||
out << "module " << getString(cell->getName()) << "(";
|
||||
for ( auto it = names.begin(); it != names.end(); ++it)
|
||||
{
|
||||
out << (*it);
|
||||
if (it + 1 != names.end())
|
||||
{
|
||||
out << ", ";
|
||||
}
|
||||
}
|
||||
out << ");\n";
|
||||
// now individually declare each port with direction and width
|
||||
for (auto &name: names)
|
||||
{
|
||||
int idx_min = -1, idx_max;
|
||||
Net::Direction dir;
|
||||
for (auto it: net2bus)
|
||||
{
|
||||
if (it.second.first == name) // find net with name
|
||||
{
|
||||
int idx = it.second.second;
|
||||
if (idx < 0)
|
||||
{
|
||||
if (idx_min >= 0)
|
||||
{
|
||||
std::cerr << "Net name \"" << name << "\" used with index " << idx_min
|
||||
<< " and without index" << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
dir = it.first->getDirection();
|
||||
break;
|
||||
}
|
||||
if (idx_min < 0)
|
||||
{
|
||||
idx_min = idx_max = idx;
|
||||
dir = it.first->getDirection();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (idx < idx_min)
|
||||
{
|
||||
idx_min = idx;
|
||||
}
|
||||
if (idx > idx_max)
|
||||
{
|
||||
idx_max = idx;
|
||||
}
|
||||
if (dir != it.first->getDirection())
|
||||
{
|
||||
int other = (idx == idx_min)?idx_max:idx_min;
|
||||
std::cerr << "Net \"" << name << "\" with index " << idx << " and " << other
|
||||
<< " has different directions" << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dir == Net::Direction::IN)
|
||||
{
|
||||
out << " input ";
|
||||
}
|
||||
else if (dir == Net::Direction::INOUT)
|
||||
{
|
||||
out << " inout ";
|
||||
}
|
||||
else if (dir == Net::Direction::OUT)
|
||||
{
|
||||
out << " output ";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Undetermined direction " << dir << " for the net \"" << name << "\"" << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
if (idx_min >= 0)
|
||||
{
|
||||
out << "[" << idx_max << ":" << idx_min << "] ";
|
||||
}
|
||||
out << name << ";" << std::endl;
|
||||
}
|
||||
// collect all wires (and not ports) names without indexes in ordered way
|
||||
names.clear();
|
||||
for(Net *net: wires)
|
||||
{
|
||||
std::string &name = net2bus[net].first;
|
||||
auto it = std::lower_bound(names.begin(), names.end(), name);
|
||||
if(it == names.end() || (*it) != name) // name not in the list yet
|
||||
{
|
||||
names.insert(it, name);
|
||||
}
|
||||
}
|
||||
// now individually declare each wire with width
|
||||
for (auto &name: names)
|
||||
{
|
||||
int idx_min = -1, idx_max = -1;
|
||||
for (auto it: net2bus)
|
||||
{
|
||||
if (it.second.first == name) // find all nets by name
|
||||
{
|
||||
int idx = it.second.second;
|
||||
if (idx < 0) // without index
|
||||
{
|
||||
if (idx_min >= 0)
|
||||
{
|
||||
std::cerr << "Net name \"" << name << "\" used with index " << idx_min
|
||||
<< " and without index" << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (idx_min < 0) // first time encountered
|
||||
{
|
||||
idx_min = idx_max = idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (idx < idx_min)
|
||||
{
|
||||
idx_min = idx;
|
||||
}
|
||||
if (idx > idx_max)
|
||||
{
|
||||
idx_max = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out << " wire ";
|
||||
if (idx_min >= 0)
|
||||
{
|
||||
out << "[" << idx_max << ":" << idx_min << "] ";
|
||||
}
|
||||
out << name << ";" << std::endl;
|
||||
}
|
||||
// free not needed resources
|
||||
names.clear();
|
||||
ports.clear();
|
||||
wires.clear();
|
||||
nets.clear();
|
||||
// declare instancies with connections
|
||||
for(Instance* instance: cell->getInstances()) // go through all cells instances that form our cell
|
||||
{
|
||||
std::vector<Plug*> conns;
|
||||
for(Plug* plug: instance->getPlugs()) // plugs are connect points of the cells
|
||||
{
|
||||
Net* net = plug->getMasterNet();
|
||||
if(net->isPower() || net->isGround()) // VDD and VSS are not part of Verilog netlist
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// insert in sorted order
|
||||
auto it = std::lower_bound(conns.begin(), conns.end(), plug,
|
||||
[](Plug* lhs, Plug* rhs) -> bool
|
||||
{ return getString(lhs->getMasterNet()->getName()) <
|
||||
getString(rhs->getMasterNet()->getName()); });
|
||||
conns.insert(it, plug);
|
||||
}
|
||||
if (conns.empty()) // instance has no connections apart from VSS&VDD
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// declare instance
|
||||
out << " " << getString(instance->getMasterCell()->getName()) << " "
|
||||
<< getString(instance->getName()) << " (" << std::endl;
|
||||
// declare connections
|
||||
for (auto it = conns.begin(); it != conns.end(); ++it)
|
||||
{
|
||||
auto &info = net2bus[(*it)->getNet()];
|
||||
out << " ." << getString((*it)->getMasterNet()->getName()) << "(" << info.first;
|
||||
if (info.second >= 0) // indexed wire
|
||||
{
|
||||
out << "[" << info.second << "]";
|
||||
}
|
||||
out << ")";
|
||||
if ( it+1 != conns.end()) // not last, so need comma
|
||||
{
|
||||
out << ",";
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
out << " );" << std::endl;
|
||||
}
|
||||
out << "endmodule" << std::endl;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CRL::Verilog".
|
||||
|
||||
bool Verilog::save ( Cell* cell, uint64_t flags )
|
||||
{
|
||||
ofstream out(getString(cell->getName()) + ".v");
|
||||
_write_hdr(out);
|
||||
if (flags & TopCell)
|
||||
{
|
||||
_write_cell(out, cell);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::set<Cell*> cells;
|
||||
_populate_non_terminal_cells(cell, cells);
|
||||
for (auto &it: cells)
|
||||
{
|
||||
_write_cell(out, it);
|
||||
}
|
||||
}
|
||||
out.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // CRL namespace.
|
|
@ -56,6 +56,7 @@
|
|||
PyAcmSigda.cpp
|
||||
#PyIspd05.cpp
|
||||
PySpice.cpp
|
||||
PyVerilog.cpp
|
||||
PyBlif.cpp
|
||||
PyGds.cpp
|
||||
PyLefImport.cpp
|
||||
|
@ -80,6 +81,7 @@
|
|||
crlcore/PyAcmSigda.h
|
||||
#crlcore/PyIspd05.h
|
||||
crlcore/PySpice.h
|
||||
crlcore/PyVerilog.h
|
||||
crlcore/PyBlif.h
|
||||
crlcore/PyGds.h
|
||||
crlcore/PyLefImport.h
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "crlcore/PyAcmSigda.h"
|
||||
// #include "crlcore/PyIspd05.h"
|
||||
#include "crlcore/PySpice.h"
|
||||
#include "crlcore/PyVerilog.h"
|
||||
#include "crlcore/PyBlif.h"
|
||||
#include "crlcore/PyGds.h"
|
||||
#include "crlcore/PyLefImport.h"
|
||||
|
@ -129,6 +130,7 @@ extern "C" {
|
|||
PyAcmSigda_LinkPyType ();
|
||||
// PyIspd05_LinkPyType ();
|
||||
PySpice_LinkPyType ();
|
||||
PyVerilog_LinkPyType ();
|
||||
PyBlif_LinkPyType ();
|
||||
PyGds_LinkPyType ();
|
||||
PyLefImport_LinkPyType ();
|
||||
|
@ -154,6 +156,7 @@ extern "C" {
|
|||
PYTYPE_READY_NEW ( AcmSigda );
|
||||
// PYTYPE_READY_NEW ( Ispd05 );
|
||||
PYTYPE_READY_NEW ( Spice );
|
||||
PYTYPE_READY_NEW ( Verilog );
|
||||
PYTYPE_READY_NEW ( Blif );
|
||||
PYTYPE_READY_NEW ( Gds );
|
||||
PYTYPE_READY_NEW ( LefImport );
|
||||
|
@ -205,6 +208,8 @@ extern "C" {
|
|||
// PyModule_AddObject ( module, "Ispd05", (PyObject*)&PyTypeIspd05 );
|
||||
Py_INCREF ( &PyTypeSpice );
|
||||
PyModule_AddObject ( module, "Spice", (PyObject*)&PyTypeSpice );
|
||||
Py_INCREF ( &PyTypeVerilog );
|
||||
PyModule_AddObject ( module, "Verilog", (PyObject*)&PyTypeVerilog );
|
||||
Py_INCREF ( &PyTypeBlif );
|
||||
PyModule_AddObject ( module, "Blif", (PyObject*)&PyTypeBlif );
|
||||
Py_INCREF ( &PyTypeGds );
|
||||
|
@ -224,6 +229,7 @@ extern "C" {
|
|||
PyRoutingLayerGauge_postModuleInit ();
|
||||
PyAllianceFramework_postModuleInit ();
|
||||
PySpice_postModuleInit ();
|
||||
PyVerilog_postModuleInit ();
|
||||
PyGds_postModuleInit ();
|
||||
PyDefExport_postModuleInit ();
|
||||
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) SU 2021-2021, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | Verilog / Hurricane Interface |
|
||||
// | |
|
||||
// | Authors : Jean-Paul CHAPUT, Serge Rabyking |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./PyVerilog.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "crlcore/PyVerilog.h"
|
||||
#include "hurricane/isobar/PyCell.h"
|
||||
#include "hurricane/isobar/PyLibrary.h"
|
||||
//#include "crlcore/VerilogEntity.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace CRL {
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::hex;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Exception;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Isobar::ProxyProperty;
|
||||
using Isobar::ProxyError;
|
||||
using Isobar::ConstructorError;
|
||||
using Isobar::HurricaneError;
|
||||
using Isobar::HurricaneWarning;
|
||||
using Isobar::getPyHash;
|
||||
using Isobar::ParseOneArg;
|
||||
using Isobar::ParseTwoArg;
|
||||
using Isobar::__cs;
|
||||
using Isobar::PyCell;
|
||||
using Isobar::PyTypeCell;
|
||||
using Isobar::PyCell_Link;
|
||||
using Isobar::PyLibrary;
|
||||
using Isobar::PyTypeLibrary;
|
||||
using Isobar::PyLibrary_Link;
|
||||
|
||||
extern "C" {
|
||||
|
||||
#if defined(__PYTHON_MODULE__)
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyVerilog" Python Module Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
|
||||
static PyObject* PyVerilog_save ( PyObject*, PyObject* args )
|
||||
{
|
||||
cdebug_log(30,0) << "PyVerilog_save()" << endl;
|
||||
|
||||
HTRY
|
||||
long flags = 0;
|
||||
PyObject* pyCell = NULL;
|
||||
if (PyArg_ParseTuple( args, "Ol:Verilog.save", &pyCell, &flags )) {
|
||||
if (IsPyCell(pyCell)) {
|
||||
Verilog::save( PYCELL_O(pyCell), flags );
|
||||
} else {
|
||||
PyErr_SetString( ConstructorError, "Verilog.save(): Bad parameter type (not a Cell)." );
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
std::cout << ConstructorError << std::endl;
|
||||
PyErr_SetString( ConstructorError, "Verilog.save(): Bad number of parameters." );
|
||||
return NULL;
|
||||
}
|
||||
HCATCH
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
// static PyObject* PyVerilog_load ( PyObject*, PyObject* args )
|
||||
// {
|
||||
// cdebug_log(30,0) << "PyVerilog_load()" << endl;
|
||||
|
||||
|
||||
// HTRY
|
||||
// unsigned long mode = 0;
|
||||
// char* path = NULL;
|
||||
// PyObject* pyLibrary = NULL;
|
||||
// if (PyArg_ParseTuple( args, "Osk:Verilog.load", &pyLibrary, &path, &mode )) {
|
||||
// if (IsPyLibrary(pyLibrary)) {
|
||||
// Verilog::load( PYLIBRARY_O(pyLibrary), string(path), (uint64_t)mode );
|
||||
// } else {
|
||||
// PyErr_SetString( ConstructorError, "Verilog.load(): Bad parameter type (not a Library)." );
|
||||
// return NULL;
|
||||
// }
|
||||
// } else {
|
||||
// PyErr_SetString( ConstructorError, "Verilog.load(): Bad number of parameters." );
|
||||
// return NULL;
|
||||
// }
|
||||
// HCATCH
|
||||
|
||||
// Py_RETURN_NONE;
|
||||
// }
|
||||
|
||||
|
||||
// static PyObject* PyVerilog_clearProperties ( PyObject* )
|
||||
// {
|
||||
// cdebug_log(30,0) << "PyVerilog_clearProperties()" << endl;
|
||||
// HTRY
|
||||
// Verilog::clearProperties();
|
||||
// HCATCH
|
||||
// Py_RETURN_NONE;
|
||||
// }
|
||||
|
||||
|
||||
// Standart Destroy (Attribute).
|
||||
|
||||
|
||||
PyMethodDef PyVerilog_Methods[] =
|
||||
{ { "save" , (PyCFunction)PyVerilog_save , METH_VARARGS|METH_STATIC
|
||||
, "Save a complete Verilog design." }
|
||||
// , { "load" , (PyCFunction)PyVerilog_load , METH_VARARGS|METH_STATIC
|
||||
// , "Load a Verilog layout inside a Cell (cumulative)." }
|
||||
// , { "clearProperties" , (PyCFunction)PyVerilog_clearProperties, METH_NOARGS|METH_STATIC
|
||||
// , "Remove all Verilog related properties from the Cells." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
NoObjectDeleteMethod(Verilog)
|
||||
PyTypeObjectLinkPyTypeWithoutObject(Verilog,Verilog)
|
||||
|
||||
|
||||
#else // End of Python Module Code Part.
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyVerilog" Shared Library Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
// Type Definition.
|
||||
PyTypeObjectDefinitionsOfModule(CRL,Verilog)
|
||||
|
||||
|
||||
extern void PyVerilog_postModuleInit ()
|
||||
{
|
||||
PyObject* constant;
|
||||
|
||||
LoadObjectConstant(PyTypeVerilog.tp_dict,::CRL::Verilog::TopCell ,"TopCell");
|
||||
}
|
||||
|
||||
|
||||
#endif // End of Shared Library Code Part.
|
||||
|
||||
} // extern "C".
|
||||
|
||||
} // CRL namespace.
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) SU 2021-2023, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | Verilog / Hurricane Interface |
|
||||
// | |
|
||||
// | Authors : Jean-Paul CHAPUT, Serge Rabyking |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./crlcore/PyVerilog.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
#include "crlcore/Verilog.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Python Object : "PyVerilog".
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
} PyVerilog;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Functions & Types exported to "PyCRL.ccp".
|
||||
|
||||
extern PyTypeObject PyTypeVerilog;
|
||||
extern PyMethodDef PyVerilog_Methods[];
|
||||
|
||||
extern void PyVerilog_LinkPyType ();
|
||||
extern void PyVerilog_postModuleInit ();
|
||||
|
||||
#define IsPyVerilog(v) ( (v)->ob_type == &PyTypeVerilog )
|
||||
#define PY_VERILOG(v) ( (PyVerilog*)(v) )
|
||||
|
||||
} // extern "C".
|
||||
|
||||
} // Hurricane namespace.
|
|
@ -18,6 +18,7 @@ pyCRL_files = files([
|
|||
'PyGraphicToolEngine.cpp',
|
||||
'PyAcmSigda.cpp',
|
||||
'PySpice.cpp',
|
||||
'PyVerilog.cpp',
|
||||
'PyBlif.cpp',
|
||||
'PyGds.cpp',
|
||||
'PyLefImport.cpp',
|
||||
|
|
Loading…
Reference in New Issue