mirror of https://github.com/YosysHQ/yosys.git
Implemented TCL support (only via -c option at the moment)
This commit is contained in:
parent
b9870a364e
commit
73fba5164f
3
Makefile
3
Makefile
|
@ -37,6 +37,9 @@ CXX = gcc
|
|||
CXXFLAGS += -std=gnu++0x -march=native -O3 -DNDEBUG
|
||||
endif
|
||||
|
||||
CXXFLAGS += -I/usr/include/tcl8.5 -DYOSYS_ENABLE_TCL
|
||||
LDLIBS += -ltcl8.5
|
||||
|
||||
include frontends/*/Makefile.inc
|
||||
include passes/*/Makefile.inc
|
||||
include backends/*/Makefile.inc
|
||||
|
|
4
README
4
README
|
@ -246,8 +246,8 @@ TODOs / Open Bugs
|
|||
- Actually use range information on parameters
|
||||
- Add brief source code documentation to most passes and kernel code
|
||||
- Implement mux-to-tribuf pass and rebalance mixed mux/tribuf trees
|
||||
- Add commands 'delete' (remove objects) and 'attr' (get, set and remove attributes)
|
||||
- TCL and Python interfaces to frontends, passes, backends and RTLIL
|
||||
- Add 'edit' command for changing the design (delete, add, modify objects)
|
||||
- Improve TCL support and add 'list' command for inspecting the design from TCL
|
||||
- Additional internal cell types: $pla and $lut
|
||||
- Support for registering designs (as collection of modules) to CellTypes
|
||||
- Smarter resource sharing pass (add MUXes and get rid of duplicated cells)
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
#include <stdio.h>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/register.h"
|
||||
#include "kernel/log.h"
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command)
|
||||
{
|
||||
|
@ -233,10 +233,15 @@ int main(int argc, char **argv)
|
|||
std::vector<void*> loaded_modules;
|
||||
std::string output_filename = "";
|
||||
std::string scriptfile = "";
|
||||
bool scriptfile_tcl = false;
|
||||
bool got_output_filename = false;
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
yosys_tcl = Tcl_CreateInterp();
|
||||
#endif
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "Sm:f:b:o:p:l:qts:")) != -1)
|
||||
while ((opt = getopt(argc, argv, "Sm:f:b:o:p:l:qts:c:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
|
@ -284,10 +289,15 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case 's':
|
||||
scriptfile = optarg;
|
||||
scriptfile_tcl = false;
|
||||
break;
|
||||
case 'c':
|
||||
scriptfile = optarg;
|
||||
scriptfile_tcl = true;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: %s [-S] [-q] [-t] [-l logfile] [-o <outfile>] [-f <frontend>] [-s <scriptfile>]\n", argv[0]);
|
||||
fprintf(stderr, "Usage: %s [-S] [-q] [-t] [-l logfile] [-o <outfile>] [-f <frontend>] [{-s|-c} <scriptfile>]\n", argv[0]);
|
||||
fprintf(stderr, " %*s[-p <pass> [-p ..]] [-b <backend>] [-m <module_file>] [<infile> [..]]\n", int(strlen(argv[0])+1), "");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -q\n");
|
||||
|
@ -311,6 +321,9 @@ int main(int argc, char **argv)
|
|||
fprintf(stderr, " -s scriptfile\n");
|
||||
fprintf(stderr, " execute the commands in the script file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -c tcl_scriptfile\n");
|
||||
fprintf(stderr, " execute the commands in the tcl script file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -p command\n");
|
||||
fprintf(stderr, " execute the commands\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
@ -366,6 +379,10 @@ int main(int argc, char **argv)
|
|||
design->selection_stack.push_back(RTLIL::Selection());
|
||||
log_push();
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
yosys_tcl_design = design;
|
||||
#endif
|
||||
|
||||
if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) {
|
||||
if (!got_output_filename)
|
||||
backend_command = "";
|
||||
|
@ -375,8 +392,17 @@ int main(int argc, char **argv)
|
|||
while (optind < argc)
|
||||
run_frontend(argv[optind++], frontend_command, design, output_filename == "-" ? &backend_command : NULL);
|
||||
|
||||
if (!scriptfile.empty())
|
||||
run_frontend(scriptfile, "script", design, output_filename == "-" ? &backend_command : NULL);
|
||||
if (!scriptfile.empty()) {
|
||||
if (scriptfile_tcl) {
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
if (Tcl_EvalFile(yosys_tcl, scriptfile.c_str()) != TCL_OK)
|
||||
log_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_tcl));
|
||||
#else
|
||||
log_error("Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n");
|
||||
#endif
|
||||
} else
|
||||
run_frontend(scriptfile, "script", design, output_filename == "-" ? &backend_command : NULL);
|
||||
}
|
||||
|
||||
for (auto it = passes_commands.begin(); it != passes_commands.end(); it++)
|
||||
run_pass(*it, design);
|
||||
|
@ -386,6 +412,10 @@ int main(int argc, char **argv)
|
|||
|
||||
delete design;
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
yosys_tcl_design = NULL;
|
||||
#endif
|
||||
|
||||
log("\nREADY.\n");
|
||||
log_pop();
|
||||
|
||||
|
@ -400,6 +430,10 @@ int main(int argc, char **argv)
|
|||
for (auto mod : loaded_modules)
|
||||
dlclose(mod);
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
Tcl_DeleteInterp(yosys_tcl);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,11 @@
|
|||
using namespace REGISTER_INTERN;
|
||||
#define MAX_REG_COUNT 1000
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
Tcl_Interp *yosys_tcl = NULL;
|
||||
RTLIL::Design *yosys_tcl_design = NULL;
|
||||
#endif
|
||||
|
||||
namespace REGISTER_INTERN
|
||||
{
|
||||
int raw_register_count = 0;
|
||||
|
@ -51,6 +56,8 @@ void Pass::run_register()
|
|||
{
|
||||
assert(pass_register.count(pass_name) == 0);
|
||||
pass_register[pass_name] = this;
|
||||
|
||||
register_tcl();
|
||||
}
|
||||
|
||||
void Pass::init_register()
|
||||
|
@ -70,6 +77,25 @@ void Pass::done_register()
|
|||
raw_register_done = false;
|
||||
}
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
static int tcl_pass(ClientData that_vp, Tcl_Interp*, int argc, const char *argv[])
|
||||
{
|
||||
Pass *that = (Pass*)that_vp;
|
||||
std::vector<std::string> args;
|
||||
for (int i = 0; i < argc; i++)
|
||||
args.push_back(argv[i]);
|
||||
that->call(yosys_tcl_design, args);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Pass::register_tcl()
|
||||
{
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
Tcl_CreateCommand(yosys_tcl, pass_name.c_str(), tcl_pass, (ClientData)this, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
Pass::~Pass()
|
||||
{
|
||||
}
|
||||
|
@ -189,6 +215,8 @@ void Frontend::run_register()
|
|||
|
||||
assert(frontend_register.count(frontend_name) == 0);
|
||||
frontend_register[frontend_name] = this;
|
||||
|
||||
register_tcl();
|
||||
}
|
||||
|
||||
Frontend::~Frontend()
|
||||
|
@ -281,6 +309,8 @@ void Backend::run_register()
|
|||
|
||||
assert(backend_register.count(backend_name) == 0);
|
||||
backend_register[backend_name] = this;
|
||||
|
||||
register_tcl();
|
||||
}
|
||||
|
||||
Backend::~Backend()
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
#include <tcl.h>
|
||||
extern Tcl_Interp *yosys_tcl;
|
||||
extern RTLIL::Design *yosys_tcl_design;
|
||||
#endif
|
||||
|
||||
struct Pass
|
||||
{
|
||||
std::string pass_name, short_help;
|
||||
|
@ -44,6 +50,7 @@ struct Pass
|
|||
|
||||
static void init_register();
|
||||
static void done_register();
|
||||
void register_tcl();
|
||||
};
|
||||
|
||||
struct Frontend : Pass
|
||||
|
|
Loading…
Reference in New Issue