Added emscripten (emcc) support to build system and some build fixes

This commit is contained in:
Clifford Wolf 2014-08-22 16:09:13 +02:00
parent ba83a7bdc6
commit 98442e019d
11 changed files with 101 additions and 14 deletions

View File

@ -2,11 +2,14 @@
CONFIG := clang CONFIG := clang
# CONFIG := gcc # CONFIG := gcc
# CONFIG := gcc-4.6 # CONFIG := gcc-4.6
# CONFIG := emcc
# features (the more the better) # features (the more the better)
ENABLE_TCL := 1 ENABLE_TCL := 1
ENABLE_QT4 := 1 ENABLE_QT4 := 1
ENABLE_ABC := 1 ENABLE_ABC := 1
ENABLE_PLUGINS := 1
ENABLE_READLINE := 1
ENABLE_VERIFIC := 0 ENABLE_VERIFIC := 0
# other configuration flags # other configuration flags
@ -27,7 +30,7 @@ all: top-all
CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -DYOSYS_SRC='"$(shell pwd)"' -D_YOSYS_ -fPIC -I${DESTDIR}/include CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -DYOSYS_SRC='"$(shell pwd)"' -D_YOSYS_ -fPIC -I${DESTDIR}/include
LDFLAGS = -L${DESTDIR}/lib LDFLAGS = -L${DESTDIR}/lib
LDLIBS = -lstdc++ -lreadline -lm -lffi -ldl LDLIBS = -lstdc++ -lm
QMAKE = qmake-qt4 QMAKE = qmake-qt4
SED = sed SED = sed
@ -72,6 +75,22 @@ CXX = gcc-4.6
CXXFLAGS += -std=gnu++0x -Os CXXFLAGS += -std=gnu++0x -Os
endif endif
ifeq ($(CONFIG),emcc)
CXX = emcc
CXXFLAGS += -std=c++11 -Os -Wno-warn-absolute-paths
CXXFLAGS := $(filter-out -ggdb,$(CXXFLAGS))
endif
ifeq ($(ENABLE_READLINE),1)
CXXFLAGS += -DYOSYS_ENABLE_READLINE
LDLIBS += -lreadline
endif
ifeq ($(ENABLE_PLUGINS),1)
CXXFLAGS += -DYOSYS_ENABLE_PLUGINS
LDLIBS += -lffi -ldl
endif
ifeq ($(ENABLE_TCL),1) ifeq ($(ENABLE_TCL),1)
TCL_VERSION ?= tcl8.5 TCL_VERSION ?= tcl8.5
TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) TCL_INCLUDE ?= /usr/include/$(TCL_VERSION)
@ -290,6 +309,14 @@ config-gcc: clean
config-gcc-4.6: clean config-gcc-4.6: clean
echo 'CONFIG := gcc-4.6' > Makefile.conf echo 'CONFIG := gcc-4.6' > Makefile.conf
config-emcc: clean
echo 'CONFIG := emcc' > Makefile.conf
echo 'ENABLE_TCL := 0' >> Makefile.conf
echo 'ENABLE_QT4 := 0' >> Makefile.conf
echo 'ENABLE_ABC := 0' >> Makefile.conf
echo 'ENABLE_PLUGINS := 0' >> Makefile.conf
echo 'ENABLE_READLINE := 0' >> Makefile.conf
config-gprof: clean config-gprof: clean
echo 'CONFIG := gcc' > Makefile.conf echo 'CONFIG := gcc' > Makefile.conf
echo 'ENABLE_GPROF := 1' >> Makefile.conf echo 'ENABLE_GPROF := 1' >> Makefile.conf

View File

@ -844,7 +844,11 @@ RTLIL::Const AstNode::realAsConst(int width)
{ {
double v = round(realvalue); double v = round(realvalue);
RTLIL::Const result; RTLIL::Const result;
#ifdef EMSCRIPTEN
if (!isfinite(v)) {
#else
if (!std::isfinite(v)) { if (!std::isfinite(v)) {
#endif
result.bits = std::vector<RTLIL::State>(width, RTLIL::State::Sx); result.bits = std::vector<RTLIL::State>(width, RTLIL::State::Sx);
} else { } else {
bool is_negative = v < 0; bool is_negative = v < 0;

View File

@ -17,9 +17,12 @@
* *
*/ */
#include "ast.h"
#ifdef YOSYS_ENABLE_PLUGINS
#include <dlfcn.h> #include <dlfcn.h>
#include <ffi.h> #include <ffi.h>
#include "ast.h"
typedef void (*ffi_fptr) (); typedef void (*ffi_fptr) ();
@ -126,3 +129,12 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname,
return newNode; return newNode;
} }
#else /* YOSYS_ENABLE_PLUGINS */
AST::AstNode *AST::dpi_call(const std::string&, const std::string &fname, const std::vector<std::string>&, const std::vector<AstNode*>&)
{
log_error("Can't call DPI function `%s': this version of yosys is built without plugin support\n", fname.c_str());
}
#endif /* YOSYS_ENABLE_PLUGINS */

View File

@ -108,7 +108,7 @@ struct CellTypes
for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"})) for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"}))
setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true);
setup_type("$assert", {"\\A", "\\EN"}, {}, true); setup_type("$assert", {"\\A", "\\EN"}, std::set<RTLIL::IdString>(), true);
} }
void setup_internals_mem() void setup_internals_mem()
@ -121,7 +121,7 @@ struct CellTypes
setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"});
setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}); setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"});
setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, {}); setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, std::set<RTLIL::IdString>());
setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"}); setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"});
setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"}); setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"});

