diff options
| author | Ahmed Irfan <ahmedirfan1983@gmail.com> | 2014-09-22 11:35:04 +0200 |
|---|---|---|
| committer | Ahmed Irfan <ahmedirfan1983@gmail.com> | 2014-09-22 11:35:04 +0200 |
| commit | d3c67ad9b61f602de1100cd264efd227dcacb417 (patch) | |
| tree | 88c462c53bdab128cd1edbded42483772f82612a /kernel/register.cc | |
| parent | b783dbe148e6d246ebd107c0913de2989ab5af48 (diff) | |
| parent | 13117bb346dd02d2345f716b4403239aebe3d0e2 (diff) | |
| download | yosys-d3c67ad9b61f602de1100cd264efd227dcacb417.tar.gz yosys-d3c67ad9b61f602de1100cd264efd227dcacb417.tar.bz2 yosys-d3c67ad9b61f602de1100cd264efd227dcacb417.zip | |
Merge branch 'master' of https://github.com/cliffordwolf/yosys into btor
added case for memwr cell that is used in muxes (same cell is used more than one time)
corrected bug for xnor and logic_not
added pmux cell translation
Conflicts:
backends/btor/btor.cc
Diffstat (limited to 'kernel/register.cc')
| -rw-r--r-- | kernel/register.cc | 263 |
1 files changed, 183 insertions, 80 deletions
diff --git a/kernel/register.cc b/kernel/register.cc index 325709664..2f7b89ffd 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -17,50 +17,46 @@ * */ -#include "register.h" -#include "log.h" -#include <assert.h> +#include "kernel/yosys.h" #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <errno.h> + +YOSYS_NAMESPACE_BEGIN -using namespace REGISTER_INTERN; #define MAX_REG_COUNT 1000 -namespace REGISTER_INTERN -{ - bool echo_mode = false; - int raw_register_count = 0; - bool raw_register_done = false; - Pass *raw_register_array[MAX_REG_COUNT]; - - std::map<std::string, Frontend*> frontend_register; - std::map<std::string, Pass*> pass_register; - std::map<std::string, Backend*> backend_register; -} +bool echo_mode = false; +Pass *first_queued_pass; +Pass *current_pass; + +std::map<std::string, Frontend*> frontend_register; +std::map<std::string, Pass*> pass_register; +std::map<std::string, Backend*> backend_register; std::vector<std::string> Frontend::next_args; Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_help(short_help) { - assert(!raw_register_done); - assert(raw_register_count < MAX_REG_COUNT); - raw_register_array[raw_register_count++] = this; + next_queued_pass = first_queued_pass; + first_queued_pass = this; + call_counter = 0; + runtime_ns = 0; } void Pass::run_register() { - assert(pass_register.count(pass_name) == 0); + log_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; + while (first_queued_pass) { + first_queued_pass->run_register(); + first_queued_pass = first_queued_pass->next_queued_pass; + } } void Pass::done_register() @@ -68,13 +64,32 @@ void Pass::done_register() frontend_register.clear(); pass_register.clear(); backend_register.clear(); - raw_register_done = false; + log_assert(first_queued_pass == NULL); } Pass::~Pass() { } +Pass::pre_post_exec_state_t Pass::pre_execute() +{ + pre_post_exec_state_t state; + call_counter++; + state.begin_ns = PerformanceTimer::query(); + state.parent_pass = current_pass; + current_pass = this; + return state; +} + +void Pass::post_execute(Pass::pre_post_exec_state_t state) +{ + int64_t time_ns = PerformanceTimer::query() - state.begin_ns; + runtime_ns += time_ns; + current_pass = state.parent_pass; + if (current_pass) + current_pass->runtime_ns -= time_ns; +} + void Pass::help() { log("\n"); @@ -117,7 +132,7 @@ void Pass::extra_args(std::vector<std::string> args, size_t argidx, RTLIL::Desig std::string arg = args[argidx]; if (arg.substr(0, 1) == "-") - cmd_error(args, argidx, "Unkown option or option in arguments."); + cmd_error(args, argidx, "Unknown option or option in arguments."); if (!select) cmd_error(args, argidx, "Extra argument."); @@ -133,8 +148,10 @@ void Pass::call(RTLIL::Design *design, std::string command) std::vector<std::string> args; char *s = strdup(command.c_str()), *sstart = s, *saveptr; s += strspn(s, " \t\r\n"); - if (*s == 0 || *s == '#') + if (*s == 0 || *s == '#') { + free(sstart); return; + } if (*s == '!') { for (s++; *s == ' ' || *s == '\t'; s++) { } char *p = s + strlen(s) - 1; @@ -144,6 +161,7 @@ void Pass::call(RTLIL::Design *design, std::string command) int retCode = system(s); if (retCode != 0) log_cmd_error("Shell command returned error code %d.\n", retCode); + free(sstart); return; } for (char *p = strtok_r(s, " \t\r\n", &saveptr); p; p = strtok_r(NULL, " \t\r\n", &saveptr)) { @@ -186,18 +204,20 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args) log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str()); size_t orig_sel_stack_pos = design->selection_stack.size(); + auto state = pass_register[args[0]]->pre_execute(); pass_register[args[0]]->execute(args, design); + pass_register[args[0]]->post_execute(state); while (design->selection_stack.size() > orig_sel_stack_pos) design->selection_stack.pop_back(); design->check(); } -void Pass::call_newsel(RTLIL::Design *design, std::string command) +void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command) { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(RTLIL::Selection()); + design->selection_stack.push_back(selection); Pass::call(design, command); @@ -205,11 +225,11 @@ void Pass::call_newsel(RTLIL::Design *design, std::string command) design->selected_active_module = backup_selected_active_module; } -void Pass::call_newsel(RTLIL::Design *design, std::vector<std::string> args) +void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::vector<std::string> args) { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(RTLIL::Selection()); + design->selection_stack.push_back(selection); Pass::call(design, args); @@ -217,16 +237,44 @@ void Pass::call_newsel(RTLIL::Design *design, std::vector<std::string> args) design->selected_active_module = backup_selected_active_module; } -Frontend::Frontend(std::string name, std::string short_help) : Pass("read_"+name, short_help), frontend_name(name) +void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command) +{ + std::string backup_selected_active_module = design->selected_active_module; + design->selected_active_module = module->name.str(); + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); + + Pass::call(design, command); + + design->selection_stack.pop_back(); + design->selected_active_module = backup_selected_active_module; +} + +void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vector<std::string> args) +{ + std::string backup_selected_active_module = design->selected_active_module; + design->selected_active_module = module->name.str(); + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); + + Pass::call(design, args); + + design->selection_stack.pop_back(); + design->selected_active_module = backup_selected_active_module; +} + +Frontend::Frontend(std::string name, std::string short_help) : + Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help), + frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name) { } void Frontend::run_register() { - assert(pass_register.count(pass_name) == 0); + log_assert(pass_register.count(pass_name) == 0); pass_register[pass_name] = this; - assert(frontend_register.count(frontend_name) == 0); + log_assert(frontend_register.count(frontend_name) == 0); frontend_register[frontend_name] = this; } @@ -236,17 +284,22 @@ Frontend::~Frontend() void Frontend::execute(std::vector<std::string> args, RTLIL::Design *design) { - assert(next_args.empty()); + log_assert(next_args.empty()); do { - FILE *f = NULL; + std::istream *f = NULL; next_args.clear(); + auto state = pre_execute(); execute(f, std::string(), args, design); + post_execute(state); args = next_args; - fclose(f); + delete f; } while (!args.empty()); } -void Frontend::extra_args(FILE *&f, std::string &filename, std::vector<std::string> args, size_t argidx) +FILE *Frontend::current_script_file = NULL; +std::string Frontend::last_here_document; + +void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<std::string> args, size_t argidx) { bool called_with_fp = f != NULL; @@ -256,15 +309,53 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vector<std::stri std::string arg = args[argidx]; if (arg.substr(0, 1) == "-") - cmd_error(args, argidx, "Unkown option or option in arguments."); + cmd_error(args, argidx, "Unknown option or option in arguments."); if (f != NULL) cmd_error(args, argidx, "Extra filename argument in direct file mode."); filename = arg; - f = fopen(filename.c_str(), "r"); + if (filename == "<<" && argidx+1 < args.size()) + filename += args[++argidx]; + if (filename.substr(0, 2) == "<<") { + if (Frontend::current_script_file == NULL) + log_error("Unexpected here document '%s' outside of script!\n", filename.c_str()); + if (filename.size() <= 2) + log_error("Missing EOT marker in here document!\n"); + std::string eot_marker = filename.substr(2); + last_here_document.clear(); + while (1) { + std::string buffer; + char block[4096]; + while (1) { + if (fgets(block, 4096, Frontend::current_script_file) == NULL) + log_error("Unexpected end of file in here document '%s'!\n", filename.c_str()); + buffer += block; + if (buffer.size() > 0 && (buffer[buffer.size() - 1] == '\n' || buffer[buffer.size() - 1] == '\r')) + break; + } + int indent = buffer.find_first_not_of(" \t\r\n"); + if (buffer.substr(indent, eot_marker.size()) == eot_marker) + break; + last_here_document += buffer; + } + f = new std::istringstream(last_here_document); + } else { + if (filename.substr(0, 2) == "+/") + filename = proc_share_dirname() + filename.substr(1); + std::ifstream *ff = new std::ifstream; + ff->open(filename.c_str()); + if (ff->fail()) + delete ff; + else + f = ff; + } if (f == NULL) log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); + for (size_t i = argidx+1; i < args.size(); i++) + if (args[i].substr(0, 1) == "-") + cmd_error(args, i, "Found option, expected arguments."); + if (argidx+1 < args.size()) { next_args.insert(next_args.begin(), args.begin(), args.begin()+argidx); next_args.insert(next_args.begin()+argidx, args.begin()+argidx+1, args.end()); @@ -281,7 +372,7 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vector<std::stri // cmd_log_args(args); } -void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filename, std::string command) +void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::string command) { std::vector<std::string> args; char *s = strdup(command.c_str()); @@ -291,7 +382,7 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam frontend_call(design, f, filename, args); } -void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector<std::string> args) +void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::vector<std::string> args) { if (args.size() == 0) return; @@ -299,9 +390,14 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam log_cmd_error("No such frontend: %s\n", args[0].c_str()); if (f != NULL) { + auto state = frontend_register[args[0]]->pre_execute(); frontend_register[args[0]]->execute(f, filename, args, design); + frontend_register[args[0]]->post_execute(state); } else if (filename == "-") { - frontend_register[args[0]]->execute(stdin, "<stdin>", args, design); + std::istream *f_cin = &std::cin; + auto state = frontend_register[args[0]]->pre_execute(); + frontend_register[args[0]]->execute(f_cin, "<stdin>", args, design); + frontend_register[args[0]]->post_execute(state); } else { if (!filename.empty()) args.push_back(filename); @@ -311,16 +407,18 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam design->check(); } -Backend::Backend(std::string name, std::string short_help) : Pass("write_"+name, short_help), backend_name(name) +Backend::Backend(std::string name, std::string short_help) : + Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "write_" + name, short_help), + backend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name) { } void Backend::run_register() { - assert(pass_register.count(pass_name) == 0); + log_assert(pass_register.count(pass_name) == 0); pass_register[pass_name] = this; - assert(backend_register.count(backend_name) == 0); + log_assert(backend_register.count(backend_name) == 0); backend_register[backend_name] = this; } @@ -330,13 +428,15 @@ Backend::~Backend() void Backend::execute(std::vector<std::string> args, RTLIL::Design *design) { - FILE *f = NULL; + std::ostream *f = NULL; + auto state = pre_execute(); execute(f, std::string(), args, design); - if (f != stdout) - fclose(f); + post_execute(state); + if (f != &std::cout) + delete f; } -void Backend::extra_args(FILE *&f, std::string &filename, std::vector<std::string> args, size_t argidx) +void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx) { bool called_with_fp = f != NULL; @@ -345,20 +445,24 @@ void Backend::extra_args(FILE *&f, std::string &filename, std::vector<std::strin std::string arg = args[argidx]; if (arg.substr(0, 1) == "-" && arg != "-") - cmd_error(args, argidx, "Unkown option or option in arguments."); + cmd_error(args, argidx, "Unknown option or option in arguments."); if (f != NULL) cmd_error(args, argidx, "Extra filename argument in direct file mode."); if (arg == "-") { filename = "<stdout>"; - f = stdout; + f = &std::cout; continue; } filename = arg; - f = fopen(filename.c_str(), "w"); - if (f == NULL) + std::ofstream *ff = new std::ofstream; + ff->open(filename.c_str(), std::ofstream::trunc); + if (ff->fail()) { + delete ff; log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + f = ff; } if (called_with_fp) @@ -368,11 +472,11 @@ void Backend::extra_args(FILE *&f, std::string &filename, std::vector<std::strin if (f == NULL) { filename = "<stdout>"; - f = stdout; + f = &std::cout; } } -void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::string command) +void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command) { std::vector<std::string> args; char *s = strdup(command.c_str()); @@ -382,7 +486,7 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, backend_call(design, f, filename, args); } -void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector<std::string> args) +void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::vector<std::string> args) { if (args.size() == 0) return; @@ -392,9 +496,14 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, size_t orig_sel_stack_pos = design->selection_stack.size(); if (f != NULL) { + auto state = backend_register[args[0]]->pre_execute(); backend_register[args[0]]->execute(f, filename, args, design); + backend_register[args[0]]->post_execute(state); } else if (filename == "-") { - backend_register[args[0]]->execute(stdout, "<stdout>", args, design); + std::ostream *f_cout = &std::cout; + auto state = backend_register[args[0]]->pre_execute(); + backend_register[args[0]]->execute(f_cout, "<stdout>", args, design); + backend_register[args[0]]->post_execute(state); } else { if (!filename.empty()) args.push_back(filename); @@ -479,7 +588,7 @@ struct HelpPass : public Pass { { if (args.size() == 1) { log("\n"); - for (auto &it : REGISTER_INTERN::pass_register) + for (auto &it : pass_register) log(" %-20s %s\n", it.first.c_str(), it.second->short_help.c_str()); log("\n"); log("Type 'help <command>' for more information on a command.\n"); @@ -489,7 +598,7 @@ struct HelpPass : public Pass { if (args.size() == 2) { if (args[1] == "-all") { - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { log("\n\n"); log("%s -- %s\n", it.first.c_str(), it.second->short_help.c_str()); for (size_t i = 0; i < it.first.size() + it.second->short_help.size() + 6; i++) @@ -502,39 +611,31 @@ struct HelpPass : public Pass { else if (args[1] == "-write-tex-command-reference-manual") { FILE *f = fopen("command-reference-manual.tex", "wt"); fprintf(f, "%% Generated using the yosys 'help -write-tex-command-reference-manual' command.\n\n"); - for (auto &it : REGISTER_INTERN::pass_register) { - size_t memsize; - char *memptr; - FILE *memf = open_memstream(&memptr, &memsize); - log_files.push_back(memf); + for (auto &it : pass_register) { + std::ostringstream buf; + log_streams.push_back(&buf); it.second->help(); - log_files.pop_back(); - fclose(memf); - write_tex(f, it.first, it.second->short_help, memptr); - free(memptr); + log_streams.pop_back(); + write_tex(f, it.first, it.second->short_help, buf.str()); } fclose(f); } // this option is undocumented as it is for internal use only else if (args[1] == "-write-web-command-reference-manual") { FILE *f = fopen("templates/cmd_index.in", "wt"); - for (auto &it : REGISTER_INTERN::pass_register) { - size_t memsize; - char *memptr; - FILE *memf = open_memstream(&memptr, &memsize); - log_files.push_back(memf); + for (auto &it : pass_register) { + std::ostringstream buf; + log_streams.push_back(&buf); it.second->help(); - log_files.pop_back(); - fclose(memf); - write_html(f, it.first, it.second->short_help, memptr); - free(memptr); + log_streams.pop_back(); + write_html(f, it.first, it.second->short_help, buf.str()); } fclose(f); } - else if (REGISTER_INTERN::pass_register.count(args[1]) == 0) + else if (pass_register.count(args[1]) == 0) log("No such command: %s\n", args[1].c_str()); else - REGISTER_INTERN::pass_register.at(args[1])->help(); + pass_register.at(args[1])->help(); return; } @@ -575,3 +676,5 @@ struct EchoPass : public Pass { } } EchoPass; +YOSYS_NAMESPACE_END + |
