22 #ifdef YOSYS_ENABLE_PLUGINS
29 typedef void (*ffi_fptr) ();
31 static ffi_fptr resolve_fn (std::string symbol_name)
33 if (symbol_name.find(
':') != std::string::npos)
35 int pos = symbol_name.find(
':');
36 std::string plugin_name = symbol_name.substr(0, pos);
37 std::string real_symbol_name = symbol_name.substr(pos+1);
43 log_error(
"unable to resolve '%s': can't find plugin `%s'\n", symbol_name.c_str(), plugin_name.c_str());
45 void *symbol = dlsym(
loaded_plugins.at(plugin_name), real_symbol_name.c_str());
47 if (symbol ==
nullptr)
48 log_error(
"unable to resolve '%s': can't find symbol `%s' in plugin `%s'\n",
49 symbol_name.c_str(), real_symbol_name.c_str(), plugin_name.c_str());
51 return (ffi_fptr) symbol;
55 void *symbol = dlsym(it.second, symbol_name.c_str());
56 if (symbol !=
nullptr)
57 return (ffi_fptr) symbol;
60 void *symbol = dlsym(RTLD_DEFAULT, symbol_name.c_str());
61 if (symbol !=
nullptr)
62 return (ffi_fptr) symbol;
64 log_error(
"unable to resolve '%s'.\n", symbol_name.c_str());
67 AST::AstNode *
AST::dpi_call(
const std::string &rtype,
const std::string &fname,
const std::vector<std::string> &argtypes,
const std::vector<AstNode*> &
args)
70 union {
double f64;
float f32; int32_t i32; } value_store [args.size() + 1];
71 ffi_type *types [args.size() + 1];
72 void *values [args.size() + 1];
76 log(
"Calling DPI function `%s' and returning `%s':\n", fname.c_str(), rtype.c_str());
79 for (
int i = 0; i <
GetSize(args); i++) {
80 if (argtypes[i] ==
"real") {
81 log(
" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed));
82 value_store[i].f64 = args[i]->asReal(args[i]->is_signed);
83 values[i] = &value_store[i].f64;
84 types[i] = &ffi_type_double;
85 }
else if (argtypes[i] ==
"shortreal") {
86 log(
" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed));
87 value_store[i].f32 = args[i]->asReal(args[i]->is_signed);
88 values[i] = &value_store[i].f32;
89 types[i] = &ffi_type_double;
90 }
else if (argtypes[i] ==
"integer") {
91 log(
" arg %d (%s): %lld\n", i, argtypes[i].c_str(), (
long long)args[i]->asInt(args[i]->is_signed));
92 value_store[i].i32 = args[i]->asInt(args[i]->is_signed);
93 values[i] = &value_store[i].i32;
94 types[i] = &ffi_type_sint32;
96 log_error(
"invalid argtype '%s' for argument %d.\n", argtypes[i].c_str(), i);
100 if (rtype ==
"integer") {
101 types[args.size()] = &ffi_type_slong;
102 values[args.size()] = &value_store[args.size()].i32;
103 }
else if (rtype ==
"shortreal") {
104 types[args.size()] = &ffi_type_float;
105 values[args.size()] = &value_store[args.size()].f32;
106 }
else if (rtype ==
"real") {
107 types[args.size()] = &ffi_type_double;
108 values[args.size()] = &value_store[args.size()].f64;
110 log_error(
"invalid rtype '%s'.\n", rtype.c_str());
113 if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, args.size(), types[args.size()], types)) != FFI_OK)
114 log_error(
"ffi_prep_cif failed: status %d.\n", status);
116 ffi_call(&cif, resolve_fn(fname.c_str()), values[args.size()], values);
118 if (rtype ==
"real") {
120 newNode->
realvalue = value_store[args.size()].f64;
121 log(
" return realvalue: %g\n", newNode->
asReal(
true));
122 }
else if (rtype ==
"shortreal") {
124 newNode->
realvalue = value_store[args.size()].f32;
125 log(
" return realvalue: %g\n", newNode->
asReal(
true));
127 newNode = AstNode::mkconst_int(value_store[args.size()].i32,
false);
128 log(
" return integer: %lld\n", (
long long)newNode->
asInt(
true));
140 AST::AstNode *
AST::dpi_call(
const std::string&,
const std::string &fname,
const std::vector<std::string>&,
const std::vector<AstNode*>&)
142 log_error(
"Can't call DPI function `%s': this version of yosys is built without plugin support\n", fname.c_str());
AstNode * dpi_call(const std::string &rtype, const std::string &fname, const std::vector< std::string > &argtypes, const std::vector< AstNode * > &args)
#define YOSYS_NAMESPACE_END
void log_error(const char *format,...)
double asReal(bool is_signed)
int GetSize(RTLIL::Wire *wire)
#define log_assert(_assert_expr_)
std::map< std::string, std::string > loaded_plugin_aliases
#define YOSYS_NAMESPACE_BEGIN
void log(const char *format,...)
uint64_t asInt(bool is_signed)
std::map< std::string, void * > loaded_plugins