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