From ae731369ddb8838302b5d9a3fa32689c44ab7934 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 6 Jan 2013 13:50:30 +0100 Subject: Improvements in command shell - Added 'shell' command (run interactive shell from synth script) - Added support for ; as cmd seperator as in "proc; opt" - Fixed c++ static initialization order problem with pass register --- kernel/driver.cc | 65 ++++++++++++++++++++++++++++----------------- kernel/register.cc | 78 +++++++++++++++++++++++++++++++++++++++++++++--------- kernel/register.h | 9 +++++++ 3 files changed, 114 insertions(+), 38 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index c49bf657..ae179675 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -140,6 +140,40 @@ static const char *create_prompt(RTLIL::Design *design) return buffer; } +static void shell(RTLIL::Design *design) +{ + log_cmd_error_throw = true; + + rl_readline_name = "yosys"; + rl_attempted_completion_function = readline_completion; + + char *command = NULL; + while ((command = readline(create_prompt(design))) != NULL) + { + if (command[strspn(command, " \t\r\n")] == 0) + continue; + add_history(command); + + try { + assert(design->selection_stack.size() == 1); + Pass::call(design, command); + } catch (int) { + while (design->selection_stack.size() > 1) + design->selection_stack.pop_back(); + log_reset_stack(); + } + } + + log_cmd_error_throw = false; +} + +struct ShellPass : public Pass { + ShellPass() : Pass("shell") { } + virtual void execute(std::vector, RTLIL::Design *design) { + shell(design); + } +} ShellPass; + int main(int argc, char **argv) { std::string frontend_command = "auto"; @@ -149,6 +183,8 @@ int main(int argc, char **argv) std::string scriptfile = ""; bool got_output_filename = false; + Pass::init_register(); + RTLIL::Design *design = new RTLIL::Design; design->selection_stack.push_back(RTLIL::Selection()); log_push(); @@ -196,33 +232,10 @@ int main(int argc, char **argv) if (log_errfile == NULL) log_files.push_back(stderr); - if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) - { - log_cmd_error_throw = true; - - rl_readline_name = "yosys"; - rl_attempted_completion_function = readline_completion; - - char *command = NULL; - while ((command = readline(create_prompt(design))) != NULL) - { - if (command[strspn(command, " \t\r\n")] == 0) - continue; - add_history(command); - - try { - assert(design->selection_stack.size() == 1); - Pass::call(design, command); - } catch (int) { - while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); - log_reset_stack(); - } - } - + if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) { if (!got_output_filename) backend_command = ""; - log_cmd_error_throw = false; + shell(design); } while (optind < argc) @@ -248,6 +261,8 @@ int main(int argc, char **argv) log_errfile = NULL; log_files.clear(); + Pass::done_register(); + return 0; } diff --git a/kernel/register.cc b/kernel/register.cc index fb70c80d..302a8f6c 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -23,8 +23,14 @@ #include using namespace REGISTER_INTERN; +#define MAX_REG_COUNT 1000 + +namespace REGISTER_INTERN +{ + int raw_register_count = 0; + bool raw_register_done = false; + Pass *raw_register_array[MAX_REG_COUNT]; -namespace REGISTER_INTERN { std::map frontend_register; std::map pass_register; std::map backend_register; @@ -34,13 +40,36 @@ std::vector Frontend::next_args; Pass::Pass(std::string name) : pass_name(name) { - assert(pass_register.count(name) == 0); - pass_register[name] = this; + assert(!raw_register_done); + assert(raw_register_count < MAX_REG_COUNT); + raw_register_array[raw_register_count++] = this; +} + +void Pass::run_register() +{ + assert(pass_register.count(pass_name) == 0); + pass_register[pass_name] = this; +} + +void Pass::init_register() +{ + if (raw_register_done) + done_register(); + while (raw_register_count > 0) + raw_register_array[--raw_register_count]->run_register(); + raw_register_done = true; +} + +void Pass::done_register() +{ + frontend_register.clear(); + pass_register.clear(); + backend_register.clear(); + raw_register_done = false; } Pass::~Pass() { - pass_register.erase(pass_name); } void Pass::help() @@ -92,9 +121,20 @@ void Pass::extra_args(std::vector args, size_t argidx, RTLIL::Desig void Pass::call(RTLIL::Design *design, std::string command) { std::vector args; - char *s = strdup(command.c_str()); - for (char *p = strtok(s, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) - args.push_back(p); + char *s = strdup(command.c_str()), *saveptr; + for (char *p = strtok_r(s, " \t\r\n", &saveptr); p; p = strtok_r(NULL, " \t\r\n", &saveptr)) { + std::string str = p; + int strsz = str.size(); + if (strsz > 0 && str[strsz-1] == ';') { + while (strsz > 0 && str[strsz-1] == ';') + strsz--; + if (strsz > 0) + args.push_back(str.substr(0, strsz)); + call(design, args); + args.clear(); + } else + args.push_back(str); + } free(s); call(design, args); } @@ -114,13 +154,19 @@ void Pass::call(RTLIL::Design *design, std::vector args) Frontend::Frontend(std::string name) : Pass("read_"+name), frontend_name(name) { - assert(frontend_register.count(name) == 0); - frontend_register[name] = this; +} + +void Frontend::run_register() +{ + assert(pass_register.count(pass_name) == 0); + pass_register[pass_name] = this; + + assert(frontend_register.count(frontend_name) == 0); + frontend_register[frontend_name] = this; } Frontend::~Frontend() { - frontend_register.erase(frontend_name); } void Frontend::execute(std::vector args, RTLIL::Design *design) @@ -200,13 +246,19 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam Backend::Backend(std::string name) : Pass("write_"+name), backend_name(name) { - assert(backend_register.count(name) == 0); - backend_register[name] = this; +} + +void Backend::run_register() +{ + assert(pass_register.count(pass_name) == 0); + pass_register[pass_name] = this; + + assert(backend_register.count(backend_name) == 0); + backend_register[backend_name] = this; } Backend::~Backend() { - backend_register.erase(backend_name); } void Backend::execute(std::vector args, RTLIL::Design *design) diff --git a/kernel/register.h b/kernel/register.h index 713d468e..56350be3 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -30,6 +30,7 @@ struct Pass { std::string pass_name; Pass(std::string name); + virtual void run_register(); virtual ~Pass(); virtual void help(); virtual void execute(std::vector args, RTLIL::Design *design) = 0; @@ -40,12 +41,16 @@ struct Pass static void call(RTLIL::Design *design, std::string command); static void call(RTLIL::Design *design, std::vector args); + + static void init_register(); + static void done_register(); }; struct Frontend : Pass { std::string frontend_name; Frontend(std::string name); + virtual void run_register(); virtual ~Frontend(); virtual void execute(std::vector args, RTLIL::Design *design); virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; @@ -61,6 +66,7 @@ struct Backend : Pass { std::string backend_name; Backend(std::string name); + virtual void run_register(); virtual ~Backend(); virtual void execute(std::vector args, RTLIL::Design *design); virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; @@ -72,6 +78,9 @@ struct Backend : Pass }; namespace REGISTER_INTERN { + extern int raw_register_count; + extern bool raw_register_done; + extern Pass *raw_register_array[]; extern std::map pass_register; extern std::map frontend_register; extern std::map backend_register; -- cgit v1.2.3 From a24086d1db96b4f3553e279985331e49482934bc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 6 Jan 2013 14:40:15 +0100 Subject: Added "getting started" section to README --- README | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/README b/README index 0a519262..13591693 100644 --- a/README +++ b/README @@ -17,6 +17,109 @@ compatible licence that is similar in terms to the MIT license or the 2-clause BSD license). +Getting Started +=============== + +To build Yosys simply typoe 'make' in this directory. You need +a C++ compiler with C++11 support (up-to-date CLANG or GCC is +recommended) and some standard tools such as GNU Flex, GNU Bison, +and GNU Make. It might be neccessary to make some changes to +the config section of the Makefile. + + $ vi Makefile + $ make + $ make test + $ sudo make install + +Yosys can be used using the interactive command shell, using +synthesis scripts or using command line arguments. Let's perform +a simple synthesis job using the interactive command shell: + + $ ./yosys + yosys> + +reading the design using the verilog frontend: + + yosys> read_verilog tests/simple/fiedler-cooley.v + +writing the design to the console in yosys's internal format: + + yosys> write_ilang + +convert processes (always blocks) to netlist elements and perform +some simple optimizations: + + yosys> proc; opt + +display design netlist using 'gv' as postscript viewer: + + yosys> show -viewer gv + +translating netlist to gate logic and perform some simple optimizations: + + yosys> techmap; opt + +write design netlist to a new verilog file: + + yosys> write_verilog synth.v + +a simmilar synthesis can be performed using yosys command line options only: + + $ ./yosys -o synth.v -p proc -p opt -p techmap -p opt tests/simple/fiedler-cooley.v + +or using a simple synthesis script: + + $ cat synth.ys + read_verilog tests/simple/fiedler-cooley.v + proc; opt; techmap; opt + write_verilog synth.v + + $ ././yosys synth.ys + +It is also possible to only have the synthesis commands but not the read/write +commands in the synthesis script: + + $ cat synth.ys + proc; opt; techmap; opt + + $ ./yosys -o synth.v tests/simple/fiedler-cooley.v synth.ys + +The following synthesis script works reasonable for all designs: + + # check design hierarchy + hierarchy + + # translate processes (always blocks) and memories (arrays) + proc; memory; opt + + # detect and optimize FSM encodings + fsm; opt + + # convert to gate logic + techmap; opt + +If ABC (http://www.eecs.berkeley.edu/~alanmi/abc/) is installed and +a cell library is given in the file liberty mycells.lib, the following +synthesis script will synthesize for the given cell library: + + # the high-level stuff + hierarchy; proc; memory; opt; fsm; opt + + # mapping to internal cell library + techmap + + # mapping flip-flops to mycells.lib + dfflibmap -liberty mycells.lib + + # mapping logic to mycells.lib + abc -liberty mycells.lib + + # cleanup + opt + +Yosys is under construction. A more detailed documentation will follow. + + Unsupported Verilog-2005 Features ================================= @@ -83,7 +186,7 @@ TODOs / Open Bugs - TCL and Python interfaces to frontends, passes, backends and RTLIL -- Additional internal cell types: $bitcount, $pla, $lut and $pmux +- Additional internal cell types: $pla and $lut - Subsystem for selecting stuff (and limiting scope of passes) @@ -93,5 +196,5 @@ TODOs / Open Bugs - Smarter resource sharing pass (add MUXes and get rid of duplicated cells) -- FSM state encoding and technology mapping +- Better FSM state encoding and technology mapping -- cgit v1.2.3