View File

@ -26,7 +26,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) #if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L || defined(EMSCRIPTEN))
typedef struct memstream { typedef struct memstream {
off_t pos; off_t pos;

View File

@ -20,8 +20,10 @@
#include "kernel/yosys.h" #include "kernel/yosys.h"
#include "libs/sha1/sha1.h" #include "libs/sha1/sha1.h"
#include <readline/readline.h> #ifdef YOSYS_ENABLE_READLINE
#include <readline/history.h> # include <readline/readline.h>
# include <readline/history.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -46,6 +48,7 @@ int main(int argc, char **argv)
bool print_stats = true; bool print_stats = true;
bool call_abort = false; bool call_abort = false;
#ifdef YOSYS_ENABLE_READLINE
int history_offset = 0; int history_offset = 0;
std::string history_file; std::string history_file;
if (getenv("HOME") != NULL) { if (getenv("HOME") != NULL) {
@ -53,6 +56,7 @@ int main(int argc, char **argv)
read_history(history_file.c_str()); read_history(history_file.c_str());
history_offset = where_history(); history_offset = where_history();
} }
#endif
int opt; int opt;
while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1)
@ -329,6 +333,7 @@ int main(int argc, char **argv)
if (call_abort) if (call_abort)
abort(); abort();
#ifdef YOSYS_ENABLE_READLINE
if (!history_file.empty()) { if (!history_file.empty()) {
if (history_offset > 0) { if (history_offset > 0) {
history_truncate_file(history_file.c_str(), 100); history_truncate_file(history_file.c_str(), 100);
@ -341,6 +346,7 @@ int main(int argc, char **argv)
HIST_ENTRY **hist_list = history_list(); HIST_ENTRY **hist_list = history_list();
if (hist_list != NULL) if (hist_list != NULL)
free(hist_list); free(hist_list);
#endif
yosys_shutdown(); yosys_shutdown();

View File

@ -1605,6 +1605,10 @@ RTLIL::Memory::Memory()
size = 0; size = 0;
} }
RTLIL::Cell::Cell() : module(nullptr)
{
}
bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const
{ {
return connections_.count(portname) != 0; return connections_.count(portname) != 0;

View File

@ -77,7 +77,7 @@ namespace RTLIL
// the global id string cache // the global id string cache
struct char_ptr_cmp { struct char_ptr_cmp {
bool operator()(const char *a, const char *b) { bool operator()(const char *a, const char *b) const {
for (int i = 0; a[i] || b[i]; i++) for (int i = 0; a[i] || b[i]; i++)
if (a[i] != b[i]) if (a[i] != b[i])
return a[i] < b[i]; return a[i] < b[i];
@ -815,8 +815,7 @@ struct RTLIL::Cell
protected: protected:
// use module->addCell() and module->remove() to create or destroy cells // use module->addCell() and module->remove() to create or destroy cells
friend struct RTLIL::Module; friend struct RTLIL::Module;
Cell() : module(nullptr) { }; Cell();
~Cell() { };
public: public:
// do not simply copy cells // do not simply copy cells

View File

@ -19,12 +19,15 @@
#include "kernel/yosys.h" #include "kernel/yosys.h"
#include <readline/readline.h> #ifdef YOSYS_ENABLE_READLINE
#include <readline/history.h> # include <readline/readline.h>
# include <readline/history.h>
#endif
#include <dlfcn.h> #include <dlfcn.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
#include <errno.h>
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
@ -232,6 +235,11 @@ std::string proc_self_dirname ()
buflen--; buflen--;
return std::string(path, buflen); return std::string(path, buflen);
} }
#elif defined(EMSCRIPTEN)
std::string proc_self_dirname ()
{
return "/";
}
#else #else
#error Dont know how to determine process executable base path! #error Dont know how to determine process executable base path!
#endif #endif
@ -416,6 +424,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
Backend::backend_call(design, NULL, filename, command); Backend::backend_call(design, NULL, filename, command);
} }
#ifdef YOSYS_ENABLE_READLINE
static char *readline_cmd_generator(const char *text, int state) static char *readline_cmd_generator(const char *text, int state)
{ {
static std::map<std::string, Pass*>::iterator it; static std::map<std::string, Pass*>::iterator it;
@ -493,6 +502,7 @@ static char **readline_completion(const char *text, int start, int)
return rl_completion_matches(text, readline_obj_generator); return rl_completion_matches(text, readline_obj_generator);
return NULL; return NULL;
} }
#endif
void shell(RTLIL::Design *design) void shell(RTLIL::Design *design)
{ {
@ -501,16 +511,25 @@ void shell(RTLIL::Design *design)
recursion_counter++; recursion_counter++;
log_cmd_error_throw = true; log_cmd_error_throw = true;
#ifdef YOSYS_ENABLE_READLINE
rl_readline_name = "yosys"; rl_readline_name = "yosys";
rl_attempted_completion_function = readline_completion; rl_attempted_completion_function = readline_completion;
rl_basic_word_break_characters = " \t\n"; rl_basic_word_break_characters = " \t\n";
#endif
char *command = NULL; char *command = NULL;
#ifdef YOSYS_ENABLE_READLINE
while ((command = readline(create_prompt(design, recursion_counter))) != NULL) while ((command = readline(create_prompt(design, recursion_counter))) != NULL)
#else
char command_buffer[4096];
while ((command = fgets(command_buffer, 4096, stdin)) != NULL)
#endif
{ {
if (command[strspn(command, " \t\r\n")] == 0) if (command[strspn(command, " \t\r\n")] == 0)
continue; continue;
#ifdef YOSYS_ENABLE_READLINE
add_history(command); add_history(command);
#endif
char *p = command + strspn(command, " \t\r\n"); char *p = command + strspn(command, " \t\r\n");
if (!strncmp(p, "exit", 4)) { if (!strncmp(p, "exit", 4)) {
@ -576,6 +595,7 @@ struct ShellPass : public Pass {
} }
} ShellPass; } ShellPass;
#ifdef YOSYS_ENABLE_READLINE
struct HistoryPass : public Pass { struct HistoryPass : public Pass {
HistoryPass() : Pass("history", "show last interactive commands") { } HistoryPass() : Pass("history", "show last interactive commands") { }
virtual void help() { virtual void help() {
@ -593,6 +613,7 @@ struct HistoryPass : public Pass {
log("%s\n", (*list)->line); log("%s\n", (*list)->line);
} }
} HistoryPass; } HistoryPass;
#endif
struct ScriptPass : public Pass { struct ScriptPass : public Pass {
ScriptPass() : Pass("script", "execute commands from script file") { } ScriptPass() : Pass("script", "execute commands from script file") { }

View File

@ -18,7 +18,10 @@
*/ */
#include "kernel/yosys.h" #include "kernel/yosys.h"
#include <dlfcn.h>
#ifdef YOSYS_ENABLE_PLUGINS
# include <dlfcn.h>
#endif
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
@ -27,6 +30,7 @@ std::map<std::string, std::string> loaded_plugin_aliases;
void load_plugin(std::string filename, std::vector<std::string> aliases) void load_plugin(std::string filename, std::vector<std::string> aliases)
{ {
#ifdef YOSYS_ENABLE_PLUGINS
if (filename.find('/') == std::string::npos) if (filename.find('/') == std::string::npos)
filename = "./" + filename; filename = "./" + filename;
@ -40,6 +44,9 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
for (auto &alias : aliases) for (auto &alias : aliases)
loaded_plugin_aliases[alias] = filename; loaded_plugin_aliases[alias] = filename;
#else
log_error("This version of yosys is built without plugin support.\n");
#endif
} }
struct PluginPass : public Pass { struct PluginPass : public Pass {

View File

@ -22,7 +22,10 @@
#include "kernel/log.h" #include "kernel/log.h"
#include <string.h> #include <string.h>
#include <dirent.h> #include <dirent.h>
#include <readline/readline.h>
#ifdef YOSYS_ENABLE_READLINE
# include <readline/readline.h>
#endif
using RTLIL::id2cstr; using RTLIL::id2cstr;
@ -770,6 +773,7 @@ struct ShowPass : public Pass {
} }
if (flag_pause) { if (flag_pause) {
#ifdef YOSYS_ENABLE_READLINE
char *input = NULL; char *input = NULL;
while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) { while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) {
if (input[strspn(input, " \t\r\n")] == 0) if (input[strspn(input, " \t\r\n")] == 0)
@ -780,6 +784,9 @@ struct ShowPass : public Pass {
break; break;
} }
} }
#else
log_cmd_error("This version of yosys is built without readline support => 'show -pause' is not available.\n");
#endif
} }
log_pop(); log_pop();