From 0defc86519fb02dd366b20ccec4add09302eae98 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Feb 2014 19:17:07 +0100 Subject: renamed ilang "scope error" to "ilang error" --- frontends/ilang/parser.y | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index c2e090220..ebb4d3095 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -87,7 +87,7 @@ design: module: TOK_MODULE TOK_ID EOL { if (current_design->modules.count($2) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of module %s.", $2).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); current_module = new RTLIL::Module; current_module->name = $2; current_module->attributes = attrbuf; @@ -120,7 +120,7 @@ wire_stmt: attrbuf.clear(); } wire_options TOK_ID EOL { if (current_module->wires.count($4) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of wire %s.", $4).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); current_wire->name = $4; current_module->wires[$4] = current_wire; free($4); @@ -157,7 +157,7 @@ memory_stmt: attrbuf.clear(); } memory_options TOK_ID EOL { if (current_module->memories.count($4) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of memory %s.", $4).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of memory %s.", $4).c_str()); current_memory->name = $4; current_module->memories[$4] = current_memory; free($4); @@ -175,7 +175,7 @@ memory_options: cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { if (current_module->cells.count($3) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of cell %s.", $3).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); current_cell = new RTLIL::Cell; current_cell->type = $2; current_cell->name = $3; @@ -200,7 +200,7 @@ cell_body: } | cell_body TOK_CONNECT TOK_ID sigspec EOL { if (current_cell->connections.count($3) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of cell port %s.", $3).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); current_cell->connections[$3] = *$4; delete $4; free($3); @@ -210,7 +210,7 @@ cell_body: proc_stmt: TOK_PROCESS TOK_ID EOL { if (current_module->processes.count($2) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of process %s.", $2).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of process %s.", $2).c_str()); current_process = new RTLIL::Process; current_process->name = $2; current_process->attributes = attrbuf; @@ -362,7 +362,7 @@ sigspec: } | TOK_ID { if (current_module->wires.count($1) == 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: wire %s not found", $1).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); RTLIL::SigChunk chunk; chunk.wire = current_module->wires[$1]; chunk.width = current_module->wires[$1]->width; @@ -374,7 +374,7 @@ sigspec: } | TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: wire %s not found", $1).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); RTLIL::SigChunk chunk; chunk.wire = current_module->wires[$1]; chunk.offset = $3; @@ -386,7 +386,7 @@ sigspec: } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: wire %s not found", $1).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); RTLIL::SigChunk chunk; chunk.wire = current_module->wires[$1]; chunk.width = $3 - $5 + 1; -- cgit v1.2.3 From 007bdff55d69e6e29091c7beff19c36eeb7ed078 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 23:29:54 +0100 Subject: Added support for functions returning integer --- frontends/verilog/parser.y | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 5b6bf58c2..8080729b0 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -106,7 +106,7 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT -%type wire_type range non_opt_range expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -360,6 +360,16 @@ range: $$ = NULL; }; +range_or_integer: + range { + $$ = $1; + } | + TOK_INTEGER { + $$ = new AstNode(AST_RANGE); + $$->children.push_back(AstNode::mkconst_int(31, true)); + $$->children.push_back(AstNode::mkconst_int(0, true)); + }; + module_body: module_body module_body_stmt | /* empty */; @@ -380,7 +390,7 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range TOK_ID ';' { + TOK_FUNCTION opt_signed range_or_integer TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$4; ast_stack.back()->children.push_back(current_function_or_task); -- cgit v1.2.3 From cd9e8741a71502c303c6f25d02bb2259a7dd7ff3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 13:59:13 +0100 Subject: Implemented read_verilog -defer --- frontends/ast/ast.cc | 135 ++++++++++++++++++++-------------- frontends/ast/ast.h | 2 +- frontends/verilog/verilog_frontend.cc | 12 ++- 3 files changed, 90 insertions(+), 59 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 96608ae37..ab2972b2c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -747,14 +747,18 @@ bool AstNode::asBool() } // create a new AstModule from an AST_MODULE AST node -static AstModule* process_module(AstNode *ast) +static AstModule* process_module(AstNode *ast, bool defer) { assert(ast->type == AST_MODULE); - log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str()); + + if (defer) + log("Storing AST representation for module `%s'.\n", ast->str.c_str()); + else + log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str()); current_module = new AstModule; current_module->ast = NULL; - current_module->name = ast->str; + current_module->name = defer ? "$abstract" + ast->str : ast->str; current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); current_ast_mod = ast; @@ -766,60 +770,63 @@ static AstModule* process_module(AstNode *ast) log("--- END OF AST DUMP ---\n"); } - while (ast->simplify(!flag_noopt, false, false, 0, -1, false)) { } + if (!defer) + { + while (ast->simplify(!flag_noopt, false, false, 0, -1, false)) { } - if (flag_dump_ast2) { - log("Dumping verilog AST after simplification:\n"); - ast->dumpAst(NULL, " "); - log("--- END OF AST DUMP ---\n"); - } + if (flag_dump_ast2) { + log("Dumping verilog AST after simplification:\n"); + ast->dumpAst(NULL, " "); + log("--- END OF AST DUMP ---\n"); + } - if (flag_dump_vlog) { - log("Dumping verilog AST (as requested by dump_vlog option):\n"); - ast->dumpVlog(NULL, " "); - log("--- END OF AST DUMP ---\n"); - } + if (flag_dump_vlog) { + log("Dumping verilog AST (as requested by dump_vlog option):\n"); + ast->dumpVlog(NULL, " "); + log("--- END OF AST DUMP ---\n"); + } - if (flag_lib) { - std::vector new_children; - for (auto child : ast->children) { - if (child->type == AST_WIRE && (child->is_input || child->is_output)) - new_children.push_back(child); - else - delete child; + if (flag_lib) { + std::vector new_children; + for (auto child : ast->children) { + if (child->type == AST_WIRE && (child->is_input || child->is_output)) + new_children.push_back(child); + else + delete child; + } + ast->children.swap(new_children); + ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); } - ast->children.swap(new_children); - ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); - } - ignoreThisSignalsInInitial = RTLIL::SigSpec(); + ignoreThisSignalsInInitial = RTLIL::SigSpec(); - for (auto &attr : ast->attributes) { - if (attr.second->type != AST_CONSTANT) - log_error("Attribute `%s' with non-constant value at %s:%d!\n", - attr.first.c_str(), ast->filename.c_str(), ast->linenum); - current_module->attributes[attr.first] = attr.second->asAttrConst(); - } - for (size_t i = 0; i < ast->children.size(); i++) { - AstNode *node = ast->children[i]; - if (node->type == AST_WIRE || node->type == AST_MEMORY) - node->genRTLIL(); - } - for (size_t i = 0; i < ast->children.size(); i++) { - AstNode *node = ast->children[i]; - if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL) - node->genRTLIL(); - } + for (auto &attr : ast->attributes) { + if (attr.second->type != AST_CONSTANT) + log_error("Attribute `%s' with non-constant value at %s:%d!\n", + attr.first.c_str(), ast->filename.c_str(), ast->linenum); + current_module->attributes[attr.first] = attr.second->asAttrConst(); + } + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type == AST_WIRE || node->type == AST_MEMORY) + node->genRTLIL(); + } + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL) + node->genRTLIL(); + } - ignoreThisSignalsInInitial.sort_and_unify(); + ignoreThisSignalsInInitial.sort_and_unify(); - for (size_t i = 0; i < ast->children.size(); i++) { - AstNode *node = ast->children[i]; - if (node->type == AST_INITIAL) - node->genRTLIL(); - } + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type == AST_INITIAL) + node->genRTLIL(); + } - ignoreThisSignalsInInitial = RTLIL::SigSpec(); + ignoreThisSignalsInInitial = RTLIL::SigSpec(); + } current_module->ast = ast_before_simplify; current_module->nolatches = flag_nolatches; @@ -832,7 +839,7 @@ static AstModule* process_module(AstNode *ast) } // create AstModule instances for all modules in the AST tree and add them to 'design' -void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef) +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer) { current_ast = ast; flag_dump_ast1 = dump_ast1; @@ -847,7 +854,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { - if (design->modules.count((*it)->str) != 0) { + if (design->modules.count((*it)->str) != 0 && design->modules.count("$abstract" + (*it)->str) != 0) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -855,7 +862,10 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - design->modules[(*it)->str] = process_module(*it); + if (defer) + design->modules["$abstract" + (*it)->str] = process_module(*it, true); + else + design->modules[(*it)->str] = process_module(*it, false); } } @@ -869,7 +879,12 @@ AstModule::~AstModule() // create a new parametric module (when needed) and return the name of the generated module RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map parameters) { - log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", name.c_str()); + std::string stripped_name = name; + + if (stripped_name.substr(0, 9) == "$abstract") + stripped_name = stripped_name.substr(9); + + log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); current_ast = NULL; flag_dump_ast1 = false; @@ -885,12 +900,13 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map hash_data; - hash_data.insert(hash_data.end(), name.begin(), name.end()); + hash_data.insert(hash_data.end(), stripped_name.begin(), stripped_name.end()); hash_data.push_back(0); AstNode *new_ast = ast->clone(); int para_counter = 0; + int orig_parameters_n = parameters.size(); for (auto it = new_ast->children.begin(); it != new_ast->children.end(); it++) { AstNode *child = *it; if (child->type != AST_PARAMETER) @@ -917,10 +933,15 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map 0) - log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), name.c_str()); + log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), stripped_name.c_str()); std::string modname; + if (orig_parameters_n == 0) + { + modname = stripped_name; + } + else if (para_info.size() > 60) { unsigned char hash[20]; @@ -933,16 +954,16 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapmodules.count(modname) == 0) { new_ast->str = modname; - design->modules[modname] = process_module(new_ast); + design->modules[modname] = process_module(new_ast, false); design->modules[modname]->check(); } else { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 01702c3cf..8335db096 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -232,7 +232,7 @@ namespace AST }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code - void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1 = false, bool dump_ast2 = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false, bool noopt = false, bool icells = false, bool ignore_redef = false); + void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1 = false, bool dump_ast2 = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false, bool noopt = false, bool icells = false, bool ignore_redef = false, bool defer = true); // parametric modules are supported directly by the AST library // therfore we need our own derivate of RTLIL::Module with overloaded virtual functions diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index c70d6f305..d46dfa6e2 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -106,6 +106,11 @@ struct VerilogFrontend : public Frontend { log(" ignore re-definitions of modules. (the default behavior is to\n"); log(" create an error message.)\n"); log("\n"); + log(" -defer\n"); + log(" only read the abstract syntax tree and defer actual compilation\n"); + log(" to a later 'hierarchy' command. Useful in cases where the default\n"); + log(" parameters of modules yield invalid or not synthesizable code.\n"); + log("\n"); log(" -setattr \n"); log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); @@ -135,6 +140,7 @@ struct VerilogFrontend : public Frontend { bool flag_noopt = false; bool flag_icells = false; bool flag_ignore_redef = false; + bool flag_defer = false; std::map defines_map; std::list include_dirs; std::list attributes; @@ -199,6 +205,10 @@ struct VerilogFrontend : public Frontend { flag_ignore_redef = true; continue; } + if (arg == "-defer") { + flag_defer = true; + continue; + } if (arg == "-setattr" && argidx+1 < args.size()) { attributes.push_back(RTLIL::escape_id(args[++argidx])); continue; @@ -264,7 +274,7 @@ struct VerilogFrontend : public Frontend { child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } - AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef); + AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer); if (!flag_nopp) fclose(fp); -- cgit v1.2.3 From 534c1a5dd009b41629d2d05acfde747ce6fbc19c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 19:56:44 +0100 Subject: Created basic support for function calls in parameter values --- frontends/ast/ast.cc | 2 +- frontends/ast/ast.h | 7 +- frontends/ast/genrtlil.cc | 12 +-- frontends/ast/simplify.cc | 212 +++++++++++++++++++++++++++++++++++++--------- 4 files changed, 184 insertions(+), 49 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index ab2972b2c..7e199cd5c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -772,7 +772,7 @@ static AstModule* process_module(AstNode *ast, bool defer) if (!defer) { - while (ast->simplify(!flag_noopt, false, false, 0, -1, false)) { } + while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { } if (flag_dump_ast2) { log("Dumping verilog AST after simplification:\n"); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8335db096..ec4f4f62b 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -190,7 +190,7 @@ namespace AST // simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc. // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() - bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint); + bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); void expand_genblock(std::string index_var, std::string prefix, std::map &name_map); void replace_ids(std::map &rules); void mem2reg_as_needed_pass1(std::map> &mem2reg_places, @@ -198,6 +198,11 @@ namespace AST void mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode *mod, AstNode *block); void meminfo(int &mem_width, int &mem_size, int &addr_bits); + // additional functionality for evaluating constant functions + struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; + void replace_variables(std::map &variables, AstNode *fcall); + AstNode *eval_const_function(AstNode *fcall); + // create a human-readable text representation of the AST (for debugging) void dumpAst(FILE *f, std::string indent); void dumpVlog(FILE *f, std::string indent); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 591d027cb..d92da4000 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -648,8 +648,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) else if (!range->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } + while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); @@ -665,7 +665,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_TO_BITS: - while (children[0]->simplify(true, false, false, 1, -1, false) == true) { } + while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } if (children[0]->type != AST_CONSTANT) log_error("Left operand of tobits expression is not constant at %s:%d!\n", filename.c_str(), linenum); children[1]->detectSignWidthWorker(sub_width_hint, sign_hint); @@ -693,7 +693,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_REPLICATE: - while (children[0]->simplify(true, false, false, 1, -1, false) == true) { } + while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } if (children[0]->type != AST_CONSTANT) log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum); children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint); @@ -961,8 +961,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } + while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b51079ce5..85dc1d3c2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -43,7 +43,7 @@ using namespace AST_INTERNAL; // // this function also does all name resolving and sets the id2ast member of all // nodes that link to a different node using names and lexical scoping. -bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint) +bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param) { AstNode *newNode = NULL; bool did_something = false; @@ -52,7 +52,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { assert(type == AST_MODULE); - while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint)) { } + while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { } if (!flag_nomem2reg && !get_bool_attribute("\\nomem2reg")) { @@ -114,7 +114,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, reg->is_reg = true; reg->is_signed = node->is_signed; children.push_back(reg); - while (reg->simplify(true, false, false, 1, -1, false)) { } + while (reg->simplify(true, false, false, 1, -1, false, false)) { } } } @@ -128,7 +128,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } - while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint)) { } + while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { } return false; } @@ -148,7 +148,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.) if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX) - const_fold = true; + const_fold = true, in_param = true; if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) const_fold = true; @@ -215,7 +215,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE) - while (node->simplify(true, false, false, 1, -1, false)) { } + while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) { } } } @@ -237,8 +237,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_ASSIGN_EQ: case AST_ASSIGN_LE: case AST_ASSIGN: - while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false) == true) { } - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) { } + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) { } children[0]->detectSignWidth(backup_width_hint, backup_sign_hint); children[1]->detectSignWidth(width_hint, sign_hint); width_hint = std::max(width_hint, backup_width_hint); @@ -247,11 +247,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_PARAMETER: case AST_LOCALPARAM: - while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) { } children[0]->detectSignWidth(width_hint, sign_hint); if (children.size() > 1) { assert(children[1]->type == AST_RANGE); - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false) == true) { } + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) { } if (!children[1]->range_valid) log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); width_hint = std::max(width_hint, children[1]->range_left - children[1]->range_right + 1); @@ -307,7 +307,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint = -1; sign_hint = true; for (auto child : children) { - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } child->detectSignWidthWorker(width_hint, sign_hint); } reset_width_after_children = true; @@ -337,9 +337,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (detect_width_simple && width_hint < 0) { for (auto child : children) - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } if (type == AST_REPLICATE) - while (children[0]->simplify(true, false, in_lvalue, stage, -1, false) == true) { } + while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) { } detectSignWidth(width_hint, sign_hint); } @@ -379,13 +379,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint_here = -1, sign_hint_here = false; if (children_are_self_determined) width_hint_here = -1, sign_hint_here = false; - did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here); + did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param); if (did_something_here) did_something = true; } } for (auto &attr : attributes) { - while (attr.second->simplify(true, false, false, stage, -1, false)) { } + while (attr.second->simplify(true, false, false, stage, -1, false, true)) { } } if (reset_width_after_children) { @@ -556,7 +556,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (current_block) wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false); current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false)) { } + while (wire->simplify(true, false, false, 1, -1, false, false)) { } AstNode *data = clone(); delete data->children[1]; @@ -621,7 +621,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // eval 1st expression AstNode *varbuf = init_ast->children[1]->clone(); - while (varbuf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (varbuf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (varbuf->type != AST_CONSTANT) log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); @@ -643,7 +643,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { // eval 2nd expression AstNode *buf = while_ast->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); @@ -672,7 +672,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENFOR) { for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } } else { @@ -684,7 +684,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // eval 3rd expression buf = next_ast->children[1]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); @@ -708,7 +708,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::vector new_children; for (size_t i = 0; i < children.size(); i++) if (children[i]->type == AST_WIRE) { - children[i]->simplify(false, false, false, stage, -1, false); + children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); } else new_children.push_back(children[i]); @@ -727,7 +727,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < children.size(); i++) { - children[i]->simplify(false, false, false, stage, -1, false); + children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); } @@ -739,7 +739,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENIF && children.size() != 0) { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -764,7 +764,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -780,7 +780,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENCASE && children.size() != 0) { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -814,7 +814,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, continue; buf = child->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -840,7 +840,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -955,8 +955,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, shift_expr = range->children[1]->clone(); AstNode *left_at_zero_ast = range->children[0]->clone(); AstNode *right_at_zero_ast = range->children[1]->clone(); - while (left_at_zero_ast->simplify(true, true, false, stage, -1, false)) { } - while (right_at_zero_ast->simplify(true, true, false, stage, -1, false)) { } + while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); @@ -988,7 +988,7 @@ skip_dynamic_range_lvalue_expansion:; wire_check->str = id_check; current_ast_mod->children.push_back(wire_check); current_scope[wire_check->str] = wire_check; - while (wire_check->simplify(true, false, false, 1, -1, false)) { } + while (wire_check->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_en = new AstNode(AST_WIRE); wire_en->str = id_en; @@ -996,7 +996,7 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(0, false, 1))))); current_ast_mod->children.back()->children[0]->children[0]->children[0]->str = id_en; current_scope[wire_en->str] = wire_en; - while (wire_en->simplify(true, false, false, 1, -1, false)) { } + while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } std::vector x_bit; x_bit.push_back(RTLIL::State::Sx); @@ -1070,19 +1070,19 @@ skip_dynamic_range_lvalue_expansion:; wire_addr->str = id_addr; current_ast_mod->children.push_back(wire_addr); current_scope[wire_addr->str] = wire_addr; - while (wire_addr->simplify(true, false, false, 1, -1, false)) { } + while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; current_ast_mod->children.push_back(wire_data); current_scope[wire_data->str] = wire_data; - while (wire_data->simplify(true, false, false, 1, -1, false)) { } + while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_en = new AstNode(AST_WIRE); wire_en->str = id_en; current_ast_mod->children.push_back(wire_en); current_scope[wire_en->str] = wire_en; - while (wire_en->simplify(true, false, false, 1, -1, false)) { } + while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } std::vector x_bits; for (int i = 0; i < mem_width; i++) @@ -1138,7 +1138,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$clog2") { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); @@ -1160,6 +1160,23 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } + if (in_param) + { + bool all_args_const = true; + for (auto child : children) + if (child->type != AST_CONSTANT) + all_args_const = false; + + if (all_args_const) { + AstNode *func_workspace = current_scope[str]->clone(); + newNode = func_workspace->eval_const_function(this); + delete func_workspace; + goto apply_newNode; + } + + log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); + } + AstNode *decl = current_scope[str]; std::stringstream sstr; sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++) << "$"; @@ -1184,7 +1201,7 @@ skip_dynamic_range_lvalue_expansion:; wire->is_output = false; current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false)) { } + while (wire->simplify(true, false, false, 1, -1, false, false)) { } AstNode *lvalue = new AstNode(AST_IDENTIFIER); lvalue->str = wire->str; @@ -1206,7 +1223,7 @@ skip_dynamic_range_lvalue_expansion:; wire->is_input = false; wire->is_output = false; current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false)) { } + while (wire->simplify(true, false, false, 1, -1, false, false)) { } replace_rules[child->str] = wire->str; @@ -1628,14 +1645,14 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * wire_addr->is_reg = true; wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_addr); - while (wire_addr->simplify(true, false, false, 1, -1, false)) { } + while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; wire_data->is_reg = true; wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_data); - while (wire_data->simplify(true, false, false, 1, -1, false)) { } + while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } assert(block != NULL); size_t assign_idx = 0; @@ -1694,7 +1711,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * if (block) wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_addr); - while (wire_addr->simplify(true, false, false, 1, -1, false)) { } + while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; @@ -1702,7 +1719,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * if (block) wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_data); - while (wire_data->simplify(true, false, false, 1, -1, false)) { } + while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; @@ -1779,3 +1796,116 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) addr_bits++; } +// helper function for AstNode::eval_const_function() +void AstNode::replace_variables(std::map &variables, AstNode *fcall) +{ + if (type == AST_IDENTIFIER && variables.count(str)) { + int offset = variables.at(str).offset, width = variables.at(str).val.bits.size(); + if (!children.empty()) { + while (simplify(true, false, false, 1, -1, false, true)) { } + if (!range_valid) + log_error("Non-constant range in %s:%d (called from %s:%d).\n", + filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); + offset = std::min(range_left, range_right); + width = std::min(std::abs(range_left - range_right) + 1, width); + } + offset -= variables.at(str).offset; + std::vector &var_bits = variables.at(str).val.bits; + std::vector new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width); + AstNode *newNode = mkconst_bits(new_bits, variables.at(str).is_signed); + newNode->cloneInto(this); + delete newNode; + return; + } + + for (auto &child : children) + child->replace_variables(variables, fcall); +} + +// evaluate functions with all-const arguments +AstNode *AstNode::eval_const_function(AstNode *fcall) +{ + std::map backup_scope; + std::map variables; + AstNode *block = NULL; + + size_t argidx = 0; + for (auto child : children) + { + if (child->type == AST_BLOCK) + { + log_assert(block == NULL); + block = child; + continue; + } + + if (child->type == AST_WIRE) + { + while (child->simplify(true, false, false, 1, -1, false, true)) { } + if (!child->range_valid) + log_error("Can't determine size of variable %s in %s:%d (called from %s:%d).\n", + child->str.c_str(), child->filename.c_str(), child->linenum, fcall->filename.c_str(), fcall->linenum); + variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1); + variables[child->str].offset = std::min(child->range_left, child->range_right); + variables[child->str].is_signed = child->is_signed; + if (child->is_input && argidx < fcall->children.size()) + variables[child->str].val = fcall->children.at(argidx++)->bitsAsConst(variables[child->str].val.bits.size()); + backup_scope[child->str] = current_scope[child->str]; + current_scope[child->str] = child; + continue; + } + + log_abort(); + } + + log_assert(block != NULL); + log_assert(variables.count(str)); + + while (!block->children.empty()) + { + AstNode *stmt = block->children.front(); + +#if 0 + log("-----------------------------------\n"); + for (auto &it : variables) + log("%20s %40s\n", it.first.c_str(), log_signal(it.second.val)); + stmt->dumpAst(NULL, "stmt> "); +#endif + + if (stmt->type == AST_ASSIGN_EQ) + { + stmt->children.at(1)->replace_variables(variables, fcall); + while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + + if (stmt->children.at(1)->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + if (stmt->children.at(0)->type != AST_IDENTIFIER || !stmt->children.at(0)->children.empty()) + log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + if (!variables.count(stmt->children.at(0)->str)) + log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + + block->children.erase(block->children.begin()); + continue; + } + + log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + log_abort(); + } + + for (auto &it : backup_scope) + if (it.second == NULL) + current_scope.erase(it.first); + else + current_scope[it.first] = it.second; + + return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed); +} + -- cgit v1.2.3 From e8af3def7fbefa1608e72609e1c534091fc7c88e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 20:33:22 +0100 Subject: Added support for FOR loops in function calls in parameters --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7e199cd5c..56e9393b7 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -136,6 +136,7 @@ std::string AST::type2str(AstNodeType type) X(AST_COND) X(AST_DEFAULT) X(AST_FOR) + X(AST_WHILE) X(AST_GENVAR) X(AST_GENFOR) X(AST_GENIF) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index ec4f4f62b..f42bc35fb 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -116,6 +116,7 @@ namespace AST AST_COND, AST_DEFAULT, AST_FOR, + AST_WHILE, AST_GENVAR, AST_GENFOR, diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 85dc1d3c2..236843d5d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1891,10 +1891,51 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + delete block->children.front(); block->children.erase(block->children.begin()); continue; } + if (stmt->type == AST_FOR) + { + block->children.insert(block->children.begin(), stmt->children.at(0)); + stmt->children.at(3)->children.push_back(stmt->children.at(2)); + stmt->children.erase(stmt->children.begin() + 2); + stmt->children.erase(stmt->children.begin()); + stmt->type = AST_WHILE; + continue; + } + + if (stmt->type == AST_WHILE) + { + AstNode *cond = stmt->children.at(0)->clone(); + cond->replace_variables(variables, fcall); + while (cond->simplify(true, false, false, 1, -1, false, true)) { } + + if (cond->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + if (cond->asBool()) { + block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); + } else { + delete block->children.front(); + block->children.erase(block->children.begin()); + } + + delete cond; + continue; + } + + if (stmt->type == AST_BLOCK) + { + block->children.erase(block->children.begin()); + block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end()); + stmt->children.clear(); + delete stmt; + continue; + } + log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); log_abort(); -- cgit v1.2.3 From 45d2b6ffce24c3a4254ef7f80f300cc7840fec25 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 20:45:30 +0100 Subject: Be more conservative with new const-function code --- frontends/ast/simplify.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 236843d5d..2ae3cae08 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -148,10 +148,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.) if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX) - const_fold = true, in_param = true; + const_fold = true; if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) const_fold = true; + // in certain cases a function must be evaluated constant. this is what in_param controls. + if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_PREFIX) + in_param = true; + std::map backup_scope; // create name resolution entries for all objects with names -- cgit v1.2.3 From 4440610d3ffc5426c38e5cf8fccd757203c11a0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 12:57:28 +0100 Subject: Added liberty frontend --- frontends/liberty/Makefile.inc | 3 + frontends/liberty/liberty.cc | 359 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 362 insertions(+) create mode 100644 frontends/liberty/Makefile.inc create mode 100644 frontends/liberty/liberty.cc (limited to 'frontends') diff --git a/frontends/liberty/Makefile.inc b/frontends/liberty/Makefile.inc new file mode 100644 index 000000000..a02ef5e45 --- /dev/null +++ b/frontends/liberty/Makefile.inc @@ -0,0 +1,3 @@ + +OBJS += frontends/liberty/liberty.o + diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc new file mode 100644 index 000000000..220f32f5e --- /dev/null +++ b/frontends/liberty/liberty.cc @@ -0,0 +1,359 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "passes/techmap/libparse.h" +#include "kernel/register.h" +#include "kernel/log.h" + +using namespace PASS_DFFLIBMAP; + +struct token_t { + char type; + RTLIL::SigSpec sig; + token_t (char t) : type(t) { } + token_t (char t, RTLIL::SigSpec s) : type(t), sig(s) { } +}; + +static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&expr) +{ + log_assert(*expr != 0); + + int id_len = 0; + while (('a' <= expr[id_len] && expr[id_len] <= 'z') || ('A' <= expr[id_len] && expr[id_len] <= 'Z') || + ('0' <= expr[id_len] && expr[id_len] <= '9') || expr[id_len] == '.' || expr[id_len] == '_') id_len++; + + if (id_len == 0) + log_error("Expected identifier at `%s'.\n", expr); + + if (id_len == 1 && (*expr == '0' || *expr == '1')) + return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1; + + std::string id = RTLIL::escape_id(std::string(expr, id_len)); + if (!module->wires.count(id)) + log_error("Can't resolve wire name %s.\n", RTLIL::id2cstr(id)); + + expr += id_len; + return module->wires.at(id); +} + +static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_INV_"; + cell->connections["\\A"] = A; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_XOR_"; + cell->connections["\\A"] = A; + cell->connections["\\B"] = B; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_AND_"; + cell->connections["\\A"] = A; + cell->connections["\\B"] = B; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_OR_"; + cell->connections["\\A"] = A; + cell->connections["\\B"] = B; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) +{ + int top = int(stack.size())-1; + + if (0 <= top-1 && stack[top].type == 0 && stack[top-1].type == '!') { + token_t t = token_t(0, create_inv_cell(module, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top-1 && stack[top].type == '\'' && stack[top-1].type == 0) { + token_t t = token_t(0, create_inv_cell(module, stack[top-1].sig)); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top && stack[top].type == 0) { + if (next_token.type == '\'') + return false; + stack[top].type = 1; + return true; + } + + if (0 <= top-2 && stack[top-2].type == 1 && stack[top-1].type == '^' && stack[top].type == 1) { + token_t t = token_t(1, create_xor_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top && stack[top].type == 1) { + if (next_token.type == '^') + return false; + stack[top].type = 2; + return true; + } + + if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) { + token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top-2 && stack[top-2].type == 2 && (stack[top-1].type == '*' || stack[top-1].type == '&') && stack[top].type == 2) { + token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top && stack[top].type == 2) { + if (next_token.type == '*' || next_token.type == '&' || next_token.type == 0) + return false; + stack[top].type = 3; + return true; + } + + if (0 <= top-2 && stack[top-2].type == 3 && (stack[top-1].type == '+' || stack[top-1].type == '|') && stack[top].type == 3) { + token_t t = token_t(3, create_or_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top-2 && stack[top-2].type == '(' && stack[top-1].type == 3 && stack[top].type == ')') { + token_t t = token_t(0, stack[top-1].sig); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + return false; +} + +static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) +{ + const char *orig_expr = expr; + std::vector stack; + + while (*expr) + { + if (*expr == ' ' || *expr == '\t' || *expr == '\r' || *expr == '\n' || *expr == '"') { + expr++; + continue; + } + + token_t next_token(0); + if (*expr == '(' || *expr == ')' || *expr == '\'' || *expr == '!' || *expr == '^' || *expr == '*' || *expr == '+' || *expr == '|') + next_token = token_t(*(expr++)); + else + next_token = token_t(0, parse_func_identifier(module, expr)); + + while (parse_func_reduce(module, stack, next_token)) {} + stack.push_back(next_token); + } + + while (parse_func_reduce(module, stack, token_t('.'))) {} + +#if 0 + for (size_t i = 0; i < stack.size(); i++) + if (stack[i].type < 16) + log("%3d: %d %s\n", int(i), stack[i].type, log_signal(stack[i].sig)); + else + log("%3d: %c\n", int(i), stack[i].type); +#endif + + if (stack.size() != 1 || stack.back().type != 3) + log_error("Parser error in function expr `%s'.\n", orig_expr); + + return stack.back().sig; +} + +struct LibertyFrontend : public Frontend { + LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" read_liberty [filename]\n"); + log("\n"); + log("Read cells from liberty file as modules into current design.\n"); + log("\n"); + log(" -lib\n"); + log(" only create empty blackbox modules\n"); + log("\n"); + log(" -ignore_redef\n"); + log(" ignore re-definitions of modules. (the default behavior is to\n"); + log(" create an error message.)\n"); + log("\n"); + log(" -setattr \n"); + log(" set the specified attribute (to the value 1) on all loaded modules\n"); + log("\n"); + } + virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + { + bool flag_lib = false; + bool flag_ignore_redef = false; + std::vector attributes; + + log_header("Executing Liberty frontend.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + std::string arg = args[argidx]; + if (arg == "-lib") { + flag_lib = true; + continue; + } + if (arg == "-ignore_redef") { + flag_ignore_redef = true; + continue; + } + if (arg == "-setattr" && argidx+1 < args.size()) { + attributes.push_back(RTLIL::escape_id(args[++argidx])); + continue; + } + break; + } + extra_args(f, filename, args, argidx); + + LibertyParser parser(f); + int cell_count = 0; + + for (auto cell : parser.ast->children) + { + if (cell->id != "cell" || cell->args.size() != 1) + continue; + + std::string cell_name = RTLIL::escape_id(cell->args.at(0)); + + if (design->modules.count(cell_name)) { + if (flag_ignore_redef) + continue; + log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); + } + + if (!flag_lib) + { + LibertyAst *ff = cell->find("ff"); + if (ff != NULL) { + log("Warning: skipping flip-flop cell %s.\n", RTLIL::id2cstr(cell_name)); + continue; + } + + LibertyAst *latch = cell->find("latch"); + if (latch != NULL) { + log("Warning: skipping latch cell %s.\n", RTLIL::id2cstr(cell_name)); + continue; + } + } + + // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); + cell_count++; + + RTLIL::Module *module = new RTLIL::Module; + module->name = cell_name; + design->modules[module->name] = module; + + for (auto &attr : attributes) + module->attributes[attr] = 1; + + for (auto pin : cell->children) + { + if (pin->id != "pin" || pin->args.size() != 1) + continue; + + LibertyAst *dir = pin->find("direction"); + if (dir == NULL || dir->value == "internal") + continue; + + log_assert(dir->value == "input" || dir->value == "output"); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(pin->args.at(0)); + module->add(wire); + + if (dir->value == "input") { + wire->port_input = true; + continue; + } + + wire->port_output = true; + + if (flag_lib) + continue; + + LibertyAst *func = pin->find("function"); + if (func == NULL) + log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + + RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); + module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + + continue; + } + + module->fixup_ports(); + } + + log("Imported %d cell types from liberty file.\n", cell_count); + } +} LibertyFrontend; + -- cgit v1.2.3 From 5e39e6ece28e1145a04e8f00f9ac4f5d9a738acf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 15:42:10 +0100 Subject: Correctly convert constants to RTLIL (fixed undef handling) --- frontends/ast/genrtlil.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index d92da4000..12fe23fd8 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -905,18 +905,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (width_hint < 0) detectSignWidth(width_hint, sign_hint); - RTLIL::SigChunk chunk; - chunk.wire = NULL; - chunk.data.bits = bits; - chunk.width = bits.size(); - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; - is_signed = sign_hint; - return sig; + return RTLIL::SigSpec(bitsAsConst(width_hint, sign_hint)); } // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node -- cgit v1.2.3 From 96b1ebc8dc337b5412ebce91a7cecb84264b474a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 19:36:09 +0100 Subject: Bugfix in expression parser of read_liberty --- frontends/liberty/liberty.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 220f32f5e..ca899cb95 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -143,8 +143,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack } if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) { - token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig)); - stack.pop_back(); + token_t t = token_t(2, create_and_cell(module, stack[top-1].sig, stack[top].sig)); stack.pop_back(); stack.pop_back(); stack.push_back(t); -- cgit v1.2.3 From 118517ca5ae12d2793b1b5d1127f7fe3603d9fed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 19:36:33 +0100 Subject: Added ff and latch support to read_liberty --- frontends/liberty/liberty.cc | 294 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 254 insertions(+), 40 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index ca899cb95..485d28ee1 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -160,7 +160,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack } if (0 <= top && stack[top].type == 2) { - if (next_token.type == '*' || next_token.type == '&' || next_token.type == 0) + if (next_token.type == '*' || next_token.type == '&' || next_token.type == 0 || next_token.type == '(') return false; stack[top].type = 3; return true; @@ -225,6 +225,223 @@ static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) return stack.back().sig; } +static void create_ff(RTLIL::Module *module, LibertyAst *node) +{ + RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + + RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig; + bool clk_polarity = true, clear_polarity = true, preset_polarity = true; + + for (auto child : node->children) { + if (child->id == "clocked_on") + clk_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "next_state") + data_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "clear") + clear_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "preset") + preset_sig = parse_func_expr(module, child->value.c_str()); + } + + if (clk_sig.width == 0 || data_sig.width == 0) + log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); + + for (bool rerun_invert_rollback = true; rerun_invert_rollback;) + { + rerun_invert_rollback = false; + + for (auto &it : module->cells) { + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clk_sig) { + clk_sig = it.second->connections.at("\\A"); + clk_polarity = !clk_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { + clear_sig = it.second->connections.at("\\A"); + clear_polarity = !clear_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { + preset_sig = it.second->connections.at("\\A"); + preset_polarity = !preset_polarity; + rerun_invert_rollback = true; + } + } + } + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_INV_"; + cell->connections["\\A"] = iq_sig; + cell->connections["\\Y"] = iqn_sig; + module->add(cell); + + cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->connections["\\D"] = data_sig; + cell->connections["\\Q"] = iq_sig; + cell->connections["\\C"] = clk_sig; + module->add(cell); + + if (clear_sig.width == 0 && preset_sig.width == 0) { + cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); + } + + if (clear_sig.width == 1 && preset_sig.width == 0) { + cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + cell->connections["\\R"] = clear_sig; + } + + if (clear_sig.width == 0 && preset_sig.width == 1) { + cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); + cell->connections["\\R"] = preset_sig; + } + + if (clear_sig.width == 1 && preset_sig.width == 1) { + cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + cell->connections["\\S"] = preset_sig; + cell->connections["\\R"] = clear_sig; + } + + log_assert(!cell->type.empty()); +} + +static void create_latch(RTLIL::Module *module, LibertyAst *node) +{ + RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + + RTLIL::SigSpec enable_sig, data_sig, clear_sig, preset_sig; + bool enable_polarity = true, clear_polarity = true, preset_polarity = true; + + for (auto child : node->children) { + if (child->id == "enable") + enable_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "data_in") + data_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "clear") + clear_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "preset") + preset_sig = parse_func_expr(module, child->value.c_str()); + } + + if (enable_sig.width == 0 || data_sig.width == 0) + log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); + + for (bool rerun_invert_rollback = true; rerun_invert_rollback;) + { + rerun_invert_rollback = false; + + for (auto &it : module->cells) { + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == enable_sig) { + enable_sig = it.second->connections.at("\\A"); + enable_polarity = !enable_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { + clear_sig = it.second->connections.at("\\A"); + clear_polarity = !clear_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { + preset_sig = it.second->connections.at("\\A"); + preset_polarity = !preset_polarity; + rerun_invert_rollback = true; + } + } + } + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_INV_"; + cell->connections["\\A"] = iq_sig; + cell->connections["\\Y"] = iqn_sig; + module->add(cell); + + if (clear_sig.width == 1) + { + RTLIL::SigSpec clear_negative = clear_sig; + RTLIL::SigSpec clear_enable = clear_sig; + + if (clear_polarity == true || clear_polarity != enable_polarity) + { + RTLIL::Cell *inv = new RTLIL::Cell; + inv->name = NEW_ID; + inv->type = "$_INV_"; + inv->connections["\\A"] = clear_sig; + inv->connections["\\Y"] = NEW_WIRE(module, 1);; + module->add(inv); + + if (clear_polarity == true) + clear_negative = inv->connections["\\Y"]; + if (clear_polarity != enable_polarity) + clear_enable = inv->connections["\\Y"]; + } + + RTLIL::Cell *data_gate = new RTLIL::Cell; + data_gate->name = NEW_ID; + data_gate->type = "$_AND_"; + data_gate->connections["\\A"] = data_sig; + data_gate->connections["\\B"] = clear_negative; + data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(data_gate); + + RTLIL::Cell *enable_gate = new RTLIL::Cell; + enable_gate->name = NEW_ID; + enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + enable_gate->connections["\\A"] = enable_sig; + enable_gate->connections["\\B"] = clear_enable; + enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(enable_gate); + } + + if (preset_sig.width == 1) + { + RTLIL::SigSpec preset_positive = preset_sig; + RTLIL::SigSpec preset_enable = preset_sig; + + if (preset_polarity == false || preset_polarity != enable_polarity) + { + RTLIL::Cell *inv = new RTLIL::Cell; + inv->name = NEW_ID; + inv->type = "$_INV_"; + inv->connections["\\A"] = preset_sig; + inv->connections["\\Y"] = NEW_WIRE(module, 1);; + module->add(inv); + + if (preset_polarity == false) + preset_positive = inv->connections["\\Y"]; + if (preset_polarity != enable_polarity) + preset_enable = inv->connections["\\Y"]; + } + + RTLIL::Cell *data_gate = new RTLIL::Cell; + data_gate->name = NEW_ID; + data_gate->type = "$_OR_"; + data_gate->connections["\\A"] = data_sig; + data_gate->connections["\\B"] = preset_positive; + data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(data_gate); + + RTLIL::Cell *enable_gate = new RTLIL::Cell; + enable_gate->name = NEW_ID; + enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + enable_gate->connections["\\A"] = enable_sig; + enable_gate->connections["\\B"] = preset_enable; + enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(enable_gate); + } + + cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N'); + cell->connections["\\D"] = data_sig; + cell->connections["\\Q"] = iq_sig; + cell->connections["\\E"] = enable_sig; + module->add(cell); +} + struct LibertyFrontend : public Frontend { LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { } virtual void help() @@ -289,21 +506,6 @@ struct LibertyFrontend : public Frontend { log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); } - if (!flag_lib) - { - LibertyAst *ff = cell->find("ff"); - if (ff != NULL) { - log("Warning: skipping flip-flop cell %s.\n", RTLIL::id2cstr(cell_name)); - continue; - } - - LibertyAst *latch = cell->find("latch"); - if (latch != NULL) { - log("Warning: skipping latch cell %s.\n", RTLIL::id2cstr(cell_name)); - continue; - } - } - // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); cell_count++; @@ -314,39 +516,51 @@ struct LibertyFrontend : public Frontend { for (auto &attr : attributes) module->attributes[attr] = 1; - for (auto pin : cell->children) - { - if (pin->id != "pin" || pin->args.size() != 1) - continue; + for (auto node : cell->children) + if (node->id == "pin" && node->args.size() == 1) { + LibertyAst *dir = node->find("direction"); + if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "internal")) + log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + if (!flag_lib || dir->value != "internal") + module->new_wire(1, RTLIL::escape_id(node->args.at(0))); + } - LibertyAst *dir = pin->find("direction"); - if (dir == NULL || dir->value == "internal") - continue; + for (auto node : cell->children) + { + if (!flag_lib) { + if (node->id == "ff" && node->args.size() == 2) + create_ff(module, node); + if (node->id == "latch" && node->args.size() == 2) + create_latch(module, node); + } - log_assert(dir->value == "input" || dir->value == "output"); + if (node->id == "pin" && node->args.size() == 1) + { + LibertyAst *dir = node->find("direction"); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(pin->args.at(0)); - module->add(wire); + if (flag_lib && dir->value == "internal") + continue; - if (dir->value == "input") { - wire->port_input = true; - continue; - } + RTLIL::Wire *wire = module->wires.at(RTLIL::escape_id(node->args.at(0))); - wire->port_output = true; + if (dir && dir->value == "input") { + wire->port_input = true; + continue; + } - if (flag_lib) - continue; + if (dir && dir->value == "output") + wire->port_output = true; - LibertyAst *func = pin->find("function"); - if (func == NULL) - log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + if (flag_lib) + continue; - RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); - module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + LibertyAst *func = node->find("function"); + if (func == NULL) + log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); - continue; + RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); + module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + } } module->fixup_ports(); -- cgit v1.2.3 From 7ac524e8e8d1745dec4605c32944e318f46daf4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 13:16:38 +0100 Subject: Improved support for constant functions --- frontends/ast/simplify.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2ae3cae08..5e37911d3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1167,9 +1167,11 @@ skip_dynamic_range_lvalue_expansion:; if (in_param) { bool all_args_const = true; - for (auto child : children) + for (auto child : children) { + while (child->simplify(true, false, false, 1, -1, false, true)) { } if (child->type != AST_CONSTANT) all_args_const = false; + } if (all_args_const) { AstNode *func_workspace = current_scope[str]->clone(); @@ -1931,6 +1933,53 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (stmt->type == AST_CASE) + { + AstNode *expr = stmt->children.at(0)->clone(); + expr->replace_variables(variables, fcall); + while (expr->simplify(true, false, false, 1, -1, false, true)) { } + + AstNode *sel_case = NULL; + for (size_t i = 1; i < stmt->children.size(); i++) + { + bool found_match = false; + log_assert(stmt->children.at(i)->type == AST_COND); + + if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) { + sel_case = stmt->children.at(i)->children.back(); + continue; + } + + for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++) + { + AstNode *cond = stmt->children.at(i)->children.at(j)->clone(); + cond->replace_variables(variables, fcall); + + cond = new AstNode(AST_EQ, expr->clone(), cond); + while (cond->simplify(true, false, false, 1, -1, false, true)) { } + + if (cond->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + found_match = cond->asBool(); + delete cond; + } + + if (found_match) { + sel_case = stmt->children.at(i)->children.back(); + break; + } + } + + block->children.erase(block->children.begin()); + if (sel_case) + block->children.insert(block->children.begin(), sel_case->clone()); + delete stmt; + delete expr; + continue; + } + if (stmt->type == AST_BLOCK) { block->children.erase(block->children.begin()); -- cgit v1.2.3 From 7d7e068dd1c5e04cf0c2b9e18abade2b49fe677e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 20:20:25 +0100 Subject: Added a warning note about error reporting to read_verilog help message --- frontends/verilog/verilog_frontend.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'frontends') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index d46dfa6e2..477f26b45 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -125,6 +125,11 @@ struct VerilogFrontend : public Frontend { log("The command 'verilog_defaults' can be used to register default options for\n"); log("subsequent calls to 'read_verilog'.\n"); log("\n"); + log("Note that the Verilog frontend does a pretty good job of processing valid\n"); + log("verilog input, but has not very good error reporting. It generally is\n"); + log("recommended to use a simulator (for example icarus verilog) for checking\n"); + log("the syntax of the code, rather than to rely on read_verilog for that.\n"); + log("\n"); } virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) { -- cgit v1.2.3 From 02e6f2c5be8c5514cc8cdb7b3344f6170fb87af9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 14:28:52 +0100 Subject: Added Verilog support for "`default_nettype none" --- frontends/ast/ast.cc | 8 ++++++-- frontends/ast/ast.h | 6 +++--- frontends/ast/genrtlil.cc | 5 ++++- frontends/verilog/lexer.l | 12 ++++++++++++ frontends/verilog/parser.y | 1 + frontends/verilog/preproc.cc | 1 - frontends/verilog/verilog_frontend.cc | 3 ++- frontends/verilog/verilog_frontend.h | 3 +++ 8 files changed, 31 insertions(+), 8 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 56e9393b7..58be06791 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -46,7 +46,7 @@ namespace AST { // instanciate global variables (private API) namespace AST_INTERNAL { - bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells; + bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map current_scope; RTLIL::SigSpec *genRTLIL_subst_from = NULL; @@ -836,11 +836,12 @@ static AstModule* process_module(AstNode *ast, bool defer) current_module->lib = flag_lib; current_module->noopt = flag_noopt; current_module->icells = flag_icells; + current_module->autowire = flag_autowire; return current_module; } // create AstModule instances for all modules in the AST tree and add them to 'design' -void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer) +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire) { current_ast = ast; flag_dump_ast1 = dump_ast1; @@ -852,6 +853,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_lib = lib; flag_noopt = noopt; flag_icells = icells; + flag_autowire = autowire; assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { @@ -897,6 +899,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::maplib = lib; new_mod->noopt = noopt; new_mod->icells = icells; + new_mod->autowire = autowire; return new_mod; } diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index f42bc35fb..72a2a4600 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -238,13 +238,13 @@ namespace AST }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code - void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1 = false, bool dump_ast2 = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false, bool noopt = false, bool icells = false, bool ignore_redef = false, bool defer = true); + void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire); // parametric modules are supported directly by the AST library // therfore we need our own derivate of RTLIL::Module with overloaded virtual functions struct AstModule : RTLIL::Module { AstNode *ast; - bool nolatches, nomem2reg, mem2reg, lib, noopt, icells; + bool nolatches, nomem2reg, mem2reg, lib, noopt, icells, autowire; virtual ~AstModule(); virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); virtual RTLIL::Module *clone() const; @@ -265,7 +265,7 @@ namespace AST namespace AST_INTERNAL { // internal state variables - extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells; + extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; extern AST::AstNode *current_ast, *current_ast_mod; extern std::map current_scope; extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 12fe23fd8..bc3783bda 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -921,7 +921,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Wire *wire = new RTLIL::Wire; wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); wire->name = str; - log("Warning: Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum); + if (flag_autowire) + log("Warning: Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum); + else + log_error("Identifier `%s' is implicitly declared at %s:%d and `default_nettype is set to none.\n", str.c_str(), filename.c_str(), linenum); current_module->wires[str] = wire; } else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) { diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 81167cf4e..79f44b4a6 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -81,6 +81,18 @@ namespace VERILOG_FRONTEND { "`timescale"[ \t]+[^ \t\r\n/]+[ \t]*"/"[ \t]*[^ \t\r\n]* /* ignore timescale directive */ +"`default_nettype"[ \t]+[^ \t\r\n/]+ { + char *p = yytext; + while (*p != 0 && *p != ' ' && *p != '\t') p++; + while (*p == ' ' || *p == '\t') p++; + if (!strcmp(p, "none")) + VERILOG_FRONTEND::default_nettype_wire = false; + else if (!strcmp(p, "wire")) + VERILOG_FRONTEND::default_nettype_wire = true; + else + frontend_verilog_yyerror("Unsupported default nettype: %s", p); +} + "`"[a-zA-Z_$][a-zA-Z0-9_$]* { frontend_verilog_yyerror("Unimplemented compiler directive or undefined macro %s.", yytext); } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 8080729b0..4726f1aa3 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -53,6 +53,7 @@ namespace VERILOG_FRONTEND { struct AstNode *current_ast, *current_ast_mod; int current_function_or_task_port_id; std::vector case_type_stack; + bool default_nettype_wire; } static void append_attr(AstNode *ast, std::map *al) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index db53e8c68..873ae3d51 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -373,7 +373,6 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } if (tok == "`timescale") { - std::string name; skip_spaces(); while (!tok.empty() && tok != "\n") tok = next_token(true); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 477f26b45..13c2676db 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -256,6 +256,7 @@ struct VerilogFrontend : public Frontend { AST::get_line_num = &frontend_verilog_yyget_lineno; current_ast = new AST::AstNode(AST::AST_DESIGN); + default_nettype_wire = true; FILE *fp = f; std::string code_after_preproc; @@ -279,7 +280,7 @@ struct VerilogFrontend : public Frontend { child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } - AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer); + AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire); if (!flag_nopp) fclose(fp); diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 8b4fae6e9..99b2164ef 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -42,6 +42,9 @@ namespace VERILOG_FRONTEND // this function converts a Verilog constant to an AST_CONSTANT node AST::AstNode *const2ast(std::string code, char case_type = 0); + + // state of `default_nettype + extern bool default_nettype_wire; } // the pre-processor -- cgit v1.2.3 From 4bd25edcd4773d312cc47384e639161d485492de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 19:12:32 +0100 Subject: Cleanups in handling of read_verilog -defer and -icells --- frontends/ast/ast.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 58be06791..d9ad6d8ef 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -759,7 +759,7 @@ static AstModule* process_module(AstNode *ast, bool defer) current_module = new AstModule; current_module->ast = NULL; - current_module->name = defer ? "$abstract" + ast->str : ast->str; + current_module->name = ast->str; current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); current_ast_mod = ast; @@ -857,7 +857,11 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { - if (design->modules.count((*it)->str) != 0 && design->modules.count("$abstract" + (*it)->str) != 0) { + if (flag_icells && (*it)->str.substr(0, 2) == "\\$") + (*it)->str = (*it)->str.substr(1); + if (defer) + (*it)->str = "$abstract" + (*it)->str; + if (design->modules.count((*it)->str)) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -865,10 +869,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - if (defer) - design->modules["$abstract" + (*it)->str] = process_module(*it, true); - else - design->modules[(*it)->str] = process_module(*it, false); + design->modules[(*it)->str] = process_module(*it, defer); } } -- cgit v1.2.3 From 0a60f95224376304565d950832f8320d5f4fb70e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 18:59:49 +0100 Subject: Added vhdl2verilog --- frontends/vhdl2verilog/Makefile.inc | 1 + frontends/vhdl2verilog/vhdl2verilog.cc | 154 +++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 frontends/vhdl2verilog/Makefile.inc create mode 100644 frontends/vhdl2verilog/vhdl2verilog.cc (limited to 'frontends') diff --git a/frontends/vhdl2verilog/Makefile.inc b/frontends/vhdl2verilog/Makefile.inc new file mode 100644 index 000000000..003d89c4a --- /dev/null +++ b/frontends/vhdl2verilog/Makefile.inc @@ -0,0 +1 @@ +OBJS += frontends/vhdl2verilog/vhdl2verilog.o diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc new file mode 100644 index 000000000..9e9953ced --- /dev/null +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -0,0 +1,154 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include +#include + +struct Vhdl2verilogPass : public Pass { + Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" vhdl2verilog [options] ..\n"); + log("\n"); + log("This pass looks for subcircuits that are isomorphic to any of the modules\n"); + log("in the given map file and replaces them with instances of this modules. The\n"); + log("map file can be a verilog source file (*.v) or an ilang file (*.il).\n"); + log("\n"); + log(" -out \n"); + log(" do not import the vhdl2verilog output. instead write it to the\n"); + log(" specified file.\n"); + log("\n"); + log(" -vhdl2verilog_dir \n"); + log(" do use the specified vhdl2verilog installations. this is the directory\n"); + log(" that contains the setup_env.sh file. when this option is not present,\n"); + log(" it is assumed that vhdl2verilog is in the PATH environment variable.\n"); + log("\n"); + log(" -top \n"); + log(" The name of the top entity. This option is mandatory.\n"); + log("\n"); + log("vhdl2verilog can be obtained from:\n"); + log("http://www.edautils.com/vhdl2verilog.html\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + log_header("Executing VHDL2VERILOG (importing VHDL designs using vhdl2verilog).\n"); + log_push(); + + std::string out_file, top_entity; + std::string vhdl2verilog_dir; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-out" && argidx+1 < args.size()) { + out_file = args[++argidx]; + continue; + } + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_entity = args[++argidx]; + continue; + } + if (args[argidx] == "-vhdl2verilog_dir" && argidx+1 < args.size()) { + vhdl2verilog_dir = args[++argidx]; + continue; + } + break; + } + + if (argidx == args.size()) + cmd_error(args, argidx, "Missing filenames."); + if (args[argidx].substr(0, 1) == "-") + cmd_error(args, argidx, "Unkown option."); + if (top_entity.empty()) + log_cmd_error("Missing -top option.\n"); + + char tempdir_name[] = "/tmp/yosys-abc-XXXXXX"; + char *p = mkdtemp(tempdir_name); + log("Using temp directory %s.\n", tempdir_name); + if (p == NULL) + log_error("For some reason mkdtemp() failed!\n"); + + if (!out_file.empty() && out_file[0] != '/') { + char *pwd = get_current_dir_name(); + out_file = pwd + ("/" + out_file); + free(pwd); + } + + FILE *f = fopen(stringf("%s/files.list", tempdir_name).c_str(), "wt"); + while (argidx < args.size()) { + std::string file = args[argidx++]; + if (file.empty()) + continue; + if (file[0] != '/') { + char *pwd = get_current_dir_name(); + file = pwd + ("/" + file); + free(pwd); + } + fprintf(f, "%s\n", file.c_str()); + log("Adding '%s' to the file list.\n", file.c_str()); + } + fclose(f); + + std::string command = "exec 2>&1; "; + if (!vhdl2verilog_dir.empty()) + command += stringf("cd '%s'; . ./setup_env.sh; ", vhdl2verilog_dir.c_str()); + command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'", tempdir_name, + out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str()); + + log("Running '%s'..\n", command.c_str()); + + errno = ENOMEM; // popen does not set errno if memory allocation fails, therefore set it by hand + f = popen(command.c_str(), "r"); + if (f == NULL) + log_error("Opening pipe to `%s' for reading failed: %s\n", command.c_str(), strerror(errno)); + + char logbuf[1024]; + while (fgets(logbuf, 1024, f) != NULL) + log("%s", logbuf); + + int ret = pclose(f); + if (ret < 0) + log_error("Closing pipe to `%s' failed: %s\n", command.c_str(), strerror(errno)); + if (WEXITSTATUS(ret) != 0) + log_error("Execution of command \"%s\" failed: the shell returned %d\n", command.c_str(), WEXITSTATUS(ret)); + + if (out_file.empty()) { + f = fopen(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str(), "rt"); + if (f == NULL) + log_error("Can't open vhdl2verilog output file `vhdl2verilog_output.v'.\n"); + Frontend::frontend_call(design, f, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog"); + fclose(f); + } + + log_header("Removing temp directory `%s':\n", tempdir_name); + system(stringf("rm -rf '%s'", tempdir_name).c_str()); + + log_pop(); + } +} Vhdl2verilogPass; + -- cgit v1.2.3 From f8c9143b2b232e2f22e6cfbf9c431b2a1b756afa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 17:08:00 +0100 Subject: Fixed bug in generation of undefs for $memwr MUXes --- frontends/ast/simplify.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5e37911d3..55ed28b01 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1088,14 +1088,16 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - std::vector x_bits; + std::vector x_bits_addr, x_bits_data; + for (int i = 0; i < addr_bits; i++) + x_bits_addr.push_back(RTLIL::State::Sx); for (int i = 0; i < mem_width; i++) - x_bits.push_back(RTLIL::State::Sx); + x_bits_data.push_back(RTLIL::State::Sx); - AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits, false)); + AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); assign_addr->children[0]->str = id_addr; - AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits, false)); + AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); assign_data->children[0]->str = id_data; AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1)); -- cgit v1.2.3 From 6bc94b7eb2ecc7c2836c2fc10029542ce92eae11 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 24 Feb 2014 12:41:25 +0100 Subject: Don't blow up constants unneccessarily in Verilog frontend --- frontends/ast/genrtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index bc3783bda..dda069cb8 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -906,7 +906,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); is_signed = sign_hint; - return RTLIL::SigSpec(bitsAsConst(width_hint, sign_hint)); + return RTLIL::SigSpec(bitsAsConst()); } // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node -- cgit v1.2.3 From ae5032af845b4c85510b3ce4a63fea3cca5e6a00 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 26 Feb 2014 21:32:19 +0100 Subject: Fixed bit-extending in $mux argument (use $bu0 instead of $pos) --- frontends/ast/genrtlil.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dda069cb8..c3025913c 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -83,7 +83,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) -static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed) +static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) { if (width <= sig.width) { sig.extend(width, is_signed); @@ -96,7 +96,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s RTLIL::Cell *cell = new RTLIL::Cell; cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); cell->name = sstr.str(); - cell->type = "$pos"; + cell->type = celltype; current_module->cells[cell->name] = cell; RTLIL::Wire *wire = new RTLIL::Wire; @@ -1041,7 +1041,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = arg.width; if (width_hint > 0) { width = width_hint; - widthExtend(this, arg, width, is_signed); + widthExtend(this, arg, width, is_signed, "$pos"); } return uniop2rtlil(this, type_name, width, arg); } @@ -1196,8 +1196,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = std::max(val1.width, val2.width); is_signed = children[1]->is_signed && children[2]->is_signed; - widthExtend(this, val1, width, is_signed); - widthExtend(this, val2, width, is_signed); + widthExtend(this, val1, width, is_signed, "$bu0"); + widthExtend(this, val2, width, is_signed, "$bu0"); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); -- cgit v1.2.3 From 04999f4af0f6e5c46843d9212abb0c962f533cca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 17:47:19 +0100 Subject: Fixed vhdl2verilog help message --- frontends/vhdl2verilog/vhdl2verilog.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 9e9953ced..367e63fe0 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -35,9 +35,8 @@ struct Vhdl2verilogPass : public Pass { log("\n"); log(" vhdl2verilog [options] ..\n"); log("\n"); - log("This pass looks for subcircuits that are isomorphic to any of the modules\n"); - log("in the given map file and replaces them with instances of this modules. The\n"); - log("map file can be a verilog source file (*.v) or an ilang file (*.il).\n"); + log("This command reads VHDL source files using the 'vhdl2verilog' tool and the\n"); + log("Yosys Verilog frontend.\n"); log("\n"); log(" -out \n"); log(" do not import the vhdl2verilog output. instead write it to the\n"); -- cgit v1.2.3 From ef90236a5dd59497661e9c9ba440adf22d6052de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 17:48:15 +0100 Subject: Fixed vhdl2verilog temp dir name --- frontends/vhdl2verilog/vhdl2verilog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 367e63fe0..de3936939 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -86,7 +86,7 @@ struct Vhdl2verilogPass : public Pass { if (top_entity.empty()) log_cmd_error("Missing -top option.\n"); - char tempdir_name[] = "/tmp/yosys-abc-XXXXXX"; + char tempdir_name[] = "/tmp/yosys-vhdl2verilog-XXXXXX"; char *p = mkdtemp(tempdir_name); log("Using temp directory %s.\n", tempdir_name); if (p == NULL) -- cgit v1.2.3 From de7bd12004f24b7e9fff3ba1f253537704db4e44 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:45:33 +0100 Subject: Bugfix in recursive AST simplification --- frontends/ast/simplify.cc | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 55ed28b01..72d90e4ae 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -219,7 +219,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE) - while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) { } + while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) + did_something = true; } } @@ -241,8 +242,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_ASSIGN_EQ: case AST_ASSIGN_LE: case AST_ASSIGN: - while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) { } - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) + did_something = true; + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) + did_something = true; children[0]->detectSignWidth(backup_width_hint, backup_sign_hint); children[1]->detectSignWidth(width_hint, sign_hint); width_hint = std::max(width_hint, backup_width_hint); @@ -251,11 +254,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_PARAMETER: case AST_LOCALPARAM: - while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) + did_something = true; children[0]->detectSignWidth(width_hint, sign_hint); if (children.size() > 1) { assert(children[1]->type == AST_RANGE); - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) { } + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) + did_something = true; if (!children[1]->range_valid) log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); width_hint = std::max(width_hint, children[1]->range_left - children[1]->range_right + 1); @@ -311,7 +316,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint = -1; sign_hint = true; for (auto child : children) { - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) + did_something = true; child->detectSignWidthWorker(width_hint, sign_hint); } reset_width_after_children = true; @@ -341,9 +347,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (detect_width_simple && width_hint < 0) { for (auto child : children) - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) + did_something = true; if (type == AST_REPLICATE) - while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) { } + while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) + did_something = true; detectSignWidth(width_hint, sign_hint); } @@ -389,7 +397,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } for (auto &attr : attributes) { - while (attr.second->simplify(true, false, false, stage, -1, false, true)) { } + while (attr.second->simplify(true, false, false, stage, -1, false, true)) + did_something = true; } if (reset_width_after_children) { @@ -539,7 +548,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, current_scope[str] = auto_wire; did_something = true; } - id2ast = current_scope[str]; + if (id2ast != current_scope[str]) { + id2ast = current_scope[str]; + did_something = true; + } } // split memory access with bit select to individual statements -- cgit v1.2.3 From d6a01fe412419d32ec5b0d91f9076849d1ed489d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:55:58 +0100 Subject: Fixed merging of compatible wire decls in AST frontend --- frontends/ast/simplify.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 72d90e4ae..a20aacff5 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -206,10 +206,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, did_something = true; delete node; continue; + wires_are_incompatible: + if (stage > 1) + log_error("Incompatible re-declaration of wire %s at %s:%d.\n", node->str.c_str(), filename.c_str(), linenum); + continue; } this_wire_scope[node->str] = node; } - wires_are_incompatible: if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR || node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_CELL) { backup_scope[node->str] = current_scope[node->str]; -- cgit v1.2.3 From 09805ee9ec0408bdc68b914927899f02371efcb7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:56:31 +0100 Subject: Include id2ast pointers when dumping AST --- frontends/ast/ast.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d9ad6d8ef..f2f2d0e69 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -244,6 +244,12 @@ void AstNode::dumpAst(FILE *f, std::string indent) std::string type_name = type2str(type); fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum); + + if (id2ast) + fprintf(f, " [%p -> %p]", this, id2ast); + else + fprintf(f, " [%p]", this); + if (!str.empty()) fprintf(f, " str='%s'", str.c_str()); if (!bits.empty()) { -- cgit v1.2.3 From 4d07f8825845618daffb4d61bdcbb3eda0e1393a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 16:37:19 +0100 Subject: Fixed gcc compiler warning --- frontends/vhdl2verilog/vhdl2verilog.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index de3936939..0467810e5 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -145,7 +145,8 @@ struct Vhdl2verilogPass : public Pass { } log_header("Removing temp directory `%s':\n", tempdir_name); - system(stringf("rm -rf '%s'", tempdir_name).c_str()); + if (system(stringf("rm -rf '%s'", tempdir_name).c_str()) != 0) + log_error("Execution of \"rm -rf '%s'\" failed!\n", tempdir_name); log_pop(); } -- cgit v1.2.3 From 620d51d9f713d68ebc920b5b1cac59cc176b0b9d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 17:19:14 +0100 Subject: Bugfix in ilang frontend autoidx recovery --- frontends/ilang/lexer.l | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 5da8ce675..000919275 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -131,8 +131,8 @@ void update_autoidx(const char *p) q++; if ((q - p) < 10) { int idx = atoi(p); - if (idx > RTLIL::autoidx) - RTLIL::autoidx = idx; + if (idx >= RTLIL::autoidx) + RTLIL::autoidx = idx+1; } } } -- cgit v1.2.3 From 8d06f9f2fe19cc581e61ff66d0641bc03f815fb3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Mar 2014 20:40:04 +0100 Subject: Added "verific" command --- frontends/verific/Makefile.inc | 1 + frontends/verific/verific.cc | 488 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 489 insertions(+) create mode 100644 frontends/verific/Makefile.inc create mode 100644 frontends/verific/verific.cc (limited to 'frontends') diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc new file mode 100644 index 000000000..74a669ef4 --- /dev/null +++ b/frontends/verific/Makefile.inc @@ -0,0 +1 @@ +OBJS += frontends/verific/verific.o diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc new file mode 100644 index 000000000..5c2b933cb --- /dev/null +++ b/frontends/verific/verific.cc @@ -0,0 +1,488 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include +#include + +#ifdef VERIFIC_DIR + +#include "veri_file.h" +#include "vhdl_file.h" +#include "VeriWrite.h" +#include "DataBase.h" +#include "Message.h" + +#ifdef VERIFIC_NAMESPACE +using namespace Verific ; +#endif + +static void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefile, const char *msg, va_list args) +{ + log("VERIFIC-%s [%s] ", + msg_type == VERIFIC_NONE ? "NONE" : + msg_type == VERIFIC_ERROR ? "ERROR" : + msg_type == VERIFIC_WARNING ? "WARNING" : + msg_type == VERIFIC_IGNORE ? "IGNORE" : + msg_type == VERIFIC_INFO ? "INFO" : + msg_type == VERIFIC_COMMENT ? "COMMENT" : + msg_type == VERIFIC_PROGRAM_ERROR ? "PROGRAM_ERROR" : "UNKNOWN", message_id); + if (linefile) + log("%s:%d: ", LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile)); + logv(msg, args); + log("\n"); +} + +void import_attributes(std::map &attributes, DesignObj *obj) +{ + MapIter mi; + Att *attr; + + if (obj->Linefile()) + attributes["\\src"] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile())); + + // FIXME: Parse numeric attributes + FOREACH_ATTRIBUTE(obj, mi, attr) + attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(std::string(attr->Value())); +} + +static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set &nl_todo) +{ + if (design->modules.count(RTLIL::escape_id(nl->Owner()->Name()))) + log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); + + RTLIL::Module *module = new RTLIL::Module; + module->name = RTLIL::escape_id(nl->Owner()->Name()); + design->modules[module->name] = module; + + log("Importing module %s.\n", RTLIL::id2cstr(module->name)); + + std::map net_map; + + MapIter mi, mi2; + Port *port; + PortBus *portbus; + Net *net; + NetBus *netbus; + Instance *inst; + + FOREACH_PORT_OF_NETLIST(nl, mi, port) + { + if (port->Bus()) + continue; + + // log(" importing port %s.\n", port->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(port->Name()); + import_attributes(wire->attributes, port); + module->add(wire); + + if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_IN) + wire->port_input = true; + if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_OUT) + wire->port_output = true; + + if (port->GetNet()) { + net = port->GetNet(); + if (net_map.count(net) == 0) + net_map[net] = wire; + else if (wire->port_input) + module->connections.push_back(RTLIL::SigSig(net_map.at(net), wire)); + else + module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + } + } + + FOREACH_PORTBUS_OF_NETLIST(nl, mi, portbus) + { + // log(" importing portbus %s.\n", portbus->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(portbus->Name()); + wire->width = portbus->Size(); + wire->start_offset = std::min(portbus->LeftIndex(), portbus->RightIndex()); + import_attributes(wire->attributes, port); + module->add(wire); + + if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN) + wire->port_input = true; + if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_OUT) + wire->port_output = true; + + for (int i = portbus->LeftIndex();; i += portbus->IsUp() ? +1 : -1) { + if (portbus->ElementAtIndex(i) && portbus->ElementAtIndex(i)->GetNet()) { + net = portbus->ElementAtIndex(i)->GetNet(); + RTLIL::SigBit bit(wire, i - wire->start_offset); + if (net_map.count(net) == 0) + net_map[net] = bit; + else if (wire->port_input) + module->connections.push_back(RTLIL::SigSig(net_map.at(net), bit)); + else + module->connections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + } + if (i == portbus->RightIndex()) + break; + } + } + + module->fixup_ports(); + + FOREACH_NET_OF_NETLIST(nl, mi, net) + { + if (net_map.count(net)) { + // log(" skipping net %s.\n", net->Name()); + continue; + } + + if (net->Bus()) + continue; + + // log(" importing net %s.\n", net->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(net->Name()); + while (module->count_id(wire->name)) + wire->name += "_"; + import_attributes(wire->attributes, port); + module->add(wire); + + if (net_map.count(net) == 0) + net_map[net] = wire; + else + module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + } + + FOREACH_NETBUS_OF_NETLIST(nl, mi, netbus) + { + bool found_new_net = false; + for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { + net = netbus->ElementAtIndex(i); + if (net_map.count(net) == 0) + found_new_net = true; + if (i == netbus->RightIndex()) + break; + } + + if (found_new_net) + { + // log(" importing netbus %s.\n", netbus->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(netbus->Name()); + wire->width = netbus->Size(); + wire->start_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); + while (module->count_id(wire->name)) + wire->name += "_"; + import_attributes(wire->attributes, port); + module->add(wire); + + for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { + if (netbus->ElementAtIndex(i)) { + net = netbus->ElementAtIndex(i); + RTLIL::SigBit bit(wire, i - wire->start_offset); + if (net_map.count(net) == 0) + net_map[net] = bit; + else + module->connections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + } + if (i == netbus->RightIndex()) + break; + } + } + else + { + // log(" skipping netbus %s.\n", netbus->Name()); + } + } + + FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) + { + log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); + + if (inst->Type() == PRIM_PWR) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S1)); + continue; + } + + if (inst->Type() == PRIM_GND) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S0)); + continue; + } + + if (inst->Type() == PRIM_X) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sx)); + continue; + } + + if (inst->Type() == PRIM_Z) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sz)); + continue; + } + + if (inst->Type() == PRIM_AND || inst->Type() == PRIM_OR || inst->Type() == PRIM_XOR || inst->Type() == PRIM_XNOR) { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = inst->Type() == PRIM_AND ? "$and" : inst->Type() == PRIM_OR ? "$or" : + inst->Type() == PRIM_XOR ? "$xor" : "$xnor"; + cell->parameters["\\A_SIGNED"] = 0; + cell->parameters["\\B_SIGNED"] = 0; + cell->parameters["\\A_WIDTH"] = 1; + cell->parameters["\\B_WIDTH"] = 1; + cell->parameters["\\Y_WIDTH"] = 1; + cell->connections["\\A"] = net_map.at(inst->GetInput1()); + cell->connections["\\B"] = net_map.at(inst->GetInput2()); + cell->connections["\\Y"] = net_map.at(inst->GetOutput()); + module->add(cell); + continue; + } + + if (inst->Type() == PRIM_INV) { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$not"; + cell->parameters["\\A_SIGNED"] = 0; + cell->parameters["\\A_WIDTH"] = 1; + cell->parameters["\\Y_WIDTH"] = 1; + cell->connections["\\A"] = net_map.at(inst->GetInput()); + cell->connections["\\Y"] = net_map.at(inst->GetOutput()); + module->add(cell); + continue; + } + + if (inst->Type() == PRIM_MUX) { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$mux"; + cell->parameters["\\WIDTH"] = 1; + cell->connections["\\A"] = net_map.at(inst->GetInput1()); + cell->connections["\\B"] = net_map.at(inst->GetInput2()); + cell->connections["\\S"] = net_map.at(inst->GetControl()); + cell->connections["\\Y"] = net_map.at(inst->GetOutput()); + module->add(cell); + continue; + } + + if (inst->Type() == PRIM_FADD) + { + RTLIL::Cell *cell1 = new RTLIL::Cell; + cell1->name = RTLIL::escape_id(NEW_ID); + cell1->type = "$add"; + cell1->parameters["\\A_SIGNED"] = 0; + cell1->parameters["\\B_SIGNED"] = 0; + cell1->parameters["\\A_WIDTH"] = 1; + cell1->parameters["\\B_WIDTH"] = 1; + cell1->parameters["\\Y_WIDTH"] = 2; + cell1->connections["\\A"] = net_map.at(inst->GetInput1()); + cell1->connections["\\B"] = net_map.at(inst->GetInput2()); + cell1->connections["\\Y"] = module->new_wire(2, NEW_ID); + module->add(cell1); + + RTLIL::Cell *cell2 = new RTLIL::Cell; + cell2->name = RTLIL::escape_id(inst->Name()); + cell2->type = "$add"; + cell2->parameters["\\A_SIGNED"] = 0; + cell2->parameters["\\B_SIGNED"] = 0; + cell2->parameters["\\A_WIDTH"] = 2; + cell2->parameters["\\B_WIDTH"] = 1; + cell2->parameters["\\Y_WIDTH"] = 2; + cell2->connections["\\A"] = cell1->connections["\\Y"]; + cell2->connections["\\B"] = net_map.at(inst->GetCin()); + cell2->connections["\\Y"] = net_map.at(inst->GetOutput()); + cell2->connections["\\Y"].append(net_map.at(inst->GetCout())); + module->add(cell2); + continue; + } + + if (inst->IsPrimitive()) + log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); + + nl_todo.insert(inst->View()); + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = RTLIL::escape_id(inst->View()->Owner()->Name()); + module->add(cell); + + PortRef *pr ; + FOREACH_PORTREF_OF_INST(inst, mi2, pr) { + // log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name()); + const char *port_name = pr->GetPort()->Name(); + int port_offset = 0; + if (pr->GetPort()->Bus()) { + port_name = pr->GetPort()->Bus()->Name(); + port_offset = pr->GetPort()->Bus()->IndexOf(pr->GetPort()) - + std::min(pr->GetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); + } + RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; + while (conn.width <= port_offset) + conn.append(RTLIL::State::Sz); + conn.replace(port_offset, net_map.at(pr->GetNet())); + } + } +} + +#endif /* VERIFIC_DIR */ + +struct VerificPass : public Pass { + VerificPass() : Pass("verific", "load Verilog and VHDL designs using Verific") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" verific {-vlog95|-vlog2k|-sv2005|-sv2009|-sv} ..\n"); + log("\n"); + log("Load the specified Verilog/SystemVerilog files into Verific.\n"); + log("\n"); + log("\n"); + log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008} ..\n"); + log("\n"); + log("Load the specified VHDL files into Verific.\n"); + log("\n"); + log("\n"); + log(" verific -import ..\n"); + log("\n"); + log("Elaborate the design for the sepcified top modules, import to Yosys and\n"); + log("reset the internal state of Verific.\n"); + log("\n"); + log("\n"); + log("Visit http://verific.com/ for more information on Verific.\n"); + log("\n"); + } +#ifdef VERIFIC_DIR + virtual void execute(std::vector args, RTLIL::Design *design) + { + log_header("Executing VERIFIC (loading Verilog and VHDL designs using the Verific library).\n"); + + Message::SetConsoleOutput(0); + Message::RegisterCallBackMsg(msg_func); + + if (args.size() > 1 && args[1] == "-vlog95") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::VERILOG_95)) + log_cmd_error("Reading `%s' in VERILOG_95 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vlog2k") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::VERILOG_2K)) + log_cmd_error("Reading `%s' in VERILOG_2K mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-sv2005") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::SYSTEM_VERILOG_2005)) + log_cmd_error("Reading `%s' in SYSTEM_VERILOG_2005 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-sv2009") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::SYSTEM_VERILOG_2009)) + log_cmd_error("Reading `%s' in SYSTEM_VERILOG_2009 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-sv") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::SYSTEM_VERILOG)) + log_cmd_error("Reading `%s' in SYSTEM_VERILOG mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl87") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_87)) + log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl93") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_93)) + log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl2k") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2K)) + log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl2008") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2008)) + log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-import") + { + std::set nl_todo, nl_done; + + if (args.size() == 2) + log_cmd_error("No top module specified.\n"); + + for (size_t argidx = 2; argidx < args.size(); argidx++) { + if (veri_file::GetModule(args[argidx].c_str())) { + if (!veri_file::Elaborate(args[argidx].c_str())) + log_cmd_error("Elaboration of top module `%s' failed.\n", args[argidx].c_str()); + nl_todo.insert(Netlist::PresentDesign()); + } else { + if (!vhdl_file::Elaborate(args[argidx].c_str())) + log_cmd_error("Elaboration of top module `%s' failed.\n", args[argidx].c_str()); + nl_todo.insert(Netlist::PresentDesign()); + } + } + + while (!nl_todo.empty()) { + Netlist *nl = *nl_todo.begin(); + if (nl_done.count(nl) == 0) + import_netlist(design, nl, nl_todo); + nl_todo.erase(nl); + nl_done.insert(nl); + } + + Libset::Reset(); + return; + } + + log_cmd_error("Missing or unsupported mode parameter.\n"); + } +#else /* VERIFIC_DIR */ + virtual void execute(std::vector, RTLIL::Design *) { + log_cmd_error("This version of Yosys is built without Verific support.\n"); + } +#endif +} VerificPass; + -- cgit v1.2.3 From c71791a1ffa566585317a01becd5c33ad452fe57 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 03:03:08 +0100 Subject: Improvements in verific command --- frontends/verific/verific.cc | 98 ++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 59 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 5c2b933cb..1b25fecac 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -220,7 +220,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName(), inst->View()->Owner()->Name()); + // log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); if (inst->Type() == PRIM_PWR) { module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S1)); @@ -242,77 +242,57 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_AND || inst->Type() == PRIM_OR || inst->Type() == PRIM_XOR || inst->Type() == PRIM_XNOR) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = inst->Type() == PRIM_AND ? "$and" : inst->Type() == PRIM_OR ? "$or" : - inst->Type() == PRIM_XOR ? "$xor" : "$xnor"; - cell->parameters["\\A_SIGNED"] = 0; - cell->parameters["\\B_SIGNED"] = 0; - cell->parameters["\\A_WIDTH"] = 1; - cell->parameters["\\B_WIDTH"] = 1; - cell->parameters["\\Y_WIDTH"] = 1; - cell->connections["\\A"] = net_map.at(inst->GetInput1()); - cell->connections["\\B"] = net_map.at(inst->GetInput2()); - cell->connections["\\Y"] = net_map.at(inst->GetOutput()); - module->add(cell); + if (inst->Type() == PRIM_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + continue; + } + + if (inst->Type() == PRIM_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + continue; + } + + if (inst->Type() == PRIM_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + continue; + } + + if (inst->Type() == PRIM_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); continue; } if (inst->Type() == PRIM_INV) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = "$not"; - cell->parameters["\\A_SIGNED"] = 0; - cell->parameters["\\A_WIDTH"] = 1; - cell->parameters["\\Y_WIDTH"] = 1; - cell->connections["\\A"] = net_map.at(inst->GetInput()); - cell->connections["\\Y"] = net_map.at(inst->GetOutput()); - module->add(cell); + module->addNot(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); continue; } if (inst->Type() == PRIM_MUX) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = "$mux"; - cell->parameters["\\WIDTH"] = 1; - cell->connections["\\A"] = net_map.at(inst->GetInput1()); - cell->connections["\\B"] = net_map.at(inst->GetInput2()); - cell->connections["\\S"] = net_map.at(inst->GetControl()); - cell->connections["\\Y"] = net_map.at(inst->GetOutput()); - module->add(cell); + module->addMux(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); continue; } if (inst->Type() == PRIM_FADD) { - RTLIL::Cell *cell1 = new RTLIL::Cell; - cell1->name = RTLIL::escape_id(NEW_ID); - cell1->type = "$add"; - cell1->parameters["\\A_SIGNED"] = 0; - cell1->parameters["\\B_SIGNED"] = 0; - cell1->parameters["\\A_WIDTH"] = 1; - cell1->parameters["\\B_WIDTH"] = 1; - cell1->parameters["\\Y_WIDTH"] = 2; - cell1->connections["\\A"] = net_map.at(inst->GetInput1()); - cell1->connections["\\B"] = net_map.at(inst->GetInput2()); - cell1->connections["\\Y"] = module->new_wire(2, NEW_ID); - module->add(cell1); - - RTLIL::Cell *cell2 = new RTLIL::Cell; - cell2->name = RTLIL::escape_id(inst->Name()); - cell2->type = "$add"; - cell2->parameters["\\A_SIGNED"] = 0; - cell2->parameters["\\B_SIGNED"] = 0; - cell2->parameters["\\A_WIDTH"] = 2; - cell2->parameters["\\B_WIDTH"] = 1; - cell2->parameters["\\Y_WIDTH"] = 2; - cell2->connections["\\A"] = cell1->connections["\\Y"]; - cell2->connections["\\B"] = net_map.at(inst->GetCin()); - cell2->connections["\\Y"] = net_map.at(inst->GetOutput()); - cell2->connections["\\Y"].append(net_map.at(inst->GetCout())); - module->add(cell2); + RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); + RTLIL::SigSpec y = net_map.at(inst->GetOutput()); + y.append(net_map.at(inst->GetCout())); + + module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); + module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + continue; + } + + if (inst->Type() == PRIM_DFFRS) + { + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec d = module->new_wire(1, NEW_ID); + + module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); + module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); + module->addAnd(NEW_ID, tmp1, tmp2, d); + module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); continue; } -- cgit v1.2.3 From 5a15539c9b4280b1ed3a77a131f3197a1127404f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 12:06:57 +0100 Subject: Improved verific command (added support for some operators) --- frontends/verific/verific.cc | 162 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1b25fecac..c78d19f24 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -55,7 +55,7 @@ static void msg_func(msg_type_t msg_type, const char *message_id, linefile_type log("\n"); } -void import_attributes(std::map &attributes, DesignObj *obj) +static void import_attributes(std::map &attributes, DesignObj *obj) { MapIter mi; Att *attr; @@ -68,6 +68,61 @@ void import_attributes(std::map &attributes, Desi attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(std::string(attr->Value())); } +static RTLIL::SigSpec operatorInput(Instance *inst, std::map &net_map) +{ + RTLIL::SigSpec sig; + for (unsigned i = 0; i < inst->InputSize(); i++) + if (inst->GetInputBit(i)) + sig.append(net_map.at(inst->GetInputBit(i))); + else + sig.append(RTLIL::State::Sz); + sig.optimize(); + return sig; +} + +static RTLIL::SigSpec operatorInput1(Instance *inst, std::map &net_map) +{ + RTLIL::SigSpec sig; + for (unsigned i = 0; i < inst->Input1Size(); i++) + if (inst->GetInput1Bit(i)) + sig.append(net_map.at(inst->GetInput1Bit(i))); + else + sig.append(RTLIL::State::Sz); + sig.optimize(); + return sig; +} + +static RTLIL::SigSpec operatorInput2(Instance *inst, std::map &net_map) +{ + RTLIL::SigSpec sig; + for (unsigned i = 0; i < inst->Input2Size(); i++) + if (inst->GetInput2Bit(i)) + sig.append(net_map.at(inst->GetInput2Bit(i))); + else + sig.append(RTLIL::State::Sz); + sig.optimize(); + return sig; +} + +static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, RTLIL::Module *module) +{ + RTLIL::SigSpec sig; + RTLIL::Wire *dummy_wire = NULL; + for (unsigned i = 0; i < inst->OutputSize(); i++) + if (inst->GetInput2Bit(i)) { + sig.append(net_map.at(inst->GetInput2Bit(i))); + dummy_wire = NULL; + } else { + if (dummy_wire == NULL) + dummy_wire = module->new_wire(1, NEW_ID); + else + dummy_wire->width++; + sig.append(RTLIL::SigSpec(dummy_wire, 1, dummy_wire->width - 1)); + } + sig.optimize(); + return sig; +} + static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set &nl_todo) { if (design->modules.count(RTLIL::escape_id(nl->Owner()->Name()))) @@ -296,6 +351,109 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setView()->IsSigned() + + if (inst->Type() == OPER_ADDER) { + module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_MULTIPLIER) { + module->addMul(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_DIVIDER) { + module->addDiv(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_MODULO) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + // FIXME: OPER_REMAINDER -- how is this different from OPER_MODULO ? + + if (inst->Type() == OPER_REMAINDER) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_SHIFT_LEFT) { + module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_SHIFT_RIGHT) { + module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + // FIXME: OPER_ROTATE_LEFT OPER_ROTATE_RIGHT -- are they $sshl / $sshr cells? + + if (inst->Type() == OPER_REDUCE_AND) { + module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_REDUCE_OR) { + module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_REDUCE_XOR) { + module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_REDUCE_NAND) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + continue; + } + + if (inst->Type() == OPER_REDUCE_NOR) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceOr(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + continue; + } + + if (inst->Type() == OPER_REDUCE_XNOR) { + module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_LESSTHAN) { + module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_EQUAL) { + module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_NEQUAL) { + module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + #undef IN + #undef IN1 + #undef IN2 + #undef OUT + #undef SIGNED + + if (inst->IsOperator()) + log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); + if (inst->IsPrimitive()) log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); @@ -354,7 +512,7 @@ struct VerificPass : public Pass { #ifdef VERIFIC_DIR virtual void execute(std::vector args, RTLIL::Design *design) { - log_header("Executing VERIFIC (loading Verilog and VHDL designs using the Verific library).\n"); + log_header("Executing VERIFIC (loading Verilog and VHDL designs using Verific).\n"); Message::SetConsoleOutput(0); Message::RegisterCallBackMsg(msg_func); -- cgit v1.2.3 From 9992026a8d4482abd8fbae8cb246a87cbbbde364 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:06:57 +0100 Subject: Added support for `line compiler directive --- frontends/verilog/lexer.l | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'frontends') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 79f44b4a6..e3e5e4ab2 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -75,6 +75,17 @@ namespace VERILOG_FRONTEND { ln_stack.pop_back(); } +"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { + char *p = yytext + 5; + while (*p == ' ' || *p == '\t') p++; + frontend_verilog_yyset_lineno(atoi(p)); + while (*p && *p != ' ' && *p != '\t') p++; + while (*p == ' ' || *p == '\t') p++; + char *q = *p ? p + 1 : p; + while (*q && *q != '"') q++; + current_filename = std::string(p).substr(1, q-p-1); +} + "`file_notfound "[^\n]* { log_error("Can't open include file `%s'!\n", yytext + 15); } -- cgit v1.2.3 From 91704a78531bec2e3eea3ddf90eaedb28e1d696d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:24:24 +0100 Subject: Merged a few fixes for non-posix systems from github.com/Siesh1oo/yosys (see https://github.com/cliffordwolf/yosys/pull/28) --- frontends/vhdl2verilog/vhdl2verilog.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 0467810e5..83035d329 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -26,6 +26,8 @@ #include #include #include +#include +#include struct Vhdl2verilogPass : public Pass { Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } @@ -93,9 +95,12 @@ struct Vhdl2verilogPass : public Pass { log_error("For some reason mkdtemp() failed!\n"); if (!out_file.empty() && out_file[0] != '/') { - char *pwd = get_current_dir_name(); + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s", strerror(errno)); + log_abort(); + } out_file = pwd + ("/" + out_file); - free(pwd); } FILE *f = fopen(stringf("%s/files.list", tempdir_name).c_str(), "wt"); @@ -104,9 +109,12 @@ struct Vhdl2verilogPass : public Pass { if (file.empty()) continue; if (file[0] != '/') { - char *pwd = get_current_dir_name(); + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s", strerror(errno)); + log_abort(); + } file = pwd + ("/" + file); - free(pwd); } fprintf(f, "%s\n", file.c_str()); log("Adding '%s' to the file list.\n", file.c_str()); -- cgit v1.2.3 From fad8558eb5ecbd62e2032a48c537bfecfad3dfc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 12:48:10 +0100 Subject: Merged OSX fixes from Siesh1oo with some modifications --- frontends/verilog/verilog_frontend.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'frontends') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 13c2676db..8e9efa173 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -27,6 +27,7 @@ */ #include "verilog_frontend.h" +#include "kernel/compatibility.h" #include "kernel/register.h" #include "kernel/log.h" #include "libs/sha1/sha1.h" -- cgit v1.2.3 From 7a1ac1120351d5cf0de2c9173fb7353795b0137e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 13:12:06 +0100 Subject: Added test_navre.ys for verific frontend --- frontends/verific/test_navre.ys | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 frontends/verific/test_navre.ys (limited to 'frontends') diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys new file mode 100644 index 000000000..9e11cde05 --- /dev/null +++ b/frontends/verific/test_navre.ys @@ -0,0 +1,17 @@ +verific -vlog2k ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +verific -import softusb_navre + +flatten softusb_navre +rename softusb_navre gate + +read_verilog ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +cd softusb_navre; proc; opt; memory; opt; cd .. +rename softusb_navre gold + +expose -dff -shared gold gate +miter -equiv -ignore_gold_x -make_assert -make_outputs -make_outcmp gold gate miter + +cd miter +flatten; opt -undriven +sat -verify -maxsteps 5 -set-init-undef -set-def-inputs -prove-asserts -tempinduct-def \ + -seq 1 -set-at 1 in_rst 1 # -show-inputs -show-outputs -- cgit v1.2.3 From 6a53bc7b271662dfc67f055917578ef8c1949fd6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 17:34:31 +0100 Subject: Copy Verific vdbs files to Yosys "share" data directory --- frontends/verific/Makefile.inc | 15 +++++++++++++++ frontends/verific/verific.cc | 16 ++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index 74a669ef4..eca23e58c 100644 --- a/frontends/verific/Makefile.inc +++ b/frontends/verific/Makefile.inc @@ -1 +1,16 @@ + OBJS += frontends/verific/verific.o + +ifeq ($(ENABLE_VERIFIC),1) + +EXTRA_TARGETS += share/verific + +share/verific: + rm -rf share/verific.new + mkdir -p share/verific.new + cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs share/verific.new/vhdl_vdbs_1993 + cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008 share/verific.new/vhdl_vdbs_2008 + mv share/verific.new share/verific + +endif + diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c78d19f24..bc6abc5f8 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -27,7 +27,7 @@ #include #include -#ifdef VERIFIC_DIR +#ifdef YOSYS_ENABLE_VERIFIC #include "veri_file.h" #include "vhdl_file.h" @@ -482,7 +482,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set args, RTLIL::Design *design) { log_header("Executing VERIFIC (loading Verilog and VHDL designs using Verific).\n"); @@ -553,7 +553,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl87") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_87)) log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", args[argidx].c_str()); @@ -561,7 +561,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl93") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_93)) log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", args[argidx].c_str()); @@ -569,7 +569,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl2k") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2K)) log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", args[argidx].c_str()); @@ -577,7 +577,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl2008") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2008)) log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", args[argidx].c_str()); @@ -617,7 +617,7 @@ struct VerificPass : public Pass { log_cmd_error("Missing or unsupported mode parameter.\n"); } -#else /* VERIFIC_DIR */ +#else /* YOSYS_ENABLE_VERIFIC */ virtual void execute(std::vector, RTLIL::Design *) { log_cmd_error("This version of Yosys is built without Verific support.\n"); } -- cgit v1.2.3 From 9a1accf692adfb9f0f505a1f7e7646731fff10d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 18:21:00 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 75 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 10 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index bc6abc5f8..455bf8170 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -71,7 +71,7 @@ static void import_attributes(std::map &attribute static RTLIL::SigSpec operatorInput(Instance *inst, std::map &net_map) { RTLIL::SigSpec sig; - for (unsigned i = 0; i < inst->InputSize(); i++) + for (int i = int(inst->InputSize())-1; i >= 0; i--) if (inst->GetInputBit(i)) sig.append(net_map.at(inst->GetInputBit(i))); else @@ -83,7 +83,7 @@ static RTLIL::SigSpec operatorInput(Instance *inst, std::map &net_map) { RTLIL::SigSpec sig; - for (unsigned i = 0; i < inst->Input1Size(); i++) + for (int i = int(inst->Input1Size())-1; i >= 0; i--) if (inst->GetInput1Bit(i)) sig.append(net_map.at(inst->GetInput1Bit(i))); else @@ -95,7 +95,7 @@ static RTLIL::SigSpec operatorInput1(Instance *inst, std::map &net_map) { RTLIL::SigSpec sig; - for (unsigned i = 0; i < inst->Input2Size(); i++) + for (int i = int(inst->Input2Size())-1; i >= 0; i--) if (inst->GetInput2Bit(i)) sig.append(net_map.at(inst->GetInput2Bit(i))); else @@ -108,9 +108,9 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::mapOutputSize(); i++) - if (inst->GetInput2Bit(i)) { - sig.append(net_map.at(inst->GetInput2Bit(i))); + for (int i = int(inst->OutputSize())-1; i >= 0; i--) + if (inst->GetOutputBit(i)) { + sig.append(net_map.at(inst->GetOutputBit(i))); dummy_wire = NULL; } else { if (dummy_wire == NULL) @@ -377,8 +377,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_REMAINDER) { module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); continue; @@ -394,8 +392,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_REDUCE_AND) { module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); continue; @@ -435,6 +431,60 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_WIDE_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_NAND) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_NOR) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_BUF) { + module->addPos(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_INV) { + module->addNot(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_MINUS) { + module->addSub(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_UMINUS) { + module->addNeg(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + if (inst->Type() == OPER_EQUAL) { module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); continue; @@ -445,6 +495,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_WIDE_MUX) { + module->addMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); + continue; + } + #undef IN #undef IN1 #undef IN2 -- cgit v1.2.3 From 0ac915a757a10f50fd74e18365cbcf351885c162 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 11:46:13 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 560 ++++++++++++++++++++++++++----------------- 1 file changed, 338 insertions(+), 222 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 455bf8170..b10b3326e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -29,12 +29,18 @@ #ifdef YOSYS_ENABLE_VERIFIC +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverloaded-virtual" + #include "veri_file.h" #include "vhdl_file.h" -#include "VeriWrite.h" +#include "VeriModule.h" +#include "VhdlUnits.h" #include "DataBase.h" #include "Message.h" +#pragma clang diagnostic pop + #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif @@ -123,13 +129,288 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &nl_todo) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, Instance *inst) +{ + if (inst->Type() == PRIM_AND) { + module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_OR) { + module->addOrGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_XOR) { + module->addXorGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_INV) { + module->addInvGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_MUX) { + module->addMuxGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_FADD) + { + RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); + RTLIL::SigSpec y = net_map.at(inst->GetOutput()); + y.append(net_map.at(inst->GetCout())); + + module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); + module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + return true; + } + + if (inst->Type() == PRIM_DFFRS) + { + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec d = module->new_wire(1, NEW_ID); + + module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); + module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); + module->addAnd(NEW_ID, tmp1, tmp2, d); + module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); + return true; + } + + return false; +} + +static bool import_netlist_instance_cells(RTLIL::Module *module, std::map &net_map, Instance *inst) +{ + if (inst->Type() == PRIM_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_INV) { + module->addNot(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_MUX) { + module->addMux(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_FADD) + { + RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); + RTLIL::SigSpec y = net_map.at(inst->GetOutput()); + y.append(net_map.at(inst->GetCout())); + + module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); + module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + return true; + } + + if (inst->Type() == PRIM_DFFRS) + { + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec d = module->new_wire(1, NEW_ID); + + module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); + module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); + module->addAnd(NEW_ID, tmp1, tmp2, d); + module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); + return true; + } + + #define IN operatorInput(inst, net_map) + #define IN1 operatorInput1(inst, net_map) + #define IN2 operatorInput2(inst, net_map) + #define OUT operatorOutput(inst, net_map, module) + #define SIGNED inst->View()->IsSigned() + +#if 0 + if (inst->Type() == OPER_ADDER) { + module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_MULTIPLIER) { + module->addMul(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_DIVIDER) { + module->addDiv(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_MODULO) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REMAINDER) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_SHIFT_LEFT) { + module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_SHIFT_RIGHT) { + module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_AND) { + module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_OR) { + module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_XOR) { + module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_NAND) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + return true; + } + + if (inst->Type() == OPER_REDUCE_NOR) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceOr(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + return true; + } + + if (inst->Type() == OPER_REDUCE_XNOR) { + module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_LESSTHAN) { + module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_NAND) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_NOR) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_BUF) { + module->addPos(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_INV) { + module->addNot(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_MINUS) { + module->addSub(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_UMINUS) { + module->addNeg(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_EQUAL) { + module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_NEQUAL) { + module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_MUX) { + module->addMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); + return true; + } +#endif + + #undef IN + #undef IN1 + #undef IN2 + #undef OUT + #undef SIGNED + + return false; +} + +static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set &nl_todo, bool mode_gates) { - if (design->modules.count(RTLIL::escape_id(nl->Owner()->Name()))) - log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); - + std::string module_name = nl->IsOperator() ? std::string("$verific$") + nl->Owner()->Name() : RTLIL::escape_id(nl->Owner()->Name()); + + if (design->modules.count(module_name)) { + if (!nl->IsOperator()) + log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); + return; + } + RTLIL::Module *module = new RTLIL::Module; - module->name = RTLIL::escape_id(nl->Owner()->Name()); + module->name = module_name; design->modules[module->name] = module; log("Importing module %s.\n", RTLIL::id2cstr(module->name)); @@ -297,217 +578,15 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_AND) { - module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_OR) { - module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_XOR) { - module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_XNOR) { - module->addXnor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_INV) { - module->addNot(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_MUX) { - module->addMux(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_FADD) - { - RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = net_map.at(inst->GetOutput()); - y.append(net_map.at(inst->GetCout())); - - module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); - module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); - continue; - } - - if (inst->Type() == PRIM_DFFRS) - { - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec d = module->new_wire(1, NEW_ID); - - module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); - module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); - module->addAnd(NEW_ID, tmp1, tmp2, d); - module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); - continue; - } - - #define IN operatorInput(inst, net_map) - #define IN1 operatorInput1(inst, net_map) - #define IN2 operatorInput2(inst, net_map) - #define OUT operatorOutput(inst, net_map, module) - #define SIGNED inst->View()->IsSigned() - - if (inst->Type() == OPER_ADDER) { - module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_MULTIPLIER) { - module->addMul(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_DIVIDER) { - module->addDiv(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_MODULO) { - module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REMAINDER) { - module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_SHIFT_LEFT) { - module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_SHIFT_RIGHT) { - module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_AND) { - module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_OR) { - module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_XOR) { - module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_NAND) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); - continue; - } - - if (inst->Type() == OPER_REDUCE_NOR) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceOr(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); - continue; - } - - if (inst->Type() == OPER_REDUCE_XNOR) { - module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_LESSTHAN) { - module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_AND) { - module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_OR) { - module->addOr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_XOR) { - module->addXor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_NAND) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_NOR) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - continue; + if (!mode_gates) { + if (import_netlist_instance_cells(module, net_map, inst)) + continue; + if (inst->IsOperator()) + log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); } - if (inst->Type() == OPER_WIDE_XNOR) { - module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + if (import_netlist_instance_gates(module, net_map, inst)) continue; - } - - if (inst->Type() == OPER_WIDE_BUF) { - module->addPos(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_INV) { - module->addNot(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_MINUS) { - module->addSub(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_UMINUS) { - module->addNeg(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_EQUAL) { - module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_NEQUAL) { - module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_MUX) { - module->addMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); - continue; - } - - #undef IN - #undef IN1 - #undef IN2 - #undef OUT - #undef SIGNED - - if (inst->IsOperator()) - log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); if (inst->IsPrimitive()) log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); @@ -516,7 +595,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(inst->Name()); - cell->type = RTLIL::escape_id(inst->View()->Owner()->Name()); + cell->type = inst->IsOperator() ? std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()); module->add(cell); PortRef *pr ; @@ -555,11 +634,11 @@ struct VerificPass : public Pass { log("Load the specified VHDL files into Verific.\n"); log("\n"); log("\n"); - log(" verific -import ..\n"); + log(" verific -import [-gates] {-all | ..}\n"); log("\n"); log("Elaborate the design for the sepcified top modules, import to Yosys and\n"); - log("reset the internal state of Verific.\n"); - log("\n"); + log("reset the internal state of Verific. A gate-level netlist is created\n"); + log("when called with -gates.\n"); log("\n"); log("Visit http://verific.com/ for more information on Verific.\n"); log("\n"); @@ -642,11 +721,48 @@ struct VerificPass : public Pass { if (args.size() > 1 && args[1] == "-import") { std::set nl_todo, nl_done; + bool mode_all = false, mode_gates = false; - if (args.size() == 2) - log_cmd_error("No top module specified.\n"); + size_t argidx = 2; + for (; argidx < args.size(); argidx++) { + if (args[argidx] == "-all") { + mode_all = true; + continue; + } + if (args[argidx] == "-gates") { + mode_gates = true; + continue; + } + break; + } + + if (argidx > args.size() && args[argidx].substr(0, 1) == "-") + cmd_error(args, argidx, "unkown option"); + + if (mode_all) + { + if (argidx != args.size()) + log_cmd_error("Got -all and an explicit list of top modules.\n"); + + MapIter m1, m2, m3; + VeriModule *mod; + FOREACH_VERILOG_MODULE(m1, mod) + args.push_back(mod->Name()); + + VhdlLibrary *lib; + VhdlPrimaryUnit *primunit; + FOREACH_VHDL_LIBRARY(m1, lib) + FOREACH_VHDL_PRIMARY_UNIT(lib, m2, primunit) { + if (primunit->IsPackageDecl()) + continue; + args.push_back(primunit->Name()); + } + } + else + if (argidx == args.size()) + log_cmd_error("No top module specified.\n"); - for (size_t argidx = 2; argidx < args.size(); argidx++) { + for (; argidx < args.size(); argidx++) { if (veri_file::GetModule(args[argidx].c_str())) { if (!veri_file::Elaborate(args[argidx].c_str())) log_cmd_error("Elaboration of top module `%s' failed.\n", args[argidx].c_str()); @@ -661,7 +777,7 @@ struct VerificPass : public Pass { while (!nl_todo.empty()) { Netlist *nl = *nl_todo.begin(); if (nl_done.count(nl) == 0) - import_netlist(design, nl, nl_todo); + import_netlist(design, nl, nl_todo, mode_gates); nl_todo.erase(nl); nl_done.insert(nl); } -- cgit v1.2.3 From e37d672ae7dc47952bac483afb85aae32cb727f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 16:40:25 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 51 +++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 13 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index b10b3326e..59fce136a 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -129,7 +129,7 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, Instance *inst) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, std::map&, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -183,7 +183,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, Instance *inst) +static bool import_netlist_instance_cells(RTLIL::Module *module, std::map &net_map, std::map &const_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -245,9 +245,19 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapView()->IsSigned() -#if 0 if (inst->Type() == OPER_ADDER) { - module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + RTLIL::SigSpec out = OUT; + Net *cin = inst->GetNet(inst->View()->GetPort("cin")); + Net *cout = inst->GetNet(inst->View()->GetPort("cout")); + if (cout != NULL) + out.append(net_map.at(cout)); + if (const_map.count(cin) && const_map.at(cin) == RTLIL::State::S0) { + module->addAdd(RTLIL::escape_id(inst->Name()) + "_", IN1, IN2, out, SIGNED); + } else { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); + module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(cin), out, false); + } return true; } @@ -282,36 +292,36 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_REDUCE_AND) { - module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_REDUCE_OR) { - module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_REDUCE_XOR) { - module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_REDUCE_NAND) { RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } if (inst->Type() == OPER_REDUCE_NOR) { RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); module->addReduceOr(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } if (inst->Type() == OPER_REDUCE_XNOR) { - module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } @@ -388,7 +398,6 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapaddMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); return true; } -#endif #undef IN #undef IN1 @@ -416,6 +425,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname)); std::map net_map; + std::map const_map; MapIter mi, mi2; Port *port; @@ -554,6 +564,21 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_PWR) + const_map[inst->GetOutput()] = RTLIL::State::S1; + + if (inst->Type() == PRIM_GND) + const_map[inst->GetOutput()] = RTLIL::State::S1; + + if (inst->Type() == PRIM_X) + const_map[inst->GetOutput()] = RTLIL::State::S1; + + if (inst->Type() == PRIM_Z) + const_map[inst->GetOutput()] = RTLIL::State::S1; + } + FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) { // log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); @@ -579,13 +604,13 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); } - if (import_netlist_instance_gates(module, net_map, inst)) + if (import_netlist_instance_gates(module, net_map, const_map, inst)) continue; if (inst->IsPrimitive()) -- cgit v1.2.3 From 1d00ad9d4d241ffaa7cce35d7afc03d06521b15e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 14:36:11 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 62 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 59fce136a..30437437b 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -129,7 +129,7 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, std::map&, Instance *inst) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, std::map &const_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -158,25 +158,32 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_FADD) { - RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = net_map.at(inst->GetOutput()); - y.append(net_map.at(inst->GetCout())); - - module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); - module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); + RTLIL::SigSpec x = net_map.at(inst->GetCout()), y = net_map.at(inst->GetOutput()); + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp3 = module->new_wire(1, NEW_ID); + module->addXorGate(NEW_ID, a, b, tmp1); + module->addXorGate(RTLIL::escape_id(inst->Name()), tmp1, c, y); + module->addAndGate(NEW_ID, tmp1, c, tmp2); + module->addAndGate(NEW_ID, a, b, tmp3); + module->addOrGate(NEW_ID, tmp2, tmp3, x); return true; } if (inst->Type() == PRIM_DFFRS) { - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec d = module->new_wire(1, NEW_ID); - - module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); - module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); - module->addAnd(NEW_ID, tmp1, tmp2, d); - module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); + if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0 && const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + module->addDffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + else if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0) + module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); + else if (const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); + else + module->addDffsrGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); return true; } @@ -228,15 +235,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_DFFRS) { - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec d = module->new_wire(1, NEW_ID); - - module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); - module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); - module->addAnd(NEW_ID, tmp1, tmp2, d); - module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); - return true; + // FIXME } #define IN operatorInput(inst, net_map) @@ -247,16 +246,14 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_ADDER) { RTLIL::SigSpec out = OUT; - Net *cin = inst->GetNet(inst->View()->GetPort("cin")); - Net *cout = inst->GetNet(inst->View()->GetPort("cout")); - if (cout != NULL) - out.append(net_map.at(cout)); - if (const_map.count(cin) && const_map.at(cin) == RTLIL::State::S0) { + if (inst->GetCout() != NULL) + out.append(net_map.at(inst->GetCout())); + if (const_map.count(inst->GetCin()) && const_map.at(inst->GetCin()) == RTLIL::State::S0) { module->addAdd(RTLIL::escape_id(inst->Name()) + "_", IN1, IN2, out, SIGNED); } else { RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); - module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(cin), out, false); + module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetCin()), out, false); } return true; } @@ -634,8 +631,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; - while (conn.width <= port_offset) + while (conn.width <= port_offset) { + if (pr->GetPort()->GetDir() != DIR_IN) + conn.append(module->new_wire(port_offset - conn.width, NEW_ID)); conn.append(RTLIL::State::Sz); + } conn.replace(port_offset, net_map.at(pr->GetNet())); } } -- cgit v1.2.3 From fc2c821407fde02248bb475c432df5bb89a1bd1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 15:31:54 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 30437437b..4564d7425 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -249,9 +249,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapGetCout() != NULL) out.append(net_map.at(inst->GetCout())); if (const_map.count(inst->GetCin()) && const_map.at(inst->GetCin()) == RTLIL::State::S0) { - module->addAdd(RTLIL::escape_id(inst->Name()) + "_", IN1, IN2, out, SIGNED); + module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, out, SIGNED); } else { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + RTLIL::SigSpec tmp = module->new_wire(out.width, NEW_ID); module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetCin()), out, false); } @@ -278,6 +278,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_SHIFT_LEFT) { module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; @@ -287,6 +290,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapaddShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; } +#endif if (inst->Type() == OPER_REDUCE_AND) { module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); @@ -322,10 +326,14 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_LESSTHAN) { module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; } +#endif if (inst->Type() == OPER_WIDE_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); @@ -382,12 +390,12 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_EQUAL) { - module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_NEQUAL) { - module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); return true; } @@ -567,13 +575,13 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetOutput()] = RTLIL::State::S1; if (inst->Type() == PRIM_GND) - const_map[inst->GetOutput()] = RTLIL::State::S1; + const_map[inst->GetOutput()] = RTLIL::State::S0; if (inst->Type() == PRIM_X) - const_map[inst->GetOutput()] = RTLIL::State::S1; + const_map[inst->GetOutput()] = RTLIL::State::Sx; if (inst->Type() == PRIM_Z) - const_map[inst->GetOutput()] = RTLIL::State::S1; + const_map[inst->GetOutput()] = RTLIL::State::Sz; } FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) -- cgit v1.2.3 From 0ebee4c8e7743004ba0b7af714f3b1aff301bc61 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 22:51:12 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 55 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4564d7425..0e203a267 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -278,19 +278,22 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_SHIFT_LEFT) { - module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, false); return true; } if (inst->Type() == OPER_SHIFT_RIGHT) { - module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + Net *net_cin = inst->GetCin(); + Net *net_a_msb = inst->GetInput1Bit(0); + if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, false); + else if (net_cin == net_a_msb) + module->addSshr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, true); + else + log_error("Can't import Verific OPER_SHIFT_RIGHT instance %s: carry_in is neither 0 nor msb of left input\n", inst->Name()); return true; } -#endif if (inst->Type() == OPER_REDUCE_AND) { module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); @@ -307,33 +310,21 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_REDUCE_NAND) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); - return true; - } - - if (inst->Type() == OPER_REDUCE_NOR) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceOr(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); - return true; - } - if (inst->Type() == OPER_REDUCE_XNOR) { module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } -#if 0 - // FIXME: tests/simple/sincos.v exposes a bug in this operator - if (inst->Type() == OPER_LESSTHAN) { - module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + Net *net_cin = inst->GetCin(); + if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); + else if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S1) + module->addLe(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); + else + log_error("Can't import Verific OPER_LESSTHAN instance %s: carry_in is neither 0 nor 1\n", inst->Name()); return true; } -#endif if (inst->Type() == OPER_WIDE_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); @@ -350,20 +341,6 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_NAND) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - return true; - } - - if (inst->Type() == OPER_WIDE_NOR) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - return true; - } - if (inst->Type() == OPER_WIDE_XNOR) { module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; -- cgit v1.2.3 From 7545510edcc1d9ab14e53cae285f1ef0dfb3d7d4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Mar 2014 16:06:03 +0100 Subject: Use Verific Net::{IsGnd,IsPwr} API in Verific bindings --- frontends/verific/verific.cc | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 0e203a267..bf24c8234 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -129,7 +129,7 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, std::map &const_map, Instance *inst) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -173,12 +173,12 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_DFFRS) { - if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0 && const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + if (inst->GetSet()->IsGnd() && inst->GetReset()->IsGnd()) module->addDffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); - else if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0) + else if (inst->GetSet()->IsGnd()) module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); - else if (const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + else if (inst->GetReset()->IsGnd()) module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); else @@ -190,7 +190,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, std::map &const_map, Instance *inst) +static bool import_netlist_instance_cells(RTLIL::Module *module, std::map &net_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -248,7 +248,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapGetCout() != NULL) out.append(net_map.at(inst->GetCout())); - if (const_map.count(inst->GetCin()) && const_map.at(inst->GetCin()) == RTLIL::State::S0) { + if (inst->GetCin()->IsGnd()) { module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, out, SIGNED); } else { RTLIL::SigSpec tmp = module->new_wire(out.width, NEW_ID); @@ -286,7 +286,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_SHIFT_RIGHT) { Net *net_cin = inst->GetCin(); Net *net_a_msb = inst->GetInput1Bit(0); - if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + if (net_cin->IsGnd()) module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, false); else if (net_cin == net_a_msb) module->addSshr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, true); @@ -317,9 +317,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_LESSTHAN) { Net *net_cin = inst->GetCin(); - if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + if (net_cin->IsGnd()) module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); - else if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S1) + else if (net_cin->IsPwr()) module->addLe(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); else log_error("Can't import Verific OPER_LESSTHAN instance %s: carry_in is neither 0 nor 1\n", inst->Name()); @@ -407,7 +407,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname)); std::map net_map; - std::map const_map; MapIter mi, mi2; Port *port; @@ -546,21 +545,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_PWR) - const_map[inst->GetOutput()] = RTLIL::State::S1; - - if (inst->Type() == PRIM_GND) - const_map[inst->GetOutput()] = RTLIL::State::S0; - - if (inst->Type() == PRIM_X) - const_map[inst->GetOutput()] = RTLIL::State::Sx; - - if (inst->Type() == PRIM_Z) - const_map[inst->GetOutput()] = RTLIL::State::Sz; - } - FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) { // log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); @@ -586,13 +570,13 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); } - if (import_netlist_instance_gates(module, net_map, const_map, inst)) + if (import_netlist_instance_gates(module, net_map, inst)) continue; if (inst->IsPrimitive()) -- cgit v1.2.3 From acda74c12cd39ae1a17d15f472728b49ad584e91 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Mar 2014 17:05:05 +0100 Subject: Added support for memories to verific bindings --- frontends/verific/test_navre.ys | 1 + frontends/verific/verific.cc | 86 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys index 9e11cde05..6f63761ab 100644 --- a/frontends/verific/test_navre.ys +++ b/frontends/verific/test_navre.ys @@ -1,6 +1,7 @@ verific -vlog2k ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v verific -import softusb_navre +memory softusb_navre flatten softusb_navre rename softusb_navre gate diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index bf24c8234..8b42ca8c1 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -408,12 +408,14 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set net_map; + SetIter si; MapIter mi, mi2; Port *port; PortBus *portbus; Net *net; NetBus *netbus; Instance *inst; + PortRef *pr; FOREACH_PORT_OF_NETLIST(nl, mi, port) { @@ -479,6 +481,33 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsRamNet()) + { + RTLIL::Memory *memory = new RTLIL::Memory; + memory->name = RTLIL::escape_id(net->Name()); + log_assert(module->count_id(memory->name) == 0); + module->memories[memory->name] = memory; + + int number_of_bits = net->Size(); + int bits_in_word = number_of_bits; + FOREACH_PORTREF_OF_NET(net, si, pr) { + if (pr->GetInst()->Type() == OPER_READ_PORT) { + bits_in_word = std::min(bits_in_word, pr->GetInst()->OutputSize()); + continue; + } + if (pr->GetInst()->Type() == OPER_WRITE_PORT || pr->GetInst()->Type() == OPER_CLOCKED_WRITE_PORT) { + bits_in_word = std::min(bits_in_word, pr->GetInst()->Input2Size()); + continue; + } + log_error("Verific RamNet %s is connected to unsupported instance type %s (%s).\n", + net->Name(), pr->GetInst()->View()->Owner()->Name(), pr->GetInst()->Name()); + } + + memory->width = bits_in_word; + memory->size = number_of_bits / bits_in_word; + continue; + } + if (net_map.count(net)) { // log(" skipping net %s.\n", net->Name()); continue; @@ -569,6 +598,62 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_READ_PORT) + { + RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name())); + if (memory->width != int(inst->OutputSize())) + log_error("Import of asymetric memories from Verific is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name()); + + RTLIL::SigSpec addr = operatorInput1(inst, net_map); + RTLIL::SigSpec data = operatorOutput(inst, net_map, module); + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$memrd"; + cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\CLK_ENABLE"] = false; + cell->parameters["\\CLK_POLARITY"] = true; + cell->parameters["\\TRANSPARENT"] = false; + cell->parameters["\\ABITS"] = addr.width; + cell->parameters["\\WIDTH"] = data.width; + cell->connections["\\CLK"] = RTLIL::State::S0; + cell->connections["\\ADDR"] = addr; + cell->connections["\\DATA"] = data; + module->add(cell); + continue; + } + + if (inst->Type() == OPER_WRITE_PORT || inst->Type() == OPER_CLOCKED_WRITE_PORT) + { + RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name())); + if (memory->width != int(inst->Input2Size())) + log_error("Import of asymetric memories from Verific is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name()); + + RTLIL::SigSpec addr = operatorInput1(inst, net_map); + RTLIL::SigSpec data = operatorInput2(inst, net_map); + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$memwr"; + cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\CLK_ENABLE"] = false; + cell->parameters["\\CLK_POLARITY"] = true; + cell->parameters["\\PRIORITY"] = 0; + cell->parameters["\\ABITS"] = addr.width; + cell->parameters["\\WIDTH"] = data.width; + cell->connections["\\EN"] = net_map.at(inst->GetControl()); + cell->connections["\\CLK"] = RTLIL::State::S0; + cell->connections["\\ADDR"] = addr; + cell->connections["\\DATA"] = data; + module->add(cell); + + if (inst->Type() == OPER_CLOCKED_WRITE_PORT) { + cell->parameters["\\CLK_ENABLE"] = true; + cell->connections["\\CLK"] = net_map.at(inst->GetClock()); + } + continue; + } + if (!mode_gates) { if (import_netlist_instance_cells(module, net_map, inst)) continue; @@ -589,7 +674,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::settype = inst->IsOperator() ? std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()); module->add(cell); - PortRef *pr ; FOREACH_PORTREF_OF_INST(inst, mi2, pr) { // log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name()); const char *port_name = pr->GetPort()->Name(); -- cgit v1.2.3 From a67cd2d4a284cb945af6d477cc215cef7bdd22a8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 01:56:00 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 8b42ca8c1..84e5e6736 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -429,6 +429,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setattributes, port); module->add(wire); + wire->port_id = nl->IndexOf(port) + 1; + if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_IN) wire->port_input = true; if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_OUT) -- cgit v1.2.3 From 0b0dcfda7d6a860713e67f3a0c50f6636be687d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 02:43:53 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 55 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 84e5e6736..21aca6d43 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -110,6 +110,33 @@ static RTLIL::SigSpec operatorInput2(Instance *inst, std::map &net_map) +{ + PortBus *portbus = inst->View()->GetPortBus(portname); + if (portbus) { + RTLIL::SigSpec sig; + for (unsigned i = 0; i < portbus->Size(); i++) { + Net *net = inst->GetNet(portbus->ElementAtIndex(i)); + if (net) { + if (net->IsGnd()) + sig.append(RTLIL::State::S0); + else if (net->IsPwr()) + sig.append(RTLIL::State::S1); + else + sig.append(net_map.at(net)); + } else + sig.append(RTLIL::State::Sz); + } + sig.optimize(); + return sig; + } else { + Port *port = inst->View()->GetPort(portname); + log_assert(port != NULL); + Net *net = inst->GetNet(port); + return net_map.at(net); + } +} + static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, RTLIL::Module *module) { RTLIL::SigSpec sig; @@ -235,7 +262,18 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_DFFRS) { - // FIXME + if (inst->GetSet()->IsGnd() && inst->GetReset()->IsGnd()) + module->addDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + else if (inst->GetSet()->IsGnd()) + module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); + else if (inst->GetReset()->IsGnd()) + module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); + else + module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + return true; } #define IN operatorInput(inst, net_map) @@ -381,6 +419,16 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_DFFRS) { + RTLIL::SigSpec sig_set = operatorInport(inst, "set", net_map); + RTLIL::SigSpec sig_reset = operatorInport(inst, "reset", net_map); + if (sig_set.is_fully_const() && !sig_set.as_bool() && sig_set.is_fully_const() && !sig_set.as_bool()) { + module->addDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), IN, OUT); + } else + module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), sig_set, sig_reset, IN, OUT); + return true; + } + #undef IN #undef IN1 #undef IN2 @@ -527,10 +575,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setattributes, port); module->add(wire); - if (net_map.count(net) == 0) - net_map[net] = wire; - else - module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + net_map[net] = wire; } FOREACH_NETBUS_OF_NETLIST(nl, mi, netbus) -- cgit v1.2.3 From cdf12575651da53bff456617be2c5d1f825ba7fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 14:42:07 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 59 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 21aca6d43..1e15ef89f 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -163,11 +163,25 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NAND) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addAndGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_OR) { module->addOrGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; } + if (inst->Type() == PRIM_NOR) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addOrGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_XOR) { module->addXorGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; @@ -183,6 +197,11 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_TRI) { + module->addMuxGate(RTLIL::escape_id(inst->Name()), RTLIL::State::Sz, net_map.at(inst->GetInput()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_FADD) { RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); @@ -224,11 +243,25 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_NAND) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addAnd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_OR) { module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; } + if (inst->Type() == PRIM_NOR) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addOr(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_XOR) { module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; @@ -249,6 +282,11 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_TRI) { + module->addMux(RTLIL::escape_id(inst->Name()), RTLIL::State::Sz, net_map.at(inst->GetInput()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_FADD) { RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); @@ -266,10 +304,10 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapaddDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); else if (inst->GetSet()->IsGnd()) module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), - net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), RTLIL::State::S0); else if (inst->GetReset()->IsGnd()) module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), - net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), RTLIL::State::S1); else module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetReset()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); @@ -419,6 +457,11 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_TRI) { + module->addMux(RTLIL::escape_id(inst->Name()), RTLIL::SigSpec(RTLIL::State::Sz, inst->OutputSize()), IN, net_map.at(inst->GetControl()), OUT); + return true; + } + if (inst->Type() == OPER_WIDE_DFFRS) { RTLIL::SigSpec sig_set = operatorInport(inst, "set", net_map); RTLIL::SigSpec sig_reset = operatorInport(inst, "reset", net_map); @@ -503,7 +546,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(portbus->Name()); wire->width = portbus->Size(); wire->start_offset = std::min(portbus->LeftIndex(), portbus->RightIndex()); - import_attributes(wire->attributes, port); + import_attributes(wire->attributes, portbus); module->add(wire); if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN) @@ -572,7 +615,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(net->Name()); while (module->count_id(wire->name)) wire->name += "_"; - import_attributes(wire->attributes, port); + import_attributes(wire->attributes, net); module->add(wire); net_map[net] = wire; @@ -599,7 +642,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setstart_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); while (module->count_id(wire->name)) wire->name += "_"; - import_attributes(wire->attributes, port); + import_attributes(wire->attributes, netbus); module->add(wire); for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { @@ -706,11 +749,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); + } else { + if (import_netlist_instance_gates(module, net_map, inst)) + continue; } - if (import_netlist_instance_gates(module, net_map, inst)) - continue; - if (inst->IsPrimitive()) log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); -- cgit v1.2.3 From 470c2455e471318f4528da597e0dd8c7499b47ce Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Mar 2014 13:26:52 +0100 Subject: Fixed mapping of Verific FADD primitive with unconnected outputs --- frontends/verific/verific.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1e15ef89f..cf72b7819 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -205,7 +205,8 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_FADD) { RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); - RTLIL::SigSpec x = net_map.at(inst->GetCout()), y = net_map.at(inst->GetOutput()); + RTLIL::SigSpec x = inst->GetCout() ? net_map.at(inst->GetCout()) : module->new_wire(1, NEW_ID); + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); RTLIL::SigSpec tmp3 = module->new_wire(1, NEW_ID); @@ -290,9 +291,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_FADD) { RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = net_map.at(inst->GetOutput()); - y.append(net_map.at(inst->GetCout())); - + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); + if (inst->GetCout()) + y.append(net_map.at(inst->GetCout())); module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); return true; -- cgit v1.2.3 From a3b9692a68e88bbe3e32e0dbbd30c5e20f3800b7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Mar 2014 13:40:01 +0100 Subject: Fixed mapping of Verific WIDE_DFFRS operator --- frontends/verific/verific.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cf72b7819..7411e9434 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -466,9 +466,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_DFFRS) { RTLIL::SigSpec sig_set = operatorInport(inst, "set", net_map); RTLIL::SigSpec sig_reset = operatorInport(inst, "reset", net_map); - if (sig_set.is_fully_const() && !sig_set.as_bool() && sig_set.is_fully_const() && !sig_set.as_bool()) { + if (sig_set.is_fully_const() && !sig_set.as_bool() && sig_reset.is_fully_const() && !sig_reset.as_bool()) module->addDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), IN, OUT); - } else + else module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), sig_set, sig_reset, IN, OUT); return true; } -- cgit v1.2.3 From a1be4816d602548f4454242dc17f8a85ccaa91bd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:22:11 +0200 Subject: Replaced depricated %name-prefix= bison directive --- frontends/ilang/parser.y | 2 +- frontends/verilog/parser.y | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index ebb4d3095..6b41b0873 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -39,7 +39,7 @@ namespace ILANG_FRONTEND { using namespace ILANG_FRONTEND; %} -%name-prefix="rtlil_frontend_ilang_yy" +%name-prefix "rtlil_frontend_ilang_yy" %union { char *string; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 4726f1aa3..ed9be692b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -84,7 +84,7 @@ static void free_attr(std::map *al) %} -%name-prefix="frontend_verilog_yy" +%name-prefix "frontend_verilog_yy" %union { std::string *string; -- cgit v1.2.3 From 7188542155902bcf3880d482d472e91331f8a3ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:28:23 +0200 Subject: Fixed clang -Wdeprecated-register warnings --- frontends/ilang/lexer.l | 7 +++++++ frontends/verilog/lexer.l | 5 +++++ 2 files changed, 12 insertions(+) (limited to 'frontends') diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 000919275..6557f98ab 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -23,9 +23,16 @@ */ %{ + +#ifdef __clang__ +// bison generates code using the 'register' storage class specifier +#pragma clang diagnostic ignored "-Wdeprecated-register" +#endif + #include "kernel/rtlil.h" #include "parser.tab.h" void update_autoidx(const char *p); + %} %option yylineno diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index e3e5e4ab2..226a26709 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -34,6 +34,11 @@ %{ +#ifdef __clang__ +// bison generates code using the 'register' storage class specifier +#pragma clang diagnostic ignored "-Wdeprecated-register" +#endif + #include "kernel/log.h" #include "verilog_frontend.h" #include "frontends/ast/ast.h" -- cgit v1.2.3 From 63dfbb18cfb34d72746565a3eb3ffbcd7451cdab Mon Sep 17 00:00:00 2001 From: Johann Glaser Date: Wed, 28 May 2014 16:50:13 +0200 Subject: new flags -ignore_miss_func and -ignore_miss_dir for read_liberty --- frontends/liberty/liberty.cc | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 485d28ee1..285491e06 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -459,6 +459,13 @@ struct LibertyFrontend : public Frontend { log(" ignore re-definitions of modules. (the default behavior is to\n"); log(" create an error message.)\n"); log("\n"); + log(" -ignore_miss_func\n"); + log(" ignore cells with missing function specification of outputs\n"); + log("\n"); + log(" -ignore_miss_dir\n"); + log(" ignore cells with a missing or invalid direction\n"); + log(" specification on a pin\n"); + log("\n"); log(" -setattr \n"); log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); @@ -467,6 +474,8 @@ struct LibertyFrontend : public Frontend { { bool flag_lib = false; bool flag_ignore_redef = false; + bool flag_ignore_miss_func = false; + bool flag_ignore_miss_dir = false; std::vector attributes; log_header("Executing Liberty frontend.\n"); @@ -482,6 +491,14 @@ struct LibertyFrontend : public Frontend { flag_ignore_redef = true; continue; } + if (arg == "-ignore_miss_func") { + flag_ignore_miss_func = true; + continue; + } + if (arg == "-ignore_miss_dir") { + flag_ignore_miss_dir = true; + continue; + } if (arg == "-setattr" && argidx+1 < args.size()) { attributes.push_back(RTLIL::escape_id(args[++argidx])); continue; @@ -507,11 +524,9 @@ struct LibertyFrontend : public Frontend { } // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); - cell_count++; RTLIL::Module *module = new RTLIL::Module; module->name = cell_name; - design->modules[module->name] = module; for (auto &attr : attributes) module->attributes[attr] = 1; @@ -520,7 +535,16 @@ struct LibertyFrontend : public Frontend { if (node->id == "pin" && node->args.size() == 1) { LibertyAst *dir = node->find("direction"); if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "internal")) - log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + { + if (!flag_ignore_miss_dir) + { + log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + } else { + log("Ignoring cell %s with missing or invalid dircetion for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); + delete module; + goto skip_cell; + } + } if (!flag_lib || dir->value != "internal") module->new_wire(1, RTLIL::escape_id(node->args.at(0))); } @@ -556,7 +580,16 @@ struct LibertyFrontend : public Frontend { LibertyAst *func = node->find("function"); if (func == NULL) - log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + { + if (!flag_ignore_miss_func) + { + log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + } else { + log("Ignoring cell %s with missing function on output %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + delete module; + goto skip_cell; + } + } RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); module->connections.push_back(RTLIL::SigSig(wire, out_sig)); @@ -564,6 +597,9 @@ struct LibertyFrontend : public Frontend { } module->fixup_ports(); + design->modules[module->name] = module; + cell_count++; +skip_cell:; } log("Imported %d cell types from liberty file.\n", cell_count); -- cgit v1.2.3 From f9c1cd5edba5acb4d9b9dd287c7265111cf22087 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 4 Jun 2014 09:10:50 +0200 Subject: Improved error message for options after front-end filename arguments --- frontends/verilog/verilog_frontend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 8e9efa173..108214586 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -48,7 +48,7 @@ struct VerilogFrontend : public Frontend { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" read_verilog [filename]\n"); + log(" read_verilog [options] [filename]\n"); log("\n"); log("Load modules from a verilog file to the current design. A large subset of\n"); log("Verilog-2005 is supported.\n"); -- cgit v1.2.3 From b5cd7a01793294a53d91a2cd3ee9bbca5b9a8c54 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 17:40:04 +0200 Subject: added while and repeat support to verilog parser --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 1 + frontends/verilog/lexer.l | 2 ++ frontends/verilog/parser.y | 28 +++++++++++++++++++++++++++- 4 files changed, 31 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f2f2d0e69..105645f95 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -137,6 +137,7 @@ std::string AST::type2str(AstNodeType type) X(AST_DEFAULT) X(AST_FOR) X(AST_WHILE) + X(AST_REPEAT) X(AST_GENVAR) X(AST_GENFOR) X(AST_GENIF) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 72a2a4600..8f9c35349 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -117,6 +117,7 @@ namespace AST AST_DEFAULT, AST_FOR, AST_WHILE, + AST_REPEAT, AST_GENVAR, AST_GENFOR, diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 226a26709..5300d1b26 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -140,6 +140,8 @@ namespace VERILOG_FRONTEND { "default" { return TOK_DEFAULT; } "generate" { return TOK_GENERATE; } "endgenerate" { return TOK_ENDGENERATE; } +"while" { return TOK_WHILE; } +"repeat" { return TOK_REPEAT; } "assert"([ \t\r\n]+"property")? { return TOK_ASSERT; } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index ed9be692b..a12dcf142 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -98,7 +98,7 @@ static void free_attr(std::map *al) %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL -%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR +%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT %token TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK @@ -819,6 +819,32 @@ behavioral_stmt: ast_stack.pop_back(); ast_stack.pop_back(); } | + attr TOK_WHILE '(' expr ')' { + AstNode *node = new AstNode(AST_WHILE); + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + append_attr(node, $1); + AstNode *block = new AstNode(AST_BLOCK); + ast_stack.back()->children.push_back($4); + ast_stack.back()->children.push_back(block); + ast_stack.push_back(block); + } behavioral_stmt { + ast_stack.pop_back(); + ast_stack.pop_back(); + } | + attr TOK_REPEAT '(' expr ')' { + AstNode *node = new AstNode(AST_REPEAT); + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + append_attr(node, $1); + AstNode *block = new AstNode(AST_BLOCK); + ast_stack.back()->children.push_back($4); + ast_stack.back()->children.push_back(block); + ast_stack.push_back(block); + } behavioral_stmt { + ast_stack.pop_back(); + ast_stack.pop_back(); + } | attr TOK_IF '(' expr ')' { AstNode *node = new AstNode(AST_CASE); AstNode *block = new AstNode(AST_BLOCK); -- cgit v1.2.3 From ab54ce17c82e55cb26bf5c0dd7512decbd941b12 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 17:40:45 +0200 Subject: improved ast simplify of const functions --- frontends/ast/simplify.cc | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a20aacff5..5f40b60a8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -140,7 +140,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_FUNCTION || type == AST_TASK) return false; - // deactivate all calls non-synthesis system taks + // deactivate all calls to non-synthesis system taks if ((type == AST_FCALL || type == AST_TCALL) && (str == "$display" || str == "$stop" || str == "$finish")) { delete_children(); str = std::string(); @@ -245,9 +245,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_ASSIGN_EQ: case AST_ASSIGN_LE: case AST_ASSIGN: - while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) + while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, in_param) == true) did_something = true; - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param) == true) did_something = true; children[0]->detectSignWidth(backup_width_hint, backup_sign_hint); children[1]->detectSignWidth(width_hint, sign_hint); @@ -1825,12 +1825,16 @@ void AstNode::replace_variables(std::map &varia if (type == AST_IDENTIFIER && variables.count(str)) { int offset = variables.at(str).offset, width = variables.at(str).val.bits.size(); if (!children.empty()) { + if (children.size() != 1 || children.at(0)->type != AST_RANGE) + log_error("Memory access in constant function is not supported in %s:%d (called from %s:%d).\n", + filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); + children.at(0)->replace_variables(variables, fcall); while (simplify(true, false, false, 1, -1, false, true)) { } - if (!range_valid) + if (!children.at(0)->range_valid) log_error("Non-constant range in %s:%d (called from %s:%d).\n", filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); - offset = std::min(range_left, range_right); - width = std::min(std::abs(range_left - range_right) + 1, width); + offset = std::min(children.at(0)->range_left, children.at(0)->range_right); + width = std::min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width); } offset -= variables.at(str).offset; std::vector &var_bits = variables.at(str).val.bits; @@ -1850,6 +1854,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) { std::map backup_scope; std::map variables; + bool delete_temp_block = false; AstNode *block = NULL; size_t argidx = 0; @@ -1878,6 +1883,16 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (child->type == AST_ASSIGN_EQ) + { + log_assert(block == NULL); + delete_temp_block = true; + block = new AstNode(AST_BLOCK); + block->children.push_back(child->clone()); + continue; + } + + child->dumpAst(NULL, "unexpected> "); log_abort(); } @@ -1900,8 +1915,11 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) stmt->children.at(1)->replace_variables(variables, fcall); while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + if (stmt->type != AST_ASSIGN_EQ) + continue; + if (stmt->children.at(1)->type != AST_CONSTANT) - log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); if (stmt->children.at(0)->type != AST_IDENTIFIER || !stmt->children.at(0)->children.empty()) @@ -2011,6 +2029,9 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_abort(); } + if (delete_temp_block) + delete block; + for (auto &it : backup_scope) if (it.second == NULL) current_scope.erase(it.first); -- cgit v1.2.3 From 5c10d2ee364c8807d10069ba7be3d1da3d252fa1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 21:29:23 +0200 Subject: fix functions with no block (but single statement, loop, etc.) --- frontends/ast/simplify.cc | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5f40b60a8..47ea880c6 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1883,17 +1883,10 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } - if (child->type == AST_ASSIGN_EQ) - { - log_assert(block == NULL); - delete_temp_block = true; - block = new AstNode(AST_BLOCK); - block->children.push_back(child->clone()); - continue; - } - - child->dumpAst(NULL, "unexpected> "); - log_abort(); + log_assert(block == NULL); + delete_temp_block = true; + block = new AstNode(AST_BLOCK); + block->children.push_back(child->clone()); } log_assert(block != NULL); -- cgit v1.2.3 From 76da2fe172ed6b0822a9e4a8cf9483ef7c8f5f40 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 22:55:02 +0200 Subject: improved const function support --- frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 2 +- frontends/ast/simplify.cc | 43 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8f9c35349..6c5a0eae4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -202,6 +202,7 @@ namespace AST // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; + bool has_const_only_constructs(); void replace_variables(std::map &variables, AstNode *fcall); AstNode *eval_const_function(AstNode *fcall); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c3025913c..2efdee10a 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -579,7 +579,7 @@ struct AST_INTERNAL::ProcessGenerator break; default: - assert(0); + log_abort(); } } }; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 47ea880c6..71e7cbc6d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -606,6 +606,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, goto apply_newNode; } + if (type == AST_WHILE) + log_error("While loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum); + + if (type == AST_REPEAT) + log_error("Repeat loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum); + // unroll for loops and generate-for blocks if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0) { @@ -1181,7 +1187,7 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } - if (in_param) + if (in_param || current_scope[str]->has_const_only_constructs()) { bool all_args_const = true; for (auto child : children) { @@ -1197,7 +1203,10 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } - log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); + if (in_param) + log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); + else + log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } AstNode *decl = current_scope[str]; @@ -1819,6 +1828,19 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) addr_bits++; } +bool AstNode::has_const_only_constructs() +{ + if (type == AST_WHILE || type == AST_REPEAT) + return true; + if (type == AST_FCALL && current_scope.count(str)) + if (current_scope[str]->has_const_only_constructs()) + return true; + for (auto child : children) + if (child->AstNode::has_const_only_constructs()) + return true; + return false; +} + // helper function for AstNode::eval_const_function() void AstNode::replace_variables(std::map &variables, AstNode *fcall) { @@ -1915,7 +1937,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); - if (stmt->children.at(0)->type != AST_IDENTIFIER || !stmt->children.at(0)->children.empty()) + if (stmt->children.at(0)->type != AST_IDENTIFIER) log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); @@ -1923,7 +1945,20 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); - variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + if (stmt->children.at(0)->children.empty()) { + variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + } else { + AstNode *range = stmt->children.at(0)->children.at(0); + if (!range->range_valid) + log_error("Non-constant range in %s:%d (called from %s:%d).\n", + range->filename.c_str(), range->linenum, fcall->filename.c_str(), fcall->linenum); + int offset = std::min(range->range_left, range->range_right); + int width = std::min(std::abs(range->range_left - range->range_right) + 1, width); + varinfo_t &v = variables[stmt->children.at(0)->str]; + RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size()); + for (int i = 0; i < width; i++) + v.val.bits.at(i+offset-v.offset) = r.bits.at(i); + } delete block->children.front(); block->children.erase(block->children.begin()); -- cgit v1.2.3 From 5281562d0e9468c584e6db6f30908e3155a76ad2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 23:05:01 +0200 Subject: made the generate..endgenrate keywords optional --- frontends/verilog/parser.y | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index a12dcf142..42a8f91c5 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -373,6 +373,8 @@ range_or_integer: module_body: module_body module_body_stmt | + /* the following line makes the generate..endgenrate keywords optional */ + module_body gen_stmt | /* empty */; module_body_stmt: @@ -1013,9 +1015,12 @@ single_arg: }; module_gen_body: - module_gen_body gen_stmt | + module_gen_body gen_stmt_or_module_body_stmt | /* empty */; +gen_stmt_or_module_body_stmt: + gen_stmt | module_body_stmt; + // this production creates the obligatory if-else shift/reduce conflict gen_stmt: TOK_FOR '(' { @@ -1054,15 +1059,14 @@ gen_stmt: if ($6 != NULL) delete $6; ast_stack.pop_back(); - } | - module_body_stmt; + }; gen_stmt_block: { AstNode *node = new AstNode(AST_GENBLOCK); ast_stack.back()->children.push_back(node); ast_stack.push_back(node); - } gen_stmt { + } gen_stmt_or_module_body_stmt { ast_stack.pop_back(); }; -- cgit v1.2.3 From 7c8a7b2131aa672d04ee0ed641f3e6b120f3ec49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 00:02:05 +0200 Subject: further improved const function support --- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 10 +++++----- frontends/ast/simplify.cc | 27 ++++++++++++++++----------- 3 files changed, 22 insertions(+), 17 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6c5a0eae4..3e69e3bc0 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -202,7 +202,7 @@ namespace AST // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; - bool has_const_only_constructs(); + bool has_const_only_constructs(bool &recommend_const_eval); void replace_variables(std::map &variables, AstNode *fcall); AstNode *eval_const_function(AstNode *fcall); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 2efdee10a..9273636f4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -623,10 +623,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) if (id_ast->type == AST_AUTOWIRE) this_width = 1; else { - // current_ast_mod->dumpAst(stdout, ""); - // printf("---\n"); - // dumpAst(stdout, ""); - // fflush(stdout); + // current_ast_mod->dumpAst(NULL, "mod> "); + // log("---\n"); + // id_ast->dumpAst(NULL, "decl> "); + // dumpAst(NULL, "ref> "); log_error("Failed to detect with of signal access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); } } else { @@ -693,7 +693,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_REPLICATE: - while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } + while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { } if (children[0]->type != AST_CONSTANT) log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum); children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 71e7cbc6d..8a4d42e1b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -349,12 +349,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (detect_width_simple && width_hint < 0) { + if (type == AST_REPLICATE) + while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, true) == true) + did_something = true; for (auto child : children) while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) did_something = true; - if (type == AST_REPLICATE) - while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) - did_something = true; detectSignWidth(width_hint, sign_hint); } @@ -376,8 +376,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, bool const_fold_here = const_fold, in_lvalue_here = in_lvalue; int width_hint_here = width_hint; bool sign_hint_here = sign_hint; - if (i == 0 && type == AST_REPLICATE) - const_fold_here = true; + bool in_param_here = in_param; + if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE)) + const_fold_here = true, in_param_here = true; if (type == AST_PARAMETER || type == AST_LOCALPARAM) const_fold_here = true; if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE)) @@ -394,7 +395,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint_here = -1, sign_hint_here = false; if (children_are_self_determined) width_hint_here = -1, sign_hint_here = false; - did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param); + did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here); if (did_something_here) did_something = true; } @@ -1187,7 +1188,9 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } - if (in_param || current_scope[str]->has_const_only_constructs()) + bool recommend_const_eval = false; + bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval); + if (in_param || recommend_const_eval || require_const_eval) { bool all_args_const = true; for (auto child : children) { @@ -1205,7 +1208,7 @@ skip_dynamic_range_lvalue_expansion:; if (in_param) log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); - else + if (require_const_eval) log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } @@ -1828,15 +1831,17 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) addr_bits++; } -bool AstNode::has_const_only_constructs() +bool AstNode::has_const_only_constructs(bool &recommend_const_eval) { + if (type == AST_FOR) + recommend_const_eval = true; if (type == AST_WHILE || type == AST_REPEAT) return true; if (type == AST_FCALL && current_scope.count(str)) - if (current_scope[str]->has_const_only_constructs()) + if (current_scope[str]->has_const_only_constructs(recommend_const_eval)) return true; for (auto child : children) - if (child->AstNode::has_const_only_constructs()) + if (child->AstNode::has_const_only_constructs(recommend_const_eval)) return true; return false; } -- cgit v1.2.3 From 0b1ce63a19025f73fe4d2a54253134ea9a4de625 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 10:47:53 +0200 Subject: Added support for repeat stmt in const functions --- frontends/ast/simplify.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8a4d42e1b..e5e8980a2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2001,6 +2001,25 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (stmt->type == AST_REPEAT) + { + AstNode *num = stmt->children.at(0)->clone(); + num->replace_variables(variables, fcall); + while (num->simplify(true, false, false, 1, -1, false, true)) { } + + if (num->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + block->children.erase(block->children.begin()); + for (int i = 0; i < num->bitsAsConst().as_int(); i++) + block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); + + delete stmt; + delete num; + continue; + } + if (stmt->type == AST_CASE) { AstNode *expr = stmt->children.at(0)->clone(); -- cgit v1.2.3 From e275e8eef9ae47670075bd73a671f3acd3c0ca52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 11:48:50 +0200 Subject: Add support for cell arrays --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 25 +++++++++++++++++++++++++ frontends/verilog/parser.y | 7 +++++++ 4 files changed, 34 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 105645f95..0780f7b59 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -127,6 +127,7 @@ std::string AST::type2str(AstNodeType type) X(AST_ASSIGN) X(AST_CELL) X(AST_PRIMITIVE) + X(AST_CELLARRAY) X(AST_ALWAYS) X(AST_INITIAL) X(AST_BLOCK) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 3e69e3bc0..802bf98ff 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -107,6 +107,7 @@ namespace AST AST_ASSIGN, AST_CELL, AST_PRIMITIVE, + AST_CELLARRAY, AST_ALWAYS, AST_INITIAL, AST_BLOCK, diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e5e8980a2..fc040baac 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -878,6 +878,31 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, did_something = true; } + // unroll cell arrays + if (type == AST_CELLARRAY) + { + if (!children.at(0)->range_valid) + log_error("Non-constant array range on cell array at %s:%d.\n", filename.c_str(), linenum); + + newNode = new AstNode(AST_GENBLOCK); + int num = std::max(children.at(0)->range_left, children.at(0)->range_right) - std::min(children.at(0)->range_left, children.at(0)->range_right) + 1; + + for (int i = 0; i < num; i++) { + int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i; + AstNode *new_cell = children.at(1)->clone(); + newNode->children.push_back(new_cell); + new_cell->str += stringf("[%d]", idx); + if (new_cell->type == AST_PRIMITIVE) { + log_error("Cell arrays of primitives are currently not supported at %s:%d.\n", filename.c_str(), linenum); + } else { + log_assert(new_cell->children.at(0)->type == AST_CELLTYPE); + new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str()); + } + } + + goto apply_newNode; + } + // replace primitives with assignmens if (type == AST_PRIMITIVE) { diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 42a8f91c5..f422258c7 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -634,6 +634,13 @@ single_cell: astbuf2->str = *$1; delete $1; ast_stack.back()->children.push_back(astbuf2); + } '(' cell_port_list ')' | + TOK_ID non_opt_range { + astbuf2 = astbuf1->clone(); + if (astbuf2->type != AST_PRIMITIVE) + astbuf2->str = *$1; + delete $1; + ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2)); } '(' cell_port_list ')'; prim_list: -- cgit v1.2.3 From 482d9208aa9dacb7afe21f08c882d4881581013a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jun 2014 11:54:20 +0200 Subject: Added read_verilog -sv options, added support for bit, logic, allways_ff, always_comb, and always_latch --- frontends/verilog/lexer.l | 17 ++++++++++++++++- frontends/verilog/parser.y | 10 ++++++++-- frontends/verilog/verilog_frontend.cc | 10 ++++++++++ frontends/verilog/verilog_frontend.h | 3 +++ 4 files changed, 37 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 5300d1b26..8f4b49916 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -52,6 +52,14 @@ namespace VERILOG_FRONTEND { std::vector ln_stack; } +#define SV_KEYWORD(_tok) \ + if (sv_mode) return _tok; \ + log("Lexer warning: The SystemVerilog keyword `%s' (at %s:%d) is not "\ + "recognized unless read_verilog is called with -sv!\n", yytext, \ + AST::current_filename.c_str(), frontend_verilog_yyget_lineno()); \ + frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \ + return TOK_ID; + %} %option yylineno @@ -143,7 +151,14 @@ namespace VERILOG_FRONTEND { "while" { return TOK_WHILE; } "repeat" { return TOK_REPEAT; } -"assert"([ \t\r\n]+"property")? { return TOK_ASSERT; } +"always_comb" { SV_KEYWORD(TOK_ALWAYS); } +"always_ff" { SV_KEYWORD(TOK_ALWAYS); } +"always_latch" { SV_KEYWORD(TOK_ALWAYS); } + +"assert" { SV_KEYWORD(TOK_ASSERT); } +"property" { SV_KEYWORD(TOK_PROPERTY); } +"logic" { SV_KEYWORD(TOK_REG); } +"bit" { SV_KEYWORD(TOK_REG); } "input" { return TOK_INPUT; } "output" { return TOK_OUTPUT; } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index f422258c7..cce8a8c40 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -54,6 +54,7 @@ namespace VERILOG_FRONTEND { int current_function_or_task_port_id; std::vector case_type_stack; bool default_nettype_wire; + bool sv_mode; } static void append_attr(AstNode *ast, std::map *al) @@ -105,7 +106,7 @@ static void free_attr(std::map *al) %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED -%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT +%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY %type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id @@ -379,7 +380,7 @@ module_body: module_body_stmt: task_func_decl | param_decl | localparam_decl | defparam_decl | wire_decl | assign_stmt | cell_stmt | - always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert; + always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: TOK_TASK TOK_ID ';' { @@ -773,6 +774,11 @@ assert: ast_stack.back()->children.push_back(new AstNode(AST_ASSERT, $3)); }; +assert_property: + TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' { + ast_stack.back()->children.push_back(new AstNode(AST_ASSERT, $4)); + }; + simple_behavioral_stmt: lvalue '=' expr { AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $3); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 108214586..437fc3ec0 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -53,6 +53,10 @@ struct VerilogFrontend : public Frontend { log("Load modules from a verilog file to the current design. A large subset of\n"); log("Verilog-2005 is supported.\n"); log("\n"); + log(" -sv\n"); + log(" enable support for SystemVerilog features. (only a small subset\n"); + log(" of SystemVerilog is supported)\n"); + log("\n"); log(" -dump_ast1\n"); log(" dump abstract syntax tree (before simplification)\n"); log("\n"); @@ -150,7 +154,9 @@ struct VerilogFrontend : public Frontend { std::map defines_map; std::list include_dirs; std::list attributes; + frontend_verilog_yydebug = false; + sv_mode = false; log_header("Executing Verilog-2005 frontend.\n"); @@ -159,6 +165,10 @@ struct VerilogFrontend : public Frontend { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; + if (arg == "-sv") { + sv_mode = true; + continue; + } if (arg == "-dump_ast1") { flag_dump_ast1 = true; continue; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 99b2164ef..6d01a1532 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -45,6 +45,9 @@ namespace VERILOG_FRONTEND // state of `default_nettype extern bool default_nettype_wire; + + // running in SystemVerilog mode + extern bool sv_mode; } // the pre-processor -- cgit v1.2.3 From 7ef0da32cdcddb50de8ba8acf0c6421fe5732c55 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jun 2014 11:29:23 +0200 Subject: Added Verilog lexer and parser support for real values --- frontends/ast/ast.cc | 5 +++++ frontends/ast/ast.h | 2 ++ frontends/verilog/lexer.l | 10 ++++++++++ frontends/verilog/parser.y | 17 ++++++++++++++--- 4 files changed, 31 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0780f7b59..1ce7efc84 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -77,6 +77,7 @@ std::string AST::type2str(AstNodeType type) X(AST_ARGUMENT) X(AST_RANGE) X(AST_CONSTANT) + X(AST_REALVALUE) X(AST_CELLTYPE) X(AST_IDENTIFIER) X(AST_PREFIX) @@ -460,6 +461,10 @@ void AstNode::dumpVlog(FILE *f, std::string indent) fprintf(f, "%zd'b %s", bits.size(), RTLIL::Const(bits).as_string().c_str()); break; + case AST_REALVALUE: + fprintf(f, "%e", realvalue); + break; + case AST_BLOCK: if (children.size() == 1) { children[0]->dumpVlog(f, indent); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 802bf98ff..aeb56e352 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -55,6 +55,7 @@ namespace AST AST_ARGUMENT, AST_RANGE, AST_CONSTANT, + AST_REALVALUE, AST_CELLTYPE, AST_IDENTIFIER, AST_PREFIX, @@ -153,6 +154,7 @@ namespace AST bool is_input, is_output, is_reg, is_signed, is_string, range_valid; int port_id, range_left, range_right; uint32_t integer; + double realvalue; // this is set by simplify and used during RTLIL generation AstNode *id2ast; diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 8f4b49916..ed304572b 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -179,6 +179,16 @@ namespace VERILOG_FRONTEND { return TOK_CONST; } +[0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? { + frontend_verilog_yylval.string = new std::string(yytext); + return TOK_REAL; +} + +[0-9][0-9_]*[eE][-+]?[0-9_]+ { + frontend_verilog_yylval.string = new std::string(yytext); + return TOK_REAL; +} + \" { BEGIN(STRING); } \\. { yymore(); } \" { diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index cce8a8c40..e51712b3f 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -35,7 +35,7 @@ %{ #include -#include +#include #include "verilog_frontend.h" #include "kernel/log.h" @@ -94,7 +94,7 @@ static void free_attr(std::map *al) bool boolean; } -%token TOK_STRING TOK_ID TOK_CONST TOK_PRIMITIVE +%token TOK_STRING TOK_ID TOK_CONST TOK_REAL TOK_PRIMITIVE %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG @@ -221,7 +221,7 @@ module: frontend_verilog_yyerror("Missing details for module port `%s'.", port_stubs.begin()->first.c_str()); ast_stack.pop_back(); - assert(ast_stack.size() == 0); + log_assert(ast_stack.size() == 0); }; module_para_opt: @@ -1133,6 +1133,17 @@ basic_expr: log_error("Value conversion failed: `%s'\n", $1->c_str()); delete $1; } | + TOK_REAL { + $$ = new AstNode(AST_REALVALUE); + char *p = strdup($1->c_str()), *q; + for (int i = 0, j = 0; !p[j]; j++) + if (p[j] != '_') + p[i++] = p[j], p[i] = 0; + $$->realvalue = strtod(p, &q); + log_assert(*q == 0); + delete $1; + free(p); + } | TOK_STRING { $$ = AstNode::mkconst_str(*$1); delete $1; -- cgit v1.2.3 From 9dd16fa41c01c8da2e4905184cce0391a7547fa3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 07:44:19 +0200 Subject: Added real->int convertion in ast genrtlil --- frontends/ast/genrtlil.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9273636f4..5b43f57ff 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -602,6 +602,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) sign_hint = false; break; + case AST_REALVALUE: + width_hint = std::max(width_hint, 32); + break; + case AST_IDENTIFIER: id_ast = id2ast; if (id_ast == NULL && current_scope.count(str)) @@ -909,6 +913,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) return RTLIL::SigSpec(bitsAsConst()); } + case AST_REALVALUE: + { + int intvalue = round(realvalue); + log("Warning: converting real value %e to integer %d at %s:%d.\n", + realvalue, intvalue, filename.c_str(), linenum); + return RTLIL::SigSpec(intvalue); + } + // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node // for identifiers with dynamic bit ranges (e.g. "foo[bar]" or "foo[bar+3:bar]") a // shifter cell is created and the output signal of this cell is returned -- cgit v1.2.3 From 442a8e2875eab679ed3b31aee3d9725b87dbf4fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 08:51:22 +0200 Subject: Implemented basic real arithmetic --- frontends/ast/ast.cc | 31 ++++++++++++++++++++++++++++++- frontends/ast/ast.h | 4 ++++ frontends/ast/simplify.cc | 22 +++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 1ce7efc84..3af08b9d1 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -32,7 +32,7 @@ #include #include -#include +#include using namespace AST; using namespace AST_INTERNAL; @@ -760,6 +760,35 @@ bool AstNode::asBool() return false; } +int AstNode::isConst() +{ + if (type == AST_CONSTANT) + return 1; + if (type == AST_REALVALUE) + return 2; + return 0; +} + +double AstNode::asReal(bool is_signed) +{ + if (type == AST_CONSTANT) { + RTLIL::Const val; + val.bits = bits; + + double p = exp2(val.bits.size()-32); + if (val.bits.size() > 32) + val.bits.erase(val.bits.begin(), val.bits.begin()+(val.bits.size()-32)); + int32_t v = val.as_int() << (32-val.bits.size()); + + if (is_signed) + return v * p; + return uint32_t(v) * p; + } + if (type == AST_REALVALUE) + return realvalue; + return 0; +} + // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer) { diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index aeb56e352..95f0f142f 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -240,6 +240,10 @@ namespace AST RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); bool asBool(); + + // helper functions for real valued const eval + int isConst(); // return '1' for AST_CONSTANT and '2' for AST_REALVALUE + double asReal(bool is_signed); }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index fc040baac..7e4c265bd 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -32,7 +32,7 @@ #include #include -#include +#include using namespace AST; using namespace AST_INTERNAL; @@ -1433,10 +1433,22 @@ skip_dynamic_range_lvalue_expansion:; if (0) { case AST_MUL: const_func = RTLIL::const_mul; } if (0) { case AST_DIV: const_func = RTLIL::const_div; } if (0) { case AST_MOD: const_func = RTLIL::const_mod; } - if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { - RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), - children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); - newNode = mkconst_bits(y.bits, sign_hint); + if (children[0]->isConst() && children[1]->isConst()) { + if (children[0]->isConst() + children[1]->isConst() > 2) { + newNode = new AstNode(AST_REALVALUE); + switch (type) { + case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break; + case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break; + case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break; + case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break; + case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break; + default: log_abort(); + } + } else { + RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), + children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); + newNode = mkconst_bits(y.bits, sign_hint); + } } break; if (0) { case AST_POS: const_func = RTLIL::const_pos; } -- cgit v1.2.3 From fc7b6d172a67965c89d84696e5f2cf1218855ea5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 11:27:05 +0200 Subject: Implemented more real arithmetic --- frontends/ast/simplify.cc | 97 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 27 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7e4c265bd..77bab6b0d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1348,7 +1348,9 @@ skip_dynamic_range_lvalue_expansion:; } else if (children.size() == 0) newNode = current_scope[str]->children[0]->clone(); - } + } else + if (current_scope[str]->children[0]->isConst()) + newNode = current_scope[str]->children[0]->clone(); } else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) { newNode = mkconst_int(0, sign_hint, width_hint); @@ -1391,6 +1393,9 @@ skip_dynamic_range_lvalue_expansion:; if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1); newNode = mkconst_bits(y.bits, false); + } else + if (children[0]->isConst()) { + newNode = mkconst_int(children[0]->asReal(sign_hint) == 0, false, 1); } break; if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; } @@ -1399,6 +1404,12 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits), children[0]->is_signed, children[1]->is_signed, -1); newNode = mkconst_bits(y.bits, false); + } else + if (children[0]->isConst() && children[1]->isConst()) { + if (type == AST_LOGIC_AND) + newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1); + else + newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1); } break; if (0) { case AST_SHIFT_LEFT: const_func = RTLIL::const_shl; } @@ -1410,6 +1421,10 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint); newNode = mkconst_bits(y.bits, sign_hint); + } else + if (type == AST_POW && children[0]->isConst() && children[1]->isConst()) { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = pow(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); } break; if (0) { case AST_LT: const_func = RTLIL::const_lt; } @@ -1426,6 +1441,19 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed), children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1); newNode = mkconst_bits(y.bits, false); + } else + if (children[0]->isConst() && children[1]->isConst()) { + switch (type) { + case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); + case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); + case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); + case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); + case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); + case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); + case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); + case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); + default: log_abort(); + } } break; if (0) { case AST_ADD: const_func = RTLIL::const_add; } @@ -1433,21 +1461,20 @@ skip_dynamic_range_lvalue_expansion:; if (0) { case AST_MUL: const_func = RTLIL::const_mul; } if (0) { case AST_DIV: const_func = RTLIL::const_div; } if (0) { case AST_MOD: const_func = RTLIL::const_mod; } + if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { + RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), + children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); + newNode = mkconst_bits(y.bits, sign_hint); + } else if (children[0]->isConst() && children[1]->isConst()) { - if (children[0]->isConst() + children[1]->isConst() > 2) { - newNode = new AstNode(AST_REALVALUE); - switch (type) { - case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break; - case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break; - case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break; - case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break; - case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break; - default: log_abort(); - } - } else { - RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), - children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); - newNode = mkconst_bits(y.bits, sign_hint); + newNode = new AstNode(AST_REALVALUE); + switch (type) { + case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break; + case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break; + case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break; + case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break; + case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break; + default: log_abort(); } } break; @@ -1456,29 +1483,45 @@ skip_dynamic_range_lvalue_expansion:; if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint); newNode = mkconst_bits(y.bits, sign_hint); + } else + if (children[0]->isConst()) { + newNode = new AstNode(AST_REALVALUE); + if (type == AST_POS) + newNode->realvalue = +children[0]->asReal(sign_hint); + else + newNode->realvalue = -children[0]->asReal(sign_hint); } break; case AST_TERNARY: - if (children[0]->type == AST_CONSTANT) { + if (children[0]->isConst()) { bool found_sure_true = false; bool found_maybe_true = false; - for (auto &bit : children[0]->bits) { - if (bit == RTLIL::State::S1) - found_sure_true = true; - if (bit > RTLIL::State::S1) - found_maybe_true = true; + if (children[0]->type == AST_CONSTANT) { + for (auto &bit : children[0]->bits) { + if (bit == RTLIL::State::S1) + found_sure_true = true; + if (bit > RTLIL::State::S1) + found_maybe_true = true; + } + } else { + found_sure_true = children[0]->asReal(false) != 0; } AstNode *choice = NULL; if (found_sure_true) choice = children[1]; else if (!found_maybe_true) choice = children[2]; - if (choice != NULL && choice->type == AST_CONSTANT) { - RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); - if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) - newNode = mkconst_str(y.bits); - else - newNode = mkconst_bits(y.bits, sign_hint); + if (choice != NULL) { + if (choice->type == AST_CONSTANT) { + RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); + if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) + newNode = mkconst_str(y.bits); + else + newNode = mkconst_bits(y.bits, sign_hint); + } else + if (choice->isConst()) { + newNode = choice->clone(); + } } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) { RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint); RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint); -- cgit v1.2.3 From 9bd7d5c46856f25fd7befcdfe20198fd8eb59ccd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 12:00:47 +0200 Subject: Added handling of real-valued parameters/localparams --- frontends/ast/ast.cc | 13 ++++++++---- frontends/ast/simplify.cc | 51 ++++++++++++++++++++++++++++++++++------------ frontends/verilog/lexer.l | 5 +++-- frontends/verilog/parser.y | 17 +++++++++++----- 4 files changed, 62 insertions(+), 24 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3af08b9d1..f3cf8fa7a 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -185,6 +185,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2) range_left = -1; range_right = 0; integer = 0; + realvalue = 0; id2ast = NULL; basic_prep = false; @@ -278,6 +279,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) fprintf(f, " range=[%d:%d]%s", range_left, range_right, range_valid ? "" : "!"); if (integer != 0) fprintf(f, " int=%u", (int)integer); + if (realvalue != 0) + fprintf(f, " real=%e", realvalue); fprintf(f, "\n"); for (auto &it : attributes) { @@ -775,18 +778,20 @@ double AstNode::asReal(bool is_signed) RTLIL::Const val; val.bits = bits; - double p = exp2(val.bits.size()-32); + double p = exp2(int(val.bits.size())-32); if (val.bits.size() > 32) - val.bits.erase(val.bits.begin(), val.bits.begin()+(val.bits.size()-32)); - int32_t v = val.as_int() << (32-val.bits.size()); + val.bits.erase(val.bits.begin(), val.bits.begin()+(int(val.bits.size())-32)); + int32_t v = val.as_int() << (32-int(val.bits.size())); if (is_signed) return v * p; return uint32_t(v) * p; } + if (type == AST_REALVALUE) return realvalue; - return 0; + + log_abort(); } // create a new AstModule from an AST_MODULE AST node diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 77bab6b0d..a5c4d0230 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -48,6 +48,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *newNode = NULL; bool did_something = false; +#if 0 + log("-------------\n"); + log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n", + int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param)); + dumpAst(NULL, "> "); +#endif + if (stage == 0) { assert(type == AST_MODULE); @@ -260,8 +267,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) did_something = true; children[0]->detectSignWidth(width_hint, sign_hint); - if (children.size() > 1) { - assert(children[1]->type == AST_RANGE); + if (children.size() > 1 && children[1]->type == AST_RANGE) { while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) did_something = true; if (!children[1]->range_valid) @@ -519,18 +525,37 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } // trim/extend parameters - if ((type == AST_PARAMETER || type == AST_LOCALPARAM) && children[0]->type == AST_CONSTANT && children.size() > 1) { - if (!children[1]->range_valid) - log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); - int width = children[1]->range_left - children[1]->range_right + 1; - if (width != int(children[0]->bits.size())) { - RTLIL::SigSpec sig(children[0]->bits); - sig.extend_u0(width, children[0]->is_signed); - AstNode *old_child_0 = children[0]; - children[0] = mkconst_bits(sig.as_const().bits, children[0]->is_signed); - delete old_child_0; + if (type == AST_PARAMETER || type == AST_LOCALPARAM) { + if (children.size() > 1 && children[1]->type == AST_RANGE) { + if (children[0]->type == AST_REALVALUE) { + int intvalue = round(children[0]->realvalue); + log("Warning: converting real value %e to integer %d at %s:%d.\n", + children[0]->realvalue, intvalue, filename.c_str(), linenum); + delete children[0]; + children[0] = mkconst_int(intvalue, sign_hint); + did_something = true; + } + if (children[0]->type == AST_CONSTANT) { + if (!children[1]->range_valid) + log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); + int width = children[1]->range_left - children[1]->range_right + 1; + if (width != int(children[0]->bits.size())) { + RTLIL::SigSpec sig(children[0]->bits); + sig.extend_u0(width, children[0]->is_signed); + AstNode *old_child_0 = children[0]; + children[0] = mkconst_bits(sig.as_const().bits, children[0]->is_signed); + delete old_child_0; + } + children[0]->is_signed = is_signed; + } + } else + if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) { + double as_realvalue = children[0]->asReal(sign_hint); + delete children[0]; + children[0] = new AstNode(AST_REALVALUE); + children[0]->realvalue = as_realvalue; + did_something = true; } - children[0]->is_signed = is_signed; } // annotate identifiers using scope resolution and create auto-wires as needed diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index ed304572b..0839f5cf9 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -168,6 +168,7 @@ namespace VERILOG_FRONTEND { "integer" { return TOK_INTEGER; } "signed" { return TOK_SIGNED; } "genvar" { return TOK_GENVAR; } +"real" { return TOK_REAL; } [0-9]+ { frontend_verilog_yylval.string = new std::string(yytext); @@ -181,12 +182,12 @@ namespace VERILOG_FRONTEND { [0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? { frontend_verilog_yylval.string = new std::string(yytext); - return TOK_REAL; + return TOK_REALVAL; } [0-9][0-9_]*[eE][-+]?[0-9_]+ { frontend_verilog_yylval.string = new std::string(yytext); - return TOK_REAL; + return TOK_REALVAL; } \" { BEGIN(STRING); } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index e51712b3f..57defd56b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -94,7 +94,7 @@ static void free_attr(std::map *al) bool boolean; } -%token TOK_STRING TOK_ID TOK_CONST TOK_REAL TOK_PRIMITIVE +%token TOK_STRING TOK_ID TOK_CONST TOK_REALVAL TOK_PRIMITIVE %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG @@ -103,7 +103,7 @@ static void free_attr(std::map *al) %token TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK -%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR +%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY @@ -438,6 +438,13 @@ param_integer: astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); } | /* empty */; +param_real: + TOK_REAL { + if (astbuf1->children.size() != 1) + frontend_verilog_yyerror("Syntax error."); + astbuf1->children.push_back(new AstNode(AST_REALVALUE)); + } | /* empty */; + param_range: range { if ($1 != NULL) { @@ -451,7 +458,7 @@ param_decl: TOK_PARAMETER { astbuf1 = new AstNode(AST_PARAMETER); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); - } param_signed param_integer param_range param_decl_list ';' { + } param_signed param_integer param_real param_range param_decl_list ';' { delete astbuf1; }; @@ -459,7 +466,7 @@ localparam_decl: TOK_LOCALPARAM { astbuf1 = new AstNode(AST_LOCALPARAM); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); - } param_signed param_integer param_range param_decl_list ';' { + } param_signed param_integer param_real param_range param_decl_list ';' { delete astbuf1; }; @@ -1133,7 +1140,7 @@ basic_expr: log_error("Value conversion failed: `%s'\n", $1->c_str()); delete $1; } | - TOK_REAL { + TOK_REALVAL { $$ = new AstNode(AST_REALVALUE); char *p = strdup($1->c_str()), *q; for (int i = 0, j = 0; !p[j]; j++) -- cgit v1.2.3 From f3b4a9dd2466d243fdb1b4ebf8c5e1e0d05d21af Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 13:36:23 +0200 Subject: Added support for math functions --- frontends/ast/simplify.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a5c4d0230..89dc8ef73 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1215,6 +1215,10 @@ skip_dynamic_range_lvalue_expansion:; { if (str == "\\$clog2") { + if (children.size() != 1) + log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", + RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + AstNode *buf = children[0]->clone(); while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) @@ -1230,6 +1234,72 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } + if (str == "\\$ln" || str == "\\$log10" || str == "\\$exp" || str == "\\$sqrt" || str == "\\$pow" || + str == "\\$floor" || str == "\\$ceil" || str == "\\$sin" || str == "\\$cos" || str == "\\$tan" || + str == "\\$asin" || str == "\\$acos" || str == "\\$atan" || str == "\\$atan2" || str == "\\$hypot" || + str == "\\$sinh" || str == "\\$cosh" || str == "\\$tanh" || str == "\\$asinh" || str == "\\$acosh" || str == "\\$atanh") + { + bool func_with_two_arguments = str == "\\$pow" || str == "\\$atan2" || str == "\\$hypot"; + double x = 0, y = 0; + + if (func_with_two_arguments) { + if (children.size() != 2) + log_error("System function %s got %d arguments, expected 2 at %s:%d.\n", + RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + } else { + if (children.size() != 1) + log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", + RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + } + + if (children.size() >= 1) { + while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + if (!children[0]->isConst()) + log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", + RTLIL::id2cstr(str), filename.c_str(), linenum); + int child_width_hint = width_hint; + bool child_sign_hint = sign_hint; + children[0]->detectSignWidth(child_width_hint, child_sign_hint); + x = children[0]->asReal(child_sign_hint); + } + + if (children.size() >= 2) { + while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + if (!children[1]->isConst()) + log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", + RTLIL::id2cstr(str), filename.c_str(), linenum); + int child_width_hint = width_hint; + bool child_sign_hint = sign_hint; + children[1]->detectSignWidth(child_width_hint, child_sign_hint); + y = children[1]->asReal(child_sign_hint); + } + + 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); + else log_abort(); + goto apply_newNode; + } + if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } -- cgit v1.2.3 From d5765b5e14319c20a62a20f470e8ec5dc48d0010 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 19:33:58 +0200 Subject: Fixed relational operators for const real expressions --- frontends/ast/simplify.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 89dc8ef73..61bc03b9f 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1539,14 +1539,14 @@ skip_dynamic_range_lvalue_expansion:; } else if (children[0]->isConst() && children[1]->isConst()) { switch (type) { - case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); - case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); - case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); - case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); - case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); - case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); - case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); - case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); + case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); break; + case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); break; + case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; + case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; + case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; + case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; + case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); break; + case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); break; default: log_abort(); } } -- cgit v1.2.3 From 149fe83a8dbe37fecc16326163bbc40400147a9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 20:38:05 +0200 Subject: improved (fixed) conversion of real values to bit vectors --- frontends/ast/ast.cc | 18 ++++++++++++++++++ frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 8 ++++---- frontends/ast/simplify.cc | 14 +++++++------- 4 files changed, 30 insertions(+), 11 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f3cf8fa7a..25ea3a824 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -794,6 +794,24 @@ double AstNode::asReal(bool is_signed) log_abort(); } +RTLIL::Const AstNode::realAsConst(int width) +{ + double v = round(realvalue); + RTLIL::Const result; + if (!isfinite(v)) { + result.bits = std::vector(width, RTLIL::State::Sx); + } else { + bool is_negative = v < 0; + if (is_negative) + v *= -1; + for (int i = 0; i < width; i++, v /= 2) + result.bits.push_back((int(v) & 1) ? RTLIL::State::S1 : RTLIL::State::S0); + if (is_negative) + result = const_neg(result, result, false, false, result.bits.size()); + } + return result; +} + // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer) { diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 95f0f142f..74a476b5e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -244,6 +244,7 @@ namespace AST // helper functions for real valued const eval int isConst(); // return '1' for AST_CONSTANT and '2' for AST_REALVALUE double asReal(bool is_signed); + RTLIL::Const realAsConst(int width); }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 5b43f57ff..8a57a0ee7 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -915,10 +915,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_REALVALUE: { - int intvalue = round(realvalue); - log("Warning: converting real value %e to integer %d at %s:%d.\n", - realvalue, intvalue, filename.c_str(), linenum); - return RTLIL::SigSpec(intvalue); + RTLIL::SigSpec sig = realAsConst(width_hint); + log("Warning: converting real value %e to binary %s at %s:%d.\n", + realvalue, log_signal(sig), filename.c_str(), linenum); + return sig; } // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 61bc03b9f..ed5ee1721 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -527,18 +527,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // trim/extend parameters if (type == AST_PARAMETER || type == AST_LOCALPARAM) { if (children.size() > 1 && children[1]->type == AST_RANGE) { + if (!children[1]->range_valid) + log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); + int width = children[1]->range_left - children[1]->range_right + 1; if (children[0]->type == AST_REALVALUE) { - int intvalue = round(children[0]->realvalue); - log("Warning: converting real value %e to integer %d at %s:%d.\n", - children[0]->realvalue, intvalue, filename.c_str(), linenum); + RTLIL::Const constvalue = children[0]->realAsConst(width); + log("Warning: converting real value %e to binary %s at %s:%d.\n", + realvalue, log_signal(constvalue), filename.c_str(), linenum); delete children[0]; - children[0] = mkconst_int(intvalue, sign_hint); + children[0] = mkconst_bits(constvalue.bits, sign_hint); did_something = true; } if (children[0]->type == AST_CONSTANT) { - if (!children[1]->range_valid) - log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); - int width = children[1]->range_left - children[1]->range_right + 1; if (width != int(children[0]->bits.size())) { RTLIL::SigSpec sig(children[0]->bits); sig.extend_u0(width, children[0]->is_signed); -- cgit v1.2.3 From 48dc6ab98dbd74bd7eb00f14b4bd8429531166f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:38:31 +0200 Subject: Improved AstNode::asReal for large integers --- frontends/ast/ast.cc | 21 ++++++++++++--------- frontends/ast/simplify.cc | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 25ea3a824..cc7f442bb 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -775,17 +775,20 @@ int AstNode::isConst() double AstNode::asReal(bool is_signed) { if (type == AST_CONSTANT) { - RTLIL::Const val; - val.bits = bits; + RTLIL::Const val(bits); - double p = exp2(int(val.bits.size())-32); - if (val.bits.size() > 32) - val.bits.erase(val.bits.begin(), val.bits.begin()+(int(val.bits.size())-32)); - int32_t v = val.as_int() << (32-int(val.bits.size())); + bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1; + if (is_negative) + val = const_neg(val, val, false, false, val.bits.size()); - if (is_signed) - return v * p; - return uint32_t(v) * p; + double v = 0; + for (size_t i = 0; i < val.bits.size(); i++) + if (val.bits.at(i) == RTLIL::State::S1) + v += exp2(i); + if (is_negative) + v *= -1; + + return v; } if (type == AST_REALVALUE) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index ed5ee1721..80fd28d55 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -533,7 +533,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (children[0]->type == AST_REALVALUE) { RTLIL::Const constvalue = children[0]->realAsConst(width); log("Warning: converting real value %e to binary %s at %s:%d.\n", - realvalue, log_signal(constvalue), filename.c_str(), linenum); + children[0]->realvalue, log_signal(constvalue), filename.c_str(), linenum); delete children[0]; children[0] = mkconst_bits(constvalue.bits, sign_hint); did_something = true; -- cgit v1.2.3 From 7f57bc838517a5660beaf0645d7bb4cc6ed71ce9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:48:17 +0200 Subject: Improved parsing of large integer constants --- frontends/verilog/const2ast.cc | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index c95ce5dc4..8491a6b47 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -52,6 +52,8 @@ static int my_decimal_div_by_two(std::vector &digits) carry = digits[i] % 2; digits[i] /= 2; } + while (!digits.empty() && !digits.front()) + digits.erase(digits.begin()); return carry; } @@ -90,10 +92,15 @@ static void my_strtobin(std::vector &data, const char *str, int le if (base == 10) { data.clear(); - if (len_in_bits < 0) - len_in_bits = ceil(digits.size()/log10(2)); - for (int i = 0; i < len_in_bits; i++) - data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + if (len_in_bits < 0) { + while (!digits.empty()) + data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + while (data.size() < 32) + data.push_back(RTLIL::S0); + } else { + for (int i = 0; i < len_in_bits; i++) + data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + } return; } @@ -151,20 +158,24 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) str = code.c_str(); char *endptr; - long intval = strtol(str, &endptr, 10); + long len_in_bits = strtol(str, &endptr, 10); + + // Simple base-10 integer + if (*endptr == 0) { + std::vector data; + my_strtobin(data, str, -1, 10, case_type); + if (data.back() == RTLIL::S1) + data.push_back(RTLIL::S0); + return AstNode::mkconst_bits(data, true); + } - // Simple 32 bit integer - if (*endptr == 0) - return AstNode::mkconst_int(intval, true); - // unsized constant if (str == endptr) - intval = -1; + len_in_bits = -1; // The "'s?[bodh]" syntax if (*endptr == '\'') { - int len_in_bits = intval; std::vector data; bool is_signed = false; if (*(endptr+1) == 's') { @@ -188,6 +199,12 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) default: return NULL; } + if (len_in_bits < 0) { + if (is_signed && data.back() == RTLIL::S1) + data.push_back(RTLIL::S0); + while (data.size() < 32) + data.push_back(RTLIL::S0); + } return AstNode::mkconst_bits(data, is_signed); } -- cgit v1.2.3 From 4d1df128fa42a9e6718f38e794be8b2f8c2ff7c7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 09:27:09 +0200 Subject: Improved AstNode::realAsConst for large numbers --- frontends/ast/ast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index cc7f442bb..967111d30 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -808,7 +808,7 @@ RTLIL::Const AstNode::realAsConst(int width) if (is_negative) v *= -1; for (int i = 0; i < width; i++, v /= 2) - result.bits.push_back((int(v) & 1) ? RTLIL::State::S1 : RTLIL::State::S0); + result.bits.push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0); if (is_negative) result = const_neg(result, result, false, false, result.bits.size()); } -- cgit v1.2.3 From 5bfe865cec15c12e2a9e764a0a57c01f97f8235e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:00:57 +0200 Subject: Added found_real feature to AstNode::detectSignWidth --- frontends/ast/ast.h | 4 ++-- frontends/ast/genrtlil.cc | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 74a476b5e..f89af633e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -214,8 +214,8 @@ namespace AST void dumpVlog(FILE *f, std::string indent); // used by genRTLIL() for detecting expression width and sign - void detectSignWidthWorker(int &width_hint, bool &sign_hint); - void detectSignWidth(int &width_hint, bool &sign_hint); + void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL); + void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL); // create RTLIL code for this AST node // for expressions the resulting signal vector is returned diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 8a57a0ee7..1f0ef4450 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -585,7 +585,7 @@ struct AST_INTERNAL::ProcessGenerator }; // detect sign and width of an expression -void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) +void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real) { std::string type_name; bool sub_sign_hint = true; @@ -603,6 +603,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_REALVALUE: + if (found_real) + *found_real = true; width_hint = std::max(width_hint, 32); break; @@ -788,10 +790,13 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) } // detect sign and width of an expression -void AstNode::detectSignWidth(int &width_hint, bool &sign_hint) +void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real) { - width_hint = -1, sign_hint = true; - detectSignWidthWorker(width_hint, sign_hint); + width_hint = -1; + sign_hint = true; + if (found_real) + *found_real = false; + detectSignWidthWorker(width_hint, sign_hint, found_real); } // create RTLIL from an AST node -- cgit v1.2.3 From 0c4c79c4c6f8a433ef4b141b1523bccc261f8231 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:02:40 +0200 Subject: Fixed parsing of TOK_INTEGER (implies TOK_SIGNED) --- frontends/verilog/parser.y | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 57defd56b..37c3232aa 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -108,7 +108,7 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY -%type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type wire_type range non_opt_range range_or_signed_int expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -322,6 +322,7 @@ wire_type_token: astbuf3->is_reg = true; astbuf3->range_left = 31; astbuf3->range_right = 0; + astbuf3->is_signed = true; } | TOK_GENVAR { astbuf3->type = AST_GENVAR; @@ -362,7 +363,7 @@ range: $$ = NULL; }; -range_or_integer: +range_or_signed_int: range { $$ = $1; } | @@ -370,6 +371,7 @@ range_or_integer: $$ = new AstNode(AST_RANGE); $$->children.push_back(AstNode::mkconst_int(31, true)); $$->children.push_back(AstNode::mkconst_int(0, true)); + $$->is_signed = true; }; module_body: @@ -394,16 +396,19 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range_or_integer TOK_ID ';' { + TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$4; ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); AstNode *outreg = new AstNode(AST_WIRE); - if ($3 != NULL) - outreg->children.push_back($3); outreg->str = *$4; outreg->is_signed = $2; + if ($3 != NULL) { + outreg->children.push_back($3); + outreg->is_signed = $2 || $3->is_signed; + $3->is_signed = false; + } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; delete $4; @@ -436,6 +441,7 @@ param_integer: astbuf1->children.push_back(new AstNode(AST_RANGE)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); + astbuf1->is_signed = true; } | /* empty */; param_real: -- cgit v1.2.3 From 82bbd2f0772e62555eb669eb64883d75de4ca29a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:05:37 +0200 Subject: Use undef (x/z vs. NaN) rules for real values from IEEE Std 1800-2012 --- frontends/ast/ast.cc | 2 ++ frontends/ast/simplify.cc | 9 +++++++++ 2 files changed, 11 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 967111d30..3f704bea4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -783,6 +783,8 @@ double AstNode::asReal(bool is_signed) double v = 0; for (size_t i = 0; i < val.bits.size(); i++) + // IEEE Std 1800-2012 Par 6.12.2: Individual bits that are x or z in + // the net or the variable shall be treated as zero upon conversion. if (val.bits.at(i) == RTLIL::State::S1) v += exp2(i); if (is_negative) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 80fd28d55..3f712510b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1625,6 +1625,15 @@ skip_dynamic_range_lvalue_expansion:; if (a.bits[i] != b.bits[i]) a.bits[i] = RTLIL::State::Sx; newNode = mkconst_bits(a.bits, sign_hint); + } else if (children[1]->isConst() && children[2]->isConst()) { + newNode = new AstNode(AST_REALVALUE); + if (children[1]->asReal(sign_hint) == children[2]->asReal(sign_hint)) + newNode->realvalue = children[1]->asReal(sign_hint); + else + // IEEE Std 1800-2012 Sec. 11.4.11 states that the entry in Table 7-1 for + // the data type in question should be returned if the ?: is ambiguous. The + // value in Table 7-1 for the 'real' type is 0.0. + newNode->realvalue = 0.0; } } break; -- cgit v1.2.3 From 6c17d4f242ae2acb1581869b3ca904a0adbddc13 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:12:24 +0200 Subject: Improved ternary support for real values --- frontends/ast/simplify.cc | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 3f712510b..7be287d19 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1588,31 +1588,42 @@ skip_dynamic_range_lvalue_expansion:; } break; case AST_TERNARY: - if (children[0]->isConst()) { + if (children[0]->isConst()) + { bool found_sure_true = false; bool found_maybe_true = false; - if (children[0]->type == AST_CONSTANT) { + + if (children[0]->type == AST_CONSTANT) for (auto &bit : children[0]->bits) { if (bit == RTLIL::State::S1) found_sure_true = true; if (bit > RTLIL::State::S1) found_maybe_true = true; } - } else { - found_sure_true = children[0]->asReal(false) != 0; - } - AstNode *choice = NULL; + else + found_sure_true = children[0]->asReal(sign_hint) != 0; + + AstNode *choice = NULL, *not_choice = NULL; if (found_sure_true) - choice = children[1]; + choice = children[1], not_choice = children[2]; else if (!found_maybe_true) - choice = children[2]; + choice = children[2], not_choice = children[1]; + if (choice != NULL) { if (choice->type == AST_CONSTANT) { - RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); - if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) - newNode = mkconst_str(y.bits); - else - newNode = mkconst_bits(y.bits, sign_hint); + int other_width_hint = width_hint; + bool other_sign_hint = sign_hint, other_real = false; + not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real); + if (other_real) { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = choice->asReal(sign_hint); + } else { + RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); + if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) + newNode = mkconst_str(y.bits); + else + newNode = mkconst_bits(y.bits, sign_hint); + } } else if (choice->isConst()) { newNode = choice->clone(); -- cgit v1.2.3 From 798ff88855a6e9b8eb82a48fb4d39f78807200d9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 12:47:51 +0200 Subject: Improved handling of relational op of real values --- frontends/ast/simplify.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7be287d19..7a98e2712 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1538,15 +1538,16 @@ skip_dynamic_range_lvalue_expansion:; newNode = mkconst_bits(y.bits, false); } else if (children[0]->isConst() && children[1]->isConst()) { + bool cmp_signed = (children[0]->type == AST_REALVALUE || children[0]->is_signed) && (children[1]->type == AST_REALVALUE || children[1]->is_signed); switch (type) { - case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); break; - case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); break; - case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; - case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; - case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; - case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; - case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); break; - case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); break; + case AST_LT: newNode = mkconst_int(children[0]->asReal(cmp_signed) < children[1]->asReal(cmp_signed), false, 1); break; + case AST_LE: newNode = mkconst_int(children[0]->asReal(cmp_signed) <= children[1]->asReal(cmp_signed), false, 1); break; + case AST_EQ: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; + case AST_NE: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; + case AST_EQX: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; + case AST_NEX: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; + case AST_GE: newNode = mkconst_int(children[0]->asReal(cmp_signed) >= children[1]->asReal(cmp_signed), false, 1); break; + case AST_GT: newNode = mkconst_int(children[0]->asReal(cmp_signed) > children[1]->asReal(cmp_signed), false, 1); break; default: log_abort(); } } -- cgit v1.2.3 From 80e459469576b82975a5cf663b4aba2e044d9476 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 21:39:25 +0200 Subject: Added AstNode::MEM2REG_FL_CMPLX_LHS --- frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index f89af633e..8253a2052 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -188,6 +188,7 @@ namespace AST MEM2REG_FL_SET_ELSE = 0x00000400, MEM2REG_FL_SET_ASYNC = 0x00000800, MEM2REG_FL_EQ2 = 0x00001000, + MEM2REG_FL_CMPLX_LHS = 0x00002000, /* proc flags */ MEM2REG_FL_EQ1 = 0x01000000, diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7a98e2712..0b0e46f2c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -90,6 +90,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE)) goto verbose_activate; + if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS) + goto verbose_activate; + // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags)); continue; @@ -1757,6 +1760,21 @@ void AstNode::replace_ids(std::map &rules) child->replace_ids(rules); } +// helper function for mem2reg_as_needed_pass1 +static void mark_memories_assign_lhs_complex(std::map> &mem2reg_places, + std::map &mem2reg_candidates, AstNode *that) +{ + for (auto &child : that->children) + mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, child); + + if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) { + AstNode *mem = that->id2ast; + if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS)) + mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->linenum)); + mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS; + } +} + // find memories that should be replaced by registers void AstNode::mem2reg_as_needed_pass1(std::map> &mem2reg_places, std::map &mem2reg_candidates, std::map &proc_flags, uint32_t &flags) @@ -1766,6 +1784,10 @@ void AstNode::mem2reg_as_needed_pass1(std::map> if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) { + // mark all memories that are used in a complex expression on the left side of an assignment + for (auto &lhs_child : children[0]->children) + mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, lhs_child); + if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY) { AstNode *mem = children[0]->id2ast; -- cgit v1.2.3 From 65b2e9c0645c30d84a9d9be148430fd76d3e5f05 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 21:41:13 +0200 Subject: fixed signdness detection for expressions with reals --- frontends/ast/genrtlil.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 1f0ef4450..9f18efce0 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -594,6 +594,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun AstNode *range = NULL; AstNode *id_ast = NULL; + bool local_found_real = false; + if (found_real == NULL) + found_real = &local_found_real; + switch (type) { case AST_CONSTANT: @@ -603,8 +607,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; case AST_REALVALUE: - if (found_real) - *found_real = true; + *found_real = true; width_hint = std::max(width_hint, 32); break; @@ -787,6 +790,9 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun log_error("Don't know how to detect sign and width for %s node at %s:%d!\n", type2str(type).c_str(), filename.c_str(), linenum); } + + if (*found_real) + sign_hint = true; } // detect sign and width of an expression -- cgit v1.2.3 From 4fc43d19324eabcfe3a3788743a212ae684509cd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 24 Jun 2014 15:08:48 +0200 Subject: More found_real-related fixes to AstNode::detectSignWidthWorker --- frontends/ast/genrtlil.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9f18efce0..787f4d2d8 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -713,7 +713,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_NEG: case AST_BIT_NOT: case AST_POS: - children[0]->detectSignWidthWorker(width_hint, sign_hint); + children[0]->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_BIT_AND: @@ -721,7 +721,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_BIT_XOR: case AST_BIT_XNOR: for (auto child : children) - child->detectSignWidthWorker(width_hint, sign_hint); + child->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_REDUCE_AND: @@ -738,7 +738,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_SHIFT_SLEFT: case AST_SHIFT_SRIGHT: case AST_POW: - children[0]->detectSignWidthWorker(width_hint, sign_hint); + children[0]->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_LT: @@ -759,7 +759,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_DIV: case AST_MOD: for (auto child : children) - child->detectSignWidthWorker(width_hint, sign_hint); + child->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_LOGIC_AND: @@ -770,8 +770,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; case AST_TERNARY: - children.at(1)->detectSignWidthWorker(width_hint, sign_hint); - children.at(2)->detectSignWidthWorker(width_hint, sign_hint); + children.at(1)->detectSignWidthWorker(width_hint, sign_hint, found_real); + children.at(2)->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_MEMRD: -- cgit v1.2.3 From 076182c34e34b5e59eb5d89d5001f7547102bb4d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 25 Jun 2014 10:05:36 +0200 Subject: Fixed handling of mixed real/int ternary expressions --- frontends/ast/simplify.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 0b0e46f2c..db7f5ca34 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -247,6 +247,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, bool detect_width_simple = false; bool child_0_is_self_determined = false; bool child_1_is_self_determined = false; + bool child_2_is_self_determined = false; bool children_are_self_determined = false; bool reset_width_after_children = false; @@ -367,6 +368,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, detectSignWidth(width_hint, sign_hint); } + if (type == AST_TERNARY) { + int width_hint_left, width_hint_right; + bool sign_hint_left, sign_hint_right; + bool found_real_left, found_real_right; + children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left); + children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right); + if (found_real_left || found_real_right) { + child_1_is_self_determined = true; + child_2_is_self_determined = true; + } + } + // simplify all children first // (iterate by index as e.g. auto wires can add new children in the process) for (size_t i = 0; i < children.size(); i++) { @@ -402,6 +415,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint_here = -1, sign_hint_here = false; if (i == 1 && child_1_is_self_determined) width_hint_here = -1, sign_hint_here = false; + if (i == 2 && child_2_is_self_determined) + width_hint_here = -1, sign_hint_here = false; if (children_are_self_determined) width_hint_here = -1, sign_hint_here = false; did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here); @@ -1620,6 +1635,7 @@ skip_dynamic_range_lvalue_expansion:; not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real); if (other_real) { newNode = new AstNode(AST_REALVALUE); + choice->detectSignWidth(width_hint, sign_hint); newNode->realvalue = choice->asReal(sign_hint); } else { RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); -- cgit v1.2.3 From ee8ad72fd950e1ee204e5c97155a50b8b1445dec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Jul 2014 06:27:04 +0200 Subject: fixed parsing of constant with comment between size and value --- frontends/verilog/parser.y | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'frontends') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 37c3232aa..ce7b99272 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -1140,6 +1140,13 @@ basic_expr: delete $1; delete $2; } | + TOK_CONST TOK_CONST { + $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back()); + if ($$ == NULL || (*$2)[0] != '\'') + log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str()); + delete $1; + delete $2; + } | TOK_CONST { $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back()); if ($$ == NULL) -- cgit v1.2.3 From 55a1b8dbac91373979289c535bed61a32717f62b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 11 Jul 2014 13:05:53 +0200 Subject: Fixed processing of initial values for block-local variables --- frontends/ast/simplify.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index db7f5ca34..e547ede36 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -423,6 +423,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (did_something_here) did_something = true; } + if (stage == 2 && children[i]->type == AST_INITIAL && current_ast_mod != this) { + current_ast_mod->children.push_back(children[i]); + children.erase(children.begin() + (i--)); + did_something = true; + } } for (auto &attr : attributes) { while (attr.second->simplify(true, false, false, stage, -1, false, true)) -- cgit v1.2.3 From 0f9ca49dc6047ad5634782de23040ec57601debd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 12 Jul 2014 10:02:39 +0200 Subject: Added passing of various options to vhdl2verilog --- frontends/vhdl2verilog/vhdl2verilog.cc | 41 +++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 83035d329..4392ed444 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -45,13 +45,25 @@ struct Vhdl2verilogPass : public Pass { log(" specified file.\n"); log("\n"); log(" -vhdl2verilog_dir \n"); - log(" do use the specified vhdl2verilog installations. this is the directory\n"); + log(" do use the specified vhdl2verilog installation. this is the directory\n"); log(" that contains the setup_env.sh file. when this option is not present,\n"); log(" it is assumed that vhdl2verilog is in the PATH environment variable.\n"); log("\n"); log(" -top \n"); log(" The name of the top entity. This option is mandatory.\n"); log("\n"); + log("The following options are passed as-is to vhdl2verilog:\n"); + log("\n"); + log(" -arch \n"); + log(" -unroll_generate\n"); + log(" -nogenericeval\n"); + log(" -nouniquify\n"); + log(" -oldparser\n"); + log(" -suppress \n"); + log(" -quiet\n"); + log(" -nobanner\n"); + log(" -mapfile \n"); + log("\n"); log("vhdl2verilog can be obtained from:\n"); log("http://www.edautils.com/vhdl2verilog.html\n"); log("\n"); @@ -63,6 +75,7 @@ struct Vhdl2verilogPass : public Pass { std::string out_file, top_entity; std::string vhdl2verilog_dir; + std::string extra_opts; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -78,6 +91,24 @@ struct Vhdl2verilogPass : public Pass { vhdl2verilog_dir = args[++argidx]; continue; } + if ((args[argidx] == "-arch" || args[argidx] == "-suppress" || args[argidx] == "-mapfile") && argidx+1 < args.size()) { + if (args[argidx] == "-mapfile" && !args[argidx+1].empty() && args[argidx+1][0] != '/') { + char pwd[PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s", strerror(errno)); + log_abort(); + } + args[argidx+1] = pwd + ("/" + args[argidx+1]); + } + extra_opts += std::string(" ") + args[argidx]; + extra_opts += std::string(" '") + args[++argidx] + std::string("'"); + continue; + } + if (args[argidx] == "-unroll_generate" || args[argidx] == "-nogenericeval" || args[argidx] == "-nouniquify" || + args[argidx] == "-oldparser" || args[argidx] == "-quiet" || args[argidx] == "-nobanner") { + extra_opts += std::string(" ") + args[argidx]; + continue; + } break; } @@ -95,7 +126,7 @@ struct Vhdl2verilogPass : public Pass { log_error("For some reason mkdtemp() failed!\n"); if (!out_file.empty() && out_file[0] != '/') { - char pwd [PATH_MAX]; + char pwd[PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { log_cmd_error("getcwd failed: %s", strerror(errno)); log_abort(); @@ -109,7 +140,7 @@ struct Vhdl2verilogPass : public Pass { if (file.empty()) continue; if (file[0] != '/') { - char pwd [PATH_MAX]; + char pwd[PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { log_cmd_error("getcwd failed: %s", strerror(errno)); log_abort(); @@ -124,8 +155,8 @@ struct Vhdl2verilogPass : public Pass { std::string command = "exec 2>&1; "; if (!vhdl2verilog_dir.empty()) command += stringf("cd '%s'; . ./setup_env.sh; ", vhdl2verilog_dir.c_str()); - command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'", tempdir_name, - out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str()); + command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'%s", tempdir_name, + out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str(), extra_opts.c_str()); log("Running '%s'..\n", command.c_str()); -- cgit v1.2.3 From 543551b80a257ce0d55ce2d97fed165da7750360 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 12:23:47 +0200 Subject: changes in verilog frontend for new $mem/$memwr WR_EN interface --- frontends/ast/genrtlil.cc | 3 --- frontends/ast/simplify.cc | 10 ++++++---- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 787f4d2d8..a2fdcf8b1 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1287,9 +1287,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->connections["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); cell->connections["\\EN"] = children[2]->genRTLIL(); - if (cell->connections["\\EN"].width > 1) - cell->connections["\\EN"] = uniop2rtlil(this, "$reduce_bool", 1, cell->connections["\\EN"], false); - cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); cell->parameters["\\WIDTH"] = RTLIL::Const(current_module->memories[str]->width); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e547ede36..ba0dca139 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1177,17 +1177,19 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_data->str] = wire_data; while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } - AstNode *wire_en = new AstNode(AST_WIRE); + AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_en->str = id_en; current_ast_mod->children.push_back(wire_en); current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - std::vector x_bits_addr, x_bits_data; + std::vector x_bits_addr, x_bits_data, set_bits_en; for (int i = 0; i < addr_bits; i++) x_bits_addr.push_back(RTLIL::State::Sx); for (int i = 0; i < mem_width; i++) x_bits_data.push_back(RTLIL::State::Sx); + for (int i = 0; i < mem_width; i++) + set_bits_en.push_back(RTLIL::State::S1); AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); assign_addr->children[0]->str = id_addr; @@ -1195,7 +1197,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); assign_data->children[0]->str = id_data; - AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1)); + AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); assign_en->children[0]->str = id_en; AstNode *default_signals = new AstNode(AST_BLOCK); @@ -1210,7 +1212,7 @@ skip_dynamic_range_lvalue_expansion:; assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone()); assign_data->children[0]->str = id_data; - assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1)); + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); assign_en->children[0]->str = id_en; newNode = new AstNode(AST_BLOCK); -- cgit v1.2.3 From 24f58e57f3048f7f3e84115364b392389d124c7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:02:28 +0200 Subject: Fixed spelling of "direction" in read_liberty messages --- frontends/liberty/liberty.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 285491e06..7a74c5fcb 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -538,9 +538,9 @@ struct LibertyFrontend : public Frontend { { if (!flag_ignore_miss_dir) { - log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); } else { - log("Ignoring cell %s with missing or invalid dircetion for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); + log("Ignoring cell %s with missing or invalid direction for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); delete module; goto skip_cell; } -- cgit v1.2.3 From 5057935722edca26b13cb3a158a443d16a6445da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:12:16 +0200 Subject: Set blackbox attribute in "read_liberty -lib" --- frontends/liberty/liberty.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 7a74c5fcb..398e7a30e 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -528,6 +528,9 @@ struct LibertyFrontend : public Frontend { RTLIL::Module *module = new RTLIL::Module; module->name = cell_name; + if (flag_lib) + module->set_bool_attribute("\\blackbox"); + for (auto &attr : attributes) module->attributes[attr] = 1; -- cgit v1.2.3 From b171a4c1bce1146c890f8238a723a277c8dc2efb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:12:46 +0200 Subject: Added "inout" ports support to read_liberty --- frontends/liberty/liberty.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 398e7a30e..e7af93720 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -537,7 +537,7 @@ struct LibertyFrontend : public Frontend { for (auto node : cell->children) if (node->id == "pin" && node->args.size() == 1) { LibertyAst *dir = node->find("direction"); - if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "internal")) + if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal")) { if (!flag_ignore_miss_dir) { @@ -570,6 +570,11 @@ struct LibertyFrontend : public Frontend { RTLIL::Wire *wire = module->wires.at(RTLIL::escape_id(node->args.at(0))); + if (dir && dir->value == "inout") { + wire->port_input = true; + wire->port_output = true; + } + if (dir && dir->value == "input") { wire->port_input = true; continue; -- cgit v1.2.3 From 6d69d4aaa81f176ec97654b5103f6f59eb98c211 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 13:13:21 +0200 Subject: Added support for constant bit- or part-select for memory writes --- frontends/ast/simplify.cc | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index ba0dca139..320c80d72 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -607,9 +607,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } // split memory access with bit select to individual statements - if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE) + if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue) { - if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1 || in_lvalue) + if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1) log_error("Invalid bit-select on memory access at %s:%d!\n", filename.c_str(), linenum); int mem_width, mem_size, addr_bits; @@ -1150,9 +1150,9 @@ skip_dynamic_range_lvalue_expansion:; // assignment with memory in left-hand side expression -> replace with memory write port if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER && - children[0]->children.size() == 1 && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && - children[0]->id2ast->children.size() >= 2 && children[0]->id2ast->children[0]->range_valid && - children[0]->id2ast->children[1]->range_valid) + children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 && + children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid && + (children[0]->children.size() == 1 || children[0]->children.size() == 2)) { std::stringstream sstr; sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); @@ -1209,11 +1209,38 @@ skip_dynamic_range_lvalue_expansion:; assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; - assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone()); - assign_data->children[0]->str = id_data; + if (children[0]->children.size() == 2) + { + if (children[0]->children[1]->range_valid) + { + int offset = children[0]->children[1]->range_right; + int width = children[0]->children[1]->range_left - offset + 1; - assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); - assign_en->children[0]->str = id_en; + std::vector padding_x(offset, RTLIL::State::Sx); + + for (int i = 0; i < mem_width; i++) + set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0; + + assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone())); + assign_data->children[0]->str = id_data; + + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en->children[0]->str = id_en; + } + else + { + log_error("Writing to memories with dynamic bit- or part-select is not supported yet at %s:%d.\n", filename.c_str(), linenum); + } + } + else + { + assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone()); + assign_data->children[0]->str = id_data; + + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en->children[0]->str = id_en; + } newNode = new AstNode(AST_BLOCK); newNode->children.push_back(assign_addr); -- cgit v1.2.3 From 5867f6bcdc10cbccc196a6889f5242c0f090a2f1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 13:49:32 +0200 Subject: Added support for bit/part select to mem2reg rewriter --- frontends/ast/simplify.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 320c80d72..eee5a7b39 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1974,6 +1974,8 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * continue; AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK)); AstNode *assign_reg = new AstNode(type, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER)); + if (children[0]->children.size() == 2) + assign_reg->children[0]->children.push_back(children[0]->children[1]->clone()); assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i); assign_reg->children[1]->str = id_data; cond_node->children[1]->children.push_back(assign_reg); @@ -1990,6 +1992,10 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * if (type == AST_IDENTIFIER && id2ast && mem2reg_set.count(id2ast) > 0) { + AstNode *bit_part_sel = NULL; + if (children.size() == 2) + bit_part_sel = children[1]->clone(); + if (children[0]->children[0]->type == AST_CONSTANT) { int id = children[0]->children[0]->integer; @@ -2073,6 +2079,9 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * id2ast = NULL; str = id_data; } + + if (bit_part_sel) + children.push_back(bit_part_sel); } assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0); -- cgit v1.2.3 From 9b183539af4adf7d2a127042ca384806c7e73367 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 16:49:23 +0200 Subject: Implemented dynamic bit-/part-select for memory writes --- frontends/ast/simplify.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index eee5a7b39..f819b2506 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1159,7 +1159,7 @@ skip_dynamic_range_lvalue_expansion:; std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN"; if (type == AST_ASSIGN_EQ) - log("Warining: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n", + log("Warning: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n", filename.c_str(), linenum); int mem_width, mem_size, addr_bits; @@ -1230,7 +1230,31 @@ skip_dynamic_range_lvalue_expansion:; } else { - log_error("Writing to memories with dynamic bit- or part-select is not supported yet at %s:%d.\n", filename.c_str(), linenum); + AstNode *the_range = children[0]->children[1]; + AstNode *left_at_zero_ast = the_range->children[0]->clone(); + AstNode *right_at_zero_ast = the_range->children.size() >= 2 ? the_range->children[1]->clone() : left_at_zero_ast->clone(); + AstNode *offset_ast = right_at_zero_ast->clone(); + + while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) + log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); + int width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1; + + for (int i = 0; i < mem_width; i++) + set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0; + + assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone())); + assign_data->children[0]->str = id_data; + + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone())); + assign_en->children[0]->str = id_en; + + delete left_at_zero_ast; + delete right_at_zero_ast; + delete offset_ast; } } else -- cgit v1.2.3 From 1d88f1cf9f2088de7825f5292db5b40d4f73d036 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:35:06 +0200 Subject: Removed deprecated module->new_wire() --- frontends/liberty/liberty.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index e7af93720..cf243f63a 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -227,8 +227,8 @@ static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) static void create_ff(RTLIL::Module *module, LibertyAst *node) { - RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); - RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1)))); RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig; bool clk_polarity = true, clear_polarity = true, preset_polarity = true; @@ -309,8 +309,8 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) static void create_latch(RTLIL::Module *module, LibertyAst *node) { - RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); - RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1)))); RTLIL::SigSpec enable_sig, data_sig, clear_sig, preset_sig; bool enable_polarity = true, clear_polarity = true, preset_polarity = true; @@ -549,7 +549,7 @@ struct LibertyFrontend : public Frontend { } } if (!flag_lib || dir->value != "internal") - module->new_wire(1, RTLIL::escape_id(node->args.at(0))); + module->addWire(RTLIL::escape_id(node->args.at(0))); } for (auto node : cell->children) -- cgit v1.2.3 From 361e0d62ffd90b87c94bfc98ed3cbee1a745cd8f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:41:29 +0200 Subject: Replaced depricated NEW_WIRE macro with module->addWire() calls --- frontends/liberty/liberty.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index cf243f63a..9000d7024 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -58,7 +58,7 @@ static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) cell->name = NEW_ID; cell->type = "$_INV_"; cell->connections["\\A"] = A; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -70,7 +70,7 @@ static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, R cell->type = "$_XOR_"; cell->connections["\\A"] = A; cell->connections["\\B"] = B; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -82,7 +82,7 @@ static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, R cell->type = "$_AND_"; cell->connections["\\A"] = A; cell->connections["\\B"] = B; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -94,7 +94,7 @@ static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RT cell->type = "$_OR_"; cell->connections["\\A"] = A; cell->connections["\\B"] = B; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -370,7 +370,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) inv->name = NEW_ID; inv->type = "$_INV_"; inv->connections["\\A"] = clear_sig; - inv->connections["\\Y"] = NEW_WIRE(module, 1);; + inv->connections["\\Y"] = module->addWire(NEW_ID); module->add(inv); if (clear_polarity == true) @@ -384,7 +384,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) data_gate->type = "$_AND_"; data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = clear_negative; - data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(data_gate); RTLIL::Cell *enable_gate = new RTLIL::Cell; @@ -392,7 +392,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = clear_enable; - enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(enable_gate); } @@ -407,7 +407,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) inv->name = NEW_ID; inv->type = "$_INV_"; inv->connections["\\A"] = preset_sig; - inv->connections["\\Y"] = NEW_WIRE(module, 1);; + inv->connections["\\Y"] = module->addWire(NEW_ID); module->add(inv); if (preset_polarity == false) @@ -421,7 +421,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) data_gate->type = "$_OR_"; data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = preset_positive; - data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(data_gate); RTLIL::Cell *enable_gate = new RTLIL::Cell; @@ -429,7 +429,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = preset_enable; - enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(enable_gate); } -- cgit v1.2.3 From 4147b55c233013dd861172f13d0b9669598d234c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 15:15:18 +0200 Subject: Added "autoidx" statement to ilang file format --- frontends/ilang/lexer.l | 27 +++------------------------ frontends/ilang/parser.y | 8 +++++++- 2 files changed, 10 insertions(+), 25 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 6557f98ab..c40b81af8 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -31,7 +31,6 @@ #include "kernel/rtlil.h" #include "parser.tab.h" -void update_autoidx(const char *p); %} @@ -44,6 +43,7 @@ void update_autoidx(const char *p); %% +"autoidx" { return TOK_AUTOIDX; } "module" { return TOK_MODULE; } "attribute" { return TOK_ATTRIBUTE; } "parameter" { return TOK_PARAMETER; } @@ -76,11 +76,11 @@ void update_autoidx(const char *p); [a-z]+ { return TOK_INVALID; } "\\"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } -"$"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); update_autoidx(yytext); return TOK_ID; } +"$"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } "."[0-9]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } [0-9]+'[01xzm-]* { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_VALUE; } -[0-9]+ { rtlil_frontend_ilang_yylval.integer = atoi(yytext); return TOK_INT; } +-?[0-9]+ { rtlil_frontend_ilang_yylval.integer = atoi(yytext); return TOK_INT; } \" { BEGIN(STRING); } \\. { yymore(); } @@ -124,27 +124,6 @@ void update_autoidx(const char *p); %% -void update_autoidx(const char *p) -{ - if (*p != '$') - return; - - while (*p) { - if (*(p++) != '$') - continue; - if ('0' <= *p && *p <= '9') { - const char *q = p; - while ('0' <= *q && *q <= '9') - q++; - if ((q - p) < 10) { - int idx = atoi(p); - if (idx >= RTLIL::autoidx) - RTLIL::autoidx = idx+1; - } - } - } -} - // this is a hack to avoid the 'yyinput defined but not used' error msgs void *rtlil_frontend_ilang_avoid_input_warnings() { return (void*)&yyinput; diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 6b41b0873..d8ecf37b7 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -50,7 +50,7 @@ using namespace ILANG_FRONTEND; %token TOK_ID TOK_VALUE TOK_STRING %token TOK_INT -%token TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT +%token TOK_AUTOIDX TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT %token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC %token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_INIT %token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET @@ -82,6 +82,7 @@ optional_eol: design: design module | design attr_stmt | + design autoidx_stmt | /* empty */; module: @@ -113,6 +114,11 @@ attr_stmt: free($2); }; +autoidx_stmt: + TOK_AUTOIDX TOK_INT EOL { + RTLIL::autoidx = std::max(RTLIL::autoidx, $2); + }; + wire_stmt: TOK_WIRE { current_wire = new RTLIL::Wire; -- cgit v1.2.3 From d6d0e08834560e824cc59027b720401a1c0b1fc7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:18:05 +0200 Subject: Fixed make rules for ilang parser --- frontends/ilang/Makefile.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc index 07ebf0856..f81c8de91 100644 --- a/frontends/ilang/Makefile.inc +++ b/frontends/ilang/Makefile.inc @@ -4,10 +4,12 @@ GENFILES += frontends/ilang/parser.tab.h GENFILES += frontends/ilang/parser.output GENFILES += frontends/ilang/lexer.cc -frontends/ilang/parser.tab.cc frontends/ilang/parser.tab.h: frontends/ilang/parser.y +frontends/ilang/parser.tab.cc: frontends/ilang/parser.y bison -d -r all -b frontends/ilang/parser frontends/ilang/parser.y mv frontends/ilang/parser.tab.c frontends/ilang/parser.tab.cc +frontends/ilang/parser.tab.h: frontends/ilang/parser.tab.cc + frontends/ilang/lexer.cc: frontends/ilang/lexer.l flex -o frontends/ilang/lexer.cc frontends/ilang/lexer.l -- cgit v1.2.3 From 3b5f4ff39c94a5a664043f35b95a50240ffe9d12 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:35:58 +0200 Subject: Fixed ilang parsing of process attributes --- frontends/ilang/parser.y | 1 + 1 file changed, 1 insertion(+) (limited to 'frontends') diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index d8ecf37b7..cb438775f 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -225,6 +225,7 @@ proc_stmt: switch_stack.push_back(¤t_process->root_case.switches); case_stack.clear(); case_stack.push_back(¤t_process->root_case); + attrbuf.clear(); free($2); } case_body sync_list TOK_END EOL; -- cgit v1.2.3 From a233762a815fc180b371f699e865a7d7aed77bca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 19:56:17 +0200 Subject: SigSpec refactoring: renamed chunks and width to __chunks and __width --- frontends/ast/genrtlil.cc | 120 +++++++++++++++++++++---------------------- frontends/ilang/parser.y | 28 +++++----- frontends/liberty/liberty.cc | 16 +++--- 3 files changed, 82 insertions(+), 82 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index a2fdcf8b1..dc9f566c1 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -62,8 +62,8 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; if (gen_attributes) for (auto &attr : that->attributes) { @@ -74,7 +74,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.__width); cell->connections["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; @@ -85,7 +85,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) { - if (width <= sig.width) { + if (width <= sig.__width) { sig.extend(width, is_signed); return; } @@ -111,8 +111,8 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s chunk.offset = 0; RTLIL::SigSpec new_sig; - new_sig.chunks.push_back(chunk); - new_sig.width = chunk.width; + new_sig.__chunks.push_back(chunk); + new_sig.__width = chunk.width; if (that != NULL) for (auto &attr : that->attributes) { @@ -123,7 +123,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s } cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.__width); cell->connections["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; @@ -155,8 +155,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -168,8 +168,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\B_SIGNED"] = RTLIL::Const(that->children[1]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.width); - cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.__width); + cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.__width); cell->connections["\\A"] = left; cell->connections["\\B"] = right; @@ -182,7 +182,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi // helper function for creating RTLIL code for multiplexers static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - assert(cond.width == 1); + assert(cond.__width == 1); std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); @@ -196,7 +196,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::Wire *wire = new RTLIL::Wire; wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); wire->name = cell->name + "_Y"; - wire->width = left.width; + wire->width = left.__width; current_module->wires[wire->name] = wire; RTLIL::SigChunk chunk; @@ -205,8 +205,8 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const chunk.offset = 0; RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -215,7 +215,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->parameters["\\WIDTH"] = RTLIL::Const(left.width); + cell->parameters["\\WIDTH"] = RTLIL::Const(left.__width); cell->connections["\\A"] = right; cell->connections["\\B"] = left; @@ -311,7 +311,7 @@ struct AST_INTERNAL::ProcessGenerator // create initial assignments for the temporary signals if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) { subst_rvalue_from = subst_lvalue_from; - subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.width); + subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.__width); } else { addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from); } @@ -321,22 +321,22 @@ struct AST_INTERNAL::ProcessGenerator if (child->type == AST_BLOCK) processAst(child); - if (initSyncSignals.width > 0) + if (initSyncSignals.__width > 0) { RTLIL::SyncRule *sync = new RTLIL::SyncRule; sync->type = RTLIL::SyncType::STi; proc->syncs.push_back(sync); - assert(init_lvalue.width == init_rvalue.width); + assert(init_lvalue.__width == init_rvalue.__width); init_lvalue.optimize(); init_rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < init_lvalue.chunks.size(); i++) { - RTLIL::SigSpec lhs = init_lvalue.chunks[i]; - RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.chunks[i].width); + for (size_t i = 0; i < init_lvalue.__chunks.size(); i++) { + RTLIL::SigSpec lhs = init_lvalue.__chunks[i]; + RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.__chunks[i].width); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.width; + offset += lhs.__width; } } } @@ -345,9 +345,9 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { sig.optimize(); - for (size_t i = 0; i < sig.chunks.size(); i++) + for (size_t i = 0; i < sig.__chunks.size(); i++) { - RTLIL::SigChunk &chunk = sig.chunks[i]; + RTLIL::SigChunk &chunk = sig.__chunks[i]; if (chunk.wire == NULL) continue; @@ -426,23 +426,23 @@ struct AST_INTERNAL::ProcessGenerator // are avoided and the generated $mux cells have a more "natural" size. void addChunkActions(std::vector &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool inSyncRule = false) { - if (inSyncRule && initSyncSignals.width > 0) { + if (inSyncRule && initSyncSignals.__width > 0) { init_lvalue.append(lvalue.extract(initSyncSignals)); init_rvalue.append(lvalue.extract(initSyncSignals, &rvalue)); lvalue.remove2(initSyncSignals, &rvalue); } - assert(lvalue.width == rvalue.width); + assert(lvalue.__width == rvalue.__width); lvalue.optimize(); rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < lvalue.chunks.size(); i++) { - RTLIL::SigSpec lhs = lvalue.chunks[i]; - RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks[i].width); - if (inSyncRule && lvalue.chunks[i].wire && lvalue.chunks[i].wire->get_bool_attribute("\\nosync")) - rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.width); + for (size_t i = 0; i < lvalue.__chunks.size(); i++) { + RTLIL::SigSpec lhs = lvalue.__chunks[i]; + RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.__chunks[i].width); + if (inSyncRule && lvalue.__chunks[i].wire && lvalue.__chunks[i].wire->get_bool_attribute("\\nosync")) + rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.__width); actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.width; + offset += lhs.__width; } } @@ -460,7 +460,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_LE: { RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.width, &subst_rvalue_from, &subst_rvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.__width, &subst_rvalue_from, &subst_rvalue_to); lvalue.replace(subst_lvalue_from, subst_lvalue_to); if (ast->type == AST_ASSIGN_EQ) { @@ -533,7 +533,7 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.width, &subst_rvalue_from, &subst_rvalue_to)); + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.__width, &subst_rvalue_from, &subst_rvalue_to)); } if (default_case != current_case) sw->cases.push_back(current_case); @@ -1002,8 +1002,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); @@ -1016,7 +1016,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_TO_SIGNED: case AST_TO_UNSIGNED: { RTLIL::SigSpec sig = children[0]->genRTLIL(); - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, sign_hint); is_signed = sign_hint; return sig; @@ -1025,15 +1025,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // concatenation of signals can be done directly using RTLIL::SigSpec case AST_CONCAT: { RTLIL::SigSpec sig; - sig.width = 0; + sig.__width = 0; for (auto it = children.begin(); it != children.end(); it++) { RTLIL::SigSpec s = (*it)->genRTLIL(); - for (size_t i = 0; i < s.chunks.size(); i++) { - sig.chunks.push_back(s.chunks[i]); - sig.width += s.chunks[i].width; + for (size_t i = 0; i < s.__chunks.size(); i++) { + sig.__chunks.push_back(s.__chunks[i]); + sig.__width += s.__chunks[i].width; } } - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, false); return sig; } @@ -1048,7 +1048,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec sig; for (int i = 0; i < count; i++) sig.append(right); - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, false); is_signed = false; return sig; @@ -1061,7 +1061,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint); is_signed = children[0]->is_signed; - int width = arg.width; + int width = arg.__width; if (width_hint > 0) { width = width_hint; widthExtend(this, arg, width, is_signed, "$pos"); @@ -1079,7 +1079,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); - int width = std::max(left.width, right.width); + int width = std::max(left.__width, right.__width); if (width_hint > 0) width = width_hint; is_signed = children[0]->is_signed && children[1]->is_signed; @@ -1102,7 +1102,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (0) { case AST_REDUCE_BOOL: type_name = "$reduce_bool"; } { RTLIL::SigSpec arg = children[0]->genRTLIL(); - RTLIL::SigSpec sig = arg.width > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; + RTLIL::SigSpec sig = arg.__width > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; return sig; } @@ -1116,7 +1116,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(); - int width = width_hint > 0 ? width_hint : left.width; + int width = width_hint > 0 ? width_hint : left.__width; is_signed = children[0]->is_signed; return binop2rtlil(this, type_name, width, left, right); } @@ -1131,10 +1131,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(right_width, right_signed); - int width = width_hint > 0 ? width_hint : left.width; + int width = width_hint > 0 ? width_hint : left.__width; is_signed = children[0]->is_signed; if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed) - return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.width), right); + return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.__width), right); return binop2rtlil(this, "$pow", width, left, right); } @@ -1170,7 +1170,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); #if 0 - int width = std::max(left.width, right.width); + int width = std::max(left.__width, right.__width); if (width > width_hint && width_hint > 0) width = width_hint; if (width < width_hint) { @@ -1179,10 +1179,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (type == AST_SUB && (!children[0]->is_signed || !children[1]->is_signed)) width = width_hint; if (type == AST_MUL) - width = std::min(left.width + right.width, width_hint); + width = std::min(left.__width + right.__width, width_hint); } #else - int width = std::max(std::max(left.width, right.width), width_hint); + int width = std::max(std::max(left.__width, right.__width), width_hint); #endif is_signed = children[0]->is_signed && children[1]->is_signed; return binop2rtlil(this, type_name, width, left, right); @@ -1214,17 +1214,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); - if (cond.width > 1) + if (cond.__width > 1) cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); - int width = std::max(val1.width, val2.width); + int width = std::max(val1.__width, val2.__width); is_signed = children[1]->is_signed && children[2]->is_signed; widthExtend(this, val1, width, is_signed, "$bu0"); widthExtend(this, val2, width, is_signed, "$bu0"); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, sign_hint); return sig; } @@ -1304,10 +1304,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(children.size() == 2); RTLIL::SigSpec check = children[0]->genRTLIL(); - log_assert(check.width == 1); + log_assert(check.__width == 1); RTLIL::SigSpec en = children[1]->genRTLIL(); - log_assert(en.width == 1); + log_assert(en.__width == 1); std::stringstream sstr; sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); @@ -1335,11 +1335,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); - RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.width); + RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.__width); current_module->connections.push_back(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); - RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.width); + RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.__width); current_module->connections.push_back(RTLIL::SigSig(left, right)); } } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index cb438775f..e6d3d4c5b 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -363,8 +363,8 @@ sigspec: chunk.offset = 0; chunk.data = *$1; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = chunk.width; + $$->__chunks.push_back(chunk); + $$->__width = chunk.width; delete $1; } | TOK_ID { @@ -375,8 +375,8 @@ sigspec: chunk.width = current_module->wires[$1]->width; chunk.offset = 0; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = chunk.width; + $$->__chunks.push_back(chunk); + $$->__width = chunk.width; free($1); } | TOK_ID '[' TOK_INT ']' { @@ -387,8 +387,8 @@ sigspec: chunk.offset = $3; chunk.width = 1; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = 1; + $$->__chunks.push_back(chunk); + $$->__width = 1; free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { @@ -399,8 +399,8 @@ sigspec: chunk.width = $3 - $5 + 1; chunk.offset = $5; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = chunk.width; + $$->__chunks.push_back(chunk); + $$->__width = chunk.width; free($1); } | '{' sigspec_list '}' { @@ -410,13 +410,13 @@ sigspec: sigspec_list: sigspec_list sigspec { $$ = new RTLIL::SigSpec; - for (auto it = $2->chunks.begin(); it != $2->chunks.end(); it++) { - $$->chunks.push_back(*it); - $$->width += it->width; + for (auto it = $2->__chunks.begin(); it != $2->__chunks.end(); it++) { + $$->__chunks.push_back(*it); + $$->__width += it->width; } - for (auto it = $1->chunks.begin(); it != $1->chunks.end(); it++) { - $$->chunks.push_back(*it); - $$->width += it->width; + for (auto it = $1->__chunks.begin(); it != $1->__chunks.end(); it++) { + $$->__chunks.push_back(*it); + $$->__width += it->width; } delete $1; delete $2; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 9000d7024..c449a5936 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -244,7 +244,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (clk_sig.width == 0 || data_sig.width == 0) + if (clk_sig.__width == 0 || data_sig.__width == 0) log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -284,21 +284,21 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) cell->connections["\\C"] = clk_sig; module->add(cell); - if (clear_sig.width == 0 && preset_sig.width == 0) { + if (clear_sig.__width == 0 && preset_sig.__width == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); } - if (clear_sig.width == 1 && preset_sig.width == 0) { + if (clear_sig.__width == 1 && preset_sig.__width == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\R"] = clear_sig; } - if (clear_sig.width == 0 && preset_sig.width == 1) { + if (clear_sig.__width == 0 && preset_sig.__width == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); cell->connections["\\R"] = preset_sig; } - if (clear_sig.width == 1 && preset_sig.width == 1) { + if (clear_sig.__width == 1 && preset_sig.__width == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\S"] = preset_sig; cell->connections["\\R"] = clear_sig; @@ -326,7 +326,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (enable_sig.width == 0 || data_sig.width == 0) + if (enable_sig.__width == 0 || data_sig.__width == 0) log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -359,7 +359,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) cell->connections["\\Y"] = iqn_sig; module->add(cell); - if (clear_sig.width == 1) + if (clear_sig.__width == 1) { RTLIL::SigSpec clear_negative = clear_sig; RTLIL::SigSpec clear_enable = clear_sig; @@ -396,7 +396,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) module->add(enable_gate); } - if (preset_sig.width == 1) + if (preset_sig.__width == 1) { RTLIL::SigSpec preset_positive = preset_sig; RTLIL::SigSpec preset_enable = preset_sig; -- cgit v1.2.3 From 4b4048bc5feba1ab05c7a63f12c0a17879cb7e04 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:15:14 +0200 Subject: SigSpec refactoring: using the accessor functions everywhere --- frontends/ast/genrtlil.cc | 120 +++++++++++++++++++++---------------------- frontends/ilang/parser.y | 28 +++++----- frontends/liberty/liberty.cc | 16 +++--- 3 files changed, 82 insertions(+), 82 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dc9f566c1..681b34860 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -62,8 +62,8 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; if (gen_attributes) for (auto &attr : that->attributes) { @@ -74,7 +74,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); cell->connections["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; @@ -85,7 +85,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) { - if (width <= sig.__width) { + if (width <= sig.size()) { sig.extend(width, is_signed); return; } @@ -111,8 +111,8 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s chunk.offset = 0; RTLIL::SigSpec new_sig; - new_sig.__chunks.push_back(chunk); - new_sig.__width = chunk.width; + new_sig.chunks().push_back(chunk); + new_sig.size() = chunk.width; if (that != NULL) for (auto &attr : that->attributes) { @@ -123,7 +123,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s } cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); cell->connections["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; @@ -155,8 +155,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -168,8 +168,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\B_SIGNED"] = RTLIL::Const(that->children[1]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.__width); - cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); + cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); cell->connections["\\A"] = left; cell->connections["\\B"] = right; @@ -182,7 +182,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi // helper function for creating RTLIL code for multiplexers static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - assert(cond.__width == 1); + assert(cond.size() == 1); std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); @@ -196,7 +196,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::Wire *wire = new RTLIL::Wire; wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); wire->name = cell->name + "_Y"; - wire->width = left.__width; + wire->width = left.size(); current_module->wires[wire->name] = wire; RTLIL::SigChunk chunk; @@ -205,8 +205,8 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const chunk.offset = 0; RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -215,7 +215,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->parameters["\\WIDTH"] = RTLIL::Const(left.__width); + cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); cell->connections["\\A"] = right; cell->connections["\\B"] = left; @@ -311,7 +311,7 @@ struct AST_INTERNAL::ProcessGenerator // create initial assignments for the temporary signals if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) { subst_rvalue_from = subst_lvalue_from; - subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.__width); + subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.size()); } else { addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from); } @@ -321,22 +321,22 @@ struct AST_INTERNAL::ProcessGenerator if (child->type == AST_BLOCK) processAst(child); - if (initSyncSignals.__width > 0) + if (initSyncSignals.size() > 0) { RTLIL::SyncRule *sync = new RTLIL::SyncRule; sync->type = RTLIL::SyncType::STi; proc->syncs.push_back(sync); - assert(init_lvalue.__width == init_rvalue.__width); + assert(init_lvalue.size() == init_rvalue.size()); init_lvalue.optimize(); init_rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < init_lvalue.__chunks.size(); i++) { - RTLIL::SigSpec lhs = init_lvalue.__chunks[i]; - RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.__chunks[i].width); + for (size_t i = 0; i < init_lvalue.chunks().size(); i++) { + RTLIL::SigSpec lhs = init_lvalue.chunks()[i]; + RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.chunks()[i].width); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.__width; + offset += lhs.size(); } } } @@ -345,9 +345,9 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { sig.optimize(); - for (size_t i = 0; i < sig.__chunks.size(); i++) + for (size_t i = 0; i < sig.chunks().size(); i++) { - RTLIL::SigChunk &chunk = sig.__chunks[i]; + RTLIL::SigChunk &chunk = sig.chunks()[i]; if (chunk.wire == NULL) continue; @@ -426,23 +426,23 @@ struct AST_INTERNAL::ProcessGenerator // are avoided and the generated $mux cells have a more "natural" size. void addChunkActions(std::vector &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool inSyncRule = false) { - if (inSyncRule && initSyncSignals.__width > 0) { + if (inSyncRule && initSyncSignals.size() > 0) { init_lvalue.append(lvalue.extract(initSyncSignals)); init_rvalue.append(lvalue.extract(initSyncSignals, &rvalue)); lvalue.remove2(initSyncSignals, &rvalue); } - assert(lvalue.__width == rvalue.__width); + assert(lvalue.size() == rvalue.size()); lvalue.optimize(); rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < lvalue.__chunks.size(); i++) { - RTLIL::SigSpec lhs = lvalue.__chunks[i]; - RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.__chunks[i].width); - if (inSyncRule && lvalue.__chunks[i].wire && lvalue.__chunks[i].wire->get_bool_attribute("\\nosync")) - rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.__width); + for (size_t i = 0; i < lvalue.chunks().size(); i++) { + RTLIL::SigSpec lhs = lvalue.chunks()[i]; + RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks()[i].width); + if (inSyncRule && lvalue.chunks()[i].wire && lvalue.chunks()[i].wire->get_bool_attribute("\\nosync")) + rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size()); actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.__width; + offset += lhs.size(); } } @@ -460,7 +460,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_LE: { RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.__width, &subst_rvalue_from, &subst_rvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_from, &subst_rvalue_to); lvalue.replace(subst_lvalue_from, subst_lvalue_to); if (ast->type == AST_ASSIGN_EQ) { @@ -533,7 +533,7 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.__width, &subst_rvalue_from, &subst_rvalue_to)); + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_from, &subst_rvalue_to)); } if (default_case != current_case) sw->cases.push_back(current_case); @@ -1002,8 +1002,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); @@ -1016,7 +1016,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_TO_SIGNED: case AST_TO_UNSIGNED: { RTLIL::SigSpec sig = children[0]->genRTLIL(); - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, sign_hint); is_signed = sign_hint; return sig; @@ -1025,15 +1025,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // concatenation of signals can be done directly using RTLIL::SigSpec case AST_CONCAT: { RTLIL::SigSpec sig; - sig.__width = 0; + sig.size() = 0; for (auto it = children.begin(); it != children.end(); it++) { RTLIL::SigSpec s = (*it)->genRTLIL(); - for (size_t i = 0; i < s.__chunks.size(); i++) { - sig.__chunks.push_back(s.__chunks[i]); - sig.__width += s.__chunks[i].width; + for (size_t i = 0; i < s.chunks().size(); i++) { + sig.chunks().push_back(s.chunks()[i]); + sig.size() += s.chunks()[i].width; } } - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, false); return sig; } @@ -1048,7 +1048,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec sig; for (int i = 0; i < count; i++) sig.append(right); - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, false); is_signed = false; return sig; @@ -1061,7 +1061,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint); is_signed = children[0]->is_signed; - int width = arg.__width; + int width = arg.size(); if (width_hint > 0) { width = width_hint; widthExtend(this, arg, width, is_signed, "$pos"); @@ -1079,7 +1079,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); - int width = std::max(left.__width, right.__width); + int width = std::max(left.size(), right.size()); if (width_hint > 0) width = width_hint; is_signed = children[0]->is_signed && children[1]->is_signed; @@ -1102,7 +1102,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (0) { case AST_REDUCE_BOOL: type_name = "$reduce_bool"; } { RTLIL::SigSpec arg = children[0]->genRTLIL(); - RTLIL::SigSpec sig = arg.__width > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; + RTLIL::SigSpec sig = arg.size() > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; return sig; } @@ -1116,7 +1116,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(); - int width = width_hint > 0 ? width_hint : left.__width; + int width = width_hint > 0 ? width_hint : left.size(); is_signed = children[0]->is_signed; return binop2rtlil(this, type_name, width, left, right); } @@ -1131,10 +1131,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(right_width, right_signed); - int width = width_hint > 0 ? width_hint : left.__width; + int width = width_hint > 0 ? width_hint : left.size(); is_signed = children[0]->is_signed; if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed) - return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.__width), right); + return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.size()), right); return binop2rtlil(this, "$pow", width, left, right); } @@ -1170,7 +1170,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); #if 0 - int width = std::max(left.__width, right.__width); + int width = std::max(left.size(), right.size()); if (width > width_hint && width_hint > 0) width = width_hint; if (width < width_hint) { @@ -1179,10 +1179,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (type == AST_SUB && (!children[0]->is_signed || !children[1]->is_signed)) width = width_hint; if (type == AST_MUL) - width = std::min(left.__width + right.__width, width_hint); + width = std::min(left.size() + right.size(), width_hint); } #else - int width = std::max(std::max(left.__width, right.__width), width_hint); + int width = std::max(std::max(left.size(), right.size()), width_hint); #endif is_signed = children[0]->is_signed && children[1]->is_signed; return binop2rtlil(this, type_name, width, left, right); @@ -1214,17 +1214,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); - if (cond.__width > 1) + if (cond.size() > 1) cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); - int width = std::max(val1.__width, val2.__width); + int width = std::max(val1.size(), val2.size()); is_signed = children[1]->is_signed && children[2]->is_signed; widthExtend(this, val1, width, is_signed, "$bu0"); widthExtend(this, val2, width, is_signed, "$bu0"); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, sign_hint); return sig; } @@ -1304,10 +1304,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(children.size() == 2); RTLIL::SigSpec check = children[0]->genRTLIL(); - log_assert(check.__width == 1); + log_assert(check.size() == 1); RTLIL::SigSpec en = children[1]->genRTLIL(); - log_assert(en.__width == 1); + log_assert(en.size() == 1); std::stringstream sstr; sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); @@ -1335,11 +1335,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); - RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.__width); + RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.size()); current_module->connections.push_back(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); - RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.__width); + RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); current_module->connections.push_back(RTLIL::SigSig(left, right)); } } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e6d3d4c5b..e8af447ba 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -363,8 +363,8 @@ sigspec: chunk.offset = 0; chunk.data = *$1; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = chunk.width; + $$->chunks().push_back(chunk); + $$->size() = chunk.width; delete $1; } | TOK_ID { @@ -375,8 +375,8 @@ sigspec: chunk.width = current_module->wires[$1]->width; chunk.offset = 0; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = chunk.width; + $$->chunks().push_back(chunk); + $$->size() = chunk.width; free($1); } | TOK_ID '[' TOK_INT ']' { @@ -387,8 +387,8 @@ sigspec: chunk.offset = $3; chunk.width = 1; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = 1; + $$->chunks().push_back(chunk); + $$->size() = 1; free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { @@ -399,8 +399,8 @@ sigspec: chunk.width = $3 - $5 + 1; chunk.offset = $5; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = chunk.width; + $$->chunks().push_back(chunk); + $$->size() = chunk.width; free($1); } | '{' sigspec_list '}' { @@ -410,13 +410,13 @@ sigspec: sigspec_list: sigspec_list sigspec { $$ = new RTLIL::SigSpec; - for (auto it = $2->__chunks.begin(); it != $2->__chunks.end(); it++) { - $$->__chunks.push_back(*it); - $$->__width += it->width; + for (auto it = $2->chunks().begin(); it != $2->chunks().end(); it++) { + $$->chunks().push_back(*it); + $$->size() += it->width; } - for (auto it = $1->__chunks.begin(); it != $1->__chunks.end(); it++) { - $$->__chunks.push_back(*it); - $$->__width += it->width; + for (auto it = $1->chunks().begin(); it != $1->chunks().end(); it++) { + $$->chunks().push_back(*it); + $$->size() += it->width; } delete $1; delete $2; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index c449a5936..3fe227bec 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -244,7 +244,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (clk_sig.__width == 0 || data_sig.__width == 0) + if (clk_sig.size() == 0 || data_sig.size() == 0) log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -284,21 +284,21 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) cell->connections["\\C"] = clk_sig; module->add(cell); - if (clear_sig.__width == 0 && preset_sig.__width == 0) { + if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); } - if (clear_sig.__width == 1 && preset_sig.__width == 0) { + if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\R"] = clear_sig; } - if (clear_sig.__width == 0 && preset_sig.__width == 1) { + if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); cell->connections["\\R"] = preset_sig; } - if (clear_sig.__width == 1 && preset_sig.__width == 1) { + if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\S"] = preset_sig; cell->connections["\\R"] = clear_sig; @@ -326,7 +326,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (enable_sig.__width == 0 || data_sig.__width == 0) + if (enable_sig.size() == 0 || data_sig.size() == 0) log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -359,7 +359,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) cell->connections["\\Y"] = iqn_sig; module->add(cell); - if (clear_sig.__width == 1) + if (clear_sig.size() == 1) { RTLIL::SigSpec clear_negative = clear_sig; RTLIL::SigSpec clear_enable = clear_sig; @@ -396,7 +396,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) module->add(enable_gate); } - if (preset_sig.__width == 1) + if (preset_sig.size() == 1) { RTLIL::SigSpec preset_positive = preset_sig; RTLIL::SigSpec preset_enable = preset_sig; -- cgit v1.2.3 From 7bffde6abdaf6fc2ed090946442f90b2438e6126 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:39:13 +0200 Subject: SigSpec refactoring: change RTLIL::SigSpec::size() to be read-only --- frontends/ast/genrtlil.cc | 66 ++++++++--------------------------------------- frontends/ilang/parser.y | 43 +++++------------------------- 2 files changed, 17 insertions(+), 92 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 681b34860..34a3f1ba9 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -56,15 +56,6 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi wire->width = result_width; current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; - if (gen_attributes) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -78,8 +69,8 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->connections["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = sig; - return sig; + cell->connections["\\Y"] = wire; + return wire; } // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) @@ -105,15 +96,6 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s wire->width = width; current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec new_sig; - new_sig.chunks().push_back(chunk); - new_sig.size() = chunk.width; - if (that != NULL) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -127,8 +109,8 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->connections["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; - cell->connections["\\Y"] = new_sig; - sig = new_sig; + cell->connections["\\Y"] = wire; + sig = wire; } // helper function for creating RTLIL code for binary operations @@ -149,15 +131,6 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi wire->width = result_width; current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; - for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -175,8 +148,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->connections["\\B"] = right; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = sig; - return sig; + cell->connections["\\Y"] = wire; + return wire; } // helper function for creating RTLIL code for multiplexers @@ -199,15 +172,6 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const wire->width = left.size(); current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; - for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -220,9 +184,9 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->connections["\\A"] = right; cell->connections["\\B"] = left; cell->connections["\\S"] = cond; - cell->connections["\\Y"] = sig; + cell->connections["\\Y"] = wire; - return sig; + return wire; } // helper class for converting AST always nodes to RTLIL processes @@ -1001,9 +965,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } } - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; + RTLIL::SigSpec sig(chunk); if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); @@ -1025,14 +987,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // concatenation of signals can be done directly using RTLIL::SigSpec case AST_CONCAT: { RTLIL::SigSpec sig; - sig.size() = 0; - for (auto it = children.begin(); it != children.end(); it++) { - RTLIL::SigSpec s = (*it)->genRTLIL(); - for (size_t i = 0; i < s.chunks().size(); i++) { - sig.chunks().push_back(s.chunks()[i]); - sig.size() += s.chunks()[i].width; - } - } + for (auto it = children.begin(); it != children.end(); it++) + sig.append((*it)->genRTLIL()); if (sig.size() < width_hint) sig.extend_u0(width_hint, false); return sig; diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e8af447ba..e4d12f3a1 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -357,50 +357,25 @@ constant: sigspec: constant { - RTLIL::SigChunk chunk; - chunk.wire = NULL; - chunk.width = $1->bits.size(); - chunk.offset = 0; - chunk.data = *$1; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = chunk.width; + $$ = new RTLIL::SigSpec(*$1); delete $1; } | TOK_ID { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - RTLIL::SigChunk chunk; - chunk.wire = current_module->wires[$1]; - chunk.width = current_module->wires[$1]->width; - chunk.offset = 0; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = chunk.width; + $$ = new RTLIL::SigSpec(current_module->wires[$1]); free($1); } | TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - RTLIL::SigChunk chunk; - chunk.wire = current_module->wires[$1]; - chunk.offset = $3; - chunk.width = 1; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = 1; + $$ = new RTLIL::SigSpec(current_module->wires[$1], 1, $3); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - RTLIL::SigChunk chunk; - chunk.wire = current_module->wires[$1]; - chunk.width = $3 - $5 + 1; - chunk.offset = $5; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = chunk.width; + $$ = new RTLIL::SigSpec(current_module->wires[$1], $3 - $5 + 1, $5); free($1); } | '{' sigspec_list '}' { @@ -410,14 +385,8 @@ sigspec: sigspec_list: sigspec_list sigspec { $$ = new RTLIL::SigSpec; - for (auto it = $2->chunks().begin(); it != $2->chunks().end(); it++) { - $$->chunks().push_back(*it); - $$->size() += it->width; - } - for (auto it = $1->chunks().begin(); it != $1->chunks().end(); it++) { - $$->chunks().push_back(*it); - $$->size() += it->width; - } + $$->append(*$2); + $$->append(*$1); delete $1; delete $2; } | -- cgit v1.2.3 From 28b3fd05fa9cf6d469fdec95e247a7ffe5bc001d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:58:44 +0200 Subject: SigSpec refactoring: change RTLIL::SigSpec::chunks() to be read-only, created interim RTLIL::SigSpec::chunks_rw() --- frontends/ast/genrtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 34a3f1ba9..a51064c3e 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -311,7 +311,7 @@ struct AST_INTERNAL::ProcessGenerator sig.optimize(); for (size_t i = 0; i < sig.chunks().size(); i++) { - RTLIL::SigChunk &chunk = sig.chunks()[i]; + RTLIL::SigChunk &chunk = sig.chunks_rw()[i]; if (chunk.wire == NULL) continue; -- cgit v1.2.3 From 115dd959d9dbf68aa30f8374df0e62fba8646f1e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 23:50:21 +0200 Subject: SigSpec refactoring: More cleanups of old SigSpec use pattern --- frontends/ast/genrtlil.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index a51064c3e..18ae008cb 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -309,9 +309,11 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { sig.optimize(); - for (size_t i = 0; i < sig.chunks().size(); i++) + std::vector chunks = sig.chunks(); + + for (int i = 0; i < SIZE(chunks); i++) { - RTLIL::SigChunk &chunk = sig.chunks_rw()[i]; + RTLIL::SigChunk &chunk = chunks[i]; if (chunk.wire == NULL) continue; @@ -329,7 +331,8 @@ struct AST_INTERNAL::ProcessGenerator chunk.wire = wire; chunk.offset = 0; } - return sig; + + return chunks; } // recursively traverse the AST an collect all assigned signals -- cgit v1.2.3 From a8d3a68971ccc4e47c54a906aae374a9a54b1415 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 08:40:31 +0200 Subject: Refactoring {SigSpec|SigChunk}(RTLIL::Wire *wire, ..) constructor -- step 2/3 --- frontends/ilang/parser.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e4d12f3a1..dcb51d44d 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -369,13 +369,13 @@ sigspec: TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], 1, $3); + $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $3)); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], $3 - $5 + 1, $5); + $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $5, $3 - $5 + 1)); free($1); } | '{' sigspec_list '}' { -- cgit v1.2.3 From ec923652e2eb721aa16657e54a67666f855c3d65 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 09:48:26 +0200 Subject: Refactoring {SigSpec|SigChunk}(RTLIL::Wire *wire, ..) constructor -- step 3/3 --- frontends/ilang/parser.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index dcb51d44d..3fe5199f3 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -369,13 +369,13 @@ sigspec: TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $3)); + $$ = new RTLIL::SigSpec(current_module->wires[$1], $3); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $5, $3 - $5 + 1)); + $$ = new RTLIL::SigSpec(current_module->wires[$1], $5, $3 - $5 + 1); free($1); } | '{' sigspec_list '}' { -- cgit v1.2.3 From c094c53de83707a5bf1b268640283f1dde235873 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:32:28 +0200 Subject: Removed RTLIL::SigSpec::optimize() --- frontends/ast/genrtlil.cc | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 18ae008cb..3d848e823 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -292,8 +292,6 @@ struct AST_INTERNAL::ProcessGenerator proc->syncs.push_back(sync); assert(init_lvalue.size() == init_rvalue.size()); - init_lvalue.optimize(); - init_rvalue.optimize(); int offset = 0; for (size_t i = 0; i < init_lvalue.chunks().size(); i++) { @@ -308,7 +306,6 @@ struct AST_INTERNAL::ProcessGenerator // create new temporary signals RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { - sig.optimize(); std::vector chunks = sig.chunks(); for (int i = 0; i < SIZE(chunks); i++) @@ -399,8 +396,6 @@ struct AST_INTERNAL::ProcessGenerator lvalue.remove2(initSyncSignals, &rvalue); } assert(lvalue.size() == rvalue.size()); - lvalue.optimize(); - rvalue.optimize(); int offset = 0; for (size_t i = 0; i < lvalue.chunks().size(); i++) { @@ -433,9 +428,7 @@ struct AST_INTERNAL::ProcessGenerator if (ast->type == AST_ASSIGN_EQ) { subst_rvalue_from.remove2(unmapped_lvalue, &subst_rvalue_to); subst_rvalue_from.append(unmapped_lvalue); - subst_rvalue_from.optimize(); subst_rvalue_to.append(rvalue); - subst_rvalue_to.optimize(); } removeSignalFromCaseTree(lvalue, current_case); @@ -486,9 +479,7 @@ struct AST_INTERNAL::ProcessGenerator subst_lvalue_from.remove2(this_case_eq_lvalue, &subst_lvalue_to); subst_lvalue_from.append(this_case_eq_lvalue); - subst_lvalue_from.optimize(); subst_lvalue_to.append(this_case_eq_ltemp); - subst_lvalue_to.optimize(); RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; @@ -527,9 +518,7 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_from.remove2(this_case_eq_lvalue, &subst_rvalue_to); subst_rvalue_from.append(this_case_eq_lvalue); - subst_rvalue_from.optimize(); subst_rvalue_to.append(this_case_eq_ltemp); - subst_rvalue_to.optimize(); this_case_eq_lvalue.replace(subst_lvalue_from, subst_lvalue_to); removeSignalFromCaseTree(this_case_eq_lvalue, current_case); -- cgit v1.2.3 From 20a7965f61a43b8c367b1042081a57b5a4005b33 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:45:27 +0200 Subject: Various small fixes (from gcc compiler warnings) --- frontends/ast/simplify.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index f819b2506..d86bfb3f0 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2259,7 +2259,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_error("Non-constant range in %s:%d (called from %s:%d).\n", range->filename.c_str(), range->linenum, fcall->filename.c_str(), fcall->linenum); int offset = std::min(range->range_left, range->range_right); - int width = std::min(std::abs(range->range_left - range->range_right) + 1, width); + int width = std::abs(range->range_left - range->range_right) + 1; varinfo_t &v = variables[stmt->children.at(0)->str]; RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size()); for (int i = 0; i < width; i++) -- cgit v1.2.3 From 375aa71dfe53217ef4dd6273b96f53061b5c8e8c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:35:01 +0200 Subject: Various fixes in Verific frontend for new RTLIL API --- frontends/verific/build_amd64.txt | 33 ++++++++++++++++++++++++++ frontends/verific/verific.cc | 49 ++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 27 deletions(-) create mode 100644 frontends/verific/build_amd64.txt (limited to 'frontends') diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt new file mode 100644 index 000000000..49debe0f0 --- /dev/null +++ b/frontends/verific/build_amd64.txt @@ -0,0 +1,33 @@ + +Notes on buildin yosys with verific support on amd64 when you only have the +i386 eval version of Verific: + + +1.) Use a Makefile.conf like the following one: + +--snip-- +CONFIG := clang-debug +ENABLE_TCL := 0 +ENABLE_QT4 := 0 +ENABLE_ABC := 0 +ENABLE_VERIFIC := 1 +CXXFLAGS += -m32 +LDFLAGS += -m32 +--snap-- + + +2.) Install the neccessary multilib packages. + +Hint: On debian/ubuntu the multilib packages have names such as +libreadline-dev:amd64 or lib32readline6-dev, depending on the version +of the system you are working with. + +Hint: On Ubuntu 14.04 there is a problem with the 32bit libz +package. A workaround is running the following command in the +yosys source directory: + + ln -s /usr/include/x86_64-linux-gnu/zconf.h . + + +3.) Run 'make' and 'make install' as usual. + diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 7411e9434..c973988bb 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -82,7 +82,6 @@ static RTLIL::SigSpec operatorInput(Instance *inst, std::mapGetInputBit(i))); else sig.append(RTLIL::State::Sz); - sig.optimize(); return sig; } @@ -94,7 +93,6 @@ static RTLIL::SigSpec operatorInput1(Instance *inst, std::mapGetInput1Bit(i))); else sig.append(RTLIL::State::Sz); - sig.optimize(); return sig; } @@ -106,7 +104,6 @@ static RTLIL::SigSpec operatorInput2(Instance *inst, std::mapGetInput2Bit(i))); else sig.append(RTLIL::State::Sz); - sig.optimize(); return sig; } @@ -127,7 +124,6 @@ static RTLIL::SigSpec operatorInport(Instance *inst, const char *portname, std:: } else sig.append(RTLIL::State::Sz); } - sig.optimize(); return sig; } else { Port *port = inst->View()->GetPort(portname); @@ -147,12 +143,11 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::mapnew_wire(1, NEW_ID); + dummy_wire = module->addWire(NEW_ID); else dummy_wire->width++; - sig.append(RTLIL::SigSpec(dummy_wire, 1, dummy_wire->width - 1)); + sig.append(RTLIL::SigSpec(dummy_wire, dummy_wire->width - 1)); } - sig.optimize(); return sig; } @@ -164,7 +159,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NAND) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addAndGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -176,7 +171,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NOR) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addOrGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -205,11 +200,11 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_FADD) { RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); - RTLIL::SigSpec x = inst->GetCout() ? net_map.at(inst->GetCout()) : module->new_wire(1, NEW_ID); - RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp3 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec x = inst->GetCout() ? net_map.at(inst->GetCout()) : module->addWire(NEW_ID); + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->addWire(NEW_ID); + RTLIL::SigSpec tmp1 = module->addWire(NEW_ID); + RTLIL::SigSpec tmp2 = module->addWire(NEW_ID); + RTLIL::SigSpec tmp3 = module->addWire(NEW_ID); module->addXorGate(NEW_ID, a, b, tmp1); module->addXorGate(RTLIL::escape_id(inst->Name()), tmp1, c, y); module->addAndGate(NEW_ID, tmp1, c, tmp2); @@ -245,7 +240,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_NAND) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addAnd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -257,7 +252,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_NOR) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addOr(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -290,8 +285,8 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_FADD) { - RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); + RTLIL::SigSpec a_plus_b = module->addWire(NEW_ID, 2); + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->addWire(NEW_ID); if (inst->GetCout()) y.append(net_map.at(inst->GetCout())); module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); @@ -328,7 +323,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapGetCin()->IsGnd()) { module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, out, SIGNED); } else { - RTLIL::SigSpec tmp = module->new_wire(out.width, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID, SIZE(out)); module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetCin()), out, false); } @@ -705,8 +700,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\TRANSPARENT"] = false; - cell->parameters["\\ABITS"] = addr.width; - cell->parameters["\\WIDTH"] = data.width; + cell->parameters["\\ABITS"] = SIZE(addr); + cell->parameters["\\WIDTH"] = SIZE(data); cell->connections["\\CLK"] = RTLIL::State::S0; cell->connections["\\ADDR"] = addr; cell->connections["\\DATA"] = data; @@ -730,9 +725,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\PRIORITY"] = 0; - cell->parameters["\\ABITS"] = addr.width; - cell->parameters["\\WIDTH"] = data.width; - cell->connections["\\EN"] = net_map.at(inst->GetControl()); + cell->parameters["\\ABITS"] = SIZE(addr); + cell->parameters["\\WIDTH"] = SIZE(data); + cell->connections["\\EN"] = RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data)); cell->connections["\\CLK"] = RTLIL::State::S0; cell->connections["\\ADDR"] = addr; cell->connections["\\DATA"] = data; @@ -749,7 +744,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) - log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); + log("Warning: Unsupported Verific operator: %s (fallback to gate level implementation provided by verific)\n", inst->View()->Owner()->Name()); } else { if (import_netlist_instance_gates(module, net_map, inst)) continue; @@ -775,9 +770,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; - while (conn.width <= port_offset) { + while (SIZE(conn) <= port_offset) { if (pr->GetPort()->GetDir() != DIR_IN) - conn.append(module->new_wire(port_offset - conn.width, NEW_ID)); + conn.append(module->addWire(NEW_ID, port_offset - SIZE(conn))); conn.append(RTLIL::State::Sz); } conn.replace(port_offset, net_map.at(pr->GetNet())); -- cgit v1.2.3 From b17d6531c833f9064c5888c694aa24e8a395b72a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:15:01 +0200 Subject: Added "make PRETTY=1" --- frontends/ilang/Makefile.inc | 6 +++--- frontends/verilog/Makefile.inc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc index f81c8de91..e832cfed8 100644 --- a/frontends/ilang/Makefile.inc +++ b/frontends/ilang/Makefile.inc @@ -5,13 +5,13 @@ GENFILES += frontends/ilang/parser.output GENFILES += frontends/ilang/lexer.cc frontends/ilang/parser.tab.cc: frontends/ilang/parser.y - bison -d -r all -b frontends/ilang/parser frontends/ilang/parser.y - mv frontends/ilang/parser.tab.c frontends/ilang/parser.tab.cc + $(P) bison -d -r all -b frontends/ilang/parser frontends/ilang/parser.y + $(Q) mv frontends/ilang/parser.tab.c frontends/ilang/parser.tab.cc frontends/ilang/parser.tab.h: frontends/ilang/parser.tab.cc frontends/ilang/lexer.cc: frontends/ilang/lexer.l - flex -o frontends/ilang/lexer.cc frontends/ilang/lexer.l + $(P) flex -o frontends/ilang/lexer.cc frontends/ilang/lexer.l OBJS += frontends/ilang/parser.tab.o frontends/ilang/lexer.o OBJS += frontends/ilang/ilang_frontend.o diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc index 5586b4cc2..49eb320ec 100644 --- a/frontends/verilog/Makefile.inc +++ b/frontends/verilog/Makefile.inc @@ -5,13 +5,13 @@ GENFILES += frontends/verilog/parser.output GENFILES += frontends/verilog/lexer.cc frontends/verilog/parser.tab.cc: frontends/verilog/parser.y - bison -d -r all -b frontends/verilog/parser frontends/verilog/parser.y - mv frontends/verilog/parser.tab.c frontends/verilog/parser.tab.cc + $(P) bison -d -r all -b frontends/verilog/parser frontends/verilog/parser.y + $(Q) mv frontends/verilog/parser.tab.c frontends/verilog/parser.tab.cc frontends/verilog/parser.tab.h: frontends/verilog/parser.tab.cc frontends/verilog/lexer.cc: frontends/verilog/lexer.l - flex -o frontends/verilog/lexer.cc frontends/verilog/lexer.l + $(P) flex -o frontends/verilog/lexer.cc frontends/verilog/lexer.l OBJS += frontends/verilog/parser.tab.o OBJS += frontends/verilog/lexer.o -- cgit v1.2.3 From 6aa792c864444324a1b140c2b63bd860f0cc3914 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 22:47:57 +0200 Subject: Replaced more old SigChunk programming patterns --- frontends/ast/genrtlil.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3d848e823..e74f36abe 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -294,9 +294,9 @@ struct AST_INTERNAL::ProcessGenerator assert(init_lvalue.size() == init_rvalue.size()); int offset = 0; - for (size_t i = 0; i < init_lvalue.chunks().size(); i++) { - RTLIL::SigSpec lhs = init_lvalue.chunks()[i]; - RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.chunks()[i].width); + for (auto &init_lvalue_c : init_lvalue.chunks()) { + RTLIL::SigSpec lhs = init_lvalue_c; + RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue_c.width); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); } @@ -398,10 +398,10 @@ struct AST_INTERNAL::ProcessGenerator assert(lvalue.size() == rvalue.size()); int offset = 0; - for (size_t i = 0; i < lvalue.chunks().size(); i++) { - RTLIL::SigSpec lhs = lvalue.chunks()[i]; - RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks()[i].width); - if (inSyncRule && lvalue.chunks()[i].wire && lvalue.chunks()[i].wire->get_bool_attribute("\\nosync")) + for (auto &lvalue_c : lvalue.chunks()) { + RTLIL::SigSpec lhs = lvalue_c; + RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue_c.width); + if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute("\\nosync")) rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size()); actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); -- cgit v1.2.3 From 1488bc0c4f80b32cabd096232830b7fdfc400bbf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:16:03 +0200 Subject: Updated verific build/test instructions --- frontends/verific/build_amd64.txt | 20 +++++++++----------- frontends/verific/test_navre.ys | 4 ++-- 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 49debe0f0..2f325e515 100644 --- a/frontends/verific/build_amd64.txt +++ b/frontends/verific/build_amd64.txt @@ -1,6 +1,6 @@ -Notes on buildin yosys with verific support on amd64 when you only have the -i386 eval version of Verific: +Notes on building yosys with verific support on amd64 when you +only have the i386 eval version of Verific: 1.) Use a Makefile.conf like the following one: @@ -13,21 +13,19 @@ ENABLE_ABC := 0 ENABLE_VERIFIC := 1 CXXFLAGS += -m32 LDFLAGS += -m32 +VERIFIC_DIR = /usr/local/src/verific_lib_eval --snap-- -2.) Install the neccessary multilib packages. +2.) Install the neccessary multilib packages Hint: On debian/ubuntu the multilib packages have names such as -libreadline-dev:amd64 or lib32readline6-dev, depending on the version -of the system you are working with. +libreadline-dev:amd64 or lib32readline6-dev, depending on the +exact version of debian/ubuntu you are working with. -Hint: On Ubuntu 14.04 there is a problem with the 32bit libz -package. A workaround is running the following command in the -yosys source directory: - ln -s /usr/include/x86_64-linux-gnu/zconf.h . +3.) Build and test - -3.) Run 'make' and 'make install' as usual. +make -j8 +./yosys frontends/verific/test_navre.ys diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys index 6f63761ab..a56b725ac 100644 --- a/frontends/verific/test_navre.ys +++ b/frontends/verific/test_navre.ys @@ -1,11 +1,11 @@ -verific -vlog2k ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +verific -vlog2k ../yosys-bigsim/softusb_navre/rtl/softusb_navre.v verific -import softusb_navre memory softusb_navre flatten softusb_navre rename softusb_navre gate -read_verilog ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +read_verilog ../yosys-bigsim/softusb_navre/rtl/softusb_navre.v cd softusb_navre; proc; opt; memory; opt; cd .. rename softusb_navre gold -- cgit v1.2.3 From 309d64d46a7ca7390ccb27b06ecb78228c8b54f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 13:07:31 +0200 Subject: Fixed two memory leaks in ast simplify --- frontends/ast/simplify.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d86bfb3f0..6302260a5 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -895,7 +895,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_error("Expression in generate case at %s:%d is not constant!\n", filename.c_str(), linenum); } - if (RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool()) { + bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool(); + delete buf; + + if (is_selected) { selected_case = this_genblock; i = children.size(); break; @@ -1301,6 +1304,8 @@ skip_dynamic_range_lvalue_expansion:; log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); RTLIL::Const arg_value = buf->bitsAsConst(); + delete buf; + uint32_t result = 0; for (size_t i = 0; i < arg_value.bits.size(); i++) if (arg_value.bits.at(i) == RTLIL::State::S1) -- cgit v1.2.3 From 2bec47a4045d23d46e7d300cbf80b2dce1a549a9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 15:05:18 +0200 Subject: Use only module->addCell() and module->remove() to create and delete cells --- frontends/ast/genrtlil.cc | 73 ++++++++++++-------------------------------- frontends/ilang/parser.y | 5 +-- frontends/liberty/liberty.cc | 69 +++++++++-------------------------------- 3 files changed, 34 insertions(+), 113 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index e74f36abe..c121a8694 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -44,17 +44,11 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi std::stringstream sstr; sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = type; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = result_width; - current_module->wires[wire->name] = wire; if (gen_attributes) for (auto &attr : that->attributes) { @@ -84,17 +78,11 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s std::stringstream sstr; sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = celltype; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = width; - current_module->wires[wire->name] = wire; if (that != NULL) for (auto &attr : that->attributes) { @@ -119,17 +107,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi std::stringstream sstr; sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = type; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = result_width; - current_module->wires[wire->name] = wire; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -160,17 +142,11 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = "$mux"; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", left.size()); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = left.size(); - current_module->wires[wire->name] = wire; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -1183,17 +1159,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::stringstream sstr; sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = sstr.str(); - cell->type = "$memrd"; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_DATA", current_module->memories[str]->width); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - wire->name = cell->name + "_DATA"; - wire->width = current_module->memories[str]->width; - current_module->wires[wire->name] = wire; int addr_bits = 1; while ((1 << addr_bits) < current_module->memories[str]->size) @@ -1220,11 +1190,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::stringstream sstr; sstr << "$memwr$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memwr"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = sstr.str(); - cell->type = "$memwr"; - current_module->cells[cell->name] = cell; int addr_bits = 1; while ((1 << addr_bits) < current_module->memories[str]->size) @@ -1260,11 +1227,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::stringstream sstr; sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$assert"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = sstr.str(); - cell->type = "$assert"; - current_module->cells[cell->name] = cell; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) @@ -1297,9 +1261,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_CELL: { int port_counter = 0, para_counter = 0; - RTLIL::Cell *cell = new RTLIL::Cell; + + if (current_module->count_id(str) != 0) + log_error("Re-definition of cell `%s' at %s:%d!\n", + str.c_str(), filename.c_str(), linenum); + + RTLIL::Cell *cell = current_module->addCell(str, ""); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = str; + for (auto it = children.begin(); it != children.end(); it++) { AstNode *child = *it; if (child->type == AST_CELLTYPE) { @@ -1342,10 +1311,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) attr.first.c_str(), filename.c_str(), linenum); cell->attributes[attr.first] = attr.second->asAttrConst(); } - if (current_module->cells.count(cell->name) != 0) - log_error("Re-definition of cell `%s' at %s:%d!\n", - str.c_str(), filename.c_str(), linenum); - current_module->cells[str] = cell; } break; diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 3fe5199f3..82826a35a 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -182,11 +182,8 @@ cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { if (current_module->cells.count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); - current_cell = new RTLIL::Cell; - current_cell->type = $2; - current_cell->name = $3; + current_cell = current_module->addCell($3, $2); current_cell->attributes = attrbuf; - current_module->cells[$3] = current_cell; attrbuf.clear(); free($2); free($3); diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 3fe227bec..74524792b 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -54,48 +54,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_INV_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); cell->connections["\\A"] = A; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_XOR_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); cell->connections["\\A"] = A; cell->connections["\\B"] = B; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_AND_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); cell->connections["\\A"] = A; cell->connections["\\B"] = B; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_OR_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); cell->connections["\\A"] = A; cell->connections["\\B"] = B; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } @@ -270,19 +258,14 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_INV_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); cell->connections["\\A"] = iq_sig; cell->connections["\\Y"] = iqn_sig; - module->add(cell); - cell = new RTLIL::Cell; - cell->name = NEW_ID; + cell = module->addCell(NEW_ID, ""); cell->connections["\\D"] = data_sig; cell->connections["\\Q"] = iq_sig; cell->connections["\\C"] = clk_sig; - module->add(cell); if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -352,12 +335,9 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_INV_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); cell->connections["\\A"] = iq_sig; cell->connections["\\Y"] = iqn_sig; - module->add(cell); if (clear_sig.size() == 1) { @@ -366,12 +346,9 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { - RTLIL::Cell *inv = new RTLIL::Cell; - inv->name = NEW_ID; - inv->type = "$_INV_"; + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); inv->connections["\\A"] = clear_sig; inv->connections["\\Y"] = module->addWire(NEW_ID); - module->add(inv); if (clear_polarity == true) clear_negative = inv->connections["\\Y"]; @@ -379,21 +356,15 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) clear_enable = inv->connections["\\Y"]; } - RTLIL::Cell *data_gate = new RTLIL::Cell; - data_gate->name = NEW_ID; - data_gate->type = "$_AND_"; + RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = clear_negative; data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(data_gate); - RTLIL::Cell *enable_gate = new RTLIL::Cell; - enable_gate->name = NEW_ID; - enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = clear_enable; enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(enable_gate); } if (preset_sig.size() == 1) @@ -403,12 +374,9 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { - RTLIL::Cell *inv = new RTLIL::Cell; - inv->name = NEW_ID; - inv->type = "$_INV_"; + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); inv->connections["\\A"] = preset_sig; inv->connections["\\Y"] = module->addWire(NEW_ID); - module->add(inv); if (preset_polarity == false) preset_positive = inv->connections["\\Y"]; @@ -416,30 +384,21 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) preset_enable = inv->connections["\\Y"]; } - RTLIL::Cell *data_gate = new RTLIL::Cell; - data_gate->name = NEW_ID; - data_gate->type = "$_OR_"; + RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = preset_positive; data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(data_gate); - RTLIL::Cell *enable_gate = new RTLIL::Cell; - enable_gate->name = NEW_ID; - enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = preset_enable; enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(enable_gate); } - cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N'); + cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); cell->connections["\\D"] = data_sig; cell->connections["\\Q"] = iq_sig; cell->connections["\\E"] = enable_sig; - module->add(cell); } struct LibertyFrontend : public Frontend { -- cgit v1.2.3 From cc4f10883bcc5f0a3c1b4f0937e60be3c6a1b121 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:58:03 +0200 Subject: Renamed RTLIL::{Module,Cell}::connections to connections_ --- frontends/ast/genrtlil.cc | 48 ++++++++--------- frontends/ilang/parser.y | 6 +-- frontends/liberty/liberty.cc | 124 +++++++++++++++++++++---------------------- 3 files changed, 89 insertions(+), 89 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c121a8694..c70b79a5b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -60,10 +60,10 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); - cell->connections["\\A"] = arg; + cell->connections_["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = wire; + cell->connections_["\\Y"] = wire; return wire; } @@ -94,10 +94,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); - cell->connections["\\A"] = sig; + cell->connections_["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; - cell->connections["\\Y"] = wire; + cell->connections_["\\Y"] = wire; sig = wire; } @@ -126,11 +126,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); - cell->connections["\\A"] = left; - cell->connections["\\B"] = right; + cell->connections_["\\A"] = left; + cell->connections_["\\B"] = right; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = wire; + cell->connections_["\\Y"] = wire; return wire; } @@ -157,10 +157,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); - cell->connections["\\A"] = right; - cell->connections["\\B"] = left; - cell->connections["\\S"] = cond; - cell->connections["\\Y"] = wire; + cell->connections_["\\A"] = right; + cell->connections_["\\B"] = left; + cell->connections_["\\S"] = cond; + cell->connections_["\\Y"] = wire; return wire; } @@ -1169,9 +1169,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections["\\DATA"] = RTLIL::SigSpec(wire); + cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); + cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); + cell->connections_["\\DATA"] = RTLIL::SigSpec(wire); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1197,10 +1197,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); - cell->connections["\\EN"] = children[2]->genRTLIL(); + cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); + cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); + cell->connections_["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); + cell->connections_["\\EN"] = children[2]->genRTLIL(); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1237,8 +1237,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->connections["\\A"] = check; - cell->connections["\\EN"] = en; + cell->connections_["\\A"] = check; + cell->connections_["\\EN"] = en; } break; @@ -1248,11 +1248,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.size()); - current_module->connections.push_back(RTLIL::SigSig(left, right)); + current_module->connections_.push_back(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); - current_module->connections.push_back(RTLIL::SigSig(left, right)); + current_module->connections_.push_back(RTLIL::SigSig(left, right)); } } break; @@ -1297,9 +1297,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->connections[buf] = sig; + cell->connections_[buf] = sig; } else { - cell->connections[child->str] = sig; + cell->connections_[child->str] = sig; } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 82826a35a..bb42c5ec7 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -202,9 +202,9 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->connections.count($3) != 0) + if (current_cell->connections_.count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->connections[$3] = *$4; + current_cell->connections_[$3] = *$4; delete $4; free($3); } | @@ -395,7 +395,7 @@ conn_stmt: TOK_CONNECT sigspec sigspec EOL { if (attrbuf.size() != 0) rtlil_frontend_ilang_yyerror("dangling attribute"); - current_module->connections.push_back(RTLIL::SigSig(*$2, *$3)); + current_module->connect(*$2, *$3); delete $2; delete $3; }; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 74524792b..ec96fbdd4 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -55,36 +55,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections["\\A"] = A; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); - cell->connections["\\A"] = A; - cell->connections["\\B"] = B; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\B"] = B; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); - cell->connections["\\A"] = A; - cell->connections["\\B"] = B; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\B"] = B; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); - cell->connections["\\A"] = A; - cell->connections["\\B"] = B; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\B"] = B; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) @@ -240,18 +240,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clk_sig) { - clk_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clk_sig) { + clk_sig = it.second->connections_.at("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { - clear_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { + clear_sig = it.second->connections_.at("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { - preset_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { + preset_sig = it.second->connections_.at("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -259,13 +259,13 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections["\\A"] = iq_sig; - cell->connections["\\Y"] = iqn_sig; + cell->connections_["\\A"] = iq_sig; + cell->connections_["\\Y"] = iqn_sig; cell = module->addCell(NEW_ID, ""); - cell->connections["\\D"] = data_sig; - cell->connections["\\Q"] = iq_sig; - cell->connections["\\C"] = clk_sig; + cell->connections_["\\D"] = data_sig; + cell->connections_["\\Q"] = iq_sig; + cell->connections_["\\C"] = clk_sig; if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -273,18 +273,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections["\\R"] = clear_sig; + cell->connections_["\\R"] = clear_sig; } if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); - cell->connections["\\R"] = preset_sig; + cell->connections_["\\R"] = preset_sig; } if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections["\\S"] = preset_sig; - cell->connections["\\R"] = clear_sig; + cell->connections_["\\S"] = preset_sig; + cell->connections_["\\R"] = clear_sig; } log_assert(!cell->type.empty()); @@ -317,18 +317,18 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == enable_sig) { - enable_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == enable_sig) { + enable_sig = it.second->connections_.at("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { - clear_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { + clear_sig = it.second->connections_.at("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { - preset_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { + preset_sig = it.second->connections_.at("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -336,8 +336,8 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections["\\A"] = iq_sig; - cell->connections["\\Y"] = iqn_sig; + cell->connections_["\\A"] = iq_sig; + cell->connections_["\\Y"] = iqn_sig; if (clear_sig.size() == 1) { @@ -347,24 +347,24 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections["\\A"] = clear_sig; - inv->connections["\\Y"] = module->addWire(NEW_ID); + inv->connections_["\\A"] = clear_sig; + inv->connections_["\\Y"] = module->addWire(NEW_ID); if (clear_polarity == true) - clear_negative = inv->connections["\\Y"]; + clear_negative = inv->connections_["\\Y"]; if (clear_polarity != enable_polarity) - clear_enable = inv->connections["\\Y"]; + clear_enable = inv->connections_["\\Y"]; } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); - data_gate->connections["\\A"] = data_sig; - data_gate->connections["\\B"] = clear_negative; - data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->connections_["\\A"] = data_sig; + data_gate->connections_["\\B"] = clear_negative; + data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections["\\A"] = enable_sig; - enable_gate->connections["\\B"] = clear_enable; - enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->connections_["\\A"] = enable_sig; + enable_gate->connections_["\\B"] = clear_enable; + enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); } if (preset_sig.size() == 1) @@ -375,30 +375,30 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections["\\A"] = preset_sig; - inv->connections["\\Y"] = module->addWire(NEW_ID); + inv->connections_["\\A"] = preset_sig; + inv->connections_["\\Y"] = module->addWire(NEW_ID); if (preset_polarity == false) - preset_positive = inv->connections["\\Y"]; + preset_positive = inv->connections_["\\Y"]; if (preset_polarity != enable_polarity) - preset_enable = inv->connections["\\Y"]; + preset_enable = inv->connections_["\\Y"]; } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); - data_gate->connections["\\A"] = data_sig; - data_gate->connections["\\B"] = preset_positive; - data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->connections_["\\A"] = data_sig; + data_gate->connections_["\\B"] = preset_positive; + data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections["\\A"] = enable_sig; - enable_gate->connections["\\B"] = preset_enable; - enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->connections_["\\A"] = enable_sig; + enable_gate->connections_["\\B"] = preset_enable; + enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); } cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); - cell->connections["\\D"] = data_sig; - cell->connections["\\Q"] = iq_sig; - cell->connections["\\E"] = enable_sig; + cell->connections_["\\D"] = data_sig; + cell->connections_["\\Q"] = iq_sig; + cell->connections_["\\E"] = enable_sig; } struct LibertyFrontend : public Frontend { @@ -559,7 +559,7 @@ struct LibertyFrontend : public Frontend { } RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); - module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + module->connections_.push_back(RTLIL::SigSig(wire, out_sig)); } } -- cgit v1.2.3 From b7dda723022ad00c6c0089be888eab319953faa8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:32:50 +0200 Subject: Changed users of cell->connections_ to the new API (sed command) git grep -l 'connections_' | xargs sed -i -r -e ' s/(->|\.)connections_\["([^"]*)"\] = (.*);/\1set("\2", \3);/g; s/(->|\.)connections_\["([^"]*)"\]/\1get("\2")/g; s/(->|\.)connections_.at\("([^"]*)"\)/\1get("\2")/g; s/(->|\.)connections_.push_back/\1connect/g; s/(->|\.)connections_/\1connections()/g;' --- frontends/ast/genrtlil.cc | 48 ++++++++--------- frontends/ilang/parser.y | 4 +- frontends/liberty/liberty.cc | 124 +++++++++++++++++++++---------------------- 3 files changed, 88 insertions(+), 88 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c70b79a5b..861df3fde 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -60,10 +60,10 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); - cell->connections_["\\A"] = arg; + cell->set("\\A", arg); cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections_["\\Y"] = wire; + cell->set("\\Y", wire); return wire; } @@ -94,10 +94,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); - cell->connections_["\\A"] = sig; + cell->set("\\A", sig); cell->parameters["\\Y_WIDTH"] = width; - cell->connections_["\\Y"] = wire; + cell->set("\\Y", wire); sig = wire; } @@ -126,11 +126,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); - cell->connections_["\\A"] = left; - cell->connections_["\\B"] = right; + cell->set("\\A", left); + cell->set("\\B", right); cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections_["\\Y"] = wire; + cell->set("\\Y", wire); return wire; } @@ -157,10 +157,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); - cell->connections_["\\A"] = right; - cell->connections_["\\B"] = left; - cell->connections_["\\S"] = cond; - cell->connections_["\\Y"] = wire; + cell->set("\\A", right); + cell->set("\\B", left); + cell->set("\\S", cond); + cell->set("\\Y", wire); return wire; } @@ -1169,9 +1169,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections_["\\DATA"] = RTLIL::SigSpec(wire); + cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->set("\\DATA", RTLIL::SigSpec(wire)); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1197,10 +1197,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections_["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); - cell->connections_["\\EN"] = children[2]->genRTLIL(); + cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->set("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width)); + cell->set("\\EN", children[2]->genRTLIL()); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1237,8 +1237,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->connections_["\\A"] = check; - cell->connections_["\\EN"] = en; + cell->set("\\A", check); + cell->set("\\EN", en); } break; @@ -1248,11 +1248,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.size()); - current_module->connections_.push_back(RTLIL::SigSig(left, right)); + current_module->connect(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); - current_module->connections_.push_back(RTLIL::SigSig(left, right)); + current_module->connect(RTLIL::SigSig(left, right)); } } break; @@ -1297,9 +1297,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->connections_[buf] = sig; + cell->connections()[buf] = sig; } else { - cell->connections_[child->str] = sig; + cell->connections()[child->str] = sig; } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index bb42c5ec7..a7ce4bc7a 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -202,9 +202,9 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->connections_.count($3) != 0) + if (current_cell->connections().count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->connections_[$3] = *$4; + current_cell->connections()[$3] = *$4; delete $4; free($3); } | diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index ec96fbdd4..d7068d468 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -55,36 +55,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections_["\\A"] = A; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); - cell->connections_["\\A"] = A; - cell->connections_["\\B"] = B; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\B", B); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); - cell->connections_["\\A"] = A; - cell->connections_["\\B"] = B; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\B", B); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); - cell->connections_["\\A"] = A; - cell->connections_["\\B"] = B; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\B", B); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) @@ -240,18 +240,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clk_sig) { - clk_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == clk_sig) { + clk_sig = it.second->get("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { - clear_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { + clear_sig = it.second->get("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { - preset_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { + preset_sig = it.second->get("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -259,13 +259,13 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections_["\\A"] = iq_sig; - cell->connections_["\\Y"] = iqn_sig; + cell->set("\\A", iq_sig); + cell->set("\\Y", iqn_sig); cell = module->addCell(NEW_ID, ""); - cell->connections_["\\D"] = data_sig; - cell->connections_["\\Q"] = iq_sig; - cell->connections_["\\C"] = clk_sig; + cell->set("\\D", data_sig); + cell->set("\\Q", iq_sig); + cell->set("\\C", clk_sig); if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -273,18 +273,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections_["\\R"] = clear_sig; + cell->set("\\R", clear_sig); } if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); - cell->connections_["\\R"] = preset_sig; + cell->set("\\R", preset_sig); } if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections_["\\S"] = preset_sig; - cell->connections_["\\R"] = clear_sig; + cell->set("\\S", preset_sig); + cell->set("\\R", clear_sig); } log_assert(!cell->type.empty()); @@ -317,18 +317,18 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == enable_sig) { - enable_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == enable_sig) { + enable_sig = it.second->get("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { - clear_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { + clear_sig = it.second->get("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { - preset_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { + preset_sig = it.second->get("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -336,8 +336,8 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections_["\\A"] = iq_sig; - cell->connections_["\\Y"] = iqn_sig; + cell->set("\\A", iq_sig); + cell->set("\\Y", iqn_sig); if (clear_sig.size() == 1) { @@ -347,24 +347,24 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections_["\\A"] = clear_sig; - inv->connections_["\\Y"] = module->addWire(NEW_ID); + inv->set("\\A", clear_sig); + inv->set("\\Y", module->addWire(NEW_ID)); if (clear_polarity == true) - clear_negative = inv->connections_["\\Y"]; + clear_negative = inv->get("\\Y"); if (clear_polarity != enable_polarity) - clear_enable = inv->connections_["\\Y"]; + clear_enable = inv->get("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); - data_gate->connections_["\\A"] = data_sig; - data_gate->connections_["\\B"] = clear_negative; - data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->set("\\A", data_sig); + data_gate->set("\\B", clear_negative); + data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections_["\\A"] = enable_sig; - enable_gate->connections_["\\B"] = clear_enable; - enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->set("\\A", enable_sig); + enable_gate->set("\\B", clear_enable); + enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); } if (preset_sig.size() == 1) @@ -375,30 +375,30 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections_["\\A"] = preset_sig; - inv->connections_["\\Y"] = module->addWire(NEW_ID); + inv->set("\\A", preset_sig); + inv->set("\\Y", module->addWire(NEW_ID)); if (preset_polarity == false) - preset_positive = inv->connections_["\\Y"]; + preset_positive = inv->get("\\Y"); if (preset_polarity != enable_polarity) - preset_enable = inv->connections_["\\Y"]; + preset_enable = inv->get("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); - data_gate->connections_["\\A"] = data_sig; - data_gate->connections_["\\B"] = preset_positive; - data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->set("\\A", data_sig); + data_gate->set("\\B", preset_positive); + data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections_["\\A"] = enable_sig; - enable_gate->connections_["\\B"] = preset_enable; - enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->set("\\A", enable_sig); + enable_gate->set("\\B", preset_enable); + enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); } cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); - cell->connections_["\\D"] = data_sig; - cell->connections_["\\Q"] = iq_sig; - cell->connections_["\\E"] = enable_sig; + cell->set("\\D", data_sig); + cell->set("\\Q", iq_sig); + cell->set("\\E", enable_sig); } struct LibertyFrontend : public Frontend { @@ -559,7 +559,7 @@ struct LibertyFrontend : public Frontend { } RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); - module->connections_.push_back(RTLIL::SigSig(wire, out_sig)); + module->connect(RTLIL::SigSig(wire, out_sig)); } } -- cgit v1.2.3 From f8fdc47d3361c1a3445a9357ca26cfe75907d6b0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 15:57:57 +0200 Subject: Manual fixes for new cell connections API --- frontends/ast/genrtlil.cc | 4 ++-- frontends/ilang/parser.y | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 861df3fde..dba301f46 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1297,9 +1297,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->connections()[buf] = sig; + cell->set(buf, sig); } else { - cell->connections()[child->str] = sig; + cell->set(child->str, sig); } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index a7ce4bc7a..952dd6a3a 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -204,7 +204,7 @@ cell_body: cell_body TOK_CONNECT TOK_ID sigspec EOL { if (current_cell->connections().count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->connections()[$3] = *$4; + current_cell->set($3, *$4); delete $4; free($3); } | -- cgit v1.2.3 From 97a59851a6c411ccb06162d4b31725bf89262378 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 16:11:28 +0200 Subject: Added RTLIL::Cell::has(portname) --- frontends/ilang/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 952dd6a3a..09437a0aa 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -202,7 +202,7 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->connections().count($3) != 0) + if (current_cell->has($3)) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); current_cell->set($3, *$4); delete $4; -- cgit v1.2.3 From 946ddff9cef3ea0b4dad8664319fb13074133775 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 20:12:50 +0200 Subject: Changed a lot of code to the new RTLIL::Wire constructors --- frontends/ast/genrtlil.cc | 22 +++++++++------------- frontends/ilang/parser.y | 5 ++--- 2 files changed, 11 insertions(+), 16 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dba301f46..3bc9b06ee 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -290,16 +290,16 @@ struct AST_INTERNAL::ProcessGenerator if (chunk.wire == NULL) continue; - RTLIL::Wire *wire = new RTLIL::Wire; - wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); + std::string wire_name; do { - wire->name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, + 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++); - } while (current_module->wires.count(wire->name) > 0); - wire->width = chunk.width; - current_module->wires[wire->name] = wire; + wire_name += stringf("$%d", RTLIL::autoidx++); + } while (current_module->wires.count(wire_name) > 0); + + RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); + wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); chunk.wire = wire; chunk.offset = 0; @@ -792,15 +792,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) range_right = tmp; } - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - wire->name = str; - wire->width = range_left - range_right + 1; wire->start_offset = range_right; wire->port_id = port_id; wire->port_input = is_input; wire->port_output = is_output; - current_module->wires[wire->name] = wire; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) @@ -873,14 +870,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigChunk chunk; if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires.count(str) == 0) { - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(str); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); wire->name = str; if (flag_autowire) log("Warning: Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum); else log_error("Identifier `%s' is implicitly declared at %s:%d and `default_nettype is set to none.\n", str.c_str(), filename.c_str(), linenum); - current_module->wires[str] = wire; } else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) { if (id2ast->children[0]->type != AST_CONSTANT) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 09437a0aa..20490e0d2 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -121,14 +121,13 @@ autoidx_stmt: wire_stmt: TOK_WIRE { - current_wire = new RTLIL::Wire; + current_wire = current_module->addWire("$__ilang_frontend_tmp__"); current_wire->attributes = attrbuf; attrbuf.clear(); } wire_options TOK_ID EOL { if (current_module->wires.count($4) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); - current_wire->name = $4; - current_module->wires[$4] = current_wire; + current_module->rename(current_wire, $4); free($4); }; -- cgit v1.2.3 From f9946232adf887e5aa4a48c64f88eaa17e424009 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 01:49:51 +0200 Subject: Refactoring: Renamed RTLIL::Module::wires to wires_ --- frontends/ast/genrtlil.cc | 10 +++++----- frontends/liberty/liberty.cc | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3bc9b06ee..064aec93f 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -296,7 +296,7 @@ struct AST_INTERNAL::ProcessGenerator 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++); - } while (current_module->wires.count(wire_name) > 0); + } while (current_module->wires_.count(wire_name) > 0); RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); @@ -779,7 +779,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // create an RTLIL::Wire for an AST_WIRE node case AST_WIRE: { - if (current_module->wires.count(str) != 0) + if (current_module->wires_.count(str) != 0) log_error("Re-definition of signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); if (!range_valid) @@ -869,7 +869,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Wire *wire = NULL; RTLIL::SigChunk chunk; - if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires.count(str) == 0) { + if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) { RTLIL::Wire *wire = current_module->addWire(str); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); wire->name = str; @@ -886,7 +886,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) goto use_const_chunk; } else if (!id2ast || (id2ast->type != AST_WIRE && id2ast->type != AST_AUTOWIRE && - id2ast->type != AST_MEMORY) || current_module->wires.count(str) == 0) + id2ast->type != AST_MEMORY) || current_module->wires_.count(str) == 0) log_error("Identifier `%s' doesn't map to any signal at %s:%d!\n", str.c_str(), filename.c_str(), linenum); @@ -894,7 +894,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Identifier `%s' does map to an unexpanded memory at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - wire = current_module->wires[str]; + wire = current_module->wires_[str]; chunk.wire = wire; chunk.width = wire->width; chunk.offset = 0; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index d7068d468..c476de87a 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -45,11 +45,11 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1; std::string id = RTLIL::escape_id(std::string(expr, id_len)); - if (!module->wires.count(id)) + if (!module->wires_.count(id)) log_error("Can't resolve wire name %s.\n", RTLIL::id2cstr(id)); expr += id_len; - return module->wires.at(id); + return module->wires_.at(id); } static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) @@ -527,7 +527,7 @@ struct LibertyFrontend : public Frontend { if (flag_lib && dir->value == "internal") continue; - RTLIL::Wire *wire = module->wires.at(RTLIL::escape_id(node->args.at(0))); + RTLIL::Wire *wire = module->wires_.at(RTLIL::escape_id(node->args.at(0))); if (dir && dir->value == "inout") { wire->port_input = true; -- cgit v1.2.3 From 4c4b6021562c598c4510831bd547edaa97d14dac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 01:51:45 +0200 Subject: Refactoring: Renamed RTLIL::Module::cells to cells_ --- frontends/liberty/liberty.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index c476de87a..0107b974a 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -239,7 +239,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) { rerun_invert_rollback = false; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (it.second->type == "$_INV_" && it.second->get("\\Y") == clk_sig) { clk_sig = it.second->get("\\A"); clk_polarity = !clk_polarity; @@ -316,7 +316,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) { rerun_invert_rollback = false; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (it.second->type == "$_INV_" && it.second->get("\\Y") == enable_sig) { enable_sig = it.second->get("\\A"); enable_polarity = !enable_polarity; -- cgit v1.2.3 From 10e5791c5e5660cb784503d36439ee90d61eb06b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:18:00 +0200 Subject: Refactoring: Renamed RTLIL::Design::modules to modules_ --- frontends/ast/ast.cc | 10 +++++----- frontends/liberty/liberty.cc | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3f704bea4..170416869 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -931,7 +931,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str = (*it)->str.substr(1); if (defer) (*it)->str = "$abstract" + (*it)->str; - if (design->modules.count((*it)->str)) { + if (design->modules_.count((*it)->str)) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -939,7 +939,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - design->modules[(*it)->str] = process_module(*it, defer); + design->modules_[(*it)->str] = process_module(*it, defer); } } @@ -1036,10 +1036,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapmodules.count(modname) == 0) { + if (design->modules_.count(modname) == 0) { new_ast->str = modname; - design->modules[modname] = process_module(new_ast, false); - design->modules[modname]->check(); + design->modules_[modname] = process_module(new_ast, false); + design->modules_[modname]->check(); } else { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); } diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 0107b974a..d5f172f03 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -476,7 +476,7 @@ struct LibertyFrontend : public Frontend { std::string cell_name = RTLIL::escape_id(cell->args.at(0)); - if (design->modules.count(cell_name)) { + if (design->modules_.count(cell_name)) { if (flag_ignore_redef) continue; log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); @@ -564,7 +564,7 @@ struct LibertyFrontend : public Frontend { } module->fixup_ports(); - design->modules[module->name] = module; + design->modules_[module->name] = module; cell_count++; skip_cell:; } -- cgit v1.2.3 From 6b34215efde97fe4f1e6ecffb398455f609a9a49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 11:56:35 +0200 Subject: Fixed ilang parser for new RTLIL API --- frontends/ilang/parser.y | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 20490e0d2..a594adfb5 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -87,12 +87,12 @@ design: module: TOK_MODULE TOK_ID EOL { - if (current_design->modules.count($2) != 0) + if (current_design->modules_.count($2) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); current_module = new RTLIL::Module; current_module->name = $2; current_module->attributes = attrbuf; - current_design->modules[$2] = current_module; + current_design->modules_[$2] = current_module; attrbuf.clear(); free($2); } module_body TOK_END { @@ -125,7 +125,7 @@ wire_stmt: current_wire->attributes = attrbuf; attrbuf.clear(); } wire_options TOK_ID EOL { - if (current_module->wires.count($4) != 0) + if (current_module->wires_.count($4) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); current_module->rename(current_wire, $4); free($4); @@ -179,7 +179,7 @@ memory_options: cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { - if (current_module->cells.count($3) != 0) + if (current_module->cells_.count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); current_cell = current_module->addCell($3, $2); current_cell->attributes = attrbuf; @@ -357,21 +357,21 @@ sigspec: delete $1; } | TOK_ID { - if (current_module->wires.count($1) == 0) + if (current_module->wires_.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1]); + $$ = new RTLIL::SigSpec(current_module->wires_[$1]); free($1); } | TOK_ID '[' TOK_INT ']' { - if (current_module->wires.count($1) == 0) + if (current_module->wires_.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], $3); + $$ = new RTLIL::SigSpec(current_module->wires_[$1], $3); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { - if (current_module->wires.count($1) == 0) + if (current_module->wires_.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], $5, $3 - $5 + 1); + $$ = new RTLIL::SigSpec(current_module->wires_[$1], $5, $3 - $5 + 1); free($1); } | '{' sigspec_list '}' { -- cgit v1.2.3 From 7661ded8ddf85e8cd80ccce0bec211d9bf46e56b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 12:00:28 +0200 Subject: Fixed verific bindings for new RTLIL api --- frontends/verific/Makefile.inc | 10 ++--- frontends/verific/verific.cc | 87 ++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 55 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index eca23e58c..13f242c4b 100644 --- a/frontends/verific/Makefile.inc +++ b/frontends/verific/Makefile.inc @@ -6,11 +6,11 @@ ifeq ($(ENABLE_VERIFIC),1) EXTRA_TARGETS += share/verific share/verific: - rm -rf share/verific.new - mkdir -p share/verific.new - cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs share/verific.new/vhdl_vdbs_1993 - cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008 share/verific.new/vhdl_vdbs_2008 - mv share/verific.new share/verific + $(P) rm -rf share/verific.new + $(Q) mkdir -p share/verific.new + $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs share/verific.new/vhdl_vdbs_1993 + $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008 share/verific.new/vhdl_vdbs_2008 + $(Q) mv share/verific.new share/verific endif diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c973988bb..aee38703b 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -481,7 +481,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator() ? std::string("$verific$") + nl->Owner()->Name() : RTLIL::escape_id(nl->Owner()->Name()); - if (design->modules.count(module_name)) { + if (design->modules_.count(module_name)) { if (!nl->IsOperator()) log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); return; @@ -489,7 +489,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = module_name; - design->modules[module->name] = module; + design->modules_[module->name] = module; log("Importing module %s.\n", RTLIL::id2cstr(module->name)); @@ -511,10 +511,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(port->Name()); + RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(port->Name())); import_attributes(wire->attributes, port); - module->add(wire); wire->port_id = nl->IndexOf(port) + 1; @@ -528,9 +526,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setport_input) - module->connections.push_back(RTLIL::SigSig(net_map.at(net), wire)); + module->connect(net_map.at(net), wire); else - module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + module->connect(wire, net_map.at(net)); } } @@ -538,12 +536,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(portbus->Name()); - wire->width = portbus->Size(); + RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(portbus->Name()), portbus->Size()); wire->start_offset = std::min(portbus->LeftIndex(), portbus->RightIndex()); import_attributes(wire->attributes, portbus); - module->add(wire); if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN) wire->port_input = true; @@ -557,9 +552,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setport_input) - module->connections.push_back(RTLIL::SigSig(net_map.at(net), bit)); + module->connect(net_map.at(net), bit); else - module->connections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + module->connect(bit, net_map.at(net)); } if (i == portbus->RightIndex()) break; @@ -607,12 +602,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(net->Name()); - while (module->count_id(wire->name)) - wire->name += "_"; + std::string wire_name = RTLIL::escape_id(net->Name()); + while (module->count_id(wire_name)) + wire_name += "_"; + RTLIL::Wire *wire = module->addWire(wire_name); import_attributes(wire->attributes, net); - module->add(wire); net_map[net] = wire; } @@ -632,14 +626,12 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(netbus->Name()); - wire->width = netbus->Size(); + std::string wire_name = RTLIL::escape_id(netbus->Name()); + while (module->count_id(wire_name)) + wire_name += "_"; + RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size()); wire->start_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); - while (module->count_id(wire->name)) - wire->name += "_"; import_attributes(wire->attributes, netbus); - module->add(wire); for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { if (netbus->ElementAtIndex(i)) { @@ -648,7 +640,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setconnections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + module->connect(bit, net_map.at(net)); } if (i == netbus->RightIndex()) break; @@ -665,22 +657,22 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName(), inst->View()->Owner()->Name()); if (inst->Type() == PRIM_PWR) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S1)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::S1); continue; } if (inst->Type() == PRIM_GND) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S0)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::S0); continue; } if (inst->Type() == PRIM_X) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sx)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::Sx); continue; } if (inst->Type() == PRIM_Z) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sz)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::Sz); continue; } @@ -693,19 +685,16 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(inst->Name()); - cell->type = "$memrd"; + RTLIL::Cell *cell = module->addCell(RTLIL::escape_id(inst->Name()), "$memrd"); cell->parameters["\\MEMID"] = memory->name; cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\TRANSPARENT"] = false; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->connections["\\CLK"] = RTLIL::State::S0; - cell->connections["\\ADDR"] = addr; - cell->connections["\\DATA"] = data; - module->add(cell); + cell->set("\\CLK", RTLIL::State::S0); + cell->set("\\ADDR", addr); + cell->set("\\DATA", data); continue; } @@ -718,24 +707,21 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(inst->Name()); - cell->type = "$memwr"; + RTLIL::Cell *cell = module->addCell(RTLIL::escape_id(inst->Name()), "$memwr"); cell->parameters["\\MEMID"] = memory->name; cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\PRIORITY"] = 0; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->connections["\\EN"] = RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data)); - cell->connections["\\CLK"] = RTLIL::State::S0; - cell->connections["\\ADDR"] = addr; - cell->connections["\\DATA"] = data; - module->add(cell); + cell->set("\\EN", RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data))); + cell->set("\\CLK", RTLIL::State::S0); + cell->set("\\ADDR", addr); + cell->set("\\DATA", data); if (inst->Type() == OPER_CLOCKED_WRITE_PORT) { cell->parameters["\\CLK_ENABLE"] = true; - cell->connections["\\CLK"] = net_map.at(inst->GetClock()); + cell->set("\\CLK", net_map.at(inst->GetClock())); } continue; } @@ -755,10 +741,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setView()); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = inst->IsOperator() ? std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()); - module->add(cell); + RTLIL::Cell *cell = module->addCell(RTLIL::escape_id(inst->Name()), inst->IsOperator() ? + std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name())); FOREACH_PORTREF_OF_INST(inst, mi2, pr) { // log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name()); @@ -769,13 +753,16 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->IndexOf(pr->GetPort()) - std::min(pr->GetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } - RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; + RTLIL::SigSpec conn; + if (cell->has(RTLIL::escape_id(port_name))) + conn = cell->get(RTLIL::escape_id(port_name)); while (SIZE(conn) <= port_offset) { if (pr->GetPort()->GetDir() != DIR_IN) conn.append(module->addWire(NEW_ID, port_offset - SIZE(conn))); conn.append(RTLIL::State::Sz); } conn.replace(port_offset, net_map.at(pr->GetNet())); + cell->set(RTLIL::escape_id(port_name), conn); } } } -- cgit v1.2.3 From c4bdba78cb88df6628d975aad7a92c8cebc5d95f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 21:12:09 +0200 Subject: Added proper Design->addModule interface --- frontends/ast/ast.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 170416869..d38cb5e3f 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1051,6 +1051,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapname = name; cloneInto(new_mod); new_mod->ast = ast->clone(); -- cgit v1.2.3 From ee65dea738fefbf44b91a2ac10f9a93b35115af6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 10:10:08 +0200 Subject: Fixed signdness detection of expressions with bit- and part-selects --- frontends/ast/genrtlil.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 064aec93f..95e15903b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -599,6 +599,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun delete right_at_zero_ast; } else this_width = range->range_left - range->range_right + 1; + sign_hint = false; } else width_hint = std::max(width_hint, this_width); if (!id_ast->is_signed) -- cgit v1.2.3 From 7bd2d1064f2eceddc3c93c121c4154a2f594a040 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 11:08:55 +0200 Subject: Using log_assert() instead of assert() --- frontends/ast/ast.cc | 4 ++-- frontends/ast/genrtlil.cc | 23 +++++++++++------------ frontends/ast/simplify.cc | 34 +++++++++++++++++----------------- frontends/verific/verific.cc | 1 - frontends/verilog/const2ast.cc | 3 +-- frontends/verilog/preproc.cc | 3 +-- frontends/verilog/verilog_frontend.cc | 1 - frontends/vhdl2verilog/vhdl2verilog.cc | 1 - 8 files changed, 32 insertions(+), 38 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d38cb5e3f..cec199b63 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -820,7 +820,7 @@ RTLIL::Const AstNode::realAsConst(int width) // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer) { - assert(ast->type == AST_MODULE); + log_assert(ast->type == AST_MODULE); if (defer) log("Storing AST representation for module `%s'.\n", ast->str.c_str()); @@ -925,7 +925,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_icells = icells; flag_autowire = autowire; - assert(current_ast->type == AST_DESIGN); + log_assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { if (flag_icells && (*it)->str.substr(0, 2) == "\\$") (*it)->str = (*it)->str.substr(1); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 95e15903b..25881d639 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -32,7 +32,6 @@ #include #include -#include #include using namespace AST; @@ -137,7 +136,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi // helper function for creating RTLIL code for multiplexers static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - assert(cond.size() == 1); + log_assert(cond.size() == 1); std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); @@ -267,7 +266,7 @@ struct AST_INTERNAL::ProcessGenerator sync->type = RTLIL::SyncType::STi; proc->syncs.push_back(sync); - assert(init_lvalue.size() == init_rvalue.size()); + log_assert(init_lvalue.size() == init_rvalue.size()); int offset = 0; for (auto &init_lvalue_c : init_lvalue.chunks()) { @@ -316,7 +315,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: for (auto child : ast->children) if (child != ast->children[0]) { - assert(child->type == AST_COND); + log_assert(child->type == AST_COND); collect_lvalues(reg, child, type_eq, type_le, false); } break; @@ -341,7 +340,7 @@ struct AST_INTERNAL::ProcessGenerator break; default: - assert(0); + log_abort(); } if (run_sort_and_unify) @@ -371,7 +370,7 @@ struct AST_INTERNAL::ProcessGenerator init_rvalue.append(lvalue.extract(initSyncSignals, &rvalue)); lvalue.remove2(initSyncSignals, &rvalue); } - assert(lvalue.size() == rvalue.size()); + log_assert(lvalue.size() == rvalue.size()); int offset = 0; for (auto &lvalue_c : lvalue.chunks()) { @@ -445,7 +444,7 @@ struct AST_INTERNAL::ProcessGenerator { if (child == ast->children[0]) continue; - assert(child->type == AST_COND); + log_assert(child->type == AST_COND); subst_lvalue_from = backup_subst_lvalue_from; subst_lvalue_to = backup_subst_lvalue_to; @@ -815,9 +814,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Re-definition of memory `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - assert(children.size() >= 2); - assert(children[0]->type == AST_RANGE); - assert(children[1]->type == AST_RANGE); + log_assert(children.size() >= 2); + log_assert(children[0]->type == AST_RANGE); + log_assert(children[1]->type == AST_RANGE); if (!children[0]->range_valid || !children[1]->range_valid) log_error("Memory `%s' with non-constant width or size at %s:%d!\n", @@ -902,7 +901,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) use_const_chunk: if (children.size() != 0) { - assert(children[0]->type == AST_RANGE); + log_assert(children[0]->type == AST_RANGE); if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); @@ -1300,7 +1299,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } continue; } - assert(0); + log_abort(); } for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 6302260a5..2a55adeff 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -57,7 +57,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (stage == 0) { - assert(type == AST_MODULE); + log_assert(type == AST_MODULE); while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { } @@ -73,7 +73,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { AstNode *mem = it.first; uint32_t memflags = it.second; - assert((memflags & ~0x00ffff00) == 0); + log_assert((memflags & ~0x00ffff00) == 0); if (mem->get_bool_attribute("\\nomem2reg")) continue; @@ -480,7 +480,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // dumpAst(NULL, "> "); log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum); } - assert(children[1]->type == AST_IDENTIFIER); + log_assert(children[1]->type == AST_IDENTIFIER); newNode = children[1]->clone(); const char *second_part = children[1]->str.c_str(); if (second_part[0] == '\\') @@ -506,7 +506,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, range_valid = false; range_left = -1; range_right = 0; - assert(children.size() >= 1); + log_assert(children.size() >= 1); if (children[0]->type == AST_CONSTANT) { range_valid = true; range_left = children[0]->integer; @@ -963,8 +963,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::vector children_list; for (auto child : children) { - assert(child->type == AST_ARGUMENT); - assert(child->children.size() == 1); + log_assert(child->type == AST_ARGUMENT); + log_assert(child->children.size() == 1); children_list.push_back(child->children[0]); child->children.clear(); delete child; @@ -1019,7 +1019,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, op_type = AST_POS; if (str == "not") op_type = AST_POS, invert_results = true; - assert(op_type != AST_NONE); + log_assert(op_type != AST_NONE); AstNode *node = children_list[1]; if (op_type != AST_POS) @@ -1423,13 +1423,13 @@ skip_dynamic_range_lvalue_expansion:; if (current_block == NULL) { - assert(type == AST_FCALL); + log_assert(type == AST_FCALL); AstNode *wire = NULL; for (auto child : decl->children) if (child->type == AST_WIRE && child->str == str) wire = child->clone(); - assert(wire != NULL); + log_assert(wire != NULL); wire->str = prefix + str; wire->port_id = 0; @@ -1714,7 +1714,7 @@ skip_dynamic_range_lvalue_expansion:; } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) { RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint); RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint); - assert(a.bits.size() == b.bits.size()); + log_assert(a.bits.size() == b.bits.size()); for (size_t i = 0; i < a.bits.size(); i++) if (a.bits[i] != b.bits[i]) a.bits[i] = RTLIL::State::Sx; @@ -1761,7 +1761,7 @@ apply_newNode: // fprintf(stderr, "----\n"); // dumpAst(stderr, "- "); // newNode->dumpAst(stderr, "+ "); - assert(newNode != NULL); + log_assert(newNode != NULL); newNode->filename = filename; newNode->linenum = linenum; newNode->cloneInto(this); @@ -1937,7 +1937,7 @@ void AstNode::mem2reg_as_needed_pass1(std::map> uint32_t backup_flags = flags; flags |= children_flags; - assert((flags & ~0x000000ff) == 0); + log_assert((flags & ~0x000000ff) == 0); for (auto child : children) if (ignore_children_counter > 0) @@ -1986,11 +1986,11 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * mod->children.push_back(wire_data); while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } - assert(block != NULL); + log_assert(block != NULL); size_t assign_idx = 0; while (assign_idx < block->children.size() && block->children[assign_idx] != this) assign_idx++; - assert(assign_idx < block->children.size()); + log_assert(assign_idx < block->children.size()); AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; @@ -2091,7 +2091,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * size_t assign_idx = 0; while (assign_idx < block->children.size() && !block->children[assign_idx]->contains(this)) assign_idx++; - assert(assign_idx < block->children.size()); + log_assert(assign_idx < block->children.size()); block->children.insert(block->children.begin()+assign_idx, case_node); block->children.insert(block->children.begin()+assign_idx, assign_addr); } @@ -2113,7 +2113,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * children.push_back(bit_part_sel); } - assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0); + log_assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0); auto children_list = children; for (size_t i = 0; i < children_list.size(); i++) @@ -2123,7 +2123,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * // calulate memory dimensions void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) { - assert(type == AST_MEMORY); + log_assert(type == AST_MEMORY); mem_width = children[0]->range_left - children[0]->range_right + 1; mem_size = children[1]->range_left - children[1]->range_right; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index aee38703b..80170394e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -22,7 +22,6 @@ #include "kernel/log.h" #include #include -#include #include #include #include diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 8491a6b47..446f5e50c 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -36,7 +36,6 @@ #include "verilog_frontend.h" #include "kernel/log.h" -#include #include #include @@ -47,7 +46,7 @@ static int my_decimal_div_by_two(std::vector &digits) { int carry = 0; for (size_t i = 0; i < digits.size(); i++) { - assert(digits[i] < 10); + log_assert(digits[i] < 10); digits[i] += carry * 10; carry = digits[i] % 2; digits[i] /= 2; diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 873ae3d51..67b2ffa7c 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -37,7 +37,6 @@ #include #include #include -#include static std::list output_code; static std::list input_buffer; @@ -65,7 +64,7 @@ static char next_char() if (input_buffer.empty()) return 0; - assert(input_buffer_charp <= input_buffer.front().size()); + log_assert(input_buffer_charp <= input_buffer.front().size()); if (input_buffer_charp == input_buffer.front().size()) { input_buffer_charp = 0; input_buffer.pop_front(); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 437fc3ec0..cbc594e86 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -33,7 +33,6 @@ #include "libs/sha1/sha1.h" #include #include -#include using namespace VERILOG_FRONTEND; diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 4392ed444..63dc85acc 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -22,7 +22,6 @@ #include "kernel/log.h" #include #include -#include #include #include #include -- cgit v1.2.3 From 3c45277ee0f5822181c6058f679de632f834e7d2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 12:12:13 +0200 Subject: Added wire->upto flag for signals such as "wire [0:7] x;" --- frontends/ast/genrtlil.cc | 3 +++ frontends/ilang/lexer.l | 1 + frontends/ilang/parser.y | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 25881d639..8ee46eb85 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -786,10 +786,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Signal `%s' with non-constant width at %s:%d!\n", str.c_str(), filename.c_str(), linenum); + bool wire_upto = false; if (range_left < range_right && (range_left != -1 || range_right != 0)) { int tmp = range_left; range_left = range_right; range_right = tmp; + wire_upto = true; } RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); @@ -798,6 +800,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) wire->port_id = port_id; wire->port_input = is_input; wire->port_output = is_output; + wire->upto = wire_upto; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index c40b81af8..f3bdeb1a4 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -51,6 +51,7 @@ "wire" { return TOK_WIRE; } "memory" { return TOK_MEMORY; } "width" { return TOK_WIDTH; } +"upto" { return TOK_UPTO; } "offset" { return TOK_OFFSET; } "size" { return TOK_SIZE; } "input" { return TOK_INPUT; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index a594adfb5..38d3054b2 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -54,7 +54,7 @@ using namespace ILANG_FRONTEND; %token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC %token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_INIT %token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET -%token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED +%token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED TOK_UPTO %type sigspec sigspec_list %type sync_type @@ -135,6 +135,9 @@ wire_options: wire_options TOK_WIDTH TOK_INT { current_wire->width = $3; } | + wire_options TOK_UPTO { + current_wire->upto = true; + } | wire_options TOK_OFFSET TOK_INT { current_wire->start_offset = $3; } | -- cgit v1.2.3 From 27a872d1e7041be4894bc643a420587ff5894125 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 14:25:03 +0200 Subject: Added support for "upto" wires to Verilog front- and back-end --- frontends/ast/ast.cc | 5 ++++- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 19 ++++++++----------- frontends/ast/simplify.cc | 4 ++++ 4 files changed, 17 insertions(+), 13 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index cec199b63..5b3214f5c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -181,6 +181,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2) is_signed = false; is_string = false; range_valid = false; + range_swapped = false; port_id = 0; range_left = -1; range_right = 0; @@ -276,7 +277,7 @@ void AstNode::dumpAst(FILE *f, std::string indent) if (port_id > 0) fprintf(f, " port=%d", port_id); if (range_valid || range_left != -1 || range_right != 0) - fprintf(f, " range=[%d:%d]%s", range_left, range_right, range_valid ? "" : "!"); + fprintf(f, " %srange=[%d:%d]%s", range_swapped ? "swapped_" : "", range_left, range_right, range_valid ? "" : "!"); if (integer != 0) fprintf(f, " int=%u", (int)integer); if (realvalue != 0) @@ -620,6 +621,8 @@ bool AstNode::operator==(const AstNode &other) const return false; if (range_valid != other.range_valid) return false; + if (range_swapped != other.range_swapped) + return false; if (port_id != other.port_id) return false; if (range_left != other.range_left) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8253a2052..6c15c03ab 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -151,7 +151,7 @@ namespace AST // node content - most of it is unused in most node types std::string str; std::vector bits; - bool is_input, is_output, is_reg, is_signed, is_string, range_valid; + bool is_input, is_output, is_reg, is_signed, is_string, range_valid, range_swapped; int port_id, range_left, range_right; uint32_t integer; double realvalue; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 8ee46eb85..5545fc169 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -786,13 +786,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Signal `%s' with non-constant width at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - bool wire_upto = false; - if (range_left < range_right && (range_left != -1 || range_right != 0)) { - int tmp = range_left; - range_left = range_right; - range_right = tmp; - wire_upto = true; - } + log_assert(range_left >= range_right || (range_left == -1 && range_right == 0)); RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -800,7 +794,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) wire->port_id = port_id; wire->port_input = is_input; wire->port_output = is_output; - wire->upto = wire_upto; + wire->upto = range_swapped; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) @@ -918,17 +912,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, - fake_ast->children[0]->genRTLIL(), fake_ast->children[1]->genRTLIL()); + fake_ast->children[0]->genRTLIL(), !wire->upto ? fake_ast->children[1]->genRTLIL() : + current_module->Sub(NEW_ID, RTLIL::SigSpec(wire->width - width), fake_ast->children[1]->genRTLIL())); delete left_at_zero_ast; delete right_at_zero_ast; delete fake_ast; return sig; } else { - chunk.offset = children[0]->range_right - id2ast->range_right; - chunk.width = children[0]->range_left - children[0]->range_right + 1; if (children[0]->range_left > id2ast->range_left || id2ast->range_right > children[0]->range_right) log_error("Range select out of bounds on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); + chunk.width = children[0]->range_left - children[0]->range_right + 1; + chunk.offset = children[0]->range_right - id2ast->range_right; + if (wire->upto) + chunk.offset = wire->width - (chunk.offset + chunk.width); } } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2a55adeff..7aa6d24c3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -504,6 +504,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_RANGE) { bool old_range_valid = range_valid; range_valid = false; + range_swapped = false; range_left = -1; range_right = 0; log_assert(children.size() >= 1); @@ -525,6 +526,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int tmp = range_right; range_right = range_left; range_left = tmp; + range_swapped = true; } } @@ -535,6 +537,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (!range_valid) did_something = true; range_valid = true; + range_swapped = children[0]->range_swapped; range_left = children[0]->range_left; range_right = children[0]->range_right; } @@ -542,6 +545,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (!range_valid) did_something = true; range_valid = true; + range_swapped = false; range_left = 0; range_right = 0; } -- cgit v1.2.3 From 0598bc8708d942a0e533ddeba6a4f7b5effe7f39 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 15:19:34 +0200 Subject: Fixed width detection for part selects --- frontends/ast/genrtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 5545fc169..9e1866832 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -599,8 +599,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun } else this_width = range->range_left - range->range_right + 1; sign_hint = false; - } else - width_hint = std::max(width_hint, this_width); + } + width_hint = std::max(width_hint, this_width); if (!id_ast->is_signed) sign_hint = false; break; -- cgit v1.2.3 From 55521c085ae1ec735d3cffb80a9880b3cb3e8bca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 15:31:19 +0200 Subject: Fixed RTLIL code generator for part select of parameter --- frontends/ast/genrtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9e1866832..ca61cb39b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -912,7 +912,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, - fake_ast->children[0]->genRTLIL(), !wire->upto ? fake_ast->children[1]->genRTLIL() : + fake_ast->children[0]->genRTLIL(), !id2ast->range_swapped ? fake_ast->children[1]->genRTLIL() : current_module->Sub(NEW_ID, RTLIL::SigSpec(wire->width - width), fake_ast->children[1]->genRTLIL())); delete left_at_zero_ast; delete right_at_zero_ast; @@ -924,7 +924,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) str.c_str(), filename.c_str(), linenum); chunk.width = children[0]->range_left - children[0]->range_right + 1; chunk.offset = children[0]->range_right - id2ast->range_right; - if (wire->upto) + if (id2ast->range_swapped) chunk.offset = wire->width - (chunk.offset + chunk.width); } } -- cgit v1.2.3 From a03297a7df6c729bc13f629412ae020eb05f7c64 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 16:09:50 +0200 Subject: Set results of out-of-bounds static bit/part select to undef --- frontends/ast/genrtlil.cc | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index ca61cb39b..b4115f0cd 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -866,6 +866,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Wire *wire = NULL; RTLIL::SigChunk chunk; + int add_undef_bits_msb = 0; + int add_undef_bits_lsb = 0; + if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) { RTLIL::Wire *wire = current_module->addWire(str); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -919,17 +922,40 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) delete fake_ast; return sig; } else { - if (children[0]->range_left > id2ast->range_left || id2ast->range_right > children[0]->range_right) - log_error("Range select out of bounds on signal `%s' at %s:%d!\n", - str.c_str(), filename.c_str(), linenum); + int source_width = id2ast->range_left - id2ast->range_right + 1; chunk.width = children[0]->range_left - children[0]->range_right + 1; chunk.offset = children[0]->range_right - id2ast->range_right; if (id2ast->range_swapped) - chunk.offset = wire->width - (chunk.offset + chunk.width); + chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width); + if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) { + if (chunk.width == 1) + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting result bit to undef.\n", + str.c_str(), filename.c_str(), linenum); + else + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting all %d result bits to undef.\n", + str.c_str(), filename.c_str(), linenum, chunk.width); + chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width); + } else { + if (chunk.width + chunk.offset > source_width) { + add_undef_bits_msb = (chunk.width + chunk.offset) - source_width; + chunk.width -= add_undef_bits_msb; + } + if (chunk.offset < 0) { + add_undef_bits_lsb = -chunk.offset; + chunk.width -= add_undef_bits_lsb; + chunk.offset += add_undef_bits_lsb; + } + if (add_undef_bits_lsb) + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d LSB bits to undef.\n", + str.c_str(), filename.c_str(), linenum, add_undef_bits_lsb); + if (add_undef_bits_msb) + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d MSB bits to undef.\n", + str.c_str(), filename.c_str(), linenum, add_undef_bits_msb); + } } } - RTLIL::SigSpec sig(chunk); + RTLIL::SigSpec sig = { RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_msb), chunk, RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_lsb) }; if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); -- cgit v1.2.3 From ec589659674ba9699b5dc73129ad69f25738e87e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 16:45:26 +0200 Subject: Fixed part selects of parameters --- frontends/ast/genrtlil.cc | 15 ++++++++++----- frontends/ast/simplify.cc | 23 +++++++++++++++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b4115f0cd..9b8e0faa4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -902,6 +902,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) use_const_chunk: if (children.size() != 0) { log_assert(children[0]->type == AST_RANGE); + int source_width = id2ast->range_left - id2ast->range_right + 1; + int source_offset = id2ast->range_right; if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); @@ -914,17 +916,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); - RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, - fake_ast->children[0]->genRTLIL(), !id2ast->range_swapped ? fake_ast->children[1]->genRTLIL() : - current_module->Sub(NEW_ID, RTLIL::SigSpec(wire->width - width), fake_ast->children[1]->genRTLIL())); + RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(); + log_dump(width, shift_val, id2ast->range_swapped, source_width, id2ast->range_left, id2ast->range_right); + if (id2ast->range_right != 0) + shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right); + if (id2ast->range_swapped) + shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val); + RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, fake_ast->children[0]->genRTLIL(), shift_val); delete left_at_zero_ast; delete right_at_zero_ast; delete fake_ast; return sig; } else { - int source_width = id2ast->range_left - id2ast->range_right + 1; chunk.width = children[0]->range_left - children[0]->range_right + 1; - chunk.offset = children[0]->range_right - id2ast->range_right; + chunk.offset = children[0]->range_right - source_offset; if (id2ast->range_swapped) chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width); if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) { diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7aa6d24c3..d47bfb5e6 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -575,6 +575,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } children[0]->is_signed = is_signed; } + range_valid = true; + range_swapped = children[1]->range_swapped; + range_left = children[1]->range_left; + range_right = children[1]->range_right; } else if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) { double as_realvalue = children[0]->asReal(sign_hint); @@ -1522,8 +1526,23 @@ skip_dynamic_range_lvalue_expansion:; if (current_scope[str]->children[0]->type == AST_CONSTANT) { if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) { std::vector data; - for (int i = children[0]->range_right; i <= children[0]->range_left; i++) - data.push_back(current_scope[str]->children[0]->bits[i]); + bool param_upto = current_scope[str]->range_valid && current_scope[str]->range_swapped; + int param_offset = current_scope[str]->range_valid ? current_scope[str]->range_right : 0; + int param_width = current_scope[str]->range_valid ? current_scope[str]->range_left - current_scope[str]->range_right + 1 : + SIZE(current_scope[str]->children[0]->bits); + int tmp_range_left = children[0]->range_left, tmp_range_right = children[0]->range_right; + if (param_upto) { + tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1; + tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1; + } + log_dump(param_upto, param_offset, param_width, children[0]->range_left, children[0]->range_right, tmp_range_left, tmp_range_right); + for (int i = tmp_range_right; i <= tmp_range_left; i++) { + int index = i - param_offset; + if (0 <= index && index < param_width) + data.push_back(current_scope[str]->children[0]->bits[index]); + else + data.push_back(RTLIL::State::Sx); + } newNode = mkconst_bits(data, false); } else if (children.size() == 0) -- cgit v1.2.3 From 48822e79a34880c5f0b07e9889e463e7b6d7111b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 19:38:30 +0200 Subject: Removed left over debug code --- frontends/ast/genrtlil.cc | 1 - frontends/ast/simplify.cc | 1 - 2 files changed, 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9b8e0faa4..cb666679b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -917,7 +917,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(); - log_dump(width, shift_val, id2ast->range_swapped, source_width, id2ast->range_left, id2ast->range_right); if (id2ast->range_right != 0) shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right); if (id2ast->range_swapped) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d47bfb5e6..5665cd43c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1535,7 +1535,6 @@ skip_dynamic_range_lvalue_expansion:; tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1; tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1; } - log_dump(param_upto, param_offset, param_width, children[0]->range_left, children[0]->range_right, tmp_range_left, tmp_range_right); for (int i = tmp_range_right; i <= tmp_range_left; i++) { int index = i - param_offset; if (0 <= index && index < param_width) -- cgit v1.2.3 From 397b00252dc0c4af725614bd12fc299147ba8efa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 14:42:33 +0200 Subject: Added $shift and $shiftx cell types (needed for correct part select behavior) --- frontends/ast/genrtlil.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index cb666679b..b7f336354 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -917,11 +917,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(); - if (id2ast->range_right != 0) - shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right); - if (id2ast->range_swapped) - shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val); - RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, fake_ast->children[0]->genRTLIL(), shift_val); + if (id2ast->range_right != 0) { + shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right, fake_ast->children[1]->is_signed); + fake_ast->children[1]->is_signed = true; + } + if (id2ast->range_swapped) { + shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val, fake_ast->children[1]->is_signed); + fake_ast->children[1]->is_signed = true; + } + if (SIZE(shift_val) >= 32) + fake_ast->children[1]->is_signed = true; + RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shiftx", width, fake_ast->children[0]->genRTLIL(), shift_val); delete left_at_zero_ast; delete right_at_zero_ast; delete fake_ast; -- cgit v1.2.3 From e605af8a4937533b35068071e14f5bd92c2e5b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 20:14:25 +0200 Subject: Fixed Verilog pre-processor for files with no trailing newline --- frontends/verilog/preproc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 67b2ffa7c..9ff68822e 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -198,7 +198,7 @@ static void input_file(FILE *f, std::string filename) buffer[rc] = 0; input_buffer.insert(it, buffer); } - input_buffer.insert(it, "`file_pop\n"); + input_buffer.insert(it, "\n`file_pop\n"); } std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) -- cgit v1.2.3 From 7daad40ca408732786d46fee8b5485bf45595807 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 20:18:48 +0200 Subject: Fixed counting verilog line numbers for "// synopsys translate_off" sections --- frontends/verilog/lexer.l | 6 +++--- frontends/verilog/preproc.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 0839f5cf9..00deeb0b4 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -74,21 +74,21 @@ namespace VERILOG_FRONTEND { %% -"`file_push "[^\n]* { +"`file_push "[^\n]* { fn_stack.push_back(current_filename); ln_stack.push_back(frontend_verilog_yyget_lineno()); current_filename = yytext+11; frontend_verilog_yyset_lineno(0); } -"`file_pop"[^\n]*\n { +"`file_pop"[^\n]*\n { current_filename = fn_stack.back(); fn_stack.pop_back(); frontend_verilog_yyset_lineno(ln_stack.back()); ln_stack.pop_back(); } -"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { +"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { char *p = yytext + 5; while (*p == ' ' || *p == '\t') p++; frontend_verilog_yyset_lineno(atoi(p)); diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 9ff68822e..2cfa8ca76 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -300,7 +300,7 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m input_file(fp, fn); fclose(fp); } else - output_code.push_back("`file_notfound " + fn + "\n"); + output_code.push_back("`file_notfound " + fn); continue; } -- cgit v1.2.3 From 1cb25c05b37b0172dbc50e140fe20f25d973dd8a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 13:19:47 +0200 Subject: Moved some stuff to kernel/yosys.{h,cc}, using Yosys:: namespace --- 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 +++ 16 files changed, 108 insertions(+), 47 deletions(-) (limited to 'frontends') 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 + -- cgit v1.2.3 From e6d33513a5b809facc6e3e5e75d2248bfa94f82b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 14:11:39 +0200 Subject: Added module->design and cell->module, wire->module pointers --- frontends/ast/ast.cc | 10 +++++----- frontends/ilang/parser.y | 4 ++-- frontends/liberty/liberty.cc | 4 ++-- frontends/verific/verific.cc | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d548a679c..46b717ce0 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -936,7 +936,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str = (*it)->str.substr(1); if (defer) (*it)->str = "$abstract" + (*it)->str; - if (design->modules_.count((*it)->str)) { + if (design->has((*it)->str)) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -944,7 +944,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - design->modules_[(*it)->str] = process_module(*it, defer); + design->add(process_module(*it, defer)); } } @@ -1041,10 +1041,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapmodules_.count(modname) == 0) { + if (!design->has(modname)) { new_ast->str = modname; - design->modules_[modname] = process_module(new_ast, false); - design->modules_[modname]->check(); + design->add(process_module(new_ast, false)); + design->module(modname)->check(); } else { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index ab763b2b1..67cc7da78 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -90,12 +90,12 @@ design: module: TOK_MODULE TOK_ID EOL { - if (current_design->modules_.count($2) != 0) + if (current_design->has($2)) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); current_module = new RTLIL::Module; current_module->name = $2; current_module->attributes = attrbuf; - current_design->modules_[$2] = current_module; + current_design->add(current_module); attrbuf.clear(); free($2); } module_body TOK_END { diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index da16ab33f..d3168ab8e 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -477,7 +477,7 @@ struct LibertyFrontend : public Frontend { std::string cell_name = RTLIL::escape_id(cell->args.at(0)); - if (design->modules_.count(cell_name)) { + if (design->has(cell_name)) { if (flag_ignore_redef) continue; log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); @@ -565,7 +565,7 @@ struct LibertyFrontend : public Frontend { } module->fixup_ports(); - design->modules_[module->name] = module; + design->add(module); cell_count++; skip_cell:; } diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6e692c5a1..c7b99c7a9 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -482,7 +482,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator() ? std::string("$verific$") + nl->Owner()->Name() : RTLIL::escape_id(nl->Owner()->Name()); - if (design->modules_.count(module_name)) { + if (design->has(module_name)) { if (!nl->IsOperator()) log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); return; @@ -490,7 +490,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = module_name; - design->modules_[module->name] = module; + design->add(module); log("Importing module %s.\n", RTLIL::id2cstr(module->name)); -- cgit v1.2.3 From cdae8abe16847c533171fed111beea7b52202cce Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 16:38:54 +0200 Subject: Renamed port access function on RTLIL::Cell, added param access functions --- frontends/ast/genrtlil.cc | 44 ++++++++-------- frontends/ilang/parser.y | 4 +- frontends/liberty/liberty.cc | 122 +++++++++++++++++++++---------------------- 3 files changed, 85 insertions(+), 85 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 0cc4f4c47..f4f82823b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -61,10 +61,10 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); - cell->set("\\A", arg); + cell->setPort("\\A", arg); cell->parameters["\\Y_WIDTH"] = result_width; - cell->set("\\Y", wire); + cell->setPort("\\Y", wire); return wire; } @@ -95,10 +95,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); - cell->set("\\A", sig); + cell->setPort("\\A", sig); cell->parameters["\\Y_WIDTH"] = width; - cell->set("\\Y", wire); + cell->setPort("\\Y", wire); sig = wire; } @@ -127,11 +127,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); - cell->set("\\A", left); - cell->set("\\B", right); + cell->setPort("\\A", left); + cell->setPort("\\B", right); cell->parameters["\\Y_WIDTH"] = result_width; - cell->set("\\Y", wire); + cell->setPort("\\Y", wire); return wire; } @@ -158,10 +158,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); - cell->set("\\A", right); - cell->set("\\B", left); - cell->set("\\S", cond); - cell->set("\\Y", wire); + cell->setPort("\\A", right); + cell->setPort("\\B", left); + cell->setPort("\\S", cond); + cell->setPort("\\Y", wire); return wire; } @@ -1203,9 +1203,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); - cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); - cell->set("\\DATA", RTLIL::SigSpec(wire)); + cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->setPort("\\DATA", RTLIL::SigSpec(wire)); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1231,10 +1231,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); - cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); - cell->set("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width)); - cell->set("\\EN", children[2]->genRTLIL()); + cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width)); + cell->setPort("\\EN", children[2]->genRTLIL()); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1271,8 +1271,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->set("\\A", check); - cell->set("\\EN", en); + cell->setPort("\\A", check); + cell->setPort("\\EN", en); } break; @@ -1331,9 +1331,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->set(buf, sig); + cell->setPort(buf, sig); } else { - cell->set(child->str, sig); + cell->setPort(child->str, sig); } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 67cc7da78..f696140eb 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -207,9 +207,9 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->has($3)) + if (current_cell->hasPort($3)) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->set($3, *$4); + current_cell->setPort($3, *$4); delete $4; free($3); } | diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index d3168ab8e..72e370b94 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -56,36 +56,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->set("\\A", A); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); - cell->set("\\A", A); - cell->set("\\B", B); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\B", B); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); - cell->set("\\A", A); - cell->set("\\B", B); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\B", B); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); - cell->set("\\A", A); - cell->set("\\B", B); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\B", B); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) @@ -241,18 +241,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->get("\\Y") == clk_sig) { - clk_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clk_sig) { + clk_sig = it.second->getPort("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { - clear_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { - preset_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -260,13 +260,13 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->set("\\A", iq_sig); - cell->set("\\Y", iqn_sig); + cell->setPort("\\A", iq_sig); + cell->setPort("\\Y", iqn_sig); cell = module->addCell(NEW_ID, ""); - cell->set("\\D", data_sig); - cell->set("\\Q", iq_sig); - cell->set("\\C", clk_sig); + cell->setPort("\\D", data_sig); + cell->setPort("\\Q", iq_sig); + cell->setPort("\\C", clk_sig); if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -274,18 +274,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->set("\\R", clear_sig); + cell->setPort("\\R", clear_sig); } if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); - cell->set("\\R", preset_sig); + cell->setPort("\\R", preset_sig); } if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->set("\\S", preset_sig); - cell->set("\\R", clear_sig); + cell->setPort("\\S", preset_sig); + cell->setPort("\\R", clear_sig); } log_assert(!cell->type.empty()); @@ -318,18 +318,18 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->get("\\Y") == enable_sig) { - enable_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == enable_sig) { + enable_sig = it.second->getPort("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { - clear_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { - preset_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -337,8 +337,8 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->set("\\A", iq_sig); - cell->set("\\Y", iqn_sig); + cell->setPort("\\A", iq_sig); + cell->setPort("\\Y", iqn_sig); if (clear_sig.size() == 1) { @@ -348,24 +348,24 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->set("\\A", clear_sig); - inv->set("\\Y", module->addWire(NEW_ID)); + inv->setPort("\\A", clear_sig); + inv->setPort("\\Y", module->addWire(NEW_ID)); if (clear_polarity == true) - clear_negative = inv->get("\\Y"); + clear_negative = inv->getPort("\\Y"); if (clear_polarity != enable_polarity) - clear_enable = inv->get("\\Y"); + clear_enable = inv->getPort("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); - data_gate->set("\\A", data_sig); - data_gate->set("\\B", clear_negative); - data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + data_gate->setPort("\\A", data_sig); + data_gate->setPort("\\B", clear_negative); + data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->set("\\A", enable_sig); - enable_gate->set("\\B", clear_enable); - enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + enable_gate->setPort("\\A", enable_sig); + enable_gate->setPort("\\B", clear_enable); + enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); } if (preset_sig.size() == 1) @@ -376,30 +376,30 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->set("\\A", preset_sig); - inv->set("\\Y", module->addWire(NEW_ID)); + inv->setPort("\\A", preset_sig); + inv->setPort("\\Y", module->addWire(NEW_ID)); if (preset_polarity == false) - preset_positive = inv->get("\\Y"); + preset_positive = inv->getPort("\\Y"); if (preset_polarity != enable_polarity) - preset_enable = inv->get("\\Y"); + preset_enable = inv->getPort("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); - data_gate->set("\\A", data_sig); - data_gate->set("\\B", preset_positive); - data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + data_gate->setPort("\\A", data_sig); + data_gate->setPort("\\B", preset_positive); + data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->set("\\A", enable_sig); - enable_gate->set("\\B", preset_enable); - enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + enable_gate->setPort("\\A", enable_sig); + enable_gate->setPort("\\B", preset_enable); + enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); } cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); - cell->set("\\D", data_sig); - cell->set("\\Q", iq_sig); - cell->set("\\E", enable_sig); + cell->setPort("\\D", data_sig); + cell->setPort("\\Q", iq_sig); + cell->setPort("\\E", enable_sig); } struct LibertyFrontend : public Frontend { -- cgit v1.2.3 From c6fd82c70be33c566cdf312e3ad21401b5b8171b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 16:45:23 +0200 Subject: Fixed build of verific bindings --- frontends/verific/verific.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c7b99c7a9..30f452181 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -693,9 +693,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\TRANSPARENT"] = false; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->set("\\CLK", RTLIL::State::S0); - cell->set("\\ADDR", addr); - cell->set("\\DATA", data); + cell->setPort("\\CLK", RTLIL::State::S0); + cell->setPort("\\ADDR", addr); + cell->setPort("\\DATA", data); continue; } @@ -715,14 +715,14 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\PRIORITY"] = 0; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->set("\\EN", RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data))); - cell->set("\\CLK", RTLIL::State::S0); - cell->set("\\ADDR", addr); - cell->set("\\DATA", data); + cell->setPort("\\EN", RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data))); + cell->setPort("\\CLK", RTLIL::State::S0); + cell->setPort("\\ADDR", addr); + cell->setPort("\\DATA", data); if (inst->Type() == OPER_CLOCKED_WRITE_PORT) { cell->parameters["\\CLK_ENABLE"] = true; - cell->set("\\CLK", net_map.at(inst->GetClock())); + cell->setPort("\\CLK", net_map.at(inst->GetClock())); } continue; } @@ -755,15 +755,15 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } RTLIL::SigSpec conn; - if (cell->has(RTLIL::escape_id(port_name))) - conn = cell->get(RTLIL::escape_id(port_name)); + if (cell->hasPort(RTLIL::escape_id(port_name))) + conn = cell->getPort(RTLIL::escape_id(port_name)); while (SIZE(conn) <= port_offset) { if (pr->GetPort()->GetDir() != DIR_IN) conn.append(module->addWire(NEW_ID, port_offset - SIZE(conn))); conn.append(RTLIL::State::Sz); } conn.replace(port_offset, net_map.at(pr->GetNet())); - cell->set(RTLIL::escape_id(port_name), conn); + cell->setPort(RTLIL::escape_id(port_name), conn); } } } -- cgit v1.2.3 From bd74ed7da467de11128c57c4c424febe4a7e2f39 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 19:01:10 +0200 Subject: Replaced sha1 implementation --- frontends/ast/ast.cc | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 46b717ce0..85b67b65e 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -979,10 +979,6 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map hash_data; - hash_data.insert(hash_data.end(), stripped_name.begin(), stripped_name.end()); - hash_data.push_back(0); - AstNode *new_ast = ast->clone(); int para_counter = 0; @@ -999,10 +995,6 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapstr.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); delete child->children.at(0); child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); - hash_data.insert(hash_data.end(), child->str.begin(), child->str.end()); - hash_data.push_back(0); - hash_data.insert(hash_data.end(), parameters[para_id].bits.begin(), parameters[para_id].bits.end()); - hash_data.push_back(0xff); parameters.erase(para_id); continue; } @@ -1018,28 +1010,11 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map 60) - { - unsigned char hash[20]; - unsigned char *hash_data2 = new unsigned char[hash_data.size()]; - for (size_t i = 0; i < hash_data.size(); i++) - hash_data2[i] = hash_data[i]; - sha1::calc(hash_data2, hash_data.size(), hash); - delete[] hash_data2; - - char hexstring[41]; - sha1::toHexString(hash, hexstring); - - modname = "$paramod$" + std::string(hexstring) + stripped_name; - } + else if (para_info.size() > 60) + modname = "$paramod$" + sha1(para_info) + stripped_name; else - { modname = "$paramod" + stripped_name + para_info; - } if (!design->has(modname)) { new_ast->str = modname; -- cgit v1.2.3 From 14412e6c957a34381c33740426b35f7b90a446be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 00:45:25 +0200 Subject: Preparations for RTLIL::IdString redesign: cleanup of existing code --- frontends/ast/ast.cc | 4 ++-- frontends/ast/simplify.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 85b67b65e..5815fb0d4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -325,7 +325,7 @@ void AstNode::dumpVlog(FILE *f, std::string indent) } for (auto &it : attributes) { - fprintf(f, "%s" "(* %s = ", indent.c_str(), id2vl(it.first).c_str()); + fprintf(f, "%s" "(* %s = ", indent.c_str(), id2vl(it.first.str()).c_str()); it.second->dumpVlog(f, ""); fprintf(f, " *)%s", indent.empty() ? "" : "\n"); } @@ -958,7 +958,7 @@ AstModule::~AstModule() // create a new parametric module (when needed) and return the name of the generated module RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map parameters) { - std::string stripped_name = name; + std::string stripped_name = name.str(); if (stripped_name.substr(0, 9) == "$abstract") stripped_name = stripped_name.substr(9); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index c51692f12..4d71bb394 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -465,7 +465,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, size_t pos = str.rfind('.'); if (pos == std::string::npos) log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n", - RTLIL::id2cstr(str.c_str()), filename.c_str(), linenum); + RTLIL::id2cstr(str), filename.c_str(), linenum); std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1); if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL) log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname), RTLIL::id2cstr(paraname), filename.c_str(), linenum); -- cgit v1.2.3 From b9bd22b8c8d46284fba4d4c1cbd09092a9ccc5c3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 13:11:01 +0200 Subject: More cleanups related to RTLIL::IdString usage --- frontends/ast/genrtlil.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index f4f82823b..bea99d8d4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -48,7 +48,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); if (gen_attributes) @@ -82,7 +82,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); if (that != NULL) @@ -111,7 +111,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); for (auto &attr : that->attributes) { @@ -146,7 +146,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", left.size()); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size()); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); for (auto &attr : that->attributes) { @@ -295,7 +295,7 @@ struct AST_INTERNAL::ProcessGenerator do { 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) + if (chunk.wire->name.str().find('$') != std::string::npos) wire_name += stringf("$%d", autoidx++); } while (current_module->wires_.count(wire_name) > 0); @@ -1196,7 +1196,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_DATA", current_module->memories[str]->width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); int addr_bits = 1; -- cgit v1.2.3 From 768eb846c4473040dc07bf62ce631c8a21474ae8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 16:03:18 +0200 Subject: More bugfixes related to new RTLIL::IdString --- frontends/ast/simplify.cc | 14 +++++++------- frontends/liberty/liberty.cc | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 4d71bb394..694f1d4d8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -465,10 +465,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, size_t pos = str.rfind('.'); if (pos == std::string::npos) log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n", - RTLIL::id2cstr(str), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1); if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL) - log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname), RTLIL::id2cstr(paraname), filename.c_str(), linenum); + log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paraname).c_str(), filename.c_str(), linenum); AstNode *cell = current_scope.at(modname), *paraset = clone(); cell->children.insert(cell->children.begin() + 1, paraset); paraset->type = AST_PARASET; @@ -1306,7 +1306,7 @@ skip_dynamic_range_lvalue_expansion:; { if (children.size() != 1) log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", - RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); AstNode *buf = children[0]->clone(); while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } @@ -1336,18 +1336,18 @@ skip_dynamic_range_lvalue_expansion:; if (func_with_two_arguments) { if (children.size() != 2) log_error("System function %s got %d arguments, expected 2 at %s:%d.\n", - RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); } else { if (children.size() != 1) log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", - RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); } if (children.size() >= 1) { while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (!children[0]->isConst()) log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", - RTLIL::id2cstr(str), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; children[0]->detectSignWidth(child_width_hint, child_sign_hint); @@ -1358,7 +1358,7 @@ skip_dynamic_range_lvalue_expansion:; while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (!children[1]->isConst()) log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", - RTLIL::id2cstr(str), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; children[1]->detectSignWidth(child_width_hint, child_sign_hint); diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 72e370b94..504b8d1e4 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -47,7 +47,7 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& std::string id = RTLIL::escape_id(std::string(expr, id_len)); if (!module->wires_.count(id)) - log_error("Can't resolve wire name %s.\n", RTLIL::id2cstr(id)); + log_error("Can't resolve wire name %s.\n", RTLIL::unescape_id(id).c_str()); expr += id_len; return module->wires_.at(id); @@ -234,7 +234,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } if (clk_sig.size() == 0 || data_sig.size() == 0) - log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); + log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", log_id(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) { @@ -311,7 +311,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } if (enable_sig.size() == 0 || data_sig.size() == 0) - log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); + log_error("Latch cell %s has no data_in and/or enable attribute.\n", log_id(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) { @@ -480,10 +480,10 @@ struct LibertyFrontend : public Frontend { if (design->has(cell_name)) { if (flag_ignore_redef) continue; - log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); + log_error("Duplicate definition of cell/module %s.\n", RTLIL::unescape_id(cell_name).c_str()); } - // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); + // log("Processing cell type %s.\n", RTLIL::unescape_id(cell_name).c_str()); RTLIL::Module *module = new RTLIL::Module; module->name = cell_name; @@ -501,9 +501,9 @@ struct LibertyFrontend : public Frontend { { if (!flag_ignore_miss_dir) { - log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), log_id(module->name)); } else { - log("Ignoring cell %s with missing or invalid direction for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); + log("Ignoring cell %s with missing or invalid direction for pin %s.\n", log_id(module->name), node->args.at(0).c_str()); delete module; goto skip_cell; } @@ -551,9 +551,9 @@ struct LibertyFrontend : public Frontend { { if (!flag_ignore_miss_func) { - log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + log_error("Missing function on output %s of cell %s.\n", log_id(wire->name), log_id(module->name)); } else { - log("Ignoring cell %s with missing function on output %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + log("Ignoring cell %s with missing function on output %s.\n", log_id(module->name), log_id(wire->name)); delete module; goto skip_cell; } -- cgit v1.2.3 From b5a3419ac2c6f367b90f062c4e2252029910cdb9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:19:24 +0200 Subject: Added support for non-standard "module mod_name(...);" syntax --- frontends/verilog/parser.y | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index c62e761e2..1e0168a5f 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -55,6 +55,7 @@ namespace VERILOG_FRONTEND { struct AstNode *current_ast, *current_ast_mod; int current_function_or_task_port_id; std::vector case_type_stack; + bool do_not_require_port_stubs; bool default_nettype_wire; bool sv_mode; } @@ -210,6 +211,7 @@ hierarchical_id: module: attr TOK_MODULE TOK_ID { + do_not_require_port_stubs = false; AstNode *mod = new AstNode(AST_MODULE); current_ast->children.push_back(mod); current_ast_mod = mod; @@ -244,7 +246,8 @@ single_module_para: }; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')'; + '(' ')' | /* empty */ | '(' module_args optional_comma ')' | + '(' '.' '.' '.' ')' { do_not_require_port_stubs = true; }; module_args: module_arg | module_args ',' module_arg; @@ -582,6 +585,9 @@ wire_name: node->children.push_back($2); } if (current_function_or_task == NULL) { + if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) { + port_stubs[*$1] = ++port_counter; + } if (port_stubs.count(*$1) != 0) { if (!node->is_input && !node->is_output) frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $1->c_str()); -- cgit v1.2.3 From 0129d41efad623ee95878a673c1c1190261ba3ef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 08:35:51 +0200 Subject: Fixed AST handling of variables declared inside a functions main block --- frontends/ast/simplify.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 694f1d4d8..20edc1739 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1460,7 +1460,6 @@ skip_dynamic_range_lvalue_expansion:; } for (auto child : decl->children) - { if (child->type == AST_WIRE) { AstNode *wire = child->clone(); @@ -1488,7 +1487,9 @@ skip_dynamic_range_lvalue_expansion:; } } } - else + + for (auto child : decl->children) + if (child->type != AST_WIRE) { AstNode *stmt = child->clone(); stmt->replace_ids(replace_rules); @@ -1500,7 +1501,6 @@ skip_dynamic_range_lvalue_expansion:; break; } } - } replace_fcall_with_id: if (type == AST_FCALL) { -- cgit v1.2.3 From 91dd87e60b120119ee34a9961a7b5f33f340282e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 12:15:53 +0200 Subject: Improved scope resolution of local regs in Verilog+AST frontend --- frontends/ast/ast.h | 2 +- frontends/ast/simplify.cc | 31 +++++++++++++++++++++++++------ frontends/verilog/parser.y | 3 +-- 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 83798edf0..00b044bc4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -200,7 +200,7 @@ namespace AST // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); void expand_genblock(std::string index_var, std::string prefix, std::map &name_map); - void replace_ids(std::map &rules); + void replace_ids(const std::string &prefix, const std::map &rules); void mem2reg_as_needed_pass1(std::map> &mem2reg_places, std::map &mem2reg_flags, std::map &proc_flags, uint32_t &status_flags); void mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode *mod, AstNode *block); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 20edc1739..29d00be96 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -794,6 +794,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (children[i]->type == AST_WIRE) { children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); + current_scope[children[i]->str] = children[i]; } else new_children.push_back(children[i]); @@ -1492,7 +1493,7 @@ skip_dynamic_range_lvalue_expansion:; if (child->type != AST_WIRE) { AstNode *stmt = child->clone(); - stmt->replace_ids(replace_rules); + stmt->replace_ids(prefix, replace_rules); for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { if (*it != current_block_child) @@ -1855,12 +1856,30 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma } // rename stuff (used when tasks of functions are instanciated) -void AstNode::replace_ids(std::map &rules) +void AstNode::replace_ids(const std::string &prefix, const std::map &rules) { - if (type == AST_IDENTIFIER && rules.count(str) > 0) - str = rules[str]; - for (auto child : children) - child->replace_ids(rules); + if (type == AST_BLOCK) + { + std::map new_rules = rules; + std::string new_prefix = prefix + str; + + for (auto child : children) + if (child->type == AST_WIRE) { + new_rules[child->str] = new_prefix + child->str; + child->str = new_prefix + child->str; + } + + for (auto child : children) + if (child->type != AST_WIRE) + child->replace_ids(new_prefix, new_rules); + } + else + { + if (type == AST_IDENTIFIER && rules.count(str) > 0) + str = rules.at(str); + for (auto child : children) + child->replace_ids(prefix, rules); + } } // helper function for mem2reg_as_needed_pass1 diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 1e0168a5f..26e2ddc34 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -599,12 +599,11 @@ wire_name: if (node->is_input || node->is_output) frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str()); } - ast_stack.back()->children.push_back(node); } else { if (node->is_input || node->is_output) node->port_id = current_function_or_task_port_id++; - current_function_or_task->children.push_back(node); } + ast_stack.back()->children.push_back(node); delete $1; }; -- cgit v1.2.3 From d259abbda2b9d568228dc8d0bed2d0b0d88d7b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Aug 2014 15:43:46 +0200 Subject: Added AST_MULTIRANGE (arrays with more than 1 dimension) --- frontends/ast/ast.cc | 7 +++++++ frontends/ast/ast.h | 4 ++++ frontends/ast/simplify.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++- frontends/verilog/parser.y | 22 ++++++++++++++++---- 4 files changed, 80 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5815fb0d4..f18124e28 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -78,6 +78,7 @@ std::string AST::type2str(AstNodeType type) X(AST_PARASET) X(AST_ARGUMENT) X(AST_RANGE) + X(AST_MULTIRANGE) X(AST_CONSTANT) X(AST_REALVALUE) X(AST_CELLTYPE) @@ -284,6 +285,12 @@ void AstNode::dumpAst(FILE *f, std::string indent) fprintf(f, " int=%u", (int)integer); if (realvalue != 0) fprintf(f, " real=%e", realvalue); + if (!multirange_dimensions.empty()) { + fprintf(f, " multirange=["); + for (int v : multirange_dimensions) + fprintf(f, " %d", v); + fprintf(f, " ]"); + } fprintf(f, "\n"); for (auto &it : attributes) { diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 00b044bc4..5fb1f0a73 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -56,6 +56,7 @@ namespace AST AST_PARASET, AST_ARGUMENT, AST_RANGE, + AST_MULTIRANGE, AST_CONSTANT, AST_REALVALUE, AST_CELLTYPE, @@ -158,6 +159,9 @@ namespace AST uint32_t integer; double realvalue; + // if this is a multirange memory then this vector contains offset and length of each dimension + std::vector multirange_dimensions; + // this is set by simplify and used during RTLIL generation AstNode *id2ast; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 29d00be96..39c472621 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -553,6 +553,56 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } + // resolve multiranges on memory decl + if (type == AST_MEMORY && children.size() > 1 && children[1]->type == AST_MULTIRANGE) + { + int total_size = 1; + multirange_dimensions.clear(); + for (auto range : children[1]->children) { + if (!range->range_valid) + log_error("Non-constant range on memory decl at %s:%d.\n", filename.c_str(), linenum); + multirange_dimensions.push_back(std::min(range->range_left, range->range_right)); + multirange_dimensions.push_back(std::max(range->range_left, range->range_right) - std::min(range->range_left, range->range_right) + 1); + total_size *= multirange_dimensions.back(); + } + delete children[1]; + children[1] = new AstNode(AST_RANGE, AstNode::mkconst_int(0, true), AstNode::mkconst_int(total_size-1, true)); + did_something = true; + } + + // resolve multiranges on memory access + if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY && children.size() > 0 && children[0]->type == AST_MULTIRANGE) + { + AstNode *index_expr = nullptr; + + for (int i = 0; 2*i < SIZE(id2ast->multirange_dimensions); i++) + { + if (SIZE(children[0]->children) < i) + log_error("Insufficient number of array indices for %s at %s:%d.\n", log_id(str), filename.c_str(), linenum); + + AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone(); + + if (id2ast->multirange_dimensions[2*i]) + new_index_expr = new AstNode(AST_SUB, new_index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i], true)); + + if (i == 0) + index_expr = new_index_expr; + else + index_expr = new AstNode(AST_ADD, new AstNode(AST_MUL, index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i-1], true)), new_index_expr); + } + + for (int i = SIZE(id2ast->multirange_dimensions)/1; i < SIZE(children[0]->children); i++) + children.push_back(children[0]->children[i]->clone()); + + delete children[0]; + if (index_expr == nullptr) + children.erase(children.begin()); + else + children[0] = new AstNode(AST_RANGE, index_expr); + + did_something = true; + } + // trim/extend parameters if (type == AST_PARAMETER || type == AST_LOCALPARAM) { if (children.size() > 1 && children[1]->type == AST_RANGE) { @@ -1166,7 +1216,7 @@ skip_dynamic_range_lvalue_expansion:; if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 && children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid && - (children[0]->children.size() == 1 || children[0]->children.size() == 2)) + (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE) { std::stringstream sstr; sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 26e2ddc34..95d7f3935 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -112,7 +112,8 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY -%type wire_type range non_opt_range range_or_signed_int expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int +%type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -361,6 +362,15 @@ non_opt_range: $$->children.push_back($2); }; +non_opt_multirange: + non_opt_range non_opt_range { + $$ = new AstNode(AST_MULTIRANGE, $1, $2); + } | + non_opt_multirange non_opt_range { + $$ = $1; + $$->children.push_back($2); + }; + range: non_opt_range { $$ = $1; @@ -369,6 +379,10 @@ range: $$ = NULL; }; +range_or_multirange: + range { $$ = $1; } | + non_opt_multirange { $$ = $1; }; + range_or_signed_int: range { $$ = $1; @@ -566,7 +580,7 @@ wire_name_and_opt_assign: }; wire_name: - TOK_ID range { + TOK_ID range_or_multirange { AstNode *node = astbuf1->clone(); node->str = *$1; append_attr_clone(node, albuf); @@ -1007,8 +1021,8 @@ rvalue: $$->str = *$1; delete $1; } | - hierarchical_id non_opt_range non_opt_range { - $$ = new AstNode(AST_IDENTIFIER, $2, $3); + hierarchical_id non_opt_multirange { + $$ = new AstNode(AST_IDENTIFIER, $2); $$->str = *$1; delete $1; }; -- cgit v1.2.3 From 2dc33337346ea53a654af3d80bdf056c7ccfa43c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:41:27 +0200 Subject: Also allow "module foobar(input foo, output bar, ...);" syntax --- frontends/verilog/parser.y | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 95d7f3935..f619d3c2b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -247,8 +247,7 @@ single_module_para: }; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')' | - '(' '.' '.' '.' ')' { do_not_require_port_stubs = true; }; + '(' ')' | /* empty */ | '(' module_args optional_comma ')'; module_args: module_arg | module_args ',' module_arg; @@ -297,7 +296,10 @@ module_arg: ast_stack.back()->children.push_back(node); append_attr(node, $1); delete $4; - } module_arg_opt_assignment; + } module_arg_opt_assignment | + '.' '.' '.' { + do_not_require_port_stubs = true; + }; wire_type: { -- cgit v1.2.3 From 593264e9edce8b1df1d5b691353fa592261d4f3b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 15:21:06 +0200 Subject: Fixed building verific bindings --- frontends/verific/build_amd64.txt | 2 +- frontends/verific/verific.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 2f325e515..2c3ba7b4d 100644 --- a/frontends/verific/build_amd64.txt +++ b/frontends/verific/build_amd64.txt @@ -6,7 +6,7 @@ only have the i386 eval version of Verific: 1.) Use a Makefile.conf like the following one: --snip-- -CONFIG := clang-debug +CONFIG := clang ENABLE_TCL := 0 ENABLE_QT4 := 0 ENABLE_ABC := 0 diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 30f452181..1ffcc4229 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -687,7 +687,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setaddCell(RTLIL::escape_id(inst->Name()), "$memrd"); - cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\MEMID"] = memory->name.str(); cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\TRANSPARENT"] = false; @@ -709,7 +709,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setaddCell(RTLIL::escape_id(inst->Name()), "$memwr"); - cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\MEMID"] = memory->name.str(); cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\PRIORITY"] = 0; -- cgit v1.2.3 From f53984795d38946ee71684d88883cafd9f58f603 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:03:38 +0200 Subject: Added support for non-standard """ macro bodies --- frontends/verilog/preproc.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 8efd4d7c3..7935fbc34 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -131,6 +131,12 @@ static std::string next_token(bool pass_newline = false) token += ch; } } + if (token == "\"\"" && (ch = next_char()) != 0) { + if (ch == '"') + token += ch; + else + return_char(ch); + } } else if (ch == '/') { @@ -311,12 +317,17 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m std::map args; skip_spaces(); name = next_token(true); + bool here_doc_mode = false; int newline_count = 0; int state = 0; if (skip_spaces() != "") state = 3; while (!tok.empty()) { tok = next_token(); + if (tok == "\"\"\"") { + here_doc_mode = !here_doc_mode; + continue; + } if (state == 0 && tok == "(") { state = 1; skip_spaces(); @@ -332,7 +343,7 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } else { if (state != 2) state = 3; - if (tok == "\n") { + if (tok == "\n" && !here_doc_mode) { return_char('\n'); break; } -- cgit v1.2.3 From 1bf7a18fec76cf46a5b8710a75371e23b68d147d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 16:13:42 +0200 Subject: Added module->ports --- frontends/ast/ast.cc | 1 + frontends/ilang/parser.y | 1 + 2 files changed, 2 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f18124e28..9f17f3bfb 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -919,6 +919,7 @@ static AstModule* process_module(AstNode *ast, bool defer) current_module->noopt = flag_noopt; current_module->icells = flag_icells; current_module->autowire = flag_autowire; + current_module->fixup_ports(); return current_module; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index f696140eb..e1ef39a55 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -101,6 +101,7 @@ module: } module_body TOK_END { if (attrbuf.size() != 0) rtlil_frontend_ilang_yyerror("dangling attribute"); + current_module->fixup_ports(); } EOL; module_body: -- cgit v1.2.3 From 85e3cc12ac44c44178185b918aa2a7fe9ca89918 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:26:10 +0200 Subject: Fixed handling of task outputs --- frontends/ast/simplify.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 39c472621..76d1f8270 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1523,12 +1523,14 @@ skip_dynamic_range_lvalue_expansion:; replace_rules[child->str] = wire->str; - if (child->is_input && arg_count < children.size()) + if ((child->is_input || child->is_output) && arg_count < children.size()) { AstNode *arg = children[arg_count++]->clone(); AstNode *wire_id = new AstNode(AST_IDENTIFIER); wire_id->str = wire->str; - AstNode *assign = new AstNode(AST_ASSIGN_EQ, wire_id, arg); + AstNode *assign = child->is_input ? + new AstNode(AST_ASSIGN_EQ, wire_id, arg) : + new AstNode(AST_ASSIGN_EQ, arg, wire_id); for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { if (*it != current_block_child) -- cgit v1.2.3 From 6d56172c0d16f80742c1c4588929d1805e3dd650 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:26:30 +0200 Subject: Fixed line numbers when using here-doc macros --- frontends/verilog/preproc.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 7935fbc34..ae139741a 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -343,10 +343,15 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } else { if (state != 2) state = 3; - if (tok == "\n" && !here_doc_mode) { - return_char('\n'); - break; - } + if (tok == "\n") { + if (here_doc_mode) { + value += " "; + newline_count++; + } else { + return_char('\n'); + break; + } + } else if (tok == "\\") { char ch = next_char(); if (ch == '\n') { -- cgit v1.2.3 From c83b9904582b81e71c4c510ffdc26f9796f5da21 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 23:02:07 +0200 Subject: Changed the AST genWidthRTLIL subst interface to use a std::map --- frontends/ast/ast.cc | 3 +-- frontends/ast/ast.h | 5 +++-- frontends/ast/genrtlil.cc | 44 +++++++++++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 21 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 9f17f3bfb..551859ebf 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,8 +51,7 @@ namespace AST_INTERNAL { bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map current_scope; - RTLIL::SigSpec *genRTLIL_subst_from = NULL; - RTLIL::SigSpec *genRTLIL_subst_to = NULL; + std::map *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; AstNode *current_top_block, *current_block, *current_block_child; AstModule *current_module; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 5fb1f0a73..e7b075486 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -228,7 +228,7 @@ namespace AST // for expressions the resulting signal vector is returned // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false); - RTLIL::SigSpec genWidthRTLIL(int width, RTLIL::SigSpec *subst_from = NULL, RTLIL::SigSpec *subst_to = NULL); + RTLIL::SigSpec genWidthRTLIL(int width, std::map *new_subst_ptr = NULL); // compare AST nodes bool operator==(const AstNode &other) const; @@ -285,7 +285,8 @@ namespace AST_INTERNAL extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; extern AST::AstNode *current_ast, *current_ast_mod; extern std::map current_scope; - extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial; + extern std::map *genRTLIL_subst_ptr; + extern RTLIL::SigSpec ignoreThisSignalsInInitial; extern AST::AstNode *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; struct ProcessGenerator; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index bea99d8d4..242514863 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -173,7 +173,7 @@ struct AST_INTERNAL::ProcessGenerator AstNode *always; RTLIL::SigSpec initSyncSignals; RTLIL::Process *proc; - const RTLIL::SigSpec &outputSignals; + RTLIL::SigSpec outputSignals; // This always points to the RTLIL::CaseRule beeing filled at the moment RTLIL::CaseRule *current_case; @@ -198,7 +198,7 @@ struct AST_INTERNAL::ProcessGenerator // Buffer for generating the init action RTLIL::SigSpec init_lvalue, init_rvalue; - ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), outputSignals(subst_lvalue_from) + ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg) { // generate process and simple root case proc = new RTLIL::Process; @@ -278,6 +278,8 @@ struct AST_INTERNAL::ProcessGenerator offset += lhs.size(); } } + + outputSignals = RTLIL::SigSpec(subst_lvalue_from); } // create new temporary signals @@ -398,8 +400,12 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_EQ: case AST_ASSIGN_LE: { + std::map new_subst_rvalue_map; + for (int i = 0; i < SIZE(subst_rvalue_to); i++) + new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_from, &subst_rvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map); lvalue.replace(subst_lvalue_from, subst_lvalue_to); if (ast->type == AST_ASSIGN_EQ) { @@ -415,8 +421,12 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { + std::map new_subst_rvalue_map; + for (int i = 0; i < SIZE(subst_rvalue_to); i++) + new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_from, &subst_rvalue_to); + sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { @@ -467,8 +477,12 @@ struct AST_INTERNAL::ProcessGenerator default_case = current_case; else if (node->type == AST_BLOCK) processAst(node); - else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_from, &subst_rvalue_to)); + else { + std::map new_subst_rvalue_map; + for (int i = 0; i < SIZE(subst_rvalue_to); i++) + new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map)); + } } if (default_case != current_case) sw->cases.push_back(current_case); @@ -969,8 +983,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec sig = { RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_msb), chunk, RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_lsb) }; - if (genRTLIL_subst_from && genRTLIL_subst_to) - sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); + if (genRTLIL_subst_ptr) + sig.replace(*genRTLIL_subst_ptr); is_signed = children.size() > 0 ? false : id2ast->is_signed && sign_hint; return sig; @@ -1377,23 +1391,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // this is a wrapper for AstNode::genRTLIL() when a specific signal width is requested and/or // signals must be substituted before beeing used as input values (used by ProcessGenerator) // note that this is using some global variables to communicate this special settings to AstNode::genRTLIL(). -RTLIL::SigSpec AstNode::genWidthRTLIL(int width, RTLIL::SigSpec *subst_from, RTLIL::SigSpec *subst_to) +RTLIL::SigSpec AstNode::genWidthRTLIL(int width, std::map *new_subst_ptr) { - RTLIL::SigSpec *backup_subst_from = genRTLIL_subst_from; - RTLIL::SigSpec *backup_subst_to = genRTLIL_subst_to; + std::map *backup_subst_ptr = genRTLIL_subst_ptr; - if (subst_from) - genRTLIL_subst_from = subst_from; - if (subst_to) - genRTLIL_subst_to = subst_to; + if (new_subst_ptr) + genRTLIL_subst_ptr = new_subst_ptr; bool sign_hint = true; int width_hint = width; detectSignWidthWorker(width_hint, sign_hint); RTLIL::SigSpec sig = genRTLIL(width_hint, sign_hint); - genRTLIL_subst_from = backup_subst_from; - genRTLIL_subst_to = backup_subst_to; + genRTLIL_subst_ptr = backup_subst_ptr; if (width >= 0) sig.extend_u0(width, is_signed); -- cgit v1.2.3 From 978a933b6af8863200096bd3a56780e3378e4848 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 23:14:47 +0200 Subject: Added RTLIL::SigSpec::to_sigbit_map() --- frontends/ast/genrtlil.cc | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 242514863..3c8f1fa16 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -400,10 +400,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_EQ: case AST_ASSIGN_LE: { - std::map new_subst_rvalue_map; - for (int i = 0; i < SIZE(subst_rvalue_to); i++) - new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; - + std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map); lvalue.replace(subst_lvalue_from, subst_lvalue_to); @@ -421,10 +418,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { - std::map new_subst_rvalue_map; - for (int i = 0; i < SIZE(subst_rvalue_to); i++) - new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; - + std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map); current_case->switches.push_back(sw); @@ -478,9 +472,7 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else { - std::map new_subst_rvalue_map; - for (int i = 0; i < SIZE(subst_rvalue_to); i++) - new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map)); } } -- cgit v1.2.3 From c7afbd9d8efcf3045d9e4244600ce8d8e0d40b6d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 01:53:22 +0200 Subject: Fixed bug in "read_verilog -ignore_redef" --- frontends/ast/ast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 551859ebf..ec9616be3 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -947,7 +947,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - log_error("Ignoring re-definition of module `%s' at %s:%d!\n", + log("Ignoring re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } -- cgit v1.2.3 From f092b5014895dc5dc62b8103fcedf94cfa9f85a8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:11:40 +0200 Subject: Renamed $_INV_ cell type to $_NOT_ --- frontends/liberty/liberty.cc | 22 +++++++++++----------- frontends/verific/verific.cc | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'frontends') diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 504b8d1e4..83bfce371 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -55,7 +55,7 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { - RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_"); cell->setPort("\\A", A); cell->setPort("\\Y", module->addWire(NEW_ID)); return cell->getPort("\\Y"); @@ -241,17 +241,17 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clk_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clk_sig) { clk_sig = it.second->getPort("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) { clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) { preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; @@ -259,7 +259,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_"); cell->setPort("\\A", iq_sig); cell->setPort("\\Y", iqn_sig); @@ -318,17 +318,17 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == enable_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == enable_sig) { enable_sig = it.second->getPort("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) { clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) { preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; @@ -336,7 +336,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_"); cell->setPort("\\A", iq_sig); cell->setPort("\\Y", iqn_sig); @@ -347,7 +347,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { - RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_"); inv->setPort("\\A", clear_sig); inv->setPort("\\Y", module->addWire(NEW_ID)); @@ -375,7 +375,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { - RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_"); inv->setPort("\\A", preset_sig); inv->setPort("\\Y", module->addWire(NEW_ID)); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1ffcc4229..95b3c407e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -162,7 +162,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NAND) { RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addAndGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); - module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + module->addNotGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } @@ -174,7 +174,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NOR) { RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addOrGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); - module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + module->addNotGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } @@ -184,7 +184,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_INV) { - module->addInvGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + module->addNotGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); return true; } -- cgit v1.2.3 From 83e2698e10065a27afcc0f0db3818ed3b4a5942e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 19:31:59 +0200 Subject: AST ProcessGenerator: replaced subst_*_{from,to} with subst_*_map --- frontends/ast/genrtlil.cc | 67 ++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 41 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3c8f1fa16..b519f9c59 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -178,18 +178,18 @@ struct AST_INTERNAL::ProcessGenerator // This always points to the RTLIL::CaseRule beeing filled at the moment RTLIL::CaseRule *current_case; - // This two variables contain the replacement pattern to be used in the right hand side + // This map contains the replacement pattern to be used in the right hand side // of an assignment. E.g. in the code "foo = bar; foo = func(foo);" the foo in the right // hand side of the 2nd assignment needs to be replace with the temporary signal holding // the value assigned in the first assignment. So when the first assignement is processed // the according information is appended to subst_rvalue_from and subst_rvalue_to. - RTLIL::SigSpec subst_rvalue_from, subst_rvalue_to; + std::map subst_rvalue_map; - // This two variables contain the replacement pattern to be used in the left hand side + // This map contains the replacement pattern to be used in the left hand side // of an assignment. E.g. in the code "always @(posedge clk) foo <= bar" the signal bar // should not be connected to the signal foo. Instead it must be connected to the temporary // signal that is used as input for the register that drives the signal foo. - RTLIL::SigSpec subst_lvalue_from, subst_lvalue_to; + std::map subst_lvalue_map; // The code here generates a number of temprorary signal for each output register. This // map helps generating nice numbered names for all this temporary signals. @@ -214,8 +214,10 @@ struct AST_INTERNAL::ProcessGenerator current_case = &proc->root_case; // create initial temporary signal for all output registers + RTLIL::SigSpec subst_lvalue_from, subst_lvalue_to; collect_lvalues(subst_lvalue_from, always, true, true); subst_lvalue_to = new_temp_signal(subst_lvalue_from); + subst_lvalue_map = subst_lvalue_from.to_sigbit_map(subst_lvalue_to); bool found_anyedge_syncs = false; for (auto child : always->children) @@ -251,8 +253,7 @@ struct AST_INTERNAL::ProcessGenerator // create initial assignments for the temporary signals if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) { - subst_rvalue_from = subst_lvalue_from; - subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.size()); + subst_rvalue_map = subst_lvalue_from.to_sigbit_map(RTLIL::SigSpec(RTLIL::State::Sx, SIZE(subst_lvalue_from))); } else { addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from); } @@ -400,15 +401,13 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_EQ: case AST_ASSIGN_LE: { - std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map); - lvalue.replace(subst_lvalue_from, subst_lvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map); + lvalue.replace(subst_lvalue_map); if (ast->type == AST_ASSIGN_EQ) { - subst_rvalue_from.remove2(unmapped_lvalue, &subst_rvalue_to); - subst_rvalue_from.append(unmapped_lvalue); - subst_rvalue_to.append(rvalue); + for (int i = 0; i < SIZE(unmapped_lvalue); i++) + subst_rvalue_map[unmapped_lvalue[i]] = rvalue[i]; } removeSignalFromCaseTree(lvalue, current_case); @@ -418,9 +417,8 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { - std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map); + sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { @@ -436,13 +434,10 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec this_case_eq_ltemp = new_temp_signal(this_case_eq_lvalue); RTLIL::SigSpec this_case_eq_rvalue = this_case_eq_lvalue; - this_case_eq_rvalue.replace(subst_rvalue_from, subst_rvalue_to); + this_case_eq_rvalue.replace(subst_rvalue_map); - RTLIL::SigSpec backup_subst_lvalue_from = subst_lvalue_from; - RTLIL::SigSpec backup_subst_lvalue_to = subst_lvalue_to; - - RTLIL::SigSpec backup_subst_rvalue_from = subst_rvalue_from; - RTLIL::SigSpec backup_subst_rvalue_to = subst_rvalue_to; + std::map backup_subst_lvalue_map = subst_lvalue_map; + std::map backup_subst_rvalue_map = subst_rvalue_map; RTLIL::CaseRule *default_case = NULL; RTLIL::CaseRule *last_generated_case = NULL; @@ -452,15 +447,11 @@ struct AST_INTERNAL::ProcessGenerator continue; log_assert(child->type == AST_COND); - subst_lvalue_from = backup_subst_lvalue_from; - subst_lvalue_to = backup_subst_lvalue_to; - - subst_rvalue_from = backup_subst_rvalue_from; - subst_rvalue_to = backup_subst_rvalue_to; + subst_lvalue_map = backup_subst_lvalue_map; + subst_rvalue_map = backup_subst_rvalue_map; - subst_lvalue_from.remove2(this_case_eq_lvalue, &subst_lvalue_to); - subst_lvalue_from.append(this_case_eq_lvalue); - subst_lvalue_to.append(this_case_eq_ltemp); + for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) + subst_lvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; @@ -471,10 +462,8 @@ struct AST_INTERNAL::ProcessGenerator default_case = current_case; else if (node->type == AST_BLOCK) processAst(node); - else { - std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map)); - } + else + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map)); } if (default_case != current_case) sw->cases.push_back(current_case); @@ -493,17 +482,13 @@ struct AST_INTERNAL::ProcessGenerator sw->cases.push_back(default_case); } - subst_lvalue_from = backup_subst_lvalue_from; - subst_lvalue_to = backup_subst_lvalue_to; - - subst_rvalue_from = backup_subst_rvalue_from; - subst_rvalue_to = backup_subst_rvalue_to; + subst_lvalue_map = backup_subst_lvalue_map; + subst_rvalue_map = backup_subst_rvalue_map; - subst_rvalue_from.remove2(this_case_eq_lvalue, &subst_rvalue_to); - subst_rvalue_from.append(this_case_eq_lvalue); - subst_rvalue_to.append(this_case_eq_ltemp); + for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) + subst_rvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; - this_case_eq_lvalue.replace(subst_lvalue_from, subst_lvalue_to); + this_case_eq_lvalue.replace(subst_lvalue_map); removeSignalFromCaseTree(this_case_eq_lvalue, current_case); addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp); } -- cgit v1.2.3 From 7f734ecc098a2a113ced835cefc9d4e1982f08d0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 23:50:36 +0200 Subject: Added module->uniquify() --- frontends/verific/verific.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 95b3c407e..0440f88e5 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -603,9 +603,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - std::string wire_name = RTLIL::escape_id(net->Name()); - while (module->count_id(wire_name)) - wire_name += "_"; + RTLIL::IdString wire_name = module->uniquify(RTLIL::escape_id(net->Name())); RTLIL::Wire *wire = module->addWire(wire_name); import_attributes(wire->attributes, net); @@ -627,9 +625,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - std::string wire_name = RTLIL::escape_id(netbus->Name()); - while (module->count_id(wire_name)) - wire_name += "_"; + RTLIL::IdString wire_name = module->uniquify(RTLIL::escape_id(netbus->Name())); RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size()); wire->start_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); import_attributes(wire->attributes, netbus); -- cgit v1.2.3 From d491fd8c19cddb49d2feed2a873a328825c7b8f4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 00:57:24 +0200 Subject: Use stackmap<> in AST ProcessGenerator --- frontends/ast/ast.cc | 2 +- frontends/ast/ast.h | 4 ++-- frontends/ast/genrtlil.cc | 40 +++++++++++++++++++--------------------- 3 files changed, 22 insertions(+), 24 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index ec9616be3..6ac771447 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,7 +51,7 @@ namespace AST_INTERNAL { bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map current_scope; - std::map *genRTLIL_subst_ptr = NULL; + const std::map *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; AstNode *current_top_block, *current_block, *current_block_child; AstModule *current_module; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index e7b075486..6ea241fa9 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -228,7 +228,7 @@ namespace AST // for expressions the resulting signal vector is returned // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false); - RTLIL::SigSpec genWidthRTLIL(int width, std::map *new_subst_ptr = NULL); + RTLIL::SigSpec genWidthRTLIL(int width, const std::map *new_subst_ptr = NULL); // compare AST nodes bool operator==(const AstNode &other) const; @@ -285,7 +285,7 @@ namespace AST_INTERNAL extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; extern AST::AstNode *current_ast, *current_ast_mod; extern std::map current_scope; - extern std::map *genRTLIL_subst_ptr; + extern const std::map *genRTLIL_subst_ptr; extern RTLIL::SigSpec ignoreThisSignalsInInitial; extern AST::AstNode *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b519f9c59..4eb4f6c44 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -27,6 +27,7 @@ */ #include "kernel/log.h" +#include "kernel/utils.h" #include "libs/sha1/sha1.h" #include "ast.h" @@ -183,13 +184,13 @@ struct AST_INTERNAL::ProcessGenerator // hand side of the 2nd assignment needs to be replace with the temporary signal holding // the value assigned in the first assignment. So when the first assignement is processed // the according information is appended to subst_rvalue_from and subst_rvalue_to. - std::map subst_rvalue_map; + stackmap subst_rvalue_map; // This map contains the replacement pattern to be used in the left hand side // of an assignment. E.g. in the code "always @(posedge clk) foo <= bar" the signal bar // should not be connected to the signal foo. Instead it must be connected to the temporary // signal that is used as input for the register that drives the signal foo. - std::map subst_lvalue_map; + stackmap subst_lvalue_map; // The code here generates a number of temprorary signal for each output register. This // map helps generating nice numbered names for all this temporary signals. @@ -402,12 +403,12 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_LE: { RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map); - lvalue.replace(subst_lvalue_map); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map.stdmap()); + lvalue.replace(subst_lvalue_map.stdmap()); if (ast->type == AST_ASSIGN_EQ) { for (int i = 0; i < SIZE(unmapped_lvalue); i++) - subst_rvalue_map[unmapped_lvalue[i]] = rvalue[i]; + subst_rvalue_map.set(unmapped_lvalue[i], rvalue[i]); } removeSignalFromCaseTree(lvalue, current_case); @@ -418,7 +419,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map); + sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { @@ -434,10 +435,7 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec this_case_eq_ltemp = new_temp_signal(this_case_eq_lvalue); RTLIL::SigSpec this_case_eq_rvalue = this_case_eq_lvalue; - this_case_eq_rvalue.replace(subst_rvalue_map); - - std::map backup_subst_lvalue_map = subst_lvalue_map; - std::map backup_subst_rvalue_map = subst_rvalue_map; + this_case_eq_rvalue.replace(subst_rvalue_map.stdmap()); RTLIL::CaseRule *default_case = NULL; RTLIL::CaseRule *last_generated_case = NULL; @@ -447,11 +445,11 @@ struct AST_INTERNAL::ProcessGenerator continue; log_assert(child->type == AST_COND); - subst_lvalue_map = backup_subst_lvalue_map; - subst_rvalue_map = backup_subst_rvalue_map; + subst_lvalue_map.save(); + subst_rvalue_map.save(); for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) - subst_lvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; + subst_lvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]); RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; @@ -463,13 +461,16 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map)); + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map.stdmap())); } if (default_case != current_case) sw->cases.push_back(current_case); else log_assert(current_case->compare.size() == 0); current_case = backup_case; + + subst_lvalue_map.restore(); + subst_rvalue_map.restore(); } if (last_generated_case != NULL && ast->get_bool_attribute("\\full_case") && default_case == NULL) { @@ -482,13 +483,10 @@ struct AST_INTERNAL::ProcessGenerator sw->cases.push_back(default_case); } - subst_lvalue_map = backup_subst_lvalue_map; - subst_rvalue_map = backup_subst_rvalue_map; - for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) - subst_rvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; + subst_rvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]); - this_case_eq_lvalue.replace(subst_lvalue_map); + this_case_eq_lvalue.replace(subst_lvalue_map.stdmap()); removeSignalFromCaseTree(this_case_eq_lvalue, current_case); addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp); } @@ -1368,9 +1366,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // this is a wrapper for AstNode::genRTLIL() when a specific signal width is requested and/or // signals must be substituted before beeing used as input values (used by ProcessGenerator) // note that this is using some global variables to communicate this special settings to AstNode::genRTLIL(). -RTLIL::SigSpec AstNode::genWidthRTLIL(int width, std::map *new_subst_ptr) +RTLIL::SigSpec AstNode::genWidthRTLIL(int width, const std::map *new_subst_ptr) { - std::map *backup_subst_ptr = genRTLIL_subst_ptr; + const std::map *backup_subst_ptr = genRTLIL_subst_ptr; if (new_subst_ptr) genRTLIL_subst_ptr = new_subst_ptr; -- cgit v1.2.3 From 64713647a966e8a14dff39f9ac18aafe9c882f46 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:17:49 +0200 Subject: Improved AST ProcessGenerator performance --- frontends/ast/genrtlil.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 4eb4f6c44..1936146b3 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -357,7 +357,7 @@ struct AST_INTERNAL::ProcessGenerator // e.g. when the last statement in the code "a = 23; if (b) a = 42; a = 0;" is processed this // function is called to clean up the first two assignments as they are overwritten by // the third assignment. - void removeSignalFromCaseTree(RTLIL::SigSpec pattern, RTLIL::CaseRule *cs) + void removeSignalFromCaseTree(const std::set &pattern, RTLIL::CaseRule *cs) { for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) it->first.remove2(pattern, &it->second); @@ -411,7 +411,7 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_map.set(unmapped_lvalue[i], rvalue[i]); } - removeSignalFromCaseTree(lvalue, current_case); + removeSignalFromCaseTree(lvalue.to_sigbit_set(), current_case); current_case->actions.push_back(RTLIL::SigSig(lvalue, rvalue)); } break; @@ -487,7 +487,7 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]); this_case_eq_lvalue.replace(subst_lvalue_map.stdmap()); - removeSignalFromCaseTree(this_case_eq_lvalue, current_case); + removeSignalFromCaseTree(this_case_eq_lvalue.to_sigbit_set(), current_case); addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp); } break; -- cgit v1.2.3 From acb435b6cf583b6c18f405a9c92566c4e9fb85e5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:02:30 +0200 Subject: Added const folding of AST_CASE to AST simplifier --- frontends/ast/ast.cc | 8 ++++++++ frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 6ac771447..0ea38b506 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -722,6 +722,14 @@ AstNode *AstNode::mkconst_str(const std::string &str) return node; } +bool AstNode::bits_only_01() +{ + for (auto bit : bits) + if (bit != RTLIL::S0 && bit != RTLIL::S1) + return false; + return true; +} + RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed) { std::vector bits = this->bits; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6ea241fa9..ef54d76f4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -246,6 +246,7 @@ namespace AST RTLIL::Const bitsAsConst(int width = -1); RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); + bool bits_only_01(); bool asBool(); // helper functions for real valued const eval diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 76d1f8270..85671213d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1567,7 +1567,7 @@ skip_dynamic_range_lvalue_expansion:; } // perform const folding when activated - if (const_fold && newNode == NULL) + if (const_fold) { bool string_op; std::vector tmp_bits; @@ -1746,6 +1746,37 @@ skip_dynamic_range_lvalue_expansion:; newNode->realvalue = -children[0]->asReal(sign_hint); } break; + case AST_CASE: + if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) { + std::vector new_children; + new_children.push_back(children[0]); + for (int i = 1; i < SIZE(children); i++) { + AstNode *child = children[i]; + log_assert(child->type == AST_COND); + for (auto v : child->children) { + if (v->type == AST_DEFAULT) + goto keep_const_cond; + if (v->type == AST_BLOCK) + continue; + if (v->type == AST_CONSTANT && v->bits_only_01()) { + if (v->bits == children[0]->bits) { + while (i+1 < SIZE(children)) + delete children[++i]; + goto keep_const_cond; + } + continue; + } + goto keep_const_cond; + } + if (0) + keep_const_cond: + new_children.push_back(child); + else + delete child; + } + new_children.swap(children); + } + break; case AST_TERNARY: if (children[0]->isConst()) { -- cgit v1.2.3 From 640d9fc551c546b511f8d64c0ccfc438937164a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 14:29:30 +0200 Subject: Added "via_celltype" attribute on task/func --- frontends/ast/simplify.cc | 75 ++++++++++++++++++++++++++++++++++++++++++---- frontends/verilog/parser.y | 26 ++++++++-------- 2 files changed, 83 insertions(+), 18 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 85671213d..2572fa4a9 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1450,9 +1450,15 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } + AstNode *decl = current_scope[str]; + + std::stringstream sstr; + sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; + std::string prefix = sstr.str(); + bool recommend_const_eval = false; bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval); - if (in_param || recommend_const_eval || require_const_eval) + if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count("\\via_celltype")) { bool all_args_const = true; for (auto child : children) { @@ -1474,11 +1480,6 @@ skip_dynamic_range_lvalue_expansion:; log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } - AstNode *decl = current_scope[str]; - std::stringstream sstr; - sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; - std::string prefix = sstr.str(); - size_t arg_count = 0; std::map replace_rules; @@ -1510,6 +1511,68 @@ skip_dynamic_range_lvalue_expansion:; goto replace_fcall_with_id; } + if (decl->attributes.count("\\via_celltype")) + { + std::string celltype = decl->attributes.at("\\via_celltype")->asAttrConst().decode_string(); + std::string outport = str; + + if (celltype.find(' ') != std::string::npos) { + int pos = celltype.find(' '); + outport = RTLIL::escape_id(celltype.substr(pos+1)); + celltype = RTLIL::escape_id(celltype.substr(0, pos)); + } else + celltype = RTLIL::escape_id(celltype); + + AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE)); + cell->str = prefix.substr(0, SIZE(prefix)-1); + cell->children[0]->str = celltype; + + for (auto attr : decl->attributes) + if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0) + { + AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone()); + cell_arg->str = RTLIL::escape_id(attr.first.str().substr(strlen("\\via_celltype_defparam_"))); + cell->children.push_back(cell_arg); + } + + for (auto child : decl->children) + if (child->type == AST_WIRE && (child->is_input || child->is_output || (type == AST_FCALL && child->str == str))) + { + AstNode *wire = child->clone(); + wire->str = prefix + wire->str; + wire->port_id = 0; + wire->is_input = false; + wire->is_output = false; + current_ast_mod->children.push_back(wire); + while (wire->simplify(true, false, false, 1, -1, false, false)) { } + + AstNode *wire_id = new AstNode(AST_IDENTIFIER); + wire_id->str = wire->str; + + if ((child->is_input || child->is_output) && arg_count < children.size()) + { + AstNode *arg = children[arg_count++]->clone(); + AstNode *assign = child->is_input ? + new AstNode(AST_ASSIGN_EQ, wire_id, arg) : + new AstNode(AST_ASSIGN_EQ, arg, wire_id); + + for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { + if (*it != current_block_child) + continue; + current_block->children.insert(it, assign); + break; + } + } + + AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id->clone()); + cell_arg->str = child->str == str ? outport : child->str; + cell->children.push_back(cell_arg); + } + + current_ast_mod->children.push_back(cell); + goto replace_fcall_with_id; + } + for (auto child : decl->children) if (child->type == AST_WIRE) { diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index f619d3c2b..bf9b21bb6 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -407,33 +407,35 @@ module_body_stmt: always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: - TOK_TASK TOK_ID ';' { + attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); - current_function_or_task->str = *$2; + current_function_or_task->str = *$3; + append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); current_function_or_task_port_id = 1; - delete $2; + delete $3; } task_func_body TOK_ENDTASK { current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { + attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); - current_function_or_task->str = *$4; + current_function_or_task->str = *$5; + append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); AstNode *outreg = new AstNode(AST_WIRE); - outreg->str = *$4; - outreg->is_signed = $2; - if ($3 != NULL) { - outreg->children.push_back($3); - outreg->is_signed = $2 || $3->is_signed; - $3->is_signed = false; + outreg->str = *$5; + outreg->is_signed = $3; + if ($4 != NULL) { + outreg->children.push_back($4); + outreg->is_signed = $3 || $4->is_signed; + $4->is_signed = false; } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; - delete $4; + delete $5; } task_func_body TOK_ENDFUNCTION { current_function_or_task = NULL; ast_stack.pop_back(); -- cgit v1.2.3 From 38addd4c67905e3d1514ba839f07d94058e42560 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:42:28 +0200 Subject: Added support for global tasks and functions --- frontends/ast/ast.cc | 38 ++++++++++++++++++++++++----------- frontends/verilog/parser.y | 30 +++++++++++++++++---------- frontends/verilog/verilog_frontend.cc | 8 ++++---- 3 files changed, 49 insertions(+), 27 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0ea38b506..d59ff1bb6 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -945,21 +945,35 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_icells = icells; flag_autowire = autowire; + std::vector global_decls; + log_assert(current_ast->type == AST_DESIGN); - for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { - if (flag_icells && (*it)->str.substr(0, 2) == "\\$") - (*it)->str = (*it)->str.substr(1); - if (defer) - (*it)->str = "$abstract" + (*it)->str; - if (design->has((*it)->str)) { - if (!ignore_redef) - log_error("Re-definition of module `%s' at %s:%d!\n", + for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) + { + if ((*it)->type == AST_MODULE) + { + for (auto n : global_decls) + (*it)->children.push_back(n->clone()); + + if (flag_icells && (*it)->str.substr(0, 2) == "\\$") + (*it)->str = (*it)->str.substr(1); + + if (defer) + (*it)->str = "$abstract" + (*it)->str; + + if (design->has((*it)->str)) { + if (!ignore_redef) + log_error("Re-definition of module `%s' at %s:%d!\n", + (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); + log("Ignoring re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - log("Ignoring re-definition of module `%s' at %s:%d!\n", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - continue; + continue; + } + + design->add(process_module(*it, defer)); } - design->add(process_module(*it, defer)); + else + global_decls.push_back(*it); } } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index bf9b21bb6..acd904e55 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -137,14 +137,21 @@ static void free_attr(std::map *al) %% -input: - module input | - defattr input | - /* empty */ { - for (auto &it : default_attr_list) - delete it.second; - default_attr_list.clear(); - }; +input: { + ast_stack.push_back(current_ast); +} design { + ast_stack.pop_back(); + log_assert(SIZE(ast_stack) == 0); + for (auto &it : default_attr_list) + delete it.second; + default_attr_list.clear(); +}; + +design: + module design | + defattr design | + task_func_decl design | + /* empty */; attr: { @@ -214,9 +221,9 @@ module: attr TOK_MODULE TOK_ID { do_not_require_port_stubs = false; AstNode *mod = new AstNode(AST_MODULE); - current_ast->children.push_back(mod); - current_ast_mod = mod; + ast_stack.back()->children.push_back(mod); ast_stack.push_back(mod); + current_ast_mod = mod; port_stubs.clear(); port_counter = 0; mod->str = *$3; @@ -227,7 +234,8 @@ module: frontend_verilog_yyerror("Missing details for module port `%s'.", port_stubs.begin()->first.c_str()); ast_stack.pop_back(); - log_assert(ast_stack.size() == 0); + log_assert(ast_stack.size() == 1); + current_ast_mod = NULL; }; module_para_opt: diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 4466e1cb6..195789086 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -285,10 +285,10 @@ struct VerilogFrontend : public Frontend { frontend_verilog_yylex_destroy(); for (auto &child : current_ast->children) { - log_assert(child->type == AST::AST_MODULE); - for (auto &attr : attributes) - if (child->attributes.count(attr) == 0) - child->attributes[attr] = AST::AstNode::mkconst_int(1, false); + if (child->type == AST::AST_MODULE) + for (auto &attr : attributes) + if (child->attributes.count(attr) == 0) + child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire); -- cgit v1.2.3 From 7bfc4ae12030648cd73686d3779c6d412a3c33c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:43:51 +0200 Subject: Added Verilog/AST support for DPI functions (dpi_call() still unimplemented) --- frontends/ast/Makefile.inc | 1 + frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 4 ++++ frontends/ast/dpicall.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ frontends/ast/genrtlil.cc | 1 + frontends/ast/simplify.cc | 32 ++++++++++++++++++++++++++++++-- frontends/verilog/lexer.l | 22 ++++++++++++++++++++++ frontends/verilog/parser.y | 33 ++++++++++++++++++++++++++++++++- 8 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 frontends/ast/dpicall.cc (limited to 'frontends') diff --git a/frontends/ast/Makefile.inc b/frontends/ast/Makefile.inc index 993ead928..91d917c91 100644 --- a/frontends/ast/Makefile.inc +++ b/frontends/ast/Makefile.inc @@ -2,4 +2,5 @@ OBJS += frontends/ast/ast.o OBJS += frontends/ast/simplify.o OBJS += frontends/ast/genrtlil.o +OBJS += frontends/ast/dpicall.o diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d59ff1bb6..de38eff6c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -68,6 +68,7 @@ std::string AST::type2str(AstNodeType type) X(AST_MODULE) X(AST_TASK) X(AST_FUNCTION) + X(AST_DPI_FUNCTION) X(AST_WIRE) X(AST_MEMORY) X(AST_AUTOWIRE) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index ef54d76f4..88917c64b 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -46,6 +46,7 @@ namespace AST AST_MODULE, AST_TASK, AST_FUNCTION, + AST_DPI_FUNCTION, AST_WIRE, AST_MEMORY, @@ -278,6 +279,9 @@ namespace AST // set set_line_num and get_line_num to internal dummy functions (done by simplify() and AstModule::derive // to control the filename and linenum properties of new nodes not generated by a frontend parser) void use_internal_line_num(); + + // call a DPI function + AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector &argtypes, const std::vector &args); } namespace AST_INTERNAL diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc new file mode 100644 index 000000000..a1954dabf --- /dev/null +++ b/frontends/ast/dpicall.cc @@ -0,0 +1,44 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "ast.h" + +AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, const std::vector &argtypes, const std::vector &args) +{ + AST::AstNode *newNode = nullptr; + + log("Calling DPI function `%s' and returning `%s':\n", fname.c_str(), rtype.c_str()); + + log_assert(SIZE(args) == SIZE(argtypes)); + for (int i = 0; i < SIZE(args); i++) + if (argtypes[i] == "real" || argtypes[i] == "shortreal") + log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); + else + log(" arg %d (%s): %d\n", i, argtypes[i].c_str(), args[i]->bitsAsConst().as_int()); + + if (rtype == "real" || rtype == "shortreal") { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = 1234; + } else { + newNode = AstNode::mkconst_int(1234, false); + } + + return newNode; +} + diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 1936146b3..506c2bb25 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -753,6 +753,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // and are only accessed here thru this references case AST_TASK: case AST_FUNCTION: + case AST_DPI_FUNCTION: case AST_AUTOWIRE: case AST_LOCALPARAM: case AST_DEFPARAM: diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2572fa4a9..19f1d0554 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -226,7 +226,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, this_wire_scope[node->str] = node; } if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR || - node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_CELL) { + node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) { backup_scope[node->str] = current_scope[node->str]; current_scope[node->str] = node; } @@ -646,7 +646,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (current_scope.count(str) == 0) { for (auto node : current_ast_mod->children) { if ((node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR || - node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK) && str == node->str) { + node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION) && str == node->str) { current_scope[node->str] = node; break; } @@ -1442,6 +1442,34 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } + if (current_scope.count(str) != 0 && current_scope[str]->type == AST_DPI_FUNCTION) + { + AstNode *dpi_decl = current_scope[str]; + + std::string rtype, fname; + std::vector argtypes; + std::vector args; + + rtype = RTLIL::unescape_id(dpi_decl->children.at(0)->str); + fname = RTLIL::unescape_id(dpi_decl->str); + + for (int i = 1; i < SIZE(dpi_decl->children); i++) + { + if (i-1 >= SIZE(children)) + log_error("Insufficient number of arguments in DPI function call at %s:%d.\n", filename.c_str(), linenum); + + argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str)); + args.push_back(children.at(i-1)->clone()); + while (args.back()->simplify(true, false, false, stage, -1, false, true)) { } + + if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) + log_error("Failed to evaluate DPI function with non-constant argument at %s:%d.\n", filename.c_str(), linenum); + } + + newNode = dpi_call(rtype, fname, argtypes, args); + goto apply_newNode; + } + if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index fdb9bb02c..cf51aac82 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -74,6 +74,7 @@ YOSYS_NAMESPACE_END %x STRING %x SYNOPSYS_TRANSLATE_OFF %x SYNOPSYS_FLAGS +%x IMPORT_DPI %% @@ -274,6 +275,27 @@ supply1 { return TOK_SUPPLY1; } . /* ignore everything else */ "*/" { BEGIN(0); } +import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { + BEGIN(IMPORT_DPI); + return TOK_DPI_FUNCTION; +} + +[(),] { + return *yytext; +} + +[a-zA-Z_$][a-zA-Z0-9_$]* { + frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); + return TOK_ID; +} + +[ \t\r\n] /* ignore whitespaces */ + +";" { + BEGIN(0); + return *yytext; +} + "\\"[^ \t\r\n]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_ID; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index acd904e55..1d62bc3be 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -104,7 +104,7 @@ static void free_attr(std::map *al) %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT -%token TOK_POSEDGE TOK_NEGEDGE TOK_OR +%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL @@ -415,6 +415,16 @@ module_body_stmt: always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: + attr TOK_DPI_FUNCTION TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3)); + current_function_or_task->str = *$4; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $4; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; @@ -449,6 +459,27 @@ task_func_decl: ast_stack.pop_back(); }; +dpi_function_arg: + TOK_ID TOK_ID { + current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + delete $1; + delete $2; + } | + TOK_ID { + current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + delete $1; + }; + +opt_dpi_function_args: + '(' dpi_function_args ')' | + /* empty */; + +dpi_function_args: + dpi_function_args ',' dpi_function_arg | + dpi_function_args ',' | + dpi_function_arg | + /* empty */; + opt_signed: TOK_SIGNED { $$ = true; -- cgit v1.2.3 From 490d7a5bf2062481dfda656de86bfbeca83c080d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 13:09:47 +0200 Subject: Fixed memory leak in DPI function calls --- frontends/ast/simplify.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 19f1d0554..5cf64310b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1467,6 +1467,10 @@ skip_dynamic_range_lvalue_expansion:; } newNode = dpi_call(rtype, fname, argtypes, args); + + for (auto arg : args) + delete arg; + goto apply_newNode; } -- cgit v1.2.3 From 085c8e873d4d90129a952eba85836891635a7f8c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:11:51 +0200 Subject: Added AstNode::asInt() --- frontends/ast/ast.cc | 23 ++++++++++++++++++++++- frontends/ast/ast.h | 1 + frontends/ast/dpicall.cc | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index de38eff6c..2fc8f9835 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -792,9 +792,30 @@ int AstNode::isConst() return 0; } +uint64_t AstNode::asInt(bool is_signed) +{ + if (type == AST_CONSTANT) + { + RTLIL::Const v = bitsAsConst(64, is_signed); + uint64_t ret = 0; + + for (int i = 0; i < 64; i++) + if (v.bits.at(i) == RTLIL::State::S1) + ret |= uint64_t(1) << i; + + return ret; + } + + if (type == AST_REALVALUE) + return realvalue; + + log_abort(); +} + double AstNode::asReal(bool is_signed) { - if (type == AST_CONSTANT) { + if (type == AST_CONSTANT) + { RTLIL::Const val(bits); bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 88917c64b..0a4016736 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -247,6 +247,7 @@ namespace AST RTLIL::Const bitsAsConst(int width = -1); RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); + uint64_t asInt(bool is_signed); bool bits_only_01(); bool asBool(); diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index a1954dabf..965645cde 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -30,7 +30,7 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, if (argtypes[i] == "real" || argtypes[i] == "shortreal") log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); else - log(" arg %d (%s): %d\n", i, argtypes[i].c_str(), args[i]->bitsAsConst().as_int()); + log(" arg %d (%s): %lld\n", i, argtypes[i].c_str(), (long long)args[i]->asInt(args[i]->is_signed)); if (rtype == "real" || rtype == "shortreal") { newNode = new AstNode(AST_REALVALUE); -- cgit v1.2.3 From 6c5cafcd8bf4d6b12b4d510480a0ccc1adee7212 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:22:04 +0200 Subject: Added support for DPI function with different names in C and Verilog --- frontends/ast/simplify.cc | 8 ++++---- frontends/verilog/lexer.l | 8 ++++---- frontends/verilog/parser.y | 13 ++++++++++++- 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5cf64310b..859058cb9 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1451,15 +1451,15 @@ skip_dynamic_range_lvalue_expansion:; std::vector args; rtype = RTLIL::unescape_id(dpi_decl->children.at(0)->str); - fname = RTLIL::unescape_id(dpi_decl->str); + fname = RTLIL::unescape_id(dpi_decl->children.at(1)->str); - for (int i = 1; i < SIZE(dpi_decl->children); i++) + for (int i = 2; i < SIZE(dpi_decl->children); i++) { - if (i-1 >= SIZE(children)) + if (i-2 >= SIZE(children)) log_error("Insufficient number of arguments in DPI function call at %s:%d.\n", filename.c_str(), linenum); argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str)); - args.push_back(children.at(i-1)->clone()); + args.push_back(children.at(i-2)->clone()); while (args.back()->simplify(true, false, false, stage, -1, false, true)) { } if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index cf51aac82..f79f81a9c 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -280,10 +280,6 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { return TOK_DPI_FUNCTION; } -[(),] { - return *yytext; -} - [a-zA-Z_$][a-zA-Z0-9_$]* { frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); return TOK_ID; @@ -296,6 +292,10 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { return *yytext; } +. { + return *yytext; +} + "\\"[^ \t\r\n]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_ID; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 1d62bc3be..22312c6d1 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -416,7 +416,7 @@ module_body_stmt: task_func_decl: attr TOK_DPI_FUNCTION TOK_ID TOK_ID { - current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3)); + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3), AstNode::mkconst_str(*$4)); current_function_or_task->str = *$4; append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); @@ -425,6 +425,17 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | + attr TOK_DPI_FUNCTION TOK_ID '=' TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$5), AstNode::mkconst_str(*$3)); + current_function_or_task->str = *$6; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $5; + delete $6; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; -- cgit v1.2.3 From ad146c25823505e8f9b3cb2b67ba00821a755375 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:33:40 +0200 Subject: Fixed small memory leak in ast simplify --- frontends/ast/simplify.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 859058cb9..68c17271c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1585,8 +1585,8 @@ skip_dynamic_range_lvalue_expansion:; { AstNode *arg = children[arg_count++]->clone(); AstNode *assign = child->is_input ? - new AstNode(AST_ASSIGN_EQ, wire_id, arg) : - new AstNode(AST_ASSIGN_EQ, arg, wire_id); + new AstNode(AST_ASSIGN_EQ, wire_id->clone(), arg) : + new AstNode(AST_ASSIGN_EQ, arg, wire_id->clone()); for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { if (*it != current_block_child) @@ -1596,7 +1596,7 @@ skip_dynamic_range_lvalue_expansion:; } } - AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id->clone()); + AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id); cell_arg->str = child->str == str ? outport : child->str; cell->children.push_back(cell_arg); } -- cgit v1.2.3 From 74af3a2b7086acad45d15b590a0d23572e8c8734 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:22:09 +0200 Subject: Archibald Rust and Clifford Wolf: ffi-based dpi_call() --- frontends/ast/dpicall.cc | 96 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 6 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index 965645cde..b79bd59eb 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -17,26 +17,110 @@ * */ +#include +#include #include "ast.h" +typedef void (*ffi_fptr) (); + +static ffi_fptr resolve_fn (std::string symbol_name) +{ + if (symbol_name.find(':') != std::string::npos) + { + int pos = symbol_name.find(':'); + std::string plugin_name = symbol_name.substr(0, pos); + std::string real_symbol_name = symbol_name.substr(pos+1); + + while (loaded_plugin_aliases.count(plugin_name)) + plugin_name = loaded_plugin_aliases.at(plugin_name); + + if (loaded_plugins.count(plugin_name) == 0) + log_error("unable to resolve '%s': can't find plugin `%s'\n", symbol_name.c_str(), plugin_name.c_str()); + + void *symbol = dlsym(loaded_plugins.at(plugin_name), real_symbol_name.c_str()); + + if (symbol == nullptr) + log_error("unable to resolve '%s': can't find symbol `%s' in plugin `%s'\n", + symbol_name.c_str(), real_symbol_name.c_str(), plugin_name.c_str()); + + return (ffi_fptr) symbol; + } + + for (auto &it : loaded_plugins) { + void *symbol = dlsym(it.second, symbol_name.c_str()); + if (symbol != nullptr) + return (ffi_fptr) symbol; + } + + void *symbol = dlsym(RTLD_DEFAULT, symbol_name.c_str()); + if (symbol != nullptr) + return (ffi_fptr) symbol; + + log_error("unable to resolve '%s'.\n", symbol_name.c_str()); +} + AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, const std::vector &argtypes, const std::vector &args) { AST::AstNode *newNode = nullptr; + union { double f64; float f32; int32_t i32; } value_store [args.size() + 1]; + ffi_type *types [args.size() + 1]; + void *values [args.size() + 1]; + ffi_cif cif; + int status; log("Calling DPI function `%s' and returning `%s':\n", fname.c_str(), rtype.c_str()); log_assert(SIZE(args) == SIZE(argtypes)); - for (int i = 0; i < SIZE(args); i++) - if (argtypes[i] == "real" || argtypes[i] == "shortreal") + for (int i = 0; i < SIZE(args); i++) { + if (argtypes[i] == "real") { + log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); + value_store[i].f64 = args[i]->asReal(args[i]->is_signed); + values[i] = &value_store[i].f64; + types[i] = &ffi_type_double; + } else if (argtypes[i] == "shortreal") { log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); - else + value_store[i].f32 = args[i]->asReal(args[i]->is_signed); + values[i] = &value_store[i].f32; + types[i] = &ffi_type_double; + } else if (argtypes[i] == "integer") { log(" arg %d (%s): %lld\n", i, argtypes[i].c_str(), (long long)args[i]->asInt(args[i]->is_signed)); + value_store[i].i32 = args[i]->asInt(args[i]->is_signed); + values[i] = &value_store[i].i32; + types[i] = &ffi_type_sint32; + } else { + log_error("invalid argtype '%s' for argument %d.\n", argtypes[i].c_str(), i); + } + } + + if (rtype == "integer") { + types[args.size()] = &ffi_type_slong; + values[args.size()] = &value_store[args.size()].i32; + } else if (rtype == "shortreal") { + types[args.size()] = &ffi_type_float; + values[args.size()] = &value_store[args.size()].f32; + } else if (rtype == "real") { + types[args.size()] = &ffi_type_double; + values[args.size()] = &value_store[args.size()].f64; + } else { + log_error("invalid rtype '%s'.\n", rtype.c_str()); + } + + if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, args.size(), types[args.size()], types)) != FFI_OK) + log_error("ffi_prep_cif failed: status %d.\n", status); - if (rtype == "real" || rtype == "shortreal") { + ffi_call(&cif, resolve_fn(fname.c_str()), values[args.size()], values); + + if (rtype == "real") { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = value_store[args.size()].f64; + log(" return realvalue: %g\n", newNode->asReal(true)); + } else if (rtype == "shortreal") { newNode = new AstNode(AST_REALVALUE); - newNode->realvalue = 1234; + newNode->realvalue = value_store[args.size()].f32; + log(" return realvalue: %g\n", newNode->asReal(true)); } else { - newNode = AstNode::mkconst_int(1234, false); + newNode = AstNode::mkconst_int(value_store[args.size()].i32, false); + log(" return integer: %lld\n", (long long)newNode->asInt(true)); } return newNode; -- cgit v1.2.3 From e218f0eacf7cbcfa0736cb2d66bba0010e8e6799 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:30:29 +0200 Subject: Added support for non-standard : DPI syntax --- frontends/verilog/parser.y | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'frontends') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 22312c6d1..3512538ca 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -436,6 +436,18 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | + attr TOK_DPI_FUNCTION TOK_ID ':' TOK_ID '=' TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$7), AstNode::mkconst_str(*$3 + ":" + RTLIL::unescape_id(*$5))); + current_function_or_task->str = *$8; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $5; + delete $7; + delete $8; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; -- cgit v1.2.3 From 98442e019d745f1d61983c071decfa3ebc1ff0cf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 16:09:13 +0200 Subject: Added emscripten (emcc) support to build system and some build fixes --- frontends/ast/ast.cc | 4 ++++ frontends/ast/dpicall.cc | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'frontends') diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 2fc8f9835..1e43875ae 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -844,7 +844,11 @@ RTLIL::Const AstNode::realAsConst(int width) { double v = round(realvalue); RTLIL::Const result; +#ifdef EMSCRIPTEN + if (!isfinite(v)) { +#else if (!std::isfinite(v)) { +#endif result.bits = std::vector(width, RTLIL::State::Sx); } else { bool is_negative = v < 0; diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index b79bd59eb..2eb104fa0 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -17,9 +17,12 @@ * */ +#include "ast.h" + +#ifdef YOSYS_ENABLE_PLUGINS + #include #include -#include "ast.h" typedef void (*ffi_fptr) (); @@ -126,3 +129,12 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, return newNode; } +#else /* YOSYS_ENABLE_PLUGINS */ + +AST::AstNode *AST::dpi_call(const std::string&, const std::string &fname, const std::vector&, const std::vector&) +{ + log_error("Can't call DPI function `%s': this version of yosys is built without plugin support\n", fname.c_str()); +} + +#endif /* YOSYS_ENABLE_PLUGINS */ + -- cgit v1.2.3 From 19cff41eb4261b20374058f16807a229af46f304 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:03:55 +0200 Subject: Changed frontend-api from FILE to std::istream --- frontends/ilang/ilang_frontend.cc | 5 +++-- frontends/ilang/ilang_frontend.h | 5 ++--- frontends/ilang/lexer.l | 5 ++++- frontends/ilang/parser.y | 1 + frontends/liberty/liberty.cc | 4 ++-- frontends/verilog/lexer.l | 3 +++ frontends/verilog/parser.y | 1 + frontends/verilog/preproc.cc | 31 ++++++++++++++++--------------- frontends/verilog/verilog_frontend.cc | 12 ++++++------ frontends/verilog/verilog_frontend.h | 5 ++++- frontends/vhdl2verilog/vhdl2verilog.cc | 8 ++++---- 11 files changed, 46 insertions(+), 34 deletions(-) (limited to 'frontends') diff --git a/frontends/ilang/ilang_frontend.cc b/frontends/ilang/ilang_frontend.cc index 2d4b99c52..f6f926db1 100644 --- a/frontends/ilang/ilang_frontend.cc +++ b/frontends/ilang/ilang_frontend.cc @@ -45,15 +45,16 @@ struct IlangFrontend : public Frontend { log("representation of a design in yosys's internal format.)\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { log_header("Executing ILANG frontend.\n"); extra_args(f, filename, args, 1); log("Input filename: %s\n", filename.c_str()); + ILANG_FRONTEND::lexin = f; ILANG_FRONTEND::current_design = design; rtlil_frontend_ilang_yydebug = false; - rtlil_frontend_ilang_yyrestart(f); + rtlil_frontend_ilang_yyrestart(NULL); rtlil_frontend_ilang_yyparse(); rtlil_frontend_ilang_yylex_destroy(); } diff --git a/frontends/ilang/ilang_frontend.h b/frontends/ilang/ilang_frontend.h index 317ec0d51..b04d6c512 100644 --- a/frontends/ilang/ilang_frontend.h +++ b/frontends/ilang/ilang_frontend.h @@ -26,12 +26,11 @@ #define ILANG_FRONTEND_H #include "kernel/yosys.h" -#include YOSYS_NAMESPACE_BEGIN namespace ILANG_FRONTEND { - void ilang_frontend(FILE *f, RTLIL::Design *design); + extern std::istream *lexin; extern RTLIL::Design *current_design; } @@ -42,7 +41,7 @@ int rtlil_frontend_ilang_yylex(void); void rtlil_frontend_ilang_yyerror(char const *s); void rtlil_frontend_ilang_yyrestart(FILE *f); int rtlil_frontend_ilang_yyparse(void); -void rtlil_frontend_ilang_yylex_destroy(void); +int rtlil_frontend_ilang_yylex_destroy(void); int rtlil_frontend_ilang_yyget_lineno(void); #endif diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index f3bdeb1a4..4109cd4bc 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -29,9 +29,12 @@ #pragma clang diagnostic ignored "-Wdeprecated-register" #endif -#include "kernel/rtlil.h" +#include "ilang_frontend.h" #include "parser.tab.h" +#define YY_INPUT(buf,result,max_size) \ + result = ILANG_FRONTEND::lexin->readsome(buf, max_size); + %} %option yylineno diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e1ef39a55..a5cc06898 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -27,6 +27,7 @@ #include "ilang_frontend.h" YOSYS_NAMESPACE_BEGIN namespace ILANG_FRONTEND { + std::istream *lexin; RTLIL::Design *current_design; RTLIL::Module *current_module; RTLIL::Wire *current_wire; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 83bfce371..a9ab022a4 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -430,7 +430,7 @@ struct LibertyFrontend : public Frontend { log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { bool flag_lib = false; bool flag_ignore_redef = false; @@ -467,7 +467,7 @@ struct LibertyFrontend : public Frontend { } extra_args(f, filename, args, argidx); - LibertyParser parser(f); + LibertyParser parser(*f); int cell_count = 0; for (auto cell : parser.ast->children) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index f79f81a9c..c9302aba8 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -63,6 +63,9 @@ YOSYS_NAMESPACE_END frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \ return TOK_ID; +#define YY_INPUT(buf,result,max_size) \ + result = lexin->readsome(buf, max_size); + %} %option yylineno diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 3512538ca..a9f69a49c 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -58,6 +58,7 @@ namespace VERILOG_FRONTEND { bool do_not_require_port_stubs; bool default_nettype_wire; bool sv_mode; + std::istream *lexin; } YOSYS_NAMESPACE_END diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index ae139741a..f83433219 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -193,7 +193,7 @@ static std::string next_token(bool pass_newline = false) return token; } -static void input_file(FILE *f, std::string filename) +static void input_file(std::istream &f, std::string filename) { char buffer[513]; int rc; @@ -202,14 +202,14 @@ static void input_file(FILE *f, std::string filename) auto it = input_buffer.begin(); input_buffer.insert(it, "`file_push " + filename + "\n"); - while ((rc = fread(buffer, 1, sizeof(buffer)-1, f)) > 0) { + while ((rc = f.readsome(buffer, sizeof(buffer)-1)) > 0) { buffer[rc] = 0; input_buffer.insert(it, buffer); } input_buffer.insert(it, "\n`file_pop\n"); } -std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) +std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) { std::set defines_with_args; std::map defines_map(pre_defines_map); @@ -288,27 +288,28 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m else fn = fn.substr(0, pos) + fn.substr(pos+1); } - FILE *fp = fopen(fn.c_str(), "r"); - if (fp == NULL && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) { + std::ifstream ff; + ff.clear(); + ff.open(fn.c_str()); + if (ff.fail() && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) { // if the include file was not found, it is not given with an absolute path, and the // currently read file is given with a path, then try again relative to its directory - std::string fn2 = filename.substr(0, filename.rfind('/')+1) + fn; - fp = fopen(fn2.c_str(), "r"); + ff.clear(); + ff.open(filename.substr(0, filename.rfind('/')+1) + fn); } - if (fp == NULL && fn.size() > 0 && fn[0] != '/') { + if (ff.fail() && fn.size() > 0 && fn[0] != '/') { // if the include file was not found and it is not given with an absolute path, then // search it in the include path for (auto incdir : include_dirs) { - std::string fn2 = incdir + '/' + fn; - fp = fopen(fn2.c_str(), "r"); - if (fp != NULL) break; + ff.clear(); + ff.open(incdir + '/' + fn); + if (!ff.fail()) break; } } - if (fp != NULL) { - input_file(fp, fn); - fclose(fp); - } else + if (ff.fail()) output_code.push_back("`file_notfound " + fn); + else + input_file(ff, fn); continue; } diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 195789086..c63fbb08a 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -136,7 +136,7 @@ struct VerilogFrontend : public Frontend { log("the syntax of the code, rather than to rely on read_verilog for that.\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { bool flag_dump_ast1 = false; bool flag_dump_ast2 = false; @@ -269,18 +269,18 @@ struct VerilogFrontend : public Frontend { current_ast = new AST::AstNode(AST::AST_DESIGN); default_nettype_wire = true; - FILE *fp = f; + lexin = f; std::string code_after_preproc; if (!flag_nopp) { - code_after_preproc = frontend_verilog_preproc(f, filename, defines_map, include_dirs); + code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, include_dirs); if (flag_ppdump) log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str()); - fp = fmemopen((void*)code_after_preproc.c_str(), code_after_preproc.size(), "r"); + lexin = new std::istringstream(code_after_preproc); } frontend_verilog_yyset_lineno(1); - frontend_verilog_yyrestart(fp); + frontend_verilog_yyrestart(NULL); frontend_verilog_yyparse(); frontend_verilog_yylex_destroy(); @@ -294,7 +294,7 @@ struct VerilogFrontend : public Frontend { AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire); if (!flag_nopp) - fclose(fp); + delete lexin; delete current_ast; current_ast = NULL; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index dac5b3d02..af6495f8f 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -50,10 +50,13 @@ namespace VERILOG_FRONTEND // running in SystemVerilog mode extern bool sv_mode; + + // lexer input stream + extern std::istream *lexin; } // the pre-processor -std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); +std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); YOSYS_NAMESPACE_END diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index f0545700a..8b6f62a63 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -177,11 +177,11 @@ struct Vhdl2verilogPass : public Pass { log_error("Execution of command \"%s\" failed: the shell returned %d\n", command.c_str(), WEXITSTATUS(ret)); if (out_file.empty()) { - f = fopen(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str(), "rt"); - if (f == NULL) + std::ifstream ff; + ff.open(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str()); + if (ff.fail()) log_error("Can't open vhdl2verilog output file `vhdl2verilog_output.v'.\n"); - Frontend::frontend_call(design, f, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog"); - fclose(f); + Frontend::frontend_call(design, &ff, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog"); } log_header("Removing temp directory `%s':\n", tempdir_name); -- cgit v1.2.3 From 58367cd87a5d2bac1de81512f60939c080b3b9ef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:14:58 +0200 Subject: Removed compatbility.{h,cc}: Not using open_memstream/fmemopen anymore --- frontends/verilog/verilog_frontend.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index c63fbb08a..c6d4a0b79 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -27,11 +27,8 @@ */ #include "verilog_frontend.h" -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include "libs/sha1/sha1.h" -#include #include YOSYS_NAMESPACE_BEGIN -- cgit v1.2.3 From 8927aa6148f5575b2da9bfb76afb4af076fe18f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 4 Sep 2014 02:07:52 +0200 Subject: Removed $bu0 cell type --- frontends/ast/genrtlil.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 506c2bb25..0c7be1f54 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -70,7 +70,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) -static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) +static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed) { if (width <= sig.size()) { sig.extend(width, is_signed); @@ -80,7 +80,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s std::stringstream sstr; sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); - RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$pos"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width); @@ -1012,7 +1012,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = arg.size(); if (width_hint > 0) { width = width_hint; - widthExtend(this, arg, width, is_signed, "$pos"); + widthExtend(this, arg, width, is_signed); } return uniop2rtlil(this, type_name, width, arg); } @@ -1167,8 +1167,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = std::max(val1.size(), val2.size()); is_signed = children[1]->is_signed && children[2]->is_signed; - widthExtend(this, val1, width, is_signed, "$bu0"); - widthExtend(this, val2, width, is_signed, "$bu0"); + widthExtend(this, val1, width, is_signed); + widthExtend(this, val2, width, is_signed); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); -- cgit v1.2.3 From 79cbf9067c07ed810b3466174278d77b9a05b46d Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Sat, 6 Sep 2014 08:47:06 +0200 Subject: Corrected spelling mistakes found by lintian --- frontends/ast/simplify.cc | 2 +- frontends/verific/build_amd64.txt | 2 +- frontends/verific/verific.cc | 2 +- frontends/vhdl2verilog/vhdl2verilog.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 68c17271c..1998c12e4 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -464,7 +464,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_DEFPARAM && !str.empty()) { size_t pos = str.rfind('.'); if (pos == std::string::npos) - log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n", + log_error("Defparam `%s' does not contain a dot (module/parameter separator) at %s:%d!\n", RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1); if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL) diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 2c3ba7b4d..94615d38d 100644 --- a/frontends/verific/build_amd64.txt +++ b/frontends/verific/build_amd64.txt @@ -17,7 +17,7 @@ VERIFIC_DIR = /usr/local/src/verific_lib_eval --snap-- -2.) Install the neccessary multilib packages +2.) Install the necessary multilib packages Hint: On debian/ubuntu the multilib packages have names such as libreadline-dev:amd64 or lib32readline6-dev, depending on the diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 0440f88e5..d0f148386 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -887,7 +887,7 @@ struct VerificPass : public Pass { } if (argidx > args.size() && args[argidx].substr(0, 1) == "-") - cmd_error(args, argidx, "unkown option"); + cmd_error(args, argidx, "unknown option"); if (mode_all) { diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 8b6f62a63..b408d621b 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -116,7 +116,7 @@ struct Vhdl2verilogPass : public Pass { if (argidx == args.size()) cmd_error(args, argidx, "Missing filenames."); if (args[argidx].substr(0, 1) == "-") - cmd_error(args, argidx, "Unkown option."); + cmd_error(args, argidx, "Unknown option."); if (top_entity.empty()) log_cmd_error("Missing -top option.\n"); -- cgit v1.2.3 From deff416ea7d60b490b0e4f8d70abdb1ad8d4d0f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 17:58:27 +0200 Subject: Fixed assignment of out-of bounds array element --- frontends/ast/genrtlil.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 0c7be1f54..f87a68f67 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -276,6 +276,7 @@ struct AST_INTERNAL::ProcessGenerator for (auto &init_lvalue_c : init_lvalue.chunks()) { RTLIL::SigSpec lhs = init_lvalue_c; RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue_c.width); + remove_unwanted_lvalue_bits(lhs, rhs); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); } @@ -284,6 +285,22 @@ struct AST_INTERNAL::ProcessGenerator outputSignals = RTLIL::SigSpec(subst_lvalue_from); } + void remove_unwanted_lvalue_bits(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) + { + RTLIL::SigSpec new_lhs, new_rhs; + + log_assert(SIZE(lhs) == SIZE(rhs)); + for (int i = 0; i < SIZE(lhs); i++) { + if (lhs[i].wire == nullptr) + continue; + new_lhs.append(lhs[i]); + new_rhs.append(rhs[i]); + } + + lhs = new_lhs; + rhs = new_rhs; + } + // create new temporary signals RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { @@ -349,8 +366,13 @@ struct AST_INTERNAL::ProcessGenerator log_abort(); } - if (run_sort_and_unify) - reg.sort_and_unify(); + if (run_sort_and_unify) { + std::set sorted_reg; + for (auto bit : reg) + if (bit.wire) + sorted_reg.insert(bit); + reg = RTLIL::SigSpec(sorted_reg); + } } // remove all assignments to the given signal pattern in a case and all its children. @@ -384,6 +406,7 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue_c.width); if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute("\\nosync")) rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size()); + remove_unwanted_lvalue_bits(lhs, rhs); actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); } @@ -412,6 +435,7 @@ struct AST_INTERNAL::ProcessGenerator } removeSignalFromCaseTree(lvalue.to_sigbit_set(), current_case); + remove_unwanted_lvalue_bits(lvalue, rvalue); current_case->actions.push_back(RTLIL::SigSig(lvalue, rvalue)); } break; -- cgit v1.2.3 From 680eaaac41bc64000faa483955279155b0fc0a6b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 19:31:04 +0200 Subject: Fixed $clog2 (off by one error) --- frontends/ast/simplify.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 1998c12e4..9e797573c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1123,7 +1123,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - result_width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1; + result_width = abs(left_at_zero_ast->integer - right_at_zero_ast->integer) + 1; } did_something = true; newNode = new AstNode(AST_CASE, shift_expr); @@ -1370,7 +1370,7 @@ skip_dynamic_range_lvalue_expansion:; uint32_t result = 0; for (size_t i = 0; i < arg_value.bits.size(); i++) if (arg_value.bits.at(i) == RTLIL::State::S1) - result = i; + result = i + 1; newNode = mkconst_int(result, false); goto apply_newNode; -- cgit v1.2.3 From 48b00dcceab8bb046258cd6f0912636a6e5b232c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 12:25:23 +0200 Subject: Another $clog2 bugfix --- frontends/ast/simplify.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'frontends') diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 9e797573c..969cc2302 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1365,6 +1365,8 @@ skip_dynamic_range_lvalue_expansion:; log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); RTLIL::Const arg_value = buf->bitsAsConst(); + if (arg_value.as_bool()) + arg_value = const_sub(arg_value, 1, false, false, SIZE(arg_value)); delete buf; uint32_t result = 0; -- cgit v1.2.3