2000-08-12 18:34:37 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
|
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form 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.
|
|
|
|
|
*
|
|
|
|
|
* This program 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 this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
|
|
|
|
#if !defined(WINNT) && !defined(macintosh)
|
2000-08-26 02:54:03 +02:00
|
|
|
#ident "$Id: t-dll.cc,v 1.5 2000/08/26 00:54:03 steve Exp $"
|
2000-08-12 18:34:37 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
# include "target.h"
|
|
|
|
|
# include "ivl_target.h"
|
2000-08-20 06:13:56 +02:00
|
|
|
# include "compiler.h"
|
2000-08-12 18:34:37 +02:00
|
|
|
# include <dlfcn.h>
|
|
|
|
|
|
|
|
|
|
struct ivl_design_s {
|
|
|
|
|
const Design*des_;
|
|
|
|
|
};
|
|
|
|
|
|
2000-08-14 06:39:56 +02:00
|
|
|
struct ivl_net_const_s {
|
|
|
|
|
const NetConst*con_;
|
|
|
|
|
};
|
|
|
|
|
|
2000-08-20 06:13:56 +02:00
|
|
|
struct ivl_net_logic_s {
|
|
|
|
|
const NetLogic*dev_;
|
|
|
|
|
};
|
|
|
|
|
|
2000-08-14 06:39:56 +02:00
|
|
|
struct ivl_process_s {
|
|
|
|
|
const NetProcTop*top_;
|
|
|
|
|
};
|
|
|
|
|
|
2000-08-19 20:12:42 +02:00
|
|
|
struct ivl_scope_s {
|
|
|
|
|
const NetScope*scope_;
|
|
|
|
|
};
|
|
|
|
|
|
2000-08-12 18:34:37 +02:00
|
|
|
/*
|
|
|
|
|
* The DLL target type loads a named object file to handle the process
|
|
|
|
|
* of scanning the netlist. When it is time to start the design, I
|
|
|
|
|
* locate and link in the desired DLL, then start calling methods. The
|
|
|
|
|
* DLL will call me back to get information out of the netlist in
|
|
|
|
|
* particular.
|
|
|
|
|
*/
|
|
|
|
|
struct dll_target : public target_t {
|
|
|
|
|
|
|
|
|
|
bool start_design(const Design*);
|
|
|
|
|
void end_design(const Design*);
|
|
|
|
|
|
2000-08-14 06:39:56 +02:00
|
|
|
bool bufz(const NetBUFZ*);
|
2000-08-19 20:12:42 +02:00
|
|
|
void event(const NetEvent*);
|
|
|
|
|
void logic(const NetLogic*);
|
2000-08-14 06:39:56 +02:00
|
|
|
bool net_const(const NetConst*);
|
2000-08-19 20:12:42 +02:00
|
|
|
void net_probe(const NetEvProbe*);
|
2000-08-14 06:39:56 +02:00
|
|
|
|
|
|
|
|
bool process(const NetProcTop*);
|
2000-08-19 20:12:42 +02:00
|
|
|
void scope(const NetScope*);
|
2000-08-14 06:39:56 +02:00
|
|
|
|
2000-08-12 18:34:37 +02:00
|
|
|
void*dll_;
|
2000-08-14 06:39:56 +02:00
|
|
|
string dll_path_;
|
2000-08-12 18:34:37 +02:00
|
|
|
|
|
|
|
|
struct ivl_design_s ivl_des;
|
|
|
|
|
|
|
|
|
|
start_design_f start_design_;
|
|
|
|
|
end_design_f end_design_;
|
|
|
|
|
|
2000-08-19 20:12:42 +02:00
|
|
|
net_bufz_f net_bufz_;
|
|
|
|
|
net_const_f net_const_;
|
|
|
|
|
net_event_f net_event_;
|
|
|
|
|
net_logic_f net_logic_;
|
|
|
|
|
net_probe_f net_probe_;
|
2000-08-14 06:39:56 +02:00
|
|
|
|
2000-08-19 20:12:42 +02:00
|
|
|
process_f process_;
|
|
|
|
|
scope_f scope_;
|
2000-08-14 06:39:56 +02:00
|
|
|
|
2000-08-12 18:34:37 +02:00
|
|
|
} dll_target_obj;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool dll_target::start_design(const Design*des)
|
|
|
|
|
{
|
2000-08-14 06:39:56 +02:00
|
|
|
dll_path_ = des->get_flag("DLL");
|
|
|
|
|
dll_ = dlopen(dll_path_.c_str(), RTLD_NOW);
|
2000-08-12 18:34:37 +02:00
|
|
|
if (dll_ == 0) {
|
2000-08-14 06:39:56 +02:00
|
|
|
cerr << dll_path_ << ": " << dlerror() << endl;
|
2000-08-12 18:34:37 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ivl_des.des_ = des;
|
|
|
|
|
|
|
|
|
|
start_design_ = (start_design_f)dlsym(dll_, "target_start_design");
|
|
|
|
|
end_design_ = (end_design_f) dlsym(dll_, "target_end_design");
|
2000-08-19 20:12:42 +02:00
|
|
|
|
2000-08-20 06:13:56 +02:00
|
|
|
net_bufz_ = (net_bufz_f) dlsym(dll_, LU "target_net_bufz" TU);
|
|
|
|
|
net_const_ = (net_const_f) dlsym(dll_, LU "target_net_const" TU);
|
|
|
|
|
net_event_ = (net_event_f) dlsym(dll_, LU "target_net_event" TU);
|
|
|
|
|
net_logic_ = (net_logic_f) dlsym(dll_, LU "target_net_logic" TU);
|
|
|
|
|
net_probe_ = (net_probe_f) dlsym(dll_, LU "target_net_probe" TU);
|
|
|
|
|
process_ = (process_f) dlsym(dll_, LU "target_process" TU);
|
|
|
|
|
scope_ = (scope_f) dlsym(dll_, LU "target_scope" TU);
|
2000-08-14 06:39:56 +02:00
|
|
|
|
2000-08-12 18:34:37 +02:00
|
|
|
(start_design_)(&ivl_des);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dll_target::end_design(const Design*)
|
|
|
|
|
{
|
|
|
|
|
(end_design_)(&ivl_des);
|
|
|
|
|
dlclose(dll_);
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-14 06:39:56 +02:00
|
|
|
bool dll_target::bufz(const NetBUFZ*net)
|
|
|
|
|
{
|
|
|
|
|
if (net_bufz_) {
|
|
|
|
|
int rc = (net_bufz_)(net->name().c_str(), 0);
|
|
|
|
|
return rc == 0;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
cerr << dll_path_ << ": internal error: target DLL lacks "
|
|
|
|
|
<< "target_net_bufz function." << endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-19 20:12:42 +02:00
|
|
|
void dll_target::event(const NetEvent*net)
|
|
|
|
|
{
|
|
|
|
|
if (net_event_) {
|
|
|
|
|
(net_event_)(net->full_name().c_str(), 0);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
cerr << dll_path_ << ": internal error: target DLL lacks "
|
|
|
|
|
<< "target_net_event function." << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void dll_target::logic(const NetLogic*net)
|
|
|
|
|
{
|
2000-08-20 06:13:56 +02:00
|
|
|
struct ivl_net_logic_s obj;
|
|
|
|
|
obj.dev_ = net;
|
|
|
|
|
|
2000-08-19 20:12:42 +02:00
|
|
|
if (net_logic_) {
|
2000-08-20 06:13:56 +02:00
|
|
|
(net_logic_)(net->name().c_str(), &obj);
|
2000-08-19 20:12:42 +02:00
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
cerr << dll_path_ << ": internal error: target DLL lacks "
|
|
|
|
|
<< "target_net_logic function." << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-14 06:39:56 +02:00
|
|
|
bool dll_target::net_const(const NetConst*net)
|
|
|
|
|
{
|
|
|
|
|
struct ivl_net_const_s obj;
|
|
|
|
|
|
|
|
|
|
obj.con_ = net;
|
|
|
|
|
|
|
|
|
|
if (net_const_) {
|
|
|
|
|
int rc = (net_const_)(net->name().c_str(), &obj);
|
|
|
|
|
return rc == 0;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
cerr << dll_path_ << ": internal error: target DLL lacks "
|
|
|
|
|
<< "target_net_const function." << endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-19 20:12:42 +02:00
|
|
|
void dll_target::net_probe(const NetEvProbe*net)
|
|
|
|
|
{
|
|
|
|
|
if (net_probe_) {
|
|
|
|
|
int rc = (net_probe_)(net->name().c_str(), 0);
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
cerr << dll_path_ << ": internal error: target DLL lacks "
|
|
|
|
|
<< "target_net_probe function." << endl;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-14 06:39:56 +02:00
|
|
|
bool dll_target::process(const NetProcTop*net)
|
|
|
|
|
{
|
|
|
|
|
struct ivl_process_s obj;
|
|
|
|
|
|
|
|
|
|
obj.top_ = net;
|
|
|
|
|
|
|
|
|
|
if (process_) {
|
|
|
|
|
int rc = (process_)(&obj);
|
|
|
|
|
return rc == 0;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
cerr << dll_path_ << ": internal error: target DLL lacks "
|
|
|
|
|
<< "target_process function." << endl;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-19 20:12:42 +02:00
|
|
|
void dll_target::scope(const NetScope*net)
|
|
|
|
|
{
|
|
|
|
|
struct ivl_scope_s obj;
|
|
|
|
|
|
|
|
|
|
obj.scope_ = net;
|
|
|
|
|
|
|
|
|
|
if (scope_)
|
|
|
|
|
(scope_)(&obj);
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-12 18:34:37 +02:00
|
|
|
extern const struct target tgt_dll = { "dll", &dll_target_obj };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
|
|
|
|
|
|
|
|
|
|
extern "C" const char*ivl_get_flag(ivl_design_t des, const char*key)
|
|
|
|
|
{
|
|
|
|
|
return des->des_->get_flag(key).c_str();
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-26 02:54:03 +02:00
|
|
|
extern "C" const char*ivl_get_root_name(ivl_design_t des)
|
|
|
|
|
{
|
|
|
|
|
return des->des_->find_root_scope()->name().c_str();
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-20 06:13:56 +02:00
|
|
|
extern "C" ivl_logic_t ivl_get_logic_type(ivl_net_logic_t net)
|
|
|
|
|
{
|
|
|
|
|
switch (net->dev_->type()) {
|
|
|
|
|
case NetLogic::AND:
|
|
|
|
|
return IVL_AND;
|
|
|
|
|
case NetLogic::OR:
|
|
|
|
|
return IVL_OR;
|
|
|
|
|
}
|
|
|
|
|
assert(0);
|
|
|
|
|
return IVL_AND;
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-26 02:54:03 +02:00
|
|
|
extern "C" unsigned ivl_get_logic_pins(ivl_net_logic_t net)
|
|
|
|
|
{
|
|
|
|
|
return net->dev_->pin_count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" ivl_nexus_t ivl_get_logic_pin(ivl_net_logic_t net, unsigned pin)
|
|
|
|
|
{
|
|
|
|
|
return (ivl_nexus_t) (net->dev_->pin(pin).nexus());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C" const char* ivl_get_nexus_name(ivl_nexus_t net)
|
|
|
|
|
{
|
|
|
|
|
const Nexus*nex = (const Nexus*)net;
|
|
|
|
|
return nex->name();
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-12 18:34:37 +02:00
|
|
|
/*
|
|
|
|
|
* $Log: t-dll.cc,v $
|
2000-08-26 02:54:03 +02:00
|
|
|
* Revision 1.5 2000/08/26 00:54:03 steve
|
|
|
|
|
* Get at gate information for ivl_target interface.
|
|
|
|
|
*
|
2000-08-20 06:13:56 +02:00
|
|
|
* Revision 1.4 2000/08/20 04:13:57 steve
|
|
|
|
|
* Add ivl_target support for logic gates, and
|
|
|
|
|
* make the interface more accessible.
|
|
|
|
|
*
|
2000-08-19 20:12:42 +02:00
|
|
|
* Revision 1.3 2000/08/19 18:12:42 steve
|
|
|
|
|
* Add target calls for scope, events and logic.
|
|
|
|
|
*
|
2000-08-14 06:39:56 +02:00
|
|
|
* Revision 1.2 2000/08/14 04:39:57 steve
|
|
|
|
|
* add th t-dll functions for net_const, net_bufz and processes.
|
|
|
|
|
*
|
2000-08-12 18:34:37 +02:00
|
|
|
* Revision 1.1 2000/08/12 16:34:37 steve
|
|
|
|
|
* Start stub for loadable targets.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|