From 1cb25c05b37b0172dbc50e140fe20f25d973dd8a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 13:19:47 +0200 Subject: [PATCH] Moved some stuff to kernel/yosys.{h,cc}, using Yosys:: namespace --- backends/ilang/ilang_backend.cc | 6 +- backends/ilang/ilang_backend.h | 6 +- frontends/ast/ast.cc | 6 +- frontends/ast/ast.h | 4 + frontends/ast/genrtlil.cc | 24 +- frontends/ast/simplify.cc | 60 +-- frontends/ilang/ilang_frontend.cc | 4 + frontends/ilang/ilang_frontend.h | 6 +- frontends/ilang/parser.y | 9 +- frontends/liberty/liberty.cc | 3 + frontends/verific/verific.cc | 8 +- frontends/verilog/const2ast.cc | 4 + frontends/verilog/lexer.l | 3 + frontends/verilog/parser.y | 7 +- frontends/verilog/preproc.cc | 4 + frontends/verilog/verilog_frontend.cc | 3 + frontends/verilog/verilog_frontend.h | 6 +- frontends/vhdl2verilog/vhdl2verilog.cc | 4 + kernel/calc.cc | 7 +- kernel/driver.cc | 546 +----------------------- kernel/log.cc | 6 +- kernel/log.h | 6 +- kernel/register.cc | 34 +- kernel/register.h | 14 +- kernel/rtlil.cc | 8 +- kernel/rtlil.h | 18 +- kernel/sigtools.h | 8 +- kernel/yosys.cc | 565 +++++++++++++++++++++++++ kernel/yosys.h | 38 +- libs/subcircuit/subcircuit.cc | 4 +- passes/abc/abc.cc | 4 +- passes/cmds/design.cc | 4 + passes/fsm/fsm_extract.cc | 4 +- passes/memory/memory_collect.cc | 2 +- passes/memory/memory_dff.cc | 2 +- passes/memory/memory_map.cc | 2 +- passes/memory/memory_unpack.cc | 2 +- passes/proc/proc_dff.cc | 6 +- passes/proc/proc_mux.cc | 4 +- passes/techmap/extract.cc | 2 +- passes/techmap/techmap.cc | 2 +- 41 files changed, 790 insertions(+), 665 deletions(-) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index c055c1334..b7088f599 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -336,7 +336,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { - int init_autoidx = RTLIL::autoidx; + int init_autoidx = autoidx; if (!flag_m) { int count_selected_mods = 0; @@ -353,7 +353,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ if (!only_selected || flag_m) { if (only_selected) fprintf(f, "\n"); - fprintf(f, "autoidx %d\n", RTLIL::autoidx); + fprintf(f, "autoidx %d\n", autoidx); } for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { @@ -364,7 +364,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ } } - log_assert(init_autoidx == RTLIL::autoidx); + log_assert(init_autoidx == autoidx); } struct IlangBackend : public Backend { diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h index fecbcc1fe..b0fec4889 100644 --- a/backends/ilang/ilang_backend.h +++ b/backends/ilang/ilang_backend.h @@ -25,9 +25,11 @@ #ifndef ILANG_BACKEND_H #define ILANG_BACKEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include +YOSYS_NAMESPACE_BEGIN + namespace ILANG_BACKEND { void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint = true); @@ -44,4 +46,6 @@ namespace ILANG_BACKEND { void dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); } +YOSYS_NAMESPACE_END + #endif diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5b3214f5c..d548a679c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -34,6 +34,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; using namespace AST_INTERNAL; @@ -806,7 +808,7 @@ RTLIL::Const AstNode::realAsConst(int width) { double v = round(realvalue); RTLIL::Const result; - if (!isfinite(v)) { + if (!std::isfinite(v)) { result.bits = std::vector(width, RTLIL::State::Sx); } else { bool is_negative = v < 0; @@ -1087,3 +1089,5 @@ void AST::use_internal_line_num() get_line_num = &internal_get_line_num; } +YOSYS_NAMESPACE_END + diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6c15c03ab..83798edf0 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -33,6 +33,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + namespace AST { // all node types, type2str() must be extended @@ -285,4 +287,6 @@ namespace AST_INTERNAL struct ProcessGenerator; } +YOSYS_NAMESPACE_END + #endif diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b7f336354..0cc4f4c47 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -34,6 +34,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; using namespace AST_INTERNAL; @@ -41,7 +43,7 @@ using namespace AST_INTERNAL; static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true) { std::stringstream sstr; - sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -75,7 +77,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s } std::stringstream sstr; - sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -104,7 +106,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { std::stringstream sstr; - sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -139,7 +141,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const log_assert(cond.size() == 1); std::stringstream sstr; - sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -201,7 +203,7 @@ struct AST_INTERNAL::ProcessGenerator // generate process and simple root case proc = new RTLIL::Process; proc->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); - proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->linenum, RTLIL::autoidx++); + proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->linenum, autoidx++); for (auto &attr : always->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -294,7 +296,7 @@ struct AST_INTERNAL::ProcessGenerator wire_name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, chunk.wire->name.c_str(), chunk.width+chunk.offset-1, chunk.offset);; if (chunk.wire->name.find('$') != std::string::npos) - wire_name += stringf("$%d", RTLIL::autoidx++); + wire_name += stringf("$%d", autoidx++); } while (current_module->wires_.count(wire_name) > 0); RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); @@ -1189,7 +1191,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMRD: { std::stringstream sstr; - sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1220,7 +1222,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMWR: { std::stringstream sstr; - sstr << "$memwr$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$memwr$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memwr"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1241,7 +1243,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0); - cell->parameters["\\PRIORITY"] = RTLIL::Const(RTLIL::autoidx-1); + cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1); } break; @@ -1257,7 +1259,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(en.size() == 1); std::stringstream sstr; - sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$assert$" << filename << ":" << linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$assert"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1399,3 +1401,5 @@ RTLIL::SigSpec AstNode::genWidthRTLIL(int width, RTLIL::SigSpec *subst_from, RT return sig; } +YOSYS_NAMESPACE_END + diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5665cd43c..c51692f12 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -34,6 +34,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; using namespace AST_INTERNAL; @@ -624,7 +626,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, id2ast->meminfo(mem_width, mem_size, addr_bits); std::stringstream sstr; - sstr << "$mem2bits$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$mem2bits$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string wire_id = sstr.str(); AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); @@ -744,7 +746,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, buf = new AstNode(AST_GENBLOCK, body_ast->clone()); if (buf->str.empty()) { std::stringstream sstr; - sstr << "$genblock$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$genblock$" << filename << ":" << linenum << "$" << (autoidx++); buf->str = sstr.str(); } std::map name_map; @@ -1091,7 +1093,7 @@ skip_dynamic_range_lvalue_expansion:; if (stage > 1 && type == AST_ASSERT && current_block != NULL) { std::stringstream sstr; - sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$assert$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN"; AstNode *wire_check = new AstNode(AST_WIRE); @@ -1166,7 +1168,7 @@ skip_dynamic_range_lvalue_expansion:; (children[0]->children.size() == 1 || children[0]->children.size() == 2)) { std::stringstream sstr; - sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN"; if (type == AST_ASSIGN_EQ) @@ -1364,27 +1366,27 @@ skip_dynamic_range_lvalue_expansion:; } newNode = new AstNode(AST_REALVALUE); - if (str == "\\$ln") newNode->realvalue = log(x); - else if (str == "\\$log10") newNode->realvalue = log10(x); - else if (str == "\\$exp") newNode->realvalue = exp(x); - else if (str == "\\$sqrt") newNode->realvalue = sqrt(x); - else if (str == "\\$pow") newNode->realvalue = pow(x, y); - else if (str == "\\$floor") newNode->realvalue = floor(x); - else if (str == "\\$ceil") newNode->realvalue = ceil(x); - else if (str == "\\$sin") newNode->realvalue = sin(x); - else if (str == "\\$cos") newNode->realvalue = cos(x); - else if (str == "\\$tan") newNode->realvalue = tan(x); - else if (str == "\\$asin") newNode->realvalue = asin(x); - else if (str == "\\$acos") newNode->realvalue = acos(x); - else if (str == "\\$atan") newNode->realvalue = atan(x); - else if (str == "\\$atan2") newNode->realvalue = atan2(x, y); - else if (str == "\\$hypot") newNode->realvalue = hypot(x, y); - else if (str == "\\$sinh") newNode->realvalue = sinh(x); - else if (str == "\\$cosh") newNode->realvalue = cosh(x); - else if (str == "\\$tanh") newNode->realvalue = tanh(x); - else if (str == "\\$asinh") newNode->realvalue = asinh(x); - else if (str == "\\$acosh") newNode->realvalue = acosh(x); - else if (str == "\\$atanh") newNode->realvalue = atanh(x); + if (str == "\\$ln") newNode->realvalue = ::log(x); + else if (str == "\\$log10") newNode->realvalue = ::log10(x); + else if (str == "\\$exp") newNode->realvalue = ::exp(x); + else if (str == "\\$sqrt") newNode->realvalue = ::sqrt(x); + else if (str == "\\$pow") newNode->realvalue = ::pow(x, y); + else if (str == "\\$floor") newNode->realvalue = ::floor(x); + else if (str == "\\$ceil") newNode->realvalue = ::ceil(x); + else if (str == "\\$sin") newNode->realvalue = ::sin(x); + else if (str == "\\$cos") newNode->realvalue = ::cos(x); + else if (str == "\\$tan") newNode->realvalue = ::tan(x); + else if (str == "\\$asin") newNode->realvalue = ::asin(x); + else if (str == "\\$acos") newNode->realvalue = ::acos(x); + else if (str == "\\$atan") newNode->realvalue = ::atan(x); + else if (str == "\\$atan2") newNode->realvalue = ::atan2(x, y); + else if (str == "\\$hypot") newNode->realvalue = ::hypot(x, y); + else if (str == "\\$sinh") newNode->realvalue = ::sinh(x); + else if (str == "\\$cosh") newNode->realvalue = ::cosh(x); + else if (str == "\\$tanh") newNode->realvalue = ::tanh(x); + else if (str == "\\$asinh") newNode->realvalue = ::asinh(x); + else if (str == "\\$acosh") newNode->realvalue = ::acosh(x); + else if (str == "\\$atanh") newNode->realvalue = ::atanh(x); else log_abort(); goto apply_newNode; } @@ -1423,7 +1425,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *decl = current_scope[str]; std::stringstream sstr; - sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++) << "$"; + sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; std::string prefix = sstr.str(); size_t arg_count = 0; @@ -1988,7 +1990,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * mem2reg_set.count(children[0]->id2ast) > 0 && children[0]->children[0]->children[0]->type != AST_CONSTANT) { std::stringstream sstr; - sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; @@ -2059,7 +2061,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * else { std::stringstream sstr; - sstr << "$mem2reg_rd$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$mem2reg_rd$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; @@ -2421,3 +2423,5 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed); } +YOSYS_NAMESPACE_END + diff --git a/frontends/ilang/ilang_frontend.cc b/frontends/ilang/ilang_frontend.cc index 572a35720..2d4b99c52 100644 --- a/frontends/ilang/ilang_frontend.cc +++ b/frontends/ilang/ilang_frontend.cc @@ -26,6 +26,8 @@ #include "kernel/register.h" #include "kernel/log.h" +YOSYS_NAMESPACE_BEGIN + void rtlil_frontend_ilang_yyerror(char const *s) { log_error("Parser error in line %d: %s\n", rtlil_frontend_ilang_yyget_lineno(), s); @@ -57,3 +59,5 @@ struct IlangFrontend : public Frontend { } } IlangFrontend; +YOSYS_NAMESPACE_END + diff --git a/frontends/ilang/ilang_frontend.h b/frontends/ilang/ilang_frontend.h index 5e768c3b9..317ec0d51 100644 --- a/frontends/ilang/ilang_frontend.h +++ b/frontends/ilang/ilang_frontend.h @@ -25,14 +25,18 @@ #ifndef ILANG_FRONTEND_H #define ILANG_FRONTEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include +YOSYS_NAMESPACE_BEGIN + namespace ILANG_FRONTEND { void ilang_frontend(FILE *f, RTLIL::Design *design); extern RTLIL::Design *current_design; } +YOSYS_NAMESPACE_END + extern int rtlil_frontend_ilang_yydebug; int rtlil_frontend_ilang_yylex(void); void rtlil_frontend_ilang_yyerror(char const *s); diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 38d3054b2..ab763b2b1 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -25,6 +25,7 @@ %{ #include #include "ilang_frontend.h" +YOSYS_NAMESPACE_BEGIN namespace ILANG_FRONTEND { RTLIL::Design *current_design; RTLIL::Module *current_module; @@ -37,6 +38,8 @@ namespace ILANG_FRONTEND { std::map attrbuf; } using namespace ILANG_FRONTEND; +YOSYS_NAMESPACE_END +USING_YOSYS_NAMESPACE %} %name-prefix "rtlil_frontend_ilang_yy" @@ -44,8 +47,8 @@ using namespace ILANG_FRONTEND; %union { char *string; int integer; - RTLIL::Const *data; - RTLIL::SigSpec *sigspec; + YOSYS_NAMESPACE_PREFIX RTLIL::Const *data; + YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec *sigspec; } %token TOK_ID TOK_VALUE TOK_STRING @@ -116,7 +119,7 @@ attr_stmt: autoidx_stmt: TOK_AUTOIDX TOK_INT EOL { - RTLIL::autoidx = std::max(RTLIL::autoidx, $2); + autoidx = std::max(autoidx, $2); }; wire_stmt: diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index d5f172f03..da16ab33f 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -21,6 +21,7 @@ #include "kernel/register.h" #include "kernel/log.h" +YOSYS_NAMESPACE_BEGIN using namespace PASS_DFFLIBMAP; struct token_t { @@ -573,3 +574,5 @@ skip_cell:; } } LibertyFrontend; +YOSYS_NAMESPACE_END + diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 80170394e..6e692c5a1 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -17,7 +17,7 @@ * */ -#include "kernel/register.h" +#include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/log.h" #include @@ -26,6 +26,8 @@ #include #include +USING_YOSYS_NAMESPACE + #ifdef YOSYS_ENABLE_VERIFIC #pragma clang diagnostic push @@ -768,6 +770,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; // divide an arbitrary length decimal number by two and return the rest @@ -210,3 +212,5 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) return NULL; } +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 00deeb0b4..fdb9bb02c 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -44,13 +44,16 @@ #include "frontends/ast/ast.h" #include "parser.tab.h" +USING_YOSYS_NAMESPACE using namespace AST; using namespace VERILOG_FRONTEND; +YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { std::vector fn_stack; std::vector ln_stack; } +YOSYS_NAMESPACE_END #define SV_KEYWORD(_tok) \ if (sv_mode) return _tok; \ diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index ce7b99272..c62e761e2 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -39,9 +39,11 @@ #include "verilog_frontend.h" #include "kernel/log.h" +USING_YOSYS_NAMESPACE using namespace AST; using namespace VERILOG_FRONTEND; +YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { int port_counter; std::map port_stubs; @@ -56,6 +58,7 @@ namespace VERILOG_FRONTEND { bool default_nettype_wire; bool sv_mode; } +YOSYS_NAMESPACE_END static void append_attr(AstNode *ast, std::map *al) { @@ -89,8 +92,8 @@ static void free_attr(std::map *al) %union { std::string *string; - struct AstNode *ast; - std::map *al; + struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast; + std::map *al; bool boolean; } diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 2cfa8ca76..8efd4d7c3 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -38,6 +38,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + static std::list output_code; static std::list input_buffer; static size_t input_buffer_charp; @@ -427,3 +429,5 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m return output; } +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index cbc594e86..4466e1cb6 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -34,6 +34,7 @@ #include #include +YOSYS_NAMESPACE_BEGIN using namespace VERILOG_FRONTEND; // use the Verilog bison/flex parser to generate an AST and use AST::process() to convert it to RTLIL @@ -376,3 +377,5 @@ struct VerilogDefaults : public Pass { } } VerilogDefaults; +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 6d01a1532..dac5b3d02 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -29,12 +29,14 @@ #ifndef VERILOG_FRONTEND_H #define VERILOG_FRONTEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "frontends/ast/ast.h" #include #include #include +YOSYS_NAMESPACE_BEGIN + namespace VERILOG_FRONTEND { // this variable is set to a new AST_DESIGN node and then filled with the AST by the bison parser @@ -53,6 +55,8 @@ namespace VERILOG_FRONTEND // the pre-processor std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); +YOSYS_NAMESPACE_END + // the usual bison/flex stuff extern int frontend_verilog_yydebug; int frontend_verilog_yylex(void); diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 63dc85acc..f0545700a 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + struct Vhdl2verilogPass : public Pass { Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } virtual void help() @@ -190,3 +192,5 @@ struct Vhdl2verilogPass : public Pass { } } Vhdl2verilogPass; +YOSYS_NAMESPACE_END + diff --git a/kernel/calc.cc b/kernel/calc.cc index b3ff3cf2a..29717aad5 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -21,10 +21,11 @@ // Schneier, Bruce (1996). Applied Cryptography: Protocols, Algorithms, and Source Code in C, // Second Edition (2nd ed.). Wiley. ISBN 978-0-471-11709-4, page 244 -#include "kernel/log.h" -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "libs/bigint/BigIntegerLibrary.hh" +YOSYS_NAMESPACE_BEGIN + static void extend(RTLIL::Const &arg, int width, bool is_signed) { RTLIL::State padding = RTLIL::State::S0; @@ -592,3 +593,5 @@ RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, boo return RTLIL::const_sub(zero, arg1_ext, false, signed1, result_len); } +YOSYS_NAMESPACE_END + diff --git a/kernel/driver.cc b/kernel/driver.cc index d9ef22238..01ade7d46 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -17,9 +17,12 @@ * */ -#include +#include "kernel/yosys.h" + #include #include + +#include #include #include #include @@ -27,523 +30,7 @@ #include #include -#include -#include - -#include "kernel/yosys.h" - -bool fgetline(FILE *f, std::string &buffer) -{ - buffer = ""; - char block[4096]; - while (1) { - if (fgets(block, 4096, f) == NULL) - return false; - buffer += block; - if (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) { - while (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) - buffer.resize(buffer.size()-1); - return true; - } - } -} - -static void handle_label(std::string &command, bool &from_to_active, const std::string &run_from, const std::string &run_to) -{ - int pos = 0; - std::string label; - - while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) - pos++; - - while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') - label += command[pos++]; - - if (label.back() == ':' && SIZE(label) > 1) - { - label = label.substr(0, SIZE(label)-1); - command = command.substr(pos); - - if (label == run_from) - from_to_active = true; - else if (label == run_to || (run_from == run_to && !run_from.empty())) - from_to_active = false; - } -} - -static void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) -{ - if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") - command = "verilog"; - else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") - command = "verilog -sv"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") - command = "ilang"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") - command = "script"; - else if (filename == "-") - command = "script"; - else - log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str()); - } - - if (command == "script") - { - std::string run_from, run_to; - bool from_to_active = true; - - if (from_to_label != NULL) { - size_t pos = from_to_label->find(':'); - if (pos == std::string::npos) { - run_from = *from_to_label; - run_to = *from_to_label; - } else { - run_from = from_to_label->substr(0, pos); - run_to = from_to_label->substr(pos+1); - } - from_to_active = run_from.empty(); - } - - log("\n-- Executing script file `%s' --\n", filename.c_str()); - - FILE *f = stdin; - - if (filename != "-") - f = fopen(filename.c_str(), "r"); - - if (f == NULL) - log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); - - FILE *backup_script_file = Frontend::current_script_file; - Frontend::current_script_file = f; - - try { - std::string command; - while (fgetline(f, command)) { - while (!command.empty() && command[command.size()-1] == '\\') { - std::string next_line; - if (!fgetline(f, next_line)) - break; - command.resize(command.size()-1); - command += next_line; - } - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); - } - - if (!command.empty()) { - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); - } - } - catch (log_cmd_error_expection) { - Frontend::current_script_file = backup_script_file; - throw log_cmd_error_expection(); - } - - Frontend::current_script_file = backup_script_file; - - if (filename != "-") - fclose(f); - - if (backend_command != NULL && *backend_command == "auto") - *backend_command = ""; - - return; - } - - if (filename == "-") { - log("\n-- Parsing stdin using frontend `%s' --\n", command.c_str()); - } else { - log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str()); - } - - Frontend::frontend_call(design, NULL, filename, command); -} - -static void run_pass(std::string command, RTLIL::Design *design) -{ - log("\n-- Running pass `%s' --\n", command.c_str()); - - Pass::call(design, command); -} - -static void run_backend(std::string filename, std::string command, RTLIL::Design *design) -{ - if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") - command = "verilog"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") - command = "ilang"; - else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") - command = "blif"; - else if (filename == "-") - command = "ilang"; - else if (filename.empty()) - return; - else - log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename.c_str()); - } - - if (filename.empty()) - filename = "-"; - - if (filename == "-") { - log("\n-- Writing to stdout using backend `%s' --\n", command.c_str()); - } else { - log("\n-- Writing to `%s' using backend `%s' --\n", filename.c_str(), command.c_str()); - } - - Backend::backend_call(design, NULL, filename, command); -} - -static char *readline_cmd_generator(const char *text, int state) -{ - static std::map::iterator it; - static int len; - - if (!state) { - it = REGISTER_INTERN::pass_register.begin(); - len = strlen(text); - } - - for (; it != REGISTER_INTERN::pass_register.end(); it++) { - if (it->first.substr(0, len) == text) - return strdup((it++)->first.c_str()); - } - return NULL; -} - -static char *readline_obj_generator(const char *text, int state) -{ - static std::vector obj_names; - static size_t idx; - - if (!state) - { - idx = 0; - obj_names.clear(); - - RTLIL::Design *design = yosys_get_design(); - int len = strlen(text); - - if (design->selected_active_module.empty()) - { - for (auto &it : design->modules_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - } - else - if (design->modules_.count(design->selected_active_module) > 0) - { - RTLIL::Module *module = design->modules_.at(design->selected_active_module); - - for (auto &it : module->wires_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->memories) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->cells_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->processes) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - } - - std::sort(obj_names.begin(), obj_names.end()); - } - - if (idx < obj_names.size()) - return strdup(obj_names[idx++]); - - idx = 0; - obj_names.clear(); - return NULL; -} - -static char **readline_completion(const char *text, int start, int) -{ - if (start == 0) - return rl_completion_matches(text, readline_cmd_generator); - if (strncmp(rl_line_buffer, "read_", 5) && strncmp(rl_line_buffer, "write_", 6)) - return rl_completion_matches(text, readline_obj_generator); - return NULL; -} - -const char *create_prompt(RTLIL::Design *design, int recursion_counter) -{ - static char buffer[100]; - std::string str = "\n"; - if (recursion_counter > 1) - str += stringf("(%d) ", recursion_counter); - str += "yosys"; - if (!design->selected_active_module.empty()) - str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); - if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { - if (design->selected_active_module.empty()) - str += "*"; - else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || - design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) - str += "*"; - } - snprintf(buffer, 100, "%s> ", str.c_str()); - return buffer; -} - -static void shell(RTLIL::Design *design) -{ - static int recursion_counter = 0; - - recursion_counter++; - log_cmd_error_throw = true; - - rl_readline_name = "yosys"; - rl_attempted_completion_function = readline_completion; - rl_basic_word_break_characters = " \t\n"; - - char *command = NULL; - while ((command = readline(create_prompt(design, recursion_counter))) != NULL) - { - if (command[strspn(command, " \t\r\n")] == 0) - continue; - add_history(command); - - char *p = command + strspn(command, " \t\r\n"); - if (!strncmp(p, "exit", 4)) { - p += 4; - p += strspn(p, " \t\r\n"); - if (*p == 0) - break; - } - - try { - log_assert(design->selection_stack.size() == 1); - Pass::call(design, command); - } catch (log_cmd_error_expection) { - while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); - log_reset_stack(); - } - } - if (command == NULL) - printf("exit\n"); - - recursion_counter--; - log_cmd_error_throw = false; -} - -struct ShellPass : public Pass { - ShellPass() : Pass("shell", "enter interactive command mode") { } - virtual void help() { - log("\n"); - log(" shell\n"); - log("\n"); - log("This command enters the interactive command mode. This can be useful\n"); - log("in a script to interrupt the script at a certain point and allow for\n"); - log("interactive inspection or manual synthesis of the design at this point.\n"); - log("\n"); - log("The command prompt of the interactive shell indicates the current\n"); - log("selection (see 'help select'):\n"); - log("\n"); - log(" yosys>\n"); - log(" the entire design is selected\n"); - log("\n"); - log(" yosys*>\n"); - log(" only part of the design is selected\n"); - log("\n"); - log(" yosys [modname]>\n"); - log(" the entire module 'modname' is selected using 'select -module modname'\n"); - log("\n"); - log(" yosys [modname]*>\n"); - log(" only part of current module 'modname' is selected\n"); - log("\n"); - log("When in interactive shell, some errors (e.g. invalid command arguments)\n"); - log("do not terminate yosys but return to the command prompt.\n"); - log("\n"); - log("This command is the default action if nothing else has been specified\n"); - log("on the command line.\n"); - log("\n"); - log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - extra_args(args, 1, design, false); - shell(design); - } -} ShellPass; - -struct HistoryPass : public Pass { - HistoryPass() : Pass("history", "show last interactive commands") { } - virtual void help() { - log("\n"); - log(" history\n"); - log("\n"); - log("This command prints all commands in the shell history buffer. This are\n"); - log("all commands executed in an interactive session, but not the commands\n"); - log("from executed scripts.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - extra_args(args, 1, design, false); - for(HIST_ENTRY **list = history_list(); *list != NULL; list++) - log("%s\n", (*list)->line); - } -} HistoryPass; - -struct ScriptPass : public Pass { - ScriptPass() : Pass("script", "execute commands from script file") { } - virtual void help() { - log("\n"); - log(" script [:]\n"); - log("\n"); - log("This command executes the yosys commands in the specified file.\n"); - log("\n"); - log("The 2nd argument can be used to only execute the section of the\n"); - log("file between the specified labels. An empty from label is synonymous\n"); - log("for the beginning of the file and an empty to label is synonymous\n"); - log("for the end of the file.\n"); - log("\n"); - log("If only one label is specified (without ':') then only the block\n"); - log("marked with that label (until the next label) is executed.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - if (args.size() < 2) - log_cmd_error("Missing script file.\n"); - else if (args.size() == 2) - run_frontend(args[1], "script", design, NULL, NULL); - else if (args.size() == 3) - run_frontend(args[1], "script", design, NULL, &args[2]); - else - extra_args(args, 2, design, false); - } -} ScriptPass; - -#ifdef YOSYS_ENABLE_TCL -static Tcl_Interp *yosys_tcl_interp = NULL; - -static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[]) -{ - std::vector args; - for (int i = 1; i < argc; i++) - args.push_back(argv[i]); - - if (args.size() >= 1 && args[0] == "-import") { - for (auto &it : REGISTER_INTERN::pass_register) { - std::string tcl_command_name = it.first; - if (tcl_command_name == "proc") - tcl_command_name = "procs"; - Tcl_CmdInfo info; - if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) { - log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str()); - } else { - std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name.c_str(), it.first.c_str()); - Tcl_Eval(interp, tcl_script.c_str()); - } - } - return TCL_OK; - } - - if (args.size() == 1) { - Pass::call(yosys_get_design(), args[0]); - return TCL_OK; - } - - Pass::call(yosys_get_design(), args); - return TCL_OK; -} - -extern Tcl_Interp *yosys_get_tcl_interp() -{ - if (yosys_tcl_interp == NULL) { - yosys_tcl_interp = Tcl_CreateInterp(); - Tcl_CreateCommand(yosys_tcl_interp, "yosys", tcl_yosys_cmd, NULL, NULL); - } - return yosys_tcl_interp; -} - -struct TclPass : public Pass { - TclPass() : Pass("tcl", "execute a TCL script file") { } - virtual void help() { - log("\n"); - log(" tcl \n"); - log("\n"); - log("This command executes the tcl commands in the specified file.\n"); - log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); - log("\n"); - log("The tcl command 'yosys -import' can be used to import all yosys\n"); - log("commands directly as tcl commands to the tcl shell. The yosys\n"); - log("command 'proc' is wrapped using the tcl command 'procs' in order\n"); - log("to avoid a name collision with the tcl builting command 'proc'.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - if (args.size() < 2) - log_cmd_error("Missing script file.\n"); - if (args.size() > 2) - extra_args(args, 1, design, false); - if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK) - log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); - } -} TclPass; -#endif - -static RTLIL::Design *yosys_design = NULL; - -extern RTLIL::Design *yosys_get_design() -{ - return yosys_design; -} - -#if defined(__linux__) -std::string proc_self_dirname () -{ - char path [PATH_MAX]; - ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); - if (buflen < 0) { - log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); - log_abort(); - } - while (buflen > 0 && path[buflen-1] != '/') - buflen--; - return std::string(path, buflen); -} -#elif defined(__APPLE__) -#include -std::string proc_self_dirname () -{ - char * path = NULL; - uint32_t buflen = 0; - while (_NSGetExecutablePath(path, &buflen) != 0) - path = (char *) realloc((void *) path, buflen); - while (buflen > 0 && path[buflen-1] != '/') - buflen--; - return std::string(path, buflen); -} -#else - #error Dont know how to determine process executable base path! -#endif - -std::string proc_share_dirname () -{ - std::string proc_self_path = proc_self_dirname(); - std::string proc_share_path = proc_self_path + "share/"; - if (access(proc_share_path.c_str(), X_OK) == 0) - return proc_share_path; - proc_share_path = proc_self_path + "../share/yosys/"; - if (access(proc_share_path.c_str(), X_OK) == 0) - return proc_share_path; - log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); - log_abort(); -} +USING_YOSYS_NAMESPACE int main(int argc, char **argv) { @@ -739,11 +226,7 @@ int main(int argc, char **argv) log("\n"); } - Pass::init_register(); - - yosys_design = new RTLIL::Design; - yosys_design->selection_stack.push_back(RTLIL::Selection()); - log_push(); + yosys_setup(); if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) { if (!got_output_filename) @@ -804,7 +287,6 @@ int main(int argc, char **argv) log("\nEnd of script.\n"); if (call_abort) abort(); - log_pop(); if (!history_file.empty()) { if (history_offset > 0) { @@ -819,25 +301,11 @@ int main(int argc, char **argv) if (hist_list != NULL) free(hist_list); - for (auto f : log_files) - if (f != stderr) - fclose(f); - log_errfile = NULL; - log_files.clear(); - - Pass::done_register(); + yosys_shutdown(); for (auto mod : loaded_modules) dlclose(mod); -#ifdef YOSYS_ENABLE_TCL - if (yosys_tcl_interp != NULL) { - Tcl_DeleteInterp(yosys_tcl_interp); - Tcl_Finalize(); - yosys_tcl_interp = NULL; - } -#endif - return 0; } diff --git a/kernel/log.cc b/kernel/log.cc index 5fe0d0863..64dd7a92a 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; @@ -233,7 +235,7 @@ std::map> get_coverage_data() { std::map> coverage_data; - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { std::string key = stringf("passes.%s", it.first.c_str()); coverage_data[key].first = stringf("%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); coverage_data[key].second += it.second->call_counter; @@ -260,3 +262,5 @@ std::map> get_coverage_data() return coverage_data; } +YOSYS_NAMESPACE_END + diff --git a/kernel/log.h b/kernel/log.h index a491d067d..0109faf62 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + #define S__LINE__sub2(x) #x #define S__LINE__sub1(x) S__LINE__sub2(x) #define S__LINE__ S__LINE__sub1(__LINE__) @@ -40,8 +42,6 @@ extern bool log_time; extern bool log_cmd_error_throw; extern int log_verbose_level; -std::string stringf(const char *fmt, ...); - void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); void logv_error(const char *format, va_list ap) __attribute__ ((noreturn)); @@ -246,4 +246,6 @@ void log_dump_args_worker(const char *p, T first, Args ... args) log("\n"); \ } while (0) +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/register.cc b/kernel/register.cc index c7bd2cce7..7469b3e81 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -17,26 +17,22 @@ * */ -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include #include #include #include -using namespace REGISTER_INTERN; +YOSYS_NAMESPACE_BEGIN + #define MAX_REG_COUNT 1000 -namespace REGISTER_INTERN -{ - bool echo_mode = false; - Pass *first_queued_pass; +bool echo_mode = false; +Pass *first_queued_pass; - std::map frontend_register; - std::map pass_register; - std::map backend_register; -} +std::map frontend_register; +std::map pass_register; +std::map backend_register; std::vector Frontend::next_args; @@ -552,7 +548,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 ' for more information on a command.\n"); @@ -562,7 +558,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++) @@ -575,7 +571,7 @@ 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) { + for (auto &it : pass_register) { size_t memsize; char *memptr; FILE *memf = open_memstream(&memptr, &memsize); @@ -591,7 +587,7 @@ struct HelpPass : public Pass { // 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) { + for (auto &it : pass_register) { size_t memsize; char *memptr; FILE *memf = open_memstream(&memptr, &memsize); @@ -604,10 +600,10 @@ struct HelpPass : public Pass { } 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; } @@ -648,3 +644,5 @@ struct EchoPass : public Pass { } } EchoPass; +YOSYS_NAMESPACE_END + diff --git a/kernel/register.h b/kernel/register.h index 41780bfb9..17942ca96 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -20,12 +20,14 @@ #ifndef REGISTER_H #define REGISTER_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include #include #include #include +YOSYS_NAMESPACE_BEGIN + struct Pass { std::string pass_name, short_help; @@ -94,10 +96,10 @@ struct Backend : Pass // implemented in passes/cmds/select.cc extern void handle_extra_select_args(Pass *pass, std::vector args, size_t argidx, size_t args_size, RTLIL::Design *design); -namespace REGISTER_INTERN { - extern std::map pass_register; - extern std::map frontend_register; - extern std::map backend_register; -} +extern std::map pass_register; +extern std::map frontend_register; +extern std::map backend_register; + +YOSYS_NAMESPACE_END #endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f864d88c0..82fa7aec2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -17,16 +17,14 @@ * */ -#include "kernel/compatibility.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include "frontends/verilog/verilog_frontend.h" #include "backends/ilang/ilang_backend.h" #include #include -int RTLIL::autoidx = 1; +YOSYS_NAMESPACE_BEGIN RTLIL::Const::Const() { @@ -2736,3 +2734,5 @@ RTLIL::Process *RTLIL::Process::clone() const return new_proc; } +YOSYS_NAMESPACE_END + diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7bd75bd1d..4d8581c72 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -22,6 +22,8 @@ #ifndef RTLIL_H #define RTLIL_H +YOSYS_NAMESPACE_BEGIN + namespace RTLIL { enum State : unsigned char { @@ -50,8 +52,6 @@ namespace RTLIL CONST_FLAG_REAL = 4 // unused -- to be used for parameters }; - extern int autoidx; - struct Const; struct Selection; struct Design; @@ -123,18 +123,6 @@ namespace RTLIL return str.c_str(); } - static IdString new_id(std::string file, int line, std::string func) __attribute__((unused)); - static IdString new_id(std::string file, int line, std::string func) { - std::string str = "$auto$"; - size_t pos = file.find_last_of('/'); - str += pos != std::string::npos ? file.substr(pos+1) : file; - str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++); - return str; - } - -#define NEW_ID \ - RTLIL::new_id(__FILE__, __LINE__, __FUNCTION__) - template struct sort_by_name { bool operator()(T *a, T *b) const { return a->name < b->name; @@ -969,4 +957,6 @@ void RTLIL::Process::rewrite_sigspecs(T functor) it->rewrite_sigspecs(functor); } +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 79a9fb238..b691749a8 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -20,9 +20,9 @@ #ifndef SIGTOOLS_H #define SIGTOOLS_H -#include "kernel/rtlil.h" -#include "kernel/log.h" -#include +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN struct SigPool { @@ -398,4 +398,6 @@ struct SigMap } }; +YOSYS_NAMESPACE_END + #endif /* SIGTOOLS_H */ diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d25443826..34800ce8e 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -19,6 +19,21 @@ #include "kernel/yosys.h" +#include +#include + +#include +#include + +YOSYS_NAMESPACE_BEGIN + +int autoidx = 1; +RTLIL::Design *yosys_design = NULL; + +#ifdef YOSYS_ENABLE_TCL +Tcl_Interp *yosys_tcl_interp = NULL; +#endif + std::string stringf(const char *fmt, ...) { std::string string; @@ -38,3 +53,553 @@ std::string stringf(const char *fmt, ...) return string; } +void yosys_setup() +{ + Pass::init_register(); + + yosys_design = new RTLIL::Design; + yosys_design->selection_stack.push_back(RTLIL::Selection()); + log_push(); +} + +void yosys_shutdown() +{ + log_pop(); + + for (auto f : log_files) + if (f != stderr) + fclose(f); + log_errfile = NULL; + log_files.clear(); + + Pass::done_register(); + +#ifdef YOSYS_ENABLE_TCL + if (yosys_tcl_interp != NULL) { + Tcl_DeleteInterp(yosys_tcl_interp); + Tcl_Finalize(); + yosys_tcl_interp = NULL; + } +#endif +} + +RTLIL::IdString new_id(std::string file, int line, std::string func) +{ + std::string str = "$auto$"; + size_t pos = file.find_last_of('/'); + str += pos != std::string::npos ? file.substr(pos+1) : file; + str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++); + return str; +} + +RTLIL::Design *yosys_get_design() +{ + return yosys_design; +} + +const char *create_prompt(RTLIL::Design *design, int recursion_counter) +{ + static char buffer[100]; + std::string str = "\n"; + if (recursion_counter > 1) + str += stringf("(%d) ", recursion_counter); + str += "yosys"; + if (!design->selected_active_module.empty()) + str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); + if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { + if (design->selected_active_module.empty()) + str += "*"; + else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || + design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) + str += "*"; + } + snprintf(buffer, 100, "%s> ", str.c_str()); + return buffer; +} + +#ifdef YOSYS_ENABLE_TCL +static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[]) +{ + std::vector args; + for (int i = 1; i < argc; i++) + args.push_back(argv[i]); + + if (args.size() >= 1 && args[0] == "-import") { + for (auto &it : pass_register) { + std::string tcl_command_name = it.first; + if (tcl_command_name == "proc") + tcl_command_name = "procs"; + Tcl_CmdInfo info; + if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) { + log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str()); + } else { + std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name.c_str(), it.first.c_str()); + Tcl_Eval(interp, tcl_script.c_str()); + } + } + return TCL_OK; + } + + if (args.size() == 1) { + Pass::call(yosys_get_design(), args[0]); + return TCL_OK; + } + + Pass::call(yosys_get_design(), args); + return TCL_OK; +} + +extern Tcl_Interp *yosys_get_tcl_interp() +{ + if (yosys_tcl_interp == NULL) { + yosys_tcl_interp = Tcl_CreateInterp(); + Tcl_CreateCommand(yosys_tcl_interp, "yosys", tcl_yosys_cmd, NULL, NULL); + } + return yosys_tcl_interp; +} + +struct TclPass : public Pass { + TclPass() : Pass("tcl", "execute a TCL script file") { } + virtual void help() { + log("\n"); + log(" tcl \n"); + log("\n"); + log("This command executes the tcl commands in the specified file.\n"); + log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); + log("\n"); + log("The tcl command 'yosys -import' can be used to import all yosys\n"); + log("commands directly as tcl commands to the tcl shell. The yosys\n"); + log("command 'proc' is wrapped using the tcl command 'procs' in order\n"); + log("to avoid a name collision with the tcl builting command 'proc'.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + if (args.size() > 2) + extra_args(args, 1, design, false); + if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK) + log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); + } +} TclPass; +#endif + +#if defined(__linux__) +std::string proc_self_dirname () +{ + char path [PATH_MAX]; + ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); + if (buflen < 0) { + log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); + log_abort(); + } + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#elif defined(__APPLE__) +#include +std::string proc_self_dirname () +{ + char * path = NULL; + uint32_t buflen = 0; + while (_NSGetExecutablePath(path, &buflen) != 0) + path = (char *) realloc((void *) path, buflen); + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#else + #error Dont know how to determine process executable base path! +#endif + +std::string proc_share_dirname () +{ + std::string proc_self_path = proc_self_dirname(); + std::string proc_share_path = proc_self_path + "share/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + proc_share_path = proc_self_path + "../share/yosys/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); + log_abort(); +} + +bool fgetline(FILE *f, std::string &buffer) +{ + buffer = ""; + char block[4096]; + while (1) { + if (fgets(block, 4096, f) == NULL) + return false; + buffer += block; + if (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) { + while (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) + buffer.resize(buffer.size()-1); + return true; + } + } +} + +static void handle_label(std::string &command, bool &from_to_active, const std::string &run_from, const std::string &run_to) +{ + int pos = 0; + std::string label; + + while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) + pos++; + + while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') + label += command[pos++]; + + if (label.back() == ':' && SIZE(label) > 1) + { + label = label.substr(0, SIZE(label)-1); + command = command.substr(pos); + + if (label == run_from) + from_to_active = true; + else if (label == run_to || (run_from == run_to && !run_from.empty())) + from_to_active = false; + } +} + +void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) +{ + if (command == "auto") { + if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + command = "verilog"; + else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") + command = "verilog -sv"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + command = "ilang"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") + command = "script"; + else if (filename == "-") + command = "script"; + else + log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str()); + } + + if (command == "script") + { + std::string run_from, run_to; + bool from_to_active = true; + + if (from_to_label != NULL) { + size_t pos = from_to_label->find(':'); + if (pos == std::string::npos) { + run_from = *from_to_label; + run_to = *from_to_label; + } else { + run_from = from_to_label->substr(0, pos); + run_to = from_to_label->substr(pos+1); + } + from_to_active = run_from.empty(); + } + + log("\n-- Executing script file `%s' --\n", filename.c_str()); + + FILE *f = stdin; + + if (filename != "-") + f = fopen(filename.c_str(), "r"); + + if (f == NULL) + log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); + + FILE *backup_script_file = Frontend::current_script_file; + Frontend::current_script_file = f; + + try { + std::string command; + while (fgetline(f, command)) { + while (!command.empty() && command[command.size()-1] == '\\') { + std::string next_line; + if (!fgetline(f, next_line)) + break; + command.resize(command.size()-1); + command += next_line; + } + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + + if (!command.empty()) { + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + } + catch (log_cmd_error_expection) { + Frontend::current_script_file = backup_script_file; + throw log_cmd_error_expection(); + } + + Frontend::current_script_file = backup_script_file; + + if (filename != "-") + fclose(f); + + if (backend_command != NULL && *backend_command == "auto") + *backend_command = ""; + + return; + } + + if (filename == "-") { + log("\n-- Parsing stdin using frontend `%s' --\n", command.c_str()); + } else { + log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str()); + } + + Frontend::frontend_call(design, NULL, filename, command); +} + +void run_pass(std::string command, RTLIL::Design *design) +{ + log("\n-- Running pass `%s' --\n", command.c_str()); + + Pass::call(design, command); +} + +void run_backend(std::string filename, std::string command, RTLIL::Design *design) +{ + if (command == "auto") { + if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + command = "verilog"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + command = "ilang"; + else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") + command = "blif"; + else if (filename == "-") + command = "ilang"; + else if (filename.empty()) + return; + else + log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename.c_str()); + } + + if (filename.empty()) + filename = "-"; + + if (filename == "-") { + log("\n-- Writing to stdout using backend `%s' --\n", command.c_str()); + } else { + log("\n-- Writing to `%s' using backend `%s' --\n", filename.c_str(), command.c_str()); + } + + Backend::backend_call(design, NULL, filename, command); +} + +static char *readline_cmd_generator(const char *text, int state) +{ + static std::map::iterator it; + static int len; + + if (!state) { + it = pass_register.begin(); + len = strlen(text); + } + + for (; it != pass_register.end(); it++) { + if (it->first.substr(0, len) == text) + return strdup((it++)->first.c_str()); + } + return NULL; +} + +static char *readline_obj_generator(const char *text, int state) +{ + static std::vector obj_names; + static size_t idx; + + if (!state) + { + idx = 0; + obj_names.clear(); + + RTLIL::Design *design = yosys_get_design(); + int len = strlen(text); + + if (design->selected_active_module.empty()) + { + for (auto &it : design->modules_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + } + else + if (design->modules_.count(design->selected_active_module) > 0) + { + RTLIL::Module *module = design->modules_.at(design->selected_active_module); + + for (auto &it : module->wires_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->memories) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->cells_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->processes) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + } + + std::sort(obj_names.begin(), obj_names.end()); + } + + if (idx < obj_names.size()) + return strdup(obj_names[idx++]); + + idx = 0; + obj_names.clear(); + return NULL; +} + +static char **readline_completion(const char *text, int start, int) +{ + if (start == 0) + return rl_completion_matches(text, readline_cmd_generator); + if (strncmp(rl_line_buffer, "read_", 5) && strncmp(rl_line_buffer, "write_", 6)) + return rl_completion_matches(text, readline_obj_generator); + return NULL; +} + +void shell(RTLIL::Design *design) +{ + static int recursion_counter = 0; + + recursion_counter++; + log_cmd_error_throw = true; + + rl_readline_name = "yosys"; + rl_attempted_completion_function = readline_completion; + rl_basic_word_break_characters = " \t\n"; + + char *command = NULL; + while ((command = readline(create_prompt(design, recursion_counter))) != NULL) + { + if (command[strspn(command, " \t\r\n")] == 0) + continue; + add_history(command); + + char *p = command + strspn(command, " \t\r\n"); + if (!strncmp(p, "exit", 4)) { + p += 4; + p += strspn(p, " \t\r\n"); + if (*p == 0) + break; + } + + try { + log_assert(design->selection_stack.size() == 1); + Pass::call(design, command); + } catch (log_cmd_error_expection) { + while (design->selection_stack.size() > 1) + design->selection_stack.pop_back(); + log_reset_stack(); + } + } + if (command == NULL) + printf("exit\n"); + + recursion_counter--; + log_cmd_error_throw = false; +} + +struct ShellPass : public Pass { + ShellPass() : Pass("shell", "enter interactive command mode") { } + virtual void help() { + log("\n"); + log(" shell\n"); + log("\n"); + log("This command enters the interactive command mode. This can be useful\n"); + log("in a script to interrupt the script at a certain point and allow for\n"); + log("interactive inspection or manual synthesis of the design at this point.\n"); + log("\n"); + log("The command prompt of the interactive shell indicates the current\n"); + log("selection (see 'help select'):\n"); + log("\n"); + log(" yosys>\n"); + log(" the entire design is selected\n"); + log("\n"); + log(" yosys*>\n"); + log(" only part of the design is selected\n"); + log("\n"); + log(" yosys [modname]>\n"); + log(" the entire module 'modname' is selected using 'select -module modname'\n"); + log("\n"); + log(" yosys [modname]*>\n"); + log(" only part of current module 'modname' is selected\n"); + log("\n"); + log("When in interactive shell, some errors (e.g. invalid command arguments)\n"); + log("do not terminate yosys but return to the command prompt.\n"); + log("\n"); + log("This command is the default action if nothing else has been specified\n"); + log("on the command line.\n"); + log("\n"); + log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + extra_args(args, 1, design, false); + shell(design); + } +} ShellPass; + +struct HistoryPass : public Pass { + HistoryPass() : Pass("history", "show last interactive commands") { } + virtual void help() { + log("\n"); + log(" history\n"); + log("\n"); + log("This command prints all commands in the shell history buffer. This are\n"); + log("all commands executed in an interactive session, but not the commands\n"); + log("from executed scripts.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + extra_args(args, 1, design, false); + for(HIST_ENTRY **list = history_list(); *list != NULL; list++) + log("%s\n", (*list)->line); + } +} HistoryPass; + +struct ScriptPass : public Pass { + ScriptPass() : Pass("script", "execute commands from script file") { } + virtual void help() { + log("\n"); + log(" script [:]\n"); + log("\n"); + log("This command executes the yosys commands in the specified file.\n"); + log("\n"); + log("The 2nd argument can be used to only execute the section of the\n"); + log("file between the specified labels. An empty from label is synonymous\n"); + log("for the beginning of the file and an empty to label is synonymous\n"); + log("for the end of the file.\n"); + log("\n"); + log("If only one label is specified (without ':') then only the block\n"); + log("marked with that label (until the next label) is executed.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + else if (args.size() == 2) + run_frontend(args[1], "script", design, NULL, NULL); + else if (args.size() == 3) + run_frontend(args[1], "script", design, NULL, &args[2]); + else + extra_args(args, 2, design, false); + } +} ScriptPass; + +YOSYS_NAMESPACE_END + diff --git a/kernel/yosys.h b/kernel/yosys.h index 67629d9b1..9b36ebcc9 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -29,6 +29,9 @@ // If you want to know how to register a command with Yosys, you could read // "kernel/register.h", but it would be easier to just look at a simple // example instead. A simple one would be "passes/cmds/log.cc". +// +// This header is very boring. It just defines some general things that +// belong nowhere else and includes the interesting headers. #ifndef YOSYS_H @@ -38,20 +41,24 @@ #include #include #include +#include #include #if 0 # define YOSYS_NAMESPACE_BEGIN namespace Yosys { # define YOSYS_NAMESPACE_END } +# define YOSYS_NAMESPACE_PREFIX Yosys:: +# define USING_YOSYS_NAMESPACE using namespace Yosys; #else # define YOSYS_NAMESPACE_BEGIN # define YOSYS_NAMESPACE_END +# define YOSYS_NAMESPACE_PREFIX +# define USING_YOSYS_NAMESPACE #endif YOSYS_NAMESPACE_BEGIN std::string stringf(const char *fmt, ...); - #define SIZE(__obj) int(__obj.size()) YOSYS_NAMESPACE_END @@ -63,20 +70,35 @@ YOSYS_NAMESPACE_END YOSYS_NAMESPACE_BEGIN +void yosys_setup(); +void yosys_shutdown(); + #ifdef YOSYS_ENABLE_TCL #include -extern Tcl_Interp *yosys_get_tcl_interp(); +Tcl_Interp *yosys_get_tcl_interp(); #endif +extern int autoidx; +extern RTLIL::Design *yosys_design; + +RTLIL::IdString new_id(std::string file, int line, std::string func); + +#define NEW_ID \ + YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) + +RTLIL::Design *yosys_get_design(); +std::string proc_self_dirname(); +std::string proc_share_dirname(); +const char *create_prompt(RTLIL::Design *design, int recursion_counter); + +void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label); +void run_pass(std::string command, RTLIL::Design *design); +void run_backend(std::string filename, std::string command, RTLIL::Design *design); +void shell(RTLIL::Design *design); + // from kernel/version_*.o (cc source generated from Makefile) extern const char *yosys_version_str; -// implemented in driver.cc -extern RTLIL::Design *yosys_get_design(); -extern std::string proc_self_dirname(); -extern std::string proc_share_dirname(); -extern const char *create_prompt(RTLIL::Design *design, int recursion_counter); - // from passes/cmds/design.cc extern std::map saved_designs; extern std::vector pushed_designs; diff --git a/libs/subcircuit/subcircuit.cc b/libs/subcircuit/subcircuit.cc index da2638792..84f23d636 100644 --- a/libs/subcircuit/subcircuit.cc +++ b/libs/subcircuit/subcircuit.cc @@ -26,8 +26,8 @@ #include #ifdef _YOSYS_ -# include "kernel/log.h" -# define my_printf log +# include "kernel/yosys.h" +# define my_printf YOSYS_NAMESPACE_PREFIX log #else # define my_printf printf #endif diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index d2be7dcf1..d204e93c6 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -313,7 +313,7 @@ static void handle_loops() } std::stringstream sstr; - sstr << "$abcloop$" << (RTLIL::autoidx++); + sstr << "$abcloop$" << (autoidx++); RTLIL::Wire *wire = module->addWire(sstr.str()); bool first_line = true; @@ -400,7 +400,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str, bool keepff) { module = current_module; - map_autoidx = RTLIL::autoidx++; + map_autoidx = autoidx++; signal_map.clear(); signal_list.clear(); diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index bd1ee68f2..79695c635 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -22,6 +22,8 @@ #include "kernel/rtlil.h" #include "kernel/log.h" +YOSYS_NAMESPACE_BEGIN + std::map saved_designs; std::vector pushed_designs; @@ -249,3 +251,5 @@ struct DesignPass : public Pass { } } DesignPass; +YOSYS_NAMESPACE_END + diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 6da468321..718f779b6 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -270,7 +270,7 @@ static void extract_fsm(RTLIL::Wire *wire) // create fsm cell - RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), RTLIL::autoidx++), "$fsm"); + RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); fsm_cell->set("\\CLK", clk); fsm_cell->set("\\ARST", arst); fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); @@ -296,7 +296,7 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::Cell *cell = module->cells_.at(cellport.first); RTLIL::SigSpec port_sig = assign_map(cell->get(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); - RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++), unconn_sig.size()); + RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), autoidx++), unconn_sig.size()); port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); } } diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 40c68abc1..aecb7bd6c 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -126,7 +126,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) } std::stringstream sstr; - sstr << "$mem$" << memory->name << "$" << (RTLIL::autoidx++); + sstr << "$mem$" << memory->name << "$" << (autoidx++); RTLIL::Cell *mem = module->addCell(sstr.str(), "$mem"); mem->parameters["\\MEMID"] = RTLIL::Const(memory->name); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 325056170..6cbce781f 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -113,7 +113,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) sig.sort_and_unify(); std::stringstream sstr; - sstr << "$memory_dff_disconnected$" << (RTLIL::autoidx++); + sstr << "$memory_dff_disconnected$" << (autoidx++); RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 49291656c..0000bd507 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -41,7 +41,7 @@ static std::string genid(std::string name, std::string token1 = "", int i = -1, if (k >= 0) sstr << "[" << k << "]"; - sstr << token4 << "$" << (RTLIL::autoidx++); + sstr << token4 << "$" << (autoidx++); return sstr.str(); } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index cdf7db04b..3f675edea 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -31,7 +31,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at("\\MEMID").decode_string()); while (module->memories.count(mem_name) != 0) - mem_name += stringf("_%d", RTLIL::autoidx++); + mem_name += stringf("_%d", autoidx++); RTLIL::Memory *mem = new RTLIL::Memory; mem->name = mem_name; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 91cafe3be..d894b442b 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -122,7 +122,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S } std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; @@ -144,7 +144,7 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec bool clk_polarity, bool set_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec set, RTLIL::Process *proc) { std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.size()); RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size()); @@ -191,7 +191,7 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ bool clk_polarity, bool arst_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec *arst, RTLIL::Process *proc) { std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::Cell *cell = mod->addCell(sstr.str(), arst ? "$adff" : "$dff"); cell->attributes = proc->attributes; diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index e7661245e..b18ce4925 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -57,7 +57,7 @@ static void extract_core_signal(const RTLIL::CaseRule *cs, RTLIL::SigSpec &sig) static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SwitchRule *sw) { std::stringstream sstr; - sstr << "$procmux$" << (RTLIL::autoidx++); + sstr << "$procmux$" << (autoidx++); RTLIL::Wire *cmp_wire = mod->addWire(sstr.str() + "_CMP", 0); @@ -127,7 +127,7 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, log_assert(when_signal.size() == else_signal.size()); std::stringstream sstr; - sstr << "$procmux$" << (RTLIL::autoidx++); + sstr << "$procmux$" << (autoidx++); // the trivial cases if (compare.size() == 0 || when_signal == else_signal) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 19d323341..ed389f2fb 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -296,7 +296,7 @@ namespace SigSet> sig2port; // create new cell - RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), RTLIL::autoidx++), needle->name); + RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), autoidx++), needle->name); // create cell ports for (auto &it : needle->wires_) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 2aa59e61b..c2e5960ff 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -161,7 +161,7 @@ struct TechmapWorker for (auto &it : tpl->cells_) if (it.first == "\\_TECHMAP_REPLACE_") { orig_cell_name = cell->name; - module->rename(cell, stringf("$techmap%d", RTLIL::autoidx++) + cell->name); + module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name); break; } -- 2.30.2