From 0defc86519fb02dd366b20ccec4add09302eae98 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Feb 2014 19:17:07 +0100 Subject: [PATCH 001/750] renamed ilang "scope error" to "ilang error" --- frontends/ilang/parser.y | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index c2e09022..ebb4d309 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; From ab71bd0746c39402aefaea85322fe36bdbaabb09 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 08:35:42 +0100 Subject: [PATCH 002/750] Updated ABC to rev e97a6e1d59b9 --- Makefile | 2 +- passes/abc/abc.cc | 53 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 697cf69f..9a8a277a 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 10cc13a2a0f1 +ABCREV = e97a6e1d59b9 ABCPULL = 1 -include Makefile.conf diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 5aa13572..e6b7a72d 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -29,10 +29,10 @@ // Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558–562, doi:10.1145/368996.369025 // http://en.wikipedia.org/wiki/Topological_sorting -#define ABC_COMMAND_LIB "strash; retime; balance; dch; map; topo" -#define ABC_COMMAND_CTR "strash; retime; balance; dch; map; topo; buffer; upsize; dnsize; stime" -#define ABC_COMMAND_LUT "strash; retime; balance; dch; if" -#define ABC_COMMAND_DFL "strash; retime; balance; dch; map" +#define ABC_COMMAND_LIB "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; map -v;" +#define ABC_COMMAND_CTR "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; map -v; buffer -v; upsize -v; dnsize -v; stime -p" +#define ABC_COMMAND_LUT "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; if -v" +#define ABC_COMMAND_DFL "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; map -v" #include "kernel/register.h" #include "kernel/sigtools.h" @@ -359,6 +359,30 @@ static void handle_loops() fclose(dot_f); } +static std::string add_echos_to_abc_cmd(std::string str) +{ + std::string new_str, token; + for (size_t i = 0; i < str.size(); i++) { + token += str[i]; + if (str[i] == ';') { + while (i+1 < str.size() && str[i+1] == ' ') + i++; + if (!new_str.empty()) + new_str += "echo; "; + new_str += "echo + " + token + " " + token + " "; + token.clear(); + } + } + + if (!token.empty()) { + if (!new_str.empty()) + new_str += "echo; echo + " + token + "; "; + new_str += token; + } + + return new_str; +} + static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str) { @@ -398,6 +422,17 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std abc_command = constr_file.empty() ? ABC_COMMAND_LIB : ABC_COMMAND_CTR; else abc_command = ABC_COMMAND_DFL; + abc_command = add_echos_to_abc_cmd(abc_command); + + if (abc_command.size() > 128) { + for (size_t i = 0; i+1 < abc_command.size(); i++) + if (abc_command[i] == ';' && abc_command[i+1] == ' ') + abc_command[i+1] = '\n'; + FILE *f = fopen(stringf("%s/abc.script", tempdir_name).c_str(), "wt"); + fprintf(f, "%s\n", abc_command.c_str()); + fclose(f); + abc_command = stringf("source %s/abc.script", tempdir_name); + } if (clk_str.empty()) { if (clk_str[0] == '!') { @@ -578,6 +613,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std exe_file.c_str(), tempdir_name, tempdir_name, abc_command.c_str()); buffer += stringf("write_blif %s/output.blif' 2>&1", tempdir_name); + log("%s\n", buffer.c_str()); + errno = ENOMEM; // popen does not set errno if memory allocation fails, therefore set it by hand f = popen(buffer.c_str(), "r"); if (f == NULL) @@ -838,6 +875,14 @@ struct AbcPass : public Pass { log(" -constr \n"); log(" pass this file with timing constraints to ABC. use with -liberty.\n"); log("\n"); + log(" a constr file contains two lines:\n"); + log(" set_driving_cell \n"); + log(" set_load \n"); + log("\n"); + log(" the set_driving_cell statement defines which cell type is assumed to\n"); + log(" drive the primary inputs and the set_load statement sets the number of\n"); + log(" flip-flops driven by each primary output.\n"); + log("\n"); log(" -lut \n"); log(" generate netlist using luts of (max) the specified width.\n"); log("\n"); From 9ce7b0fc3bcd1fcb8cebe4f3c86318eaa4fbc943 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 13:11:58 +0100 Subject: [PATCH 003/750] Disabled "abc -dff" in "make test" for now (waiting for scorr bugfix in ABC) --- tests/tools/autotest.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 7bccd9a5..b7ec8b8f 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -114,7 +114,8 @@ do test_passes -p "$scriptopt" else test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt" - test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" + # test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" + test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc; opt" fi touch ../${bn}.log } From 007bdff55d69e6e29091c7beff19c36eeb7ed078 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 23:29:54 +0100 Subject: [PATCH 004/750] Added support for functions returning integer --- frontends/verilog/parser.y | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 5b6bf58c..8080729b 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); From 7664f5d92b9fd78c7a858702544887d48c1d5aec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 08:07:08 +0100 Subject: [PATCH 005/750] Updated ABC and some related changes --- Makefile | 2 +- passes/abc/abc.cc | 41 +++++++++++++++++++++++++++++++---------- tests/tools/autotest.sh | 3 +-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 9a8a277a..72bd6d1e 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = e97a6e1d59b9 +ABCREV = d7d412483aa9 ABCPULL = 1 -include Makefile.conf diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index e6b7a72d..1115bdc7 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -29,10 +29,10 @@ // Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558–562, doi:10.1145/368996.369025 // http://en.wikipedia.org/wiki/Topological_sorting -#define ABC_COMMAND_LIB "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; map -v;" -#define ABC_COMMAND_CTR "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; map -v; buffer -v; upsize -v; dnsize -v; stime -p" -#define ABC_COMMAND_LUT "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; if -v" -#define ABC_COMMAND_DFL "strash; ifraig -v; retime -v; balance -v; dch -vf; scorr -v; map -v" +#define ABC_COMMAND_LIB "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v;" +#define ABC_COMMAND_CTR "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v; buffer -v; upsize -v; dnsize -v; stime -p" +#define ABC_COMMAND_LUT "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; if -v" +#define ABC_COMMAND_DFL "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v" #include "kernel/register.h" #include "kernel/sigtools.h" @@ -383,6 +383,25 @@ static std::string add_echos_to_abc_cmd(std::string str) return new_str; } +static std::string fold_abc_cmd(std::string str) +{ + std::string token, new_str = " "; + int char_counter = 10; + + for (size_t i = 0; i <= str.size(); i++) { + if (i < str.size()) + token += str[i]; + if (i == str.size() || str[i] == ';') { + if (char_counter + token.size() > 75) + new_str += "\n ", char_counter = 14; + new_str += token, char_counter += token.size(); + token.clear(); + } + } + + return new_str; +} + static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str) { @@ -508,6 +527,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std fprintf(f, " n%d", si.id); count_input++; } + if (count_input == 0) + fprintf(f, " dummy_input\n"); fprintf(f, "\n"); int count_output = 0; @@ -857,16 +878,16 @@ struct AbcPass : public Pass { log(" if no -script parameter is given, the following scripts are used:\n"); log("\n"); log(" for -liberty without -constr:\n"); - log(" %s\n", ABC_COMMAND_LIB); + log("%s\n", fold_abc_cmd(ABC_COMMAND_LIB).c_str()); log("\n"); log(" for -liberty with -constr:\n"); - log(" %s\n", ABC_COMMAND_CTR); + log("%s\n", fold_abc_cmd(ABC_COMMAND_CTR).c_str()); log("\n"); log(" for -lut:\n"); - log(" %s\n", ABC_COMMAND_LUT); + log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT).c_str()); log("\n"); log(" otherwise:\n"); - log(" %s\n", ABC_COMMAND_DFL); + log("%s\n", fold_abc_cmd(ABC_COMMAND_DFL).c_str()); log("\n"); log(" -liberty \n"); log(" generate netlists for the specified cell library (using the liberty\n"); @@ -880,8 +901,8 @@ struct AbcPass : public Pass { log(" set_load \n"); log("\n"); log(" the set_driving_cell statement defines which cell type is assumed to\n"); - log(" drive the primary inputs and the set_load statement sets the number of\n"); - log(" flip-flops driven by each primary output.\n"); + log(" drive the primary inputs and the set_load statement sets the load in\n"); + log(" femtofarads for each primary output.\n"); log("\n"); log(" -lut \n"); log(" generate netlist using luts of (max) the specified width.\n"); diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index b7ec8b8f..7bccd9a5 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -114,8 +114,7 @@ do test_passes -p "$scriptopt" else test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt" - # test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" - test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc; opt" + test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" fi touch ../${bn}.log } From b4639078903847469c2cfe211b3e5d7006a78cc8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 08:12:52 +0100 Subject: [PATCH 006/750] Removed double blanks in ABC default command sequences --- passes/abc/abc.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 1115bdc7..dae3a22f 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -29,10 +29,10 @@ // Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558–562, doi:10.1145/368996.369025 // http://en.wikipedia.org/wiki/Topological_sorting -#define ABC_COMMAND_LIB "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v;" -#define ABC_COMMAND_CTR "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v; buffer -v; upsize -v; dnsize -v; stime -p" -#define ABC_COMMAND_LUT "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; if -v" -#define ABC_COMMAND_DFL "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v" +#define ABC_COMMAND_LIB "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v;" +#define ABC_COMMAND_CTR "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v; buffer -v; upsize -v; dnsize -v; stime -p" +#define ABC_COMMAND_LUT "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; if -v" +#define ABC_COMMAND_DFL "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v" #include "kernel/register.h" #include "kernel/sigtools.h" From cd9e8741a71502c303c6f25d02bb2259a7dd7ff3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 13:59:13 +0100 Subject: [PATCH 007/750] Implemented read_verilog -defer --- frontends/ast/ast.cc | 139 +++++++++++++++----------- frontends/ast/ast.h | 2 +- frontends/verilog/verilog_frontend.cc | 12 ++- passes/hierarchy/hierarchy.cc | 26 +++-- 4 files changed, 111 insertions(+), 68 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 96608ae3..ab2972b2 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,61 +770,64 @@ 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_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_dump_ast2) { + log("Dumping verilog AST after simplification:\n"); + ast->dumpAst(NULL, " "); + log("--- END OF AST DUMP ---\n"); } - ast->children.swap(new_children); - ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); - } - ignoreThisSignalsInInitial = RTLIL::SigSpec(); + if (flag_dump_vlog) { + log("Dumping verilog AST (as requested by dump_vlog option):\n"); + ast->dumpVlog(NULL, " "); + log("--- END OF AST DUMP ---\n"); + } - 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(); - } + 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); + } - ignoreThisSignalsInInitial.sort_and_unify(); + ignoreThisSignalsInInitial = RTLIL::SigSpec(); - for (size_t i = 0; i < ast->children.size(); i++) { - AstNode *node = ast->children[i]; - if (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(); + + 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; current_module->nomem2reg = flag_nomem2reg; @@ -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 01702c3c..8335db09 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 c70d6f30..d46dfa6e 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); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 50d0e6e4..526d1729 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -145,6 +145,14 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla if (design->modules.count(cell->type) == 0) { + if (design->modules.count("$abstract" + cell->type)) + { + cell->type = design->modules.at("$abstract" + cell->type)->derive(design, cell->parameters); + cell->parameters.clear(); + did_something = true; + continue; + } + if (cell->type[0] == '$') continue; @@ -210,7 +218,7 @@ static void hierarchy_worker(RTLIL::Design *design, std::set &us } } -static void hierarchy(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib) +static void hierarchy(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib, bool first_pass) { std::set used; hierarchy_worker(design, used, top, 0); @@ -221,6 +229,8 @@ static void hierarchy(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib) del_modules.push_back(it.second); for (auto mod : del_modules) { + if (first_pass && mod->name.substr(0, 9) == "$abstract") + continue; if (!purge_lib && mod->get_bool_attribute("\\blackbox")) continue; log("Removing unused module `%s'.\n", mod->name.c_str()); @@ -362,10 +372,12 @@ struct HierarchyPass : public Pass { if (args[argidx] == "-top") { if (++argidx >= args.size()) log_cmd_error("Option -top requires an additional argument!\n"); - if (args[argidx][0] != '$' && args[argidx][0] != '\\') - top_mod = design->modules.count("\\" + args[argidx]) > 0 ? design->modules["\\" + args[argidx]] : NULL; - else - top_mod = design->modules.count(args[argidx]) > 0 ? design->modules[args[argidx]] : NULL; + top_mod = design->modules.count(RTLIL::escape_id(args[argidx])) ? design->modules.at(RTLIL::escape_id(args[argidx])) : NULL; + if (top_mod == NULL && design->modules.count("$abstract" + RTLIL::escape_id(args[argidx]))) { + std::map empty_parameters; + design->modules.at("$abstract" + RTLIL::escape_id(args[argidx]))->derive(design, empty_parameters); + top_mod = design->modules.count(RTLIL::escape_id(args[argidx])) ? design->modules.at(RTLIL::escape_id(args[argidx])) : NULL; + } if (top_mod == NULL) log_cmd_error("Module `%s' not found!\n", args[argidx].c_str()); continue; @@ -387,7 +399,7 @@ struct HierarchyPass : public Pass { top_mod = mod_it.second; if (top_mod != NULL) - hierarchy(design, top_mod, purge_lib); + hierarchy(design, top_mod, purge_lib, true); bool did_something = true; bool did_something_once = false; @@ -409,7 +421,7 @@ struct HierarchyPass : public Pass { if (top_mod != NULL && did_something_once) { log_header("Re-running hierarchy analysis..\n"); - hierarchy(design, top_mod, purge_lib); + hierarchy(design, top_mod, purge_lib, false); } if (top_mod != NULL) { From a1239416185aebca03d131dc3ebe3e3d45c5a9f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 18:56:36 +0100 Subject: [PATCH 008/750] Updated ABC --- Makefile | 2 +- passes/abc/abc.cc | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 72bd6d1e..89e4a915 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = d7d412483aa9 +ABCREV = 2058c8ccea68 ABCPULL = 1 -include Makefile.conf diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index dae3a22f..eaecb791 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -640,9 +640,32 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std f = popen(buffer.c_str(), "r"); if (f == NULL) log_error("Opening pipe to `%s' for reading failed: %s\n", buffer.c_str(), strerror(errno)); +#if 0 char logbuf[1024]; while (fgets(logbuf, 1024, f) != NULL) log("ABC: %s", logbuf); +#else + bool got_cr = false; + std::string linebuf; + char logbuf[1024]; + while (fgets(logbuf, 1024, f) != NULL) + for (char *p = logbuf; *p; p++) { + if (*p == '\r') { + got_cr = true; + continue; + } + if (*p == '\n') { + log("ABC: %s\n", linebuf.c_str()); + got_cr = false, linebuf.clear(); + continue; + } + if (got_cr) + got_cr = false, linebuf.clear(); + linebuf += *p; + } + if (!linebuf.empty()) + log("ABC: %s\n", linebuf.c_str()); +#endif errno = 0; int ret = pclose(f); if (ret < 0) From de3ea9269a55b653b94651559bebc93e01e28afb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 19:14:15 +0100 Subject: [PATCH 009/750] updated default ABC command strings --- passes/abc/abc.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index eaecb791..4add6452 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -29,10 +29,10 @@ // Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558–562, doi:10.1145/368996.369025 // http://en.wikipedia.org/wiki/Topological_sorting -#define ABC_COMMAND_LIB "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v;" -#define ABC_COMMAND_CTR "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v; buffer -v; upsize -v; dnsize -v; stime -p" -#define ABC_COMMAND_LUT "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; if -v" -#define ABC_COMMAND_DFL "strash; ifraig -v; retime -v; balance -v; scorr -v; dch -vf; map -v" +#define ABC_COMMAND_LIB "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v" +#define ABC_COMMAND_CTR "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v; buffer -v; upsize -v; dnsize -v; stime -p" +#define ABC_COMMAND_LUT "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; if -v" +#define ABC_COMMAND_DFL "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v" #include "kernel/register.h" #include "kernel/sigtools.h" From 3121d19d95ae916b96baa000197f3ec2aa5c5ad7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 11:28:42 +0100 Subject: [PATCH 010/750] Added abc -keepff option --- passes/abc/abc.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 4add6452..bd0d983a 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -109,7 +109,7 @@ static void mark_port(RTLIL::SigSpec sig) } } -static void extract_cell(RTLIL::Cell *cell) +static void extract_cell(RTLIL::Cell *cell, bool keepff) { if (cell->type == "$_DFF_N_" || cell->type == "$_DFF_P_") { @@ -121,6 +121,11 @@ static void extract_cell(RTLIL::Cell *cell) RTLIL::SigSpec sig_d = cell->connections["\\D"]; RTLIL::SigSpec sig_q = cell->connections["\\Q"]; + if (keepff) + for (auto &c : sig_q.chunks) + if (c.wire != NULL) + c.wire->attributes["\\keep"] = 1; + assign_map.apply(sig_d); assign_map.apply(sig_q); @@ -403,7 +408,7 @@ static std::string fold_abc_cmd(std::string str) } static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str) + std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str, bool keepff) { module = current_module; map_autoidx = RTLIL::autoidx++; @@ -498,7 +503,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std if (design->selected(current_module, it.second)) cells.push_back(it.second); for (auto c : cells) - extract_cell(c); + extract_cell(c, keepff); for (auto &wire_it : module->wires) { if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute("\\keep")) @@ -940,6 +945,10 @@ struct AbcPass : public Pass { log(" with -dff, then it falls back to the automatic dection of clock domain\n"); log(" if the specified clock is not found in a module.)\n"); log("\n"); + log(" -keepff\n"); + log(" set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n"); + log(" them, for example for equivialence checking.)\n"); + log("\n"); log(" -nocleanup\n"); log(" when this option is used, the temporary files created by this pass\n"); log(" are not removed. this is useful for debugging.\n"); @@ -960,7 +969,7 @@ struct AbcPass : public Pass { std::string exe_file = rewrite_yosys_exe("yosys-abc"); std::string script_file, liberty_file, constr_file, clk_str; - bool dff_mode = false, cleanup = true; + bool dff_mode = false, keepff = false, cleanup = true; int lut_mode = 0; size_t argidx; @@ -1001,6 +1010,10 @@ struct AbcPass : public Pass { clk_str = args[++argidx]; continue; } + if (arg == "-keepff") { + keepff = true; + continue; + } if (arg == "-nocleanup") { cleanup = false; continue; @@ -1020,7 +1033,7 @@ struct AbcPass : public Pass { if (mod_it.second->processes.size() > 0) log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str()); else - abc_module(design, mod_it.second, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, dff_mode, clk_str); + abc_module(design, mod_it.second, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, dff_mode, clk_str, keepff); } assign_map.clear(); From 534c1a5dd009b41629d2d05acfde747ce6fbc19c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 19:56:44 +0100 Subject: [PATCH 011/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index ab2972b2..7e199cd5 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 8335db09..ec4f4f62 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 591d027c..d92da400 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 b51079ce..85dc1d3c 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); +} + From e8af3def7fbefa1608e72609e1c534091fc7c88e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 20:33:22 +0100 Subject: [PATCH 012/750] 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(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7e199cd5..56e9393b 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 ec4f4f62..f42bc35f 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 85dc1d3c..236843d5 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(); From 45d2b6ffce24c3a4254ef7f80f300cc7840fec25 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 20:45:30 +0100 Subject: [PATCH 013/750] Be more conservative with new const-function code --- frontends/ast/simplify.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 236843d5..2ae3cae0 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 From 4440610d3ffc5426c38e5cf8fccd757203c11a0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 12:57:28 +0100 Subject: [PATCH 014/750] 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 diff --git a/frontends/liberty/Makefile.inc b/frontends/liberty/Makefile.inc new file mode 100644 index 00000000..a02ef5e4 --- /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 00000000..220f32f5 --- /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; + From 67effc9f5bc82b45ff163bfefea53c40d2c8819a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 13:16:08 +0100 Subject: [PATCH 015/750] Fixed opt_const handling of double invert with non-1 output width --- passes/opt/opt_const.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 34d1a69c..f611d721 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -108,7 +108,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons #define ACTION_DO(_p_, _s_) do { replace_cell(module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO_Y(_v_) ACTION_DO("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].width == 1 && invert_map.count(assign_map(cell->connections["\\A"])) != 0) { replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections["\\A"]))); goto next_cell; From 30379ea20d0f07016f24652336e85493bcff2f18 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 15:40:17 +0100 Subject: [PATCH 016/750] Added frontend (-f) option to autotest.sh --- tests/tools/autotest.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 7bccd9a5..0e6c357c 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -6,6 +6,7 @@ use_xsim=false use_modelsim=false verbose=false keeprunning=false +frontend="verilog" backend_opts="-noattr -noexpr" scriptfiles="" scriptopt="" @@ -15,7 +16,7 @@ if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdat ( set -ex; gcc -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1 fi -while getopts xml:wkvrs:p: opt; do +while getopts xml:wkvrf:s:p: opt; do case "$opt" in x) use_xsim=true ;; @@ -31,13 +32,15 @@ while getopts xml:wkvrs:p: opt; do verbose=true ;; r) backend_opts="$backend_opts -norename" ;; + f) + frontend="$OPTARG" ;; s) [[ "$OPTARG" == /* ]] || OPTARG="$PWD/$OPTARG" scriptfiles="$scriptfiles $OPTARG" ;; p) scriptopt="$OPTARG" ;; *) - echo "Usage: $0 [-x|-m] [-w] [-k] [-v] [-r] [-l libs] [-s script] [-p cmdstring] verilog-files\n" >&2 + echo "Usage: $0 [-x|-m] [-w] [-k] [-v] [-r] [-l libs] [-f frontend] [-s script] [-p cmdstring] verilog-files\n" >&2 exit 1 esac done @@ -111,10 +114,10 @@ do if [ -n "$scriptfiles" ]; then test_passes elif [ -n "$scriptopt" ]; then - test_passes -p "$scriptopt" + test_passes -f "$frontend" -p "$scriptopt" else - test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt" - test_passes -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" + test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt" + test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" fi touch ../${bn}.log } From 5e39e6ece28e1145a04e8f00f9ac4f5d9a738acf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 15:42:10 +0100 Subject: [PATCH 017/750] Correctly convert constants to RTLIL (fixed undef handling) --- frontends/ast/genrtlil.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index d92da400..12fe23fd 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 From cdf0f10760d08b8349f392f1cbe41a6ca2b1f49e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 16:34:12 +0100 Subject: [PATCH 018/750] Fixed dfflibmap for cell libraries with no set-reset-ff --- passes/techmap/dfflibmap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 23d93353..fd5fa86e 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -342,7 +342,7 @@ static bool expand_cellmap(std::string pattern, std::string inv) static void map_sr_to_arst(const char *from, const char *to) { - if (cell_mappings.count(to) > 0) + if (!cell_mappings.count(from) || cell_mappings.count(to) > 0) return; char from_clk_pol = from[8], from_set_pol = from[9], from_clr_pol = from[10]; From 96b1ebc8dc337b5412ebce91a7cecb84264b474a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 19:36:09 +0100 Subject: [PATCH 019/750] Bugfix in expression parser of read_liberty --- frontends/liberty/liberty.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 220f32f5..ca899cb9 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); From 118517ca5ae12d2793b1b5d1127f7fe3603d9fed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 19:36:33 +0100 Subject: [PATCH 020/750] Added ff and latch support to read_liberty --- frontends/liberty/liberty.cc | 300 ++++++++++++++++++++++++++++++----- 1 file changed, 257 insertions(+), 43 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index ca899cb9..485d28ee 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; - - 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; + 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))); } - wire->port_output = true; + 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); + } - if (flag_lib) - continue; + if (node->id == "pin" && node->args.size() == 1) + { + LibertyAst *dir = node->find("direction"); - 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 && dir->value == "internal") + continue; - RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); - module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + RTLIL::Wire *wire = module->wires.at(RTLIL::escape_id(node->args.at(0))); - continue; + if (dir && dir->value == "input") { + wire->port_input = true; + continue; + } + + if (dir && dir->value == "output") + wire->port_output = true; + + if (flag_lib) + continue; + + 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)); + + RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); + module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + } } module->fixup_ports(); From 623a68f5283331d96cded03bfd323266c88286f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 21:59:26 +0100 Subject: [PATCH 021/750] Added iopadmap -bits --- passes/techmap/iopadmap.cc | 62 +++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index b9821497..cc678516 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -57,6 +57,11 @@ struct IopadmapPass : public Pass { log(" -nameparam \n"); log(" Use the specified parameter to set the port name.\n"); log("\n"); + log(" -bits\n"); + log(" create individual bit-wide buffers even for ports that\n"); + log(" are wider. (the default behavio is to create word-wide\n"); + log(" buffers use -widthparam to set the word size on the cell.)\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { @@ -66,6 +71,7 @@ struct IopadmapPass : public Pass { std::string outpad_celltype, outpad_portname, outpad_portname2; std::string inoutpad_celltype, inoutpad_portname, inoutpad_portname2; std::string widthparam, nameparam; + bool flag_bits = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -97,6 +103,10 @@ struct IopadmapPass : public Pass { nameparam = args[++argidx]; continue; } + if (arg == "-bits") { + flag_bits = true; + continue; + } break; } extra_args(args, argidx, design); @@ -146,31 +156,55 @@ struct IopadmapPass : public Pass { } else log_abort(); - if (wire->width != 1 && widthparam.empty()) { - log("Don't map multi-bit port %s.%s: Missing option -widthparam.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + if (!flag_bits && wire->width != 1 && widthparam.empty()) { + log("Don't map multi-bit port %s.%s: Missing option -widthparam or -bits.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); continue; } log("Mapping port %s.%s using %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name), celltype.c_str()); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = RTLIL::escape_id(celltype); - cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); + RTLIL::Wire *new_wire = NULL; if (!portname2.empty()) { - RTLIL::Wire *new_wire = new RTLIL::Wire; + new_wire = new RTLIL::Wire; *new_wire = *wire; wire->name = NEW_ID; module->wires[wire->name] = wire; module->wires[new_wire->name] = new_wire; - cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); } - if (!widthparam.empty()) - cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); - if (!nameparam.empty()) - cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name)); - cell->attributes["\\keep"] = RTLIL::Const(1); - module->add(cell); + + if (flag_bits) + { + for (int i = 0; i < wire->width; i++) + { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = RTLIL::escape_id(celltype); + cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, 1, i); + if (!portname2.empty()) + cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, 1, i); + if (!widthparam.empty()) + cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); + if (!nameparam.empty()) + cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", RTLIL::id2cstr(wire->name), i)); + cell->attributes["\\keep"] = RTLIL::Const(1); + module->add(cell); + } + } + else + { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = RTLIL::escape_id(celltype); + cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); + if (!portname2.empty()) + cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); + if (!widthparam.empty()) + cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); + if (!nameparam.empty()) + cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name)); + cell->attributes["\\keep"] = RTLIL::Const(1); + module->add(cell); + } wire->port_id = 0; wire->port_input = false; From 9a816b65a80a7a56b06ac5d0859be73b24008202 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 00:16:54 +0100 Subject: [PATCH 022/750] Added != support for relational select pattern --- passes/cmds/select.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index a1a64f14..3a886b1c 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -63,6 +63,8 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char if (match_op == '=') return value == pattern_value; + if (match_op == '!') + return value != pattern_value; if (match_op == '<') return value.as_int() < pattern_value.as_int(); if (match_op == '>') @@ -82,6 +84,8 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char if (match_op == '=') return value_str == pattern; + if (match_op == '!') + return value_str != pattern; if (match_op == '<') return value_str < pattern; if (match_op == '>') @@ -115,9 +119,11 @@ static bool match_attr(const std::map &attributes static bool match_attr(const std::map &attributes, std::string match_expr) { - size_t pos = match_expr.find_first_of("<=>"); + size_t pos = match_expr.find_first_of(""); if (pos != std::string::npos) { + if (match_expr.substr(pos, 2) == "!=") + return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '!'); if (match_expr.substr(pos, 2) == "<=") return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '['); if (match_expr.substr(pos, 2) == ">=") From c05c3098f1d8a319706ad671607e7d894f33758e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 00:35:53 +0100 Subject: [PATCH 023/750] Tagging Yoys 0.2.0 --- CHANGELOG | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- Makefile | 2 +- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fa2c9b08..ebc4c644 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,43 +3,126 @@ List of incompatible changes and major milestones between releases ================================================================== -Yosys 0.1.0 .. Yoys 0.1.0+ --------------------------- +Yosys 0.1.0 .. Yoys 0.2.0 +------------------------- + + * Changes to the driver program: + - Added "yosys -h" and "yosys -H" + - Added support for backslash line continuation in scripts + - Added support for #-comments in same line as command + - Added "echo" and "log" commands * Improvements in Verilog frontend: - Added support for local registers in named blocks - Added support for "case" in "generate" blocks - Added support for $clog2 system function + - Added support for basic SystemVerilog assert statements - Added preprocessor support for macro arguments - Added preprocessor support for `elsif statement + - Added "verilog_defaults" command + - Added read_verilog -icells option + - Added support for constant sizes from parameters + - Added "read_verilog -setattr" + - Added support for function returning 'integer' + - Added limited support for function calls in parameter values + - Added "read_verilog -defer" to suppress evaluation of modules with default parameters + + * Other front- and back-ends: + - Added BTOR backend + - Added Liberty frontend * Improvements in technology mapping: - The "dfflibmap" command now strongly prefers solutions with no inverters in clock paths - The "dfflibmap" command now prefers cells with smaller area + - Added support for multiple -map options to techmap + - Added "dfflibmap" support for //-comments in liberty files + - Added "memory_unpack" command to revert "memory_collect" + - Added standard techmap rule "techmap -share_map pmux2mux.v" + - Added "iopadmap -bits" + - Added "setundef" command + - Added "hilomap" command + + * Changes in the internal cell library: + - Major rewrite of simlib.v for better compatibility with other tools + - Added PRIORITY parameter to $memwr cells + - Added TRANSPARENT parameter to $memrd cells + - Added RD_TRANSPARENT parameter to $mem cells + - Added $bu0 cell (always 0-extend, even undef MSB) + - Added $assert cell type + - Added $slice and $concat cell types * Integration with ABC: - - Updated ABC to hg rev 57517e81666b + - Updated ABC to hg rev 2058c8ccea68 - Tighter integration of ABC build with Yosys build. The make targets 'make abc' and 'make install-abc' are now obsolete. - Added support for passing FFs from one clock domain through ABC - Now always use BLIF as exchange format with ABC + - Added support for "abc -script +" + - Improved standard ABC recipe + - Added support for "keep" attribute to abc command + - Added "abc -dff / -clk / -keepff" options * Improvements to "eval" and "sat" framework: - Added support for "0" and "~0" in right-hand side -set expressions - Added "eval -set-undef" and "eval -table" - - Added "sat -set-init" support for sequential problems + - Added "sat -set-init" and "sat -set-init-*" for sequential problems - Added undef support to SAT solver, incl. various new "sat" options - Added correct support for === and !== for "eval" and "sat" + - Added "sat -tempinduct" (default -seq is now non-induction sequential) + - Added "sat -prove-asserts" + - Complete rewrite of the 'freduce' command + - Added "miter" command + - Added "sat -show-inputs" and "sat -show-outputs" + - Added "sat -ignore_unknown_cells" (now produce an error by default) + - Added "sat -falsify" + - Now "sat -verify" and "sat -falsify" can also be used without "-prove" + - Added "expose" command + - Added support for @ to sat and eval signal expressions + + * Changes in the 'make test' framework and auxilary test tools: + - Added autotest.sh -p and -f options + - Replaced autotest.sh ISIM support with XSIM support + - Added test cases for SAT framework * Added "abbreviated IDs": - Now $$foo can be abbriviated as $foo. - Usually this last part is a unique id (from RTLIL::autoidx) - This abbreviated IDs are now also used in "show" output + * Other changes to selection framework: + - Now */ is optional in */: expressions + - Added "select -assert-none" and "select -assert-any" + - Added support for matching modules by attribute (A:) + - Added "select -none" + - Added support for r: pattern for matching cell parameters + - Added support for !=, <, <=, >=, > for attribute and parameter matching + - Added support for %s for selecting sub-modules + - Added support for %m for expanding selections to whole modules + - Added support for i:*, o:* and x:* pattern for selecting module ports + - Added support for s: pattern for matching wire width + - Added support for %a operation to select wire aliases + * Various other changes to commands and options: - The "ls" command now supports wildcards - Added "show -pause" and "show -format dot" + - Added "show -color" support for cells + - Added "show -label" and "show -notitle" - Added "dump -m" and "dump -n" - Added "history" command + - Added "rename -hide" + - Added "connect" command + - Added "splitnets -driver" + - Added "opt_const -mux_undef" + - Added "opt_const -mux_bool" + - Added "opt_const -undriven" + - Added "opt -mux_undef -mux_bool -undriven -purge" + - Added "hierarchy -libdir" + - Added "hierarchy -purge_lib" (by default now do not remove lib cells) + - Added "delete" command + - Added "dump -append" + - Added "setattr" and "setparam" commands + - Added "design -stash/-copy-from/-copy-to" + - Added "copy" command + - Added "splice" command diff --git a/Makefile b/Makefile index 89e4a915..94a168a9 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ LDFLAGS = -rdynamic LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt QMAKE = qmake-qt4 -YOSYS_VER := 0.1.0+ +YOSYS_VER := 0.2.0 GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o From b0ae19fa92787436e4c139f42af5f5890f0d4dd8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 00:54:41 +0100 Subject: [PATCH 024/750] Now we are in Yoys 0.2.0+ development --- CHANGELOG | 10 ++++++++-- Makefile | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ebc4c644..c014f458 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,12 @@ -List of incompatible changes and major milestones between releases -================================================================== +List of changes and major improvements between releases +======================================================= + + +Yosys 0.2.0 .. Yoys 0.2.0+ +-------------------------- + + ... TBD ... Yosys 0.1.0 .. Yoys 0.2.0 diff --git a/Makefile b/Makefile index 94a168a9..730a5355 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ LDFLAGS = -rdynamic LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt QMAKE = qmake-qt4 -YOSYS_VER := 0.2.0 +YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o From 7ac524e8e8d1745dec4605c32944e318f46daf4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 13:16:38 +0100 Subject: [PATCH 025/750] Improved support for constant functions --- frontends/ast/simplify.cc | 51 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2ae3cae0..5e37911d 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()); From 9c29969bbc1b19f251011feaa791d242ac8e5e81 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 13:45:47 +0100 Subject: [PATCH 026/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 45 +++++++++++++++++++ manual/PRESENTATION_ExAdv/Makefile | 5 ++- manual/PRESENTATION_ExAdv/red_or3x1_cells.v | 5 +++ manual/PRESENTATION_ExAdv/red_or3x1_map.v | 48 +++++++++++++++++++++ manual/PRESENTATION_ExAdv/red_or3x1_test.v | 5 +++ manual/PRESENTATION_ExAdv/red_or3x1_test.ys | 7 +++ 6 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 manual/PRESENTATION_ExAdv/red_or3x1_cells.v create mode 100644 manual/PRESENTATION_ExAdv/red_or3x1_map.v create mode 100644 manual/PRESENTATION_ExAdv/red_or3x1_test.v create mode 100644 manual/PRESENTATION_ExAdv/red_or3x1_test.ys diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 21c5cdec..3f5743da 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -239,6 +239,51 @@ show -color red @cone_ab -color magenta @cone_a -color blue @cone_b \subsectionpagesuffix \end{frame} +\subsubsection{Introduction to techmap} + +\begin{frame}{\subsubsecname} +\begin{itemize} +\item +The {\tt techmap} command replaces cells in the design with implementations given +as verilog code (called ``map files''). It can replace Yosys' internal cell +types (such as {\tt \$or}) as well as user-defined cell types. +\medskip\item +Verilog parameters are used extensively to customize the internal cell types. +\medskip\item +Additional special parameters are used by techmap to communicate meta-data to the +map files. +\medskip\item +Special wires are used to instruct techmap how to handle a module in the map file. +\medskip\item +Generate blocks and recursion are powerful tools for writing map files. +\end{itemize} +\end{frame} + +\begin{frame}[t]{\subsubsecname -- Example 1/2} +\vskip-0.2cm +To map the Verilog OR-reduction operator to 3-input OR gates: +\vskip-0.2cm +\begin{columns} +\column[t]{0.35\linewidth} +\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=24]{PRESENTATION_ExAdv/red_or3x1_map.v} +\column[t]{0.65\linewidth} +\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=25]{PRESENTATION_ExAdv/red_or3x1_map.v} +\end{columns} +\end{frame} + +\begin{frame}[t]{\subsubsecname -- Example 2/2} +\vbox to 0cm{ +\hfil\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/red_or3x1.pdf} +\vss +} +\begin{columns} +\column[t]{6cm} +\column[t]{4cm} +\vskip-0.6cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, firstline=4, lastline=4, frame=single]{PRESENTATION_ExAdv/red_or3x1_test.ys} +\vskip-0.2cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/red_or3x1_test.v} +\end{columns} +\end{frame} + \subsubsection{TBD} \begin{frame}{\subsubsecname} diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile index f38bd6ce..673b3a21 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/manual/PRESENTATION_ExAdv/Makefile @@ -1,6 +1,9 @@ -all: select_01.pdf +all: select_01.pdf red_or3x1.pdf select_01.pdf: select_01.v select_01.ys ../../yosys select_01.ys +red_or3x1.pdf: red_or3x1_* + ../../yosys red_or3x1_test.ys + diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_cells.v b/manual/PRESENTATION_ExAdv/red_or3x1_cells.v new file mode 100644 index 00000000..0750a130 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/red_or3x1_cells.v @@ -0,0 +1,5 @@ +module OR3X1(A, B, C, Y); + input A, B, C; + output Y; + assign Y = A | B | C; +endmodule diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_map.v b/manual/PRESENTATION_ExAdv/red_or3x1_map.v new file mode 100644 index 00000000..24ca9dab --- /dev/null +++ b/manual/PRESENTATION_ExAdv/red_or3x1_map.v @@ -0,0 +1,48 @@ +module \$reduce_or (A, Y); + + parameter A_SIGNED = 0; + parameter A_WIDTH = 0; + parameter Y_WIDTH = 0; + + input [A_WIDTH-1:0] A; + output [Y_WIDTH-1:0] Y; + + function integer min; + input integer a, b; + begin + if (a < b) + min = a; + else + min = b; + end + endfunction + + genvar i; + generate begin + if (A_WIDTH == 0) begin + assign Y = 0; + end + if (A_WIDTH == 1) begin + assign Y = A; + end + if (A_WIDTH == 2) begin + wire ybuf; + OR3X1 g (.A(A[0]), .B(A[1]), .C(1'b0), .Y(ybuf)); + assign Y = ybuf; + end + if (A_WIDTH == 3) begin + wire ybuf; + OR3X1 g (.A(A[0]), .B(A[1]), .C(A[2]), .Y(ybuf)); + assign Y = ybuf; + end + if (A_WIDTH > 3) begin + localparam next_stage_sz = (A_WIDTH+2) / 3; + wire [next_stage_sz-1:0] next_stage; + for (i = 0; i < next_stage_sz; i = i+1) begin + localparam bits = min(A_WIDTH - 3*i, 3); + assign next_stage[i] = |A[3*i +: bits]; + end + assign Y = |next_stage; + end + end endgenerate +endmodule diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_test.v b/manual/PRESENTATION_ExAdv/red_or3x1_test.v new file mode 100644 index 00000000..bcdd32cb --- /dev/null +++ b/manual/PRESENTATION_ExAdv/red_or3x1_test.v @@ -0,0 +1,5 @@ +module test (A, Y); + input [6:0] A; + output Y; + assign Y = |A; +endmodule diff --git a/manual/PRESENTATION_ExAdv/red_or3x1_test.ys b/manual/PRESENTATION_ExAdv/red_or3x1_test.ys new file mode 100644 index 00000000..b9234603 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/red_or3x1_test.ys @@ -0,0 +1,7 @@ +read_verilog red_or3x1_test.v +hierarchy -check -top test + +techmap -map red_or3x1_map.v;; + +splitnets -ports +show -prefix red_or3x1 -format pdf -notitle -lib red_or3x1_cells.v From aeb36b0b8b499a5b758840998afe9f1b4d7fc166 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 14:32:56 +0100 Subject: [PATCH 027/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 40 +++++++++++++++++++++-- manual/PRESENTATION_ExAdv/Makefile | 5 ++- manual/PRESENTATION_ExAdv/sym_mul_cells.v | 6 ++++ manual/PRESENTATION_ExAdv/sym_mul_map.v | 15 +++++++++ manual/PRESENTATION_ExAdv/sym_mul_test.v | 5 +++ manual/PRESENTATION_ExAdv/sym_mul_test.ys | 6 ++++ 6 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 manual/PRESENTATION_ExAdv/sym_mul_cells.v create mode 100644 manual/PRESENTATION_ExAdv/sym_mul_map.v create mode 100644 manual/PRESENTATION_ExAdv/sym_mul_test.v create mode 100644 manual/PRESENTATION_ExAdv/sym_mul_test.ys diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 3f5743da..4ef10d7a 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -259,7 +259,7 @@ Generate blocks and recursion are powerful tools for writing map files. \end{itemize} \end{frame} -\begin{frame}[t]{\subsubsecname -- Example 1/2} +\begin{frame}[t]{\subsubsecname{} -- Example 1/2} \vskip-0.2cm To map the Verilog OR-reduction operator to 3-input OR gates: \vskip-0.2cm @@ -271,7 +271,7 @@ To map the Verilog OR-reduction operator to 3-input OR gates: \end{columns} \end{frame} -\begin{frame}[t]{\subsubsecname -- Example 2/2} +\begin{frame}[t]{\subsubsecname{} -- Example 2/2} \vbox to 0cm{ \hfil\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/red_or3x1.pdf} \vss @@ -284,6 +284,42 @@ To map the Verilog OR-reduction operator to 3-input OR gates: \end{columns} \end{frame} +\subsubsection{Conditional techmap} + +\begin{frame}{\subsubsecname} +\begin{itemize} +\item In some cases only cells with certain properties should be substituted. +\medskip +\item The special wire {\tt \_TECHMAP\_FAIL\_} can be used to disable a module +in the map file for a certain set of parameters. +\medskip +\item The wire {\tt \_TECHMAP\_FAIL\_} must be set to a constant value. If it +is non-zero then the module is disabled for this set of parameters. +\medskip +\item Example use-cases: +\begin{itemize} +\item coarse-grain cell types that only operate on certain bit widths +\item memory resources for different memory geometries (width, depth, ports, etc.) +\end{itemize} +\end{itemize} +\end{frame} + +\begin{frame}[t]{\subsubsecname{} -- Example} +\vbox to 0cm{ +\vskip-0.5cm +\hfill\includegraphics[width=6cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/sym_mul.pdf} +\vss +} +\vskip-0.5cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/sym_mul_map.v} +\begin{columns} +\column[t]{6cm} +\vskip-0.5cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/sym_mul_test.v} +\column[t]{4cm} +\vskip-0.5cm\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=4]{PRESENTATION_ExAdv/sym_mul_test.ys} +\end{columns} +\end{frame} + \subsubsection{TBD} \begin{frame}{\subsubsecname} diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile index 673b3a21..4ee5886d 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/manual/PRESENTATION_ExAdv/Makefile @@ -1,5 +1,5 @@ -all: select_01.pdf red_or3x1.pdf +all: select_01.pdf red_or3x1.pdf sym_mul.pdf select_01.pdf: select_01.v select_01.ys ../../yosys select_01.ys @@ -7,3 +7,6 @@ select_01.pdf: select_01.v select_01.ys red_or3x1.pdf: red_or3x1_* ../../yosys red_or3x1_test.ys +sym_mul.pdf: sym_mul_* + ../../yosys sym_mul_test.ys + diff --git a/manual/PRESENTATION_ExAdv/sym_mul_cells.v b/manual/PRESENTATION_ExAdv/sym_mul_cells.v new file mode 100644 index 00000000..ce177154 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/sym_mul_cells.v @@ -0,0 +1,6 @@ +module MYMUL(A, B, Y); + parameter WIDTH = 1; + input [WIDTH-1:0] A, B; + output [WIDTH-1:0] Y; + assign Y = A * B; +endmodule diff --git a/manual/PRESENTATION_ExAdv/sym_mul_map.v b/manual/PRESENTATION_ExAdv/sym_mul_map.v new file mode 100644 index 00000000..293c5b84 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/sym_mul_map.v @@ -0,0 +1,15 @@ +module \$mul (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + wire _TECHMAP_FAIL_ = A_WIDTH != B_WIDTH || B_WIDTH != Y_WIDTH; + + MYMUL #( .WIDTH(Y_WIDTH) ) g ( .A(A), .B(B), .Y(Y) ); +endmodule diff --git a/manual/PRESENTATION_ExAdv/sym_mul_test.v b/manual/PRESENTATION_ExAdv/sym_mul_test.v new file mode 100644 index 00000000..eb715f83 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/sym_mul_test.v @@ -0,0 +1,5 @@ +module test(A, B, C, Y1, Y2); + input [7:0] A, B, C; + output [7:0] Y1 = A * B; + output [15:0] Y2 = A * C; +endmodule diff --git a/manual/PRESENTATION_ExAdv/sym_mul_test.ys b/manual/PRESENTATION_ExAdv/sym_mul_test.ys new file mode 100644 index 00000000..0c07e7e8 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/sym_mul_test.ys @@ -0,0 +1,6 @@ +read_verilog sym_mul_test.v +hierarchy -check -top test + +techmap -map sym_mul_map.v;; + +show -prefix sym_mul -format pdf -notitle -lib sym_mul_cells.v From d3dc22a90f8b87ffe0109b0fa2074d887642e7cb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 17:16:44 +0100 Subject: [PATCH 028/750] Added recursion support to techmap --- passes/techmap/techmap.cc | 578 +++++++++++++++++++------------------- 1 file changed, 290 insertions(+), 288 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index eeeebd11..eb044d6f 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -50,317 +50,320 @@ static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module } } -std::map simplemap_mappers; -std::map>, RTLIL::Module*> techmap_cache; -std::map techmap_do_cache; - -struct TechmapWireData { - RTLIL::Wire *wire; - RTLIL::SigSpec value; -}; - -typedef std::map> TechmapWires; - -static TechmapWires techmap_find_special_wires(RTLIL::Module *module) +struct TechmapWorker { - TechmapWires result; + std::map simplemap_mappers; + std::map>, RTLIL::Module*> techmap_cache; + std::map techmap_do_cache; - if (module == NULL) - return result; + struct TechmapWireData { + RTLIL::Wire *wire; + RTLIL::SigSpec value; + }; - for (auto &it : module->wires) { - const char *p = it.first.c_str(); - if (*p == '$') - continue; + typedef std::map> TechmapWires; - const char *q = strrchr(p+1, '.'); - p = q ? q : p+1; - - if (!strncmp(p, "_TECHMAP_", 9)) { - TechmapWireData record; - record.wire = it.second; - record.value = it.second; - result[p].push_back(record); - it.second->attributes["\\keep"] = RTLIL::Const(1); - it.second->attributes["\\_techmap_special_"] = RTLIL::Const(1); - } - } - - if (!result.empty()) { - SigMap sigmap(module); - for (auto &it1 : result) - for (auto &it2 : it1.second) - sigmap.apply(it2.value); - } - - return result; -} - -static void techmap_module_worker(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, bool flatten_mode) -{ - log("Mapping `%s.%s' using `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(tpl->name)); - - if (tpl->memories.size() != 0) - log_error("Technology map yielded memories -> this is not supported.\n"); - - if (tpl->processes.size() != 0) - log_error("Technology map yielded processes -> this is not supported.\n"); - - std::map positional_ports; - - for (auto &it : tpl->wires) { - if (it.second->port_id > 0) - positional_ports[stringf("$%d", it.second->port_id)] = it.first; - RTLIL::Wire *w = new RTLIL::Wire(*it.second); - apply_prefix(cell->name, w->name); - w->port_input = false; - w->port_output = false; - w->port_id = 0; - if (it.second->get_bool_attribute("\\_techmap_special_")) - w->attributes.clear(); - module->wires[w->name] = w; - design->select(module, w); - } - - SigMap port_signal_map; - - for (auto &it : cell->connections) { - RTLIL::IdString portname = it.first; - if (positional_ports.count(portname) > 0) - portname = positional_ports.at(portname); - if (tpl->wires.count(portname) == 0 || tpl->wires.at(portname)->port_id == 0) { - if (portname.substr(0, 1) == "$") - log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str()); - continue; - } - RTLIL::Wire *w = tpl->wires.at(portname); - RTLIL::SigSig c; - if (w->port_output) { - c.first = it.second; - c.second = RTLIL::SigSpec(w); - apply_prefix(cell->name, c.second, module); - } else { - c.first = RTLIL::SigSpec(w); - c.second = it.second; - apply_prefix(cell->name, c.first, module); - } - if (c.second.width > c.first.width) - c.second.remove(c.first.width, c.second.width - c.first.width); - if (c.second.width < c.first.width) - c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.width - c.second.width)); - assert(c.first.width == c.second.width); -#if 0 - // more conservative approach: - // connect internal and external wires - module->connections.push_back(c); -#else - // approach that yields nicer outputs: - // replace internal wires that are connected to external wires - if (w->port_output) - port_signal_map.add(c.second, c.first); - else - port_signal_map.add(c.first, c.second); -#endif - } - - for (auto &it : tpl->cells) { - RTLIL::Cell *c = new RTLIL::Cell(*it.second); - if (!flatten_mode && c->type.substr(0, 2) == "\\$") - c->type = c->type.substr(1); - apply_prefix(cell->name, c->name); - for (auto &it2 : c->connections) { - apply_prefix(cell->name, it2.second, module); - port_signal_map.apply(it2.second); - } - module->cells[c->name] = c; - design->select(module, c); - } - - for (auto &it : tpl->connections) { - RTLIL::SigSig c = it; - apply_prefix(cell->name, c.first, module); - apply_prefix(cell->name, c.second, module); - port_signal_map.apply(c.first); - port_signal_map.apply(c.second); - module->connections.push_back(c); - } - - module->cells.erase(cell->name); - delete cell; -} - -static bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, - const std::map> &celltypeMap, bool flatten_mode) -{ - if (!design->selected(module)) - return false; - - bool log_continue = false; - bool did_something = false; - std::vector cell_names; - - for (auto &cell_it : module->cells) - cell_names.push_back(cell_it.first); - - for (auto &cell_name : cell_names) + TechmapWires techmap_find_special_wires(RTLIL::Module *module) { - if (module->cells.count(cell_name) == 0) - continue; + TechmapWires result; - RTLIL::Cell *cell = module->cells[cell_name]; + if (module == NULL) + return result; - if (!design->selected(module, cell) || handled_cells.count(cell) > 0) - continue; + for (auto &it : module->wires) { + const char *p = it.first.c_str(); + if (*p == '$') + continue; - if (celltypeMap.count(cell->type) == 0) - continue; + const char *q = strrchr(p+1, '.'); + p = q ? q : p+1; - for (auto &tpl_name : celltypeMap.at(cell->type)) - { - std::string derived_name = tpl_name; - RTLIL::Module *tpl = map->modules[tpl_name]; - std::map parameters = cell->parameters; - - if (!flatten_mode) - { - if (tpl->get_bool_attribute("\\techmap_simplemap")) { - log("Mapping %s.%s (%s) with simplemap.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); - if (simplemap_mappers.count(cell->type) == 0) - log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); - simplemap_mappers.at(cell->type)(module, cell); - module->cells.erase(cell->name); - delete cell; - cell = NULL; - did_something = true; - break; - } - - for (auto conn : cell->connections) { - if (conn.first.substr(0, 1) == "$") - continue; - if (tpl->wires.count(conn.first) > 0 && tpl->wires.at(conn.first)->port_id > 0) - continue; - if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0) - goto next_tpl; - parameters[conn.first] = conn.second.as_const(); - } - - if (0) { - next_tpl: - continue; - } - - if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0) - parameters["\\_TECHMAP_CELLTYPE_"] = RTLIL::unescape_id(cell->type); + if (!strncmp(p, "_TECHMAP_", 9)) { + TechmapWireData record; + record.wire = it.second; + record.value = it.second; + result[p].push_back(record); + it.second->attributes["\\keep"] = RTLIL::Const(1); + it.second->attributes["\\_techmap_special_"] = RTLIL::Const(1); } + } - std::pair> key(tpl_name, parameters); - if (techmap_cache.count(key) > 0) { - tpl = techmap_cache[key]; + if (!result.empty()) { + SigMap sigmap(module); + for (auto &it1 : result) + for (auto &it2 : it1.second) + sigmap.apply(it2.value); + } + + return result; + } + + void techmap_module_worker(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, bool flatten_mode) + { + log("Mapping `%s.%s' using `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(tpl->name)); + + if (tpl->memories.size() != 0) + log_error("Technology map yielded memories -> this is not supported.\n"); + + if (tpl->processes.size() != 0) + log_error("Technology map yielded processes -> this is not supported.\n"); + + std::map positional_ports; + + for (auto &it : tpl->wires) { + if (it.second->port_id > 0) + positional_ports[stringf("$%d", it.second->port_id)] = it.first; + RTLIL::Wire *w = new RTLIL::Wire(*it.second); + apply_prefix(cell->name, w->name); + w->port_input = false; + w->port_output = false; + w->port_id = 0; + if (it.second->get_bool_attribute("\\_techmap_special_")) + w->attributes.clear(); + module->wires[w->name] = w; + design->select(module, w); + } + + SigMap port_signal_map; + + for (auto &it : cell->connections) { + RTLIL::IdString portname = it.first; + if (positional_ports.count(portname) > 0) + portname = positional_ports.at(portname); + if (tpl->wires.count(portname) == 0 || tpl->wires.at(portname)->port_id == 0) { + if (portname.substr(0, 1) == "$") + log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str()); + continue; + } + RTLIL::Wire *w = tpl->wires.at(portname); + RTLIL::SigSig c; + if (w->port_output) { + c.first = it.second; + c.second = RTLIL::SigSpec(w); + apply_prefix(cell->name, c.second, module); } else { - if (cell->parameters.size() != 0) { - derived_name = tpl->derive(map, parameters); - tpl = map->modules[derived_name]; - log_continue = true; - } - techmap_cache[key] = tpl; + c.first = RTLIL::SigSpec(w); + c.second = it.second; + apply_prefix(cell->name, c.first, module); } + if (c.second.width > c.first.width) + c.second.remove(c.first.width, c.second.width - c.first.width); + if (c.second.width < c.first.width) + c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.width - c.second.width)); + assert(c.first.width == c.second.width); +#if 0 + // more conservative approach: + // connect internal and external wires + module->connections.push_back(c); +#else + // approach that yields nicer outputs: + // replace internal wires that are connected to external wires + if (w->port_output) + port_signal_map.add(c.second, c.first); + else + port_signal_map.add(c.first, c.second); +#endif + } - if (flatten_mode) - techmap_do_cache[tpl] = true; + for (auto &it : tpl->cells) { + RTLIL::Cell *c = new RTLIL::Cell(*it.second); + if (!flatten_mode && c->type.substr(0, 2) == "\\$") + c->type = c->type.substr(1); + apply_prefix(cell->name, c->name); + for (auto &it2 : c->connections) { + apply_prefix(cell->name, it2.second, module); + port_signal_map.apply(it2.second); + } + module->cells[c->name] = c; + design->select(module, c); + } - if (techmap_do_cache.count(tpl) == 0) + for (auto &it : tpl->connections) { + RTLIL::SigSig c = it; + apply_prefix(cell->name, c.first, module); + apply_prefix(cell->name, c.second, module); + port_signal_map.apply(c.first); + port_signal_map.apply(c.second); + module->connections.push_back(c); + } + + module->cells.erase(cell->name); + delete cell; + } + + bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, + const std::map> &celltypeMap, bool flatten_mode) + { + if (!design->selected(module)) + return false; + + bool log_continue = false; + bool did_something = false; + std::vector cell_names; + + for (auto &cell_it : module->cells) + cell_names.push_back(cell_it.first); + + for (auto &cell_name : cell_names) + { + if (module->cells.count(cell_name) == 0) + continue; + + RTLIL::Cell *cell = module->cells[cell_name]; + + if (!design->selected(module, cell) || handled_cells.count(cell) > 0) + continue; + + if (celltypeMap.count(cell->type) == 0) + continue; + + for (auto &tpl_name : celltypeMap.at(cell->type)) { - bool keep_running = true; - techmap_do_cache[tpl] = true; + std::string derived_name = tpl_name; + RTLIL::Module *tpl = map->modules[tpl_name]; + std::map parameters = cell->parameters; - while (keep_running) + if (!flatten_mode) { - TechmapWires twd = techmap_find_special_wires(tpl); - keep_running = false; + if (tpl->get_bool_attribute("\\techmap_simplemap")) { + log("Mapping %s.%s (%s) with simplemap.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + if (simplemap_mappers.count(cell->type) == 0) + log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); + simplemap_mappers.at(cell->type)(module, cell); + module->cells.erase(cell->name); + delete cell; + cell = NULL; + did_something = true; + break; + } - for (auto &it : twd["_TECHMAP_FAIL_"]) { - RTLIL::SigSpec value = it.value; - if (value.is_fully_const() && value.as_bool()) { - log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n", - derived_name.c_str(), RTLIL::id2cstr(it.wire->name), log_signal(value)); - techmap_do_cache[tpl] = false; + for (auto conn : cell->connections) { + if (conn.first.substr(0, 1) == "$") + continue; + if (tpl->wires.count(conn.first) > 0 && tpl->wires.at(conn.first)->port_id > 0) + continue; + if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0) + goto next_tpl; + parameters[conn.first] = conn.second.as_const(); + } + + if (0) { + next_tpl: + continue; + } + + if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0) + parameters["\\_TECHMAP_CELLTYPE_"] = RTLIL::unescape_id(cell->type); + } + + std::pair> key(tpl_name, parameters); + if (techmap_cache.count(key) > 0) { + tpl = techmap_cache[key]; + } else { + if (cell->parameters.size() != 0) { + derived_name = tpl->derive(map, parameters); + tpl = map->modules[derived_name]; + log_continue = true; + } + techmap_cache[key] = tpl; + } + + if (flatten_mode) + techmap_do_cache[tpl] = true; + + if (techmap_do_cache.count(tpl) == 0) + { + bool keep_running = true; + techmap_do_cache[tpl] = true; + + while (keep_running) + { + TechmapWires twd = techmap_find_special_wires(tpl); + keep_running = false; + + for (auto &it : twd["_TECHMAP_FAIL_"]) { + RTLIL::SigSpec value = it.value; + if (value.is_fully_const() && value.as_bool()) { + log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n", + derived_name.c_str(), RTLIL::id2cstr(it.wire->name), log_signal(value)); + techmap_do_cache[tpl] = false; + } + } + + if (!techmap_do_cache[tpl]) + break; + + for (auto &it : twd) + { + if (it.first.substr(0, 12) != "_TECHMAP_DO_" || it.second.empty()) + continue; + + auto &data = it.second.front(); + + if (!data.value.is_fully_const()) + log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(data.wire->name), log_signal(data.value)); + + tpl->wires.erase(data.wire->name); + const char *p = data.wire->name.c_str(); + const char *q = strrchr(p+1, '.'); + q = q ? q : p+1; + + assert(!strncmp(q, "_TECHMAP_DO_", 12)); + std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12); + while (tpl->wires.count(new_name)) + new_name += "_"; + data.wire->name = new_name; + tpl->add(data.wire); + + std::string cmd_string = data.value.as_const().decode_string(); + + RTLIL::Selection tpl_mod_sel(false); + tpl_mod_sel.select(tpl); + map->selection_stack.push_back(tpl_mod_sel); + Pass::call(map, cmd_string); + map->selection_stack.pop_back(); + + keep_running = true; + break; } } - if (!techmap_do_cache[tpl]) - break; - - for (auto &it : twd) - { - if (it.first.substr(0, 12) != "_TECHMAP_DO_" || it.second.empty()) - continue; - - auto &data = it.second.front(); - - if (!data.value.is_fully_const()) - log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(data.wire->name), log_signal(data.value)); - - tpl->wires.erase(data.wire->name); - const char *p = data.wire->name.c_str(); - const char *q = strrchr(p+1, '.'); - q = q ? q : p+1; - - assert(!strncmp(q, "_TECHMAP_DO_", 12)); - std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12); - while (tpl->wires.count(new_name)) - new_name += "_"; - data.wire->name = new_name; - tpl->add(data.wire); - - std::string cmd_string = data.value.as_const().decode_string(); - - RTLIL::Selection tpl_mod_sel(false); - tpl_mod_sel.select(tpl); - map->selection_stack.push_back(tpl_mod_sel); - Pass::call(map, cmd_string); - map->selection_stack.pop_back(); - - keep_running = true; - break; + TechmapWires twd = techmap_find_special_wires(tpl); + for (auto &it : twd) { + if (it.first != "_TECHMAP_FAIL_" && it.first.substr(0, 12) != "_TECHMAP_DO_" && it.first.substr(0, 14) != "_TECHMAP_DONE_") + log_error("Techmap yielded unknown config wire %s.\n", it.first.c_str()); + if (techmap_do_cache[tpl]) + for (auto &it2 : it.second) + if (!it2.value.is_fully_const()) + log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(it2.wire->name), log_signal(it2.value)); } } - TechmapWires twd = techmap_find_special_wires(tpl); - for (auto &it : twd) { - if (it.first != "_TECHMAP_FAIL_" && it.first.substr(0, 12) != "_TECHMAP_DO_" && it.first.substr(0, 14) != "_TECHMAP_DONE_") - log_error("Techmap yielded unknown config wire %s.\n", it.first.c_str()); - if (techmap_do_cache[tpl]) - for (auto &it2 : it.second) - if (!it2.value.is_fully_const()) - log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(it2.wire->name), log_signal(it2.value)); + if (techmap_do_cache.at(tpl) == false) + continue; + + if (log_continue) { + log_header("Continuing TECHMAP pass.\n"); + log_continue = false; } + + techmap_module_worker(design, module, cell, tpl, flatten_mode); + did_something = true; + cell = NULL; + break; } - if (techmap_do_cache.at(tpl) == false) - continue; - - if (log_continue) { - log_header("Continuing TECHMAP pass.\n"); - log_continue = false; - } - - techmap_module_worker(design, module, cell, tpl, flatten_mode); - did_something = true; - cell = NULL; - break; + handled_cells.insert(cell); } - handled_cells.insert(cell); - } + if (log_continue) { + log_header("Continuing TECHMAP pass.\n"); + log_continue = false; + } - if (log_continue) { - log_header("Continuing TECHMAP pass.\n"); - log_continue = false; + return did_something; } - - return did_something; -} +}; struct TechmapPass : public Pass { TechmapPass() : Pass("techmap", "generic technology mapper") { } @@ -469,7 +472,8 @@ struct TechmapPass : public Pass { } extra_args(args, argidx, design); - simplemap_get_mappers(simplemap_mappers); + TechmapWorker worker; + simplemap_get_mappers(worker.simplemap_mappers); RTLIL::Design *map = new RTLIL::Design; if (map_files.empty()) { @@ -509,17 +513,15 @@ struct TechmapPass : public Pass { while (did_something) { did_something = false; for (auto &mod_it : design->modules) - if (techmap_module(design, mod_it.second, map, handled_cells, celltypeMap, false)) + if (worker.techmap_module(design, mod_it.second, map, handled_cells, celltypeMap, false)) did_something = true; if (did_something) design->check(); } log("No more expansions possible.\n"); - techmap_cache.clear(); - techmap_do_cache.clear(); - simplemap_mappers.clear(); delete map; + log_pop(); } } TechmapPass; @@ -544,6 +546,8 @@ struct FlattenPass : public Pass { extra_args(args, 1, design); + TechmapWorker worker; + std::map> celltypeMap; for (auto &it : design->modules) celltypeMap[it.first].insert(it.first); @@ -559,11 +563,11 @@ struct FlattenPass : public Pass { while (did_something) { did_something = false; if (top_mod != NULL) { - if (techmap_module(design, top_mod, design, handled_cells, celltypeMap, true)) + if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true)) did_something = true; } else { for (auto &mod_it : design->modules) - if (techmap_module(design, mod_it.second, design, handled_cells, celltypeMap, true)) + if (worker.techmap_module(design, mod_it.second, design, handled_cells, celltypeMap, true)) did_something = true; } } @@ -582,8 +586,6 @@ struct FlattenPass : public Pass { design->modules.swap(new_modules); } - techmap_cache.clear(); - techmap_do_cache.clear(); log_pop(); } } FlattenPass; From 42ce3db983fdb512e181daab1817991a661066ff Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 17:39:50 +0100 Subject: [PATCH 029/750] Fixed use of selection in splitnets command --- passes/cmds/splitnets.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index da9ef43f..7e043bcf 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -169,7 +169,7 @@ struct SplitnetsPass : public Pass { { for (auto &w : module->wires) { RTLIL::Wire *wire = w.second; - if (wire->width > 1 && (wire->port_id == 0 || flag_ports)) + if (wire->width > 1 && (wire->port_id == 0 || flag_ports) && design->selected(module, w.second)) worker.splitmap[wire] = std::vector(); } From f08c71b96c325f2432abb4f95fd823ae243e003b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 17:56:19 +0100 Subject: [PATCH 030/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 41 +++++++++++++++++++++++++ manual/PRESENTATION_ExAdv/Makefile | 5 ++- manual/PRESENTATION_ExAdv/mymul_map.v | 15 +++++++++ manual/PRESENTATION_ExAdv/mymul_test.v | 4 +++ manual/PRESENTATION_ExAdv/mymul_test.ys | 15 +++++++++ 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 manual/PRESENTATION_ExAdv/mymul_map.v create mode 100644 manual/PRESENTATION_ExAdv/mymul_test.v create mode 100644 manual/PRESENTATION_ExAdv/mymul_test.ys diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 4ef10d7a..cf36d32c 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -320,6 +320,47 @@ is non-zero then the module is disabled for this set of parameters. \end{columns} \end{frame} +\subsubsection{Scripting in map modules} + +\begin{frame}{\subsubsecname} +\begin{itemize} +\item The special wires {\tt \_TECHMAP\_DO\_*} can be used to run Yosys scripts +in the context of the replacement module. +\medskip +\item The wire that comes first in alphatecial oder is interprated as string (must +be connected to constants) that is executed as script. Then the wire is removed. Repeat. +\medskip +\item You can even call techmap recursively! +\medskip +\item Example use-cases: +\begin{itemize} +\item Using always blocks in map module: call {\tt proc} +\item Perform expensive optimizations (such as {\tt freduce}) on cells where +this is known to work well. +\item Interacting with custom commands. +\end{itemize} +\end{itemize} +\end{frame} + +\begin{frame}[t]{\subsubsecname{} -- Example} +\vbox to 0cm{ +\vskip4.2cm +\hskip0.5cm\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/mymul.pdf} +\vss +} +\vskip-0.6cm +\begin{columns} +\column[t]{6cm} +\vskip-0.6cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/mymul_map.v} +\column[t]{4.2cm} +\vskip-0.6cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/mymul_test.v} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/mymul_test.ys} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, frame=single, language=ys, firstline=7, lastline=12]{PRESENTATION_ExAdv/mymul_test.ys} +\end{columns} +\end{frame} + \subsubsection{TBD} \begin{frame}{\subsubsecname} diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile index 4ee5886d..74f26327 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/manual/PRESENTATION_ExAdv/Makefile @@ -1,5 +1,5 @@ -all: select_01.pdf red_or3x1.pdf sym_mul.pdf +all: select_01.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf select_01.pdf: select_01.v select_01.ys ../../yosys select_01.ys @@ -10,3 +10,6 @@ red_or3x1.pdf: red_or3x1_* sym_mul.pdf: sym_mul_* ../../yosys sym_mul_test.ys +mymul.pdf: mymul_* + ../../yosys mymul_test.ys + diff --git a/manual/PRESENTATION_ExAdv/mymul_map.v b/manual/PRESENTATION_ExAdv/mymul_map.v new file mode 100644 index 00000000..e888a7a7 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/mymul_map.v @@ -0,0 +1,15 @@ +module MYMUL(A, B, Y); + parameter WIDTH = 1; + input [WIDTH-1:0] A, B; + output reg [WIDTH-1:0] Y; + + wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + + integer i; + always @* begin + Y = 0; + for (i = 0; i < WIDTH; i=i+1) + if (A[i]) + Y = Y + (B << i); + end +endmodule diff --git a/manual/PRESENTATION_ExAdv/mymul_test.v b/manual/PRESENTATION_ExAdv/mymul_test.v new file mode 100644 index 00000000..620a06d9 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/mymul_test.v @@ -0,0 +1,4 @@ +module test(A, B, Y); + input [1:0] A, B; + output [1:0] Y = A * B; +endmodule diff --git a/manual/PRESENTATION_ExAdv/mymul_test.ys b/manual/PRESENTATION_ExAdv/mymul_test.ys new file mode 100644 index 00000000..48203e31 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/mymul_test.ys @@ -0,0 +1,15 @@ +read_verilog mymul_test.v +hierarchy -check -top test + +techmap -map sym_mul_map.v \ + -map mymul_map.v;; + +rename test test_mapped +read_verilog mymul_test.v +miter -equiv test test_mapped miter +flatten miter + +sat -verify -prove trigger 0 miter + +splitnets -ports test_mapped/A +show -prefix mymul -format pdf -notitle test_mapped From 7d7e068dd1c5e04cf0c2b9e18abade2b49fe677e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 20:20:25 +0100 Subject: [PATCH 031/750] Added a warning note about error reporting to read_verilog help message --- frontends/verilog/verilog_frontend.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index d46dfa6e..477f26b4 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) { From 28e14ee50a3effcd5335ec06f5b1c2acda008a4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 21:58:27 +0100 Subject: [PATCH 032/750] Fixed handling of "keep" attribute on wires in opt_clean --- passes/opt/opt_clean.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 733a1cbf..d330fb7b 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -227,10 +227,10 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool std::vector del_wires; for (auto &it : module->wires) { RTLIL::Wire *wire = it.second; - if ((!purge_mode && check_public_name(wire->name)) || wire->port_id != 0) { + if ((!purge_mode && check_public_name(wire->name)) || wire->port_id != 0 || wire->get_bool_attribute("\\keep")) { RTLIL::SigSpec s1 = RTLIL::SigSpec(wire), s2 = s1; assign_map.apply(s2); - if (!used_signals.check_any(s2) && wire->port_id == 0) { + if (!used_signals.check_any(s2) && wire->port_id == 0 && !wire->get_bool_attribute("\\keep")) { del_wires.push_back(wire); } else { s1.expand(); From a9b11d7c83a060e59185636711c3ffa4f1c76591 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 21:58:59 +0100 Subject: [PATCH 033/750] Added CONSTMSK and CONSTVAL feature to techmap --- passes/techmap/techmap.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index eb044d6f..da87c3ab 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -201,6 +201,7 @@ struct TechmapWorker bool did_something = false; std::vector cell_names; + SigMap sigmap(module); for (auto &cell_it : module->cells) cell_names.push_back(cell_it.first); @@ -254,6 +255,22 @@ struct TechmapWorker if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0) parameters["\\_TECHMAP_CELLTYPE_"] = RTLIL::unescape_id(cell->type); + + for (auto conn : cell->connections) { + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) { + std::vector v = sigmap(conn.second).to_sigbit_vector(); + for (auto &bit : v) + bit = RTLIL::SigBit(bit.wire == NULL ? RTLIL::State::S1 : RTLIL::State::S0); + parameters[stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))] = RTLIL::SigSpec(v).as_const(); + } + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", RTLIL::id2cstr(conn.first))) != 0) { + std::vector v = sigmap(conn.second).to_sigbit_vector(); + for (auto &bit : v) + if (bit.wire != NULL) + bit = RTLIL::SigBit(RTLIL::State::Sx); + parameters[stringf("\\_TECHMAP_CONSTVAL_%s_", RTLIL::id2cstr(conn.first))] = RTLIL::SigSpec(v).as_const(); + } + } } std::pair> key(tpl_name, parameters); @@ -431,6 +448,12 @@ struct TechmapPass : public Pass { log(" When a parameter with this name exists, it will be set to the type name\n"); log(" of the cell that matches the module.\n"); log("\n"); + log(" _TECHMAP_CONSTMSK__\n"); + log(" _TECHMAP_CONSTVAL__\n"); + log(" When this pair of parameters is available in a module for a port, then\n"); + log(" former has a 1-bit for each constant input bit and the latter has the\n"); + log(" value for this bit. The unused bits of the latter are set to undef (x).\n"); + log("\n"); log("When a module in the map file has a parameter where the according cell in the\n"); log("design has a port, the module from the map file is only used if the port in\n"); log("the design is connected to a constant value. The parameter is then set to the\n"); From 6d63f39eb6abbefd8a12f0fe081c33ef1638800c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 22:18:06 +0100 Subject: [PATCH 034/750] Added some additional checks to techmap --- passes/techmap/techmap.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index da87c3ab..f0d1e6da 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -293,11 +293,16 @@ struct TechmapWorker bool keep_running = true; techmap_do_cache[tpl] = true; + std::set techmap_wire_names; + while (keep_running) { TechmapWires twd = techmap_find_special_wires(tpl); keep_running = false; + for (auto &it : twd) + techmap_wire_names.insert(it.first); + for (auto &it : twd["_TECHMAP_FAIL_"]) { RTLIL::SigSpec value = it.value; if (value.is_fully_const() && value.as_bool()) { @@ -320,7 +325,9 @@ struct TechmapWorker if (!data.value.is_fully_const()) log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(data.wire->name), log_signal(data.value)); + techmap_wire_names.erase(it.first); tpl->wires.erase(data.wire->name); + const char *p = data.wire->name.c_str(); const char *q = strrchr(p+1, '.'); q = q ? q : p+1; @@ -335,10 +342,13 @@ struct TechmapWorker std::string cmd_string = data.value.as_const().decode_string(); RTLIL::Selection tpl_mod_sel(false); + std::string backup_active_module = map->selected_active_module; + map->selected_active_module = tpl->name; tpl_mod_sel.select(tpl); map->selection_stack.push_back(tpl_mod_sel); Pass::call(map, cmd_string); map->selection_stack.pop_back(); + map->selected_active_module = backup_active_module; keep_running = true; break; @@ -353,7 +363,11 @@ struct TechmapWorker for (auto &it2 : it.second) if (!it2.value.is_fully_const()) log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(it2.wire->name), log_signal(it2.value)); + techmap_wire_names.erase(it.first); } + + for (auto &it : techmap_wire_names) + log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", RTLIL::id2cstr(it)); } if (techmap_do_cache.at(tpl) == false) From 37cbb1ca60b03cbaaef5041db5f631b90a303f9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 22:31:53 +0100 Subject: [PATCH 035/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 38 ++++++++++++++++++++++ manual/PRESENTATION_ExAdv/Makefile | 5 ++- manual/PRESENTATION_ExAdv/mulshift_map.v | 26 +++++++++++++++ manual/PRESENTATION_ExAdv/mulshift_test.v | 5 +++ manual/PRESENTATION_ExAdv/mulshift_test.ys | 7 ++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 manual/PRESENTATION_ExAdv/mulshift_map.v create mode 100644 manual/PRESENTATION_ExAdv/mulshift_test.v create mode 100644 manual/PRESENTATION_ExAdv/mulshift_test.ys diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index cf36d32c..483389d8 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -361,6 +361,44 @@ this is known to work well. \end{columns} \end{frame} +\subsubsection{Handling constant inputs} + +\begin{frame}{\subsubsecname} +\begin{itemize} +\item The special parameters {\tt \_TECHMAP\_CONSTMSK\_\it \tt \_} and +{\tt \_TECHMAP\_CONSTVAL\_\it \tt \_} can be used to handle constant +input values to cells. +\medskip +\item The former contains 1-bits for all constant input bits on the port. +\medskip +\item The latter contains the constant bits or undef (x) for non-constant bits. +\medskip +\item Example use-cases: +\begin{itemize} +\item Converting arithmetic (for example multiply to shift) +\item Identify constant addresses or enable bits in memory interfaces. +\end{itemize} +\end{itemize} +\end{frame} + +\begin{frame}[t]{\subsubsecname{} -- Example} +\vbox to 0cm{ +\vskip5.2cm +\hskip6.5cm\includegraphics[width=5cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/mulshift.pdf} +\vss +} +\vskip-0.6cm +\begin{columns} +\column[t]{6cm} +\vskip-0.4cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/mulshift_map.v} +\column[t]{4.2cm} +\vskip-0.6cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/mulshift_test.v} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/mulshift_test.ys} +\end{columns} +\end{frame} + \subsubsection{TBD} \begin{frame}{\subsubsecname} diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile index 74f26327..3bbc239a 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/manual/PRESENTATION_ExAdv/Makefile @@ -1,5 +1,5 @@ -all: select_01.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf +all: select_01.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf select_01.pdf: select_01.v select_01.ys ../../yosys select_01.ys @@ -13,3 +13,6 @@ sym_mul.pdf: sym_mul_* mymul.pdf: mymul_* ../../yosys mymul_test.ys +mulshift.pdf: mulshift_* + ../../yosys mulshift_test.ys + diff --git a/manual/PRESENTATION_ExAdv/mulshift_map.v b/manual/PRESENTATION_ExAdv/mulshift_map.v new file mode 100644 index 00000000..4a3c2a06 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/mulshift_map.v @@ -0,0 +1,26 @@ +module MYMUL(A, B, Y); + parameter WIDTH = 1; + input [WIDTH-1:0] A, B; + output reg [WIDTH-1:0] Y; + + parameter _TECHMAP_CONSTVAL_A_ = WIDTH'bx; + parameter _TECHMAP_CONSTVAL_B_ = WIDTH'bx; + + reg _TECHMAP_FAIL_; + wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + + integer i; + always @* begin + _TECHMAP_FAIL_ <= 1; + for (i = 0; i < WIDTH; i=i+1) begin + if (_TECHMAP_CONSTVAL_A_ === WIDTH'd1 << i) begin + _TECHMAP_FAIL_ <= 0; + Y <= B << i; + end + if (_TECHMAP_CONSTVAL_B_ === WIDTH'd1 << i) begin + _TECHMAP_FAIL_ <= 0; + Y <= A << i; + end + end + end +endmodule diff --git a/manual/PRESENTATION_ExAdv/mulshift_test.v b/manual/PRESENTATION_ExAdv/mulshift_test.v new file mode 100644 index 00000000..4b975f41 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/mulshift_test.v @@ -0,0 +1,5 @@ +module test (A, X, Y); +input [7:0] A; +output [7:0] X = A * 8'd 6; +output [7:0] Y = A * 8'd 8; +endmodule diff --git a/manual/PRESENTATION_ExAdv/mulshift_test.ys b/manual/PRESENTATION_ExAdv/mulshift_test.ys new file mode 100644 index 00000000..c5dac49e --- /dev/null +++ b/manual/PRESENTATION_ExAdv/mulshift_test.ys @@ -0,0 +1,7 @@ +read_verilog mulshift_test.v +hierarchy -check -top test + +techmap -map sym_mul_map.v \ + -map mulshift_map.v;; + +show -prefix mulshift -format pdf -notitle -lib sym_mul_cells.v From ca53ef50982d84917a4f6d293dd0d07805bb8eb6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 09:44:39 +0100 Subject: [PATCH 036/750] Better preserve wires when flattening (in comparison to techmap) --- passes/techmap/techmap.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index f0d1e6da..53164b58 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -151,18 +151,18 @@ struct TechmapWorker if (c.second.width < c.first.width) c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.width - c.second.width)); assert(c.first.width == c.second.width); -#if 0 - // more conservative approach: - // connect internal and external wires - module->connections.push_back(c); -#else - // approach that yields nicer outputs: - // replace internal wires that are connected to external wires - if (w->port_output) - port_signal_map.add(c.second, c.first); - else - port_signal_map.add(c.first, c.second); -#endif + if (flatten_mode) { + // more conservative approach: + // connect internal and external wires + module->connections.push_back(c); + } else { + // approach that yields nicer outputs: + // replace internal wires that are connected to external wires + if (w->port_output) + port_signal_map.add(c.second, c.first); + else + port_signal_map.add(c.first, c.second); + } } for (auto &it : tpl->cells) { From 0fbc1a59dd617aa3e9e9219180b8df0a37447300 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 09:45:04 +0100 Subject: [PATCH 037/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 40 +++++++++++++++++++++++++++++------ manual/PRESENTATION_ExSyn.tex | 2 +- manual/PRESENTATION_Intro.tex | 4 ++-- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 483389d8..80210b96 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -87,7 +87,7 @@ cd .. # switch back to design \end{lstlisting} \bigskip -Note: Most synthesis script never switch to module context. But it is a very powerful +Note: Most synthesis scripts never switch to module context. But it is a very powerful tool for interactive design investigation. \end{frame} @@ -101,7 +101,7 @@ Special pattern can be used to select by object property or type. For example: select w:reg_* # select all wires whose names start with reg_ select a:foobar # select all objects with the attribute foobar set select a:foobar=42 # select all objects with the attribute foobar set to 42 -select A:blabla # select all module with the attribute blabla set +select A:blabla # select all modules with the attribute blabla set select foo/t:$add # select all $add cells from the module foo \end{lstlisting} @@ -114,7 +114,7 @@ reference to the {\tt select} command. \begin{frame}[fragile]{\subsubsecname} When more than one selection expression is used in one statement they are -pushed on a stack. At the final elements on the stack are combined into a union: +pushed on a stack. The final elements on the stack are combined into a union: \medskip \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] @@ -170,7 +170,7 @@ See {\tt help select} for full documentation of this expressions. \begin{frame}[fragile]{\subsubsecname} Sometime a selection can most easily described by a series of add/delete operations. -For the commands {\tt select -add} and {\tt select -del} add or remove objects +The commands {\tt select -add} and {\tt select -del} respectively add or remove objects from the current selection instead of overwriting it. \medskip @@ -327,7 +327,7 @@ is non-zero then the module is disabled for this set of parameters. \item The special wires {\tt \_TECHMAP\_DO\_*} can be used to run Yosys scripts in the context of the replacement module. \medskip -\item The wire that comes first in alphatecial oder is interprated as string (must +\item The wire that comes first in alphabetical oder is interpreted as string (must be connected to constants) that is executed as script. Then the wire is removed. Repeat. \medskip \item You can even call techmap recursively! @@ -340,6 +340,10 @@ this is known to work well. \item Interacting with custom commands. \end{itemize} \end{itemize} + +\scriptsize +PROTIP: Commands such as {\tt shell}, {\tt show -pause}, and {\tt dump} can be use +in the {\tt \_TECHMAP\_DO\_*} scripts for debugging map modules. \end{frame} \begin{frame}[t]{\subsubsecname{} -- Example} @@ -399,12 +403,36 @@ input values to cells. \end{columns} \end{frame} -\subsubsection{TBD} +\subsubsection{Handling shorted inputs} \begin{frame}{\subsubsecname} TBD \end{frame} +\subsubsection{Notes on using techmap} + +\begin{frame}{\subsubsecname} +\begin{itemize} +\item Don't use positional cell parameters in map modules. +\medskip +\item Don't try to implement basic logic optimization with techmap. \\ +{\small (So the OR-reduce using OR3X1 cells map was actually a bad example.)} +\medskip +\item You can use the {\tt \$\_\,\_}-prefix for internal cell types to avoid +collisions with the user-namespace. But always use two underscores or the +internal consistency checker will trigger on this cells. +\medskip +\item Techmap has two major use cases: +\begin{itemize} +\item Creating good logic-level representation of arithmetic functions. \\ +This also means using dedicated hardware resources such as half- and full-adder +cells in ASICS or dedicated carry logic in FPGAs. +\smallskip +\item Mapping of coarse-grain resources such as block memory or DSP cells. +\end{itemize} +\end{itemize} +\end{frame} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Coarse-grain synthesis} diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex index 35d0b8a7..432ce368 100644 --- a/manual/PRESENTATION_ExSyn.tex +++ b/manual/PRESENTATION_ExSyn.tex @@ -223,7 +223,7 @@ The designs in {\tt yosys-bigsim} are a good playground for experimenting with the effects of calling {\tt opt} in various places of the flow. \bigskip -It generally is a good idea us call {\tt opt} before inherently expensive +It generally is a good idea to call {\tt opt} before inherently expensive commands such as {\tt sat} or {\tt freduce}, as the possible gain is much higher in this cases as the possible loss. diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 312cb898..27576647 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -326,7 +326,7 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des Read Verilog source file and convert to internal representation. }% \only<2>{ - Elaborate the design hierarchy. Should alsways be the first + Elaborate the design hierarchy. Should always be the first command after reading the design. }% \only<3>{ @@ -794,7 +794,7 @@ We need you as a developer: \begin{frame}{\subsecname} \begin{itemize} \item Yosys is a powerful tool and framework for Verilog synthesis. -\item Is uses a command-based interface and can be controlled by scripts. +\item It uses a command-based interface and can be controlled by scripts. \item By combining existing commands and implementing new commands Yosys can be used in a wide range of application far beyond simple synthesis. \end{itemize} From 4a948d780a6dd7de73b4dd05aecabe3a12863f3f Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 17 Feb 2014 06:06:04 -0500 Subject: [PATCH 038/750] Added "-dump_fail_to_vcd" argument to SAT solver --- passes/sat/sat.cc | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index c0827159..1cf4f084 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -30,6 +30,8 @@ #include #include #include +#include +#include namespace { @@ -630,6 +632,109 @@ struct SatHelper if (last_timestep == -2) log(" no model variables selected for display.\n"); } + + void dump_model_to_vcd(std::string vcd_file_name) + { + FILE* f = fopen(vcd_file_name.c_str(), "w"); + if(!f) + log_cmd_error("Can't open output file `%s' for writing: %s\n", vcd_file_name.c_str(), strerror(errno)); + + log("Dumping SAT model to VCD file %s\n", vcd_file_name.c_str()); + + time_t timestamp; + struct tm* now; + char stime[128] = {0}; + time(×tamp); + now = localtime(×tamp); + strftime(stime, sizeof(stime), "%c", now); + + std::string module_fname = "unknown"; + auto apos = module->attributes.find("\\src"); + if(apos != module->attributes.end()) + module_fname = module->attributes["\\src"].decode_string(); + + fprintf(f, "$date\n"); + fprintf(f, " %s\n", stime); + fprintf(f, "$end\n"); + fprintf(f, "$version\n"); + fprintf(f, " Generated by %s\n", yosys_version_str); + fprintf(f, "$end\n"); + fprintf(f, "$comment\n"); + fprintf(f, " Generated from SAT problem in module %s (declared at %s)\n", + module->name.c_str(), module_fname.c_str()); + fprintf(f, "$end\n"); + + //VCD has some limits on internal (non-display) identifier names, so make legal ones + std::map vcdnames; + + fprintf(f, "$timescale 1ns\n"); //arbitrary time scale since actual clock period is unknown/unimportant + fprintf(f, "$scope module %s $end\n", module->name.c_str()); + for (auto &info : modelInfo) { + if(vcdnames.find(info.description) != vcdnames.end()) + continue; + + char namebuf[16]; + snprintf(namebuf, sizeof(namebuf), "v%d", static_cast(vcdnames.size())); + vcdnames[info.description] = namebuf; + + //Even display identifiers can't use some special characters + std::string legal_desc = info.description.c_str(); + for (auto &c : legal_desc) { + if(c == '$') + c = '_'; + if(c == ':') + c = '_'; + } + + fprintf(f, "$var wire %d %s %s $end\n", info.width, namebuf, legal_desc.c_str()); + + //Need to look at first *two* cycles! + //We need to put a name on all variables but those without an initialization clause + //have no value at timestep 0 + if(info.timestep > 1) + break; + } + fprintf(f, "$upscope $end\n"); + fprintf(f, "$enddefinitions $end\n"); + fprintf(f, "$dumpvars\n"); + + static const char bitvals[] = "01xzxx"; + + int last_timestep = -2; + for (auto &info : modelInfo) + { + RTLIL::Const value; + + for (int i = 0; i < info.width; i++) { + value.bits.push_back(modelValues.at(info.offset+i) ? RTLIL::State::S1 : RTLIL::State::S0); + if (enable_undef && modelValues.at(modelExpressions.size()/2 + info.offset + i)) + value.bits.back() = RTLIL::State::Sx; + } + + if (info.timestep != last_timestep) { + if(last_timestep == 0) + fprintf(f, "$end\n"); + else + fprintf(f, "#%d\n", info.timestep); + + last_timestep = info.timestep; + } + + if(info.width == 1) + fprintf(f, "%c%s\n", bitvals[value.bits[0]], vcdnames[info.description].c_str()); + else { + fprintf(f, "b"); + for(int k=info.width-1; k >= 0; k --) //need to flip bit ordering for VCD + fprintf(f, "%c", bitvals[value.bits[k]]); + fprintf(f, " %s\n", vcdnames[info.description].c_str()); + } + } + + if (last_timestep == -2) + log(" no model variables selected for display.\n"); + + fclose(f); + } void invalidate_model(bool max_undef) { @@ -822,6 +927,8 @@ struct SatPass : public Pass { bool ignore_div_by_zero = false, set_init_undef = false, set_init_zero = false, max_undef = false; bool tempinduct = false, prove_asserts = false, show_inputs = false, show_outputs = false; bool ignore_unknown_cells = false, falsify = false, tempinduct_def = false, set_init_def = false; + bool dump_fail_to_vcd = false; + std::string vcd_file_name = ""; log_header("Executing SAT pass (solving SAT problems in the circuit).\n"); @@ -995,6 +1102,11 @@ struct SatPass : public Pass { ignore_unknown_cells = true; continue; } + if (args[argidx] == "-dump_fail_to_vcd" && argidx+1 < args.size()) { + dump_fail_to_vcd = true; + vcd_file_name = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -1107,6 +1219,8 @@ struct SatPass : public Pass { log("SAT temporal induction proof finished - model found for base case: FAIL!\n"); print_proof_failed(); basecase.print_model(); + if(dump_fail_to_vcd) + basecase.dump_model_to_vcd(vcd_file_name); goto tip_failed; } From 0851c2b6ea7044d9bce2014a2be2365a2bf7e1b0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 13:57:14 +0100 Subject: [PATCH 039/750] Renamed "sat -dump_fail_to_vcd" to "sat -dump_vcd" and some minor cleanups --- passes/sat/sat.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 1cf4f084..2cd15d01 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -875,6 +875,9 @@ struct SatPass : public Pass { log(" -set-init-zero\n"); log(" set all initial states (not set using -set-init) to zero\n"); log("\n"); + log(" -dump_vcd \n"); + log(" dump SAT model (counter example in proof) to VCD file\n"); + log("\n"); log("The following additional options can be used to set up a proof. If also -seq\n"); log("is passed, a temporal induction proof is performed.\n"); log("\n"); @@ -927,8 +930,7 @@ struct SatPass : public Pass { bool ignore_div_by_zero = false, set_init_undef = false, set_init_zero = false, max_undef = false; bool tempinduct = false, prove_asserts = false, show_inputs = false, show_outputs = false; bool ignore_unknown_cells = false, falsify = false, tempinduct_def = false, set_init_def = false; - bool dump_fail_to_vcd = false; - std::string vcd_file_name = ""; + std::string vcd_file_name; log_header("Executing SAT pass (solving SAT problems in the circuit).\n"); @@ -1102,8 +1104,7 @@ struct SatPass : public Pass { ignore_unknown_cells = true; continue; } - if (args[argidx] == "-dump_fail_to_vcd" && argidx+1 < args.size()) { - dump_fail_to_vcd = true; + if (args[argidx] == "-dump_vcd" && argidx+1 < args.size()) { vcd_file_name = args[++argidx]; continue; } @@ -1219,7 +1220,7 @@ struct SatPass : public Pass { log("SAT temporal induction proof finished - model found for base case: FAIL!\n"); print_proof_failed(); basecase.print_model(); - if(dump_fail_to_vcd) + if(!vcd_file_name.empty()) basecase.dump_model_to_vcd(vcd_file_name); goto tip_failed; } @@ -1344,6 +1345,9 @@ struct SatPass : public Pass { sathelper.print_model(); + if(!vcd_file_name.empty()) + sathelper.dump_model_to_vcd(vcd_file_name); + if (loopcount != 0) { loopcount--, rerun_counter++; sathelper.invalidate_model(max_undef); From 02e6f2c5be8c5514cc8cdb7b3344f6170fb87af9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 14:28:52 +0100 Subject: [PATCH 040/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 56e9393b..58be0679 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 f42bc35f..72a2a460 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 12fe23fd..bc3783bd 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 81167cf4..79f44b4a 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 8080729b..4726f1aa 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 db53e8c6..873ae3d5 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 477f26b4..13c2676d 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 8b4fae6e..99b2164e 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 From 13051e6acf6c1fd506a49d258c3d99c1334c78cc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:03:16 +0100 Subject: [PATCH 041/750] Added "sat -initsteps" --- passes/sat/sat.cc | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 2cd15d01..2dc7a16b 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -903,6 +903,9 @@ struct SatPass : public Pass { log(" -maxsteps \n"); log(" Set a maximum length for the induction.\n"); log("\n"); + log(" -initsteps \n"); + log(" Set initial length for the induction.\n"); + log("\n"); log(" -timeout \n"); log(" Maximum number of seconds a single SAT instance may take.\n"); log("\n"); @@ -925,7 +928,7 @@ struct SatPass : public Pass { std::map>> sets_at; std::map> unsets_at, sets_def_at, sets_any_undef_at, sets_all_undef_at; std::vector shows, sets_def, sets_any_undef, sets_all_undef; - int loopcount = 0, seq_len = 0, maxsteps = 0, timeout = 0; + int loopcount = 0, seq_len = 0, maxsteps = 0, initsteps = 0, timeout = 0; bool verify = false, fail_on_timeout = false, enable_undef = false, set_def_inputs = false; bool ignore_div_by_zero = false, set_init_undef = false, set_init_zero = false, max_undef = false; bool tempinduct = false, prove_asserts = false, show_inputs = false, show_outputs = false; @@ -970,6 +973,10 @@ struct SatPass : public Pass { maxsteps = atoi(args[++argidx].c_str()); continue; } + if (args[argidx] == "-initsteps" && argidx+1 < args.size()) { + initsteps = atoi(args[++argidx].c_str()); + continue; + } if (args[argidx] == "-ignore_div_by_zero") { ignore_div_by_zero = true; continue; @@ -1240,21 +1247,29 @@ struct SatPass : public Pass { if (inductlen > 1) inductstep.force_unique_state(1, inductlen + 1); - log("\n[induction step] Solving problem with %d variables and %d clauses..\n", - inductstep.ez.numCnfVariables(), inductstep.ez.numCnfClauses()); - - if (!inductstep.solve(inductstep.ez.NOT(property))) { - if (inductstep.gotTimeout) - goto timeout; - log("Induction step proven: SUCCESS!\n"); - print_qed(); - goto tip_success; + if (inductlen < initsteps) + { + log("\n[induction step] Skipping problem with %d variables and %d clauses (below initsteps).\n", + inductstep.ez.numCnfVariables(), inductstep.ez.numCnfClauses()); + inductstep.ez.assume(property); } + else + { + log("\n[induction step] Solving problem with %d variables and %d clauses..\n", + inductstep.ez.numCnfVariables(), inductstep.ez.numCnfClauses()); - log("Induction step failed. Incrementing induction length.\n"); - inductstep.ez.assume(property); + if (!inductstep.solve(inductstep.ez.NOT(property))) { + if (inductstep.gotTimeout) + goto timeout; + log("Induction step proven: SUCCESS!\n"); + print_qed(); + goto tip_success; + } - inductstep.print_model(); + log("Induction step failed. Incrementing induction length.\n"); + inductstep.ez.assume(property); + inductstep.print_model(); + } } log("\nReached maximum number of time steps -> proof failed.\n"); From 61a2bf57b43eff81f177f1280574dff22885ad86 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:25:41 +0100 Subject: [PATCH 042/750] Improved non-verbose ezSAT::printDIMACS() format --- libs/ezsat/ezsat.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index dccc0055..57762525 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -1131,10 +1131,15 @@ void ezSAT::printDIMACS(FILE *f, bool verbose) const int maxClauseLen = 0; for (auto &clause : cnfClauses) maxClauseLen = std::max(int(clause.size()), maxClauseLen); + if (!verbose) + maxClauseLen = std::min(maxClauseLen, 3); for (auto &clause : cnfClauses) { for (auto idx : clause) fprintf(f, " %*d", digits, idx); - fprintf(f, " %*d\n", (digits + 1)*int(maxClauseLen - clause.size()) + digits, 0); + if (maxClauseLen >= int(clause.size())) + fprintf(f, " %*d\n", (digits + 1)*int(maxClauseLen - clause.size()) + digits, 0); + else + fprintf(f, " %*d\n", digits, 0); } } From 32af10fa9b0fb8c86451a15f780288da13d4ab99 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:28:05 +0100 Subject: [PATCH 043/750] Coding style corrections in SatHelper::dump_model_to_vcd() --- passes/sat/sat.cc | 62 +++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 2dc7a16b..3b4a394e 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -632,27 +632,27 @@ struct SatHelper if (last_timestep == -2) log(" no model variables selected for display.\n"); } - + void dump_model_to_vcd(std::string vcd_file_name) { - FILE* f = fopen(vcd_file_name.c_str(), "w"); - if(!f) + FILE *f = fopen(vcd_file_name.c_str(), "w"); + if (!f) log_cmd_error("Can't open output file `%s' for writing: %s\n", vcd_file_name.c_str(), strerror(errno)); - + log("Dumping SAT model to VCD file %s\n", vcd_file_name.c_str()); - + time_t timestamp; struct tm* now; - char stime[128] = {0}; + char stime[128] = {}; time(×tamp); now = localtime(×tamp); strftime(stime, sizeof(stime), "%c", now); - + std::string module_fname = "unknown"; auto apos = module->attributes.find("\\src"); if(apos != module->attributes.end()) module_fname = module->attributes["\\src"].decode_string(); - + fprintf(f, "$date\n"); fprintf(f, " %s\n", stime); fprintf(f, "$end\n"); @@ -663,21 +663,22 @@ struct SatHelper fprintf(f, " Generated from SAT problem in module %s (declared at %s)\n", module->name.c_str(), module_fname.c_str()); fprintf(f, "$end\n"); - - //VCD has some limits on internal (non-display) identifier names, so make legal ones + + // VCD has some limits on internal (non-display) identifier names, so make legal ones std::map vcdnames; - - fprintf(f, "$timescale 1ns\n"); //arbitrary time scale since actual clock period is unknown/unimportant + + fprintf(f, "$timescale 1ns\n"); // arbitrary time scale since actual clock period is unknown/unimportant fprintf(f, "$scope module %s $end\n", module->name.c_str()); - for (auto &info : modelInfo) { - if(vcdnames.find(info.description) != vcdnames.end()) + for (auto &info : modelInfo) + { + if (vcdnames.find(info.description) != vcdnames.end()) continue; - + char namebuf[16]; snprintf(namebuf, sizeof(namebuf), "v%d", static_cast(vcdnames.size())); vcdnames[info.description] = namebuf; - - //Even display identifiers can't use some special characters + + // Even display identifiers can't use some special characters std::string legal_desc = info.description.c_str(); for (auto &c : legal_desc) { if(c == '$') @@ -685,21 +686,21 @@ struct SatHelper if(c == ':') c = '_'; } - + fprintf(f, "$var wire %d %s %s $end\n", info.width, namebuf, legal_desc.c_str()); - - //Need to look at first *two* cycles! - //We need to put a name on all variables but those without an initialization clause - //have no value at timestep 0 + + // Need to look at first *two* cycles! + // We need to put a name on all variables but those without an initialization clause + // have no value at timestep 0 if(info.timestep > 1) break; } fprintf(f, "$upscope $end\n"); fprintf(f, "$enddefinitions $end\n"); fprintf(f, "$dumpvars\n"); - + static const char bitvals[] = "01xzxx"; - + int last_timestep = -2; for (auto &info : modelInfo) { @@ -710,19 +711,18 @@ struct SatHelper if (enable_undef && modelValues.at(modelExpressions.size()/2 + info.offset + i)) value.bits.back() = RTLIL::State::Sx; } - - if (info.timestep != last_timestep) { + + if (info.timestep != last_timestep) { if(last_timestep == 0) fprintf(f, "$end\n"); else fprintf(f, "#%d\n", info.timestep); - last_timestep = info.timestep; } - - if(info.width == 1) + + if(info.width == 1) { fprintf(f, "%c%s\n", bitvals[value.bits[0]], vcdnames[info.description].c_str()); - else { + } else { fprintf(f, "b"); for(int k=info.width-1; k >= 0; k --) //need to flip bit ordering for VCD fprintf(f, "%c", bitvals[value.bits[k]]); @@ -732,7 +732,7 @@ struct SatHelper if (last_timestep == -2) log(" no model variables selected for display.\n"); - + fclose(f); } From a78bba1f5cf5b8c312c453e5c2c1a57b6946bebd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:29:08 +0100 Subject: [PATCH 044/750] Added "sat -dump_cnf" --- passes/sat/sat.cc | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 3b4a394e..d18a220d 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -878,6 +878,10 @@ struct SatPass : public Pass { log(" -dump_vcd \n"); log(" dump SAT model (counter example in proof) to VCD file\n"); log("\n"); + log(" -dump_cnf \n"); + log(" dump CNF of SAT problem (in DIMACS format). in temporal induction\n"); + log(" proofs this is the CNF of the first induction step.\n"); + log("\n"); log("The following additional options can be used to set up a proof. If also -seq\n"); log("is passed, a temporal induction proof is performed.\n"); log("\n"); @@ -933,7 +937,7 @@ struct SatPass : public Pass { bool ignore_div_by_zero = false, set_init_undef = false, set_init_zero = false, max_undef = false; bool tempinduct = false, prove_asserts = false, show_inputs = false, show_outputs = false; bool ignore_unknown_cells = false, falsify = false, tempinduct_def = false, set_init_def = false; - std::string vcd_file_name; + std::string vcd_file_name, cnf_file_name; log_header("Executing SAT pass (solving SAT problems in the circuit).\n"); @@ -1115,6 +1119,10 @@ struct SatPass : public Pass { vcd_file_name = args[++argidx]; continue; } + if (args[argidx] == "-dump_cnf" && argidx+1 < args.size()) { + cnf_file_name = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); @@ -1255,6 +1263,19 @@ struct SatPass : public Pass { } else { + if (!cnf_file_name.empty()) + { + FILE *f = fopen(cnf_file_name.c_str(), "w"); + if (!f) + log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno)); + + log("Dumping CNF to file `%s'.\n", cnf_file_name.c_str()); + cnf_file_name.clear(); + + inductstep.ez.printDIMACS(f, false); + fclose(f); + } + log("\n[induction step] Solving problem with %d variables and %d clauses..\n", inductstep.ez.numCnfVariables(), inductstep.ez.numCnfClauses()); @@ -1333,10 +1354,18 @@ struct SatPass : public Pass { } sathelper.generate_model(); -#if 0 - // print CNF for debugging - sathelper.ez.printDIMACS(stdout, true); -#endif + if (!cnf_file_name.empty()) + { + FILE *f = fopen(cnf_file_name.c_str(), "w"); + if (!f) + log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno)); + + log("Dumping CNF to file `%s'.\n", cnf_file_name.c_str()); + cnf_file_name.clear(); + + sathelper.ez.printDIMACS(f, false); + fclose(f); + } int rerun_counter = 0; From a71d09421d31b43b6bda6f6958373ec8a409e3c1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 19:23:32 +0100 Subject: [PATCH 045/750] Added techmap support for _TECHMAP_CONNMAP_*_ --- passes/techmap/techmap.cc | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 53164b58..74621d3e 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -271,6 +271,37 @@ struct TechmapWorker parameters[stringf("\\_TECHMAP_CONSTVAL_%s_", RTLIL::id2cstr(conn.first))] = RTLIL::SigSpec(v).as_const(); } } + + int unique_bit_id_counter = 0; + std::map unique_bit_id; + unique_bit_id[RTLIL::State::S0] = unique_bit_id_counter++; + unique_bit_id[RTLIL::State::S1] = unique_bit_id_counter++; + unique_bit_id[RTLIL::State::Sx] = unique_bit_id_counter++; + unique_bit_id[RTLIL::State::Sz] = unique_bit_id_counter++; + + for (auto conn : cell->connections) + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) { + for (auto &bit : sigmap(conn.second).to_sigbit_vector()) + if (unique_bit_id.count(bit) == 0) + unique_bit_id[bit] = unique_bit_id_counter++; + } + + int bits = 0; + for (int i = 0; i < 32; i++) + if (((unique_bit_id_counter-1) & (1 << i)) != 0) + bits = i; + if (tpl->avail_parameters.count("\\_TECHMAP_BITS_CONNMAP_")) + parameters["\\_TECHMAP_BITS_CONNMAP_"] = bits; + + for (auto conn : cell->connections) + if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) { + RTLIL::Const value; + for (auto &bit : sigmap(conn.second).to_sigbit_vector()) { + RTLIL::Const chunk(unique_bit_id.at(bit), bits); + value.bits.insert(value.bits.end(), chunk.bits.begin(), chunk.bits.end()); + } + parameters[stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))] = value; + } } std::pair> key(tpl_name, parameters); @@ -468,6 +499,14 @@ struct TechmapPass : public Pass { log(" former has a 1-bit for each constant input bit and the latter has the\n"); log(" value for this bit. The unused bits of the latter are set to undef (x).\n"); log("\n"); + log(" _TECHMAP_BITS_CONNMAP_\n"); + log(" _TECHMAP_CONNMAP__\n"); + log(" For an N-bit port, the _TECHMAP_CONNMAP__ parameter, if it\n"); + log(" exists, will be set to an N*_TECHMAP_BITS_CONNMAP_ bit vector containing\n"); + log(" N words (of _TECHMAP_BITS_CONNMAP_ bits each) that assign each single\n"); + log(" bit driver a unique id. The values 0-3 are reserved for 0, 1, x, and z.\n"); + log(" This can be used to detect shorted inputs.\n"); + log("\n"); log("When a module in the map file has a parameter where the according cell in the\n"); log("design has a port, the module from the map file is only used if the port in\n"); log("the design is connected to a constant value. The parameter is then set to the\n"); From 3d9da919d8ec2f73df77dc1df02b132b12241d8e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 19:37:39 +0100 Subject: [PATCH 046/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 37 +++++++++++++++++++++- manual/PRESENTATION_ExAdv/Makefile | 5 ++- manual/PRESENTATION_ExAdv/addshift_map.v | 20 ++++++++++++ manual/PRESENTATION_ExAdv/addshift_test.v | 5 +++ manual/PRESENTATION_ExAdv/addshift_test.ys | 6 ++++ manual/PRESENTATION_Intro.tex | 2 +- 6 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 manual/PRESENTATION_ExAdv/addshift_map.v create mode 100644 manual/PRESENTATION_ExAdv/addshift_test.v create mode 100644 manual/PRESENTATION_ExAdv/addshift_test.ys diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 80210b96..e42a535f 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -406,7 +406,42 @@ input values to cells. \subsubsection{Handling shorted inputs} \begin{frame}{\subsubsecname} -TBD +\begin{itemize} +\item The special parameters {\tt \_TECHMAP\_BITS\_CONNMAP\_} and +{\tt \_TECHMAP\_CONNMAP\_\it \tt \_} can be used to handle shorted inputs. +\medskip +\item Each bit of the port correlates to an {\tt \_TECHMAP\_BITS\_CONNMAP\_} bits wide +number in {\tt \_TECHMAP\_CONNMAP\_\it \tt \_}. +\medskip +\item Each unique signal bit is assigned its own number. Identical fields in the {\tt +\_TECHMAP\_CONNMAP\_\it \tt \_} parameters mean shorted signal bits. +\medskip +\item The numbers 0-3 are reserved for {\tt 0}, {\tt 1}, {\tt x}, and {\tt z} respectively. +\medskip +\item Example use-cases: +\begin{itemize} +\item Detecting shared clock or control signals in memory interfaces. +\item In some cases this can be used for for optimization. +\end{itemize} +\end{itemize} +\end{frame} + +\begin{frame}[t]{\subsubsecname{} -- Example} +\vbox to 0cm{ +\vskip4.5cm +\hskip6.5cm\includegraphics[width=5cm,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/addshift.pdf} +\vss +} +\vskip-0.6cm +\begin{columns} +\column[t]{6cm} +\vskip-0.4cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/addshift_map.v} +\column[t]{4.2cm} +\vskip-0.6cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/addshift_test.v} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys, lastline=5]{PRESENTATION_ExAdv/addshift_test.ys} +\end{columns} \end{frame} \subsubsection{Notes on using techmap} diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile index 3bbc239a..2a2858e5 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/manual/PRESENTATION_ExAdv/Makefile @@ -1,5 +1,5 @@ -all: select_01.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf +all: select_01.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf addshift.pdf select_01.pdf: select_01.v select_01.ys ../../yosys select_01.ys @@ -16,3 +16,6 @@ mymul.pdf: mymul_* mulshift.pdf: mulshift_* ../../yosys mulshift_test.ys +addshift.pdf: addshift_* + ../../yosys addshift_test.ys + diff --git a/manual/PRESENTATION_ExAdv/addshift_map.v b/manual/PRESENTATION_ExAdv/addshift_map.v new file mode 100644 index 00000000..b6d91b01 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/addshift_map.v @@ -0,0 +1,20 @@ +module \$add (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + parameter _TECHMAP_BITS_CONNMAP_ = 0; + parameter _TECHMAP_CONNMAP_A_ = 0; + parameter _TECHMAP_CONNMAP_B_ = 0; + + wire _TECHMAP_FAIL_ = A_WIDTH != B_WIDTH || B_WIDTH < Y_WIDTH || + _TECHMAP_CONNMAP_A_ != _TECHMAP_CONNMAP_B_; + + assign Y = A << 1; +endmodule diff --git a/manual/PRESENTATION_ExAdv/addshift_test.v b/manual/PRESENTATION_ExAdv/addshift_test.v new file mode 100644 index 00000000..b53271fa --- /dev/null +++ b/manual/PRESENTATION_ExAdv/addshift_test.v @@ -0,0 +1,5 @@ +module test (A, B, X, Y); +input [7:0] A, B; +output [7:0] X = A + B; +output [7:0] Y = A + A; +endmodule diff --git a/manual/PRESENTATION_ExAdv/addshift_test.ys b/manual/PRESENTATION_ExAdv/addshift_test.ys new file mode 100644 index 00000000..c08f1106 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/addshift_test.ys @@ -0,0 +1,6 @@ +read_verilog addshift_test.v +hierarchy -check -top test + +techmap -map addshift_map.v;; + +show -prefix addshift -format pdf -notitle diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 27576647..1c07928b 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -359,7 +359,7 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des Map registers to available hardware flip-flops. }% \only<12>{ - Map logix to available hardware gates. + Map logic to available hardware gates. }% \only<13>{ Clean up the design (just the last step of {\tt opt}). From 772330608acd9726e406d182a339a314d2f046a2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 19 Feb 2014 12:40:49 +0100 Subject: [PATCH 047/750] Added vcd2txt.pl and txt2tikztiming.py (tests/tools/...) --- tests/tools/txt2tikztiming.py | 109 ++++++++++++++++++++++++++++++++++ tests/tools/vcd2txt.pl | 61 +++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100755 tests/tools/txt2tikztiming.py create mode 100755 tests/tools/vcd2txt.pl diff --git a/tests/tools/txt2tikztiming.py b/tests/tools/txt2tikztiming.py new file mode 100755 index 00000000..cfefe339 --- /dev/null +++ b/tests/tools/txt2tikztiming.py @@ -0,0 +1,109 @@ +#!/usr/bin/python + +from __future__ import division +from __future__ import print_function + +import argparse +import fileinput +import sys + +parser = argparse.ArgumentParser(description='Convert vcd2txt output to tikz-timing line.') +parser.add_argument('filename', metavar='FILE', help='input txt file') +parser.add_argument('signame', metavar='SIG', help='Signal name') +parser.add_argument('-s', metavar='scale', default=1.0, type=float, help='Scale all time spans with this factor') +parser.add_argument('-l', action='store_true', help='Logic signal (high/low)') +parser.add_argument('-b', action='store_true', help='Display binary value') +parser.add_argument('-x', action='store_true', help='Display hex value') +parser.add_argument('-d', action='store_true', help='Display decimal value') +args = parser.parse_args() + +start_time = None +stop_time = None +time_val = { } + +def value_to_logic(value): + found_x = False + for char in value: + if char == '1': + return "H" + if char == 'x': + found_x = True + return "U" if found_x else "L" + +def value_to_binary(value): + return "D{%s}" % value + +def value_to_hex(value): + hex_string = "" + found_def = False + while len(value) % 4 != 0: + value = "0" + value + while len(value) != 0: + bin_digits = value[0:4] + hex_digit = 0 + value = value[4:] + for b in bin_digits: + if b == '0': + hex_digit = hex_digit * 2 + elif b == '1': + hex_digit = hex_digit * 2 + 1 + else: + hex_digit += 100 + if hex_digit > 15: + hex_string += "x" + else: + found_def = True + hex_string += "0123456789abcdef"[hex_digit] + if not found_def: + return "U"; + return "D{%s}" % hex_string + +def value_to_decimal(value): + val = 0 + found_def = False + found_undef = False + for digit in value: + if digit == 'x': + found_undef = True + else: + val = val*2 + int(digit) + found_def = True + if found_def: + if found_undef: + return "D{X}" + else: + return "D{%d}" % val + return "U" + +for line in fileinput.input(args.filename): + (node, time, name, value) = line.strip().split('\t') + time = int(time) + if start_time is None or start_time > time: + start_time = time + if stop_time is None or stop_time < time: + stop_time = time + if name == args.signame: + if args.l: + time_val[+time] = value_to_logic(value) + elif args.b: + time_val[+time] = value_to_binary(value) + elif args.x: + time_val[+time] = value_to_hex(value) + elif args.d: + time_val[+time] = value_to_decimal(value) + else: + time_val[+time] = value + +if start_time not in time_val: + time_val[start_time] = "S" + +last_time = None +last_value = None +for t in sorted(time_val.keys()): + if last_time is not None: + print("%f%s" % ((t - last_time)*args.s, last_value), end='') + (last_time, last_value) = (t, time_val[t]) +if last_time < stop_time: + print("%f%s" % ((stop_time - last_time)*args.s, last_value), end='') +print('') + diff --git a/tests/tools/vcd2txt.pl b/tests/tools/vcd2txt.pl new file mode 100755 index 00000000..92d3d165 --- /dev/null +++ b/tests/tools/vcd2txt.pl @@ -0,0 +1,61 @@ +#!/usr/bin/perl -w +# +# Note: You might need to install the Verilog::VCD package using CPAN.. + +use strict; +use Data::Dumper; +use Verilog::VCD qw(parse_vcd list_sigs); + +$| = 1; + +my $from_time = -1; +my $to_time = -1; + +while (1) +{ + if ($ARGV[0] eq '-f') { + $from_time = +$ARGV[1]; + shift @ARGV; + shift @ARGV; + next; + } + if ($ARGV[0] eq '-t') { + $to_time = +$ARGV[1]; + shift @ARGV; + shift @ARGV; + next; + } + last; +} + +if ($#ARGV < 0) { + print STDERR "\n"; + print STDERR "VCD2TXT - Convert VCD to tab-separated text file\n"; + print STDERR "\n"; + print STDERR "Usage: $0 [-f from_time] [-t to_time] input.vcd [ ...]\n"; + print STDERR "\n"; + exit 1; +} + +my $vcd = parse_vcd($ARGV[0]); + +for my $node (keys $vcd) { + for my $net (@{$vcd->{$node}->{'nets'}}) { + my $dump_this = $#ARGV == 0; + for (my $i = 1; $i <= $#ARGV; $i++) { + my $regex = $ARGV[$i]; + $dump_this = 1 if ($net->{"hier"} . "." . $net->{"name"}) =~ /$regex/; + } + next unless $dump_this; + my $cached_value = ""; + for my $tv (@{$vcd->{$node}->{'tv'}}) { + $cached_value = $tv->[1], next if $from_time >= 0 and +$tv->[0] < $from_time; + next if $to_time >= 0 and +$tv->[0] > $to_time; + printf "%s\t%s\t%s\t%s\n", $node, $from_time, $net->{"hier"} . "." . $net->{"name"}, $cached_value + if $cached_value ne "" and $from_time >= 0 and +$tv->[0] > $from_time; + printf "%s\t%s\t%s\t%s\n", $node, $tv->[0], $net->{"hier"} . "." . $net->{"name"}, $tv->[1]; + $cached_value = ""; + } + } +} + From 98940260e1a0e5d9d5d305b5fabe0aed89c9f57c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 12:46:29 +0100 Subject: [PATCH 048/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 86 ++++++++++++++++++- manual/PRESENTATION_ExAdv/Makefile | 10 ++- manual/PRESENTATION_ExAdv/macc_simple_test.v | 6 ++ manual/PRESENTATION_ExAdv/macc_simple_test.ys | 36 ++++++++ .../PRESENTATION_ExAdv/macc_simple_test_01.v | 6 ++ .../PRESENTATION_ExAdv/macc_simple_test_02.v | 6 ++ manual/PRESENTATION_ExAdv/macc_simple_xmap.v | 6 ++ .../{select_01.v => select.v} | 0 .../{select_01.ys => select.ys} | 4 +- manual/PRESENTATION_Intro.tex | 2 +- 10 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 manual/PRESENTATION_ExAdv/macc_simple_test.v create mode 100644 manual/PRESENTATION_ExAdv/macc_simple_test.ys create mode 100644 manual/PRESENTATION_ExAdv/macc_simple_test_01.v create mode 100644 manual/PRESENTATION_ExAdv/macc_simple_test_02.v create mode 100644 manual/PRESENTATION_ExAdv/macc_simple_xmap.v rename manual/PRESENTATION_ExAdv/{select_01.v => select.v} (100%) rename manual/PRESENTATION_ExAdv/{select_01.ys => select.ys} (76%) diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index e42a535f..155403b8 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -223,11 +223,11 @@ show -color red @cone_ab -color magenta @cone_a -color blue @cone_b \begin{frame}[fragile]{\subsubsecname{} -- Example} \begin{columns} \column[t]{4cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/select_01.v} +\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/select.v} \column[t]{7cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExAdv/select_01.ys} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExAdv/select.ys} \end{columns} -\hfil\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/select_01.pdf} +\hfil\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_ExAdv/select.pdf} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -477,7 +477,85 @@ cells in ASICS or dedicated carry logic in FPGAs. \subsectionpagesuffix \end{frame} -\subsubsection{TBD} +\subsubsection{Intro to coarse-grain synthesis} + +\begin{frame}[fragile]{\subsubsecname} +In coarse-grain synthesis the target architecure has cells of the same +complexity or larger complexity than the internal RTL representation. + +For example: +\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog] + wire [15:0] a, b; + wire [31:0] c, y; + assign y = a * b + c; +\end{lstlisting} + +This circuit contains two cells in the RTL representation: one multiplier and +one adder. + +\medskip +Coarse grain synthesis is mapping this circuit to a single multiply-add cell +of the target architecture, for example using an FPGA DSP core. + +\bigskip +Fine-grain synthesis would be matching the circuit to smaller elements, such +as LUTs, gates, or half- and full-adders. +\end{frame} + +\subsubsection{The extract pass} + +\begin{frame}{\subsubsecname} +\begin{itemize} +\item Like the {\tt techmap} pass, the {\tt extract} pass is called with +a map file. It compares the circuits inside the modules of the map file +with the design and looks for sub-circuits in the design that match any +of the modules in the map file. +\bigskip +\item If a match is found, the {\tt extract} pass will replace the matching +subcircuit with an instance of the module from the map file. +\bigskip +\item In a way the {\tt extract} pass is the inverse of the techmap pass. +\end{itemize} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- Example 1/2} +\vbox to 0cm{ +\vskip2cm +\begin{tikzpicture} + \node at (0,0) {\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_00a.pdf}}; + \node at (3,-3) {\includegraphics[width=8cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_00b.pdf}}; + \draw[yshift=0.2cm,thick,-latex] (1,-1) -- (2,-2); +\end{tikzpicture} +\vss} +\vskip-1.2cm +\begin{columns} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test.v} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExAdv/macc_simple_xmap.v} +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=ys] +read_verilog macc_simple_test.v +hierarchy -check -top test + +extract -map macc_simple_xmap.v;; +\end{lstlisting} +\end{columns} +\end{frame} + +\begin{frame}[fragile]{\subsubsecname{} -- Example 2/2} +\hfil\begin{tabular}{cc} +\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test_01.v}}} & +\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExAdv/macc_simple_test_02.v}}} \\ +$\downarrow$ & $\downarrow$ \\ +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_01a.pdf}} & +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_02a.pdf}} \\ +$\downarrow$ & $\downarrow$ \\ +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_01b.pdf}} & +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_simple_test_02b.pdf}} \\ +\end{tabular} +\end{frame} + +\subsubsection{The wrap-extract-unwrap method} \begin{frame}{\subsubsecname} TBD diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile index 2a2858e5..60da3169 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/manual/PRESENTATION_ExAdv/Makefile @@ -1,8 +1,9 @@ -all: select_01.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf addshift.pdf +all: select.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf addshift.pdf \ + macc_simple_xmap.pdf -select_01.pdf: select_01.v select_01.ys - ../../yosys select_01.ys +select.pdf: select.v select.ys + ../../yosys select.ys red_or3x1.pdf: red_or3x1_* ../../yosys red_or3x1_test.ys @@ -19,3 +20,6 @@ mulshift.pdf: mulshift_* addshift.pdf: addshift_* ../../yosys addshift_test.ys +macc_simple_xmap.pdf: macc_simple_*.v macc_simple_test.ys + ../../yosys macc_simple_test.ys + diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test.v b/manual/PRESENTATION_ExAdv/macc_simple_test.v new file mode 100644 index 00000000..6358a47c --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_simple_test.v @@ -0,0 +1,6 @@ +module test(a, b, c, d, y); +input [15:0] a, b; +input [31:0] c, d; +output [31:0] y; +assign y = a * b + c + d; +endmodule diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test.ys b/manual/PRESENTATION_ExAdv/macc_simple_test.ys new file mode 100644 index 00000000..d5b01237 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_simple_test.ys @@ -0,0 +1,36 @@ +read_verilog macc_simple_test.v +hierarchy -check -top test;; + +show -prefix macc_simple_test_00a -format pdf -notitle -lib macc_simple_xmap.v + +extract -constports -map macc_simple_xmap.v;; +show -prefix macc_simple_test_00b -format pdf -notitle -lib macc_simple_xmap.v + +################################################# + +read_verilog macc_simple_test_01.v +hierarchy -check -top test;; + +show -prefix macc_simple_test_01a -format pdf -notitle -lib macc_simple_xmap.v + +extract -map macc_simple_xmap.v;; +show -prefix macc_simple_test_01b -format pdf -notitle -lib macc_simple_xmap.v + +################################################# + +design -reset +read_verilog macc_simple_test_02.v +hierarchy -check -top test;; + +show -prefix macc_simple_test_02a -format pdf -notitle -lib macc_simple_xmap.v + +extract -map macc_simple_xmap.v;; +show -prefix macc_simple_test_02b -format pdf -notitle -lib macc_simple_xmap.v + +################################################# + +design -reset +read_verilog macc_simple_xmap.v +hierarchy -check -top macc_16_16_32;; + +show -prefix macc_simple_xmap -format pdf -notitle diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test_01.v b/manual/PRESENTATION_ExAdv/macc_simple_test_01.v new file mode 100644 index 00000000..8391fb38 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_simple_test_01.v @@ -0,0 +1,6 @@ +module test(a, b, c, d, x, y); +input [15:0] a, b, c, d; +input [31:0] x; +output [31:0] y; +assign y = a*b + c*d + x; +endmodule diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test_02.v b/manual/PRESENTATION_ExAdv/macc_simple_test_02.v new file mode 100644 index 00000000..3630102f --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_simple_test_02.v @@ -0,0 +1,6 @@ +module test(a, b, c, d, x, y); +input [15:0] a, b, c, d; +input [31:0] x; +output [31:0] y; +assign y = a*b + (c*d + x); +endmodule diff --git a/manual/PRESENTATION_ExAdv/macc_simple_xmap.v b/manual/PRESENTATION_ExAdv/macc_simple_xmap.v new file mode 100644 index 00000000..42f5bae9 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_simple_xmap.v @@ -0,0 +1,6 @@ +module macc_16_16_32(a, b, c, y); +input [15:0] a, b; +input [31:0] c; +output [31:0] y; +assign y = a*b + c; +endmodule diff --git a/manual/PRESENTATION_ExAdv/select_01.v b/manual/PRESENTATION_ExAdv/select.v similarity index 100% rename from manual/PRESENTATION_ExAdv/select_01.v rename to manual/PRESENTATION_ExAdv/select.v diff --git a/manual/PRESENTATION_ExAdv/select_01.ys b/manual/PRESENTATION_ExAdv/select.ys similarity index 76% rename from manual/PRESENTATION_ExAdv/select_01.ys rename to manual/PRESENTATION_ExAdv/select.ys index a7fe2728..9832c104 100644 --- a/manual/PRESENTATION_ExAdv/select_01.ys +++ b/manual/PRESENTATION_ExAdv/select.ys @@ -1,10 +1,10 @@ -read_verilog select_01.v +read_verilog select.v hierarchy -check -top test proc; opt cd test select -set cone_a state_a %ci*:-$dff select -set cone_b state_b %ci*:-$dff select -set cone_ab @cone_a @cone_b %i -show -prefix select_01 -format pdf -notitle \ +show -prefix select -format pdf -notitle \ -color red @cone_ab -color magenta @cone_a \ -color blue @cone_b diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 1c07928b..543fb41e 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -680,7 +680,7 @@ basic functionality. Extensibility was one of Yosys' design goals. Because of the framework characterisitcs of Yosys, an increasing number of features become available in one tool. Yosys not only can be used for circuit synthesis but also for formal equivialence checking, SAT solving, and for circuit analysis, to -name just a few other application domains. With propritaery software one needs to +name just a few other application domains. With proprietary software one needs to learn a new tool for each of this applications. \end{itemize} \end{frame} From 4bd25edcd4773d312cc47384e639161d485492de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 19:12:32 +0100 Subject: [PATCH 049/750] Cleanups in handling of read_verilog -defer and -icells --- frontends/ast/ast.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 58be0679..d9ad6d8e 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); } } From 0dadfed46d938282d7651c9a817f33b1d87397c7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 20:44:11 +0100 Subject: [PATCH 050/750] Added connwrappers command --- passes/cmds/Makefile.inc | 1 + passes/cmds/connwrappers.cc | 205 ++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 passes/cmds/connwrappers.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index f01a1c4b..77cac2b4 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -15,4 +15,5 @@ OBJS += passes/cmds/copy.o OBJS += passes/cmds/splice.o OBJS += passes/cmds/scc.o OBJS += passes/cmds/log.o +OBJS += passes/cmds/connwrappers.o diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc new file mode 100644 index 00000000..dd8b4fed --- /dev/null +++ b/passes/cmds/connwrappers.cc @@ -0,0 +1,205 @@ +/* + * 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/rtlil.h" +#include "kernel/log.h" + +struct ConnwrappersWorker +{ + struct portdecl_t { + // key: celltype, portname; + std::string widthparam, signparam; + bool is_signed; + }; + + std::set decl_celltypes; + std::map, portdecl_t> decls; + + void add_port(std::string celltype, std::string portname, std::string widthparam, std::string signparam) + { + std::pair key(RTLIL::escape_id(celltype), RTLIL::escape_id(portname)); + decl_celltypes.insert(key.first); + + if (decls.count(key)) + log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str()); + + portdecl_t decl; + decl.widthparam = RTLIL::escape_id(widthparam); + decl.signparam = RTLIL::escape_id(signparam); + decl.is_signed = false; + decls[key] = decl; + } + + void add_port(std::string celltype, std::string portname, std::string widthparam, bool is_signed) + { + std::pair key(RTLIL::escape_id(celltype), RTLIL::escape_id(portname)); + decl_celltypes.insert(key.first); + + if (decls.count(key)) + log_cmd_error("Duplicate port decl: %s %s\n", celltype.c_str(), portname.c_str()); + + portdecl_t decl; + decl.widthparam = RTLIL::escape_id(widthparam); + decl.is_signed = is_signed; + decls[key] = decl; + } + + void work(RTLIL::Design *design, RTLIL::Module *module) + { + std::map> extend_map; + SigMap sigmap(module); + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + + if (!decl_celltypes.count(cell->type)) + continue; + + for (auto &conn : cell->connections) + { + std::pair key(cell->type, conn.first); + + if (!decls.count(key)) + continue; + + portdecl_t &decl = decls.at(key); + + if (!cell->parameters.count(decl.widthparam)) + continue; + + if (!decl.signparam.empty() && !cell->parameters.count(decl.signparam)) + continue; + + int inner_width = cell->parameters.at(decl.widthparam).as_int(); + int outer_width = conn.second.width; + bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(decl.signparam).as_bool(); + + if (inner_width >= outer_width) + continue; + + RTLIL::SigSpec sig = sigmap(conn.second); + extend_map[sig.extract(inner_width - 1, 1)] = std::pair(is_signed, + sig.extract(inner_width, outer_width - inner_width)); + } + } + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + + if (!design->selected(module, cell)) + continue; + + for (auto &conn : cell->connections) + { + std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); + RTLIL::SigSpec old_sig; + + for (size_t i = 0; i < sigbits.size(); i++) + { + if (!extend_map.count(sigbits[i])) + continue; + + bool is_signed = extend_map.at(sigbits[i]).first; + RTLIL::SigSpec extend_sig = extend_map.at(sigbits[i]).second; + + int extend_width = 0; + RTLIL::SigBit extend_bit = is_signed ? sigbits[i] : RTLIL::SigBit(RTLIL::State::S0); + while (extend_width < extend_sig.width && i + extend_width + 1 < sigbits.size() && + sigbits[i + extend_width + 1] == extend_bit) extend_width++; + + if (extend_width == 0) + continue; + + if (old_sig.width == 0) + old_sig = conn.second; + + conn.second.replace(i+1, extend_sig.extract(0, extend_width)); + i += extend_width; + } + + if (old_sig.width) + log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), + RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second)); + } + } + } +}; + +struct ConnwrappersPass : public Pass { + ConnwrappersPass() : Pass("connwrappers", "replace undef values with defined constants") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" connwrappers [options] [selection]\n"); + log("\n"); + log("Wrappers are used in coarse-grain synthesis to wrap cells with smaller ports\n"); + log("in wrapper cells with a (larger) constant port size. I.e. the upper bits\n"); + log("of the wrapper outut are signed/unsigned bit extended. This command uses this\n"); + log("knowlege to rewire the inputs of the driven cells to match the output of\n"); + log("the driving cell.\n"); + log("\n"); + log(" -signed \n"); + log(" -unsigned \n"); + log(" consider the specified signed/unsigned wrapper output\n"); + log("\n"); + log(" -port \n"); + log(" use the specified parameter to decide if signed or unsigned\n"); + log("\n"); + log("The options -signed, -unsigned, and -port can be specified multiple times.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + ConnwrappersWorker worker; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-signed" && argidx+3 < args.size()) { + worker.add_port(args[argidx+1], args[argidx+2], args[argidx+3], true); + argidx += 3; + continue; + } + if (args[argidx] == "-unsigned" && argidx+3 < args.size()) { + worker.add_port(args[argidx+1], args[argidx+2], args[argidx+3], false); + argidx += 3; + continue; + } + if (args[argidx] == "-port" && argidx+4 < args.size()) { + worker.add_port(args[argidx+1], args[argidx+2], args[argidx+3], args[argidx+4]); + argidx += 4; + continue; + } + break; + } + extra_args(args, argidx, design); + + log_header("Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n"); + + for (auto &mod_it : design->modules) + if (design->selected(mod_it.second)) + worker.work(design, mod_it.second); + } +} ConnwrappersPass; + From b0e84802ecf3e224387317245786cd1437773a42 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 20:44:41 +0100 Subject: [PATCH 051/750] Progress in presentation --- .../PRESENTATION_ExAdv/macc_xilinx_swap_map.v | 30 ++++++ manual/PRESENTATION_ExAdv/macc_xilinx_test.v | 6 ++ manual/PRESENTATION_ExAdv/macc_xilinx_test.ys | 17 ++++ .../macc_xilinx_unwrap_map.v | 63 +++++++++++++ .../PRESENTATION_ExAdv/macc_xilinx_wrap_map.v | 91 +++++++++++++++++++ 5 files changed, 207 insertions(+) create mode 100644 manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v create mode 100644 manual/PRESENTATION_ExAdv/macc_xilinx_test.v create mode 100644 manual/PRESENTATION_ExAdv/macc_xilinx_test.ys create mode 100644 manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v create mode 100644 manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v b/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v new file mode 100644 index 00000000..1f4867d1 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v @@ -0,0 +1,30 @@ + +(* techmap_celltype = "$mul" *) +module mul_swap_ports (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire _TECHMAP_FAIL_ = A_WIDTH >= B_WIDTH; + +\$mul #( + .A_SIGNED(B_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(B_WIDTH), + .B_WIDTH(A_WIDTH), + .Y_WIDTH(Y_WIDTH) +) _TECHMAP_REPLACE_ ( + .A(B), + .B(A), + .Y(Y) +); + +endmodule + diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.v b/manual/PRESENTATION_ExAdv/macc_xilinx_test.v new file mode 100644 index 00000000..d08d939e --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_test.v @@ -0,0 +1,6 @@ +module test(a, b, c, d, e, f, y); +input [19:0] a, b, c; +input [15:0] d, e, f; +output [41:0] y; +assign y = a*b + c*d + e*f; +endmodule diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys new file mode 100644 index 00000000..8cbc80b5 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys @@ -0,0 +1,17 @@ +read_verilog macc_xilinx_test.v +read_verilog -lib -icells macc_xilinx_unwrap_map.v +hierarchy -check -top test;; + +show -prefix macc_xilinx_test_a -format pdf -notitle + +techmap -map macc_xilinx_swap_map.v;; + +show -prefix macc_xilinx_test_b -format pdf -notitle + +techmap -map macc_xilinx_wrap_map.v + +connwrappers -unsigned $__mul_wrapper Y Y_WIDTH \ + -unsigned $__add_wrapper Y Y_WIDTH;; + +show -prefix macc_xilinx_test_c -format pdf -notitle + diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v b/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v new file mode 100644 index 00000000..386635ac --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v @@ -0,0 +1,63 @@ + +module \$__mul_wrapper (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [A_WIDTH-1:0] A_ORIG = A; +wire [B_WIDTH-1:0] B_ORIG = B; +wire [Y_WIDTH-1:0] Y_ORIG; +assign Y = Y_ORIG; + +\$mul #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) +) _TECHMAP_REPLACE_ ( + .A(A_ORIG), + .B(B_ORIG), + .Y(Y_ORIG) +); + +endmodule + +module \$__add_wrapper (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [A_WIDTH-1:0] A_ORIG = A; +wire [B_WIDTH-1:0] B_ORIG = B; +wire [Y_WIDTH-1:0] Y_ORIG; +assign Y = Y_ORIG; + +\$add #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) +) _TECHMAP_REPLACE_ ( + .A(A_ORIG), + .B(B_ORIG), + .Y(Y_ORIG) +); + +endmodule + diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v b/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v new file mode 100644 index 00000000..d1ded295 --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v @@ -0,0 +1,91 @@ + +(* techmap_celltype = "$mul" *) +module mul_wrap (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [24:0] A_25 = A; +wire [17:0] B_18 = B; +wire [47:0] Y_48; +assign Y = Y_48; + +wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + +reg _TECHMAP_FAIL_; +initial begin + _TECHMAP_FAIL_ <= 0; + if (A_SIGNED || B_SIGNED) + _TECHMAP_FAIL_ <= 1; + if (A_WIDTH < 4 || B_WIDTH < 4) + _TECHMAP_FAIL_ <= 1; + if (A_WIDTH > 25 || B_WIDTH > 18) + _TECHMAP_FAIL_ <= 1; + if (A_WIDTH*B_WIDTH < 100) + _TECHMAP_FAIL_ <= 1; +end + +\$__mul_wrapper #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) +) _TECHMAP_REPLACE_ ( + .A(A_25), + .B(B_18), + .Y(Y_48) +); + +endmodule + +(* techmap_celltype = "$add" *) +module add_wrap (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +wire [47:0] A_48 = A; +wire [47:0] B_48 = B; +wire [47:0] Y_48; +assign Y = Y_48; + +wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + +reg _TECHMAP_FAIL_; +initial begin + _TECHMAP_FAIL_ <= 0; + if (A_SIGNED || B_SIGNED) + _TECHMAP_FAIL_ <= 1; + if (A_WIDTH < 10 && B_WIDTH < 10) + _TECHMAP_FAIL_ <= 1; +end + +\$__add_wrapper #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) +) _TECHMAP_REPLACE_ ( + .A(A_48), + .B(B_48), + .Y(Y_48) +); + +endmodule + From 483c99fe46d6b1cd35abddd38a629d30e13289b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:28:59 +0100 Subject: [PATCH 052/750] Added "design -push" and "design -pop" --- kernel/register.h | 4 ++++ passes/cmds/design.cc | 53 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/kernel/register.h b/kernel/register.h index 83e1059c..b582f98c 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -40,6 +40,10 @@ std::string rewrite_yosys_exe(std::string exe); std::string get_share_file_name(std::string file); const char *create_prompt(RTLIL::Design *design, int recursion_counter); +// from passes/cmds/design.cc +extern std::map saved_designs; +extern std::vector pushed_designs; + struct Pass { std::string pass_name, short_help; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 80a6c073..7b8889d6 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -22,13 +22,18 @@ #include "kernel/rtlil.h" #include "kernel/log.h" +std::map saved_designs; +std::vector pushed_designs; + struct DesignPass : public Pass { DesignPass() : Pass("design", "save, restore and reset current design") { } - std::map saved_designs; virtual ~DesignPass() { for (auto &it : saved_designs) delete it.second; saved_designs.clear(); + for (auto &it : pushed_designs) + delete it; + pushed_designs.clear(); } virtual void help() { @@ -49,6 +54,16 @@ struct DesignPass : public Pass { log("Save the current design under the given name and then clear the current design.\n"); log("\n"); log("\n"); + log(" design -push\n"); + log("\n"); + log("Push the current design to the stack and then clear the current design.\n"); + log("\n"); + log("\n"); + log(" design -pop\n"); + log("\n"); + log("Reset the current design and pop the last design from the stack.\n"); + log("\n"); + log("\n"); log(" design -load \n"); log("\n"); log("Reset the current design and load the design previously saved under the given\n"); @@ -70,6 +85,8 @@ struct DesignPass : public Pass { { bool got_mode = false; bool reset_mode = false; + bool push_mode = false; + bool pop_mode = false; RTLIL::Design *copy_from_design = NULL, *copy_to_design = NULL; std::string save_name, load_name, as_name; std::vector copy_src_modules; @@ -83,6 +100,16 @@ struct DesignPass : public Pass { reset_mode = true; continue; } + if (!got_mode && args[argidx] == "-push") { + got_mode = true; + push_mode = true; + continue; + } + if (!got_mode && args[argidx] == "-pop") { + got_mode = true; + pop_mode = true; + continue; + } if (!got_mode && args[argidx] == "-save" && argidx+1 < args.size()) { got_mode = true; save_name = args[++argidx]; @@ -151,7 +178,10 @@ struct DesignPass : public Pass { extra_args(args, argidx, design, false); if (!got_mode) - cmd_error(args, argidx, "Missing mode argument (-reset, -save, -load, -copy-from, or -copy-to)."); + cmd_error(args, argidx, "Missing mode argument."); + + if (pop_mode && pushed_designs.empty()) + log_cmd_error("No pushed designs.\n"); if (copy_to_design != NULL) { @@ -169,7 +199,7 @@ struct DesignPass : public Pass { } } - if (!save_name.empty()) + if (!save_name.empty() || push_mode) { RTLIL::Design *design_copy = new RTLIL::Design; @@ -182,10 +212,14 @@ struct DesignPass : public Pass { if (saved_designs.count(save_name)) delete saved_designs.at(save_name); - saved_designs[save_name] = design_copy; + + if (push_mode) + pushed_designs.push_back(design_copy); + else + saved_designs[save_name] = design_copy; } - if (reset_mode || !load_name.empty()) + if (reset_mode || !load_name.empty() || push_mode || pop_mode) { for (auto &it : design->modules) delete it.second; @@ -198,9 +232,12 @@ struct DesignPass : public Pass { design->selection_stack.push_back(RTLIL::Selection()); } - if (!load_name.empty()) + if (!load_name.empty() || pop_mode) { - RTLIL::Design *saved_design = saved_designs.at(load_name); + RTLIL::Design *saved_design = pop_mode ? pushed_designs.back() : saved_designs.at(load_name); + + if (pop_mode) + pushed_designs.pop_back(); for (auto &it : saved_design->modules) design->modules[it.first] = it.second->clone(); @@ -211,4 +248,4 @@ struct DesignPass : public Pass { } } } DesignPass; - + From 236fc4209c17bf96b37e6f8a29a8aa3f24d5df45 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:30:15 +0100 Subject: [PATCH 053/750] Added "extract -map %" --- passes/techmap/extract.cc | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index eff14ff0..06b0df2d 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -315,6 +315,10 @@ struct ExtractPass : public Pass { log(" use the modules in this file as reference. This option can be used\n"); log(" multiple times.\n"); log("\n"); + log(" -map %%\n"); + log(" use the modules in this in-memory design as reference. This option can\n"); + log(" be used multiple times.\n"); + log("\n"); log(" -verbose\n"); log(" print debug output while analyzing\n"); log("\n"); @@ -524,16 +528,32 @@ struct ExtractPass : public Pass { if (!mine_mode) { map = new RTLIL::Design; - for (auto &filename : map_filenames) { - FILE *f = fopen(filename.c_str(), "rt"); - if (f == NULL) - log_cmd_error("Can't open map file `%s'.\n", filename.c_str()); - Frontend::frontend_call(map, f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); - fclose(f); + for (auto &filename : map_filenames) + { + if (filename.substr(0, 1) == "%") + { + if (!saved_designs.count(filename.substr(1))) { + delete map; + log_cmd_error("Can't saved design `%s'.\n", filename.c_str()+1); + } + for (auto &it : saved_designs.at(filename.substr(1))->modules) + if (!map->modules.count(it.first)) + map->modules[it.first] = it.second->clone(); + } + else + { + FILE *f = fopen(filename.c_str(), "rt"); + if (f == NULL) { + delete map; + log_cmd_error("Can't open map file `%s'.\n", filename.c_str()); + } + Frontend::frontend_call(map, f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); + fclose(f); - if (filename.size() <= 3 || filename.substr(filename.size()-3) != ".il") { - Pass::call(map, "proc"); - Pass::call(map, "opt_clean"); + if (filename.size() <= 3 || filename.substr(filename.size()-3) != ".il") { + Pass::call(map, "proc"); + Pass::call(map, "opt_clean"); + } } } } From 737b71c73576d67b707119805cb599644a43777d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:31:13 +0100 Subject: [PATCH 054/750] Added "extract -ignore_parameters" and "extract -ignore_param ..." --- passes/techmap/extract.cc | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 06b0df2d..d2193c7b 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -34,8 +34,14 @@ namespace class SubCircuitSolver : public SubCircuit::Solver { public: + bool ignore_parameters; + std::set> ignored_parameters; std::set cell_attr, wire_attr; + SubCircuitSolver() : ignore_parameters(false) + { + } + bool compareAttributes(const std::set &attr, const std::map &needleAttr, const std::map &haystackAttr) { for (auto &it : attr) { @@ -46,12 +52,70 @@ namespace return true; } + RTLIL::Const unified_param(RTLIL::IdString cell_type, RTLIL::IdString param, RTLIL::Const value) + { + if (cell_type.substr(0, 1) != "$" || cell_type.substr(0, 2) == "$_") + return value; + + #define param_bool(_n) if (param == _n) return value.as_bool(); + param_bool("\\ARST_POLARITY"); + param_bool("\\A_SIGNED"); + param_bool("\\B_SIGNED"); + param_bool("\\CLK_ENABLE"); + param_bool("\\CLK_POLARITY"); + param_bool("\\CLR_POLARITY"); + param_bool("\\EN_POLARITY"); + param_bool("\\SET_POLARITY"); + param_bool("\\TRANSPARENT"); + #undef param_bool + + #define param_int(_n) if (param == _n) return value.as_int(); + param_int("\\ABITS") + param_int("\\A_WIDTH") + param_int("\\B_WIDTH") + param_int("\\CTRL_IN_WIDTH") + param_int("\\CTRL_OUT_WIDTH") + param_int("\\OFFSET") + param_int("\\PRIORITY") + param_int("\\RD_PORTS") + param_int("\\SIZE") + param_int("\\STATE_BITS") + param_int("\\STATE_NUM") + param_int("\\STATE_NUM_LOG2") + param_int("\\STATE_RST") + param_int("\\S_WIDTH") + param_int("\\TRANS_NUM") + param_int("\\WIDTH") + param_int("\\WR_PORTS") + param_int("\\Y_WIDTH") + #undef param_int + + return value; + } + virtual bool userCompareNodes(const std::string &, const std::string &, void *needleUserData, const std::string &, const std::string &, void *haystackUserData, const std::map &portMapping) { RTLIL::Cell *needleCell = (RTLIL::Cell*) needleUserData; RTLIL::Cell *haystackCell = (RTLIL::Cell*) haystackUserData; + if (!needleCell || !haystackCell) { + assert(!needleCell && !haystackCell); + return true; + } + + if (!ignore_parameters) { + std::map needle_param, haystack_param; + for (auto &it : needleCell->parameters) + if (!ignored_parameters.count(std::pair(needleCell->type, it.first))) + needle_param[it.first] = unified_param(needleCell->type, it.first, it.second); + for (auto &it : haystackCell->parameters) + if (!ignored_parameters.count(std::pair(haystackCell->type, it.first))) + haystack_param[it.first] = unified_param(haystackCell->type, it.first, it.second); + if (needle_param != haystack_param) + return false; + } + if (cell_attr.size() > 0 && !compareAttributes(cell_attr, needleCell->attributes, haystackCell->attributes)) return false; @@ -351,6 +415,12 @@ struct ExtractPass : public Pass { log(" -wire_attr \n"); log(" Attributes on wires with the given name must match.\n"); log("\n"); + log(" -ignore_parameters\n"); + log(" Do not use parameters when matching cells.\n"); + log("\n"); + log(" -ignore_param \n"); + log(" Do not use this parameter when matching cells.\n"); + log("\n"); log("This pass does not operate on modules with uprocessed processes in it.\n"); log("(I.e. the 'proc' pass should be used first to convert processes to netlists.)\n"); log("\n"); @@ -498,6 +568,15 @@ struct ExtractPass : public Pass { solver.wire_attr.insert(RTLIL::escape_id(args[++argidx])); continue; } + if (args[argidx] == "-ignore_parameters") { + solver.ignore_parameters = true; + continue; + } + if (args[argidx] == "-ignore_param" && argidx+2 < args.size()) { + solver.ignored_parameters.insert(std::pair(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2]))); + argidx += 2; + continue; + } break; } extra_args(args, argidx, design); From 4e43cb731701679e6d584ba14163befcb846e87b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:42:07 +0100 Subject: [PATCH 055/750] Added _TECHMAP_REPLACE_ feature to techmap --- passes/techmap/techmap.cc | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 74621d3e..f163c024 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -108,6 +108,18 @@ struct TechmapWorker if (tpl->processes.size() != 0) log_error("Technology map yielded processes -> this is not supported.\n"); + // erase from namespace first for _TECHMAP_REPLACE_ to work + module->cells.erase(cell->name); + std::string orig_cell_name; + + if (!flatten_mode) + for (auto &it : tpl->cells) + if (it.first == "\\_TECHMAP_REPLACE_") { + orig_cell_name = cell->name; + cell->name = stringf("$techmap%d", RTLIL::autoidx++) + cell->name; + break; + } + std::map positional_ports; for (auto &it : tpl->wires) { @@ -120,7 +132,7 @@ struct TechmapWorker w->port_id = 0; if (it.second->get_bool_attribute("\\_techmap_special_")) w->attributes.clear(); - module->wires[w->name] = w; + module->add(w); design->select(module, w); } @@ -169,12 +181,15 @@ struct TechmapWorker RTLIL::Cell *c = new RTLIL::Cell(*it.second); if (!flatten_mode && c->type.substr(0, 2) == "\\$") c->type = c->type.substr(1); - apply_prefix(cell->name, c->name); + if (!flatten_mode && c->name == "\\_TECHMAP_REPLACE_") + c->name = orig_cell_name; + else + apply_prefix(cell->name, c->name); for (auto &it2 : c->connections) { apply_prefix(cell->name, it2.second, module); port_signal_map.apply(it2.second); } - module->cells[c->name] = c; + module->add(c); design->select(module, c); } @@ -187,7 +202,6 @@ struct TechmapWorker module->connections.push_back(c); } - module->cells.erase(cell->name); delete cell; } @@ -512,6 +526,9 @@ struct TechmapPass : public Pass { log("the design is connected to a constant value. The parameter is then set to the\n"); log("constant value.\n"); log("\n"); + log("A cell with the name _TECHMAP_REPLACE_ in the map file will inherit the name\n"); + log("of the cell that is beeing replaced.\n"); + log("\n"); log("See 'help extract' for a pass that does the opposite thing.\n"); log("\n"); log("See 'help flatten' for a pass that does flatten the design (which is\n"); From 9351e4d3caef1af7b7768d66b7f6edc12713d109 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:44:28 +0100 Subject: [PATCH 056/750] Progress in presentation --- manual/PRESENTATION_ExAdv/macc_xilinx_test.v | 9 +++++- manual/PRESENTATION_ExAdv/macc_xilinx_test.ys | 31 ++++++++++++++++--- .../macc_xilinx_unwrap_map.v | 12 +++---- manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v | 10 ++++++ 4 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.v b/manual/PRESENTATION_ExAdv/macc_xilinx_test.v index d08d939e..d8fdf724 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_test.v +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_test.v @@ -1,6 +1,13 @@ -module test(a, b, c, d, e, f, y); +module test1(a, b, c, d, e, f, y); input [19:0] a, b, c; input [15:0] d, e, f; output [41:0] y; assign y = a*b + c*d + e*f; endmodule + +module test2(a, b, c, d, e, f, y); +input [19:0] a, b, c; +input [15:0] d, e, f; +output [41:0] y; +assign y = a*b + (c*d + e*f); +endmodule diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys index 8cbc80b5..85c4a24f 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys @@ -1,17 +1,40 @@ read_verilog macc_xilinx_test.v read_verilog -lib -icells macc_xilinx_unwrap_map.v -hierarchy -check -top test;; +read_verilog -lib -icells macc_xilinx_xmap.v +hierarchy -check ;; -show -prefix macc_xilinx_test_a -format pdf -notitle +show -prefix macc_xilinx_test1_a -format pdf -notitle test1 +show -prefix macc_xilinx_test2_a -format pdf -notitle test2 techmap -map macc_xilinx_swap_map.v;; -show -prefix macc_xilinx_test_b -format pdf -notitle +show -prefix macc_xilinx_test1_b -format pdf -notitle test1 +show -prefix macc_xilinx_test2_b -format pdf -notitle test2 techmap -map macc_xilinx_wrap_map.v connwrappers -unsigned $__mul_wrapper Y Y_WIDTH \ -unsigned $__add_wrapper Y Y_WIDTH;; -show -prefix macc_xilinx_test_c -format pdf -notitle +show -prefix macc_xilinx_test1_c -format pdf -notitle test1 +show -prefix macc_xilinx_test2_c -format pdf -notitle test2 + +design -push +read_verilog macc_xilinx_xmap.v +techmap -map macc_xilinx_swap_map.v +techmap -map macc_xilinx_wrap_map.v;; +design -save __macc_xilinx_xmap +design -pop + +extract -constports -ignore_parameters \ + -map %__macc_xilinx_xmap \ + -swap $__add_wrapper A,B ;; + +show -prefix macc_xilinx_test1_d -format pdf -notitle test1 +show -prefix macc_xilinx_test2_d -format pdf -notitle test2 + +techmap -map macc_xilinx_unwrap_map.v;; + +show -prefix macc_xilinx_test1_e -format pdf -notitle test1 +show -prefix macc_xilinx_test2_e -format pdf -notitle test2 diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v b/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v index 386635ac..a80538d5 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v @@ -7,9 +7,9 @@ parameter A_WIDTH = 1; parameter B_WIDTH = 1; parameter Y_WIDTH = 1; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; +input [24:0] A; +input [17:0] B; +output [47:0] Y; wire [A_WIDTH-1:0] A_ORIG = A; wire [B_WIDTH-1:0] B_ORIG = B; @@ -38,9 +38,9 @@ parameter A_WIDTH = 1; parameter B_WIDTH = 1; parameter Y_WIDTH = 1; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; +input [47:0] A; +input [47:0] B; +output [47:0] Y; wire [A_WIDTH-1:0] A_ORIG = A; wire [B_WIDTH-1:0] B_ORIG = B; diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v b/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v new file mode 100644 index 00000000..15bd04ed --- /dev/null +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v @@ -0,0 +1,10 @@ +module DSP48_MACC (a, b, c, y); + +input [24:0] a; +input [17:0] b; +input [47:0] c; +output [47:0] y; + +assign y = a*b + c; + +endmodule From 2aff7b2a47d2ad65ff34e10f008733da9ef50c4a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 02:13:02 +0100 Subject: [PATCH 057/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 151 ++++++++++++++++++ manual/PRESENTATION_ExAdv/Makefile | 5 +- manual/PRESENTATION_ExAdv/macc_simple_test.ys | 1 + manual/PRESENTATION_ExAdv/macc_xilinx_test.v | 16 +- manual/PRESENTATION_ExAdv/macc_xilinx_test.ys | 23 +-- 5 files changed, 177 insertions(+), 19 deletions(-) diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 155403b8..f2080922 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -561,6 +561,157 @@ $\downarrow$ & $\downarrow$ \\ TBD \end{frame} +\subsubsection{Example: DSP48\_MACC} + +\begin{frame}[fragile]{\subsubsecname{} -- ?/?} +\hfil\begin{tabular}{cc} +{\tt test1} & {\tt test2} \\ +\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, firstline=1, lastline=6, language=verilog]{PRESENTATION_ExAdv/macc_xilinx_test.v}}} & +\fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, firstline=8, lastline=13, language=verilog]{PRESENTATION_ExAdv/macc_xilinx_test.v}}} \\ +$\downarrow$ & $\downarrow$ \\ +\end{tabular} +\vskip-0.5cm +\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] + read_verilog macc_xilinx_test.v + hierarchy -check +\end{lstlisting} +\vskip-0.5cm +\hfil\begin{tabular}{cc} +$\downarrow$ & $\downarrow$ \\ +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1a.pdf}} & +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2a.pdf}} \\ +\end{tabular} +\end{frame} + +\begin{frame}[fragile]{\subsubsecname{} -- ?/?} +\hfil\begin{tabular}{cc} +{\tt test1} & {\tt test2} \\ +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1a.pdf}} & +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2a.pdf}} \\ +$\downarrow$ & $\downarrow$ \\ +\end{tabular} +\vskip-0.2cm +\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] + techmap -map macc_xilinx_swap_map.v ;; +\end{lstlisting} +\vskip-0.2cm +\hfil\begin{tabular}{cc} +$\downarrow$ & $\downarrow$ \\ +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1b.pdf}} & +\fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2b.pdf}} \\ +\end{tabular} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +Wrapping in {\tt test1}: +\begin{columns} +\column[t]{5cm} +\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1b.pdf}}\vss} +\column[t]{6cm} +\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +techmap -map macc_xilinx_wrap_map.v + +connwrappers -unsigned $__mul_wrapper \ + Y Y_WIDTH \ + -unsigned $__add_wrapper \ + Y Y_WIDTH ;; +\end{lstlisting} +\end{columns} + +\vskip1cm +\hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1c.pdf} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +Wrapping in {\tt test2}: +\begin{columns} +\column[t]{5cm} +\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2b.pdf}}\vss} +\column[t]{6cm} +\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +techmap -map macc_xilinx_wrap_map.v + +connwrappers -unsigned $__mul_wrapper \ + Y Y_WIDTH \ + -unsigned $__add_wrapper \ + Y Y_WIDTH ;; +\end{lstlisting} +\end{columns} + +\vskip1cm +\hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2c.pdf} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +Extract in {\tt test1}: +\begin{columns} +\column[t]{4.5cm} +\vbox to 0cm{ +\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +design -push +read_verilog macc_xilinx_xmap.v +techmap -map macc_xilinx_swap_map.v +techmap -map macc_xilinx_wrap_map.v;; +design -save __macc_xilinx_xmap +design -pop +\end{lstlisting} +\vss} +\column[t]{5.5cm} +\vskip-1cm +\begin{lstlisting}[linewidth=5.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +extract -constports -ignore_parameters \ + -map %__macc_xilinx_xmap \ + -swap $__add_wrapper A,B ;; +\end{lstlisting} +\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1c.pdf}}\vss} +\end{columns} + +\vskip2cm +\hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1d.pdf} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +Extract in {\tt test2}: +\begin{columns} +\column[t]{4.5cm} +\vbox to 0cm{ +\begin{lstlisting}[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +design -push +read_verilog macc_xilinx_xmap.v +techmap -map macc_xilinx_swap_map.v +techmap -map macc_xilinx_wrap_map.v;; +design -save __macc_xilinx_xmap +design -pop +\end{lstlisting} +\vss} +\column[t]{5.5cm} +\vskip-1cm +\begin{lstlisting}[linewidth=5.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +extract -constports -ignore_parameters \ + -map %__macc_xilinx_xmap \ + -swap $__add_wrapper A,B ;; +\end{lstlisting} +\vbox to 0cm{\fbox{\includegraphics[width=4.5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2c.pdf}}\vss} +\end{columns} + +\vskip2cm +\hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +Unwrap in {\tt test2}: + +\hfil\begin{tikzpicture} +\node at (1,-1.7) {\begin{lstlisting}[linewidth=5.5cm, frame=single, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +techmap -map macc_xilinx_unwrap_map.v ;; +\end{lstlisting}}; +\node at (0,0) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf}}; +\node at (0,-4) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2e.pdf}}; +\draw[-latex] (4,-0.7) .. controls (5,-1.7) .. (4,-2.7); +\end{tikzpicture} +\end{frame} + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Automatic design changes} diff --git a/manual/PRESENTATION_ExAdv/Makefile b/manual/PRESENTATION_ExAdv/Makefile index 60da3169..993a9d9e 100644 --- a/manual/PRESENTATION_ExAdv/Makefile +++ b/manual/PRESENTATION_ExAdv/Makefile @@ -1,6 +1,6 @@ all: select.pdf red_or3x1.pdf sym_mul.pdf mymul.pdf mulshift.pdf addshift.pdf \ - macc_simple_xmap.pdf + macc_simple_xmap.pdf macc_xilinx_xmap.pdf select.pdf: select.v select.ys ../../yosys select.ys @@ -23,3 +23,6 @@ addshift.pdf: addshift_* macc_simple_xmap.pdf: macc_simple_*.v macc_simple_test.ys ../../yosys macc_simple_test.ys +macc_xilinx_xmap.pdf: macc_xilinx_*.v macc_xilinx_test.ys + ../../yosys macc_xilinx_test.ys + diff --git a/manual/PRESENTATION_ExAdv/macc_simple_test.ys b/manual/PRESENTATION_ExAdv/macc_simple_test.ys index d5b01237..8d106a28 100644 --- a/manual/PRESENTATION_ExAdv/macc_simple_test.ys +++ b/manual/PRESENTATION_ExAdv/macc_simple_test.ys @@ -8,6 +8,7 @@ show -prefix macc_simple_test_00b -format pdf -notitle -lib macc_simple_xmap.v ################################################# +design -reset read_verilog macc_simple_test_01.v hierarchy -check -top test;; diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.v b/manual/PRESENTATION_ExAdv/macc_xilinx_test.v index d8fdf724..683d9d84 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_test.v +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_test.v @@ -1,13 +1,13 @@ module test1(a, b, c, d, e, f, y); -input [19:0] a, b, c; -input [15:0] d, e, f; -output [41:0] y; -assign y = a*b + c*d + e*f; + input [19:0] a, b, c; + input [15:0] d, e, f; + output [41:0] y; + assign y = a*b + c*d + e*f; endmodule module test2(a, b, c, d, e, f, y); -input [19:0] a, b, c; -input [15:0] d, e, f; -output [41:0] y; -assign y = a*b + (c*d + e*f); + input [19:0] a, b, c; + input [15:0] d, e, f; + output [41:0] y; + assign y = a*b + (c*d + e*f); endmodule diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys index 85c4a24f..3f7893fa 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys @@ -3,21 +3,21 @@ read_verilog -lib -icells macc_xilinx_unwrap_map.v read_verilog -lib -icells macc_xilinx_xmap.v hierarchy -check ;; -show -prefix macc_xilinx_test1_a -format pdf -notitle test1 -show -prefix macc_xilinx_test2_a -format pdf -notitle test2 +show -prefix macc_xilinx_test1a -format pdf -notitle test1 +show -prefix macc_xilinx_test2a -format pdf -notitle test2 techmap -map macc_xilinx_swap_map.v;; -show -prefix macc_xilinx_test1_b -format pdf -notitle test1 -show -prefix macc_xilinx_test2_b -format pdf -notitle test2 +show -prefix macc_xilinx_test1b -format pdf -notitle test1 +show -prefix macc_xilinx_test2b -format pdf -notitle test2 techmap -map macc_xilinx_wrap_map.v connwrappers -unsigned $__mul_wrapper Y Y_WIDTH \ -unsigned $__add_wrapper Y Y_WIDTH;; -show -prefix macc_xilinx_test1_c -format pdf -notitle test1 -show -prefix macc_xilinx_test2_c -format pdf -notitle test2 +show -prefix macc_xilinx_test1c -format pdf -notitle test1 +show -prefix macc_xilinx_test2c -format pdf -notitle test2 design -push read_verilog macc_xilinx_xmap.v @@ -30,11 +30,14 @@ extract -constports -ignore_parameters \ -map %__macc_xilinx_xmap \ -swap $__add_wrapper A,B ;; -show -prefix macc_xilinx_test1_d -format pdf -notitle test1 -show -prefix macc_xilinx_test2_d -format pdf -notitle test2 +show -prefix macc_xilinx_test1d -format pdf -notitle test1 +show -prefix macc_xilinx_test2d -format pdf -notitle test2 techmap -map macc_xilinx_unwrap_map.v;; -show -prefix macc_xilinx_test1_e -format pdf -notitle test1 -show -prefix macc_xilinx_test2_e -format pdf -notitle test2 +show -prefix macc_xilinx_test1e -format pdf -notitle test1 +show -prefix macc_xilinx_test2e -format pdf -notitle test2 + +design -load +show -prefix macc_xilinx_xmap -format pdf -notitle From 79f8944811cba40ca0f3bda98ab951395d24fa0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 10:40:15 +0100 Subject: [PATCH 058/750] Renamed "write_blif -subckt" to "write_blif -icells" and added -gates and -param --- backends/blif/blif.cc | 82 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index f5a98276..1c06fe51 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -31,14 +31,16 @@ struct BlifDumperConfig { - bool subckt_mode; + bool icells_mode; bool conn_mode; bool impltf_mode; + bool gates_mode; + bool param_mode; std::string buf_type, buf_in, buf_out; std::string true_type, true_out, false_type, false_out; - BlifDumperConfig() : subckt_mode(false), conn_mode(false), impltf_mode(false) { } + BlifDumperConfig() : icells_mode(false), conn_mode(false), impltf_mode(false), gates_mode(false), param_mode(false) { } }; struct BlifDumper @@ -86,6 +88,17 @@ struct BlifDumper return cstr_buf.back().c_str(); } + const char *subckt_or_gate(std::string cell_type) + { + if (!config->gates_mode) + return "subckt"; + if (!design->modules.count(RTLIL::escape_id(cell_type))) + return "gate"; + if (design->modules.at(RTLIL::escape_id(cell_type))->get_bool_attribute("\\blackbox")) + return "gate"; + return "subckt"; + } + void dump() { fprintf(f, "\n"); @@ -119,11 +132,13 @@ struct BlifDumper if (!config->impltf_mode) { if (!config->false_type.empty()) - fprintf(f, ".subckt %s %s=$false\n", config->false_type.c_str(), config->false_out.c_str()); + fprintf(f, ".%s %s %s=$false\n", subckt_or_gate(config->false_type), + config->false_type.c_str(), config->false_out.c_str()); else fprintf(f, ".names $false\n"); if (!config->true_type.empty()) - fprintf(f, ".subckt %s %s=$true\n", config->true_type.c_str(), config->true_out.c_str()); + fprintf(f, ".%s %s %s=$true\n", subckt_or_gate(config->true_type), + config->true_type.c_str(), config->true_out.c_str()); else fprintf(f, ".names $true\n1\n"); } @@ -132,50 +147,50 @@ struct BlifDumper { RTLIL::Cell *cell = cell_it.second; - if (!config->subckt_mode && cell->type == "$_INV_") { + if (!config->icells_mode && cell->type == "$_INV_") { fprintf(f, ".names %s %s\n0 1\n", cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\Y"))); continue; } - if (!config->subckt_mode && cell->type == "$_AND_") { + if (!config->icells_mode && cell->type == "$_AND_") { fprintf(f, ".names %s %s %s\n11 1\n", cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y"))); continue; } - if (!config->subckt_mode && cell->type == "$_OR_") { + if (!config->icells_mode && cell->type == "$_OR_") { fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n", cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y"))); continue; } - if (!config->subckt_mode && cell->type == "$_XOR_") { + if (!config->icells_mode && cell->type == "$_XOR_") { fprintf(f, ".names %s %s %s\n10 1\n01 1\n", cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y"))); continue; } - if (!config->subckt_mode && cell->type == "$_MUX_") { + if (!config->icells_mode && cell->type == "$_MUX_") { fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n", cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\S")), cstr(cell->connections.at("\\Y"))); continue; } - if (!config->subckt_mode && cell->type == "$_DFF_N_") { + if (!config->icells_mode && cell->type == "$_DFF_N_") { fprintf(f, ".latch %s %s fe %s\n", cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C"))); continue; } - if (!config->subckt_mode && cell->type == "$_DFF_P_") { + if (!config->icells_mode && cell->type == "$_DFF_P_") { fprintf(f, ".latch %s %s re %s\n", cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C"))); continue; } - fprintf(f, ".subckt %s", cstr(cell->type)); + fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type)); for (auto &conn : cell->connections) for (int i = 0; i < conn.second.width; i++) { if (conn.second.width == 1) @@ -185,6 +200,24 @@ struct BlifDumper fprintf(f, "=%s", cstr(conn.second.extract(i, 1))); } fprintf(f, "\n"); + + if (config->param_mode) + for (auto ¶m : cell->parameters) { + fprintf(f, ".param %s ", RTLIL::id2cstr(param.first)); + if (param.second.flags & RTLIL::CONST_FLAG_STRING) { + std::string str = param.second.decode_string(); + fprintf(f, "\""); + for (char ch : str) + if (ch == '"' || ch == '\\') + fprintf(f, "\\%c", ch); + else if (ch < 32 || ch >= 127) + fprintf(f, "\\%03o", ch); + else + fprintf(f, "%c", ch); + fprintf(f, "\"\n"); + } else + fprintf(f, "%s\n", param.second.as_string().c_str()); + } } for (auto &conn : module->connections) @@ -192,7 +225,7 @@ struct BlifDumper if (config->conn_mode) fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); else if (!config->buf_type.empty()) - fprintf(f, ".subckt %s %s=%s %s=%s\n", config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)), + fprintf(f, ".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)), config->buf_out.c_str(), cstr(conn.first.extract(i, 1))); else fprintf(f, ".names %s %s\n1 1\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); @@ -232,14 +265,21 @@ struct BlifBackend : public Backend { log("read by a BLIF parser but a custom tool. It is recommended to not name the output\n"); log("file *.blif when any of this options is used.\n"); log("\n"); - log(" -subckt\n"); + log(" -icells\n"); log(" do not translate Yosys's internal gates to generic BLIF logic\n"); - log(" functions. Instead create .subckt lines for all cells.\n"); + log(" functions. Instead create .subckt or .gate lines for all cells.\n"); + log("\n"); + log(" -gates\n"); + log(" print .gate instead of .subckt lines for all cells that are not\n"); + log(" instantiations of other modules from this design.\n"); log("\n"); log(" -conn\n"); log(" do not generate buffers for connected wires. instead use the\n"); log(" non-standard .conn statement.\n"); log("\n"); + log(" -param\n"); + log(" use the non-standard .param statement to write module parameters\n"); + log("\n"); log(" -impltf\n"); log(" do not write definitions for the $true and $false wires.\n"); log("\n"); @@ -277,14 +317,22 @@ struct BlifBackend : public Backend { config.false_out = args[++argidx]; continue; } - if (args[argidx] == "-subckt") { - config.subckt_mode = true; + if (args[argidx] == "-icells") { + config.icells_mode = true; + continue; + } + if (args[argidx] == "-gates") { + config.gates_mode = true; continue; } if (args[argidx] == "-conn") { config.conn_mode = true; continue; } + if (args[argidx] == "-param") { + config.param_mode = true; + continue; + } if (args[argidx] == "-impltf") { config.impltf_mode = true; continue; From 81b3f52519d388f252405fa7cc7472ca9e51bc49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 12:06:40 +0100 Subject: [PATCH 059/750] Added tests/techmap/mem_simple_4x1 --- Makefile | 1 + tests/techmap/.gitignore | 1 + tests/techmap/mem_simple_4x1_cells.v | 13 +++ tests/techmap/mem_simple_4x1_map.v | 129 ++++++++++++++++++++++++ tests/techmap/mem_simple_4x1_runtest.sh | 17 ++++ tests/techmap/mem_simple_4x1_tb.v | 29 ++++++ tests/techmap/mem_simple_4x1_uut.v | 15 +++ tests/techmap/run-test.sh | 10 ++ 8 files changed, 215 insertions(+) create mode 100644 tests/techmap/.gitignore create mode 100644 tests/techmap/mem_simple_4x1_cells.v create mode 100644 tests/techmap/mem_simple_4x1_map.v create mode 100644 tests/techmap/mem_simple_4x1_runtest.sh create mode 100644 tests/techmap/mem_simple_4x1_tb.v create mode 100644 tests/techmap/mem_simple_4x1_uut.v create mode 100755 tests/techmap/run-test.sh diff --git a/Makefile b/Makefile index 730a5355..85b45577 100644 --- a/Makefile +++ b/Makefile @@ -138,6 +138,7 @@ test: yosys cd tests/simple && bash run-test.sh cd tests/hana && bash run-test.sh cd tests/asicworld && bash run-test.sh + cd tests/techmap && bash run-test.sh cd tests/sat && bash run-test.sh install: $(TARGETS) $(EXTRA_TARGETS) diff --git a/tests/techmap/.gitignore b/tests/techmap/.gitignore new file mode 100644 index 00000000..397b4a76 --- /dev/null +++ b/tests/techmap/.gitignore @@ -0,0 +1 @@ +*.log diff --git a/tests/techmap/mem_simple_4x1_cells.v b/tests/techmap/mem_simple_4x1_cells.v new file mode 100644 index 00000000..7ecdd2de --- /dev/null +++ b/tests/techmap/mem_simple_4x1_cells.v @@ -0,0 +1,13 @@ +module MEM4X1 (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); + input CLK, WR_DATA, WR_EN; + input [3:0] RD_ADDR, WR_ADDR; + output reg RD_DATA; + + reg [15:0] memory; + + always @(posedge CLK) begin + if (WR_EN) + memory[WR_ADDR] <= WR_DATA; + RD_DATA <= memory[RD_ADDR]; + end +endmodule diff --git a/tests/techmap/mem_simple_4x1_map.v b/tests/techmap/mem_simple_4x1_map.v new file mode 100644 index 00000000..d207cc1b --- /dev/null +++ b/tests/techmap/mem_simple_4x1_map.v @@ -0,0 +1,129 @@ + +module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); + parameter MEMID = ""; + parameter SIZE = 256; + parameter OFFSET = 0; + parameter ABITS = 8; + parameter WIDTH = 8; + + parameter RD_PORTS = 1; + parameter RD_CLK_ENABLE = 1'b1; + parameter RD_CLK_POLARITY = 1'b1; + parameter RD_TRANSPARENT = 1'b1; + + parameter WR_PORTS = 1; + parameter WR_CLK_ENABLE = 1'b1; + parameter WR_CLK_POLARITY = 1'b1; + + input [RD_PORTS-1:0] RD_CLK; + input [RD_PORTS*ABITS-1:0] RD_ADDR; + output reg [RD_PORTS*WIDTH-1:0] RD_DATA; + + input [WR_PORTS-1:0] WR_CLK, WR_EN; + input [WR_PORTS*ABITS-1:0] WR_ADDR; + input [WR_PORTS*WIDTH-1:0] WR_DATA; + + wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + + parameter _TECHMAP_CONNMAP_RD_CLK_ = 0; + parameter _TECHMAP_CONNMAP_WR_CLK_ = 0; + + reg _TECHMAP_FAIL_; + initial begin + _TECHMAP_FAIL_ <= 0; + + // only map cells with only one read and one write port + if (RD_PORTS > 1 || WR_PORTS > 1) + _TECHMAP_FAIL_ <= 1; + + // we expect positive read clock and non-transparent reads + if (RD_TRANSPARENT || !RD_CLK_ENABLE || !RD_CLK_POLARITY) + _TECHMAP_FAIL_ <= 1; + + // we expect positive write clock + if (!WR_CLK_ENABLE || !WR_CLK_POLARITY) + _TECHMAP_FAIL_ <= 1; + + // read and write must be in same clock domain + if (_TECHMAP_CONNMAP_RD_CLK_ != _TECHMAP_CONNMAP_WR_CLK_) + _TECHMAP_FAIL_ <= 1; + + // we don't do small memories or memories with offsets + if (OFFSET != 0 || ABITS < 4 || SIZE < 16) + _TECHMAP_FAIL_ <= 1; + end + + genvar i; + generate + for (i = 0; i < WIDTH; i=i+1) begin:slice + mem_4x1_generator #( + .ABITS(ABITS), + .SIZE(SIZE) + ) bit_slice ( + .CLK(RD_CLK), + .RD_ADDR(RD_ADDR), + .RD_DATA(RD_DATA[i]), + .WR_ADDR(WR_ADDR), + .WR_DATA(WR_DATA[i]), + .WR_EN(WR_EN) + ); + end + endgenerate +endmodule + +module mem_4x1_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); + parameter ABITS = 4; + parameter SIZE = 16; + + input CLK, WR_DATA, WR_EN; + input [ABITS-1:0] RD_ADDR, WR_ADDR; + output RD_DATA; + + wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + + generate + if (ABITS > 4) begin + wire high_rd_data, low_rd_data; + if (SIZE > 2**(ABITS-1)) begin + mem_4x1_generator #( + .ABITS(ABITS-1), + .SIZE(SIZE - 2**(ABITS-1)) + ) part_high ( + .CLK(CLK), + .RD_ADDR(RD_ADDR[ABITS-2:0]), + .RD_DATA(high_rd_data), + .WR_ADDR(WR_ADDR[ABITS-2:0]), + .WR_DATA(WR_DATA), + .WR_EN(WR_EN && WR_ADDR[ABITS-1]) + ); + end else begin + assign high_rd_data = 1'bx; + end + mem_4x1_generator #( + .ABITS(ABITS-1), + .SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE) + ) part_low ( + .CLK(CLK), + .RD_ADDR(RD_ADDR[ABITS-2:0]), + .RD_DATA(low_rd_data), + .WR_ADDR(WR_ADDR[ABITS-2:0]), + .WR_DATA(WR_DATA), + .WR_EN(WR_EN && !WR_ADDR[ABITS-1]) + ); + reg delayed_abit; + always @(posedge CLK) + delayed_abit <= RD_ADDR[ABITS-1]; + assign RD_DATA = delayed_abit ? high_rd_data : low_rd_data; + end else begin + MEM4X1 _TECHMAP_REPLACE_ ( + .CLK(CLK), + .RD_ADDR(RD_ADDR), + .RD_DATA(RD_DATA), + .WR_ADDR(WR_ADDR), + .WR_DATA(WR_DATA), + .WR_EN(WR_EN) + ); + end + endgenerate +endmodule + diff --git a/tests/techmap/mem_simple_4x1_runtest.sh b/tests/techmap/mem_simple_4x1_runtest.sh new file mode 100644 index 00000000..8285875b --- /dev/null +++ b/tests/techmap/mem_simple_4x1_runtest.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -ev + +yosys -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v + +iverilog -o mem_simple_4x1_gold_tb mem_simple_4x1_tb.v mem_simple_4x1_uut.v +iverilog -o mem_simple_4x1_gate_tb mem_simple_4x1_tb.v mem_simple_4x1_synth.v mem_simple_4x1_cells.v + +./mem_simple_4x1_gold_tb > mem_simple_4x1_gold_tb.out +./mem_simple_4x1_gate_tb > mem_simple_4x1_gate_tb.out + +diff -u mem_simple_4x1_gold_tb.out mem_simple_4x1_gate_tb.out +rm -f mem_simple_4x1_synth.v mem_simple_4x1_tb.vcd +rm -f mem_simple_4x1_{gold,gate}_tb{,.out} +: OK + diff --git a/tests/techmap/mem_simple_4x1_tb.v b/tests/techmap/mem_simple_4x1_tb.v new file mode 100644 index 00000000..53262696 --- /dev/null +++ b/tests/techmap/mem_simple_4x1_tb.v @@ -0,0 +1,29 @@ +module tb; + +reg clk, rst; +wire [7:0] out; +wire [4:0] counter; + +uut uut (clk, rst, out, counter); + +initial begin + #5 clk <= 0; + repeat (100) #5 clk <= ~clk; + #5 $finish; +end + +initial begin + rst <= 1; + repeat (2) @(posedge clk); + rst <= 0; +end + +always @(posedge clk) + $display("%d %d %d", rst, out, counter); + +initial begin + $dumpfile("mem_simple_4x1_tb.vcd"); + $dumpvars(0, uut); +end + +endmodule diff --git a/tests/techmap/mem_simple_4x1_uut.v b/tests/techmap/mem_simple_4x1_uut.v new file mode 100644 index 00000000..8d461459 --- /dev/null +++ b/tests/techmap/mem_simple_4x1_uut.v @@ -0,0 +1,15 @@ +module uut (clk, rst, out, counter); + +input clk, rst; +output reg [7:0] out; +output reg [4:0] counter; + +reg [7:0] memory [0:19]; + +always @(posedge clk) begin + counter <= rst || counter == 19 ? 0 : counter+1; + memory[counter] <= counter; + out <= memory[counter]; +end + +endmodule diff --git a/tests/techmap/run-test.sh b/tests/techmap/run-test.sh new file mode 100755 index 00000000..e2fc11e5 --- /dev/null +++ b/tests/techmap/run-test.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +for x in *_runtest.sh; do + echo "Running $x.." + if ! bash $x &> ${x%.sh}.log; then + tail ${x%.sh}.log + echo ERROR + exit 1 + fi +done From 3c5e9730924e5cc1ac5769f1fadd3f1d15a2aaa3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 12:14:38 +0100 Subject: [PATCH 060/750] Use private namespace in mem_simple_4x1_map --- tests/techmap/mem_simple_4x1_map.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/techmap/mem_simple_4x1_map.v b/tests/techmap/mem_simple_4x1_map.v index d207cc1b..5f93914c 100644 --- a/tests/techmap/mem_simple_4x1_map.v +++ b/tests/techmap/mem_simple_4x1_map.v @@ -56,7 +56,7 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); genvar i; generate for (i = 0; i < WIDTH; i=i+1) begin:slice - mem_4x1_generator #( + \$__mem_4x1_generator #( .ABITS(ABITS), .SIZE(SIZE) ) bit_slice ( @@ -71,7 +71,7 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); endgenerate endmodule -module mem_4x1_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); +module \$__mem_4x1_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); parameter ABITS = 4; parameter SIZE = 16; @@ -85,7 +85,7 @@ module mem_4x1_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); if (ABITS > 4) begin wire high_rd_data, low_rd_data; if (SIZE > 2**(ABITS-1)) begin - mem_4x1_generator #( + \$__mem_4x1_generator #( .ABITS(ABITS-1), .SIZE(SIZE - 2**(ABITS-1)) ) part_high ( @@ -99,7 +99,7 @@ module mem_4x1_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); end else begin assign high_rd_data = 1'bx; end - mem_4x1_generator #( + \$__mem_4x1_generator #( .ABITS(ABITS-1), .SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE) ) part_low ( From f3ff29d4107355f5a1941da67e6402644dffefa4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 13:10:36 +0100 Subject: [PATCH 061/750] Fixed instantiating multi-bit ports in edif backend --- backends/edif/edif.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 1748ed81..5020cd67 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -303,8 +303,10 @@ struct EdifBackend : public Backend { sig.expand(); for (int i = 0; i < sig.width; i++) { RTLIL::SigSpec sigbit(sig.chunks.at(i)); - std::string portname = sig.width > 1 ? stringf("%s[%d]", RTLIL::id2cstr(p.first), i) : RTLIL::id2cstr(p.first); - net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", edif_names(portname).c_str(), EDIF_NAME(cell->name))); + if (sig.width == 1) + net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", edif_names(RTLIL::id2cstr(p.first)).c_str(), EDIF_NAME(cell->name))); + else + net_join_db[sigbit].insert(stringf("(portRef (member %s %d) (instanceRef %s))", edif_names(RTLIL::id2cstr(p.first)).c_str(), i, EDIF_NAME(cell->name))); } } } From 038eac741415c3d7ddef3a1e9348586e7ba3d4ad Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 13:40:43 +0100 Subject: [PATCH 062/750] Better handling of nameDef and nameRef in edif backend --- backends/edif/edif.cc | 48 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 5020cd67..8ac7cc7b 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -28,7 +28,8 @@ #include #include -#define EDIF_NAME(_id) edif_names(RTLIL::unescape_id(_id)).c_str() +#define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str() +#define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str() namespace { @@ -40,8 +41,13 @@ namespace EdifNames() : counter(1) { } - std::string operator()(std::string id) + std::string operator()(std::string id, bool define) { + if (define) { + std::string new_id = operator()(id, false); + return new_id != id ? stringf("(rename %s \"%s\")", new_id.c_str(), id.c_str()) : id; + } + if (name_map.count(id) > 0) return name_map.at(id); if (generated_names.count(id) > 0) @@ -74,7 +80,7 @@ namespace } generated_names.insert(gen_name); name_map[id] = gen_name; - return stringf("(rename %s \"%s\")", gen_name.c_str(), id.c_str()); + return gen_name; } }; } @@ -155,7 +161,7 @@ struct EdifBackend : public Backend { if (top_module_name.empty()) log_error("No module found in design!\n"); - fprintf(f, "(edif %s\n", EDIF_NAME(top_module_name)); + fprintf(f, "(edif %s\n", EDIF_DEF(top_module_name)); fprintf(f, " (edifVersion 2 0 0)\n"); fprintf(f, " (edifLevel 0)\n"); fprintf(f, " (keywordMap (keywordLevel 0))\n"); @@ -182,7 +188,7 @@ struct EdifBackend : public Backend { fprintf(f, " )\n"); for (auto &cell_it : lib_cell_ports) { - fprintf(f, " (cell %s\n", EDIF_NAME(cell_it.first)); + fprintf(f, " (cell %s\n", EDIF_DEF(cell_it.first)); fprintf(f, " (cellType GENERIC)\n"); fprintf(f, " (view VIEW_NETLIST\n"); fprintf(f, " (viewType NETLIST)\n"); @@ -195,7 +201,7 @@ struct EdifBackend : public Backend { else if (!ct.cell_input(cell_it.first, port_it)) dir = "OUTPUT"; } - fprintf(f, " (port %s (direction %s))\n", EDIF_NAME(port_it), dir); + fprintf(f, " (port %s (direction %s))\n", EDIF_DEF(port_it), dir); } fprintf(f, " )\n"); fprintf(f, " )\n"); @@ -244,7 +250,7 @@ struct EdifBackend : public Backend { SigMap sigmap(module); std::map> net_join_db; - fprintf(f, " (cell %s\n", EDIF_NAME(module->name)); + fprintf(f, " (cell %s\n", EDIF_DEF(module->name)); fprintf(f, " (cellType GENERIC)\n"); fprintf(f, " (view VIEW_NETLIST\n"); fprintf(f, " (viewType NETLIST)\n"); @@ -259,14 +265,14 @@ struct EdifBackend : public Backend { else if (!wire->port_input) dir = "OUTPUT"; if (wire->width == 1) { - fprintf(f, " (port %s (direction %s))\n", EDIF_NAME(wire->name), dir); + fprintf(f, " (port %s (direction %s))\n", EDIF_DEF(wire->name), dir); RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire)); - net_join_db[sig].insert(stringf("(portRef %s)", EDIF_NAME(wire->name))); + net_join_db[sig].insert(stringf("(portRef %s)", EDIF_REF(wire->name))); } else { - fprintf(f, " (port (array %s %d) (direction %s))\n", EDIF_NAME(wire->name), wire->width, dir); + fprintf(f, " (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir); for (int i = 0; i < wire->width; i++) { RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, 1, i)); - net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_NAME(wire->name), i)); + net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), i)); } } } @@ -276,14 +282,14 @@ struct EdifBackend : public Backend { fprintf(f, " (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n"); for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; - fprintf(f, " (instance %s\n", EDIF_NAME(cell->name)); - fprintf(f, " (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_NAME(cell->type), + fprintf(f, " (instance %s\n", EDIF_DEF(cell->name)); + fprintf(f, " (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type), lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : ""); for (auto &p : cell->parameters) if ((p.second.flags & RTLIL::CONST_FLAG_STRING) != 0) - fprintf(f, "\n (property %s (string \"%s\"))", EDIF_NAME(p.first), p.second.decode_string().c_str()); + fprintf(f, "\n (property %s (string \"%s\"))", EDIF_DEF(p.first), p.second.decode_string().c_str()); else if (p.second.bits.size() <= 32 && RTLIL::SigSpec(p.second).is_fully_def()) - fprintf(f, "\n (property %s (integer %u))", EDIF_NAME(p.first), p.second.as_int()); + fprintf(f, "\n (property %s (integer %u))", EDIF_DEF(p.first), p.second.as_int()); else { std::string hex_string = ""; for (size_t i = 0; i < p.second.bits.size(); i += 4) { @@ -295,7 +301,7 @@ struct EdifBackend : public Backend { char digit_str[2] = { "0123456789abcdef"[digit_value], 0 }; hex_string = std::string(digit_str) + hex_string; } - fprintf(f, "\n (property %s (string \"%s\"))", EDIF_NAME(p.first), hex_string.c_str()); + fprintf(f, "\n (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str()); } fprintf(f, ")\n"); for (auto &p : cell->connections) { @@ -304,9 +310,9 @@ struct EdifBackend : public Backend { for (int i = 0; i < sig.width; i++) { RTLIL::SigSpec sigbit(sig.chunks.at(i)); if (sig.width == 1) - net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", edif_names(RTLIL::id2cstr(p.first)).c_str(), EDIF_NAME(cell->name))); + net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name))); else - net_join_db[sigbit].insert(stringf("(portRef (member %s %d) (instanceRef %s))", edif_names(RTLIL::id2cstr(p.first)).c_str(), i, EDIF_NAME(cell->name))); + net_join_db[sigbit].insert(stringf("(portRef (member %s %d) (instanceRef %s))", EDIF_REF(p.first), i, EDIF_REF(cell->name))); } } } @@ -322,7 +328,7 @@ struct EdifBackend : public Backend { for (size_t i = 0; i < netname.size(); i++) if (netname[i] == ' ' || netname[i] == '\\') netname.erase(netname.begin() + i--); - fprintf(f, " (net %s (joined\n", edif_names(netname).c_str()); + fprintf(f, " (net %s (joined\n", EDIF_DEF(netname)); for (auto &ref : it.second) fprintf(f, " %s\n", ref.c_str()); if (sig.chunks.at(0).wire == NULL) { @@ -339,8 +345,8 @@ struct EdifBackend : public Backend { } fprintf(f, " )\n"); - fprintf(f, " (design %s\n", EDIF_NAME(top_module_name)); - fprintf(f, " (cellRef %s (libraryRef DESIGN))\n", EDIF_NAME(top_module_name)); + fprintf(f, " (design %s\n", EDIF_DEF(top_module_name)); + fprintf(f, " (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name)); fprintf(f, " )\n"); fprintf(f, ")\n"); From 79edcd4318590974ef49b2d5f561382eea3454bf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 14:59:59 +0100 Subject: [PATCH 063/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 117 +++++++++++++++--- .../PRESENTATION_ExAdv/macc_xilinx_swap_map.v | 4 +- manual/PRESENTATION_ExAdv/macc_xilinx_test.ys | 2 +- .../macc_xilinx_unwrap_map.v | 6 +- .../PRESENTATION_ExAdv/macc_xilinx_wrap_map.v | 12 +- manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v | 4 +- 6 files changed, 113 insertions(+), 32 deletions(-) diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index f2080922..bf9b350f 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -491,15 +491,13 @@ For example: \end{lstlisting} This circuit contains two cells in the RTL representation: one multiplier and -one adder. - -\medskip -Coarse grain synthesis is mapping this circuit to a single multiply-add cell -of the target architecture, for example using an FPGA DSP core. +one adder. In some architectures this circuit can be implemented using +a single circuit element, for example an FPGA DSP core. Coarse grain synthesis +is this mapping of groups of circuit elements to larger components. \bigskip -Fine-grain synthesis would be matching the circuit to smaller elements, such -as LUTs, gates, or half- and full-adders. +Fine-grain synthesis would be matching the circuit elements to smaller +components, such as LUTs, gates, or half- and full-adders. \end{frame} \subsubsection{The extract pass} @@ -558,12 +556,101 @@ $\downarrow$ & $\downarrow$ \\ \subsubsection{The wrap-extract-unwrap method} \begin{frame}{\subsubsecname} -TBD +\scriptsize +Often a coarse-grain element has a constant bit-width, but can be used to +implement oprations with a smaller bit-width. For example, a 18x25-bit multiplier +can also be used to implement 16x20-bit multiplication. + +\bigskip +A way of mapping such elements in coarse grain synthesis is the wrap-extract-unwrap method: + +\begin{itemize} +\item {\bf wrap} \\ +Identify candidate-cells in the circuit and wrap them in a cell with a constant +wider bit-width using {\tt techmap}. The wrappers use the same parameters as the original cell, so +the information about the original width of the ports is preserved. \\ +Then use the {\tt connwrappers} command to connect up the bit-extended in- and +outputs of the wrapper cells. +\item {\bf extract} \\ +Now all operations are encoded using the same bit-width as the coarse grain element. The {\tt +extract} command can be used to replace circuits with cells of the target architecture. +\item {\bf unwrap} \\ +The remaining wrapper cell can be unwrapped using {\tt techmap}. +\end{itemize} + +\bigskip +The following sides detail an example that shows how to map MACC operations of +arbitrary size to MACC cells with a 18x25-bit multiplier and a 48-bit adder (such as +the Xilinx DSP48 cells). \end{frame} \subsubsection{Example: DSP48\_MACC} -\begin{frame}[fragile]{\subsubsecname{} -- ?/?} +\begin{frame}[t, fragile]{\subsubsecname{} -- 1/13} +Preconditioning: {\tt macc\_xilinx\_swap\_map.v} \\ +Make sure {\tt A} is the smaller port on all multipliers + +\begin{columns} +\column{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=15]{PRESENTATION_ExAdv/macc_xilinx_swap_map.v} +\column{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=16]{PRESENTATION_ExAdv/macc_xilinx_swap_map.v} +\end{columns} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- 2/13} +Wrapping multipliers: {\tt macc\_xilinx\_wrap\_map.v} + +\begin{columns} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, lastline=23]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=24, lastline=46]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} +\end{columns} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- 3/13} +Wrapping adders: {\tt macc\_xilinx\_wrap\_map.v} + +\begin{columns} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=48, lastline=67]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=68, lastline=89]{PRESENTATION_ExAdv/macc_xilinx_wrap_map.v} +\end{columns} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- 4/13} +Extract: {\tt macc\_xilinx\_xmap.v} + +\lstinputlisting[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=1, lastline=17]{PRESENTATION_ExAdv/macc_xilinx_xmap.v} + +.. simply use the same wrapping commands on this module as on the design to create a template for the {\tt extract} command. +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- 5/13} +Unwrapping multipliers: {\tt macc\_xilinx\_unwrap\_map.v} + +\begin{columns} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=1, lastline=17]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=18, lastline=30]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} +\end{columns} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname{} -- 6/13} +Unwrapping adders: {\tt macc\_xilinx\_unwrap\_map.v} + +\begin{columns} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=32, lastline=48]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{7pt}{8pt}\selectfont, language=verilog, firstline=49, lastline=61]{PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v} +\end{columns} +\end{frame} + +\begin{frame}[fragile]{\subsubsecname{} -- 7/13} \hfil\begin{tabular}{cc} {\tt test1} & {\tt test2} \\ \fbox{\hbox to 5cm {\lstinputlisting[linewidth=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, firstline=1, lastline=6, language=verilog]{PRESENTATION_ExAdv/macc_xilinx_test.v}}} & @@ -583,7 +670,7 @@ $\downarrow$ & $\downarrow$ \\ \end{tabular} \end{frame} -\begin{frame}[fragile]{\subsubsecname{} -- ?/?} +\begin{frame}[fragile]{\subsubsecname{} -- 8/13} \hfil\begin{tabular}{cc} {\tt test1} & {\tt test2} \\ \fbox{\includegraphics[width=5cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1a.pdf}} & @@ -602,7 +689,7 @@ $\downarrow$ & $\downarrow$ \\ \end{tabular} \end{frame} -\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +\begin{frame}[t, fragile]{\subsubsecname{} -- 9/13} Wrapping in {\tt test1}: \begin{columns} \column[t]{5cm} @@ -622,7 +709,7 @@ connwrappers -unsigned $__mul_wrapper \ \hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1c.pdf} \end{frame} -\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +\begin{frame}[t, fragile]{\subsubsecname{} -- 10/13} Wrapping in {\tt test2}: \begin{columns} \column[t]{5cm} @@ -642,7 +729,7 @@ connwrappers -unsigned $__mul_wrapper \ \hfil\includegraphics[width=\linewidth,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2c.pdf} \end{frame} -\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +\begin{frame}[t, fragile]{\subsubsecname{} -- 11/13} Extract in {\tt test1}: \begin{columns} \column[t]{4.5cm} @@ -670,7 +757,7 @@ extract -constports -ignore_parameters \ \hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test1d.pdf} \end{frame} -\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +\begin{frame}[t, fragile]{\subsubsecname{} -- 12/13} Extract in {\tt test2}: \begin{columns} \column[t]{4.5cm} @@ -698,7 +785,7 @@ extract -constports -ignore_parameters \ \hfil\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf} \end{frame} -\begin{frame}[t, fragile]{\subsubsecname{} -- ?/?} +\begin{frame}[t, fragile]{\subsubsecname{} -- 13/13} Unwrap in {\tt test2}: \hfil\begin{tikzpicture} diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v b/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v index 1f4867d1..e3696722 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v @@ -1,4 +1,3 @@ - (* techmap_celltype = "$mul" *) module mul_swap_ports (A, B, Y); @@ -12,7 +11,7 @@ input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; -wire _TECHMAP_FAIL_ = A_WIDTH >= B_WIDTH; +wire _TECHMAP_FAIL_ = A_WIDTH <= B_WIDTH; \$mul #( .A_SIGNED(B_SIGNED), @@ -27,4 +26,3 @@ wire _TECHMAP_FAIL_ = A_WIDTH >= B_WIDTH; ); endmodule - diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys index 3f7893fa..f3e8af4f 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_test.ys @@ -38,6 +38,6 @@ techmap -map macc_xilinx_unwrap_map.v;; show -prefix macc_xilinx_test1e -format pdf -notitle test1 show -prefix macc_xilinx_test2e -format pdf -notitle test2 -design -load +design -load __macc_xilinx_xmap show -prefix macc_xilinx_xmap -format pdf -notitle diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v b/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v index a80538d5..9dfaef13 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v @@ -1,4 +1,3 @@ - module \$__mul_wrapper (A, B, Y); parameter A_SIGNED = 0; @@ -7,8 +6,8 @@ parameter A_WIDTH = 1; parameter B_WIDTH = 1; parameter Y_WIDTH = 1; -input [24:0] A; -input [17:0] B; +input [17:0] A; +input [24:0] B; output [47:0] Y; wire [A_WIDTH-1:0] A_ORIG = A; @@ -60,4 +59,3 @@ assign Y = Y_ORIG; ); endmodule - diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v b/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v index d1ded295..f23f6c02 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_wrap_map.v @@ -1,4 +1,3 @@ - (* techmap_celltype = "$mul" *) module mul_wrap (A, B, Y); @@ -12,8 +11,8 @@ input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; -wire [24:0] A_25 = A; -wire [17:0] B_18 = B; +wire [17:0] A_18 = A; +wire [24:0] B_25 = B; wire [47:0] Y_48; assign Y = Y_48; @@ -26,7 +25,7 @@ initial begin _TECHMAP_FAIL_ <= 1; if (A_WIDTH < 4 || B_WIDTH < 4) _TECHMAP_FAIL_ <= 1; - if (A_WIDTH > 25 || B_WIDTH > 18) + if (A_WIDTH > 18 || B_WIDTH > 25) _TECHMAP_FAIL_ <= 1; if (A_WIDTH*B_WIDTH < 100) _TECHMAP_FAIL_ <= 1; @@ -39,8 +38,8 @@ end .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH) ) _TECHMAP_REPLACE_ ( - .A(A_25), - .B(B_18), + .A(A_18), + .B(B_25), .Y(Y_48) ); @@ -88,4 +87,3 @@ end ); endmodule - diff --git a/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v b/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v index 15bd04ed..06372f5a 100644 --- a/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v +++ b/manual/PRESENTATION_ExAdv/macc_xilinx_xmap.v @@ -1,7 +1,7 @@ module DSP48_MACC (a, b, c, y); -input [24:0] a; -input [17:0] b; +input [17:0] a; +input [24:0] b; input [47:0] c; output [47:0] y; From 0a60f95224376304565d950832f8320d5f4fb70e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 18:59:49 +0100 Subject: [PATCH 064/750] 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 diff --git a/frontends/vhdl2verilog/Makefile.inc b/frontends/vhdl2verilog/Makefile.inc new file mode 100644 index 00000000..003d89c4 --- /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 00000000..9e9953ce --- /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; + From 8b508dc90b87c99e13f1fa9f8e79e48c7fa52e90 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 23:34:45 +0100 Subject: [PATCH 065/750] Added workaround for vhdl-style edge triggers from vhdl2verilog to proc_arst --- passes/proc/proc_arst.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 57194657..057378e7 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -156,8 +156,12 @@ restart_proc_arst: if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) { bool polarity = sync->type == RTLIL::SyncType::STp; if (check_signal(mod, root_sig, sync->signal, polarity)) { - log("Found async reset %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str()); - sync->type = sync->type == RTLIL::SyncType::STp ? RTLIL::SyncType::ST1 : RTLIL::SyncType::ST0; + if (proc->syncs.size() == 1) { + log("Found VHDL-style edge-trigger %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str()); + } else { + log("Found async reset %s in `%s.%s'.\n", log_signal(sync->signal), mod->name.c_str(), proc->name.c_str()); + sync->type = sync->type == RTLIL::SyncType::STp ? RTLIL::SyncType::ST1 : RTLIL::SyncType::ST0; + } for (auto &action : sync->actions) { RTLIL::SigSpec rspec = action.second; RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.width); From 1ec01d8c637e611eddd16a492d1eb0f652b95da0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 01:29:02 +0100 Subject: [PATCH 066/750] Made MiniSat solver backend configurable in ezminisat.h --- libs/ezsat/ezminisat.cc | 7 +++++-- libs/ezsat/ezminisat.h | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index d545834c..4d3301c4 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -29,6 +29,7 @@ #include #include +#include ezMiniSAT::ezMiniSAT() : minisatSolver(NULL) { @@ -90,8 +91,10 @@ contradiction: for (auto id : modelExpressions) modelIdx.push_back(bind(id)); - if (minisatSolver == NULL) - minisatSolver = new Minisat::Solver; + if (minisatSolver == NULL) { + minisatSolver = new EZMINISAT_SOLVER; + minisatSolver->verbosity = EZMINISAT_VERBOSITY; + } std::vector> cnf; consumeCnf(cnf); diff --git a/libs/ezsat/ezminisat.h b/libs/ezsat/ezminisat.h index 2919aa2e..04a010d6 100644 --- a/libs/ezsat/ezminisat.h +++ b/libs/ezsat/ezminisat.h @@ -20,6 +20,9 @@ #ifndef EZMINISAT_H #define EZMINISAT_H +#define EZMINISAT_SOLVER Minisat::Solver +#define EZMINISAT_VERBOSITY 0 + #include "ezsat.h" #include @@ -28,12 +31,13 @@ // don't force ezSAT users to use minisat headers.. namespace Minisat { class Solver; + class SimpSolver; } class ezMiniSAT : public ezSAT { private: - Minisat::Solver *minisatSolver; + EZMINISAT_SOLVER *minisatSolver; std::vector minisatVars; bool foundContradiction; From 357f3f6e93df1ebf2aa28a6c433a84f320fad043 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 11:34:31 +0100 Subject: [PATCH 067/750] Added ezMiniSat EZMINISAT_INCREMENTAL compile-time option --- libs/ezsat/ezminisat.cc | 17 ++++++++++++++++- libs/ezsat/ezminisat.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 4d3301c4..a1cb8052 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -96,8 +96,12 @@ contradiction: minisatSolver->verbosity = EZMINISAT_VERBOSITY; } +#if EZMINISAT_INCREMENTAL std::vector> cnf; consumeCnf(cnf); +#else + const std::vector> &cnf = this->cnf(); +#endif while (int(minisatVars.size()) < numCnfVariables()) minisatVars.push_back(minisatSolver->newVar()); @@ -145,8 +149,14 @@ contradiction: alarm(old_alarm_timeout); } - if (!foundSolution) + if (!foundSolution) { +#if !EZMINISAT_INCREMENTAL + delete minisatSolver; + minisatSolver = NULL; + minisatVars.clear(); +#endif return false; + } modelValues.clear(); modelValues.resize(modelIdx.size()); @@ -164,6 +174,11 @@ contradiction: modelValues[i] = (value == Minisat::lbool(refvalue)); } +#if !EZMINISAT_INCREMENTAL + delete minisatSolver; + minisatSolver = NULL; + minisatVars.clear(); +#endif return true; } diff --git a/libs/ezsat/ezminisat.h b/libs/ezsat/ezminisat.h index 04a010d6..59fa2134 100644 --- a/libs/ezsat/ezminisat.h +++ b/libs/ezsat/ezminisat.h @@ -22,6 +22,7 @@ #define EZMINISAT_SOLVER Minisat::Solver #define EZMINISAT_VERBOSITY 0 +#define EZMINISAT_INCREMENTAL 1 #include "ezsat.h" #include From 337b461d26f3cdc34f4a2b6c49d61427ef10ef96 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 14:25:32 +0100 Subject: [PATCH 068/750] Added $lut support to blif backend (by user eddiehung from reddit) --- backends/blif/blif.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 1c06fe51..498f1351 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -190,6 +190,29 @@ struct BlifDumper continue; } + if (!config->icells_mode && cell->type == "$lut") { + fprintf(f, ".names"); + auto &inputs = cell->connections.at("\\I"); + auto width = cell->parameters.at("\\WIDTH").as_int(); + log_assert(inputs.width == width); + for (int i = 0; i < inputs.width; i++) { + fprintf(f, " %s", cstr(inputs.extract(i, 1))); + } + auto &output = cell->connections.at("\\O"); + log_assert(output.width == 1); + fprintf(f, " %s", cstr(output)); + fprintf(f, "\n"); + auto mask = cell->parameters.at("\\LUT").as_string(); + for (int i = 0; i < (1 << width); i++) { + if (mask[i] == '0') continue; + for (int j = width-1; j >= 0; j--) { + fputc((i>>j)&1 ? '1' : '0', f); + } + fprintf(f, " %c\n", mask[i]); + } + continue; + } + fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type)); for (auto &conn : cell->connections) for (int i = 0; i < conn.second.width; i++) { From 548519875bbffda02c5c7a891ce67fd3738d6e6f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 17:07:22 +0100 Subject: [PATCH 069/750] Fixed bug (typo) in passes/opt/opt_const.cc --- passes/opt/opt_const.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index f611d721..ad9a71b1 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -342,7 +342,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons cell->parameters.erase("\\WIDTH"); cell->type = "$or"; } else - cell->type = "$_or_"; + cell->type = "$_OR_"; OPT_DID_SOMETHING = true; did_something = true; goto next_cell; From f8c9143b2b232e2f22e6cfbf9c431b2a1b756afa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 17:08:00 +0100 Subject: [PATCH 070/750] Fixed bug in generation of undefs for $memwr MUXes --- frontends/ast/simplify.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5e37911d..55ed28b0 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)); From b76528d8a557dc324b1dfaa366e2b620795f582d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 23 Feb 2014 01:28:29 +0100 Subject: [PATCH 071/750] Fixed small memory leak in Pass::call() --- kernel/register.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/register.cc b/kernel/register.cc index 32570966..ee14ffba 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -133,8 +133,10 @@ void Pass::call(RTLIL::Design *design, std::string command) std::vector args; char *s = strdup(command.c_str()), *sstart = s, *saveptr; s += strspn(s, " \t\r\n"); - if (*s == 0 || *s == '#') + if (*s == 0 || *s == '#') { + free(sstart); return; + } if (*s == '!') { for (s++; *s == ' ' || *s == '\t'; s++) { } char *p = s + strlen(s) - 1; @@ -144,6 +146,7 @@ void Pass::call(RTLIL::Design *design, std::string command) int retCode = system(s); if (retCode != 0) log_cmd_error("Shell command returned error code %d.\n", retCode); + free(sstart); return; } for (char *p = strtok_r(s, " \t\r\n", &saveptr); p; p = strtok_r(NULL, " \t\r\n", &saveptr)) { From dab1612f81212d1bc1c07ee77b265167861ec883 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 23 Feb 2014 01:35:59 +0100 Subject: [PATCH 072/750] Added support for Minisat::SimpSolver + ezSAT frezze() API --- kernel/satgen.h | 1 + libs/ezsat/ezminisat.cc | 37 ++++++++++++++++++++++++++++++++++--- libs/ezsat/ezminisat.h | 16 ++++++++++++++-- libs/ezsat/ezsat.cc | 33 +++++++++++++++++++++++++++------ libs/ezsat/ezsat.h | 3 +++ 5 files changed, 79 insertions(+), 11 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index 840700cb..53921044 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -72,6 +72,7 @@ struct SatGen } else { std::string name = pf + stringf(c.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(c.wire->name), c.offset); vec.push_back(ez->literal(name)); + ez->freeze(vec.back()); } return vec; } diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index a1cb8052..c6126d86 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -51,9 +51,19 @@ void ezMiniSAT::clear() } foundContradiction = false; minisatVars.clear(); +#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL + cnfFrozenVars.clear(); +#endif ezSAT::clear(); } +#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL +void ezMiniSAT::freeze(int id) +{ + cnfFrozenVars.insert(bind(id)); +} +#endif + ezMiniSAT *ezMiniSAT::alarmHandlerThis = NULL; clock_t ezMiniSAT::alarmHandlerTimeout = 0; @@ -92,7 +102,7 @@ contradiction: modelIdx.push_back(bind(id)); if (minisatSolver == NULL) { - minisatSolver = new EZMINISAT_SOLVER; + minisatSolver = new Solver; minisatSolver->verbosity = EZMINISAT_VERBOSITY; } @@ -106,13 +116,27 @@ contradiction: while (int(minisatVars.size()) < numCnfVariables()) minisatVars.push_back(minisatSolver->newVar()); +#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL + for (auto idx : cnfFrozenVars) + minisatSolver->setFrozen(minisatVars.at(idx > 0 ? idx-1 : -idx-1), true); + cnfFrozenVars.clear(); +#endif + for (auto &clause : cnf) { Minisat::vec ps; - for (auto idx : clause) + for (auto idx : clause) { if (idx > 0) ps.push(Minisat::mkLit(minisatVars.at(idx-1))); else ps.push(Minisat::mkLit(minisatVars.at(-idx-1), true)); +#if EZMINISAT_SIMPSOLVER + if (minisatSolver->isEliminated(minisatVars.at(idx > 0 ? idx-1 : -idx-1))) { + fprintf(stderr, "Assert in %s:%d failed! Missing call to ezsat->freeze(): %s (lit=%d)\n", + __FILE__, __LINE__, cnfLiteralInfo(idx).c_str(), idx); + abort(); + } +#endif + } if (!minisatSolver->addClause(ps)) goto contradiction; } @@ -122,11 +146,18 @@ contradiction: Minisat::vec assumps; - for (auto idx : extraClauses) + for (auto idx : extraClauses) { if (idx > 0) assumps.push(Minisat::mkLit(minisatVars.at(idx-1))); else assumps.push(Minisat::mkLit(minisatVars.at(-idx-1), true)); +#if EZMINISAT_SIMPSOLVER + if (minisatSolver->isEliminated(minisatVars.at(idx > 0 ? idx-1 : -idx-1))) { + fprintf(stderr, "Assert in %s:%d failed! Missing call to ezsat->freeze(): %s\n", __FILE__, __LINE__, cnfLiteralInfo(idx).c_str()); + abort(); + } +#endif + } sighandler_t old_alarm_sighandler = NULL; int old_alarm_timeout = 0; diff --git a/libs/ezsat/ezminisat.h b/libs/ezsat/ezminisat.h index 59fa2134..e7e08289 100644 --- a/libs/ezsat/ezminisat.h +++ b/libs/ezsat/ezminisat.h @@ -20,7 +20,7 @@ #ifndef EZMINISAT_H #define EZMINISAT_H -#define EZMINISAT_SOLVER Minisat::Solver +#define EZMINISAT_SIMPSOLVER 0 #define EZMINISAT_VERBOSITY 0 #define EZMINISAT_INCREMENTAL 1 @@ -38,10 +38,19 @@ namespace Minisat { class ezMiniSAT : public ezSAT { private: - EZMINISAT_SOLVER *minisatSolver; +#if EZMINISAT_SIMPSOLVER + typedef Minisat::SimpSolver Solver; +#else + typedef Minisat::Solver Solver; +#endif + Solver *minisatSolver; std::vector minisatVars; bool foundContradiction; +#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL + std::set cnfFrozenVars; +#endif + static ezMiniSAT *alarmHandlerThis; static clock_t alarmHandlerTimeout; static void alarmHandler(int); @@ -50,6 +59,9 @@ public: ezMiniSAT(); virtual ~ezMiniSAT(); virtual void clear(); +#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL + virtual void freeze(int id); +#endif virtual bool solver(const std::vector &modelExpressions, std::vector &modelValues, const std::vector &assumptions); }; diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 57762525..e6c005c6 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -29,18 +29,18 @@ const int ezSAT::FALSE = 2; ezSAT::ezSAT() { - literal("TRUE"); - literal("FALSE"); - - assert(literal("TRUE") == TRUE); - assert(literal("FALSE") == FALSE); - cnfConsumed = false; cnfVariableCount = 0; cnfClausesCount = 0; solverTimeout = 0; solverTimoutStatus = false; + + freeze(literal("TRUE")); + freeze(literal("FALSE")); + + assert(literal("TRUE") == TRUE); + assert(literal("FALSE") == FALSE); } ezSAT::~ezSAT() @@ -345,6 +345,10 @@ void ezSAT::clear() cnfAssumptions.clear(); } +void ezSAT::freeze(int) +{ +} + void ezSAT::assume(int id) { cnfAssumptions.insert(id); @@ -462,6 +466,23 @@ int ezSAT::bound(int id) const return 0; } +std::string ezSAT::cnfLiteralInfo(int idx) const +{ + for (size_t i = 0; i < cnfLiteralVariables.size(); i++) { + if (cnfLiteralVariables[i] == idx) + return to_string(i+1); + if (cnfLiteralVariables[i] == -idx) + return "NOT " + to_string(i+1); + } + for (size_t i = 0; i < cnfExpressionVariables.size(); i++) { + if (cnfExpressionVariables[i] == idx) + return to_string(-i-1); + if (cnfExpressionVariables[i] == -idx) + return "NOT " + to_string(-i-1); + } + return ""; +} + int ezSAT::bind(int id) { if (id >= 0) { diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 547edb93..79100b87 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -141,6 +141,7 @@ public: // manage CNF (usually only accessed by SAT solvers) virtual void clear(); + virtual void freeze(int id); void assume(int id); int bind(int id); @@ -154,6 +155,8 @@ public: void consumeCnf(); void consumeCnf(std::vector> &cnf); + std::string cnfLiteralInfo(int idx) const; + // simple helpers for build expressions easily struct _V { From 6bc94b7eb2ecc7c2836c2fc10029542ce92eae11 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 24 Feb 2014 12:41:25 +0100 Subject: [PATCH 073/750] Don't blow up constants unneccessarily in Verilog frontend --- frontends/ast/genrtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index bc3783bd..dda069cb 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 From aaaa604853caaecf8dcbfa928914495efb5556c6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 26 Feb 2014 21:31:34 +0100 Subject: [PATCH 074/750] Added support for $bu0 to SatGen --- kernel/satgen.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index 53921044..d9bcb425 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -385,7 +385,7 @@ struct SatGen return true; } - if (cell->type == "$pos" || cell->type == "$neg") + if (cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") { std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); @@ -393,7 +393,7 @@ struct SatGen std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - if (cell->type == "$pos") { + if (cell->type == "$pos" || cell->type == "$bu0") { ez->assume(ez->vec_eq(a, yy)); } else { std::vector zero(a.size(), ez->FALSE); @@ -404,9 +404,9 @@ struct SatGen { std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); - extendSignalWidthUnary(undef_a, undef_y, cell, true); + extendSignalWidthUnary(undef_a, undef_y, cell, cell->type != "$bu0"); - if (cell->type == "$pos") { + if (cell->type == "$pos" || cell->type == "$bu0") { ez->assume(ez->vec_eq(undef_a, undef_y)); } else { int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); From ae5032af845b4c85510b3ce4a63fea3cca5e6a00 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 26 Feb 2014 21:32:19 +0100 Subject: [PATCH 075/750] Fixed bit-extending in $mux argument (use $bu0 instead of $pos) --- frontends/ast/genrtlil.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dda069cb..c3025913 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); From 9e9998433616f438cb0185519bb5b7f8e1a8f543 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 27 Feb 2014 04:09:32 +0100 Subject: [PATCH 076/750] Fixed const folding of $bu0 cells --- kernel/celltypes.h | 2 +- passes/opt/opt_const.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 34a6e56f..4a600af9 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -216,7 +216,7 @@ struct CellTypes type = "$shl"; if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && - type != "$pos" && type != "$neg" && type != "$not") { + type != "$pos" && type != "$neg" && type != "$not" && type != "$bu0") { if (!signed1 || !signed2) signed1 = false, signed2 = false; } diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index ad9a71b1..da71ec30 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -463,6 +463,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons FOLD_2ARG_CELL(pow) FOLD_1ARG_CELL(pos) + FOLD_1ARG_CELL(bu0) FOLD_1ARG_CELL(neg) // be very conservative with optimizing $mux cells as we do not want to break mux trees From 04999f4af0f6e5c46843d9212abb0c962f533cca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 17:47:19 +0100 Subject: [PATCH 077/750] Fixed vhdl2verilog help message --- frontends/vhdl2verilog/vhdl2verilog.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 9e9953ce..367e63fe 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"); From ef90236a5dd59497661e9c9ba440adf22d6052de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 17:48:15 +0100 Subject: [PATCH 078/750] Fixed vhdl2verilog temp dir name --- frontends/vhdl2verilog/vhdl2verilog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 367e63fe..de393693 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) From e3debea4e659126c538a2ff5c6a9987ca7778d89 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 20:53:09 +0100 Subject: [PATCH 079/750] Removed ezSAT built-in brute-froce solver --- libs/ezsat/ezsat.cc | 108 +++----------------------------------------- 1 file changed, 6 insertions(+), 102 deletions(-) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index e6c005c6..4ae5f4fd 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -567,109 +567,13 @@ void ezSAT::consumeCnf(std::vector> &cnf) cnfClauses.clear(); } -static bool test_bit(uint32_t bitmask, int idx) +bool ezSAT::solver(const std::vector&, std::vector&, const std::vector&) { - if (idx > 0) - return (bitmask & (1 << (+idx-1))) != 0; - else - return (bitmask & (1 << (-idx-1))) == 0; -} - -bool ezSAT::solver(const std::vector &modelExpressions, std::vector &modelValues, const std::vector &assumptions) -{ - std::vector extraClauses, modelIdx; - std::vector values(numLiterals()); - - for (auto id : assumptions) - extraClauses.push_back(bind(id)); - for (auto id : modelExpressions) - modelIdx.push_back(bind(id)); - - if (cnfVariableCount > 20) { - fprintf(stderr, "*************************************************************************************\n"); - fprintf(stderr, "ERROR: You are trying to use the builtin solver of ezSAT with more than 20 variables!\n"); - fprintf(stderr, "The builtin solver is a dumb brute force solver and only ment for testing and demo\n"); - fprintf(stderr, "purposes. Use a real SAT solve like MiniSAT (e.g. using the ezMiniSAT class) instead.\n"); - fprintf(stderr, "*************************************************************************************\n"); - abort(); - } - - for (uint32_t bitmask = 0; bitmask < (1 << numCnfVariables()); bitmask++) - { - // printf("%07o:", int(bitmask)); - // for (int i = 2; i < numLiterals(); i++) - // if (bound(i+1)) - // printf(" %s=%d", to_string(i+1).c_str(), test_bit(bitmask, bound(i+1))); - // printf(" |"); - // for (int idx = 1; idx <= numCnfVariables(); idx++) - // printf(" %3d", test_bit(bitmask, idx) ? idx : -idx); - // printf("\n"); - - for (auto idx : extraClauses) - if (!test_bit(bitmask, idx)) - goto next; - - for (auto &clause : cnfClauses) { - for (auto idx : clause) - if (test_bit(bitmask, idx)) - goto next_clause; - // printf("failed clause:"); - // for (auto idx2 : clause) - // printf(" %3d", idx2); - // printf("\n"); - goto next; - next_clause:; - // printf("passed clause:"); - // for (auto idx2 : clause) - // printf(" %3d", idx2); - // printf("\n"); - } - - modelValues.resize(modelIdx.size()); - for (int i = 0; i < int(modelIdx.size()); i++) - modelValues[i] = test_bit(bitmask, modelIdx[i]); - - // validate result using eval() - - values[0] = TRUE, values[1] = FALSE; - for (int i = 2; i < numLiterals(); i++) { - int idx = bound(i+1); - values[i] = idx != 0 ? (test_bit(bitmask, idx) ? TRUE : FALSE) : 0; - } - - for (auto id : cnfAssumptions) { - int result = eval(id, values); - if (result != TRUE) { - printInternalState(stderr); - fprintf(stderr, "Variables:"); - for (int i = 0; i < numLiterals(); i++) - fprintf(stderr, " %s=%s", lookup_literal(i+1).c_str(), values[i] == TRUE ? "TRUE" : values[i] == FALSE ? "FALSE" : "UNDEF"); - fprintf(stderr, "\nValidation of solver results failed: got `%d' (%s) for assumption '%d': %s\n", - result, result == FALSE ? "FALSE" : "UNDEF", id, to_string(id).c_str()); - abort(); - } - // printf("OK: %d -> %d\n", id, result); - } - - for (auto id : assumptions) { - int result = eval(id, values); - if (result != TRUE) { - printInternalState(stderr); - fprintf(stderr, "Variables:"); - for (int i = 0; i < numLiterals(); i++) - fprintf(stderr, " %s=%s", lookup_literal(i+1).c_str(), values[i] == TRUE ? "TRUE" : values[i] == FALSE ? "FALSE" : "UNDEF"); - fprintf(stderr, "\nValidation of solver results failed: got `%d' (%s) for assumption '%d': %s\n", - result, result == FALSE ? "FALSE" : "UNDEF", id, to_string(id).c_str()); - abort(); - } - // printf("OK: %d -> %d\n", id, result); - } - - return true; - next:; - } - - return false; + fprintf(stderr, "************************************************************************\n"); + fprintf(stderr, "ERROR: You are trying to use the solve() method of the ezSAT base class!\n"); + fprintf(stderr, "Use a dervied class like ezMiniSAT instead.\n"); + fprintf(stderr, "************************************************************************\n"); + abort(); } std::vector ezSAT::vec_const(const std::vector &bits) From edc21460565ea75cff54cab69933da8c5e9db382 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 20:55:06 +0100 Subject: [PATCH 080/750] Removed ezSAT::assumed() API --- libs/ezsat/ezsat.cc | 2 -- libs/ezsat/ezsat.h | 3 --- libs/ezsat/testbench.cc | 5 ----- 3 files changed, 10 deletions(-) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 4ae5f4fd..f77a3b91 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -342,7 +342,6 @@ void ezSAT::clear() cnfLiteralVariables.clear(); cnfExpressionVariables.clear(); cnfClauses.clear(); - cnfAssumptions.clear(); } void ezSAT::freeze(int) @@ -351,7 +350,6 @@ void ezSAT::freeze(int) void ezSAT::assume(int id) { - cnfAssumptions.insert(id); if (id < 0) { diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 79100b87..8d340b3d 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -58,7 +58,6 @@ private: int cnfVariableCount, cnfClausesCount; std::vector cnfLiteralVariables, cnfExpressionVariables; std::vector> cnfClauses; - std::set cnfAssumptions; void add_clause(const std::vector &args); void add_clause(const std::vector &args, bool argsPolarity, int a = 0, int b = 0, int c = 0); @@ -144,8 +143,6 @@ public: virtual void freeze(int id); void assume(int id); int bind(int id); - - const std::set &assumed() const { return cnfAssumptions; } int bound(int id) const; int numCnfVariables() const { return cnfVariableCount; } diff --git a/libs/ezsat/testbench.cc b/libs/ezsat/testbench.cc index cc0fe573..8283686e 100644 --- a/libs/ezsat/testbench.cc +++ b/libs/ezsat/testbench.cc @@ -38,11 +38,6 @@ struct xorshift128 { bool test(ezSAT &sat, int assumption = 0) { - for (auto id : sat.assumed()) - printf("%s\n", sat.to_string(id).c_str()); - if (assumption) - printf("%s\n", sat.to_string(assumption).c_str()); - std::vector modelExpressions; std::vector modelValues; From 23f0a12c727721478bcb87ec142fb86a329f7cdb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 20:59:00 +0100 Subject: [PATCH 081/750] ezSAT bugfix: don't call virtual methods in base class constructor --- libs/ezsat/ezminisat.cc | 3 +++ libs/ezsat/ezsat.cc | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index c6126d86..287177b1 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -35,6 +35,9 @@ ezMiniSAT::ezMiniSAT() : minisatSolver(NULL) { minisatSolver = NULL; foundContradiction = false; + + freeze(TRUE); + freeze(FALSE); } ezMiniSAT::~ezMiniSAT() diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index f77a3b91..cc6301e4 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -36,8 +36,8 @@ ezSAT::ezSAT() solverTimeout = 0; solverTimoutStatus = false; - freeze(literal("TRUE")); - freeze(literal("FALSE")); + literal("TRUE"); + literal("FALSE"); assert(literal("TRUE") == TRUE); assert(literal("FALSE") == FALSE); From d500bd749f84c0b05a8ec96d2a5fc33ace0c5b58 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 21:00:34 +0100 Subject: [PATCH 082/750] Added ezSAT::eliminated API to help the SAT solver remember eliminated variables --- libs/ezsat/ezminisat.cc | 8 ++++++++ libs/ezsat/ezminisat.h | 1 + libs/ezsat/ezsat.cc | 10 +++++++--- libs/ezsat/ezsat.h | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 287177b1..d488a906 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -65,6 +65,14 @@ void ezMiniSAT::freeze(int id) { cnfFrozenVars.insert(bind(id)); } + +bool ezMiniSAT::eliminated(int idx) +{ + idx = idx < 0 ? -idx : idx; + if (minisatSolver != NULL && idx > 0 && idx <= int(minisatVars.size())) + return minisatSolver->isEliminated(minisatVars.at(idx-1)); + return false; +} #endif ezMiniSAT *ezMiniSAT::alarmHandlerThis = NULL; diff --git a/libs/ezsat/ezminisat.h b/libs/ezsat/ezminisat.h index e7e08289..c634e66e 100644 --- a/libs/ezsat/ezminisat.h +++ b/libs/ezsat/ezminisat.h @@ -61,6 +61,7 @@ public: virtual void clear(); #if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL virtual void freeze(int id); + virtual bool eliminated(int idx); #endif virtual bool solver(const std::vector &modelExpressions, std::vector &modelValues, const std::vector &assumptions); }; diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index cc6301e4..4389c7a6 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -348,9 +348,13 @@ void ezSAT::freeze(int) { } +bool ezSAT::eliminated(int) +{ + return false; +} + void ezSAT::assume(int id) { - if (id < 0) { assert(0 < -id && -id <= int(expressions.size())); @@ -486,7 +490,7 @@ int ezSAT::bind(int id) if (id >= 0) { assert(0 < id && id <= int(literals.size())); cnfLiteralVariables.resize(literals.size()); - if (cnfLiteralVariables[id-1] == 0) { + if (cnfLiteralVariables[id-1] == 0 || eliminated(cnfLiteralVariables[id-1])) { cnfLiteralVariables[id-1] = ++cnfVariableCount; if (id == TRUE) add_clause(+cnfLiteralVariables[id-1]); @@ -499,7 +503,7 @@ int ezSAT::bind(int id) assert(0 < -id && -id <= int(expressions.size())); cnfExpressionVariables.resize(expressions.size()); - if (cnfExpressionVariables[-id-1] == 0) + if (cnfExpressionVariables[-id-1] == 0 || eliminated(cnfExpressionVariables[-id-1])) { OpId op; std::vector args; diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 8d340b3d..16f940a1 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -141,6 +141,7 @@ public: virtual void clear(); virtual void freeze(int id); + virtual bool eliminated(int idx); void assume(int id); int bind(int id); int bound(int id) const; From 895e9fc70cb2d45c606c64a7b12d51dc0564c005 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 3 Mar 2014 02:12:45 +0100 Subject: [PATCH 083/750] ezSAT: Fixed handling of eliminated Literals, added auto-freeze for expressions --- libs/ezsat/ezsat.cc | 29 ++++++++++++++++++++++------- libs/ezsat/ezsat.h | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 4389c7a6..bbebee74 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -485,12 +485,16 @@ std::string ezSAT::cnfLiteralInfo(int idx) const return ""; } -int ezSAT::bind(int id) +int ezSAT::bind(int id, bool auto_freeze) { if (id >= 0) { assert(0 < id && id <= int(literals.size())); cnfLiteralVariables.resize(literals.size()); - if (cnfLiteralVariables[id-1] == 0 || eliminated(cnfLiteralVariables[id-1])) { + if (eliminated(cnfLiteralVariables[id-1])) { + fprintf(stderr, "ezSAT: Missing freeze on literal `%s'.\n", to_string(id).c_str()); + abort(); + } + if (cnfLiteralVariables[id-1] == 0) { cnfLiteralVariables[id-1] = ++cnfVariableCount; if (id == TRUE) add_clause(+cnfLiteralVariables[id-1]); @@ -503,7 +507,18 @@ int ezSAT::bind(int id) assert(0 < -id && -id <= int(expressions.size())); cnfExpressionVariables.resize(expressions.size()); - if (cnfExpressionVariables[-id-1] == 0 || eliminated(cnfExpressionVariables[-id-1])) + if (eliminated(cnfExpressionVariables[-id-1])) + { + cnfExpressionVariables[-id-1] = 0; + + // this will recursively call bind(id). within the recursion + // the cnf is pre-set to 0. an idx is allocated there, then it + // is frozen, then it returns here with the new idx already set. + if (auto_freeze) + freeze(id); + } + + if (cnfExpressionVariables[-id-1] == 0) { OpId op; std::vector args; @@ -520,7 +535,7 @@ int ezSAT::bind(int id) newArgs.push_back(OR(AND(args[i], NOT(args[i+1])), AND(NOT(args[i]), args[i+1]))); args.swap(newArgs); } - idx = bind(args.at(0)); + idx = bind(args.at(0), false); goto assign_idx; } @@ -528,17 +543,17 @@ int ezSAT::bind(int id) std::vector invArgs; for (auto arg : args) invArgs.push_back(NOT(arg)); - idx = bind(OR(expression(OpAnd, args), expression(OpAnd, invArgs))); + idx = bind(OR(expression(OpAnd, args), expression(OpAnd, invArgs)), false); goto assign_idx; } if (op == OpITE) { - idx = bind(OR(AND(args[0], args[1]), AND(NOT(args[0]), args[2]))); + idx = bind(OR(AND(args[0], args[1]), AND(NOT(args[0]), args[2])), false); goto assign_idx; } for (int i = 0; i < int(args.size()); i++) - args[i] = bind(args[i]); + args[i] = bind(args[i], false); switch (op) { diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 16f940a1..13b39d4e 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -143,7 +143,7 @@ public: virtual void freeze(int id); virtual bool eliminated(int idx); void assume(int id); - int bind(int id); + int bind(int id, bool auto_freeze = true); int bound(int id) const; int numCnfVariables() const { return cnfVariableCount; } From d5bd93997c9ce7c31ef430684700a2096618672e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 3 Mar 2014 02:13:17 +0100 Subject: [PATCH 084/750] ezSAT: Added frozen_literal() API --- libs/ezsat/ezsat.cc | 14 ++++++++++++++ libs/ezsat/ezsat.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index bbebee74..fb3d2499 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -67,6 +67,20 @@ int ezSAT::literal(const std::string &name) return literalsCache.at(name); } +int ezSAT::frozen_literal() +{ + int id = literal(); + freeze(id); + return id; +} + +int ezSAT::frozen_literal(const std::string &name) +{ + int id = literal(name); + freeze(id); + return id; +} + int ezSAT::expression(OpId op, int a, int b, int c, int d, int e, int f) { std::vector args(6); diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 13b39d4e..b0b731d0 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -79,6 +79,8 @@ public: int value(bool val); int literal(); int literal(const std::string &name); + int frozen_literal(); + int frozen_literal(const std::string &name); int expression(OpId op, int a = 0, int b = 0, int c = 0, int d = 0, int e = 0, int f = 0); int expression(OpId op, const std::vector &args); From 96e753041dbd0abc86ff0a6404f13d29edcb985d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 3 Mar 2014 02:14:27 +0100 Subject: [PATCH 085/750] fixed freduce for Minisat::SimpSolver: use frozen_literal() --- passes/sat/freduce.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 81250b00..746523f8 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -112,13 +112,13 @@ struct FindReducedInputs size_t idx_bits = get_bits(idx); if (sat_pi_uniq_bitvec.size() != idx_bits) { - sat_pi_uniq_bitvec.push_back(ez.literal(stringf("uniq_%d", int(idx_bits)-1))); + sat_pi_uniq_bitvec.push_back(ez.frozen_literal(stringf("uniq_%d", int(idx_bits)-1))); for (auto &it : sat_pi) ez.assume(ez.OR(ez.NOT(it.second), ez.NOT(sat_pi_uniq_bitvec.back()))); } log_assert(sat_pi_uniq_bitvec.size() == idx_bits); - sat_pi[bit] = ez.literal(stringf("pi_%s", log_signal(bit))); + sat_pi[bit] = ez.frozen_literal(stringf("p, falsei_%s", log_signal(bit))); ez.assume(ez.IFF(ez.XOR(sat_a, sat_b), sat_pi[bit])); for (size_t i = 0; i < idx_bits; i++) From de7bd12004f24b7e9fff3ba1f253537704db4e44 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:45:33 +0100 Subject: [PATCH 086/750] Bugfix in recursive AST simplification --- frontends/ast/simplify.cc | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 55ed28b0..72d90e4a 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 From d6a01fe412419d32ec5b0d91f9076849d1ed489d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:55:58 +0100 Subject: [PATCH 087/750] Fixed merging of compatible wire decls in AST frontend --- frontends/ast/simplify.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 72d90e4a..a20aacff 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]; From 09805ee9ec0408bdc68b914927899f02371efcb7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:56:31 +0100 Subject: [PATCH 088/750] Include id2ast pointers when dumping AST --- frontends/ast/ast.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d9ad6d8e..f2f2d0e6 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()) { From b1b8fe3a566099e5fd29e6d8c60e8f8b4feb0f34 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:57:10 +0100 Subject: [PATCH 089/750] Switched to EZMINISAT_SIMPSOLVER as default SAT solver --- libs/ezsat/ezminisat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ezsat/ezminisat.h b/libs/ezsat/ezminisat.h index c634e66e..ac9c071c 100644 --- a/libs/ezsat/ezminisat.h +++ b/libs/ezsat/ezminisat.h @@ -20,7 +20,7 @@ #ifndef EZMINISAT_H #define EZMINISAT_H -#define EZMINISAT_SIMPSOLVER 0 +#define EZMINISAT_SIMPSOLVER 1 #define EZMINISAT_VERBOSITY 0 #define EZMINISAT_INCREMENTAL 1 From a1bfde8c5ea0d5c9778579bf78165637ac6c9b25 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 11:53:37 +0100 Subject: [PATCH 090/750] Strictly zero-extend unsigned A-inputs of shift operations --- kernel/calc.cc | 4 ++-- kernel/satgen.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/calc.cc b/kernel/calc.cc index a56db93a..749589f2 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -305,14 +305,14 @@ static RTLIL::Const const_shift(const RTLIL::Const &arg1, const RTLIL::Const &ar RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; - extend(arg1_ext, result_len, signed1); + extend_u0(arg1_ext, result_len, signed1); return const_shift(arg1_ext, arg2, false, -1, result_len); } RTLIL::Const RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; - extend(arg1_ext, result_len, signed1); + extend_u0(arg1_ext, result_len, signed1); return const_shift(arg1_ext, arg2, false, +1, result_len); } diff --git a/kernel/satgen.h b/kernel/satgen.h index d9bcb425..3ae9502f 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -634,7 +634,7 @@ struct SatGen while (undef_y.size() < undef_a.size()) undef_y.push_back(ez->literal()); while (undef_y.size() > undef_a.size()) - undef_a.push_back(undef_a.back()); + undef_a.push_back(cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : ez->FALSE); tmp = undef_a; for (size_t i = 0; i < b.size(); i++) From d7f29bb23f9bb2c74e02bc1221bcf27efc7ee4dc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 11:54:22 +0100 Subject: [PATCH 091/750] Improved techmap of shift with wide B inputs --- techlibs/common/stdcells.v | 50 ++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index fdee26b6..a51dcb94 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -165,6 +165,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; parameter WIDTH = Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -181,11 +182,16 @@ generate .A(A), .Y(chain[WIDTH-1:0]) ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V + assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; + for (i = 0; i < BB_WIDTH; i = i + 1) begin:V wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) @@ -200,7 +206,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate @@ -218,6 +224,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -225,7 +232,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; + wire [WIDTH*(BB_WIDTH+1)-1:0] chain; \$pos #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), @@ -234,11 +241,16 @@ generate .A(A), .Y(chain[WIDTH-1:0]) ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V + assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; + for (i = 0; i < BB_WIDTH; i = i + 1) begin:V wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(2 ** (i > 30 ? 30 : i)) @@ -253,7 +265,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate @@ -271,6 +283,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -292,6 +305,11 @@ generate wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) @@ -306,7 +324,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate @@ -324,6 +342,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -331,7 +350,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; + wire [WIDTH*(BB_WIDTH+1)-1:0] chain; \$pos #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), @@ -342,18 +361,23 @@ generate ); for (i = 0; i < Y_WIDTH; i = i + 1) begin:Y if (i < WIDTH) begin - assign Y[i] = chain[WIDTH*B_WIDTH + i]; + assign Y[i] = chain[WIDTH*BB_WIDTH + i]; end else if (A_SIGNED) begin - assign Y[i] = chain[WIDTH*B_WIDTH + WIDTH-1]; + assign Y[i] = chain[WIDTH*BB_WIDTH + WIDTH-1]; end else begin assign Y[i] = 0; end end - for (i = 0; i < B_WIDTH; i = i + 1) begin:V + for (i = 0; i < BB_WIDTH; i = i + 1) begin:V wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; + wire BBIT; + if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) + assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; + else + assign BBIT = B[i]; \$__shift #( .WIDTH(WIDTH), .SHIFT(2 ** (i > 30 ? 30 : i)) @@ -368,7 +392,7 @@ generate .A(unshifted), .B(shifted), .Y(result), - .S(B[i]) + .S(BBIT) ); end endgenerate From 1ecaf1bb767834dc6a763549b63d9d4653c342d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 12:15:17 +0100 Subject: [PATCH 092/750] Added techmap -max_iter option --- passes/techmap/techmap.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index f163c024..937f4131 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -464,6 +464,9 @@ struct TechmapPass : public Pass { log(" yosys data files are). this is mainly used internally when techmap\n"); log(" is called from other commands.\n"); log("\n"); + log(" -max_iter \n"); + log(" only run the specified number of iterations.\n"); + log("\n"); log(" -D , -I \n"); log(" this options are passed as-is to the verilog frontend for loading the\n"); log(" map file. Note that the verilog frontend is also called with the\n"); @@ -542,6 +545,7 @@ struct TechmapPass : public Pass { std::vector map_files; std::string verilog_frontend = "verilog -ignore_redef"; + int max_iter = -1; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -553,6 +557,10 @@ struct TechmapPass : public Pass { map_files.push_back(get_share_file_name(args[++argidx])); continue; } + if (args[argidx] == "-max_iter" && argidx+1 < args.size()) { + max_iter = atoi(args[++argidx].c_str()); + continue; + } if (args[argidx] == "-D" && argidx+1 < args.size()) { verilog_frontend += " -D " + args[++argidx]; continue; @@ -610,6 +618,8 @@ struct TechmapPass : public Pass { did_something = true; if (did_something) design->check(); + if (max_iter > 0 && --max_iter == 0) + break; } log("No more expansions possible.\n"); From 8406e7f7b6cb8e79f7df02c2c616073a51c1ea9e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 12:15:44 +0100 Subject: [PATCH 093/750] Strictly zero-extend unsigned A-inputs of shift operations in techmap --- techlibs/common/stdcells.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index a51dcb94..cddaf4c6 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -174,7 +174,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate wire [WIDTH*(B_WIDTH+1)-1:0] chain; - \$pos #( + \$bu0 #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH) @@ -233,7 +233,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate wire [WIDTH*(BB_WIDTH+1)-1:0] chain; - \$pos #( + \$bu0 #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH) @@ -292,7 +292,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate wire [WIDTH*(B_WIDTH+1)-1:0] chain; - \$pos #( + \$bu0 #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH) @@ -351,7 +351,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate wire [WIDTH*(BB_WIDTH+1)-1:0] chain; - \$pos #( + \$bu0 #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH) From 97710ffad5d4750b538dac5f08b77dce37e3cda4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 13:08:44 +0100 Subject: [PATCH 094/750] Fixed use of frozen literals in SatGen --- kernel/satgen.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index 3ae9502f..bf72a31c 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -66,13 +66,12 @@ struct SatGen if (c.wire == NULL) { RTLIL::State bit = c.data.bits.at(0); if (model_undef && dup_undef && bit == RTLIL::State::Sx) - vec.push_back(ez->literal()); + vec.push_back(ez->frozen_literal()); else vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->TRUE : ez->FALSE); } else { std::string name = pf + stringf(c.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(c.wire->name), c.offset); - vec.push_back(ez->literal(name)); - ez->freeze(vec.back()); + vec.push_back(ez->frozen_literal(name)); } return vec; } From 973507d85b0a20118f6a56ec787d44d6b574d3a6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 13:22:10 +0100 Subject: [PATCH 095/750] Fixes for improved techmap of shifts with large B inputs --- techlibs/common/stdcells.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index cddaf4c6..a05ea278 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -165,7 +165,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; parameter WIDTH = Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -173,7 +173,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; + wire [WIDTH*(BB_WIDTH+1)-1:0] chain; \$bu0 #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), @@ -224,7 +224,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -283,7 +283,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; @@ -291,7 +291,7 @@ output [Y_WIDTH-1:0] Y; genvar i; generate - wire [WIDTH*(B_WIDTH+1)-1:0] chain; + wire [WIDTH*(BB_WIDTH+1)-1:0] chain; \$bu0 #( .A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), @@ -300,8 +300,8 @@ generate .A(A), .Y(chain[WIDTH-1:0]) ); - assign Y = chain[WIDTH*(B_WIDTH+1)-1 : WIDTH*B_WIDTH]; - for (i = 0; i < B_WIDTH; i = i + 1) begin:V + assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; + for (i = 0; i < BB_WIDTH; i = i + 1) begin:V wire [WIDTH-1:0] unshifted, shifted, result; assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; @@ -342,7 +342,7 @@ parameter B_WIDTH = 1; parameter Y_WIDTH = 1; localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 1 < B_WIDTH ? $clog2(WIDTH) + 1 : B_WIDTH; +localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; From 9b9c3327ccf3a8e69f9af57333839f470df0ce66 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 14:18:34 +0100 Subject: [PATCH 096/750] Fixed undef handling in opt_reduce --- passes/opt/opt_reduce.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index dd129981..fee8fb71 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -65,8 +65,8 @@ struct OptReduceWorker continue; } if (chunk.wire == NULL) { - new_sig_a = RTLIL::SigSpec(RTLIL::State::Sx); - break; + new_sig_a.append(chunk); + continue; } bool imported_children = false; From 4d07f8825845618daffb4d61bdcbb3eda0e1393a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 16:37:19 +0100 Subject: [PATCH 097/750] Fixed gcc compiler warning --- frontends/vhdl2verilog/vhdl2verilog.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index de393693..0467810e 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(); } From da5859a6744943469d5165724fa79ce243e5d8e3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 18:14:26 +0100 Subject: [PATCH 098/750] Added freduce -stop --- passes/sat/freduce.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 746523f8..8d7ce5aa 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -31,7 +31,7 @@ namespace { bool inv_mode; -int verbose_level; +int verbose_level, reduce_counter, reduce_stop_at; typedef std::map>> drivers_t; struct equiv_bit_t @@ -648,7 +648,7 @@ struct FreduceWorker int rewired_sigbits = 0; for (auto &grp : equiv) { - log(" Using as master for group: %s\n", log_signal(grp.front().bit)); + log(" [%d] Using as master for group: %s\n", ++reduce_counter, log_signal(grp.front().bit)); RTLIL::SigSpec inv_sig; for (size_t i = 1; i < grp.size(); i++) @@ -692,6 +692,11 @@ struct FreduceWorker rewired_sigbits++; } + + if (reduce_counter == reduce_stop_at) { + log(" Reached limit passed using -stop option. Skipping all further reductions.\n"); + break; + } } log(" Rewired a total of %d signal bits in module %s.\n", rewired_sigbits, RTLIL::id2cstr(module->name)); @@ -711,7 +716,7 @@ struct FreducePass : public Pass { log("\n"); log("This pass performs functional reduction in the circuit. I.e. if two nodes are\n"); log("equivialent, they are merged to one node and one of the redundant drivers is\n"); - log("unconnected. A subsequent call to 'clean' will remove the redundant drivers.\n"); + log("disconnected. A subsequent call to 'clean' will remove the redundant drivers.\n"); log("\n"); log(" -v, -vv\n"); log(" enable verbose or very verbose output\n"); @@ -719,6 +724,10 @@ struct FreducePass : public Pass { log(" -inv\n"); log(" enable explicit handling of inverted signals\n"); log("\n"); + log(" -stop \n"); + log(" stop after reduction operations. this is mostly used for\n"); + log(" debugging the freduce command itself.\n"); + log("\n"); log("This pass is undef-aware, i.e. it considers don't-care values for detecting\n"); log("equivialent nodes.\n"); log("\n"); @@ -728,6 +737,8 @@ struct FreducePass : public Pass { } virtual void execute(std::vector args, RTLIL::Design *design) { + reduce_counter = 0; + reduce_stop_at = 0; verbose_level = 0; inv_mode = false; @@ -747,6 +758,10 @@ struct FreducePass : public Pass { inv_mode = true; continue; } + if (args[argidx] == "-stop" && argidx+1 < args.size()) { + reduce_stop_at = atoi(args[++argidx].c_str()); + continue; + } break; } extra_args(args, argidx, design); From 54d74cf6165ebefc2cf7aee4fab43566362eedb1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 22:06:58 +0100 Subject: [PATCH 099/750] Added freduce -dump --- passes/sat/freduce.cc | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 8d7ce5aa..22af1345 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -33,6 +33,7 @@ namespace { bool inv_mode; int verbose_level, reduce_counter, reduce_stop_at; typedef std::map>> drivers_t; +std::string dump_prefix; struct equiv_bit_t { @@ -559,6 +560,13 @@ struct FreduceWorker { } + void dump() + { + std::string filename = stringf("%s_%s_%05d.il", dump_prefix.c_str(), RTLIL::id2cstr(module->name), reduce_counter); + log("%s Writing dump file `%s'.\n", reduce_counter ? " " : "", filename.c_str()); + Pass::call(design, stringf("dump -outfile %s %s", filename.c_str(), design->selected_active_module.empty() ? module->name.c_str() : "")); + } + int run() { log("Running functional reduction on module %s:\n", RTLIL::id2cstr(module->name)); @@ -644,11 +652,14 @@ struct FreduceWorker std::map bitusage; module->rewrite_sigspecs(CountBitUsage(sigmap, bitusage)); + if (!dump_prefix.empty()) + dump(); + log(" Rewiring %d equivialent groups:\n", int(equiv.size())); int rewired_sigbits = 0; for (auto &grp : equiv) { - log(" [%d] Using as master for group: %s\n", ++reduce_counter, log_signal(grp.front().bit)); + log(" [%05d] Using as master for group: %s\n", ++reduce_counter, log_signal(grp.front().bit)); RTLIL::SigSpec inv_sig; for (size_t i = 1; i < grp.size(); i++) @@ -693,6 +704,9 @@ struct FreduceWorker rewired_sigbits++; } + if (!dump_prefix.empty()) + dump(); + if (reduce_counter == reduce_stop_at) { log(" Reached limit passed using -stop option. Skipping all further reductions.\n"); break; @@ -728,6 +742,10 @@ struct FreducePass : public Pass { log(" stop after reduction operations. this is mostly used for\n"); log(" debugging the freduce command itself.\n"); log("\n"); + log(" -dump \n"); + log(" dump the design to __.il after each reduction\n"); + log(" operation. this is mostly used for debugging the freduce command.\n"); + log("\n"); log("This pass is undef-aware, i.e. it considers don't-care values for detecting\n"); log("equivialent nodes.\n"); log("\n"); @@ -741,6 +759,7 @@ struct FreducePass : public Pass { reduce_stop_at = 0; verbose_level = 0; inv_mode = false; + dump_prefix = std::string(); log_header("Executing FREDUCE pass (perform functional reduction).\n"); @@ -762,6 +781,10 @@ struct FreducePass : public Pass { reduce_stop_at = atoi(args[++argidx].c_str()); continue; } + if (args[argidx] == "-dump" && argidx+1 < args.size()) { + dump_prefix = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); From f7bd0a523203ed52713ecde56c1cfb89df4d48af Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 15:56:10 +0100 Subject: [PATCH 100/750] Use log_abort() and log_assert() in BTOR backend --- backends/btor/btor.cc | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 03ef183a..45f7b414 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -28,7 +28,6 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include -#include #include struct BtorDumperConfig @@ -244,7 +243,7 @@ struct BtorDumper return it->second; } } - assert(false); + log_abort(); return -1; } @@ -283,7 +282,7 @@ struct BtorDumper } else log("writing const error\n"); - assert(false); + log_abort(); return -1; } @@ -302,7 +301,7 @@ struct BtorDumper else { int wire_line_num = dump_wire(chunk->wire); - assert(wire_line_num>0); + log_assert(wire_line_num>0); ++line_num; str = stringf("%d slice %d %d %d %d;2", line_num, chunk->width, wire_line_num, chunk->width + chunk->offset - 1, chunk->offset); @@ -329,12 +328,12 @@ struct BtorDumper { int l1, l2, w1, w2; l1 = dump_sigchunk(&s.chunks[0]); - assert(l1>0); + log_assert(l1>0); w1 = s.chunks[0].width; for (unsigned i=1; i < s.chunks.size(); ++i) { l2 = dump_sigchunk(&s.chunks[i]); - assert(l2>0); + log_assert(l2>0); w2 = s.chunks[i].width; ++line_num; str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); @@ -374,7 +373,7 @@ struct BtorDumper l = line_num; } } - assert(l>0); + log_assert(l>0); return l; } @@ -390,8 +389,8 @@ struct BtorDumper log("writing assert cell - %s\n", cstr(cell->type)); const RTLIL::SigSpec* expr = &cell->connections.at(RTLIL::IdString("\\A")); const RTLIL::SigSpec* en = &cell->connections.at(RTLIL::IdString("\\EN")); - assert(expr->width == 1); - assert(en->width == 1); + log_assert(expr->width == 1); + log_assert(en->width == 1); int expr_line = dump_sigspec(expr, 1); int en_line = dump_sigspec(en, 1); int one_line = ++line_num; @@ -444,7 +443,7 @@ struct BtorDumper log("writing unary cell - %s\n", cstr(cell->type)); int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - assert(output_width == 1); + log_assert(output_width == 1); int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); if(cell->type == "$logic_not" && w > 1) { @@ -470,7 +469,7 @@ struct BtorDumper { log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - assert(!(cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || + log_assert(!(cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") || output_width == 1); bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool(); bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool(); @@ -511,7 +510,7 @@ struct BtorDumper int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); - assert(l1_signed == l2_signed); + log_assert(l1_signed == l2_signed); l1_width = l1_width > output_width ? l1_width : output_width; l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; @@ -592,7 +591,7 @@ struct BtorDumper { log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - assert(output_width == 1); + log_assert(output_width == 1); int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); @@ -653,7 +652,7 @@ struct BtorDumper for(unsigned i=0; ichunks.size(); ++i) { output_width = cell_output->chunks[i].width; - assert( output_width == cell_output->chunks[i].wire->width);//full reg is given the next value + log_assert( output_width == cell_output->chunks[i].wire->width);//full reg is given the next value int reg = dump_wire(cell_output->chunks[i].wire);//register int slice = value; if(cell_output->chunks.size()>1) @@ -760,11 +759,11 @@ struct BtorDumper log("writing slice cell\n"); const RTLIL::SigSpec* input = &cell->connections.at(RTLIL::IdString("\\A")); int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); - assert(input->width == input_width); + log_assert(input->width == input_width); int input_line = dump_sigspec(input, input_width); const RTLIL::SigSpec* output = &cell->connections.at(RTLIL::IdString("\\Y")); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - assert(output->width == output_width); + log_assert(output->width == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); ++line_num; str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, input_line, output_width+offset-1, offset); @@ -776,11 +775,11 @@ struct BtorDumper log("writing concat cell\n"); const RTLIL::SigSpec* input_a = &cell->connections.at(RTLIL::IdString("\\A")); int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); - assert(input_a->width == input_a_width); + log_assert(input_a->width == input_a_width); int input_a_line = dump_sigspec(input_a, input_a_width); const RTLIL::SigSpec* input_b = &cell->connections.at(RTLIL::IdString("\\B")); int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); - assert(input_b->width == input_b_width); + log_assert(input_b->width == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); ++line_num; str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), input_a_width+input_b_width, From 620d51d9f713d68ebc920b5b1cac59cc176b0b9d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 17:19:14 +0100 Subject: [PATCH 101/750] Bugfix in ilang frontend autoidx recovery --- frontends/ilang/lexer.l | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 5da8ce67..00091927 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; } } } From 6f8865d81ab6392bdd1413f0ae6f5a5774524d28 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 18:29:04 +0100 Subject: [PATCH 102/750] Some minor code cleanups in freduce command --- passes/sat/freduce.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 22af1345..eb94cad2 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -244,7 +244,6 @@ struct PerformReduction return 0; if (sigdepth.count(out) != 0) return sigdepth.at(out); - sigdepth[out] = 0; if (drivers.count(out) != 0) { std::pair> &drv = drivers.at(out); @@ -253,17 +252,18 @@ struct PerformReduction log_error("Can't create SAT model for cell %s (%s)!\n", RTLIL::id2cstr(drv.first->name), RTLIL::id2cstr(drv.first->type)); celldone.insert(drv.first); } - int max_child_dept = 0; + int max_child_depth = 0; for (auto &bit : drv.second) - max_child_dept = std::max(register_cone_worker(celldone, sigdepth, bit), max_child_dept); - sigdepth[out] = max_child_dept + 1; + max_child_depth = std::max(register_cone_worker(celldone, sigdepth, bit), max_child_depth); + sigdepth[out] = max_child_depth + 1; } else { pi_bits.push_back(out); sat_pi.push_back(satgen.importSigSpec(out).front()); ez.assume(ez.NOT(satgen.importUndefSigSpec(out).front())); + sigdepth[out] = 0; } - return sigdepth[out]; + return sigdepth.at(out); } PerformReduction(SigMap &sigmap, drivers_t &drivers, std::set> &inv_pairs, std::vector &bits, int cone_size) : From e3b11ea2d64724102070f96e667c4dea07c0c3e5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 18:44:23 +0100 Subject: [PATCH 103/750] Fixed bug in freduce command --- passes/sat/freduce.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index eb94cad2..d4b7b5c1 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -560,6 +560,31 @@ struct FreduceWorker { } + bool find_bit_in_cone(std::set &celldone, RTLIL::SigBit needle, RTLIL::SigBit haystack) + { + if (needle == haystack) + return true; + if (haystack.wire == NULL || needle.wire == NULL || drivers.count(haystack) == 0) + return false; + + std::pair> &drv = drivers.at(haystack); + + if (celldone.count(drv.first)) + return false; + celldone.insert(drv.first); + + for (auto &bit : drv.second) + if (find_bit_in_cone(celldone, needle, bit)) + return true; + return false; + } + + bool find_bit_in_cone(RTLIL::SigBit needle, RTLIL::SigBit haystack) + { + std::set celldone; + return find_bit_in_cone(celldone, needle, haystack); + } + void dump() { std::string filename = stringf("%s_%s_%05d.il", dump_prefix.c_str(), RTLIL::id2cstr(module->name), reduce_counter); @@ -674,6 +699,11 @@ struct FreduceWorker continue; } + if (find_bit_in_cone(grp[i].bit, grp.front().bit)) { + log(" Skipping dependency of master: %s\n", log_signal(grp[i].bit)); + continue; + } + log(" Connect slave%s: %s\n", grp[i].inverted ? " using inverter" : "", log_signal(grp[i].bit)); RTLIL::Cell *drv = drivers.at(grp[i].bit).first; From 22aabe05c9dcb7a7f5c16988fc98a43e55b52beb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Mar 2014 15:15:38 +0100 Subject: [PATCH 104/750] Verbose reading of liberty and constr files in ABC pass --- passes/abc/abc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index bd0d983a..2829e660 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -625,10 +625,10 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std std::string buffer; if (!liberty_file.empty()) { - buffer += stringf("%s -s -c 'read_blif %s/input.blif; read_lib %s; ", + buffer += stringf("%s -s -c 'read_blif %s/input.blif; read_lib -w %s; ", exe_file.c_str(), tempdir_name, liberty_file.c_str()); if (!constr_file.empty()) - buffer += stringf("read_constr %s; ", constr_file.c_str()); + buffer += stringf("read_constr -v %s; ", constr_file.c_str()); buffer += abc_command + "; "; } else if (lut_mode) From fcae92868de81de87079c1415d3d0123dce8d84c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Mar 2014 15:16:07 +0100 Subject: [PATCH 105/750] Fixed dumping of timing() { .. } block in libparse --- passes/techmap/libparse.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 8cbb8e2b..2ff55153 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -63,9 +63,10 @@ void LibertyAst::dump(FILE *f, std::string indent, std::string path, bool path_o } fprintf(f, "%s%s", indent.c_str(), id.c_str()); - if (!args.empty()) { + if (!args.empty() || !children.empty()) { + fprintf(f, "("); for (size_t i = 0; i < args.size(); i++) - fprintf(f, "%s%s", i > 0 ? ", " : "(", args[i].c_str()); + fprintf(f, "%s%s", i > 0 ? ", " : "", args[i].c_str()); fprintf(f, ")"); } if (!value.empty()) From 8d06f9f2fe19cc581e61ff66d0641bc03f815fb3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Mar 2014 20:40:04 +0100 Subject: [PATCH 106/750] Added "verific" command --- Makefile | 14 +- frontends/verific/Makefile.inc | 1 + frontends/verific/verific.cc | 488 +++++++++++++++++++++++++++++++++ 3 files changed, 501 insertions(+), 2 deletions(-) create mode 100644 frontends/verific/Makefile.inc create mode 100644 frontends/verific/verific.cc diff --git a/Makefile b/Makefile index 85b45577..a68ceccb 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ ENABLE_TCL := 1 ENABLE_QT4 := 1 ENABLE_MINISAT := 1 ENABLE_ABC := 1 +ENABLE_VERIFIC := 0 # other configuration flags ENABLE_GPROF := 0 @@ -58,8 +59,10 @@ CXXFLAGS += -std=gnu++0x -march=native -O3 -DNDEBUG endif ifeq ($(ENABLE_TCL),1) -CXXFLAGS += -I/usr/include/tcl8.5 -DYOSYS_ENABLE_TCL -LDLIBS += -ltcl8.5 +TCL_VERSION ?= tcl8.5 +TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) +CXXFLAGS += -I$(TCL_INCLUDE) -DYOSYS_ENABLE_TCL +LDLIBS += -l$(TCL_VERSION) endif ifeq ($(ENABLE_GPROF),1) @@ -75,6 +78,13 @@ ifeq ($(ENABLE_ABC),1) TARGETS += yosys-abc endif +ifeq ($(ENABLE_VERIFIC),1) +VERIFIC_DIR ?= /usr/local/src/verific_lib_eval +VERIFIC_COMPONENTS ?= verilog vhdl database util containers +CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -D'VERIFIC_DIR="$(VERIFIC_DIR)"' +LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) +endif + OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc new file mode 100644 index 00000000..74a669ef --- /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 00000000..5c2b933c --- /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; + From fdef064b1d8bbaff8d8f3f2dbf728132ef463010 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 03:02:27 +0100 Subject: [PATCH 107/750] Added RTLIL::Module::add... helper methods --- kernel/rtlil.cc | 236 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 57 ++++++++++++ 2 files changed, 293 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 396eaf11..811289a4 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -844,6 +844,242 @@ void RTLIL::Module::fixup_ports() all_ports[i]->port_id = i+1; } + +#define DEF_METHOD(_func, _type) \ + RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->parameters["\\A_SIGNED"] = is_signed; \ + cell->parameters["\\A_WIDTH"] = sig_a.width; \ + cell->parameters["\\Y_WIDTH"] = sig_y.width; \ + cell->connections["\\A"] = sig_a; \ + cell->connections["\\Y"] = sig_y; \ + add(cell); \ + return cell; \ + } +DEF_METHOD(addNot, "$not") +DEF_METHOD(addPos, "$pos") +DEF_METHOD(addBu0, "$bu0") +DEF_METHOD(addNeg, "$neg") +DEF_METHOD(addReduceAnd, "$redcue_and") +DEF_METHOD(addReduceOr, "$redcue_or") +DEF_METHOD(addReduceXor, "$redcue_xor") +DEF_METHOD(addReduceXnor, "$redcue_xnor") +DEF_METHOD(addReduceBool, "$redcue_bool") +DEF_METHOD(addLogicNot, "$logic_not") +#undef DEF_METHOD + +#define DEF_METHOD(_func, _type) \ + RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->parameters["\\A_SIGNED"] = is_signed; \ + cell->parameters["\\B_SIGNED"] = is_signed; \ + cell->parameters["\\A_WIDTH"] = sig_a.width; \ + cell->parameters["\\B_WIDTH"] = sig_b.width; \ + cell->parameters["\\Y_WIDTH"] = sig_y.width; \ + cell->connections["\\A"] = sig_a; \ + cell->connections["\\B"] = sig_b; \ + cell->connections["\\Y"] = sig_y; \ + add(cell); \ + return cell; \ + } +DEF_METHOD(addAnd, "$and") +DEF_METHOD(addOr, "$or") +DEF_METHOD(addXor, "$xor") +DEF_METHOD(addXnor, "$xnor") +DEF_METHOD(addShl, "$shl") +DEF_METHOD(addShr, "$shr") +DEF_METHOD(addSshl, "$Sshl") +DEF_METHOD(addSshr, "$Sshr") +DEF_METHOD(addLt, "$lt") +DEF_METHOD(addLe, "$le") +DEF_METHOD(addEq, "$eq") +DEF_METHOD(addNe, "$ne") +DEF_METHOD(addEqx, "$eqx") +DEF_METHOD(addNex, "$nex") +DEF_METHOD(addGe, "$ge") +DEF_METHOD(addGt, "$gt") +DEF_METHOD(addAdd, "$add") +DEF_METHOD(addSub, "$sub") +DEF_METHOD(addMul, "$mul") +DEF_METHOD(addDiv, "$div") +DEF_METHOD(addMod, "$mod") +DEF_METHOD(addLogicAnd, "$logic_and") +DEF_METHOD(addLogicOr, "$logic_or") +#undef DEF_METHOD + +#define DEF_METHOD(_func, _type, _pmux) \ + RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->parameters["\\WIDTH"] = sig_a.width; \ + cell->parameters["\\WIDTH"] = sig_b.width; \ + if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.width; \ + cell->connections["\\A"] = sig_a; \ + cell->connections["\\B"] = sig_b; \ + cell->connections["\\S"] = sig_s; \ + cell->connections["\\Y"] = sig_y; \ + add(cell); \ + return cell; \ + } +DEF_METHOD(addMux, "$mux", 0) +DEF_METHOD(addPmux, "$pmux", 1) +DEF_METHOD(addSafePmux, "$safe_pmux", 1) +#undef DEF_METHOD + +RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$pow"; + cell->parameters["\\A_SIGNED"] = a_signed; + cell->parameters["\\B_SIGNED"] = b_signed; + cell->parameters["\\A_WIDTH"] = sig_a.width; + cell->parameters["\\B_WIDTH"] = sig_b.width; + cell->parameters["\\Y_WIDTH"] = sig_y.width; + cell->connections["\\A"] = sig_a; + cell->connections["\\B"] = sig_b; + cell->connections["\\Y"] = sig_y; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$slice"; + cell->parameters["\\A_WIDTH"] = sig_a.width; + cell->parameters["\\Y_WIDTH"] = sig_y.width; + cell->parameters["\\OFFSET"] = offset; + cell->connections["\\A"] = sig_a; + cell->connections["\\Y"] = sig_y; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$concat"; + cell->parameters["\\A_WIDTH"] = sig_a.width; + cell->parameters["\\B_WIDTH"] = sig_b.width; + cell->connections["\\A"] = sig_a; + cell->connections["\\B"] = sig_b; + cell->connections["\\Y"] = sig_y; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, RTLIL::SigSpec sig_o, RTLIL::Const lut) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$lut"; + cell->parameters["\\LUT"] = lut; + cell->parameters["\\WIDTH"] = sig_i.width; + cell->connections["\\I"] = sig_i; + cell->connections["\\O"] = sig_o; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$assert"; + cell->connections["\\A"] = sig_a; + cell->connections["\\EN"] = sig_en; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$sr"; + cell->parameters["\\SET_POLARITY"] = set_polarity; + cell->parameters["\\CLR_POLARITY"] = clr_polarity; + cell->parameters["\\WIDTH"] = sig_q.width; + cell->connections["\\SET"] = sig_set; + cell->connections["\\CLR"] = sig_clr; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$dff"; + cell->parameters["\\CLK_POLARITY"] = clk_polarity; + cell->parameters["\\WIDTH"] = sig_q.width; + cell->connections["\\CLK"] = sig_clk; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$dffsr"; + cell->parameters["\\CLK_POLARITY"] = clk_polarity; + cell->parameters["\\SET_POLARITY"] = set_polarity; + cell->parameters["\\CLR_POLARITY"] = clr_polarity; + cell->parameters["\\WIDTH"] = sig_q.width; + cell->connections["\\CLK"] = sig_clk; + cell->connections["\\SET"] = sig_set; + cell->connections["\\CLR"] = sig_clr; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, + RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$dffsr"; + cell->parameters["\\CLK_POLARITY"] = clk_polarity; + cell->parameters["\\ARST_POLARITY"] = arst_polarity; + cell->parameters["\\ARST_VALUE"] = arst_value; + cell->parameters["\\WIDTH"] = sig_q.width; + cell->connections["\\CLK"] = sig_clk; + cell->connections["\\ARST"] = sig_arst; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$dffsr"; + cell->parameters["\\EN_POLARITY"] = en_polarity; + cell->parameters["\\WIDTH"] = sig_q.width; + cell->connections["\\EN"] = sig_en; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + RTLIL::Wire::Wire() { width = 1; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index caadf198..48f3e392 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -294,6 +294,63 @@ struct RTLIL::Module { void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; + RTLIL::Cell* addNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addPos (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addBu0 (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addNeg (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + + RTLIL::Cell* addAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + + RTLIL::Cell* addReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + + RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + + RTLIL::Cell* addLt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addLe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addEq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addNe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addEqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addNex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addGe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addGt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + + RTLIL::Cell* addAdd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addSub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addMul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addDiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addMod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addPow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed = false, bool b_signed = false); + + RTLIL::Cell* addLogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addLogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addLogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + + RTLIL::Cell* addMux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); + RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); + RTLIL::Cell* addSafePmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); + + RTLIL::Cell* addSlice (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset); + RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); + RTLIL::Cell* addLut (RTLIL::IdString name, RTLIL::SigSpec sig_i, RTLIL::SigSpec sig_o, RTLIL::Const lut); + RTLIL::Cell* addAssert (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en); + + RTLIL::Cell* addSr (RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity = true, bool clr_polarity = true); + RTLIL::Cell* addDff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true); + RTLIL::Cell* addDffsr (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true); + RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, + RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true); + RTLIL::Cell* addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true); }; struct RTLIL::Wire { From c71791a1ffa566585317a01becd5c33ad452fe57 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 03:03:08 +0100 Subject: [PATCH 108/750] Improvements in verific command --- frontends/verific/verific.cc | 96 ++++++++++++++---------------------- 1 file changed, 38 insertions(+), 58 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 5c2b933c..1b25feca 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::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::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); + 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; } From 5a15539c9b4280b1ed3a77a131f3197a1127404f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 12:06:57 +0100 Subject: [PATCH 109/750] Improved verific command (added support for some operators) --- frontends/verific/verific.cc | 162 ++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1b25feca..c78d19f2 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); From 78c64a64017dbc3e15aeac3246d5fc159555fbe2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 12:07:26 +0100 Subject: [PATCH 110/750] Fixed a typo in RTLIL::Module::addReduce... --- kernel/rtlil.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 811289a4..21fcae2b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -862,11 +862,11 @@ DEF_METHOD(addNot, "$not") DEF_METHOD(addPos, "$pos") DEF_METHOD(addBu0, "$bu0") DEF_METHOD(addNeg, "$neg") -DEF_METHOD(addReduceAnd, "$redcue_and") -DEF_METHOD(addReduceOr, "$redcue_or") -DEF_METHOD(addReduceXor, "$redcue_xor") -DEF_METHOD(addReduceXnor, "$redcue_xnor") -DEF_METHOD(addReduceBool, "$redcue_bool") +DEF_METHOD(addReduceAnd, "$reduce_and") +DEF_METHOD(addReduceOr, "$reduce_or") +DEF_METHOD(addReduceXor, "$reduce_xor") +DEF_METHOD(addReduceXnor, "$reduce_xnor") +DEF_METHOD(addReduceBool, "$reduce_bool") DEF_METHOD(addLogicNot, "$logic_not") #undef DEF_METHOD From 9b3d83359cc3f55049b5a48cb736a9a43bf04afc Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:35:46 +0100 Subject: [PATCH 111/750] - passes/techmap/dfflibmap.cc, passes/fsm/fsm_recode.cc, passes/cmds/select.cc: #include for errno, use c++-style includes. --- passes/cmds/select.cc | 1 + passes/fsm/fsm_recode.cc | 3 ++- passes/techmap/dfflibmap.cc | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 3a886b1c..59f936b0 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -23,6 +23,7 @@ #include "kernel/log.h" #include #include +#include using RTLIL::id2cstr; diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 5a4e091c..b0228796 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -23,8 +23,9 @@ #include "kernel/consteval.h" #include "kernel/celltypes.h" #include "fsmdata.h" -#include "math.h" +#include #include +#include static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &fsm_data, const char *prefix, FILE *f) { diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index fd5fa86e..4bf73358 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -21,6 +21,7 @@ #include "kernel/log.h" #include "libparse.h" #include +#include using namespace PASS_DFFLIBMAP; From f7c2cf6fe29fc452385c37f015e03febf650ecd3 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:35:53 +0100 Subject: [PATCH 112/750] - passes/abc/abc.cc: #include for errno; use POSIX getcwd() for portability (get_current_dir_name() does not exist on BSD). --- passes/abc/abc.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 2829e660..24a634f6 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "blifparse.h" @@ -973,7 +974,11 @@ struct AbcPass : public Pass { int lut_mode = 0; size_t argidx; - char *pwd = get_current_dir_name(); + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s\n", strerror(errno)); + log_abort(); + } for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-exe" && argidx+1 < args.size()) { @@ -1020,7 +1025,6 @@ struct AbcPass : public Pass { } break; } - free(pwd); extra_args(args, argidx, design); if (lut_mode != 0 && !liberty_file.empty()) From 40e0b79495195eaa2bc6bf32e8d52a5aa956a2b4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:35:59 +0100 Subject: [PATCH 113/750] - libs/ezsat/ezsat.cc: need to #include or math.h for math functions. --- libs/ezsat/ezsat.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index fb3d2499..6da363fc 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -19,10 +19,11 @@ #include "ezsat.h" +#include #include +#include #include -#include const int ezSAT::TRUE = 1; const int ezSAT::FALSE = 2; From 8111938e962b60294e51d5f0d10b6d1855bc1b91 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:07 +0100 Subject: [PATCH 114/750] - kernel/log.h: add rusage()-based fallback for systems without clock_gettime(). --- kernel/log.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/kernel/log.h b/kernel/log.h index c4c03352..fbc3c1c3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -23,6 +23,8 @@ #include "kernel/rtlil.h" #include #include +#include +#include #include extern std::vector log_files; @@ -65,9 +67,23 @@ struct PerformanceTimer } static int64_t query() { +#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) struct timespec ts; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); return int64_t(ts.tv_sec)*1000000000 + ts.tv_nsec; +#elif defined(RUSAGE_SELF) + struct rusage rusage; + int64_t t; + if (getrusage(RUSAGE_SELF, &rusage) == -1) { + log_cmd_error("getrusage failed!\n"); + log_abort(); + } + t = 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; + t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; + return t; +#else + #error Dont know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?). +#endif } void reset() { From 6698d67d2416069ea728b879db67b6ea0582cce4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:12 +0100 Subject: [PATCH 115/750] - kernel/driver.cc: need to #include or errno.h for errno. --- kernel/driver.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/driver.cc b/kernel/driver.cc index 00a61ec0..ce95cad4 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include From c056217e72ff1e2da1340f97ad3a76f3ed486841 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:23 +0100 Subject: [PATCH 116/750] - kernel/register.cc: need to #include or errno.h for errno. --- kernel/register.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/register.cc b/kernel/register.cc index ee14ffba..ab5cba11 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -23,6 +23,7 @@ #include #include #include +#include using namespace REGISTER_INTERN; #define MAX_REG_COUNT 1000 From f6579282d73aec055e2fc4ebebd1b6313da248fd Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:27 +0100 Subject: [PATCH 117/750] - frontends/vhdl2verilog/vhdl2verilog.cc: #include for errno; use POSIX getcwd() for portability. --- frontends/vhdl2verilog/vhdl2verilog.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 0467810e..d8568fe9 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -26,6 +26,7 @@ #include #include #include +#include struct Vhdl2verilogPass : public Pass { Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } @@ -93,9 +94,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 +108,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()); From 9327d434d522f888609e5f4a42a6e06f01864e79 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:37:14 +0100 Subject: [PATCH 118/750] - README: fix typo in sed-command for minisat-include fix. --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 385ee2c0..45febc2f 100644 --- a/README +++ b/README @@ -292,7 +292,7 @@ a recent version of gcc: This is a bug in the minisat header. It can be fixed by adding spaces before and after each occurrence of PRIi64 in the header file: - sudo sed -i 's/PRIi64/ & /' /usr/include/minisat/utils/Options.h + sudo sed -i -e 's/PRIi64/ & /' /usr/include/minisat/utils/Options.h Roadmap / Large-scale TODOs From 0fb044a58f7cc66364af3a0a53c8b5089e0149ad Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:38:01 +0100 Subject: [PATCH 119/750] - Makefile, kernel/posix_compatibility.h/.cc: provide POSIX.2008 fake implementation of open_memstream()/fmemopen() for pre-POSIX.2008 systems. - Makefile: OSX build rules (Apple's gcc and clang have no -rdynamic option and no librt). - Makefile: Generate debugger symbols and don't optimize for size in debug target (otherwise the debugger pretty hard to use). - Makefile: Reorder target concatenation in order to avoid use-before-built problems for source-include and linker dependencies. - Makefile: On OSX/macports, qmake-qt4 is named 'qmake' (the default Qt4 installation name, unless the distribution changes it). - Makefile: For OSX/Macports, we need to pass -I/opt/local/include and -L/opt/local/lib to give GNU libraries precedence over Apple's. - Makefile: Build a local minisat copy just like abc (to avoid dependency on broken/unmaintained distribution header files). - .gitignore: Ignore minisat directory. --- .gitignore | 1 + Makefile | 46 +++++++++--- kernel/posix_compatibility.cc | 134 ++++++++++++++++++++++++++++++++++ kernel/posix_compatibility.h | 40 ++++++++++ 4 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 kernel/posix_compatibility.cc create mode 100644 kernel/posix_compatibility.h diff --git a/.gitignore b/.gitignore index f251d2b6..77d6e29e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /qtcreator.creator /qtcreator.creator.user /Makefile.conf +/minisat /abc /yosys /yosys-abc diff --git a/Makefile b/Makefile index a68ceccb..c0d43a2c 100644 --- a/Makefile +++ b/Makefile @@ -19,14 +19,24 @@ INSTALL_SUDO := OBJS = GENFILES = EXTRA_TARGETS = -TARGETS = yosys yosys-config +TARGETS = all: top-all -CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -LDFLAGS = -rdynamic -LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt -QMAKE = qmake-qt4 +CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h +LDFLAGS = -I${DESTDIR}/lib +LDLIBS = -lstdc++ -lreadline -lm -ldl + +ifeq (Darwin,$(findstring Darwin,$(shell uname))) + # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + CXXFLAGS += -I/opt/local/include + LDFLAGS += -L/opt/local/lib + QMAKE = qmake +else + LDFLAGS += -rdynamic + LDLIBS += -lrt + QMAKE = qmake-qt4 +endif YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) @@ -41,16 +51,18 @@ OBJS = kernel/version_$(GIT_REV).o ABCREV = 2058c8ccea68 ABCPULL = 1 +MINISATREV = HEAD + -include Makefile.conf ifeq ($(CONFIG),clang-debug) CXX = clang -CXXFLAGS += -std=c++11 -Os +CXXFLAGS += -std=c++11 -g -O0 -Wall endif ifeq ($(CONFIG),gcc-debug) CXX = gcc -CXXFLAGS += -std=gnu++0x -Os +CXXFLAGS += -std=gnu++0x -g -O0 -Wall endif ifeq ($(CONFIG),release) @@ -70,8 +82,8 @@ CXXFLAGS += -pg -fno-inline LDFLAGS += -pg endif -ifeq ($(ENABLE_QT4),1) -TARGETS += yosys-svgviewer +ifeq ($(ENABLE_MINISAT),1) +TARGETS += yosys-minisat endif ifeq ($(ENABLE_ABC),1) @@ -85,7 +97,14 @@ CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -D'VERIFIC_DI LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif -OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o +# Build yosys after minisat and abc (we need to access the local copies of the downloaded/installed header files). +TARGETS += yosys yosys-config + +ifeq ($(ENABLE_QT4),1) +TARGETS += yosys-svgviewer +endif + +OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/posix_compatibility.o OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o @@ -123,6 +142,13 @@ yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make cp libs/svgviewer/svgviewer yosys-svgviewer +yosys-minisat: $(DESTDIR)/bin/minisat +$(DESTDIR)/bin/minisat: + test -d minisat || ( git clone https://github.com/niklasso/minisat.git minisat && sed -i -e 's/PRIi64/ & /' minisat/minisat/utils/Options.h ) + ( cd minisat && git checkout $(MINISATREV) ) + ( cd minisat && $(MAKE) prefix=$(DESTDIR) DESTDIR="" config install ) + @( cd minisat && echo "Installed minisat version `git describe --always --dirty` into $(DESTDIR)." ) + abc/abc-$(ABCREV): ifneq ($(ABCREV),default) if ( cd abc && hg identify; ) | grep -q +; then \ diff --git a/kernel/posix_compatibility.cc b/kernel/posix_compatibility.cc new file mode 100644 index 00000000..d3fb0087 --- /dev/null +++ b/kernel/posix_compatibility.cc @@ -0,0 +1,134 @@ +/* + * 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. + * + */ + +/** + * POSIX.2008 fake implementation for pre-POSIX.2008 systems. (OSX, BSD, MINGW, CYGWIN, older Linux &c.) + */ + +#include +#include +#include +#include + +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) +typedef struct memstream { + off_t pos; + off_t size; + char * buffer; + char ** bufp; + size_t * sizep; + bool realloc; +} memstream_t; + +static int memstream_read (void * cookie, char * buf, int size) +{ + memstream_t * mem = (memstream_t *) cookie; + off_t available = mem->size - mem->pos; + if (available < 0) + available = 0; + if (size > available) + size = available; + memcpy(buf, mem->buffer + mem->pos, size); + mem->pos += size; + return size; +} + +static int memstream_write (void * cookie, const char * buf, int size) +{ + memstream_t * mem = (memstream_t *) cookie; + off_t available = mem->size - mem->pos; + if (size > available) { + if (mem->realloc) { + mem->buffer = (char *) realloc(mem->buffer, mem->pos + size + 1); + memset(mem->buffer + mem->size, 0, mem->pos + size + 1 - mem->size); + mem->size = mem->pos + size; + if (mem->bufp) + *(mem->bufp) = mem->buffer; + if (mem->sizep) + *(mem->sizep) = mem->size; + } else { + size = available; + } + } + memcpy(mem->buffer + mem->pos, buf, sizeof(char) * size); + mem->pos += size; + return size; +} + +static fpos_t memstream_seek (void * cookie, fpos_t offset, int whence) +{ + memstream_t * mem = (memstream_t *) cookie; + switch (whence) { + case SEEK_SET: + if (offset < 0) + goto error_inval; + mem->pos = offset; + return 0; + case SEEK_CUR: + if (mem->pos + offset < 0) + goto error_inval; + mem->pos += offset; + return 0; + case SEEK_END: + if (mem->size + offset < 0) + goto error_inval; + mem->pos = mem->size + offset; + break; + default: + goto error_inval; + } + return mem->pos; +error_inval: + errno = EINVAL; + return -1; +} + +static int memstream_close (void * cookie) +{ + memstream_t * mem = (memstream_t *) cookie; + if (mem->bufp) + *(mem->bufp) = mem->buffer; + if (mem->sizep) + *(mem->sizep) = mem->size; + free(cookie); + return 0; +} + +FILE * fmemopen (void * buf, size_t size, const char * mode) +{ + memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); + memset(mem, 0, sizeof(memstream_t)); + mem->size = size; + mem->buffer = (char *) buf; + (void) mode; + return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); +} + +FILE * open_memstream (char ** bufp, size_t * sizep) +{ + memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); + memset(mem, 0, sizeof(memstream_t)); + mem->bufp = bufp; + mem->sizep = sizep; + mem->realloc = true; + return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); +} + +#endif + diff --git a/kernel/posix_compatibility.h b/kernel/posix_compatibility.h new file mode 100644 index 00000000..d6eaade0 --- /dev/null +++ b/kernel/posix_compatibility.h @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +#ifndef POSIX_COMPATIBILITY_H +#define POSIX_COMPATIBILITY_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include + +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) +FILE * open_memstream (char ** bufp, size_t * sizep); +FILE * fmemopen (void * buf, size_t size, const char * mode); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + From 8a0216bd9f81faf45e1ff463edcc6d82dfa20565 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 15:02:58 +0100 Subject: [PATCH 120/750] - libs/ezsat/ezminisat.cc: use POSIX.2001 sigaction() instead on non-portable signal(). --- libs/ezsat/ezminisat.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index d488a906..92f56b00 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -170,14 +170,18 @@ contradiction: #endif } - sighandler_t old_alarm_sighandler = NULL; + struct sigaction sig_action; + struct sigaction old_sig_action; int old_alarm_timeout = 0; if (solverTimeout > 0) { + sig_action.sa_handler = alarmHandler; + sig_action.sa_mask = 0; + sig_action.sa_flags = 0; alarmHandlerThis = this; alarmHandlerTimeout = clock() + solverTimeout*CLOCKS_PER_SEC; old_alarm_timeout = alarm(0); - old_alarm_sighandler = signal(SIGALRM, alarmHandler); + sigaction(SIGALRM, &sig_action, &old_sig_action); alarm(1); } @@ -187,7 +191,7 @@ contradiction: if (alarmHandlerTimeout == 0) solverTimoutStatus = true; alarm(0); - signal(SIGALRM, old_alarm_sighandler); + sigaction(SIGALRM, &old_sig_action, NULL); alarm(old_alarm_timeout); } From 63ca8d3fe4273d9e07233f94037a63659d6d18e4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 15:07:37 +0100 Subject: [PATCH 121/750] - Makefile, techlibs/common/Makefile.inc: call GNU sed instead of BSD sed on OSX (for extended regular expressions). --- Makefile | 6 ++++-- techlibs/common/Makefile.inc | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c0d43a2c..7bd8a450 100644 --- a/Makefile +++ b/Makefile @@ -32,10 +32,12 @@ ifeq (Darwin,$(findstring Darwin,$(shell uname))) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake + SED = gsed else LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 + SED = sed endif YOSYS_VER := 0.2.0+ @@ -134,7 +136,7 @@ kernel/version_$(GIT_REV).cc: Makefile echo "extern const char *yosys_version_str; const char *yosys_version_str=\"Yosys $(YOSYS_VER) (git sha1 $(GIT_REV))\";" > kernel/version_$(GIT_REV).cc yosys-config: yosys-config.in - sed -e 's,@CXX@,$(CXX),;' -e 's,@CXXFLAGS@,$(CXXFLAGS),;' -e 's,@LDFLAGS@,$(LDFLAGS),;' -e 's,@LDLIBS@,$(LDLIBS),;' \ + $(SED) -e 's,@CXX@,$(CXX),;' -e 's,@CXXFLAGS@,$(CXXFLAGS),;' -e 's,@LDFLAGS@,$(LDFLAGS),;' -e 's,@LDLIBS@,$(LDLIBS),;' \ -e 's,@BINDIR@,$(DESTDIR)/bin,;' -e 's,@DATDIR@,$(DESTDIR)/share/yosys,;' < yosys-config.in > yosys-config chmod +x yosys-config @@ -144,7 +146,7 @@ yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp yosys-minisat: $(DESTDIR)/bin/minisat $(DESTDIR)/bin/minisat: - test -d minisat || ( git clone https://github.com/niklasso/minisat.git minisat && sed -i -e 's/PRIi64/ & /' minisat/minisat/utils/Options.h ) + test -d minisat || ( git clone https://github.com/niklasso/minisat.git minisat && $(SED) -i -e 's/PRIi64/ & /' minisat/minisat/utils/Options.h ) ( cd minisat && git checkout $(MINISATREV) ) ( cd minisat && $(MAKE) prefix=$(DESTDIR) DESTDIR="" config install ) @( cd minisat && echo "Installed minisat version `git describe --always --dirty` into $(DESTDIR)." ) diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 6d94d5c9..c68b13f6 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -2,7 +2,7 @@ EXTRA_TARGETS += techlibs/common/blackbox.v techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib.v techlibs/common/simcells.v - cat techlibs/common/simlib.v techlibs/common/simcells.v | sed -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new + cat techlibs/common/simlib.v techlibs/common/simcells.v | $(SED) -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v EXTRA_TARGETS += share/simlib.v share/simcells.v share/blackbox.v share/pmux2mux.v From 2f2e76ac68dc8da8618ebbf602e2c871f5d4b1b8 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 19:50:02 +0100 Subject: [PATCH 122/750] - frontends/vhdl2verilog/vhdl2verilog.cc, passes/abc/abc.cc: #include for PATH_MAX. --- frontends/vhdl2verilog/vhdl2verilog.cc | 1 + passes/abc/abc.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index d8568fe9..83035d32 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -27,6 +27,7 @@ #include #include #include +#include struct Vhdl2verilogPass : public Pass { Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 24a634f6..286b750c 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -45,6 +45,7 @@ #include #include #include +#include #include "blifparse.h" From 4d56e23e318a6739ec06ce74d81dfa1d940aef0f Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: [PATCH 123/750] - Makefile: export PATH=${DESTDIR}/bin:$(PATH) and (DY)LD_LIBRARY_PATH, to make sure our local copies of built executables and libraries are used. - Makefile: use find expression in target 'yosys-svgviewer' to find svgviewer binary (qmake will build into .app package on OSX). - Makefile: make 'test' target dependent on $(TARGETS) and $(EXTRA_TARGETS) to make sure that minisat is built. --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7bd8a450..82c09d05 100644 --- a/Makefile +++ b/Makefile @@ -27,13 +27,17 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -I${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl +export PATH := ${DESTDIR}/bin:$(PATH) + ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else + export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 @@ -142,7 +146,7 @@ yosys-config: yosys-config.in yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make - cp libs/svgviewer/svgviewer yosys-svgviewer + cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer yosys-minisat: $(DESTDIR)/bin/minisat $(DESTDIR)/bin/minisat: @@ -172,7 +176,7 @@ endif yosys-abc: abc/abc-$(ABCREV) cp abc/abc-$(ABCREV) yosys-abc -test: yosys +test: $(TARGETS) $(EXTRA_TARGETS) cd tests/simple && bash run-test.sh cd tests/hana && bash run-test.sh cd tests/asicworld && bash run-test.sh From 113f129b348c48fff67242fe65906b3821ae7bd4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: [PATCH 124/750] - Makefile: fix typo in LDFLAGS: obviously -L, not -I is required here --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 82c09d05..849860a3 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ TARGETS = all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h -LDFLAGS = -I${DESTDIR}/lib +LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl export PATH := ${DESTDIR}/bin:$(PATH) From d091be401140088431ac2c1bf2bc97415e37c9ff Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:23:55 +0100 Subject: [PATCH 125/750] - libs/ezsat/ezminisat.cc: use sigemptyset() to clear sig_action.sa_mask; use SA_RESTART flag for improved robustness of code that is not signal-aware. --- libs/ezsat/ezminisat.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 92f56b00..4677f68b 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -176,8 +176,8 @@ contradiction: if (solverTimeout > 0) { sig_action.sa_handler = alarmHandler; - sig_action.sa_mask = 0; - sig_action.sa_flags = 0; + sigemptyset(&sig_action.sa_mask); + sig_action.sa_flags = SA_RESTART; alarmHandlerThis = this; alarmHandlerTimeout = clock() + solverTimeout*CLOCKS_PER_SEC; old_alarm_timeout = alarm(0); From 876c016904989bc54eafada1363e31f291854542 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: [PATCH 126/750] - Makefile: include $(PWD) in PATH, since 'make test' can happen before 'make install'. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 849860a3..ce9a99bc 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := ${DESTDIR}/bin:$(PATH) +export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': From 4fd1a4c12b8a57454bc6e7f3b7bba6a7aeade96c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 11:39:30 +0100 Subject: [PATCH 127/750] Use "verilog -noattr" in tests/techmap/mem_simple_4x1 test (for old iverilog) --- tests/techmap/mem_simple_4x1_runtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/techmap/mem_simple_4x1_runtest.sh b/tests/techmap/mem_simple_4x1_runtest.sh index 8285875b..541da483 100644 --- a/tests/techmap/mem_simple_4x1_runtest.sh +++ b/tests/techmap/mem_simple_4x1_runtest.sh @@ -2,7 +2,7 @@ set -ev -yosys -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v +yosys -b 'verilog -noattr' -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v iverilog -o mem_simple_4x1_gold_tb mem_simple_4x1_tb.v mem_simple_4x1_uut.v iverilog -o mem_simple_4x1_gate_tb mem_simple_4x1_tb.v mem_simple_4x1_synth.v mem_simple_4x1_cells.v From bada3ee815c05933723a64234106ab68b7599568 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 11:59:58 +0100 Subject: [PATCH 128/750] Fixed yosys path in tests/techmap/mem_simple_4x1_runtest.sh --- tests/techmap/mem_simple_4x1_runtest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/techmap/mem_simple_4x1_runtest.sh b/tests/techmap/mem_simple_4x1_runtest.sh index 541da483..e2c6303d 100644 --- a/tests/techmap/mem_simple_4x1_runtest.sh +++ b/tests/techmap/mem_simple_4x1_runtest.sh @@ -2,7 +2,7 @@ set -ev -yosys -b 'verilog -noattr' -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v +../../yosys -b 'verilog -noattr' -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v iverilog -o mem_simple_4x1_gold_tb mem_simple_4x1_tb.v mem_simple_4x1_uut.v iverilog -o mem_simple_4x1_gate_tb mem_simple_4x1_tb.v mem_simple_4x1_synth.v mem_simple_4x1_cells.v From fa75c8286e066ba4b73da94068662834cb671640 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 13:09:01 +0100 Subject: [PATCH 129/750] Fixed memory corruption in passes/abc/blifparse.cc --- passes/abc/blifparse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 2d46d1a8..1d4da19a 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -40,7 +40,7 @@ static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count, } if (buffer_len == 0 || buffer[buffer_len-1] == '\\') { - if (buffer[buffer_len-1] == '\\') + if (buffer_len > 0 && buffer[buffer_len-1] == '\\') buffer[--buffer_len] = 0; line_count++; if (fgets(buffer+buffer_len, buffer_size-buffer_len, f) == NULL) From 707b46956e7de08ae44ec1d8812fe0393e60457b Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 14:06:41 +0100 Subject: [PATCH 130/750] - passes/techmap/Makefile.inc: POSIX 'od' has no '-w' option. Use '-An' instead. Replace awk by simple shell commands for portability. --- passes/techmap/Makefile.inc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index ae1ebbb5..b83ab849 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -10,10 +10,12 @@ OBJS += passes/techmap/extract.o GENFILES += passes/techmap/stdcells.inc passes/techmap/stdcells.inc: techlibs/common/stdcells.v - echo "// autogenerated from $<" > $@.new - od -v -td1 -w1 $< | awk 'BEGIN { print "static char stdcells_code[] = {"; } $$2 != "" { print $$2 ","; } \ - END { print 0 "};"; }' | fmt >> $@.new - mv $@.new $@ + echo "// autogenerated from $<\n" > $@.new + echo "static char stdcells_code[] = {" >> $@.new + for c in `od -v -td1 -An $<` ; do echo " $$c," >> $@.new ; done + echo " 0 };" >> $@.new + fmt $@.new > $@ + rm -f $@.new passes/techmap/techmap.o: passes/techmap/stdcells.inc From 9992026a8d4482abd8fbae8cb246a87cbbbde364 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:06:57 +0100 Subject: [PATCH 131/750] Added support for `line compiler directive --- frontends/verilog/lexer.l | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 79f44b4a..e3e5e4ab 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); } From 91704a78531bec2e3eea3ddf90eaedb28e1d696d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:24:24 +0100 Subject: [PATCH 132/750] Merged a few fixes for non-posix systems from github.com/Siesh1oo/yosys (see https://github.com/cliffordwolf/yosys/pull/28) --- README | 2 +- frontends/vhdl2verilog/vhdl2verilog.cc | 16 ++++++++++++---- kernel/driver.cc | 1 + kernel/log.h | 16 ++++++++++++++++ kernel/register.cc | 1 + libs/ezsat/ezminisat.cc | 12 ++++++++---- libs/ezsat/ezsat.cc | 3 ++- passes/abc/abc.cc | 9 +++++++-- passes/cmds/select.cc | 1 + passes/fsm/fsm_recode.cc | 3 ++- passes/techmap/dfflibmap.cc | 1 + 11 files changed, 52 insertions(+), 13 deletions(-) diff --git a/README b/README index 385ee2c0..45febc2f 100644 --- a/README +++ b/README @@ -292,7 +292,7 @@ a recent version of gcc: This is a bug in the minisat header. It can be fixed by adding spaces before and after each occurrence of PRIi64 in the header file: - sudo sed -i 's/PRIi64/ & /' /usr/include/minisat/utils/Options.h + sudo sed -i -e 's/PRIi64/ & /' /usr/include/minisat/utils/Options.h Roadmap / Large-scale TODOs diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 0467810e..83035d32 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()); diff --git a/kernel/driver.cc b/kernel/driver.cc index 00a61ec0..ce95cad4 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include diff --git a/kernel/log.h b/kernel/log.h index c4c03352..fbc3c1c3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -23,6 +23,8 @@ #include "kernel/rtlil.h" #include #include +#include +#include #include extern std::vector log_files; @@ -65,9 +67,23 @@ struct PerformanceTimer } static int64_t query() { +#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) struct timespec ts; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); return int64_t(ts.tv_sec)*1000000000 + ts.tv_nsec; +#elif defined(RUSAGE_SELF) + struct rusage rusage; + int64_t t; + if (getrusage(RUSAGE_SELF, &rusage) == -1) { + log_cmd_error("getrusage failed!\n"); + log_abort(); + } + t = 1000000000ULL * (int64_t) rusage.ru_utime.tv_sec + (int64_t) rusage.ru_utime.tv_usec * 1000ULL; + t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL; + return t; +#else + #error Dont know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?). +#endif } void reset() { diff --git a/kernel/register.cc b/kernel/register.cc index ee14ffba..ab5cba11 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -23,6 +23,7 @@ #include #include #include +#include using namespace REGISTER_INTERN; #define MAX_REG_COUNT 1000 diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index d488a906..4677f68b 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -170,14 +170,18 @@ contradiction: #endif } - sighandler_t old_alarm_sighandler = NULL; + struct sigaction sig_action; + struct sigaction old_sig_action; int old_alarm_timeout = 0; if (solverTimeout > 0) { + sig_action.sa_handler = alarmHandler; + sigemptyset(&sig_action.sa_mask); + sig_action.sa_flags = SA_RESTART; alarmHandlerThis = this; alarmHandlerTimeout = clock() + solverTimeout*CLOCKS_PER_SEC; old_alarm_timeout = alarm(0); - old_alarm_sighandler = signal(SIGALRM, alarmHandler); + sigaction(SIGALRM, &sig_action, &old_sig_action); alarm(1); } @@ -187,7 +191,7 @@ contradiction: if (alarmHandlerTimeout == 0) solverTimoutStatus = true; alarm(0); - signal(SIGALRM, old_alarm_sighandler); + sigaction(SIGALRM, &old_sig_action, NULL); alarm(old_alarm_timeout); } diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index fb3d2499..6da363fc 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -19,10 +19,11 @@ #include "ezsat.h" +#include #include +#include #include -#include const int ezSAT::TRUE = 1; const int ezSAT::FALSE = 2; diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 2829e660..286b750c 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -43,7 +43,9 @@ #include #include #include +#include #include +#include #include "blifparse.h" @@ -973,7 +975,11 @@ struct AbcPass : public Pass { int lut_mode = 0; size_t argidx; - char *pwd = get_current_dir_name(); + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s\n", strerror(errno)); + log_abort(); + } for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-exe" && argidx+1 < args.size()) { @@ -1020,7 +1026,6 @@ struct AbcPass : public Pass { } break; } - free(pwd); extra_args(args, argidx, design); if (lut_mode != 0 && !liberty_file.empty()) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 3a886b1c..59f936b0 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -23,6 +23,7 @@ #include "kernel/log.h" #include #include +#include using RTLIL::id2cstr; diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 5a4e091c..b0228796 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -23,8 +23,9 @@ #include "kernel/consteval.h" #include "kernel/celltypes.h" #include "fsmdata.h" -#include "math.h" +#include #include +#include static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &fsm_data, const char *prefix, FILE *f) { diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index fd5fa86e..4bf73358 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -21,6 +21,7 @@ #include "kernel/log.h" #include "libparse.h" #include +#include using namespace PASS_DFFLIBMAP; From 7aa2d746b76a354daedd4c8a7b4d8c15b1805b21 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:42:58 +0100 Subject: [PATCH 133/750] Merged addition of SED makefile variable from github.com/Siesh1oo/yosys (see https://github.com/cliffordwolf/yosys/pull/28) --- Makefile | 3 ++- techlibs/common/Makefile.inc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a68ceccb..abb473ba 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC LDFLAGS = -rdynamic LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt QMAKE = qmake-qt4 +SED = sed YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) @@ -115,7 +116,7 @@ kernel/version_$(GIT_REV).cc: Makefile echo "extern const char *yosys_version_str; const char *yosys_version_str=\"Yosys $(YOSYS_VER) (git sha1 $(GIT_REV))\";" > kernel/version_$(GIT_REV).cc yosys-config: yosys-config.in - sed -e 's,@CXX@,$(CXX),;' -e 's,@CXXFLAGS@,$(CXXFLAGS),;' -e 's,@LDFLAGS@,$(LDFLAGS),;' -e 's,@LDLIBS@,$(LDLIBS),;' \ + $(SED) -e 's,@CXX@,$(CXX),;' -e 's,@CXXFLAGS@,$(CXXFLAGS),;' -e 's,@LDFLAGS@,$(LDFLAGS),;' -e 's,@LDLIBS@,$(LDLIBS),;' \ -e 's,@BINDIR@,$(DESTDIR)/bin,;' -e 's,@DATDIR@,$(DESTDIR)/share/yosys,;' < yosys-config.in > yosys-config chmod +x yosys-config diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 6d94d5c9..c68b13f6 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -2,7 +2,7 @@ EXTRA_TARGETS += techlibs/common/blackbox.v techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib.v techlibs/common/simcells.v - cat techlibs/common/simlib.v techlibs/common/simcells.v | sed -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new + cat techlibs/common/simlib.v techlibs/common/simcells.v | $(SED) -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v EXTRA_TARGETS += share/simlib.v share/simcells.v share/blackbox.v share/pmux2mux.v From 9087ece97c20d76359fb23cfd7a0f13552c1f2fd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:52:37 +0100 Subject: [PATCH 134/750] OSX compatible creation of stdcells.inc, using code from github.com/Siesh1oo/yosys (see https://github.com/cliffordwolf/yosys/pull/28) --- passes/techmap/Makefile.inc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index ae1ebbb5..85d580ce 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -11,8 +11,9 @@ GENFILES += passes/techmap/stdcells.inc passes/techmap/stdcells.inc: techlibs/common/stdcells.v echo "// autogenerated from $<" > $@.new - od -v -td1 -w1 $< | awk 'BEGIN { print "static char stdcells_code[] = {"; } $$2 != "" { print $$2 ","; } \ - END { print 0 "};"; }' | fmt >> $@.new + echo "static char stdcells_code[] = {" >> $@.new + od -v -td1 -An $< | $(SED) -e 's/[0-9][0-9]*/&,/g' >> $@.new + echo "0};" >> $@.new mv $@.new $@ passes/techmap/techmap.o: passes/techmap/stdcells.inc From 59d68e158281983c6b18914fb29c09b130552479 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 19:39:01 +0100 Subject: [PATCH 135/750] - Makefile: resolve merge conflict. --- Makefile | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index abb473ba..5f40b594 100644 --- a/Makefile +++ b/Makefile @@ -23,11 +23,22 @@ TARGETS = yosys yosys-config all: top-all -CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -LDFLAGS = -rdynamic -LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt -QMAKE = qmake-qt4 -SED = sed +CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h +LDFLAGS = -I${DESTDIR}/lib +LDLIBS = -lstdc++ -lreadline -lm -ldl + +ifeq (Darwin,$(findstring Darwin,$(shell uname))) + # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + CXXFLAGS += -I/opt/local/include + LDFLAGS += -L/opt/local/lib + QMAKE = qmake + SED = gsed +else + LDFLAGS += -rdynamic + LDLIBS += -lrt + QMAKE = qmake-qt4 + SED = sed +endif YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) @@ -124,6 +135,13 @@ yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make cp libs/svgviewer/svgviewer yosys-svgviewer +yosys-minisat: $(DESTDIR)/bin/minisat +$(DESTDIR)/bin/minisat: + test -d minisat || ( git clone https://github.com/niklasso/minisat.git minisat && $(SED) -i -e 's/PRIi64/ & /' minisat/minisat/utils/Options.h ) + ( cd minisat && git checkout $(MINISATREV) ) + ( cd minisat && $(MAKE) prefix=$(DESTDIR) DESTDIR="" config install ) + @( cd minisat && echo "Installed minisat version `git describe --always --dirty` into $(DESTDIR)." ) + abc/abc-$(ABCREV): ifneq ($(ABCREV),default) if ( cd abc && hg identify; ) | grep -q +; then \ From 4958559456c849811f213cb1b9e2beea61916e3c Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: [PATCH 136/750] - Makefile: export PATH=${DESTDIR}/bin:$(PATH) and (DY)LD_LIBRARY_PATH, to make sure our local copies of built executables and libraries are used. - Makefile: use find expression in target 'yosys-svgviewer' to find svgviewer binary (qmake will build into .app package on OSX). - Makefile: make 'test' target dependent on $(TARGETS) and $(EXTRA_TARGETS) to make sure that minisat is built. --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5f40b594..ad68ee1e 100644 --- a/Makefile +++ b/Makefile @@ -27,13 +27,17 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -I${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl +export PATH := ${DESTDIR}/bin:$(PATH) + ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else + export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 @@ -133,7 +137,7 @@ yosys-config: yosys-config.in yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make - cp libs/svgviewer/svgviewer yosys-svgviewer + cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer yosys-minisat: $(DESTDIR)/bin/minisat $(DESTDIR)/bin/minisat: @@ -163,7 +167,7 @@ endif yosys-abc: abc/abc-$(ABCREV) cp abc/abc-$(ABCREV) yosys-abc -test: yosys +test: $(TARGETS) $(EXTRA_TARGETS) cd tests/simple && bash run-test.sh cd tests/hana && bash run-test.sh cd tests/asicworld && bash run-test.sh From 4d56fbc150e5dcdefb1709d82aee91c9bb0d1227 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: [PATCH 137/750] - Makefile: fix typo in LDFLAGS: obviously -L, not -I is required here --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ad68ee1e..75a8f42b 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ TARGETS = yosys yosys-config all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h -LDFLAGS = -I${DESTDIR}/lib +LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl export PATH := ${DESTDIR}/bin:$(PATH) From c17ee0f6dd5bb6e53ff0bf6da4650972323fc82d Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: [PATCH 138/750] - Makefile: include $(PWD) in PATH, since 'make test' can happen before 'make install'. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 75a8f42b..9f888c86 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := ${DESTDIR}/bin:$(PATH) +export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': From 59239f65dda58980c5b20a4b4723cd725e740fda Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 22:00:49 +0100 Subject: [PATCH 139/750] - Makefile: don't add '-g' after '-ggdb' to CXXFLAGS --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index ce9a99bc..c1c81b8e 100644 --- a/Makefile +++ b/Makefile @@ -63,12 +63,12 @@ MINISATREV = HEAD ifeq ($(CONFIG),clang-debug) CXX = clang -CXXFLAGS += -std=c++11 -g -O0 -Wall +CXXFLAGS += -std=c++11 -O0 -Wall endif ifeq ($(CONFIG),gcc-debug) CXX = gcc -CXXFLAGS += -std=gnu++0x -g -O0 -Wall +CXXFLAGS += -std=gnu++0x -O0 -Wall endif ifeq ($(CONFIG),release) From 94c1307c262e4b14f4a91b1bbcf9099ee6202bab Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Mar 2014 10:17:51 +0100 Subject: [PATCH 140/750] Added libs/minisat (copy of minisat git master) --- Makefile | 9 +- README | 15 - kernel/satgen.h | 7 +- libs/ezsat/ezminisat.cc | 9 +- libs/minisat/Alg.h | 84 +++ libs/minisat/Alloc.h | 131 +++++ libs/minisat/Dimacs.h | 87 +++ libs/minisat/Heap.h | 168 ++++++ libs/minisat/IntMap.h | 106 ++++ libs/minisat/IntTypes.h | 42 ++ libs/minisat/LICENSE | 21 + libs/minisat/Map.h | 193 +++++++ libs/minisat/Options.cc | 94 ++++ libs/minisat/Options.h | 386 +++++++++++++ libs/minisat/ParseUtils.h | 129 +++++ libs/minisat/Queue.h | 69 +++ libs/minisat/Rnd.h | 67 +++ libs/minisat/SimpSolver.cc | 727 ++++++++++++++++++++++++ libs/minisat/SimpSolver.h | 222 ++++++++ libs/minisat/Solver.cc | 1068 ++++++++++++++++++++++++++++++++++++ libs/minisat/Solver.h | 409 ++++++++++++++ libs/minisat/SolverTypes.h | 478 ++++++++++++++++ libs/minisat/Sort.h | 98 ++++ libs/minisat/System.cc | 171 ++++++ libs/minisat/System.h | 72 +++ libs/minisat/UPDATE.sh | 12 + libs/minisat/Vec.h | 134 +++++ libs/minisat/XAlloc.h | 45 ++ 28 files changed, 5025 insertions(+), 28 deletions(-) create mode 100644 libs/minisat/Alg.h create mode 100644 libs/minisat/Alloc.h create mode 100644 libs/minisat/Dimacs.h create mode 100644 libs/minisat/Heap.h create mode 100644 libs/minisat/IntMap.h create mode 100644 libs/minisat/IntTypes.h create mode 100644 libs/minisat/LICENSE create mode 100644 libs/minisat/Map.h create mode 100644 libs/minisat/Options.cc create mode 100644 libs/minisat/Options.h create mode 100644 libs/minisat/ParseUtils.h create mode 100644 libs/minisat/Queue.h create mode 100644 libs/minisat/Rnd.h create mode 100644 libs/minisat/SimpSolver.cc create mode 100644 libs/minisat/SimpSolver.h create mode 100644 libs/minisat/Solver.cc create mode 100644 libs/minisat/Solver.h create mode 100644 libs/minisat/SolverTypes.h create mode 100644 libs/minisat/Sort.h create mode 100644 libs/minisat/System.cc create mode 100644 libs/minisat/System.h create mode 100644 libs/minisat/UPDATE.sh create mode 100644 libs/minisat/Vec.h create mode 100644 libs/minisat/XAlloc.h diff --git a/Makefile b/Makefile index abb473ba..0acc0d0e 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ CONFIG := clang-debug # features (the more the better) ENABLE_TCL := 1 ENABLE_QT4 := 1 -ENABLE_MINISAT := 1 ENABLE_ABC := 1 ENABLE_VERIFIC := 0 @@ -95,11 +94,11 @@ OBJS += libs/sha1/sha1.o OBJS += libs/subcircuit/subcircuit.o OBJS += libs/ezsat/ezsat.o -ifeq ($(ENABLE_MINISAT),1) -CXXFLAGS += -DYOSYS_ENABLE_MINISAT OBJS += libs/ezsat/ezminisat.o -LDLIBS += -lminisat -endif +OBJS += libs/minisat/Options.o +OBJS += libs/minisat/SimpSolver.o +OBJS += libs/minisat/Solver.o +OBJS += libs/minisat/System.o include frontends/*/Makefile.inc include passes/*/Makefile.inc diff --git a/README b/README index 45febc2f..5a48a207 100644 --- a/README +++ b/README @@ -280,21 +280,6 @@ Verilog Attributes and non-standard features must be put in parentheses. Examples: WIDTH'd42, (4+2)'b101010 -Workarounds for known build problems -==================================== - -You might get an error message like this one during build when building with -a recent version of gcc: - - /usr/include/minisat/utils/Options.h:285:29: error: - unable to find string literal operator ‘operator"" PRIi64’ - -This is a bug in the minisat header. It can be fixed by adding spaces before -and after each occurrence of PRIi64 in the header file: - - sudo sed -i -e 's/PRIi64/ & /' /usr/include/minisat/utils/Options.h - - Roadmap / Large-scale TODOs =========================== diff --git a/kernel/satgen.h b/kernel/satgen.h index bf72a31c..81d02929 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -24,13 +24,8 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" -#ifdef YOSYS_ENABLE_MINISAT -# include "libs/ezsat/ezminisat.h" +#include "libs/ezsat/ezminisat.h" typedef ezMiniSAT ezDefaultSAT; -#else -# include "libs/ezsat/ezsat.h" -typedef ezSAT ezDefaultSAT; -#endif struct SatGen { diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 4677f68b..caee73f8 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -28,8 +28,13 @@ #include #include -#include -#include +#ifdef _YOSYS_ +# include "libs/minisat/Solver.h" +# include "libs/minisat/SimpSolver.h" +#else +# include +# include +#endif ezMiniSAT::ezMiniSAT() : minisatSolver(NULL) { diff --git a/libs/minisat/Alg.h b/libs/minisat/Alg.h new file mode 100644 index 00000000..7f7eac61 --- /dev/null +++ b/libs/minisat/Alg.h @@ -0,0 +1,84 @@ +/*******************************************************************************************[Alg.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Alg_h +#define Minisat_Alg_h + +#include "libs/minisat/Vec.h" + +namespace Minisat { + +//================================================================================================= +// Useful functions on vector-like types: + +//================================================================================================= +// Removing and searching for elements: +// + +template +static inline void remove(V& ts, const T& t) +{ + int j = 0; + for (; j < (int)ts.size() && ts[j] != t; j++); + assert(j < (int)ts.size()); + for (; j < (int)ts.size()-1; j++) ts[j] = ts[j+1]; + ts.pop(); +} + + +template +static inline bool find(V& ts, const T& t) +{ + int j = 0; + for (; j < (int)ts.size() && ts[j] != t; j++); + return j < (int)ts.size(); +} + + +//================================================================================================= +// Copying vectors with support for nested vector types: +// + +// Base case: +template +static inline void copy(const T& from, T& to) +{ + to = from; +} + +// Recursive case: +template +static inline void copy(const vec& from, vec& to, bool append = false) +{ + if (!append) + to.clear(); + for (int i = 0; i < from.size(); i++){ + to.push(); + copy(from[i], to.last()); + } +} + +template +static inline void append(const vec& from, vec& to){ copy(from, to, true); } + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Alloc.h b/libs/minisat/Alloc.h new file mode 100644 index 00000000..0de4f07c --- /dev/null +++ b/libs/minisat/Alloc.h @@ -0,0 +1,131 @@ +/*****************************************************************************************[Alloc.h] +Copyright (c) 2008-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + + +#ifndef Minisat_Alloc_h +#define Minisat_Alloc_h + +#include "libs/minisat/XAlloc.h" +#include "libs/minisat/Vec.h" + +namespace Minisat { + +//================================================================================================= +// Simple Region-based memory allocator: + +template +class RegionAllocator +{ + T* memory; + uint32_t sz; + uint32_t cap; + uint32_t wasted_; + + void capacity(uint32_t min_cap); + + public: + // TODO: make this a class for better type-checking? + typedef uint32_t Ref; + enum { Ref_Undef = UINT32_MAX }; + enum { Unit_Size = sizeof(T) }; + + explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); } + ~RegionAllocator() + { + if (memory != NULL) + ::free(memory); + } + + + uint32_t size () const { return sz; } + uint32_t wasted () const { return wasted_; } + + Ref alloc (int size); + void free (int size) { wasted_ += size; } + + // Deref, Load Effective Address (LEA), Inverse of LEA (AEL): + T& operator[](Ref r) { assert(r < sz); return memory[r]; } + const T& operator[](Ref r) const { assert(r < sz); return memory[r]; } + + T* lea (Ref r) { assert(r < sz); return &memory[r]; } + const T* lea (Ref r) const { assert(r < sz); return &memory[r]; } + Ref ael (const T* t) { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]); + return (Ref)(t - &memory[0]); } + + void moveTo(RegionAllocator& to) { + if (to.memory != NULL) ::free(to.memory); + to.memory = memory; + to.sz = sz; + to.cap = cap; + to.wasted_ = wasted_; + + memory = NULL; + sz = cap = wasted_ = 0; + } + + +}; + +template +void RegionAllocator::capacity(uint32_t min_cap) +{ + if (cap >= min_cap) return; + + uint32_t prev_cap = cap; + while (cap < min_cap){ + // NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the + // result even by clearing the least significant bit. The resulting sequence of capacities + // is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when + // using 'uint32_t' as indices so that as much as possible of this space can be used. + uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1; + cap += delta; + + if (cap <= prev_cap) + throw OutOfMemoryException(); + } + // printf(" .. (%p) cap = %u\n", this, cap); + + assert(cap > 0); + memory = (T*)xrealloc(memory, sizeof(T)*cap); +} + + +template +typename RegionAllocator::Ref +RegionAllocator::alloc(int size) +{ + // printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout); + assert(size > 0); + capacity(sz + size); + + uint32_t prev_sz = sz; + sz += size; + + // Handle overflow: + if (sz < prev_sz) + throw OutOfMemoryException(); + + return prev_sz; +} + + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Dimacs.h b/libs/minisat/Dimacs.h new file mode 100644 index 00000000..383e894b --- /dev/null +++ b/libs/minisat/Dimacs.h @@ -0,0 +1,87 @@ +/****************************************************************************************[Dimacs.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Dimacs_h +#define Minisat_Dimacs_h + +#include + +#include "libs/minisat/ParseUtils.h" +#include "libs/minisat/SolverTypes.h" + +namespace Minisat { + +//================================================================================================= +// DIMACS Parser: + +template +static void readClause(B& in, Solver& S, vec& lits) { + int parsed_lit, var; + lits.clear(); + for (;;){ + parsed_lit = parseInt(in); + if (parsed_lit == 0) break; + var = abs(parsed_lit)-1; + while (var >= S.nVars()) S.newVar(); + lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) ); + } +} + +template +static void parse_DIMACS_main(B& in, Solver& S, bool strictp = false) { + vec lits; + int vars = 0; + int clauses = 0; + int cnt = 0; + for (;;){ + skipWhitespace(in); + if (*in == EOF) break; + else if (*in == 'p'){ + if (eagerMatch(in, "p cnf")){ + vars = parseInt(in); + clauses = parseInt(in); + // SATRACE'06 hack + // if (clauses > 4000000) + // S.eliminate(true); + }else{ + printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3); + } + } else if (*in == 'c' || *in == 'p') + skipLine(in); + else{ + cnt++; + readClause(in, S, lits); + S.addClause_(lits); } + } + if (strictp && cnt != clauses) + printf("PARSE ERROR! DIMACS header mismatch: wrong number of clauses\n"); +} + +// Inserts problem into solver. +// +template +static void parse_DIMACS(gzFile input_stream, Solver& S, bool strictp = false) { + StreamBuffer in(input_stream); + parse_DIMACS_main(in, S, strictp); } + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Heap.h b/libs/minisat/Heap.h new file mode 100644 index 00000000..a7512462 --- /dev/null +++ b/libs/minisat/Heap.h @@ -0,0 +1,168 @@ +/******************************************************************************************[Heap.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Heap_h +#define Minisat_Heap_h + +#include "libs/minisat/Vec.h" +#include "libs/minisat/IntMap.h" + +namespace Minisat { + +//================================================================================================= +// A heap implementation with support for decrease/increase key. + + +template > +class Heap { + vec heap; // Heap of Keys + IntMap indices; // Each Key's position (index) in the Heap + Comp lt; // The heap is a minimum-heap with respect to this comparator + + // Index "traversal" functions + static inline int left (int i) { return i*2+1; } + static inline int right (int i) { return (i+1)*2; } + static inline int parent(int i) { return (i-1) >> 1; } + + + void percolateUp(int i) + { + K x = heap[i]; + int p = parent(i); + + while (i != 0 && lt(x, heap[p])){ + heap[i] = heap[p]; + indices[heap[p]] = i; + i = p; + p = parent(p); + } + heap [i] = x; + indices[x] = i; + } + + + void percolateDown(int i) + { + K x = heap[i]; + while (left(i) < heap.size()){ + int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i); + if (!lt(heap[child], x)) break; + heap[i] = heap[child]; + indices[heap[i]] = i; + i = child; + } + heap [i] = x; + indices[x] = i; + } + + + public: + Heap(const Comp& c, MkIndex _index = MkIndex()) : indices(_index), lt(c) {} + + int size () const { return heap.size(); } + bool empty () const { return heap.size() == 0; } + bool inHeap (K k) const { return indices.has(k) && indices[k] >= 0; } + int operator[](int index) const { assert(index < heap.size()); return heap[index]; } + + void decrease (K k) { assert(inHeap(k)); percolateUp (indices[k]); } + void increase (K k) { assert(inHeap(k)); percolateDown(indices[k]); } + + + // Safe variant of insert/decrease/increase: + void update(K k) + { + if (!inHeap(k)) + insert(k); + else { + percolateUp(indices[k]); + percolateDown(indices[k]); } + } + + + void insert(K k) + { + indices.reserve(k, -1); + assert(!inHeap(k)); + + indices[k] = heap.size(); + heap.push(k); + percolateUp(indices[k]); + } + + + void remove(K k) + { + assert(inHeap(k)); + + int k_pos = indices[k]; + indices[k] = -1; + + if (k_pos < heap.size()-1){ + heap[k_pos] = heap.last(); + indices[heap[k_pos]] = k_pos; + heap.pop(); + percolateDown(k_pos); + }else + heap.pop(); + } + + + K removeMin() + { + K x = heap[0]; + heap[0] = heap.last(); + indices[heap[0]] = 0; + indices[x] = -1; + heap.pop(); + if (heap.size() > 1) percolateDown(0); + return x; + } + + + // Rebuild the heap from scratch, using the elements in 'ns': + void build(const vec& ns) { + for (int i = 0; i < heap.size(); i++) + indices[heap[i]] = -1; + heap.clear(); + + for (int i = 0; i < ns.size(); i++){ + // TODO: this should probably call reserve instead of relying on it being reserved already. + assert(indices.has(ns[i])); + indices[ns[i]] = i; + heap.push(ns[i]); } + + for (int i = heap.size() / 2 - 1; i >= 0; i--) + percolateDown(i); + } + + void clear(bool dispose = false) + { + // TODO: shouldn't the 'indices' map also be dispose-cleared? + for (int i = 0; i < heap.size(); i++) + indices[heap[i]] = -1; + heap.clear(dispose); + } +}; + + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/IntMap.h b/libs/minisat/IntMap.h new file mode 100644 index 00000000..61dd0f67 --- /dev/null +++ b/libs/minisat/IntMap.h @@ -0,0 +1,106 @@ +/****************************************************************************************[IntMap.h] +Copyright (c) 2011, Niklas Sorensson +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_IntMap_h +#define Minisat_IntMap_h + +#include "libs/minisat/Vec.h" + +namespace Minisat { + + template struct MkIndexDefault { + typename vec::Size operator()(T t) const { return (typename vec::Size)t; } + }; + + template > + class IntMap { + vec map; + MkIndex index; + public: + explicit IntMap(MkIndex _index = MkIndex()) : index(_index){} + + bool has (K k) const { return index(k) < map.size(); } + + const V& operator[](K k) const { assert(has(k)); return map[index(k)]; } + V& operator[](K k) { assert(has(k)); return map[index(k)]; } + + const V* begin () const { return &map[0]; } + const V* end () const { return &map[map.size()]; } + V* begin () { return &map[0]; } + V* end () { return &map[map.size()]; } + + void reserve(K key, V pad) { map.growTo(index(key)+1, pad); } + void reserve(K key) { map.growTo(index(key)+1); } + void insert (K key, V val, V pad){ reserve(key, pad); operator[](key) = val; } + void insert (K key, V val) { reserve(key); operator[](key) = val; } + + void clear (bool dispose = false) { map.clear(dispose); } + void moveTo (IntMap& to) { map.moveTo(to.map); to.index = index; } + void copyTo (IntMap& to) const { map.copyTo(to.map); to.index = index; } + }; + + + template > + class IntSet + { + IntMap in_set; + vec xs; + + public: + // Size operations: + int size (void) const { return xs.size(); } + void clear (bool free = false){ + if (free) + in_set.clear(true); + else + for (int i = 0; i < xs.size(); i++) + in_set[xs[i]] = 0; + xs.clear(free); + } + + // Allow inspecting the internal vector: + const vec& + toVec () const { return xs; } + + // Vector interface: + K operator [] (int index) const { return xs[index]; } + + + void insert (K k) { in_set.reserve(k, 0); if (!in_set[k]) { in_set[k] = 1; xs.push(k); } } + bool has (K k) { in_set.reserve(k, 0); return in_set[k]; } + }; + + #if 0 + template > + class IntMapNil { + vec map; + V nil; + + public: + IntMap(){} + + void reserve(K); + V& find (K); + const V& operator[](K k) const; + + }; + #endif + +//================================================================================================= +} // namespace Minisat +#endif diff --git a/libs/minisat/IntTypes.h b/libs/minisat/IntTypes.h new file mode 100644 index 00000000..c4881628 --- /dev/null +++ b/libs/minisat/IntTypes.h @@ -0,0 +1,42 @@ +/**************************************************************************************[IntTypes.h] +Copyright (c) 2009-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_IntTypes_h +#define Minisat_IntTypes_h + +#ifdef __sun + // Not sure if there are newer versions that support C99 headers. The + // needed features are implemented in the headers below though: + +# include +# include +# include + +#else + +# include +# include + +#endif + +#include + +//================================================================================================= + +#endif diff --git a/libs/minisat/LICENSE b/libs/minisat/LICENSE new file mode 100644 index 00000000..22816ff3 --- /dev/null +++ b/libs/minisat/LICENSE @@ -0,0 +1,21 @@ +MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson + Copyright (c) 2007-2010 Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libs/minisat/Map.h b/libs/minisat/Map.h new file mode 100644 index 00000000..93b6da31 --- /dev/null +++ b/libs/minisat/Map.h @@ -0,0 +1,193 @@ +/*******************************************************************************************[Map.h] +Copyright (c) 2006-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Map_h +#define Minisat_Map_h + +#include "libs/minisat/IntTypes.h" +#include "libs/minisat/Vec.h" + +namespace Minisat { + +//================================================================================================= +// Default hash/equals functions +// + +template struct Hash { uint32_t operator()(const K& k) const { return hash(k); } }; +template struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } }; + +template struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } }; +template struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } }; + +static inline uint32_t hash(uint32_t x){ return x; } +static inline uint32_t hash(uint64_t x){ return (uint32_t)x; } +static inline uint32_t hash(int32_t x) { return (uint32_t)x; } +static inline uint32_t hash(int64_t x) { return (uint32_t)x; } + + +//================================================================================================= +// Some primes +// + +static const int nprimes = 25; +static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 }; + +//================================================================================================= +// Hash table implementation of Maps +// + +template, class E = Equal > +class Map { + public: + struct Pair { K key; D data; }; + + private: + H hash; + E equals; + + vec* table; + int cap; + int size; + + // Don't allow copying (error prone): + Map& operator = (Map& other); + Map (Map& other); + + bool checkCap(int new_size) const { return new_size > cap; } + + int32_t index (const K& k) const { return hash(k) % cap; } + void _insert (const K& k, const D& d) { + vec& ps = table[index(k)]; + ps.push(); ps.last().key = k; ps.last().data = d; } + + void rehash () { + const vec* old = table; + + int old_cap = cap; + int newsize = primes[0]; + for (int i = 1; newsize <= cap && i < nprimes; i++) + newsize = primes[i]; + + table = new vec[newsize]; + cap = newsize; + + for (int i = 0; i < old_cap; i++){ + for (int j = 0; j < old[i].size(); j++){ + _insert(old[i][j].key, old[i][j].data); }} + + delete [] old; + + // printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize); + } + + + public: + + Map () : table(NULL), cap(0), size(0) {} + Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){} + ~Map () { delete [] table; } + + // PRECONDITION: the key must already exist in the map. + const D& operator [] (const K& k) const + { + assert(size != 0); + const D* res = NULL; + const vec& ps = table[index(k)]; + for (int i = 0; i < ps.size(); i++) + if (equals(ps[i].key, k)) + res = &ps[i].data; + assert(res != NULL); + return *res; + } + + // PRECONDITION: the key must already exist in the map. + D& operator [] (const K& k) + { + assert(size != 0); + D* res = NULL; + vec& ps = table[index(k)]; + for (int i = 0; i < ps.size(); i++) + if (equals(ps[i].key, k)) + res = &ps[i].data; + assert(res != NULL); + return *res; + } + + // PRECONDITION: the key must *NOT* exist in the map. + void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; } + bool peek (const K& k, D& d) const { + if (size == 0) return false; + const vec& ps = table[index(k)]; + for (int i = 0; i < ps.size(); i++) + if (equals(ps[i].key, k)){ + d = ps[i].data; + return true; } + return false; + } + + bool has (const K& k) const { + if (size == 0) return false; + const vec& ps = table[index(k)]; + for (int i = 0; i < ps.size(); i++) + if (equals(ps[i].key, k)) + return true; + return false; + } + + // PRECONDITION: the key must exist in the map. + void remove(const K& k) { + assert(table != NULL); + vec& ps = table[index(k)]; + int j = 0; + for (; j < ps.size() && !equals(ps[j].key, k); j++); + assert(j < ps.size()); + ps[j] = ps.last(); + ps.pop(); + size--; + } + + void clear () { + cap = size = 0; + delete [] table; + table = NULL; + } + + int elems() const { return size; } + int bucket_count() const { return cap; } + + // NOTE: the hash and equality objects are not moved by this method: + void moveTo(Map& other){ + delete [] other.table; + + other.table = table; + other.cap = cap; + other.size = size; + + table = NULL; + size = cap = 0; + } + + // NOTE: given a bit more time, I could make a more C++-style iterator out of this: + const vec& bucket(int i) const { return table[i]; } +}; + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Options.cc b/libs/minisat/Options.cc new file mode 100644 index 00000000..b1b3e31b --- /dev/null +++ b/libs/minisat/Options.cc @@ -0,0 +1,94 @@ +#define __STDC_FORMAT_MACROS +#define __STDC_LIMIT_MACROS +/**************************************************************************************[Options.cc] +Copyright (c) 2008-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#include "libs/minisat/Sort.h" +#include "libs/minisat/Options.h" +#include "libs/minisat/ParseUtils.h" + +using namespace Minisat; + +void Minisat::parseOptions(int& argc, char** argv, bool strict) +{ + int i, j; + for (i = j = 1; i < argc; i++){ + const char* str = argv[i]; + if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){ + if (*str == '\0') + printUsageAndExit(argc, argv); + else if (match(str, "-verb")) + printUsageAndExit(argc, argv, true); + } else { + bool parsed_ok = false; + + for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){ + parsed_ok = Option::getOptionList()[k]->parse(argv[i]); + + // fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip"); + } + + if (!parsed_ok){ + if (strict && match(argv[i], "-")) + fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()), exit(1); + else + argv[j++] = argv[i]; + } + } + } + + argc -= (i - j); +} + + +void Minisat::setUsageHelp (const char* str){ Option::getUsageString() = str; } +void Minisat::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; } +void Minisat::printUsageAndExit (int /*argc*/, char** argv, bool verbose) +{ + const char* usage = Option::getUsageString(); + if (usage != NULL) + fprintf(stderr, usage, argv[0]); + + sort(Option::getOptionList(), Option::OptionLt()); + + const char* prev_cat = NULL; + const char* prev_type = NULL; + + for (int i = 0; i < Option::getOptionList().size(); i++){ + const char* cat = Option::getOptionList()[i]->category; + const char* type = Option::getOptionList()[i]->type_name; + + if (cat != prev_cat) + fprintf(stderr, "\n%s OPTIONS:\n\n", cat); + else if (type != prev_type) + fprintf(stderr, "\n"); + + Option::getOptionList()[i]->help(verbose); + + prev_cat = Option::getOptionList()[i]->category; + prev_type = Option::getOptionList()[i]->type_name; + } + + fprintf(stderr, "\nHELP OPTIONS:\n\n"); + fprintf(stderr, " --%shelp Print help message.\n", Option::getHelpPrefixString()); + fprintf(stderr, " --%shelp-verb Print verbose help message.\n", Option::getHelpPrefixString()); + fprintf(stderr, "\n"); + exit(0); +} + diff --git a/libs/minisat/Options.h b/libs/minisat/Options.h new file mode 100644 index 00000000..7d140a1f --- /dev/null +++ b/libs/minisat/Options.h @@ -0,0 +1,386 @@ +/***************************************************************************************[Options.h] +Copyright (c) 2008-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Options_h +#define Minisat_Options_h + +#include +#include +#include +#include + +#include "libs/minisat/IntTypes.h" +#include "libs/minisat/Vec.h" +#include "libs/minisat/ParseUtils.h" + +namespace Minisat { + +//================================================================================================== +// Top-level option parse/help functions: + + +extern void parseOptions (int& argc, char** argv, bool strict = false); +extern void printUsageAndExit(int argc, char** argv, bool verbose = false); +extern void setUsageHelp (const char* str); +extern void setHelpPrefixStr (const char* str); + + +//================================================================================================== +// Options is an abstract class that gives the interface for all types options: + + +class Option +{ + protected: + const char* name; + const char* description; + const char* category; + const char* type_name; + + static vec& getOptionList () { static vec options; return options; } + static const char*& getUsageString() { static const char* usage_str; return usage_str; } + static const char*& getHelpPrefixString() { static const char* help_prefix_str = ""; return help_prefix_str; } + + struct OptionLt { + bool operator()(const Option* x, const Option* y) { + int test1 = strcmp(x->category, y->category); + return test1 < 0 || (test1 == 0 && strcmp(x->type_name, y->type_name) < 0); + } + }; + + Option(const char* name_, + const char* desc_, + const char* cate_, + const char* type_) : + name (name_) + , description(desc_) + , category (cate_) + , type_name (type_) + { + getOptionList().push(this); + } + + public: + virtual ~Option() {} + + virtual bool parse (const char* str) = 0; + virtual void help (bool verbose = false) = 0; + + friend void parseOptions (int& argc, char** argv, bool strict); + friend void printUsageAndExit (int argc, char** argv, bool verbose); + friend void setUsageHelp (const char* str); + friend void setHelpPrefixStr (const char* str); +}; + + +//================================================================================================== +// Range classes with specialization for floating types: + + +struct IntRange { + int begin; + int end; + IntRange(int b, int e) : begin(b), end(e) {} +}; + +struct Int64Range { + int64_t begin; + int64_t end; + Int64Range(int64_t b, int64_t e) : begin(b), end(e) {} +}; + +struct DoubleRange { + double begin; + double end; + bool begin_inclusive; + bool end_inclusive; + DoubleRange(double b, bool binc, double e, bool einc) : begin(b), end(e), begin_inclusive(binc), end_inclusive(einc) {} +}; + + +//================================================================================================== +// Double options: + + +class DoubleOption : public Option +{ + protected: + DoubleRange range; + double value; + + public: + DoubleOption(const char* c, const char* n, const char* d, double def = double(), DoubleRange r = DoubleRange(-HUGE_VAL, false, HUGE_VAL, false)) + : Option(n, d, c, ""), range(r), value(def) { + // FIXME: set LC_NUMERIC to "C" to make sure that strtof/strtod parses decimal point correctly. + } + + operator double (void) const { return value; } + operator double& (void) { return value; } + DoubleOption& operator=(double x) { value = x; return *this; } + + virtual bool parse(const char* str){ + const char* span = str; + + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; + + char* end; + double tmp = strtod(span, &end); + + if (end == NULL) + return false; + else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){ + fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); + exit(1); + }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){ + fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); + exit(1); } + + value = tmp; + // fprintf(stderr, "READ VALUE: %g\n", value); + + return true; + } + + virtual void help (bool verbose = false){ + fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n", + name, type_name, + range.begin_inclusive ? '[' : '(', + range.begin, + range.end, + range.end_inclusive ? ']' : ')', + value); + if (verbose){ + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } + } +}; + + +//================================================================================================== +// Int options: + + +class IntOption : public Option +{ + protected: + IntRange range; + int32_t value; + + public: + IntOption(const char* c, const char* n, const char* d, int32_t def = int32_t(), IntRange r = IntRange(INT32_MIN, INT32_MAX)) + : Option(n, d, c, ""), range(r), value(def) {} + + operator int32_t (void) const { return value; } + operator int32_t& (void) { return value; } + IntOption& operator= (int32_t x) { value = x; return *this; } + + virtual bool parse(const char* str){ + const char* span = str; + + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; + + char* end; + int32_t tmp = strtol(span, &end, 10); + + if (end == NULL) + return false; + else if (tmp > range.end){ + fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); + exit(1); + }else if (tmp < range.begin){ + fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); + exit(1); } + + value = tmp; + + return true; + } + + virtual void help (bool verbose = false){ + fprintf(stderr, " -%-12s = %-8s [", name, type_name); + if (range.begin == INT32_MIN) + fprintf(stderr, "imin"); + else + fprintf(stderr, "%4d", range.begin); + + fprintf(stderr, " .. "); + if (range.end == INT32_MAX) + fprintf(stderr, "imax"); + else + fprintf(stderr, "%4d", range.end); + + fprintf(stderr, "] (default: %d)\n", value); + if (verbose){ + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } + } +}; + + +// Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll. +#ifndef _MSC_VER + +class Int64Option : public Option +{ + protected: + Int64Range range; + int64_t value; + + public: + Int64Option(const char* c, const char* n, const char* d, int64_t def = int64_t(), Int64Range r = Int64Range(INT64_MIN, INT64_MAX)) + : Option(n, d, c, ""), range(r), value(def) {} + + operator int64_t (void) const { return value; } + operator int64_t& (void) { return value; } + Int64Option& operator= (int64_t x) { value = x; return *this; } + + virtual bool parse(const char* str){ + const char* span = str; + + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; + + char* end; + int64_t tmp = strtoll(span, &end, 10); + + if (end == NULL) + return false; + else if (tmp > range.end){ + fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name); + exit(1); + }else if (tmp < range.begin){ + fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name); + exit(1); } + + value = tmp; + + return true; + } + + virtual void help (bool verbose = false){ + fprintf(stderr, " -%-12s = %-8s [", name, type_name); + if (range.begin == INT64_MIN) + fprintf(stderr, "imin"); + else + fprintf(stderr, "%4" PRIi64 , range.begin); + + fprintf(stderr, " .. "); + if (range.end == INT64_MAX) + fprintf(stderr, "imax"); + else + fprintf(stderr, "%4" PRIi64 , range.end); + + fprintf(stderr, "] (default: %" PRIi64 ")\n", value); + if (verbose){ + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } + } +}; +#endif + +//================================================================================================== +// String option: + + +class StringOption : public Option +{ + const char* value; + public: + StringOption(const char* c, const char* n, const char* d, const char* def = NULL) + : Option(n, d, c, ""), value(def) {} + + operator const char* (void) const { return value; } + operator const char*& (void) { return value; } + StringOption& operator= (const char* x) { value = x; return *this; } + + virtual bool parse(const char* str){ + const char* span = str; + + if (!match(span, "-") || !match(span, name) || !match(span, "=")) + return false; + + value = span; + return true; + } + + virtual void help (bool verbose = false){ + fprintf(stderr, " -%-10s = %8s\n", name, type_name); + if (verbose){ + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } + } +}; + + +//================================================================================================== +// Bool option: + + +class BoolOption : public Option +{ + bool value; + + public: + BoolOption(const char* c, const char* n, const char* d, bool v) + : Option(n, d, c, ""), value(v) {} + + operator bool (void) const { return value; } + operator bool& (void) { return value; } + BoolOption& operator=(bool b) { value = b; return *this; } + + virtual bool parse(const char* str){ + const char* span = str; + + if (match(span, "-")){ + bool b = !match(span, "no-"); + + if (strcmp(span, name) == 0){ + value = b; + return true; } + } + + return false; + } + + virtual void help (bool verbose = false){ + + fprintf(stderr, " -%s, -no-%s", name, name); + + for (uint32_t i = 0; i < 32 - strlen(name)*2; i++) + fprintf(stderr, " "); + + fprintf(stderr, " "); + fprintf(stderr, "(default: %s)\n", value ? "on" : "off"); + if (verbose){ + fprintf(stderr, "\n %s\n", description); + fprintf(stderr, "\n"); + } + } +}; + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/ParseUtils.h b/libs/minisat/ParseUtils.h new file mode 100644 index 00000000..7b2ddc55 --- /dev/null +++ b/libs/minisat/ParseUtils.h @@ -0,0 +1,129 @@ +/************************************************************************************[ParseUtils.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_ParseUtils_h +#define Minisat_ParseUtils_h + +#include +#include + +#include + +#include "libs/minisat/XAlloc.h" + +namespace Minisat { + +//------------------------------------------------------------------------------------------------- +// A simple buffered character stream class: + + + +class StreamBuffer { + gzFile in; + unsigned char* buf; + int pos; + int size; + + enum { buffer_size = 64*1024 }; + + void assureLookahead() { + if (pos >= size) { + pos = 0; + size = gzread(in, buf, buffer_size); } } + +public: + explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0){ + buf = (unsigned char*)xrealloc(NULL, buffer_size); + assureLookahead(); + } + ~StreamBuffer() { free(buf); } + + int operator * () const { return (pos >= size) ? EOF : buf[pos]; } + void operator ++ () { pos++; assureLookahead(); } + int position () const { return pos; } +}; + + +//------------------------------------------------------------------------------------------------- +// End-of-file detection functions for StreamBuffer and char*: + + +static inline bool isEof(StreamBuffer& in) { return *in == EOF; } +static inline bool isEof(const char* in) { return *in == '\0'; } + +//------------------------------------------------------------------------------------------------- +// Generic parse functions parametrized over the input-stream type. + + +template +static void skipWhitespace(B& in) { + while ((*in >= 9 && *in <= 13) || *in == 32) + ++in; } + + +template +static void skipLine(B& in) { + for (;;){ + if (isEof(in)) return; + if (*in == '\n') { ++in; return; } + ++in; } } + + +template +static int parseInt(B& in) { + int val = 0; + bool neg = false; + skipWhitespace(in); + if (*in == '-') neg = true, ++in; + else if (*in == '+') ++in; + if (*in < '0' || *in > '9') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(3); + while (*in >= '0' && *in <= '9') + val = val*10 + (*in - '0'), + ++in; + return neg ? -val : val; } + + +// String matching: in case of a match the input iterator will be advanced the corresponding +// number of characters. +template +static bool match(B& in, const char* str) { + int i; + for (i = 0; str[i] != '\0'; i++) + if (in[i] != str[i]) + return false; + + in += i; + + return true; +} + +// String matching: consumes characters eagerly, but does not require random access iterator. +template +static bool eagerMatch(B& in, const char* str) { + for (; *str != '\0'; ++str, ++in) + if (*str != *in) + return false; + return true; } + + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Queue.h b/libs/minisat/Queue.h new file mode 100644 index 00000000..1cae4f5a --- /dev/null +++ b/libs/minisat/Queue.h @@ -0,0 +1,69 @@ +/*****************************************************************************************[Queue.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Queue_h +#define Minisat_Queue_h + +#include "libs/minisat/Vec.h" + +namespace Minisat { + +//================================================================================================= + +template +class Queue { + vec buf; + int first; + int end; + +public: + typedef T Key; + + Queue() : buf(1), first(0), end(0) {} + + void clear (bool dealloc = false) { buf.clear(dealloc); buf.growTo(1); first = end = 0; } + int size () const { return (end >= first) ? end - first : end - first + buf.size(); } + + const T& operator [] (int index) const { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; } + T& operator [] (int index) { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; } + + T peek () const { assert(first != end); return buf[first]; } + void pop () { assert(first != end); first++; if (first == buf.size()) first = 0; } + void insert(T elem) { // INVARIANT: buf[end] is always unused + buf[end++] = elem; + if (end == buf.size()) end = 0; + if (first == end){ // Resize: + vec tmp((buf.size()*3 + 1) >> 1); + //**/printf("queue alloc: %d elems (%.1f MB)\n", tmp.size(), tmp.size() * sizeof(T) / 1000000.0); + int i = 0; + for (int j = first; j < buf.size(); j++) tmp[i++] = buf[j]; + for (int j = 0 ; j < end ; j++) tmp[i++] = buf[j]; + first = 0; + end = buf.size(); + tmp.moveTo(buf); + } + } +}; + + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Rnd.h b/libs/minisat/Rnd.h new file mode 100644 index 00000000..cf706101 --- /dev/null +++ b/libs/minisat/Rnd.h @@ -0,0 +1,67 @@ +/*******************************************************************************************[Rnd.h] +Copyright (c) 2012, Niklas Sorensson +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Rnd_h +#define Minisat_Rnd_h + +#include "libs/minisat/Vec.h" + +namespace Minisat { + +// Generate a random double: +static inline double drand(double& seed) +{ + seed *= 1389796; + int q = (int)(seed / 2147483647); + seed -= (double)q * 2147483647; + return seed / 2147483647; +} + + +// Generate a random integer: +static inline int irand(double& seed, int size) { return (int)(drand(seed) * size); } + + +// Randomly shuffle the contents of a vector: +template +static void randomShuffle(double& seed, vec& xs) +{ + for (int i = 0; i < xs.size(); i++){ + int pick = i + irand(seed, xs.size() - i); + T tmp = xs[i]; + xs[i] = xs[pick]; + xs[pick] = tmp; + } +} + +// Randomly shuffle a vector of a vector (ugly) +template +static void randomShuffle(double& seed, vec >& xs) +{ + for (int i = 0; i < xs.size(); i++){ + int pick = i + irand(seed, xs.size() - i); + vec tmp; xs[i].moveTo(tmp); + xs[pick].moveTo(xs[i]); + tmp.moveTo(xs[pick]); + } +} + + +//================================================================================================= +} // namespace Minisat +#endif diff --git a/libs/minisat/SimpSolver.cc b/libs/minisat/SimpSolver.cc new file mode 100644 index 00000000..23236810 --- /dev/null +++ b/libs/minisat/SimpSolver.cc @@ -0,0 +1,727 @@ +#define __STDC_FORMAT_MACROS +#define __STDC_LIMIT_MACROS +/***********************************************************************************[SimpSolver.cc] +Copyright (c) 2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#include "libs/minisat/Sort.h" +#include "libs/minisat/SimpSolver.h" +#include "libs/minisat/System.h" + +using namespace Minisat; + +//================================================================================================= +// Options: + + +static const char* _cat = "SIMP"; + +static BoolOption opt_use_asymm (_cat, "asymm", "Shrink clauses by asymmetric branching.", false); +static BoolOption opt_use_rcheck (_cat, "rcheck", "Check if a clause is already implied. (costly)", false); +static BoolOption opt_use_elim (_cat, "elim", "Perform variable elimination.", true); +static IntOption opt_grow (_cat, "grow", "Allow a variable elimination step to grow by a number of clauses.", 0); +static IntOption opt_clause_lim (_cat, "cl-lim", "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20, IntRange(-1, INT32_MAX)); +static IntOption opt_subsumption_lim (_cat, "sub-lim", "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX)); +static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.", 0.5, DoubleRange(0, false, HUGE_VAL, false)); + + +//================================================================================================= +// Constructor/Destructor: + + +SimpSolver::SimpSolver() : + grow (opt_grow) + , clause_lim (opt_clause_lim) + , subsumption_lim (opt_subsumption_lim) + , simp_garbage_frac (opt_simp_garbage_frac) + , use_asymm (opt_use_asymm) + , use_rcheck (opt_use_rcheck) + , use_elim (opt_use_elim) + , extend_model (true) + , merges (0) + , asymm_lits (0) + , eliminated_vars (0) + , elimorder (1) + , use_simplification (true) + , occurs (ClauseDeleted(ca)) + , elim_heap (ElimLt(n_occ)) + , bwdsub_assigns (0) + , n_touched (0) +{ + vec dummy(1,lit_Undef); + ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below. + bwdsub_tmpunit = ca.alloc(dummy); + remove_satisfied = false; +} + + +SimpSolver::~SimpSolver() +{ +} + + +Var SimpSolver::newVar(lbool upol, bool dvar) { + Var v = Solver::newVar(upol, dvar); + + frozen .insert(v, (char)false); + eliminated.insert(v, (char)false); + + if (use_simplification){ + n_occ .insert( mkLit(v), 0); + n_occ .insert(~mkLit(v), 0); + occurs .init (v); + touched .insert(v, 0); + elim_heap .insert(v); + } + return v; } + + +void SimpSolver::releaseVar(Lit l) +{ + assert(!isEliminated(var(l))); + if (!use_simplification && var(l) >= max_simp_var) + // Note: Guarantees that no references to this variable is + // left in model extension datastructure. Could be improved! + Solver::releaseVar(l); + else + // Otherwise, don't allow variable to be reused. + Solver::addClause(l); +} + + +lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp) +{ + vec extra_frozen; + lbool result = l_True; + + do_simp &= use_simplification; + + if (do_simp){ + // Assumptions must be temporarily frozen to run variable elimination: + for (int i = 0; i < assumptions.size(); i++){ + Var v = var(assumptions[i]); + + // If an assumption has been eliminated, remember it. + assert(!isEliminated(v)); + + if (!frozen[v]){ + // Freeze and store. + setFrozen(v, true); + extra_frozen.push(v); + } } + + result = lbool(eliminate(turn_off_simp)); + } + + if (result == l_True) + result = Solver::solve_(); + else if (verbosity >= 1) + printf("===============================================================================\n"); + + if (result == l_True && extend_model) + extendModel(); + + if (do_simp) + // Unfreeze the assumptions that were frozen: + for (int i = 0; i < extra_frozen.size(); i++) + setFrozen(extra_frozen[i], false); + + return result; +} + + + +bool SimpSolver::addClause_(vec& ps) +{ +#ifndef NDEBUG + for (int i = 0; i < ps.size(); i++) + assert(!isEliminated(var(ps[i]))); +#endif + + int nclauses = clauses.size(); + + if (use_rcheck && implied(ps)) + return true; + + if (!Solver::addClause_(ps)) + return false; + + if (use_simplification && clauses.size() == nclauses + 1){ + CRef cr = clauses.last(); + const Clause& c = ca[cr]; + + // NOTE: the clause is added to the queue immediately and then + // again during 'gatherTouchedClauses()'. If nothing happens + // in between, it will only be checked once. Otherwise, it may + // be checked twice unnecessarily. This is an unfortunate + // consequence of how backward subsumption is used to mimic + // forward subsumption. + subsumption_queue.insert(cr); + for (int i = 0; i < c.size(); i++){ + occurs[var(c[i])].push(cr); + n_occ[c[i]]++; + touched[var(c[i])] = 1; + n_touched++; + if (elim_heap.inHeap(var(c[i]))) + elim_heap.increase(var(c[i])); + } + } + + return true; +} + + +void SimpSolver::removeClause(CRef cr) +{ + const Clause& c = ca[cr]; + + if (use_simplification) + for (int i = 0; i < c.size(); i++){ + n_occ[c[i]]--; + updateElimHeap(var(c[i])); + occurs.smudge(var(c[i])); + } + + Solver::removeClause(cr); +} + + +bool SimpSolver::strengthenClause(CRef cr, Lit l) +{ + Clause& c = ca[cr]; + assert(decisionLevel() == 0); + assert(use_simplification); + + // FIX: this is too inefficient but would be nice to have (properly implemented) + // if (!find(subsumption_queue, &c)) + subsumption_queue.insert(cr); + + if (c.size() == 2){ + removeClause(cr); + c.strengthen(l); + }else{ + detachClause(cr, true); + c.strengthen(l); + attachClause(cr); + remove(occurs[var(l)], cr); + n_occ[l]--; + updateElimHeap(var(l)); + } + + return c.size() == 1 ? enqueue(c[0]) && propagate() == CRef_Undef : true; +} + + +// Returns FALSE if clause is always satisfied ('out_clause' should not be used). +bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec& out_clause) +{ + merges++; + out_clause.clear(); + + bool ps_smallest = _ps.size() < _qs.size(); + const Clause& ps = ps_smallest ? _qs : _ps; + const Clause& qs = ps_smallest ? _ps : _qs; + + for (int i = 0; i < qs.size(); i++){ + if (var(qs[i]) != v){ + for (int j = 0; j < ps.size(); j++) + if (var(ps[j]) == var(qs[i])){ + if (ps[j] == ~qs[i]) + return false; + else + goto next; + } + out_clause.push(qs[i]); + } + next:; + } + + for (int i = 0; i < ps.size(); i++) + if (var(ps[i]) != v) + out_clause.push(ps[i]); + + return true; +} + + +// Returns FALSE if clause is always satisfied. +bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size) +{ + merges++; + + bool ps_smallest = _ps.size() < _qs.size(); + const Clause& ps = ps_smallest ? _qs : _ps; + const Clause& qs = ps_smallest ? _ps : _qs; + const Lit* __ps = (const Lit*)ps; + const Lit* __qs = (const Lit*)qs; + + size = ps.size()-1; + + for (int i = 0; i < qs.size(); i++){ + if (var(__qs[i]) != v){ + for (int j = 0; j < ps.size(); j++) + if (var(__ps[j]) == var(__qs[i])){ + if (__ps[j] == ~__qs[i]) + return false; + else + goto next; + } + size++; + } + next:; + } + + return true; +} + + +void SimpSolver::gatherTouchedClauses() +{ + if (n_touched == 0) return; + + int i,j; + for (i = j = 0; i < subsumption_queue.size(); i++) + if (ca[subsumption_queue[i]].mark() == 0) + ca[subsumption_queue[i]].mark(2); + + for (i = 0; i < nVars(); i++) + if (touched[i]){ + const vec& cs = occurs.lookup(i); + for (j = 0; j < cs.size(); j++) + if (ca[cs[j]].mark() == 0){ + subsumption_queue.insert(cs[j]); + ca[cs[j]].mark(2); + } + touched[i] = 0; + } + + for (i = 0; i < subsumption_queue.size(); i++) + if (ca[subsumption_queue[i]].mark() == 2) + ca[subsumption_queue[i]].mark(0); + + n_touched = 0; +} + + +bool SimpSolver::implied(const vec& c) +{ + assert(decisionLevel() == 0); + + trail_lim.push(trail.size()); + for (int i = 0; i < c.size(); i++) + if (value(c[i]) == l_True){ + cancelUntil(0); + return true; + }else if (value(c[i]) != l_False){ + assert(value(c[i]) == l_Undef); + uncheckedEnqueue(~c[i]); + } + + bool result = propagate() != CRef_Undef; + cancelUntil(0); + return result; +} + + +// Backward subsumption + backward subsumption resolution +bool SimpSolver::backwardSubsumptionCheck(bool verbose) +{ + int cnt = 0; + int subsumed = 0; + int deleted_literals = 0; + assert(decisionLevel() == 0); + + while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){ + + // Empty subsumption queue and return immediately on user-interrupt: + if (asynch_interrupt){ + subsumption_queue.clear(); + bwdsub_assigns = trail.size(); + break; } + + // Check top-level assignments by creating a dummy clause and placing it in the queue: + if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){ + Lit l = trail[bwdsub_assigns++]; + ca[bwdsub_tmpunit][0] = l; + ca[bwdsub_tmpunit].calcAbstraction(); + subsumption_queue.insert(bwdsub_tmpunit); } + + CRef cr = subsumption_queue.peek(); subsumption_queue.pop(); + Clause& c = ca[cr]; + + if (c.mark()) continue; + + if (verbose && verbosity >= 2 && cnt++ % 1000 == 0) + printf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals); + + assert(c.size() > 1 || value(c[0]) == l_True); // Unit-clauses should have been propagated before this point. + + // Find best variable to scan: + Var best = var(c[0]); + for (int i = 1; i < c.size(); i++) + if (occurs[var(c[i])].size() < occurs[best].size()) + best = var(c[i]); + + // Search all candidates: + vec& _cs = occurs.lookup(best); + CRef* cs = (CRef*)_cs; + + for (int j = 0; j < _cs.size(); j++) + if (c.mark()) + break; + else if (!ca[cs[j]].mark() && cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){ + Lit l = c.subsumes(ca[cs[j]]); + + if (l == lit_Undef) + subsumed++, removeClause(cs[j]); + else if (l != lit_Error){ + deleted_literals++; + + if (!strengthenClause(cs[j], ~l)) + return false; + + // Did current candidate get deleted from cs? Then check candidate at index j again: + if (var(l) == best) + j--; + } + } + } + + return true; +} + + +bool SimpSolver::asymm(Var v, CRef cr) +{ + Clause& c = ca[cr]; + assert(decisionLevel() == 0); + + if (c.mark() || satisfied(c)) return true; + + trail_lim.push(trail.size()); + Lit l = lit_Undef; + for (int i = 0; i < c.size(); i++) + if (var(c[i]) != v && value(c[i]) != l_False) + uncheckedEnqueue(~c[i]); + else + l = c[i]; + + if (propagate() != CRef_Undef){ + cancelUntil(0); + asymm_lits++; + if (!strengthenClause(cr, l)) + return false; + }else + cancelUntil(0); + + return true; +} + + +bool SimpSolver::asymmVar(Var v) +{ + assert(use_simplification); + + const vec& cls = occurs.lookup(v); + + if (value(v) != l_Undef || cls.size() == 0) + return true; + + for (int i = 0; i < cls.size(); i++) + if (!asymm(v, cls[i])) + return false; + + return backwardSubsumptionCheck(); +} + + +static void mkElimClause(vec& elimclauses, Lit x) +{ + elimclauses.push(toInt(x)); + elimclauses.push(1); +} + + +static void mkElimClause(vec& elimclauses, Var v, Clause& c) +{ + int first = elimclauses.size(); + int v_pos = -1; + + // Copy clause to elimclauses-vector. Remember position where the + // variable 'v' occurs: + for (int i = 0; i < c.size(); i++){ + elimclauses.push(toInt(c[i])); + if (var(c[i]) == v) + v_pos = i + first; + } + assert(v_pos != -1); + + // Swap the first literal with the 'v' literal, so that the literal + // containing 'v' will occur first in the clause: + uint32_t tmp = elimclauses[v_pos]; + elimclauses[v_pos] = elimclauses[first]; + elimclauses[first] = tmp; + + // Store the length of the clause last: + elimclauses.push(c.size()); +} + + + +bool SimpSolver::eliminateVar(Var v) +{ + assert(!frozen[v]); + assert(!isEliminated(v)); + assert(value(v) == l_Undef); + + // Split the occurrences into positive and negative: + // + const vec& cls = occurs.lookup(v); + vec pos, neg; + for (int i = 0; i < cls.size(); i++) + (find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]); + + // Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no + // clause must exceed the limit on the maximal clause size (if it is set): + // + int cnt = 0; + int clause_size = 0; + + for (int i = 0; i < pos.size(); i++) + for (int j = 0; j < neg.size(); j++) + if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) && + (++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim))) + return true; + + // Delete and store old clauses: + eliminated[v] = true; + setDecisionVar(v, false); + eliminated_vars++; + + if (pos.size() > neg.size()){ + for (int i = 0; i < neg.size(); i++) + mkElimClause(elimclauses, v, ca[neg[i]]); + mkElimClause(elimclauses, mkLit(v)); + }else{ + for (int i = 0; i < pos.size(); i++) + mkElimClause(elimclauses, v, ca[pos[i]]); + mkElimClause(elimclauses, ~mkLit(v)); + } + + for (int i = 0; i < cls.size(); i++) + removeClause(cls[i]); + + // Produce clauses in cross product: + vec& resolvent = add_tmp; + for (int i = 0; i < pos.size(); i++) + for (int j = 0; j < neg.size(); j++) + if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent)) + return false; + + // Free occurs list for this variable: + occurs[v].clear(true); + + // Free watchers lists for this variable, if possible: + if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true); + if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true); + + return backwardSubsumptionCheck(); +} + + +bool SimpSolver::substitute(Var v, Lit x) +{ + assert(!frozen[v]); + assert(!isEliminated(v)); + assert(value(v) == l_Undef); + + if (!ok) return false; + + eliminated[v] = true; + setDecisionVar(v, false); + const vec& cls = occurs.lookup(v); + + vec& subst_clause = add_tmp; + for (int i = 0; i < cls.size(); i++){ + Clause& c = ca[cls[i]]; + + subst_clause.clear(); + for (int j = 0; j < c.size(); j++){ + Lit p = c[j]; + subst_clause.push(var(p) == v ? x ^ sign(p) : p); + } + + removeClause(cls[i]); + + if (!addClause_(subst_clause)) + return ok = false; + } + + return true; +} + + +void SimpSolver::extendModel() +{ + int i, j; + Lit x; + + for (i = elimclauses.size()-1; i > 0; i -= j){ + for (j = elimclauses[i--]; j > 1; j--, i--) + if (modelValue(toLit(elimclauses[i])) != l_False) + goto next; + + x = toLit(elimclauses[i]); + model[var(x)] = lbool(!sign(x)); + next:; + } +} + + +bool SimpSolver::eliminate(bool turn_off_elim) +{ + if (!simplify()) + return false; + else if (!use_simplification) + return true; + + // Main simplification loop: + // + while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){ + + gatherTouchedClauses(); + // printf(" ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns); + if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) && + !backwardSubsumptionCheck(true)){ + ok = false; goto cleanup; } + + // Empty elim_heap and return immediately on user-interrupt: + if (asynch_interrupt){ + assert(bwdsub_assigns == trail.size()); + assert(subsumption_queue.size() == 0); + assert(n_touched == 0); + elim_heap.clear(); + goto cleanup; } + + // printf(" ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size()); + for (int cnt = 0; !elim_heap.empty(); cnt++){ + Var elim = elim_heap.removeMin(); + + if (asynch_interrupt) break; + + if (isEliminated(elim) || value(elim) != l_Undef) continue; + + if (verbosity >= 2 && cnt % 100 == 0) + printf("elimination left: %10d\r", elim_heap.size()); + + if (use_asymm){ + // Temporarily freeze variable. Otherwise, it would immediately end up on the queue again: + bool was_frozen = frozen[elim]; + frozen[elim] = true; + if (!asymmVar(elim)){ + ok = false; goto cleanup; } + frozen[elim] = was_frozen; } + + // At this point, the variable may have been set by assymetric branching, so check it + // again. Also, don't eliminate frozen variables: + if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){ + ok = false; goto cleanup; } + + checkGarbage(simp_garbage_frac); + } + + assert(subsumption_queue.size() == 0); + } + cleanup: + + // If no more simplification is needed, free all simplification-related data structures: + if (turn_off_elim){ + touched .clear(true); + occurs .clear(true); + n_occ .clear(true); + elim_heap.clear(true); + subsumption_queue.clear(true); + + use_simplification = false; + remove_satisfied = true; + ca.extra_clause_field = false; + max_simp_var = nVars(); + + // Force full cleanup (this is safe and desirable since it only happens once): + rebuildOrderHeap(); + garbageCollect(); + }else{ + // Cheaper cleanup: + checkGarbage(); + } + + if (verbosity >= 1 && elimclauses.size() > 0) + printf("| Eliminated clauses: %10.2f Mb |\n", + double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024)); + + return ok; +} + + +//================================================================================================= +// Garbage Collection methods: + + +void SimpSolver::relocAll(ClauseAllocator& to) +{ + if (!use_simplification) return; + + // All occurs lists: + // + for (int i = 0; i < nVars(); i++){ + occurs.clean(i); + vec& cs = occurs[i]; + for (int j = 0; j < cs.size(); j++) + ca.reloc(cs[j], to); + } + + // Subsumption queue: + // + for (int i = subsumption_queue.size(); i > 0; i--){ + CRef cr = subsumption_queue.peek(); subsumption_queue.pop(); + if (ca[cr].mark()) continue; + ca.reloc(cr, to); + subsumption_queue.insert(cr); + } + + // Temporary clause: + // + ca.reloc(bwdsub_tmpunit, to); +} + + +void SimpSolver::garbageCollect() +{ + // Initialize the next region to a size corresponding to the estimated utilization degree. This + // is not precise but should avoid some unnecessary reallocations for the new region: + ClauseAllocator to(ca.size() - ca.wasted()); + + to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields. + relocAll(to); + Solver::relocAll(to); + if (verbosity >= 2) + printf("| Garbage collection: %12d bytes => %12d bytes |\n", + ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size); + to.moveTo(ca); +} diff --git a/libs/minisat/SimpSolver.h b/libs/minisat/SimpSolver.h new file mode 100644 index 00000000..fc9bb439 --- /dev/null +++ b/libs/minisat/SimpSolver.h @@ -0,0 +1,222 @@ +/************************************************************************************[SimpSolver.h] +Copyright (c) 2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_SimpSolver_h +#define Minisat_SimpSolver_h + +#include "libs/minisat/Queue.h" +#include "libs/minisat/Solver.h" + + +namespace Minisat { + +//================================================================================================= + + +class SimpSolver : public Solver { + public: + // Constructor/Destructor: + // + SimpSolver(); + ~SimpSolver(); + + // Problem specification: + // + Var newVar (lbool upol = l_Undef, bool dvar = true); + void releaseVar(Lit l); + bool addClause (const vec& ps); + bool addEmptyClause(); // Add the empty clause to the solver. + bool addClause (Lit p); // Add a unit clause to the solver. + bool addClause (Lit p, Lit q); // Add a binary clause to the solver. + bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver. + bool addClause (Lit p, Lit q, Lit r, Lit s); // Add a quaternary clause to the solver. + bool addClause_( vec& ps); + bool substitute(Var v, Lit x); // Replace all occurences of v with x (may cause a contradiction). + + // Variable mode: + // + void setFrozen (Var v, bool b); // If a variable is frozen it will not be eliminated. + bool isEliminated(Var v) const; + + // Alternative freeze interface (may replace 'setFrozen()'): + void freezeVar (Var v); // Freeze one variable so it will not be eliminated. + void thaw (); // Thaw all frozen variables. + + + // Solving: + // + bool solve (const vec& assumps, bool do_simp = true, bool turn_off_simp = false); + lbool solveLimited(const vec& assumps, bool do_simp = true, bool turn_off_simp = false); + bool solve ( bool do_simp = true, bool turn_off_simp = false); + bool solve (Lit p , bool do_simp = true, bool turn_off_simp = false); + bool solve (Lit p, Lit q, bool do_simp = true, bool turn_off_simp = false); + bool solve (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false); + bool eliminate (bool turn_off_elim = false); // Perform variable elimination based simplification. + + // Memory managment: + // + virtual void garbageCollect(); + + + // Generate a (possibly simplified) DIMACS file: + // +#if 0 + void toDimacs (const char* file, const vec& assumps); + void toDimacs (const char* file); + void toDimacs (const char* file, Lit p); + void toDimacs (const char* file, Lit p, Lit q); + void toDimacs (const char* file, Lit p, Lit q, Lit r); +#endif + + // Mode of operation: + // + int grow; // Allow a variable elimination step to grow by a number of clauses (default to zero). + int clause_lim; // Variables are not eliminated if it produces a resolvent with a length above this limit. + // -1 means no limit. + int subsumption_lim; // Do not check if subsumption against a clause larger than this. -1 means no limit. + double simp_garbage_frac; // A different limit for when to issue a GC during simplification (Also see 'garbage_frac'). + + bool use_asymm; // Shrink clauses by asymmetric branching. + bool use_rcheck; // Check if a clause is already implied. Prett costly, and subsumes subsumptions :) + bool use_elim; // Perform variable elimination. + bool extend_model; // Flag to indicate whether the user needs to look at the full model. + + // Statistics: + // + int merges; + int asymm_lits; + int eliminated_vars; + + protected: + + // Helper structures: + // + struct ElimLt { + const LMap& n_occ; + explicit ElimLt(const LMap& no) : n_occ(no) {} + + // TODO: are 64-bit operations here noticably bad on 32-bit platforms? Could use a saturating + // 32-bit implementation instead then, but this will have to do for now. + uint64_t cost (Var x) const { return (uint64_t)n_occ[mkLit(x)] * (uint64_t)n_occ[~mkLit(x)]; } + bool operator()(Var x, Var y) const { return cost(x) < cost(y); } + + // TODO: investigate this order alternative more. + // bool operator()(Var x, Var y) const { + // int c_x = cost(x); + // int c_y = cost(y); + // return c_x < c_y || c_x == c_y && x < y; } + }; + + struct ClauseDeleted { + const ClauseAllocator& ca; + explicit ClauseDeleted(const ClauseAllocator& _ca) : ca(_ca) {} + bool operator()(const CRef& cr) const { return ca[cr].mark() == 1; } }; + + // Solver state: + // + int elimorder; + bool use_simplification; + Var max_simp_var; // Max variable at the point simplification was turned off. + vec elimclauses; + VMap touched; + OccLists, ClauseDeleted> + occurs; + LMap n_occ; + Heap elim_heap; + Queue subsumption_queue; + VMap frozen; + vec frozen_vars; + VMap eliminated; + int bwdsub_assigns; + int n_touched; + + // Temporaries: + // + CRef bwdsub_tmpunit; + + // Main internal methods: + // + lbool solve_ (bool do_simp = true, bool turn_off_simp = false); + bool asymm (Var v, CRef cr); + bool asymmVar (Var v); + void updateElimHeap (Var v); + void gatherTouchedClauses (); + bool merge (const Clause& _ps, const Clause& _qs, Var v, vec& out_clause); + bool merge (const Clause& _ps, const Clause& _qs, Var v, int& size); + bool backwardSubsumptionCheck (bool verbose = false); + bool eliminateVar (Var v); + void extendModel (); + + void removeClause (CRef cr); + bool strengthenClause (CRef cr, Lit l); + bool implied (const vec& c); + void relocAll (ClauseAllocator& to); +}; + + +//================================================================================================= +// Implementation of inline methods: + + +inline bool SimpSolver::isEliminated (Var v) const { return eliminated[v]; } +inline void SimpSolver::updateElimHeap(Var v) { + assert(use_simplification); + // if (!frozen[v] && !isEliminated(v) && value(v) == l_Undef) + if (elim_heap.inHeap(v) || (!frozen[v] && !isEliminated(v) && value(v) == l_Undef)) + elim_heap.update(v); } + + +inline bool SimpSolver::addClause (const vec& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); } +inline bool SimpSolver::addEmptyClause() { add_tmp.clear(); return addClause_(add_tmp); } +inline bool SimpSolver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); } +inline bool SimpSolver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); } +inline bool SimpSolver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); } +inline bool SimpSolver::addClause (Lit p, Lit q, Lit r, Lit s){ add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); add_tmp.push(s); return addClause_(add_tmp); } +inline void SimpSolver::setFrozen (Var v, bool b) { frozen[v] = (char)b; if (use_simplification && !b) { updateElimHeap(v); } } + +inline void SimpSolver::freezeVar(Var v){ + if (!frozen[v]){ + frozen[v] = 1; + frozen_vars.push(v); + } } + +inline void SimpSolver::thaw(){ + for (int i = 0; i < frozen_vars.size(); i++){ + Var v = frozen_vars[i]; + frozen[v] = 0; + if (use_simplification) + updateElimHeap(v); + } + frozen_vars.clear(); } + +inline bool SimpSolver::solve ( bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); return solve_(do_simp, turn_off_simp) == l_True; } +inline bool SimpSolver::solve (Lit p , bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_(do_simp, turn_off_simp) == l_True; } +inline bool SimpSolver::solve (Lit p, Lit q, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_(do_simp, turn_off_simp) == l_True; } +inline bool SimpSolver::solve (Lit p, Lit q, Lit r, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_(do_simp, turn_off_simp) == l_True; } +inline bool SimpSolver::solve (const vec& assumps, bool do_simp, bool turn_off_simp){ + budgetOff(); assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp) == l_True; } + +inline lbool SimpSolver::solveLimited (const vec& assumps, bool do_simp, bool turn_off_simp){ + assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); } + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Solver.cc b/libs/minisat/Solver.cc new file mode 100644 index 00000000..ebca294a --- /dev/null +++ b/libs/minisat/Solver.cc @@ -0,0 +1,1068 @@ +#define __STDC_FORMAT_MACROS +#define __STDC_LIMIT_MACROS +/***************************************************************************************[Solver.cc] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#include + +#include "libs/minisat/Alg.h" +#include "libs/minisat/Sort.h" +#include "libs/minisat/System.h" +#include "libs/minisat/Solver.h" + +using namespace Minisat; + +//================================================================================================= +// Options: + + +static const char* _cat = "CORE"; + +static DoubleOption opt_var_decay (_cat, "var-decay", "The variable activity decay factor", 0.95, DoubleRange(0, false, 1, false)); +static DoubleOption opt_clause_decay (_cat, "cla-decay", "The clause activity decay factor", 0.999, DoubleRange(0, false, 1, false)); +static DoubleOption opt_random_var_freq (_cat, "rnd-freq", "The frequency with which the decision heuristic tries to choose a random variable", 0, DoubleRange(0, true, 1, true)); +static DoubleOption opt_random_seed (_cat, "rnd-seed", "Used by the random variable selection", 91648253, DoubleRange(0, false, HUGE_VAL, false)); +static IntOption opt_ccmin_mode (_cat, "ccmin-mode", "Controls conflict clause minimization (0=none, 1=basic, 2=deep)", 2, IntRange(0, 2)); +static IntOption opt_phase_saving (_cat, "phase-saving", "Controls the level of phase saving (0=none, 1=limited, 2=full)", 2, IntRange(0, 2)); +static BoolOption opt_rnd_init_act (_cat, "rnd-init", "Randomize the initial activity", false); +static BoolOption opt_luby_restart (_cat, "luby", "Use the Luby restart sequence", true); +static IntOption opt_restart_first (_cat, "rfirst", "The base restart interval", 100, IntRange(1, INT32_MAX)); +static DoubleOption opt_restart_inc (_cat, "rinc", "Restart interval increase factor", 2, DoubleRange(1, false, HUGE_VAL, false)); +static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false)); +static IntOption opt_min_learnts_lim (_cat, "min-learnts", "Minimum learnt clause limit", 0, IntRange(0, INT32_MAX)); + + +//================================================================================================= +// Constructor/Destructor: + + +Solver::Solver() : + + // Parameters (user settable): + // + verbosity (0) + , var_decay (opt_var_decay) + , clause_decay (opt_clause_decay) + , random_var_freq (opt_random_var_freq) + , random_seed (opt_random_seed) + , luby_restart (opt_luby_restart) + , ccmin_mode (opt_ccmin_mode) + , phase_saving (opt_phase_saving) + , rnd_pol (false) + , rnd_init_act (opt_rnd_init_act) + , garbage_frac (opt_garbage_frac) + , min_learnts_lim (opt_min_learnts_lim) + , restart_first (opt_restart_first) + , restart_inc (opt_restart_inc) + + // Parameters (the rest): + // + , learntsize_factor((double)1/(double)3), learntsize_inc(1.1) + + // Parameters (experimental): + // + , learntsize_adjust_start_confl (100) + , learntsize_adjust_inc (1.5) + + // Statistics: (formerly in 'SolverStats') + // + , solves(0), starts(0), decisions(0), rnd_decisions(0), propagations(0), conflicts(0) + , dec_vars(0), num_clauses(0), num_learnts(0), clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) + + , watches (WatcherDeleted(ca)) + , order_heap (VarOrderLt(activity)) + , ok (true) + , cla_inc (1) + , var_inc (1) + , qhead (0) + , simpDB_assigns (-1) + , simpDB_props (0) + , progress_estimate (0) + , remove_satisfied (true) + , next_var (0) + + // Resource constraints: + // + , conflict_budget (-1) + , propagation_budget (-1) + , asynch_interrupt (false) +{} + + +Solver::~Solver() +{ +} + + +//================================================================================================= +// Minor methods: + + +// Creates a new SAT variable in the solver. If 'decision' is cleared, variable will not be +// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result). +// +Var Solver::newVar(lbool upol, bool dvar) +{ + Var v; + if (free_vars.size() > 0){ + v = free_vars.last(); + free_vars.pop(); + }else + v = next_var++; + + watches .init(mkLit(v, false)); + watches .init(mkLit(v, true )); + assigns .insert(v, l_Undef); + vardata .insert(v, mkVarData(CRef_Undef, 0)); + activity .insert(v, rnd_init_act ? drand(random_seed) * 0.00001 : 0); + seen .insert(v, 0); + polarity .insert(v, true); + user_pol .insert(v, upol); + decision .reserve(v); + trail .capacity(v+1); + setDecisionVar(v, dvar); + return v; +} + + +// Note: at the moment, only unassigned variable will be released (this is to avoid duplicate +// releases of the same variable). +void Solver::releaseVar(Lit l) +{ + if (value(l) == l_Undef){ + addClause(l); + released_vars.push(var(l)); + } +} + + +bool Solver::addClause_(vec& ps) +{ + assert(decisionLevel() == 0); + if (!ok) return false; + + // Check if clause is satisfied and remove false/duplicate literals: + sort(ps); + Lit p; int i, j; + for (i = j = 0, p = lit_Undef; i < ps.size(); i++) + if (value(ps[i]) == l_True || ps[i] == ~p) + return true; + else if (value(ps[i]) != l_False && ps[i] != p) + ps[j++] = p = ps[i]; + ps.shrink(i - j); + + if (ps.size() == 0) + return ok = false; + else if (ps.size() == 1){ + uncheckedEnqueue(ps[0]); + return ok = (propagate() == CRef_Undef); + }else{ + CRef cr = ca.alloc(ps, false); + clauses.push(cr); + attachClause(cr); + } + + return true; +} + + +void Solver::attachClause(CRef cr){ + const Clause& c = ca[cr]; + assert(c.size() > 1); + watches[~c[0]].push(Watcher(cr, c[1])); + watches[~c[1]].push(Watcher(cr, c[0])); + if (c.learnt()) num_learnts++, learnts_literals += c.size(); + else num_clauses++, clauses_literals += c.size(); +} + + +void Solver::detachClause(CRef cr, bool strict){ + const Clause& c = ca[cr]; + assert(c.size() > 1); + + // Strict or lazy detaching: + if (strict){ + remove(watches[~c[0]], Watcher(cr, c[1])); + remove(watches[~c[1]], Watcher(cr, c[0])); + }else{ + watches.smudge(~c[0]); + watches.smudge(~c[1]); + } + + if (c.learnt()) num_learnts--, learnts_literals -= c.size(); + else num_clauses--, clauses_literals -= c.size(); +} + + +void Solver::removeClause(CRef cr) { + Clause& c = ca[cr]; + detachClause(cr); + // Don't leave pointers to free'd memory! + if (locked(c)) vardata[var(c[0])].reason = CRef_Undef; + c.mark(1); + ca.free(cr); +} + + +bool Solver::satisfied(const Clause& c) const { + for (int i = 0; i < c.size(); i++) + if (value(c[i]) == l_True) + return true; + return false; } + + +// Revert to the state at given level (keeping all assignment at 'level' but not beyond). +// +void Solver::cancelUntil(int level) { + if (decisionLevel() > level){ + for (int c = trail.size()-1; c >= trail_lim[level]; c--){ + Var x = var(trail[c]); + assigns [x] = l_Undef; + if (phase_saving > 1 || (phase_saving == 1 && c > trail_lim.last())) + polarity[x] = sign(trail[c]); + insertVarOrder(x); } + qhead = trail_lim[level]; + trail.shrink(trail.size() - trail_lim[level]); + trail_lim.shrink(trail_lim.size() - level); + } } + + +//================================================================================================= +// Major methods: + + +Lit Solver::pickBranchLit() +{ + Var next = var_Undef; + + // Random decision: + if (drand(random_seed) < random_var_freq && !order_heap.empty()){ + next = order_heap[irand(random_seed,order_heap.size())]; + if (value(next) == l_Undef && decision[next]) + rnd_decisions++; } + + // Activity based decision: + while (next == var_Undef || value(next) != l_Undef || !decision[next]) + if (order_heap.empty()){ + next = var_Undef; + break; + }else + next = order_heap.removeMin(); + + // Choose polarity based on different polarity modes (global or per-variable): + if (next == var_Undef) + return lit_Undef; + else if (user_pol[next] != l_Undef) + return mkLit(next, user_pol[next] == l_True); + else if (rnd_pol) + return mkLit(next, drand(random_seed) < 0.5); + else + return mkLit(next, polarity[next]); +} + + +/*_________________________________________________________________________________________________ +| +| analyze : (confl : Clause*) (out_learnt : vec&) (out_btlevel : int&) -> [void] +| +| Description: +| Analyze conflict and produce a reason clause. +| +| Pre-conditions: +| * 'out_learnt' is assumed to be cleared. +| * Current decision level must be greater than root level. +| +| Post-conditions: +| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. +| * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the +| rest of literals. There may be others from the same level though. +| +|________________________________________________________________________________________________@*/ +void Solver::analyze(CRef confl, vec& out_learnt, int& out_btlevel) +{ + int pathC = 0; + Lit p = lit_Undef; + + // Generate conflict clause: + // + out_learnt.push(); // (leave room for the asserting literal) + int index = trail.size() - 1; + + do{ + assert(confl != CRef_Undef); // (otherwise should be UIP) + Clause& c = ca[confl]; + + if (c.learnt()) + claBumpActivity(c); + + for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ + Lit q = c[j]; + + if (!seen[var(q)] && level(var(q)) > 0){ + varBumpActivity(var(q)); + seen[var(q)] = 1; + if (level(var(q)) >= decisionLevel()) + pathC++; + else + out_learnt.push(q); + } + } + + // Select next clause to look at: + while (!seen[var(trail[index--])]); + p = trail[index+1]; + confl = reason(var(p)); + seen[var(p)] = 0; + pathC--; + + }while (pathC > 0); + out_learnt[0] = ~p; + + // Simplify conflict clause: + // + int i, j; + out_learnt.copyTo(analyze_toclear); + if (ccmin_mode == 2){ + for (i = j = 1; i < out_learnt.size(); i++) + if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i])) + out_learnt[j++] = out_learnt[i]; + + }else if (ccmin_mode == 1){ + for (i = j = 1; i < out_learnt.size(); i++){ + Var x = var(out_learnt[i]); + + if (reason(x) == CRef_Undef) + out_learnt[j++] = out_learnt[i]; + else{ + Clause& c = ca[reason(var(out_learnt[i]))]; + for (int k = 1; k < c.size(); k++) + if (!seen[var(c[k])] && level(var(c[k])) > 0){ + out_learnt[j++] = out_learnt[i]; + break; } + } + } + }else + i = j = out_learnt.size(); + + max_literals += out_learnt.size(); + out_learnt.shrink(i - j); + tot_literals += out_learnt.size(); + + // Find correct backtrack level: + // + if (out_learnt.size() == 1) + out_btlevel = 0; + else{ + int max_i = 1; + // Find the first literal assigned at the next-highest level: + for (int i = 2; i < out_learnt.size(); i++) + if (level(var(out_learnt[i])) > level(var(out_learnt[max_i]))) + max_i = i; + // Swap-in this literal at index 1: + Lit p = out_learnt[max_i]; + out_learnt[max_i] = out_learnt[1]; + out_learnt[1] = p; + out_btlevel = level(var(p)); + } + + for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) +} + + +// Check if 'p' can be removed from a conflict clause. +bool Solver::litRedundant(Lit p) +{ + enum { seen_undef = 0, seen_source = 1, seen_removable = 2, seen_failed = 3 }; + assert(seen[var(p)] == seen_undef || seen[var(p)] == seen_source); + assert(reason(var(p)) != CRef_Undef); + + Clause* c = &ca[reason(var(p))]; + vec& stack = analyze_stack; + stack.clear(); + + for (uint32_t i = 1; ; i++){ + if (i < (uint32_t)c->size()){ + // Checking 'p'-parents 'l': + Lit l = (*c)[i]; + + // Variable at level 0 or previously removable: + if (level(var(l)) == 0 || seen[var(l)] == seen_source || seen[var(l)] == seen_removable){ + continue; } + + // Check variable can not be removed for some local reason: + if (reason(var(l)) == CRef_Undef || seen[var(l)] == seen_failed){ + stack.push(ShrinkStackElem(0, p)); + for (int i = 0; i < stack.size(); i++) + if (seen[var(stack[i].l)] == seen_undef){ + seen[var(stack[i].l)] = seen_failed; + analyze_toclear.push(stack[i].l); + } + + return false; + } + + // Recursively check 'l': + stack.push(ShrinkStackElem(i, p)); + i = 0; + p = l; + c = &ca[reason(var(p))]; + }else{ + // Finished with current element 'p' and reason 'c': + if (seen[var(p)] == seen_undef){ + seen[var(p)] = seen_removable; + analyze_toclear.push(p); + } + + // Terminate with success if stack is empty: + if (stack.size() == 0) break; + + // Continue with top element on stack: + i = stack.last().i; + p = stack.last().l; + c = &ca[reason(var(p))]; + + stack.pop(); + } + } + + return true; +} + + +/*_________________________________________________________________________________________________ +| +| analyzeFinal : (p : Lit) -> [void] +| +| Description: +| Specialized analysis procedure to express the final conflict in terms of assumptions. +| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and +| stores the result in 'out_conflict'. +|________________________________________________________________________________________________@*/ +void Solver::analyzeFinal(Lit p, LSet& out_conflict) +{ + out_conflict.clear(); + out_conflict.insert(p); + + if (decisionLevel() == 0) + return; + + seen[var(p)] = 1; + + for (int i = trail.size()-1; i >= trail_lim[0]; i--){ + Var x = var(trail[i]); + if (seen[x]){ + if (reason(x) == CRef_Undef){ + assert(level(x) > 0); + out_conflict.insert(~trail[i]); + }else{ + Clause& c = ca[reason(x)]; + for (int j = 1; j < c.size(); j++) + if (level(var(c[j])) > 0) + seen[var(c[j])] = 1; + } + seen[x] = 0; + } + } + + seen[var(p)] = 0; +} + + +void Solver::uncheckedEnqueue(Lit p, CRef from) +{ + assert(value(p) == l_Undef); + assigns[var(p)] = lbool(!sign(p)); + vardata[var(p)] = mkVarData(from, decisionLevel()); + trail.push_(p); +} + + +/*_________________________________________________________________________________________________ +| +| propagate : [void] -> [Clause*] +| +| Description: +| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned, +| otherwise CRef_Undef. +| +| Post-conditions: +| * the propagation queue is empty, even if there was a conflict. +|________________________________________________________________________________________________@*/ +CRef Solver::propagate() +{ + CRef confl = CRef_Undef; + int num_props = 0; + + while (qhead < trail.size()){ + Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate. + vec& ws = watches.lookup(p); + Watcher *i, *j, *end; + num_props++; + + for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){ + // Try to avoid inspecting the clause: + Lit blocker = i->blocker; + if (value(blocker) == l_True){ + *j++ = *i++; continue; } + + // Make sure the false literal is data[1]: + CRef cr = i->cref; + Clause& c = ca[cr]; + Lit false_lit = ~p; + if (c[0] == false_lit) + c[0] = c[1], c[1] = false_lit; + assert(c[1] == false_lit); + i++; + + // If 0th watch is true, then clause is already satisfied. + Lit first = c[0]; + Watcher w = Watcher(cr, first); + if (first != blocker && value(first) == l_True){ + *j++ = w; continue; } + + // Look for new watch: + for (int k = 2; k < c.size(); k++) + if (value(c[k]) != l_False){ + c[1] = c[k]; c[k] = false_lit; + watches[~c[1]].push(w); + goto NextClause; } + + // Did not find watch -- clause is unit under assignment: + *j++ = w; + if (value(first) == l_False){ + confl = cr; + qhead = trail.size(); + // Copy the remaining watches: + while (i < end) + *j++ = *i++; + }else + uncheckedEnqueue(first, cr); + + NextClause:; + } + ws.shrink(i - j); + } + propagations += num_props; + simpDB_props -= num_props; + + return confl; +} + + +/*_________________________________________________________________________________________________ +| +| reduceDB : () -> [void] +| +| Description: +| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked +| clauses are clauses that are reason to some assignment. Binary clauses are never removed. +|________________________________________________________________________________________________@*/ +struct reduceDB_lt { + ClauseAllocator& ca; + reduceDB_lt(ClauseAllocator& ca_) : ca(ca_) {} + bool operator () (CRef x, CRef y) { + return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); } +}; +void Solver::reduceDB() +{ + int i, j; + double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity + + sort(learnts, reduceDB_lt(ca)); + // Don't delete binary or locked clauses. From the rest, delete clauses from the first half + // and clauses with activity smaller than 'extra_lim': + for (i = j = 0; i < learnts.size(); i++){ + Clause& c = ca[learnts[i]]; + if (c.size() > 2 && !locked(c) && (i < learnts.size() / 2 || c.activity() < extra_lim)) + removeClause(learnts[i]); + else + learnts[j++] = learnts[i]; + } + learnts.shrink(i - j); + checkGarbage(); +} + + +void Solver::removeSatisfied(vec& cs) +{ + int i, j; + for (i = j = 0; i < cs.size(); i++){ + Clause& c = ca[cs[i]]; + if (satisfied(c)) + removeClause(cs[i]); + else{ + // Trim clause: + assert(value(c[0]) == l_Undef && value(c[1]) == l_Undef); + for (int k = 2; k < c.size(); k++) + if (value(c[k]) == l_False){ + c[k--] = c[c.size()-1]; + c.pop(); + } + cs[j++] = cs[i]; + } + } + cs.shrink(i - j); +} + + +void Solver::rebuildOrderHeap() +{ + vec vs; + for (Var v = 0; v < nVars(); v++) + if (decision[v] && value(v) == l_Undef) + vs.push(v); + order_heap.build(vs); +} + + +/*_________________________________________________________________________________________________ +| +| simplify : [void] -> [bool] +| +| Description: +| Simplify the clause database according to the current top-level assigment. Currently, the only +| thing done here is the removal of satisfied clauses, but more things can be put here. +|________________________________________________________________________________________________@*/ +bool Solver::simplify() +{ + assert(decisionLevel() == 0); + + if (!ok || propagate() != CRef_Undef) + return ok = false; + + if (nAssigns() == simpDB_assigns || (simpDB_props > 0)) + return true; + + // Remove satisfied clauses: + removeSatisfied(learnts); + if (remove_satisfied){ // Can be turned off. + removeSatisfied(clauses); + + // TODO: what todo in if 'remove_satisfied' is false? + + // Remove all released variables from the trail: + for (int i = 0; i < released_vars.size(); i++){ + assert(seen[released_vars[i]] == 0); + seen[released_vars[i]] = 1; + } + + int i, j; + for (i = j = 0; i < trail.size(); i++) + if (seen[var(trail[i])] == 0) + trail[j++] = trail[i]; + trail.shrink(i - j); + //printf("trail.size()= %d, qhead = %d\n", trail.size(), qhead); + qhead = trail.size(); + + for (int i = 0; i < released_vars.size(); i++) + seen[released_vars[i]] = 0; + + // Released variables are now ready to be reused: + append(released_vars, free_vars); + released_vars.clear(); + } + checkGarbage(); + rebuildOrderHeap(); + + simpDB_assigns = nAssigns(); + simpDB_props = clauses_literals + learnts_literals; // (shouldn't depend on stats really, but it will do for now) + + return true; +} + + +/*_________________________________________________________________________________________________ +| +| search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool] +| +| Description: +| Search for a model the specified number of conflicts. +| NOTE! Use negative value for 'nof_conflicts' indicate infinity. +| +| Output: +| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If +| all variables are decision variables, this means that the clause set is satisfiable. 'l_False' +| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. +|________________________________________________________________________________________________@*/ +lbool Solver::search(int nof_conflicts) +{ + assert(ok); + int backtrack_level; + int conflictC = 0; + vec learnt_clause; + starts++; + + for (;;){ + CRef confl = propagate(); + if (confl != CRef_Undef){ + // CONFLICT + conflicts++; conflictC++; + if (decisionLevel() == 0) return l_False; + + learnt_clause.clear(); + analyze(confl, learnt_clause, backtrack_level); + cancelUntil(backtrack_level); + + if (learnt_clause.size() == 1){ + uncheckedEnqueue(learnt_clause[0]); + }else{ + CRef cr = ca.alloc(learnt_clause, true); + learnts.push(cr); + attachClause(cr); + claBumpActivity(ca[cr]); + uncheckedEnqueue(learnt_clause[0], cr); + } + + varDecayActivity(); + claDecayActivity(); + + if (--learntsize_adjust_cnt == 0){ + learntsize_adjust_confl *= learntsize_adjust_inc; + learntsize_adjust_cnt = (int)learntsize_adjust_confl; + max_learnts *= learntsize_inc; + + if (verbosity >= 1) + printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", + (int)conflicts, + (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals, + (int)max_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progressEstimate()*100); + } + + }else{ + // NO CONFLICT + if ((nof_conflicts >= 0 && conflictC >= nof_conflicts) || !withinBudget()){ + // Reached bound on number of conflicts: + progress_estimate = progressEstimate(); + cancelUntil(0); + return l_Undef; } + + // Simplify the set of problem clauses: + if (decisionLevel() == 0 && !simplify()) + return l_False; + + if (learnts.size()-nAssigns() >= max_learnts) + // Reduce the set of learnt clauses: + reduceDB(); + + Lit next = lit_Undef; + while (decisionLevel() < assumptions.size()){ + // Perform user provided assumption: + Lit p = assumptions[decisionLevel()]; + if (value(p) == l_True){ + // Dummy decision level: + newDecisionLevel(); + }else if (value(p) == l_False){ + analyzeFinal(~p, conflict); + return l_False; + }else{ + next = p; + break; + } + } + + if (next == lit_Undef){ + // New variable decision: + decisions++; + next = pickBranchLit(); + + if (next == lit_Undef) + // Model found: + return l_True; + } + + // Increase decision level and enqueue 'next' + newDecisionLevel(); + uncheckedEnqueue(next); + } + } +} + + +double Solver::progressEstimate() const +{ + double progress = 0; + double F = 1.0 / nVars(); + + for (int i = 0; i <= decisionLevel(); i++){ + int beg = i == 0 ? 0 : trail_lim[i - 1]; + int end = i == decisionLevel() ? trail.size() : trail_lim[i]; + progress += pow(F, i) * (end - beg); + } + + return progress / nVars(); +} + +/* + Finite subsequences of the Luby-sequence: + + 0: 1 + 1: 1 1 2 + 2: 1 1 2 1 1 2 4 + 3: 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8 + ... + + + */ + +static double luby(double y, int x){ + + // Find the finite subsequence that contains index 'x', and the + // size of that subsequence: + int size, seq; + for (size = 1, seq = 0; size < x+1; seq++, size = 2*size+1); + + while (size-1 != x){ + size = (size-1)>>1; + seq--; + x = x % size; + } + + return pow(y, seq); +} + +// NOTE: assumptions passed in member-variable 'assumptions'. +lbool Solver::solve_() +{ + model.clear(); + conflict.clear(); + if (!ok) return l_False; + + solves++; + + max_learnts = nClauses() * learntsize_factor; + if (max_learnts < min_learnts_lim) + max_learnts = min_learnts_lim; + + learntsize_adjust_confl = learntsize_adjust_start_confl; + learntsize_adjust_cnt = (int)learntsize_adjust_confl; + lbool status = l_Undef; + + if (verbosity >= 1){ + printf("============================[ Search Statistics ]==============================\n"); + printf("| Conflicts | ORIGINAL | LEARNT | Progress |\n"); + printf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n"); + printf("===============================================================================\n"); + } + + // Search: + int curr_restarts = 0; + while (status == l_Undef){ + double rest_base = luby_restart ? luby(restart_inc, curr_restarts) : pow(restart_inc, curr_restarts); + status = search(rest_base * restart_first); + if (!withinBudget()) break; + curr_restarts++; + } + + if (verbosity >= 1) + printf("===============================================================================\n"); + + + if (status == l_True){ + // Extend & copy model: + model.growTo(nVars()); + for (int i = 0; i < nVars(); i++) model[i] = value(i); + }else if (status == l_False && conflict.size() == 0) + ok = false; + + cancelUntil(0); + return status; +} + + +bool Solver::implies(const vec& assumps, vec& out) +{ + trail_lim.push(trail.size()); + for (int i = 0; i < assumps.size(); i++){ + Lit a = assumps[i]; + + if (value(a) == l_False){ + cancelUntil(0); + return false; + }else if (value(a) == l_Undef) + uncheckedEnqueue(a); + } + + unsigned trail_before = trail.size(); + bool ret = true; + if (propagate() == CRef_Undef){ + out.clear(); + for (int j = trail_before; j < trail.size(); j++) + out.push(trail[j]); + }else + ret = false; + + cancelUntil(0); + return ret; +} + +//================================================================================================= +// Writing CNF to DIMACS: +// +// FIXME: this needs to be rewritten completely. + +static Var mapVar(Var x, vec& map, Var& max) +{ + if (map.size() <= x || map[x] == -1){ + map.growTo(x+1, -1); + map[x] = max++; + } + return map[x]; +} + + +void Solver::toDimacs(FILE* f, Clause& c, vec& map, Var& max) +{ + if (satisfied(c)) return; + + for (int i = 0; i < c.size(); i++) + if (value(c[i]) != l_False) + fprintf(f, "%s%d ", sign(c[i]) ? "-" : "", mapVar(var(c[i]), map, max)+1); + fprintf(f, "0\n"); +} + + +void Solver::toDimacs(const char *file, const vec& assumps) +{ + FILE* f = fopen(file, "wr"); + if (f == NULL) + fprintf(stderr, "could not open file %s\n", file), exit(1); + toDimacs(f, assumps); + fclose(f); +} + + +void Solver::toDimacs(FILE* f, const vec& assumps) +{ + // Handle case when solver is in contradictory state: + if (!ok){ + fprintf(f, "p cnf 1 2\n1 0\n-1 0\n"); + return; } + + vec map; Var max = 0; + + // Cannot use removeClauses here because it is not safe + // to deallocate them at this point. Could be improved. + int cnt = 0; + for (int i = 0; i < clauses.size(); i++) + if (!satisfied(ca[clauses[i]])) + cnt++; + + for (int i = 0; i < clauses.size(); i++) + if (!satisfied(ca[clauses[i]])){ + Clause& c = ca[clauses[i]]; + for (int j = 0; j < c.size(); j++) + if (value(c[j]) != l_False) + mapVar(var(c[j]), map, max); + } + + // Assumptions are added as unit clauses: + cnt += assumps.size(); + + fprintf(f, "p cnf %d %d\n", max, cnt); + + for (int i = 0; i < assumps.size(); i++){ + assert(value(assumps[i]) != l_False); + fprintf(f, "%s%d 0\n", sign(assumps[i]) ? "-" : "", mapVar(var(assumps[i]), map, max)+1); + } + + for (int i = 0; i < clauses.size(); i++) + toDimacs(f, ca[clauses[i]], map, max); + + if (verbosity > 0) + printf("Wrote DIMACS with %d variables and %d clauses.\n", max, cnt); +} + + +void Solver::printStats() const +{ + double cpu_time = cpuTime(); + double mem_used = memUsedPeak(); + printf("restarts : %"PRIu64"\n", starts); + printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", conflicts , conflicts /cpu_time); + printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", decisions, (float)rnd_decisions*100 / (float)decisions, decisions /cpu_time); + printf("propagations : %-12"PRIu64" (%.0f /sec)\n", propagations, propagations/cpu_time); + printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", tot_literals, (max_literals - tot_literals)*100 / (double)max_literals); + if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used); + printf("CPU time : %g s\n", cpu_time); +} + + +//================================================================================================= +// Garbage Collection methods: + +void Solver::relocAll(ClauseAllocator& to) +{ + // All watchers: + // + watches.cleanAll(); + for (int v = 0; v < nVars(); v++) + for (int s = 0; s < 2; s++){ + Lit p = mkLit(v, s); + vec& ws = watches[p]; + for (int j = 0; j < ws.size(); j++) + ca.reloc(ws[j].cref, to); + } + + // All reasons: + // + for (int i = 0; i < trail.size(); i++){ + Var v = var(trail[i]); + + // Note: it is not safe to call 'locked()' on a relocated clause. This is why we keep + // 'dangling' reasons here. It is safe and does not hurt. + if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)]))){ + assert(!isRemoved(reason(v))); + ca.reloc(vardata[v].reason, to); + } + } + + // All learnt: + // + int i, j; + for (i = j = 0; i < learnts.size(); i++) + if (!isRemoved(learnts[i])){ + ca.reloc(learnts[i], to); + learnts[j++] = learnts[i]; + } + learnts.shrink(i - j); + + // All original: + // + for (i = j = 0; i < clauses.size(); i++) + if (!isRemoved(clauses[i])){ + ca.reloc(clauses[i], to); + clauses[j++] = clauses[i]; + } + clauses.shrink(i - j); +} + + +void Solver::garbageCollect() +{ + // Initialize the next region to a size corresponding to the estimated utilization degree. This + // is not precise but should avoid some unnecessary reallocations for the new region: + ClauseAllocator to(ca.size() - ca.wasted()); + + relocAll(to); + if (verbosity >= 2) + printf("| Garbage collection: %12d bytes => %12d bytes |\n", + ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size); + to.moveTo(ca); +} diff --git a/libs/minisat/Solver.h b/libs/minisat/Solver.h new file mode 100644 index 00000000..73fc7d4c --- /dev/null +++ b/libs/minisat/Solver.h @@ -0,0 +1,409 @@ +/****************************************************************************************[Solver.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Solver_h +#define Minisat_Solver_h + +#include "libs/minisat/Vec.h" +#include "libs/minisat/Heap.h" +#include "libs/minisat/Alg.h" +#include "libs/minisat/IntMap.h" +#include "libs/minisat/Options.h" +#include "libs/minisat/SolverTypes.h" + + +namespace Minisat { + +//================================================================================================= +// Solver -- the main class: + +class Solver { +public: + + // Constructor/Destructor: + // + Solver(); + virtual ~Solver(); + + // Problem specification: + // + Var newVar (lbool upol = l_Undef, bool dvar = true); // Add a new variable with parameters specifying variable mode. + void releaseVar(Lit l); // Make literal true and promise to never refer to variable again. + + bool addClause (const vec& ps); // Add a clause to the solver. + bool addEmptyClause(); // Add the empty clause, making the solver contradictory. + bool addClause (Lit p); // Add a unit clause to the solver. + bool addClause (Lit p, Lit q); // Add a binary clause to the solver. + bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver. + bool addClause (Lit p, Lit q, Lit r, Lit s); // Add a quaternary clause to the solver. + bool addClause_( vec& ps); // Add a clause to the solver without making superflous internal copy. Will + // change the passed vector 'ps'. + + // Solving: + // + bool simplify (); // Removes already satisfied clauses. + bool solve (const vec& assumps); // Search for a model that respects a given set of assumptions. + lbool solveLimited (const vec& assumps); // Search for a model that respects a given set of assumptions (With resource constraints). + bool solve (); // Search without assumptions. + bool solve (Lit p); // Search for a model that respects a single assumption. + bool solve (Lit p, Lit q); // Search for a model that respects two assumptions. + bool solve (Lit p, Lit q, Lit r); // Search for a model that respects three assumptions. + bool okay () const; // FALSE means solver is in a conflicting state + + bool implies (const vec& assumps, vec& out); + + // Iterate over clauses and top-level assignments: + ClauseIterator clausesBegin() const; + ClauseIterator clausesEnd() const; + TrailIterator trailBegin() const; + TrailIterator trailEnd () const; + + void toDimacs (FILE* f, const vec& assumps); // Write CNF to file in DIMACS-format. + void toDimacs (const char *file, const vec& assumps); + void toDimacs (FILE* f, Clause& c, vec& map, Var& max); + + // Convenience versions of 'toDimacs()': + void toDimacs (const char* file); + void toDimacs (const char* file, Lit p); + void toDimacs (const char* file, Lit p, Lit q); + void toDimacs (const char* file, Lit p, Lit q, Lit r); + + // Variable mode: + // + void setPolarity (Var v, lbool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'. + void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic. + + // Read state: + // + lbool value (Var x) const; // The current value of a variable. + lbool value (Lit p) const; // The current value of a literal. + lbool modelValue (Var x) const; // The value of a variable in the last model. The last call to solve must have been satisfiable. + lbool modelValue (Lit p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable. + int nAssigns () const; // The current number of assigned literals. + int nClauses () const; // The current number of original clauses. + int nLearnts () const; // The current number of learnt clauses. + int nVars () const; // The current number of variables. + int nFreeVars () const; + void printStats () const; // Print some current statistics to standard output. + + // Resource contraints: + // + void setConfBudget(int64_t x); + void setPropBudget(int64_t x); + void budgetOff(); + void interrupt(); // Trigger a (potentially asynchronous) interruption of the solver. + void clearInterrupt(); // Clear interrupt indicator flag. + + // Memory managment: + // + virtual void garbageCollect(); + void checkGarbage(double gf); + void checkGarbage(); + + // Extra results: (read-only member variable) + // + vec model; // If problem is satisfiable, this vector contains the model (if any). + LSet conflict; // If problem is unsatisfiable (possibly under assumptions), + // this vector represent the final conflict clause expressed in the assumptions. + + // Mode of operation: + // + int verbosity; + double var_decay; + double clause_decay; + double random_var_freq; + double random_seed; + bool luby_restart; + int ccmin_mode; // Controls conflict clause minimization (0=none, 1=basic, 2=deep). + int phase_saving; // Controls the level of phase saving (0=none, 1=limited, 2=full). + bool rnd_pol; // Use random polarities for branching heuristics. + bool rnd_init_act; // Initialize variable activities with a small random value. + double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered. + int min_learnts_lim; // Minimum number to set the learnts limit to. + + int restart_first; // The initial restart limit. (default 100) + double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.5) + double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3) + double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1) + + int learntsize_adjust_start_confl; + double learntsize_adjust_inc; + + // Statistics: (read-only member variable) + // + uint64_t solves, starts, decisions, rnd_decisions, propagations, conflicts; + uint64_t dec_vars, num_clauses, num_learnts, clauses_literals, learnts_literals, max_literals, tot_literals; + +protected: + + // Helper structures: + // + struct VarData { CRef reason; int level; }; + static inline VarData mkVarData(CRef cr, int l){ VarData d = {cr, l}; return d; } + + struct Watcher { + CRef cref; + Lit blocker; + Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {} + bool operator==(const Watcher& w) const { return cref == w.cref; } + bool operator!=(const Watcher& w) const { return cref != w.cref; } + }; + + struct WatcherDeleted + { + const ClauseAllocator& ca; + WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {} + bool operator()(const Watcher& w) const { return ca[w.cref].mark() == 1; } + }; + + struct VarOrderLt { + const IntMap& activity; + bool operator () (Var x, Var y) const { return activity[x] > activity[y]; } + VarOrderLt(const IntMap& act) : activity(act) { } + }; + + struct ShrinkStackElem { + uint32_t i; + Lit l; + ShrinkStackElem(uint32_t _i, Lit _l) : i(_i), l(_l){} + }; + + // Solver state: + // + vec clauses; // List of problem clauses. + vec learnts; // List of learnt clauses. + vec trail; // Assignment stack; stores all assigments made in the order they were made. + vec trail_lim; // Separator indices for different decision levels in 'trail'. + vec assumptions; // Current set of assumptions provided to solve by the user. + + VMap activity; // A heuristic measurement of the activity of a variable. + VMap assigns; // The current assignments. + VMap polarity; // The preferred polarity of each variable. + VMap user_pol; // The users preferred polarity of each variable. + VMap decision; // Declares if a variable is eligible for selection in the decision heuristic. + VMap vardata; // Stores reason and level for each variable. + OccLists, WatcherDeleted, MkIndexLit> + watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true). + + Heaporder_heap; // A priority queue of variables ordered with respect to the variable activity. + + bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used! + double cla_inc; // Amount to bump next clause with. + double var_inc; // Amount to bump next variable with. + int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat). + int simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'. + int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'. + double progress_estimate;// Set by 'search()'. + bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'. + Var next_var; // Next variable to be created. + ClauseAllocator ca; + + vec released_vars; + vec free_vars; + + // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is + // used, exept 'seen' wich is used in several places. + // + VMap seen; + vecanalyze_stack; + vec analyze_toclear; + vec add_tmp; + + double max_learnts; + double learntsize_adjust_confl; + int learntsize_adjust_cnt; + + // Resource contraints: + // + int64_t conflict_budget; // -1 means no budget. + int64_t propagation_budget; // -1 means no budget. + bool asynch_interrupt; + + // Main internal methods: + // + void insertVarOrder (Var x); // Insert a variable in the decision order priority queue. + Lit pickBranchLit (); // Return the next decision variable. + void newDecisionLevel (); // Begins a new decision level. + void uncheckedEnqueue (Lit p, CRef from = CRef_Undef); // Enqueue a literal. Assumes value of literal is undefined. + bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise. + CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause. + void cancelUntil (int level); // Backtrack until a certain level. + void analyze (CRef confl, vec& out_learnt, int& out_btlevel); // (bt = backtrack) + void analyzeFinal (Lit p, LSet& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION? + bool litRedundant (Lit p); // (helper method for 'analyze()') + lbool search (int nof_conflicts); // Search for a given number of conflicts. + lbool solve_ (); // Main solve method (assumptions given in 'assumptions'). + void reduceDB (); // Reduce the set of learnt clauses. + void removeSatisfied (vec& cs); // Shrink 'cs' to contain only non-satisfied clauses. + void rebuildOrderHeap (); + + // Maintaining Variable/Clause activity: + // + void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead. + void varBumpActivity (Var v, double inc); // Increase a variable with the current 'bump' value. + void varBumpActivity (Var v); // Increase a variable with the current 'bump' value. + void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead. + void claBumpActivity (Clause& c); // Increase a clause with the current 'bump' value. + + // Operations on clauses: + // + void attachClause (CRef cr); // Attach a clause to watcher lists. + void detachClause (CRef cr, bool strict = false); // Detach a clause to watcher lists. + void removeClause (CRef cr); // Detach and free a clause. + bool isRemoved (CRef cr) const; // Test if a clause has been removed. + bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state. + bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state. + + // Misc: + // + int decisionLevel () const; // Gives the current decisionlevel. + uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels. + CRef reason (Var x) const; + int level (Var x) const; + double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ... + bool withinBudget () const; + void relocAll (ClauseAllocator& to); + + // Static helpers: + // + + // Returns a random float 0 <= x < 1. Seed must never be 0. + static inline double drand(double& seed) { + seed *= 1389796; + int q = (int)(seed / 2147483647); + seed -= (double)q * 2147483647; + return seed / 2147483647; } + + // Returns a random integer 0 <= x < size. Seed must never be 0. + static inline int irand(double& seed, int size) { + return (int)(drand(seed) * size); } +}; + + +//================================================================================================= +// Implementation of inline methods: + +inline CRef Solver::reason(Var x) const { return vardata[x].reason; } +inline int Solver::level (Var x) const { return vardata[x].level; } + +inline void Solver::insertVarOrder(Var x) { + if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x); } + +inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); } +inline void Solver::varBumpActivity(Var v) { varBumpActivity(v, var_inc); } +inline void Solver::varBumpActivity(Var v, double inc) { + if ( (activity[v] += inc) > 1e100 ) { + // Rescale: + for (int i = 0; i < nVars(); i++) + activity[i] *= 1e-100; + var_inc *= 1e-100; } + + // Update order_heap with respect to new activity: + if (order_heap.inHeap(v)) + order_heap.decrease(v); } + +inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); } +inline void Solver::claBumpActivity (Clause& c) { + if ( (c.activity() += cla_inc) > 1e20 ) { + // Rescale: + for (int i = 0; i < learnts.size(); i++) + ca[learnts[i]].activity() *= 1e-20; + cla_inc *= 1e-20; } } + +inline void Solver::checkGarbage(void){ return checkGarbage(garbage_frac); } +inline void Solver::checkGarbage(double gf){ + if (ca.wasted() > ca.size() * gf) + garbageCollect(); } + +// NOTE: enqueue does not set the ok flag! (only public methods do) +inline bool Solver::enqueue (Lit p, CRef from) { return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true); } +inline bool Solver::addClause (const vec& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); } +inline bool Solver::addEmptyClause () { add_tmp.clear(); return addClause_(add_tmp); } +inline bool Solver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); } +inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); } +inline bool Solver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); } +inline bool Solver::addClause (Lit p, Lit q, Lit r, Lit s){ add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); add_tmp.push(s); return addClause_(add_tmp); } + +inline bool Solver::isRemoved (CRef cr) const { return ca[cr].mark() == 1; } +inline bool Solver::locked (const Clause& c) const { return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c; } +inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); } + +inline int Solver::decisionLevel () const { return trail_lim.size(); } +inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); } +inline lbool Solver::value (Var x) const { return assigns[x]; } +inline lbool Solver::value (Lit p) const { return assigns[var(p)] ^ sign(p); } +inline lbool Solver::modelValue (Var x) const { return model[x]; } +inline lbool Solver::modelValue (Lit p) const { return model[var(p)] ^ sign(p); } +inline int Solver::nAssigns () const { return trail.size(); } +inline int Solver::nClauses () const { return num_clauses; } +inline int Solver::nLearnts () const { return num_learnts; } +inline int Solver::nVars () const { return next_var; } +// TODO: nFreeVars() is not quite correct, try to calculate right instead of adapting it like below: +inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); } +inline void Solver::setPolarity (Var v, lbool b){ user_pol[v] = b; } +inline void Solver::setDecisionVar(Var v, bool b) +{ + if ( b && !decision[v]) dec_vars++; + else if (!b && decision[v]) dec_vars--; + + decision[v] = b; + insertVarOrder(v); +} +inline void Solver::setConfBudget(int64_t x){ conflict_budget = conflicts + x; } +inline void Solver::setPropBudget(int64_t x){ propagation_budget = propagations + x; } +inline void Solver::interrupt(){ asynch_interrupt = true; } +inline void Solver::clearInterrupt(){ asynch_interrupt = false; } +inline void Solver::budgetOff(){ conflict_budget = propagation_budget = -1; } +inline bool Solver::withinBudget() const { + return !asynch_interrupt && + (conflict_budget < 0 || conflicts < (uint64_t)conflict_budget) && + (propagation_budget < 0 || propagations < (uint64_t)propagation_budget); } + +// FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a +// pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or +// all calls to solve must return an 'lbool'. I'm not yet sure which I prefer. +inline bool Solver::solve () { budgetOff(); assumptions.clear(); return solve_() == l_True; } +inline bool Solver::solve (Lit p) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_() == l_True; } +inline bool Solver::solve (Lit p, Lit q) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_() == l_True; } +inline bool Solver::solve (Lit p, Lit q, Lit r) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_() == l_True; } +inline bool Solver::solve (const vec& assumps){ budgetOff(); assumps.copyTo(assumptions); return solve_() == l_True; } +inline lbool Solver::solveLimited (const vec& assumps){ assumps.copyTo(assumptions); return solve_(); } +inline bool Solver::okay () const { return ok; } + +inline ClauseIterator Solver::clausesBegin() const { return ClauseIterator(ca, &clauses[0]); } +inline ClauseIterator Solver::clausesEnd () const { return ClauseIterator(ca, &clauses[clauses.size()]); } +inline TrailIterator Solver::trailBegin () const { return TrailIterator(&trail[0]); } +inline TrailIterator Solver::trailEnd () const { + return TrailIterator(&trail[decisionLevel() == 0 ? trail.size() : trail_lim[0]]); } + +inline void Solver::toDimacs (const char* file){ vec as; toDimacs(file, as); } +inline void Solver::toDimacs (const char* file, Lit p){ vec as; as.push(p); toDimacs(file, as); } +inline void Solver::toDimacs (const char* file, Lit p, Lit q){ vec as; as.push(p); as.push(q); toDimacs(file, as); } +inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ vec as; as.push(p); as.push(q); as.push(r); toDimacs(file, as); } + + +//================================================================================================= +// Debug etc: + + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/SolverTypes.h b/libs/minisat/SolverTypes.h new file mode 100644 index 00000000..be40a4c3 --- /dev/null +++ b/libs/minisat/SolverTypes.h @@ -0,0 +1,478 @@ +/***********************************************************************************[SolverTypes.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + + +#ifndef Minisat_SolverTypes_h +#define Minisat_SolverTypes_h + +#include + +#include "libs/minisat/IntTypes.h" +#include "libs/minisat/Alg.h" +#include "libs/minisat/Vec.h" +#include "libs/minisat/IntMap.h" +#include "libs/minisat/Map.h" +#include "libs/minisat/Alloc.h" + +namespace Minisat { + +//================================================================================================= +// Variables, literals, lifted booleans, clauses: + + +// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N, +// so that they can be used as array indices. + +typedef int Var; +#if defined(MINISAT_CONSTANTS_AS_MACROS) +#define var_Undef (-1) +#else + const Var var_Undef = -1; +#endif + + +struct Lit { + int x; + + // Use this as a constructor: + friend Lit mkLit(Var var, bool sign = false); + + bool operator == (Lit p) const { return x == p.x; } + bool operator != (Lit p) const { return x != p.x; } + bool operator < (Lit p) const { return x < p.x; } // '<' makes p, ~p adjacent in the ordering. +}; + + +inline Lit mkLit (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; } +inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; } +inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; } +inline bool sign (Lit p) { return p.x & 1; } +inline int var (Lit p) { return p.x >> 1; } + +// Mapping Literals to and from compact integers suitable for array indexing: +inline int toInt (Var v) { return v; } +inline int toInt (Lit p) { return p.x; } +inline Lit toLit (int i) { Lit p; p.x = i; return p; } + +//const Lit lit_Undef = mkLit(var_Undef, false); // }- Useful special constants. +//const Lit lit_Error = mkLit(var_Undef, true ); // } + +const Lit lit_Undef = { -2 }; // }- Useful special constants. +const Lit lit_Error = { -1 }; // } + +struct MkIndexLit { vec::Size operator()(Lit l) const { return vec::Size(l.x); } }; + +template class VMap : public IntMap{}; +template class LMap : public IntMap{}; +class LSet : public IntSet{}; + +//================================================================================================= +// Lifted booleans: +// +// NOTE: this implementation is optimized for the case when comparisons between values are mostly +// between one variable and one constant. Some care had to be taken to make sure that gcc +// does enough constant propagation to produce sensible code, and this appears to be somewhat +// fragile unfortunately. + +class lbool { + uint8_t value; + +public: + explicit lbool(uint8_t v) : value(v) { } + + lbool() : value(0) { } + explicit lbool(bool x) : value(!x) { } + + bool operator == (lbool b) const { return ((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value)); } + bool operator != (lbool b) const { return !(*this == b); } + lbool operator ^ (bool b) const { return lbool((uint8_t)(value^(uint8_t)b)); } + + lbool operator && (lbool b) const { + uint8_t sel = (this->value << 1) | (b.value << 3); + uint8_t v = (0xF7F755F4 >> sel) & 3; + return lbool(v); } + + lbool operator || (lbool b) const { + uint8_t sel = (this->value << 1) | (b.value << 3); + uint8_t v = (0xFCFCF400 >> sel) & 3; + return lbool(v); } + + friend int toInt (lbool l); + friend lbool toLbool(int v); +}; +inline int toInt (lbool l) { return l.value; } +inline lbool toLbool(int v) { return lbool((uint8_t)v); } + +#if defined(MINISAT_CONSTANTS_AS_MACROS) + #define l_True (lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants. + #define l_False (lbool((uint8_t)1)) + #define l_Undef (lbool((uint8_t)2)) +#else + const lbool l_True ((uint8_t)0); + const lbool l_False((uint8_t)1); + const lbool l_Undef((uint8_t)2); +#endif + + +//================================================================================================= +// Clause -- a simple class for representing a clause: + +class Clause; +typedef RegionAllocator::Ref CRef; + +class Clause { + struct { + unsigned mark : 2; + unsigned learnt : 1; + unsigned has_extra : 1; + unsigned reloced : 1; + unsigned size : 27; } header; + union { Lit lit; float act; uint32_t abs; CRef rel; } data[0]; + + friend class ClauseAllocator; + + // NOTE: This constructor cannot be used directly (doesn't allocate enough memory). + Clause(const vec& ps, bool use_extra, bool learnt) { + header.mark = 0; + header.learnt = learnt; + header.has_extra = use_extra; + header.reloced = 0; + header.size = ps.size(); + + for (int i = 0; i < ps.size(); i++) + data[i].lit = ps[i]; + + if (header.has_extra){ + if (header.learnt) + data[header.size].act = 0; + else + calcAbstraction(); + } + } + + // NOTE: This constructor cannot be used directly (doesn't allocate enough memory). + Clause(const Clause& from, bool use_extra){ + header = from.header; + header.has_extra = use_extra; // NOTE: the copied clause may lose the extra field. + + for (int i = 0; i < from.size(); i++) + data[i].lit = from[i]; + + if (header.has_extra){ + if (header.learnt) + data[header.size].act = from.data[header.size].act; + else + data[header.size].abs = from.data[header.size].abs; + } + } + +public: + void calcAbstraction() { + assert(header.has_extra); + uint32_t abstraction = 0; + for (int i = 0; i < size(); i++) + abstraction |= 1 << (var(data[i].lit) & 31); + data[header.size].abs = abstraction; } + + + int size () const { return header.size; } + void shrink (int i) { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; } + void pop () { shrink(1); } + bool learnt () const { return header.learnt; } + bool has_extra () const { return header.has_extra; } + uint32_t mark () const { return header.mark; } + void mark (uint32_t m) { header.mark = m; } + const Lit& last () const { return data[header.size-1].lit; } + + bool reloced () const { return header.reloced; } + CRef relocation () const { return data[0].rel; } + void relocate (CRef c) { header.reloced = 1; data[0].rel = c; } + + // NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for + // subsumption operations to behave correctly. + Lit& operator [] (int i) { return data[i].lit; } + Lit operator [] (int i) const { return data[i].lit; } + operator const Lit* (void) const { return (Lit*)data; } + + float& activity () { assert(header.has_extra); return data[header.size].act; } + uint32_t abstraction () const { assert(header.has_extra); return data[header.size].abs; } + + Lit subsumes (const Clause& other) const; + void strengthen (Lit p); +}; + + +//================================================================================================= +// ClauseAllocator -- a simple class for allocating memory for clauses: + +const CRef CRef_Undef = RegionAllocator::Ref_Undef; +class ClauseAllocator +{ + RegionAllocator ra; + + static uint32_t clauseWord32Size(int size, bool has_extra){ + return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); } + + public: + enum { Unit_Size = RegionAllocator::Unit_Size }; + + bool extra_clause_field; + + ClauseAllocator(uint32_t start_cap) : ra(start_cap), extra_clause_field(false){} + ClauseAllocator() : extra_clause_field(false){} + + void moveTo(ClauseAllocator& to){ + to.extra_clause_field = extra_clause_field; + ra.moveTo(to.ra); } + + CRef alloc(const vec& ps, bool learnt = false) + { + assert(sizeof(Lit) == sizeof(uint32_t)); + assert(sizeof(float) == sizeof(uint32_t)); + bool use_extra = learnt | extra_clause_field; + CRef cid = ra.alloc(clauseWord32Size(ps.size(), use_extra)); + new (lea(cid)) Clause(ps, use_extra, learnt); + + return cid; + } + + CRef alloc(const Clause& from) + { + bool use_extra = from.learnt() | extra_clause_field; + CRef cid = ra.alloc(clauseWord32Size(from.size(), use_extra)); + new (lea(cid)) Clause(from, use_extra); + return cid; } + + uint32_t size () const { return ra.size(); } + uint32_t wasted () const { return ra.wasted(); } + + // Deref, Load Effective Address (LEA), Inverse of LEA (AEL): + Clause& operator[](CRef r) { return (Clause&)ra[r]; } + const Clause& operator[](CRef r) const { return (Clause&)ra[r]; } + Clause* lea (CRef r) { return (Clause*)ra.lea(r); } + const Clause* lea (CRef r) const { return (Clause*)ra.lea(r);; } + CRef ael (const Clause* t){ return ra.ael((uint32_t*)t); } + + void free(CRef cid) + { + Clause& c = operator[](cid); + ra.free(clauseWord32Size(c.size(), c.has_extra())); + } + + void reloc(CRef& cr, ClauseAllocator& to) + { + Clause& c = operator[](cr); + + if (c.reloced()) { cr = c.relocation(); return; } + + cr = to.alloc(c); + c.relocate(cr); + } +}; + +//================================================================================================= +// Simple iterator classes (for iterating over clauses and top-level assignments): + +class ClauseIterator { + const ClauseAllocator& ca; + const CRef* crefs; +public: + ClauseIterator(const ClauseAllocator& _ca, const CRef* _crefs) : ca(_ca), crefs(_crefs){} + + void operator++(){ crefs++; } + const Clause& operator*() const { return ca[*crefs]; } + + // NOTE: does not compare that references use the same clause-allocator: + bool operator==(const ClauseIterator& ci) const { return crefs == ci.crefs; } + bool operator!=(const ClauseIterator& ci) const { return crefs != ci.crefs; } +}; + + +class TrailIterator { + const Lit* lits; +public: + TrailIterator(const Lit* _lits) : lits(_lits){} + + void operator++() { lits++; } + Lit operator*() const { return *lits; } + + bool operator==(const TrailIterator& ti) const { return lits == ti.lits; } + bool operator!=(const TrailIterator& ti) const { return lits != ti.lits; } +}; + + +//================================================================================================= +// OccLists -- a class for maintaining occurence lists with lazy deletion: + +template > +class OccLists +{ + IntMap occs; + IntMap dirty; + vec dirties; + Deleted deleted; + + public: + OccLists(const Deleted& d, MkIndex _index = MkIndex()) : + occs(_index), + dirty(_index), + deleted(d){} + + void init (const K& idx){ occs.reserve(idx); occs[idx].clear(); dirty.reserve(idx, 0); } + Vec& operator[](const K& idx){ return occs[idx]; } + Vec& lookup (const K& idx){ if (dirty[idx]) clean(idx); return occs[idx]; } + + void cleanAll (); + void clean (const K& idx); + void smudge (const K& idx){ + if (dirty[idx] == 0){ + dirty[idx] = 1; + dirties.push(idx); + } + } + + void clear(bool free = true){ + occs .clear(free); + dirty .clear(free); + dirties.clear(free); + } +}; + + +template +void OccLists::cleanAll() +{ + for (int i = 0; i < dirties.size(); i++) + // Dirties may contain duplicates so check here if a variable is already cleaned: + if (dirty[dirties[i]]) + clean(dirties[i]); + dirties.clear(); +} + + +template +void OccLists::clean(const K& idx) +{ + Vec& vec = occs[idx]; + int i, j; + for (i = j = 0; i < vec.size(); i++) + if (!deleted(vec[i])) + vec[j++] = vec[i]; + vec.shrink(i - j); + dirty[idx] = 0; +} + + +//================================================================================================= +// CMap -- a class for mapping clauses to values: + + +template +class CMap +{ + struct CRefHash { + uint32_t operator()(CRef cr) const { return (uint32_t)cr; } }; + + typedef Map HashTable; + HashTable map; + + public: + // Size-operations: + void clear () { map.clear(); } + int size () const { return map.elems(); } + + + // Insert/Remove/Test mapping: + void insert (CRef cr, const T& t){ map.insert(cr, t); } + void growTo (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility + void remove (CRef cr) { map.remove(cr); } + bool has (CRef cr, T& t) { return map.peek(cr, t); } + + // Vector interface (the clause 'c' must already exist): + const T& operator [] (CRef cr) const { return map[cr]; } + T& operator [] (CRef cr) { return map[cr]; } + + // Iteration (not transparent at all at the moment): + int bucket_count() const { return map.bucket_count(); } + const vec& bucket(int i) const { return map.bucket(i); } + + // Move contents to other map: + void moveTo(CMap& other){ map.moveTo(other.map); } + + // TMP debug: + void debug(){ + printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); } +}; + + +/*_________________________________________________________________________________________________ +| +| subsumes : (other : const Clause&) -> Lit +| +| Description: +| Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other' +| by subsumption resolution. +| +| Result: +| lit_Error - No subsumption or simplification +| lit_Undef - Clause subsumes 'other' +| p - The literal p can be deleted from 'other' +|________________________________________________________________________________________________@*/ +inline Lit Clause::subsumes(const Clause& other) const +{ + //if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0) + //if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0)) + assert(!header.learnt); assert(!other.header.learnt); + assert(header.has_extra); assert(other.header.has_extra); + if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0) + return lit_Error; + + Lit ret = lit_Undef; + const Lit* c = (const Lit*)(*this); + const Lit* d = (const Lit*)other; + + for (unsigned i = 0; i < header.size; i++) { + // search for c[i] or ~c[i] + for (unsigned j = 0; j < other.header.size; j++) + if (c[i] == d[j]) + goto ok; + else if (ret == lit_Undef && c[i] == ~d[j]){ + ret = c[i]; + goto ok; + } + + // did not find it + return lit_Error; + ok:; + } + + return ret; +} + +inline void Clause::strengthen(Lit p) +{ + remove(*this, p); + calcAbstraction(); +} + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/Sort.h b/libs/minisat/Sort.h new file mode 100644 index 00000000..4a25a9b4 --- /dev/null +++ b/libs/minisat/Sort.h @@ -0,0 +1,98 @@ +/******************************************************************************************[Sort.h] +Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Sort_h +#define Minisat_Sort_h + +#include "libs/minisat/Vec.h" + +//================================================================================================= +// Some sorting algorithms for vec's + + +namespace Minisat { + +template +struct LessThan_default { + bool operator () (T x, T y) { return x < y; } +}; + + +template +void selectionSort(T* array, int size, LessThan lt) +{ + int i, j, best_i; + T tmp; + + for (i = 0; i < size-1; i++){ + best_i = i; + for (j = i+1; j < size; j++){ + if (lt(array[j], array[best_i])) + best_i = j; + } + tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp; + } +} +template static inline void selectionSort(T* array, int size) { + selectionSort(array, size, LessThan_default()); } + +template +void sort(T* array, int size, LessThan lt) +{ + if (size <= 15) + selectionSort(array, size, lt); + + else{ + T pivot = array[size / 2]; + T tmp; + int i = -1; + int j = size; + + for(;;){ + do i++; while(lt(array[i], pivot)); + do j--; while(lt(pivot, array[j])); + + if (i >= j) break; + + tmp = array[i]; array[i] = array[j]; array[j] = tmp; + } + + sort(array , i , lt); + sort(&array[i], size-i, lt); + } +} +template static inline void sort(T* array, int size) { + sort(array, size, LessThan_default()); } + + +//================================================================================================= +// For 'vec's: + + +template void sort(vec& v, LessThan lt) { + sort((T*)v, v.size(), lt); } +template void sort(vec& v) { + sort(v, LessThan_default()); } + + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/System.cc b/libs/minisat/System.cc new file mode 100644 index 00000000..01d0dfe1 --- /dev/null +++ b/libs/minisat/System.cc @@ -0,0 +1,171 @@ +#define __STDC_FORMAT_MACROS +#define __STDC_LIMIT_MACROS +/***************************************************************************************[System.cc] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#include +#include + +#include "libs/minisat/System.h" + +#if defined(__linux__) + +#include + +using namespace Minisat; + +static inline int memReadStat(int field) +{ + char name[256]; + pid_t pid = getpid(); + int value; + + sprintf(name, "/proc/%d/statm", pid); + FILE* in = fopen(name, "rb"); + if (in == NULL) return 0; + + for (; field >= 0; field--) + if (fscanf(in, "%d", &value) != 1) + printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1); + fclose(in); + return value; +} + + +static inline int memReadPeak(void) +{ + char name[256]; + pid_t pid = getpid(); + + sprintf(name, "/proc/%d/status", pid); + FILE* in = fopen(name, "rb"); + if (in == NULL) return 0; + + // Find the correct line, beginning with "VmPeak:": + int peak_kb = 0; + while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1) + while (!feof(in) && fgetc(in) != '\n') + ; + fclose(in); + + return peak_kb; +} + +double Minisat::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); } +double Minisat::memUsedPeak(bool strictlyPeak) { + double peak = memReadPeak() / (double)1024; + return peak == 0 && !strictlyPeak ? memUsed() : peak; } + +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__gnu_hurd__) + +double Minisat::memUsed() { + struct rusage ru; + getrusage(RUSAGE_SELF, &ru); + return (double)ru.ru_maxrss / 1024; } +double Minisat::memUsedPeak() { return memUsed(); } + + +#elif defined(__APPLE__) +#include + +double Minisat::memUsed() { + malloc_statistics_t t; + malloc_zone_statistics(NULL, &t); + return (double)t.max_size_in_use / (1024*1024); } +double Minisat::memUsedPeak() { return memUsed(); } + +#else +double Minisat::memUsed() { return 0; } +double Minisat::memUsedPeak() { return 0; } +#endif + + +void Minisat::setX86FPUPrecision() +{ +#if defined(__linux__) && defined(_FPU_EXTENDED) && defined(_FPU_DOUBLE) && defined(_FPU_GETCW) + // Only correct FPU precision on Linux architectures that needs and supports it: + fpu_control_t oldcw, newcw; + _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw); + printf("WARNING: for repeatability, setting FPU to use double precision\n"); +#endif +} + + +#if !defined(_MSC_VER) && !defined(__MINGW32__) +void Minisat::limitMemory(uint64_t max_mem_mb) +{ +// FIXME: OpenBSD does not support RLIMIT_AS. Not sure how well RLIMIT_DATA works instead. +#if defined(__OpenBSD__) +#define RLIMIT_AS RLIMIT_DATA +#endif + + // Set limit on virtual memory: + if (max_mem_mb != 0){ + rlim_t new_mem_lim = (rlim_t)max_mem_mb * 1024*1024; + rlimit rl; + getrlimit(RLIMIT_AS, &rl); + if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){ + rl.rlim_cur = new_mem_lim; + if (setrlimit(RLIMIT_AS, &rl) == -1) + printf("WARNING! Could not set resource limit: Virtual memory.\n"); + } + } + +#if defined(__OpenBSD__) +#undef RLIMIT_AS +#endif +} +#else +void Minisat::limitMemory(uint64_t /*max_mem_mb*/) +{ + printf("WARNING! Memory limit not supported on this architecture.\n"); +} +#endif + + +#if !defined(_MSC_VER) && !defined(__MINGW32__) +void Minisat::limitTime(uint32_t max_cpu_time) +{ + if (max_cpu_time != 0){ + rlimit rl; + getrlimit(RLIMIT_CPU, &rl); + if (rl.rlim_max == RLIM_INFINITY || (rlim_t)max_cpu_time < rl.rlim_max){ + rl.rlim_cur = max_cpu_time; + if (setrlimit(RLIMIT_CPU, &rl) == -1) + printf("WARNING! Could not set resource limit: CPU-time.\n"); + } + } +} +#else +void Minisat::limitTime(uint32_t /*max_cpu_time*/) +{ + printf("WARNING! CPU-time limit not supported on this architecture.\n"); +} +#endif + + +void Minisat::sigTerm(void handler(int)) +{ + signal(SIGINT, handler); + signal(SIGTERM,handler); +#ifdef SIGXCPU + signal(SIGXCPU,handler); +#endif +} diff --git a/libs/minisat/System.h b/libs/minisat/System.h new file mode 100644 index 00000000..eb8a7e4d --- /dev/null +++ b/libs/minisat/System.h @@ -0,0 +1,72 @@ +/****************************************************************************************[System.h] +Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_System_h +#define Minisat_System_h + +#if defined(__linux__) +#include +#endif + +#include "libs/minisat/IntTypes.h" + +//------------------------------------------------------------------------------------------------- + +namespace Minisat { + +static inline double cpuTime(void); // CPU-time in seconds. + +extern double memUsed(); // Memory in mega bytes (returns 0 for unsupported architectures). +extern double memUsedPeak(bool strictlyPeak = false); // Peak-memory in mega bytes (returns 0 for unsupported architectures). + +extern void setX86FPUPrecision(); // Make sure double's are represented with the same precision + // in memory and registers. + +extern void limitMemory(uint64_t max_mem_mb); // Set a limit on total memory usage. The exact + // semantics varies depending on architecture. + +extern void limitTime(uint32_t max_cpu_time); // Set a limit on maximum CPU time. The exact + // semantics varies depending on architecture. + +extern void sigTerm(void handler(int)); // Set up handling of available termination signals. + +} + +//------------------------------------------------------------------------------------------------- +// Implementation of inline functions: + +#if defined(_MSC_VER) || defined(__MINGW32__) +#include + +static inline double Minisat::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; } + +#else +#include +#include +#include + +static inline double Minisat::cpuTime(void) { + struct rusage ru; + getrusage(RUSAGE_SELF, &ru); + return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; } + +#endif + +#endif diff --git a/libs/minisat/UPDATE.sh b/libs/minisat/UPDATE.sh new file mode 100644 index 00000000..88fcf759 --- /dev/null +++ b/libs/minisat/UPDATE.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +rm -fv LICENSE *.cc *.h +git clone --depth 1 https://github.com/niklasso/minisat minisat_upstream +rm minisat_upstream/minisat/*/Main.cc +mv minisat_upstream/LICENSE minisat_upstream/minisat/*/*.{h,cc} . +rm -rf minisat_upstream + +sed -i -e 's,^#include *"minisat/[^/]\+,#include "libs/minisat,' *.cc *.h +sed -i -e 's/PRIi64/ & /' Options.h +sed -i -e '1 i #define __STDC_LIMIT_MACROS' *.cc +sed -i -e '1 i #define __STDC_FORMAT_MACROS' *.cc diff --git a/libs/minisat/Vec.h b/libs/minisat/Vec.h new file mode 100644 index 00000000..2086e0bb --- /dev/null +++ b/libs/minisat/Vec.h @@ -0,0 +1,134 @@ +/*******************************************************************************************[Vec.h] +Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson +Copyright (c) 2007-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_Vec_h +#define Minisat_Vec_h + +#include +#include +#include + +#include "libs/minisat/IntTypes.h" +#include "libs/minisat/XAlloc.h" + +namespace Minisat { + +//================================================================================================= +// Automatically resizable arrays +// +// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc) + +template +class vec { +public: + typedef _Size Size; +private: + T* data; + Size sz; + Size cap; + + // Don't allow copying (error prone): + vec& operator=(vec& other); + vec (vec& other); + + static inline Size max(Size x, Size y){ return (x > y) ? x : y; } + +public: + // Constructors: + vec() : data(NULL), sz(0), cap(0) { } + explicit vec(Size size) : data(NULL), sz(0), cap(0) { growTo(size); } + vec(Size size, const T& pad) : data(NULL), sz(0), cap(0) { growTo(size, pad); } + ~vec() { clear(true); } + + // Pointer to first element: + operator T* (void) { return data; } + + // Size operations: + Size size (void) const { return sz; } + void shrink (Size nelems) { assert(nelems <= sz); for (Size i = 0; i < nelems; i++) sz--, data[sz].~T(); } + void shrink_ (Size nelems) { assert(nelems <= sz); sz -= nelems; } + int capacity (void) const { return cap; } + void capacity (Size min_cap); + void growTo (Size size); + void growTo (Size size, const T& pad); + void clear (bool dealloc = false); + + // Stack interface: + void push (void) { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; } + //void push (const T& elem) { if (sz == cap) capacity(sz+1); data[sz++] = elem; } + void push (const T& elem) { if (sz == cap) capacity(sz+1); new (&data[sz++]) T(elem); } + void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; } + void pop (void) { assert(sz > 0); sz--, data[sz].~T(); } + // NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but + // in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not + // happen given the way capacities are calculated (below). Essentially, all capacities are + // even, but INT_MAX is odd. + + const T& last (void) const { return data[sz-1]; } + T& last (void) { return data[sz-1]; } + + // Vector interface: + const T& operator [] (Size index) const { return data[index]; } + T& operator [] (Size index) { return data[index]; } + + // Duplicatation (preferred instead): + void copyTo(vec& copy) const { copy.clear(); copy.growTo(sz); for (Size i = 0; i < sz; i++) copy[i] = data[i]; } + void moveTo(vec& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; } +}; + + +template +void vec::capacity(Size min_cap) { + if (cap >= min_cap) return; + Size add = max((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2 + const Size size_max = std::numeric_limits::max(); + if ( ((size_max <= std::numeric_limits::max()) && (add > size_max - cap)) + || (((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM) ) + throw OutOfMemoryException(); + } + + +template +void vec::growTo(Size size, const T& pad) { + if (sz >= size) return; + capacity(size); + for (Size i = sz; i < size; i++) data[i] = pad; + sz = size; } + + +template +void vec::growTo(Size size) { + if (sz >= size) return; + capacity(size); + for (Size i = sz; i < size; i++) new (&data[i]) T(); + sz = size; } + + +template +void vec::clear(bool dealloc) { + if (data != NULL){ + for (Size i = 0; i < sz; i++) data[i].~T(); + sz = 0; + if (dealloc) free(data), data = NULL, cap = 0; } } + +//================================================================================================= +} + +#endif diff --git a/libs/minisat/XAlloc.h b/libs/minisat/XAlloc.h new file mode 100644 index 00000000..1da17602 --- /dev/null +++ b/libs/minisat/XAlloc.h @@ -0,0 +1,45 @@ +/****************************************************************************************[XAlloc.h] +Copyright (c) 2009-2010, Niklas Sorensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + + +#ifndef Minisat_XAlloc_h +#define Minisat_XAlloc_h + +#include +#include + +namespace Minisat { + +//================================================================================================= +// Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing: + +class OutOfMemoryException{}; +static inline void* xrealloc(void *ptr, size_t size) +{ + void* mem = realloc(ptr, size); + if (mem == NULL && errno == ENOMEM){ + throw OutOfMemoryException(); + }else + return mem; +} + +//================================================================================================= +} + +#endif From 31528634796c15d0dcdb113ff730fa743663ca07 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Mar 2014 10:46:27 +0100 Subject: [PATCH 141/750] Fixed dependencies of "make test" --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0acc0d0e..73051e52 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,7 @@ endif yosys-abc: abc/abc-$(ABCREV) cp abc/abc-$(ABCREV) yosys-abc -test: yosys +test: $(TARGETS) $(EXTRA_TARGETS) cd tests/simple && bash run-test.sh cd tests/hana && bash run-test.sh cd tests/asicworld && bash run-test.sh From 8f3fa094817ec2c7df4253c690b5ccdb50a5b7d8 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 19:39:01 +0100 Subject: [PATCH 142/750] - Makefile: resolve merge conflict. --- Makefile | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 73051e52..8da8b4c5 100644 --- a/Makefile +++ b/Makefile @@ -22,11 +22,22 @@ TARGETS = yosys yosys-config all: top-all -CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -LDFLAGS = -rdynamic -LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt -QMAKE = qmake-qt4 -SED = sed +CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h +LDFLAGS = -I${DESTDIR}/lib +LDLIBS = -lstdc++ -lreadline -lm -ldl + +ifeq (Darwin,$(findstring Darwin,$(shell uname))) + # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + CXXFLAGS += -I/opt/local/include + LDFLAGS += -L/opt/local/lib + QMAKE = qmake + SED = gsed +else + LDFLAGS += -rdynamic + LDLIBS += -lrt + QMAKE = qmake-qt4 + SED = sed +endif YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) @@ -123,6 +134,13 @@ yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make cp libs/svgviewer/svgviewer yosys-svgviewer +yosys-minisat: $(DESTDIR)/bin/minisat +$(DESTDIR)/bin/minisat: + test -d minisat || ( git clone https://github.com/niklasso/minisat.git minisat && $(SED) -i -e 's/PRIi64/ & /' minisat/minisat/utils/Options.h ) + ( cd minisat && git checkout $(MINISATREV) ) + ( cd minisat && $(MAKE) prefix=$(DESTDIR) DESTDIR="" config install ) + @( cd minisat && echo "Installed minisat version `git describe --always --dirty` into $(DESTDIR)." ) + abc/abc-$(ABCREV): ifneq ($(ABCREV),default) if ( cd abc && hg identify; ) | grep -q +; then \ From 94bc11f0216010e54a8a4dd1fd390af97181f627 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: [PATCH 143/750] - Makefile: export PATH=${DESTDIR}/bin:$(PATH) and (DY)LD_LIBRARY_PATH, to make sure our local copies of built executables and libraries are used. - Makefile: use find expression in target 'yosys-svgviewer' to find svgviewer binary (qmake will build into .app package on OSX). - Makefile: make 'test' target dependent on $(TARGETS) and $(EXTRA_TARGETS) to make sure that minisat is built. --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8da8b4c5..1bafd217 100644 --- a/Makefile +++ b/Makefile @@ -26,13 +26,17 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -I${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl +export PATH := ${DESTDIR}/bin:$(PATH) + ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else + export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 @@ -132,7 +136,7 @@ yosys-config: yosys-config.in yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make - cp libs/svgviewer/svgviewer yosys-svgviewer + cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer yosys-minisat: $(DESTDIR)/bin/minisat $(DESTDIR)/bin/minisat: From 51bf1c871e89167228c406649201e608fd618d5c Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: [PATCH 144/750] - Makefile: fix typo in LDFLAGS: obviously -L, not -I is required here --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1bafd217..39b324b4 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ TARGETS = yosys yosys-config all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h -LDFLAGS = -I${DESTDIR}/lib +LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl export PATH := ${DESTDIR}/bin:$(PATH) From cfabaa16895d85ce21b0a1bf020f5ac1108cc614 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: [PATCH 145/750] - Makefile: include $(PWD) in PATH, since 'make test' can happen before 'make install'. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 39b324b4..9460e341 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := ${DESTDIR}/bin:$(PATH) +export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': From 948d04c06c181a1c270017b6d7c819426a360303 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:12:52 +0100 Subject: [PATCH 146/750] - libs/minisat/System.cc: fix definition/declaration mismatch for Minisat::memUsedPeak() and mark unused parameters as unused to fix compiler error+warning. (minisat bug tracker issues #1, #9, #10.) --- libs/minisat/System.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/minisat/System.cc b/libs/minisat/System.cc index 01d0dfe1..59e65fb5 100644 --- a/libs/minisat/System.cc +++ b/libs/minisat/System.cc @@ -79,7 +79,7 @@ double Minisat::memUsed() { struct rusage ru; getrusage(RUSAGE_SELF, &ru); return (double)ru.ru_maxrss / 1024; } -double Minisat::memUsedPeak() { return memUsed(); } +double Minisat::memUsedPeak(bool strictlyPeak) { (void) strictlyPeak; return memUsed(); } #elif defined(__APPLE__) @@ -89,11 +89,11 @@ double Minisat::memUsed() { malloc_statistics_t t; malloc_zone_statistics(NULL, &t); return (double)t.max_size_in_use / (1024*1024); } -double Minisat::memUsedPeak() { return memUsed(); } +double Minisat::memUsedPeak(bool strictlyPeak) { (void) strictlyPeak; return memUsed(); } #else double Minisat::memUsed() { return 0; } -double Minisat::memUsedPeak() { return 0; } +double Minisat::memUsedPeak(bool strictlyPeak) { (void) strictlyPeak; return 0; } #endif From 18367919ea64a0881da7cf439c99365a8807d3a3 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:15:53 +0100 Subject: [PATCH 147/750] - libs/minisat/Solver.cc: insert spaces between string and PRIu64 literal, otherwise c++11-compliant compilers will bail out due to user-defined literals (minisat bug tracker #13). --- libs/minisat/Solver.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/minisat/Solver.cc b/libs/minisat/Solver.cc index ebca294a..14aa3935 100644 --- a/libs/minisat/Solver.cc +++ b/libs/minisat/Solver.cc @@ -994,11 +994,11 @@ void Solver::printStats() const { double cpu_time = cpuTime(); double mem_used = memUsedPeak(); - printf("restarts : %"PRIu64"\n", starts); - printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", conflicts , conflicts /cpu_time); - printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", decisions, (float)rnd_decisions*100 / (float)decisions, decisions /cpu_time); - printf("propagations : %-12"PRIu64" (%.0f /sec)\n", propagations, propagations/cpu_time); - printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", tot_literals, (max_literals - tot_literals)*100 / (double)max_literals); + printf("restarts : %" PRIu64 "\n", starts); + printf("conflicts : %-12" PRIu64 " (%.0f /sec)\n", conflicts , conflicts /cpu_time); + printf("decisions : %-12" PRIu64 " (%4.2f %% random) (%.0f /sec)\n", decisions, (float)rnd_decisions*100 / (float)decisions, decisions /cpu_time); + printf("propagations : %-12" PRIu64 " (%.0f /sec)\n", propagations, propagations/cpu_time); + printf("conflict literals : %-12" PRIu64 " (%4.2f %% deleted)\n", tot_literals, (max_literals - tot_literals)*100 / (double)max_literals); if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used); printf("CPU time : %g s\n", cpu_time); } From a8efb61e1f5221bdb013d90e83530392f61c13f8 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:16:55 +0100 Subject: [PATCH 148/750] - Makefile: follow changes in https://github.com/cliffordwolf/yosys --- Makefile | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 6950fcba..7bbc258d 100644 --- a/Makefile +++ b/Makefile @@ -56,8 +56,6 @@ OBJS = kernel/version_$(GIT_REV).o ABCREV = 2058c8ccea68 ABCPULL = 1 -MINISATREV = HEAD - -include Makefile.conf ifeq ($(CONFIG),clang-debug) @@ -87,8 +85,8 @@ CXXFLAGS += -pg -fno-inline LDFLAGS += -pg endif -ifeq ($(ENABLE_MINISAT),1) -TARGETS += yosys-minisat +ifeq ($(ENABLE_QT4),1) +TARGETS += yosys-svgviewer endif ifeq ($(ENABLE_ABC),1) @@ -102,13 +100,9 @@ CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -D'VERIFIC_DI LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif -# Build yosys after minisat and abc (we need to access the local copies of the downloaded/installed header files). +# Build yosys after abc (we need to access the the downloaded/installed header files and libraries when building yosys). TARGETS += yosys yosys-config -ifeq ($(ENABLE_QT4),1) -TARGETS += yosys-svgviewer -endif - OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/posix_compatibility.o OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o @@ -147,13 +141,6 @@ yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer -yosys-minisat: $(DESTDIR)/bin/minisat -$(DESTDIR)/bin/minisat: - test -d minisat || ( git clone https://github.com/niklasso/minisat.git minisat && $(SED) -i -e 's/PRIi64/ & /' minisat/minisat/utils/Options.h ) - ( cd minisat && git checkout $(MINISATREV) ) - ( cd minisat && $(MAKE) prefix=$(DESTDIR) DESTDIR="" config install ) - @( cd minisat && echo "Installed minisat version `git describe --always --dirty` into $(DESTDIR)." ) - abc/abc-$(ABCREV): ifneq ($(ABCREV),default) if ( cd abc && hg identify; ) | grep -q +; then \ From aead1b75e81b98332583ec859aa02c9757cc359f Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:18:07 +0100 Subject: [PATCH 149/750] - .gitignore: ignore qmake/OSX package libs/svgviewer/svgviewer.app --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 77d6e29e..10491a3a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /qtcreator.config /qtcreator.creator /qtcreator.creator.user +/libs/svgviewer/svgviewer.app /Makefile.conf /minisat /abc From 50423e3935095e535aa42aa17c80f0d178730e93 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:42:26 +0100 Subject: [PATCH 150/750] - Makefile: don't export DYLD_LIBRARY_PATH/LD_LIBRARY_PATH: not needed if we link minisat objects instead of library --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 7bbc258d..f7b466fd 100644 --- a/Makefile +++ b/Makefile @@ -30,13 +30,11 @@ export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': - export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else - export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 From 5a50760e2c327ded7a4da223fb16591febcb773f Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: [PATCH 151/750] - kernel/register.h, kernel/driver.cc: refactor rewrite_yosys_exe()/get_share_file_name() to portable proc_self_dirname()/proc_share_dirname(). This refactoring improves robustness and allows OSX support with only 7 new lines of code, and easy extension for other systems. - passes/abc/abc.cc, passes/cmds/show.cc, passes/techmap/techmap.cc: use new, refactored semantics. - Makefile: no need to add $(PWD) to $(PATH) anymore. --- Makefile | 2 -- kernel/driver.cc | 69 +++++++++++++++++++++------------------ kernel/register.h | 4 +-- passes/abc/abc.cc | 2 +- passes/cmds/show.cc | 3 +- passes/techmap/techmap.cc | 3 +- 6 files changed, 44 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index f7b466fd..b7bf4485 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,6 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) - ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': CXXFLAGS += -I/opt/local/include diff --git a/kernel/driver.cc b/kernel/driver.cc index ce95cad4..da4962b8 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -427,42 +428,46 @@ extern RTLIL::Design *yosys_get_design() return yosys_design; } -std::string rewrite_yosys_exe(std::string exe) +#if defined(__linux__) +std::string proc_self_dirname () { - char buffer[1024]; - ssize_t buflen = readlink("/proc/self/exe", buffer, sizeof(buffer)-1); - - if (buflen < 0) - return exe; - - buffer[buflen] = 0; - std::string newexe = stringf("%s/%s", dirname(buffer), exe.c_str()); - if (access(newexe.c_str(), X_OK) == 0) - return newexe; - - return exe; + char path [PATH_MAX]; + ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); + if (buflen < 0) { + log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); + log_abort(); + } + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); } - -std::string get_share_file_name(std::string file) +#elif defined(__APPLE__) +#include +std::string proc_self_dirname () { - char buffer[1024]; - ssize_t buflen = readlink("/proc/self/exe", buffer, sizeof(buffer)-1); + char * path = NULL; + uint32_t buflen = 0; + while (_NSGetExecutablePath(path, &buflen) != 0) + path = (char *) realloc((void *) path, buflen); + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#else + #error Dont know how to determine process executable base path! +#endif - if (buflen < 0) - log_error("Can't find file `%s': reading of /proc/self/exe failed!\n", file.c_str()); - - buffer[buflen] = 0; - const char *dir = dirname(buffer); - - std::string newfile_inplace = stringf("%s/share/%s", dir, file.c_str()); - if (access(newfile_inplace.c_str(), F_OK) == 0) - return newfile_inplace; - - std::string newfile_system = stringf("%s/../share/yosys/%s", dir, file.c_str()); - if (access(newfile_system.c_str(), F_OK) == 0) - return newfile_system; - - log_error("Can't find file `%s': no `%s' and no `%s' found!\n", file.c_str(), newfile_inplace.c_str(), newfile_system.c_str()); +std::string proc_share_dirname () +{ + std::string proc_self_path = proc_self_dirname(); + std::string proc_share_path = proc_self_path + "share/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + proc_share_path = proc_self_path + "../share/yosys/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); + log_abort(); } int main(int argc, char **argv) diff --git a/kernel/register.h b/kernel/register.h index b582f98c..f3d3f70a 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -36,8 +36,8 @@ extern const char *yosys_version_str; // implemented in driver.cc extern RTLIL::Design *yosys_get_design(); -std::string rewrite_yosys_exe(std::string exe); -std::string get_share_file_name(std::string file); +extern std::string proc_self_dirname(); +extern std::string proc_share_dirname(); const char *create_prompt(RTLIL::Design *design, int recursion_counter); // from passes/cmds/design.cc diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 286b750c..30e78e58 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -969,7 +969,7 @@ struct AbcPass : public Pass { log_header("Executing ABC pass (technology mapping using ABC).\n"); log_push(); - std::string exe_file = rewrite_yosys_exe("yosys-abc"); + std::string exe_file = proc_self_dirname() + "yosys-abc"; std::string script_file, liberty_file, constr_file, clk_str; bool dff_mode = false, keepff = false, cleanup = true; int lut_mode = 0; diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index fdccb4bc..bf37e5da 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -751,7 +751,8 @@ struct ShowPass : public Pass { log_cmd_error("Shell command failed!\n"); } else if (format.empty()) { - std::string cmd = stringf("fuser -s '%s' || '%s' '%s' &", out_file.c_str(), rewrite_yosys_exe("yosys-svgviewer").c_str(), out_file.c_str()); + std::string svgviewer = proc_self_dirname() + "yosys-svgviewer"; + std::string cmd = stringf("fuser -s '%s' || '%s' '%s' &", out_file.c_str(), svgviewer.c_str(), out_file.c_str()); log("Exec: %s\n", cmd.c_str()); if (system(cmd.c_str()) != 0) log_cmd_error("Shell command failed!\n"); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 937f4131..0ca601e3 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -548,13 +548,14 @@ struct TechmapPass : public Pass { int max_iter = -1; size_t argidx; + std::string proc_share_path = proc_share_dirname(); for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-map" && argidx+1 < args.size()) { map_files.push_back(args[++argidx]); continue; } if (args[argidx] == "-share_map" && argidx+1 < args.size()) { - map_files.push_back(get_share_file_name(args[++argidx])); + map_files.push_back(proc_share_path + args[++argidx]); continue; } if (args[argidx] == "-max_iter" && argidx+1 < args.size()) { From 8127d5e8c35da6610dc9fd43cca66ff9ca41f078 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: [PATCH 152/750] - kernel/register.h, kernel/driver.cc: refactor rewrite_yosys_exe()/get_share_file_name() to portable proc_self_dirname()/proc_share_dirname(). This refactoring improves robustness and allows OSX support with only 7 new lines of code, and easy extension for other systems. - passes/abc/abc.cc, passes/cmds/show.cc, passes/techmap/techmap.cc: use new, refactored semantics. --- kernel/driver.cc | 69 +++++++++++++++++++++------------------ kernel/register.h | 4 +-- passes/abc/abc.cc | 2 +- passes/cmds/show.cc | 3 +- passes/techmap/techmap.cc | 3 +- 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index ce95cad4..da4962b8 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -427,42 +428,46 @@ extern RTLIL::Design *yosys_get_design() return yosys_design; } -std::string rewrite_yosys_exe(std::string exe) +#if defined(__linux__) +std::string proc_self_dirname () { - char buffer[1024]; - ssize_t buflen = readlink("/proc/self/exe", buffer, sizeof(buffer)-1); - - if (buflen < 0) - return exe; - - buffer[buflen] = 0; - std::string newexe = stringf("%s/%s", dirname(buffer), exe.c_str()); - if (access(newexe.c_str(), X_OK) == 0) - return newexe; - - return exe; + char path [PATH_MAX]; + ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); + if (buflen < 0) { + log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); + log_abort(); + } + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); } - -std::string get_share_file_name(std::string file) +#elif defined(__APPLE__) +#include +std::string proc_self_dirname () { - char buffer[1024]; - ssize_t buflen = readlink("/proc/self/exe", buffer, sizeof(buffer)-1); + char * path = NULL; + uint32_t buflen = 0; + while (_NSGetExecutablePath(path, &buflen) != 0) + path = (char *) realloc((void *) path, buflen); + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#else + #error Dont know how to determine process executable base path! +#endif - if (buflen < 0) - log_error("Can't find file `%s': reading of /proc/self/exe failed!\n", file.c_str()); - - buffer[buflen] = 0; - const char *dir = dirname(buffer); - - std::string newfile_inplace = stringf("%s/share/%s", dir, file.c_str()); - if (access(newfile_inplace.c_str(), F_OK) == 0) - return newfile_inplace; - - std::string newfile_system = stringf("%s/../share/yosys/%s", dir, file.c_str()); - if (access(newfile_system.c_str(), F_OK) == 0) - return newfile_system; - - log_error("Can't find file `%s': no `%s' and no `%s' found!\n", file.c_str(), newfile_inplace.c_str(), newfile_system.c_str()); +std::string proc_share_dirname () +{ + std::string proc_self_path = proc_self_dirname(); + std::string proc_share_path = proc_self_path + "share/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + proc_share_path = proc_self_path + "../share/yosys/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); + log_abort(); } int main(int argc, char **argv) diff --git a/kernel/register.h b/kernel/register.h index b582f98c..f3d3f70a 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -36,8 +36,8 @@ extern const char *yosys_version_str; // implemented in driver.cc extern RTLIL::Design *yosys_get_design(); -std::string rewrite_yosys_exe(std::string exe); -std::string get_share_file_name(std::string file); +extern std::string proc_self_dirname(); +extern std::string proc_share_dirname(); const char *create_prompt(RTLIL::Design *design, int recursion_counter); // from passes/cmds/design.cc diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 286b750c..30e78e58 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -969,7 +969,7 @@ struct AbcPass : public Pass { log_header("Executing ABC pass (technology mapping using ABC).\n"); log_push(); - std::string exe_file = rewrite_yosys_exe("yosys-abc"); + std::string exe_file = proc_self_dirname() + "yosys-abc"; std::string script_file, liberty_file, constr_file, clk_str; bool dff_mode = false, keepff = false, cleanup = true; int lut_mode = 0; diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index fdccb4bc..bf37e5da 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -751,7 +751,8 @@ struct ShowPass : public Pass { log_cmd_error("Shell command failed!\n"); } else if (format.empty()) { - std::string cmd = stringf("fuser -s '%s' || '%s' '%s' &", out_file.c_str(), rewrite_yosys_exe("yosys-svgviewer").c_str(), out_file.c_str()); + std::string svgviewer = proc_self_dirname() + "yosys-svgviewer"; + std::string cmd = stringf("fuser -s '%s' || '%s' '%s' &", out_file.c_str(), svgviewer.c_str(), out_file.c_str()); log("Exec: %s\n", cmd.c_str()); if (system(cmd.c_str()) != 0) log_cmd_error("Shell command failed!\n"); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 937f4131..0ca601e3 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -548,13 +548,14 @@ struct TechmapPass : public Pass { int max_iter = -1; size_t argidx; + std::string proc_share_path = proc_share_dirname(); for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-map" && argidx+1 < args.size()) { map_files.push_back(args[++argidx]); continue; } if (args[argidx] == "-share_map" && argidx+1 < args.size()) { - map_files.push_back(get_share_file_name(args[++argidx])); + map_files.push_back(proc_share_path + args[++argidx]); continue; } if (args[argidx] == "-max_iter" && argidx+1 < args.size()) { From a4d72de91dc017b299d6c11d67786274f1326133 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Mar 2014 23:28:10 +0100 Subject: [PATCH 153/750] Some fixes in libs/minisat (thanks to Siesh1oo) --- libs/minisat/Solver.cc | 10 +++++----- libs/minisat/System.cc | 6 +++--- libs/minisat/UPDATE.sh | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libs/minisat/Solver.cc b/libs/minisat/Solver.cc index ebca294a..14aa3935 100644 --- a/libs/minisat/Solver.cc +++ b/libs/minisat/Solver.cc @@ -994,11 +994,11 @@ void Solver::printStats() const { double cpu_time = cpuTime(); double mem_used = memUsedPeak(); - printf("restarts : %"PRIu64"\n", starts); - printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", conflicts , conflicts /cpu_time); - printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", decisions, (float)rnd_decisions*100 / (float)decisions, decisions /cpu_time); - printf("propagations : %-12"PRIu64" (%.0f /sec)\n", propagations, propagations/cpu_time); - printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", tot_literals, (max_literals - tot_literals)*100 / (double)max_literals); + printf("restarts : %" PRIu64 "\n", starts); + printf("conflicts : %-12" PRIu64 " (%.0f /sec)\n", conflicts , conflicts /cpu_time); + printf("decisions : %-12" PRIu64 " (%4.2f %% random) (%.0f /sec)\n", decisions, (float)rnd_decisions*100 / (float)decisions, decisions /cpu_time); + printf("propagations : %-12" PRIu64 " (%.0f /sec)\n", propagations, propagations/cpu_time); + printf("conflict literals : %-12" PRIu64 " (%4.2f %% deleted)\n", tot_literals, (max_literals - tot_literals)*100 / (double)max_literals); if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used); printf("CPU time : %g s\n", cpu_time); } diff --git a/libs/minisat/System.cc b/libs/minisat/System.cc index 01d0dfe1..df4155af 100644 --- a/libs/minisat/System.cc +++ b/libs/minisat/System.cc @@ -79,7 +79,7 @@ double Minisat::memUsed() { struct rusage ru; getrusage(RUSAGE_SELF, &ru); return (double)ru.ru_maxrss / 1024; } -double Minisat::memUsedPeak() { return memUsed(); } +double Minisat::memUsedPeak(bool) { return memUsed(); } #elif defined(__APPLE__) @@ -89,11 +89,11 @@ double Minisat::memUsed() { malloc_statistics_t t; malloc_zone_statistics(NULL, &t); return (double)t.max_size_in_use / (1024*1024); } -double Minisat::memUsedPeak() { return memUsed(); } +double Minisat::memUsedPeak(bool) { return memUsed(); } #else double Minisat::memUsed() { return 0; } -double Minisat::memUsedPeak() { return 0; } +double Minisat::memUsedPeak(bool) { return 0; } #endif diff --git a/libs/minisat/UPDATE.sh b/libs/minisat/UPDATE.sh index 88fcf759..539ee23f 100644 --- a/libs/minisat/UPDATE.sh +++ b/libs/minisat/UPDATE.sh @@ -7,6 +7,7 @@ mv minisat_upstream/LICENSE minisat_upstream/minisat/*/*.{h,cc} . rm -rf minisat_upstream sed -i -e 's,^#include *"minisat/[^/]\+,#include "libs/minisat,' *.cc *.h -sed -i -e 's/PRIi64/ & /' Options.h +sed -i -e 's/Minisat::memUsedPeak()/Minisat::memUsedPeak(bool)/' System.cc +sed -i -e 's/PRI[iu]64/ & /' Options.h Solver.cc sed -i -e '1 i #define __STDC_LIMIT_MACROS' *.cc sed -i -e '1 i #define __STDC_FORMAT_MACROS' *.cc From 89443aadbc6a20270de024f41ae1cc79ec75a8cf Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 19:39:01 +0100 Subject: [PATCH 154/750] - Makefile: resolve merge conflict. --- Makefile | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 73051e52..8da8b4c5 100644 --- a/Makefile +++ b/Makefile @@ -22,11 +22,22 @@ TARGETS = yosys yosys-config all: top-all -CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -LDFLAGS = -rdynamic -LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt -QMAKE = qmake-qt4 -SED = sed +CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h +LDFLAGS = -I${DESTDIR}/lib +LDLIBS = -lstdc++ -lreadline -lm -ldl + +ifeq (Darwin,$(findstring Darwin,$(shell uname))) + # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + CXXFLAGS += -I/opt/local/include + LDFLAGS += -L/opt/local/lib + QMAKE = qmake + SED = gsed +else + LDFLAGS += -rdynamic + LDLIBS += -lrt + QMAKE = qmake-qt4 + SED = sed +endif YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) @@ -123,6 +134,13 @@ yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make cp libs/svgviewer/svgviewer yosys-svgviewer +yosys-minisat: $(DESTDIR)/bin/minisat +$(DESTDIR)/bin/minisat: + test -d minisat || ( git clone https://github.com/niklasso/minisat.git minisat && $(SED) -i -e 's/PRIi64/ & /' minisat/minisat/utils/Options.h ) + ( cd minisat && git checkout $(MINISATREV) ) + ( cd minisat && $(MAKE) prefix=$(DESTDIR) DESTDIR="" config install ) + @( cd minisat && echo "Installed minisat version `git describe --always --dirty` into $(DESTDIR)." ) + abc/abc-$(ABCREV): ifneq ($(ABCREV),default) if ( cd abc && hg identify; ) | grep -q +; then \ From cb4293624e11d61f64e51027fabc73fbcf504fa2 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: [PATCH 155/750] - Makefile: export PATH=${DESTDIR}/bin:$(PATH) and (DY)LD_LIBRARY_PATH, to make sure our local copies of built executables and libraries are used. - Makefile: use find expression in target 'yosys-svgviewer' to find svgviewer binary (qmake will build into .app package on OSX). - Makefile: make 'test' target dependent on $(TARGETS) and $(EXTRA_TARGETS) to make sure that minisat is built. --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8da8b4c5..1bafd217 100644 --- a/Makefile +++ b/Makefile @@ -26,13 +26,17 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -I${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl +export PATH := ${DESTDIR}/bin:$(PATH) + ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else + export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 @@ -132,7 +136,7 @@ yosys-config: yosys-config.in yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make - cp libs/svgviewer/svgviewer yosys-svgviewer + cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer yosys-minisat: $(DESTDIR)/bin/minisat $(DESTDIR)/bin/minisat: From 1cd7fbb6b8da3b56273426cf2fd13bec49ec0fed Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: [PATCH 156/750] - Makefile: fix typo in LDFLAGS: obviously -L, not -I is required here --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1bafd217..39b324b4 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ TARGETS = yosys yosys-config all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h -LDFLAGS = -I${DESTDIR}/lib +LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl export PATH := ${DESTDIR}/bin:$(PATH) From 4cad0462332f84b747ff4402fd95fec22fae1735 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: [PATCH 157/750] - Makefile: include $(PWD) in PATH, since 'make test' can happen before 'make install'. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 39b324b4..9460e341 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := ${DESTDIR}/bin:$(PATH) +export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': From 989ef95a7f095e69c1f763b8854c5ed56c29ad9d Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:18:07 +0100 Subject: [PATCH 158/750] - .gitignore: ignore qmake/OSX package libs/svgviewer/svgviewer.app --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f251d2b6..69d56bfa 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /qtcreator.config /qtcreator.creator /qtcreator.creator.user +/libs/svgviewer/svgviewer.app /Makefile.conf /abc /yosys From c621bfa746b1ca2d698b09d7b9e65da9d191a39b Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:42:26 +0100 Subject: [PATCH 159/750] - Makefile: don't export DYLD_LIBRARY_PATH/LD_LIBRARY_PATH: not needed if we link minisat objects instead of library --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 9460e341..1eef767b 100644 --- a/Makefile +++ b/Makefile @@ -30,13 +30,11 @@ export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': - export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else - export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 From 26895223a1b2528f8416d3d3ca19d540c38c3cfe Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: [PATCH 160/750] - kernel/register.h, kernel/driver.cc: refactor rewrite_yosys_exe()/get_share_file_name() to portable proc_self_dirname()/proc_share_dirname(). This refactoring improves robustness and allows OSX support with only 7 new lines of code, and easy extension for other systems. - passes/abc/abc.cc, passes/cmds/show.cc, passes/techmap/techmap.cc: use new, refactored semantics. - Makefile: no need to add $(PWD) to $(PATH) anymore. --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 1eef767b..035f7c5a 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,6 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) - ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': CXXFLAGS += -I/opt/local/include From 1d0abb3ad2a85188eef6201e0a32acbcec1e78b3 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: [PATCH 161/750] - Makefile: export PATH=${DESTDIR}/bin:$(PATH) and (DY)LD_LIBRARY_PATH, to make sure our local copies of built executables and libraries are used. - Makefile: use find expression in target 'yosys-svgviewer' to find svgviewer binary (qmake will build into .app package on OSX). - Makefile: make 'test' target dependent on $(TARGETS) and $(EXTRA_TARGETS) to make sure that minisat is built. --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 035f7c5a..39b324b4 100644 --- a/Makefile +++ b/Makefile @@ -26,13 +26,17 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl +export PATH := ${DESTDIR}/bin:$(PATH) + ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else + export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 From 95e309b94d759c34173ef87f730814bbb73ebb9b Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: [PATCH 162/750] - Makefile: include $(PWD) in PATH, since 'make test' can happen before 'make install'. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 39b324b4..9460e341 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := ${DESTDIR}/bin:$(PATH) +export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': From ed2c577592e1547e63a840b1e7a119c20387a7bd Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:42:26 +0100 Subject: [PATCH 163/750] - Makefile: don't export DYLD_LIBRARY_PATH/LD_LIBRARY_PATH: not needed if we link minisat objects instead of library --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 9460e341..1eef767b 100644 --- a/Makefile +++ b/Makefile @@ -30,13 +30,11 @@ export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': - export DYLD_LIBRARY_PATH := ${DESTDIR}/lib:$(DYLD_LIBRARY_PATH) CXXFLAGS += -I/opt/local/include LDFLAGS += -L/opt/local/lib QMAKE = qmake SED = gsed else - export LD_LIBRARY_PATH := ${DESTDIR}/lib:$(LD_LIBRARY_PATH) LDFLAGS += -rdynamic LDLIBS += -lrt QMAKE = qmake-qt4 From 49c0bfa3adcceb25886d879c54c08ba9b93f6488 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: [PATCH 164/750] - kernel/register.h, kernel/driver.cc: refactor rewrite_yosys_exe()/get_share_file_name() to portable proc_self_dirname()/proc_share_dirname(). This refactoring improves robustness and allows OSX support with only 7 new lines of code, and easy extension for other systems. - passes/abc/abc.cc, passes/cmds/show.cc, passes/techmap/techmap.cc: use new, refactored semantics. - Makefile: no need to add $(PWD) to $(PATH) anymore. --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 1eef767b..035f7c5a 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,6 @@ CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -I${DESTDIR}/include -MD -D_YOSY LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl -export PATH := $(PWD):$(DESTDIR)/bin:$(PATH) - ifeq (Darwin,$(findstring Darwin,$(shell uname))) # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': CXXFLAGS += -I/opt/local/include From 0e30f16af1f27543a138898c3398feddd3e92457 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Thu, 13 Mar 2014 11:34:21 +0100 Subject: [PATCH 165/750] - Makefile, kernel/posix_compatibility.h/.cc: replay isolated OSX/POSIX.2008 compatibility patch. --- Makefile | 29 +++++--- kernel/posix_compatibility.cc | 134 ++++++++++++++++++++++++++++++++++ kernel/posix_compatibility.h | 40 ++++++++++ 3 files changed, 194 insertions(+), 9 deletions(-) create mode 100644 kernel/posix_compatibility.cc create mode 100644 kernel/posix_compatibility.h diff --git a/Makefile b/Makefile index 73051e52..5e6df242 100644 --- a/Makefile +++ b/Makefile @@ -22,11 +22,22 @@ TARGETS = yosys yosys-config all: top-all -CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -LDFLAGS = -rdynamic -LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt -QMAKE = qmake-qt4 -SED = sed +CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -include kernel/posix_compatibility.h -I${DESTDIR}/include +LDFLAGS = -L${DESTDIR}/lib +LDLIBS = -lstdc++ -lreadline -lm -ldl + +ifeq (Darwin,$(findstring Darwin,$(shell uname))) + # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + CXXFLAGS += -I/opt/local/include + LDFLAGS += -L/opt/local/lib + QMAKE = qmake + SED = gsed +else + LDFLAGS += -rdynamic + LDLIBS += -lrt + QMAKE = qmake-qt4 + SED = sed +endif YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) @@ -45,12 +56,12 @@ ABCPULL = 1 ifeq ($(CONFIG),clang-debug) CXX = clang -CXXFLAGS += -std=c++11 -Os +CXXFLAGS += -std=c++11 -O0 endif ifeq ($(CONFIG),gcc-debug) CXX = gcc -CXXFLAGS += -std=gnu++0x -Os +CXXFLAGS += -std=gnu++0x -O0 endif ifeq ($(CONFIG),release) @@ -85,7 +96,7 @@ CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -D'VERIFIC_DI LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif -OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o +OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/posix_compatibility.o OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o @@ -121,7 +132,7 @@ yosys-config: yosys-config.in yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make - cp libs/svgviewer/svgviewer yosys-svgviewer + cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer abc/abc-$(ABCREV): ifneq ($(ABCREV),default) diff --git a/kernel/posix_compatibility.cc b/kernel/posix_compatibility.cc new file mode 100644 index 00000000..d3fb0087 --- /dev/null +++ b/kernel/posix_compatibility.cc @@ -0,0 +1,134 @@ +/* + * 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. + * + */ + +/** + * POSIX.2008 fake implementation for pre-POSIX.2008 systems. (OSX, BSD, MINGW, CYGWIN, older Linux &c.) + */ + +#include +#include +#include +#include + +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) +typedef struct memstream { + off_t pos; + off_t size; + char * buffer; + char ** bufp; + size_t * sizep; + bool realloc; +} memstream_t; + +static int memstream_read (void * cookie, char * buf, int size) +{ + memstream_t * mem = (memstream_t *) cookie; + off_t available = mem->size - mem->pos; + if (available < 0) + available = 0; + if (size > available) + size = available; + memcpy(buf, mem->buffer + mem->pos, size); + mem->pos += size; + return size; +} + +static int memstream_write (void * cookie, const char * buf, int size) +{ + memstream_t * mem = (memstream_t *) cookie; + off_t available = mem->size - mem->pos; + if (size > available) { + if (mem->realloc) { + mem->buffer = (char *) realloc(mem->buffer, mem->pos + size + 1); + memset(mem->buffer + mem->size, 0, mem->pos + size + 1 - mem->size); + mem->size = mem->pos + size; + if (mem->bufp) + *(mem->bufp) = mem->buffer; + if (mem->sizep) + *(mem->sizep) = mem->size; + } else { + size = available; + } + } + memcpy(mem->buffer + mem->pos, buf, sizeof(char) * size); + mem->pos += size; + return size; +} + +static fpos_t memstream_seek (void * cookie, fpos_t offset, int whence) +{ + memstream_t * mem = (memstream_t *) cookie; + switch (whence) { + case SEEK_SET: + if (offset < 0) + goto error_inval; + mem->pos = offset; + return 0; + case SEEK_CUR: + if (mem->pos + offset < 0) + goto error_inval; + mem->pos += offset; + return 0; + case SEEK_END: + if (mem->size + offset < 0) + goto error_inval; + mem->pos = mem->size + offset; + break; + default: + goto error_inval; + } + return mem->pos; +error_inval: + errno = EINVAL; + return -1; +} + +static int memstream_close (void * cookie) +{ + memstream_t * mem = (memstream_t *) cookie; + if (mem->bufp) + *(mem->bufp) = mem->buffer; + if (mem->sizep) + *(mem->sizep) = mem->size; + free(cookie); + return 0; +} + +FILE * fmemopen (void * buf, size_t size, const char * mode) +{ + memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); + memset(mem, 0, sizeof(memstream_t)); + mem->size = size; + mem->buffer = (char *) buf; + (void) mode; + return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); +} + +FILE * open_memstream (char ** bufp, size_t * sizep) +{ + memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); + memset(mem, 0, sizeof(memstream_t)); + mem->bufp = bufp; + mem->sizep = sizep; + mem->realloc = true; + return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); +} + +#endif + diff --git a/kernel/posix_compatibility.h b/kernel/posix_compatibility.h new file mode 100644 index 00000000..ed8fc896 --- /dev/null +++ b/kernel/posix_compatibility.h @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +#ifndef POSIX_COMPATIBILITY_H +#define POSIX_COMPATIBILITY_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) +#include +#include + +FILE * open_memstream (char ** bufp, size_t * sizep); +FILE * fmemopen (void * buf, size_t size, const char * mode); +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + From fad8558eb5ecbd62e2032a48c537bfecfad3dfc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 12:48:10 +0100 Subject: [PATCH 166/750] Merged OSX fixes from Siesh1oo with some modifications --- Makefile | 23 ++++- backends/ilang/ilang_backend.cc | 1 + frontends/verilog/verilog_frontend.cc | 1 + kernel/compatibility.cc | 135 ++++++++++++++++++++++++++ kernel/compatibility.h | 36 +++++++ kernel/log.cc | 1 + kernel/register.cc | 5 +- kernel/rtlil.cc | 1 + libs/svgviewer/.gitignore | 1 + passes/techmap/techmap.cc | 1 + 10 files changed, 198 insertions(+), 7 deletions(-) create mode 100644 kernel/compatibility.cc create mode 100644 kernel/compatibility.h diff --git a/Makefile b/Makefile index 73051e52..325f25a1 100644 --- a/Makefile +++ b/Makefile @@ -22,12 +22,23 @@ TARGETS = yosys yosys-config all: top-all -CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -LDFLAGS = -rdynamic -LDLIBS = -lstdc++ -lreadline -lm -ldl -lrt +CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -I${DESTDIR}/include +LDFLAGS = -L${DESTDIR}/lib +LDLIBS = -lstdc++ -lreadline -lm -ldl QMAKE = qmake-qt4 SED = sed +ifeq (Darwin,$(findstring Darwin,$(shell uname))) + # add macports include and library path to search directories, don't use '-rdynamic' and '-lrt': + CXXFLAGS += -I/opt/local/include + LDFLAGS += -L/opt/local/lib + QMAKE = qmake + SED = gsed +else + LDFLAGS += -rdynamic + LDLIBS += -lrt +endif + YOSYS_VER := 0.2.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o @@ -86,15 +97,17 @@ LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o +OBJS += kernel/compatibility.o OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o OBJS += libs/sha1/sha1.o OBJS += libs/subcircuit/subcircuit.o -OBJS += libs/ezsat/ezsat.o +OBJS += libs/ezsat/ezsat.o OBJS += libs/ezsat/ezminisat.o + OBJS += libs/minisat/Options.o OBJS += libs/minisat/SimpSolver.o OBJS += libs/minisat/Solver.o @@ -121,7 +134,7 @@ yosys-config: yosys-config.in yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp cd libs/svgviewer && $(QMAKE) && make - cp libs/svgviewer/svgviewer yosys-svgviewer + cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer abc/abc-$(ABCREV): ifneq ($(ABCREV),default) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index c585d40c..b3d96b28 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -23,6 +23,7 @@ */ #include "ilang_backend.h" +#include "kernel/compatibility.h" #include "kernel/register.h" #include "kernel/log.h" #include diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 13c2676d..8e9efa17 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" diff --git a/kernel/compatibility.cc b/kernel/compatibility.cc new file mode 100644 index 00000000..2ef023eb --- /dev/null +++ b/kernel/compatibility.cc @@ -0,0 +1,135 @@ +/* + * 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. + * + */ + +/** + * POSIX.2008 fake implementation for pre-POSIX.2008 systems. (OSX, BSD, MINGW, CYGWIN, older Linux &c.) + */ + +#include +#include +#include +#include + +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) + +typedef struct memstream { + off_t pos; + off_t size; + char * buffer; + char ** bufp; + size_t * sizep; + bool realloc; +} memstream_t; + +static int memstream_read (void * cookie, char * buf, int size) +{ + memstream_t * mem = (memstream_t *) cookie; + off_t available = mem->size - mem->pos; + if (available < 0) + available = 0; + if (size > available) + size = available; + memcpy(buf, mem->buffer + mem->pos, size); + mem->pos += size; + return size; +} + +static int memstream_write (void * cookie, const char * buf, int size) +{ + memstream_t * mem = (memstream_t *) cookie; + off_t available = mem->size - mem->pos; + if (size > available) { + if (mem->realloc) { + mem->buffer = (char *) realloc(mem->buffer, mem->pos + size + 1); + memset(mem->buffer + mem->size, 0, mem->pos + size + 1 - mem->size); + mem->size = mem->pos + size; + if (mem->bufp) + *(mem->bufp) = mem->buffer; + if (mem->sizep) + *(mem->sizep) = mem->size; + } else { + size = available; + } + } + memcpy(mem->buffer + mem->pos, buf, sizeof(char) * size); + mem->pos += size; + return size; +} + +static fpos_t memstream_seek (void * cookie, fpos_t offset, int whence) +{ + memstream_t * mem = (memstream_t *) cookie; + switch (whence) { + case SEEK_SET: + if (offset < 0) + goto error_inval; + mem->pos = offset; + return 0; + case SEEK_CUR: + if (mem->pos + offset < 0) + goto error_inval; + mem->pos += offset; + return 0; + case SEEK_END: + if (mem->size + offset < 0) + goto error_inval; + mem->pos = mem->size + offset; + break; + default: + goto error_inval; + } + return mem->pos; +error_inval: + errno = EINVAL; + return -1; +} + +static int memstream_close (void * cookie) +{ + memstream_t * mem = (memstream_t *) cookie; + if (mem->bufp) + *(mem->bufp) = mem->buffer; + if (mem->sizep) + *(mem->sizep) = mem->size; + free(cookie); + return 0; +} + +FILE * compat_fmemopen (void * buf, size_t size, const char * mode) +{ + memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); + memset(mem, 0, sizeof(memstream_t)); + mem->size = size; + mem->buffer = (char *) buf; + (void) mode; + return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); +} + +FILE * compat_open_memstream (char ** bufp, size_t * sizep) +{ + memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); + memset(mem, 0, sizeof(memstream_t)); + mem->bufp = bufp; + mem->sizep = sizep; + mem->realloc = true; + return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); +} + +#endif /* !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) */ + diff --git a/kernel/compatibility.h b/kernel/compatibility.h new file mode 100644 index 00000000..58e0b52e --- /dev/null +++ b/kernel/compatibility.h @@ -0,0 +1,36 @@ +/* + * 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. + * + */ + +#ifndef COMPATIBILITY_H +#define COMPATIBILITY_H + +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) +#include +#include + +#define open_memstream compat_open_memstream +#define fmemopen compat_fmemopen + +FILE * compat_open_memstream (char ** bufp, size_t * sizep); +FILE * compat_fmemopen (void * buf, size_t size, const char * mode); + +#endif /* !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) */ + +#endif /* COMPATIBILITY_H */ + diff --git a/kernel/log.cc b/kernel/log.cc index 779f9373..b2c92e4e 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -18,6 +18,7 @@ */ #include "kernel/log.h" +#include "kernel/compatibility.h" #include "backends/ilang/ilang_backend.h" #include diff --git a/kernel/register.cc b/kernel/register.cc index ab5cba11..511afaac 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -17,8 +17,9 @@ * */ -#include "register.h" -#include "log.h" +#include "kernel/compatibility.h" +#include "kernel/register.h" +#include "kernel/log.h" #include #include #include diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 21fcae2b..7259845a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -17,6 +17,7 @@ * */ +#include "kernel/compatibility.h" #include "kernel/rtlil.h" #include "kernel/log.h" #include "frontends/verilog/verilog_frontend.h" diff --git a/libs/svgviewer/.gitignore b/libs/svgviewer/.gitignore index b92d91f8..b46f84a6 100644 --- a/libs/svgviewer/.gitignore +++ b/libs/svgviewer/.gitignore @@ -3,3 +3,4 @@ moc_mainwindow.cpp moc_svgview.cpp qrc_svgviewer.cpp svgviewer +svgviewer.app diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 0ca601e3..69ffb923 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -17,6 +17,7 @@ * */ +#include "kernel/compatibility.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" From 542afc562fa8b828f3c87e9dbe47a373ac09f147 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 12:55:15 +0100 Subject: [PATCH 167/750] Hotfix for kernel/compatibility.h --- kernel/compatibility.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/compatibility.h b/kernel/compatibility.h index 58e0b52e..c7603c8a 100644 --- a/kernel/compatibility.h +++ b/kernel/compatibility.h @@ -20,10 +20,11 @@ #ifndef COMPATIBILITY_H #define COMPATIBILITY_H -#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) #include #include +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) + #define open_memstream compat_open_memstream #define fmemopen compat_fmemopen From 7a1ac1120351d5cf0de2c9173fb7353795b0137e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 13:12:06 +0100 Subject: [PATCH 168/750] 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 diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys new file mode 100644 index 00000000..9e11cde0 --- /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 From 34e54cda5b45fb96cd44597622c3cba00e410265 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 13:12:49 +0100 Subject: [PATCH 169/750] Small improvement in SAT log messages --- passes/sat/sat.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index d18a220d..87bff4c4 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -214,7 +214,7 @@ struct SatHelper log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", s.first.c_str(), log_signal(lhs), lhs.width, s.second.c_str(), log_signal(rhs), rhs.width); - log("Import set-constraint for timestep: %s = %s\n", log_signal(lhs), log_signal(rhs)); + log("Import set-constraint for this timestep: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); big_lhs.append(lhs); big_rhs.append(rhs); @@ -228,7 +228,7 @@ struct SatHelper log_cmd_error("Failed to parse lhs set expression `%s'.\n", s.c_str()); show_signal_pool.add(sigmap(lhs)); - log("Import unset-constraint for timestep: %s\n", log_signal(lhs)); + log("Import unset-constraint for this timestep: %s\n", log_signal(lhs)); big_lhs.remove2(lhs, &big_rhs); } @@ -291,7 +291,7 @@ struct SatHelper for (int t = 0; t < 3; t++) for (auto &sig : sets_def_undef[t]) { - log("Import %s constraint for timestep: %s\n", t == 0 ? "def" : t == 1 ? "any_undef" : "all_undef", log_signal(sig)); + log("Import %s constraint for this timestep: %s\n", t == 0 ? "def" : t == 1 ? "any_undef" : "all_undef", log_signal(sig)); std::vector undef_sig = satgen.importUndefSigSpec(sig, timestep); if (t == 0) ez.assume(ez.NOT(ez.expression(ezSAT::OpOr, undef_sig))); From 6a53bc7b271662dfc67f055917578ef8c1949fd6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 17:34:31 +0100 Subject: [PATCH 170/750] Copy Verific vdbs files to Yosys "share" data directory --- Makefile | 2 +- frontends/verific/Makefile.inc | 15 +++++++++++++++ frontends/verific/verific.cc | 16 ++++++++-------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 325f25a1..45bdc47a 100644 --- a/Makefile +++ b/Makefile @@ -92,7 +92,7 @@ endif ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib_eval VERIFIC_COMPONENTS ?= verilog vhdl database util containers -CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -D'VERIFIC_DIR="$(VERIFIC_DIR)"' +CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index 74a669ef..eca23e58 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 c78d19f2..bc6abc5f 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"); } From 9a1accf692adfb9f0f505a1f7e7646731fff10d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 18:21:00 +0100 Subject: [PATCH 171/750] Progress in Verific bindings --- frontends/verific/verific.cc | 75 +++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index bc6abc5f..455bf817 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 From 77e5968323e76dd8f5dec431cadd95c69d77dc94 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 11:45:44 +0100 Subject: [PATCH 172/750] Added RTLIL::Module::Add{Inv,And,Or,Xor,Mux}Gate API --- kernel/rtlil.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 6 ++++++ 2 files changed, 48 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7259845a..420f528a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -932,6 +932,48 @@ DEF_METHOD(addPmux, "$pmux", 1) DEF_METHOD(addSafePmux, "$safe_pmux", 1) #undef DEF_METHOD +#define DEF_METHOD_2(_func, _type, _P1, _P2) \ + RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->connections["\\" #_P1] = sig1; \ + cell->connections["\\" #_P2] = sig2; \ + add(cell); \ + return cell; \ + } +#define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ + RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->connections["\\" #_P1] = sig1; \ + cell->connections["\\" #_P2] = sig2; \ + cell->connections["\\" #_P3] = sig3; \ + add(cell); \ + return cell; \ + } +#define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ + RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3, RTLIL::SigSpec sig4) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->connections["\\" #_P1] = sig1; \ + cell->connections["\\" #_P2] = sig2; \ + cell->connections["\\" #_P3] = sig3; \ + cell->connections["\\" #_P4] = sig4; \ + add(cell); \ + return cell; \ + } +DEF_METHOD_2(addInvGate, "$_INV_", A, Y) +DEF_METHOD_3(addAndGate, "$_AND_", A, B, Y) +DEF_METHOD_3(addOrGate, "$_OR_", A, B, Y) +DEF_METHOD_3(addXorGate, "$_XOR_", A, B, Y) +DEF_METHOD_4(addMuxGate, "$_MUX_", A, B, S, Y) +#undef DEF_METHOD_2 +#undef DEF_METHOD_3 +#undef DEF_METHOD_4 + RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed) { RTLIL::Cell *cell = new RTLIL::Cell; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 48f3e392..e55a88eb 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -351,6 +351,12 @@ struct RTLIL::Module { RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true); RTLIL::Cell* addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true); + + RTLIL::Cell* addInvGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y); + RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); + RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); + RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); + RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); }; struct RTLIL::Wire { From 0ac915a757a10f50fd74e18365cbcf351885c162 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 11:46:13 +0100 Subject: [PATCH 173/750] Progress in Verific bindings --- frontends/verific/verific.cc | 560 +++++++++++++++++++++-------------- kernel/rtlil.cc | 2 +- tests/tools/autotest.sh | 14 +- 3 files changed, 348 insertions(+), 228 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 455bf817..b10b3326 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 (design->modules.count(RTLIL::escape_id(nl->Owner()->Name()))) - log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); - + 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) +{ + 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 (!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() == PRIM_OR) { - module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + if (import_netlist_instance_gates(module, net_map, inst)) 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 (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; - } - - 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; + } - for (size_t argidx = 2; argidx < args.size(); argidx++) { + 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 (; 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); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 420f528a..ee73ebe4 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -718,7 +718,7 @@ void RTLIL::Module::check() for (auto &it2 : it.second->parameters) { assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); } - if (it.second->type[0] == '$' && it.second->type.substr(0, 3) != "$__" && it.second->type.substr(0, 8) != "$paramod") { + if (it.second->type[0] == '$' && it.second->type.substr(0, 3) != "$__" && it.second->type.substr(0, 8) != "$paramod" && it.second->type.substr(0, 9) != "$verific$") { InternalCellChecker checker(this, it.second); checker.check(); } diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 0e6c357c..fafd044d 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -101,7 +101,7 @@ do test_count=0 test_passes() { - "$toolsdir"/../../yosys -b "verilog $backend_opts" "$@" -o ${bn}_syn${test_count}.v $fn $scriptfiles + "$toolsdir"/../../yosys -b "verilog $backend_opts" -o ${bn}_syn${test_count}.v "$@" compile_and_run ${bn}_tb_syn${test_count} ${bn}_out_syn${test_count} \ ${bn}_tb.v ${bn}_syn${test_count}.v $libs \ "$toolsdir"/../../techlibs/common/simlib.v \ @@ -112,12 +112,16 @@ do } if [ -n "$scriptfiles" ]; then - test_passes + test_passes $fn $scriptfiles elif [ -n "$scriptopt" ]; then - test_passes -f "$frontend" -p "$scriptopt" + test_passes -f "$frontend" -p "$scriptopt" $fn + elif [ "$frontend" = "verific" ]; then + test_passes -p "verific -vlog2k $fn; verific -import -all; opt; memory;;" + elif [ "$frontend" = "verific_gates" ]; then + test_passes -p "verific -vlog2k $fn; verific -import -gates -all; opt; memory;;" else - test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt" - test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" + test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt" $fn + test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" $fn fi touch ../${bn}.log } From 5da9558fa8a6be6e98eb0a7a7d0c6dd8bd86347f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 16:39:50 +0100 Subject: [PATCH 174/750] Added log_dump() support for generic pointers --- kernel/log.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/log.h b/kernel/log.h index fbc3c1c3..5fbd2fc6 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -128,6 +128,9 @@ static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); } static inline void log_dump_val_worker(RTLIL::SigSpec v) { log("%s", log_signal(v)); } static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } +template +static inline void log_dump_val_worker(T *ptr) { log("%p", ptr); } + template void log_dump_args_worker(const char *p, T first, Args ... args) { From e37d672ae7dc47952bac483afb85aae32cb727f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 16:40:25 +0100 Subject: [PATCH 175/750] Progress in Verific bindings --- frontends/verific/verific.cc | 51 +++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index b10b3326..59fce136 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()) From b7c71d92f6003dcd626f58a0cf06f43c6a3b8d4c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 14:35:29 +0100 Subject: [PATCH 176/750] Added RTLIL::Module::add{Dff,Dffsr,Adff,Dlatch}Gate() API --- kernel/rtlil.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++++++- kernel/rtlil.h | 7 +++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ee73ebe4..072910e3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1109,7 +1109,7 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk return cell; } -RTLIL::Cell* RTLIL::Module::addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity) +RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; @@ -1123,6 +1123,59 @@ RTLIL::Cell* RTLIL::Module::addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_ return cell; } +RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); + cell->connections["\\C"] = sig_clk; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); + cell->connections["\\C"] = sig_clk; + cell->connections["\\S"] = sig_set; + cell->connections["\\R"] = sig_clr; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, + bool arst_value, bool clk_polarity, bool arst_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'); + cell->connections["\\C"] = sig_clk; + cell->connections["\\R"] = sig_arst; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + +RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'); + cell->connections["\\E"] = sig_en; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + RTLIL::Wire::Wire() { width = 1; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e55a88eb..44142bf2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -357,6 +357,13 @@ struct RTLIL::Module { RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); + + RTLIL::Cell* addDffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true); + RTLIL::Cell* addDffsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true); + RTLIL::Cell* addAdffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, + bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true); + RTLIL::Cell* addDlatchGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true); }; struct RTLIL::Wire { From 1d00ad9d4d241ffaa7cce35d7afc03d06521b15e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 14:36:11 +0100 Subject: [PATCH 177/750] Progress in Verific bindings --- frontends/verific/verific.cc | 62 ++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 59fce136..30437437 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())); } } From fc2c821407fde02248bb475c432df5bb89a1bd1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 15:31:54 +0100 Subject: [PATCH 178/750] Progress in Verific bindings --- frontends/verific/verific.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 30437437..4564d742 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) From 0ebee4c8e7743004ba0b7af714f3b1aff301bc61 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 22:51:12 +0100 Subject: [PATCH 179/750] Progress in Verific bindings --- frontends/verific/verific.cc | 55 +++++++++++------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4564d742..0e203a26 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; From ef1795a1e8df76873074a891f9132948181febcc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 22:52:10 +0100 Subject: [PATCH 180/750] Fixed typo in RTLIL::Module::{addSshl,addSshr} --- kernel/rtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 072910e3..2b28f323 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -893,8 +893,8 @@ DEF_METHOD(addXor, "$xor") DEF_METHOD(addXnor, "$xnor") DEF_METHOD(addShl, "$shl") DEF_METHOD(addShr, "$shr") -DEF_METHOD(addSshl, "$Sshl") -DEF_METHOD(addSshr, "$Sshr") +DEF_METHOD(addSshl, "$sshl") +DEF_METHOD(addSshr, "$sshr") DEF_METHOD(addLt, "$lt") DEF_METHOD(addLe, "$le") DEF_METHOD(addEq, "$eq") From 7545510edcc1d9ab14e53cae285f1ef0dfb3d7d4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Mar 2014 16:06:03 +0100 Subject: [PATCH 181/750] Use Verific Net::{IsGnd,IsPwr} API in Verific bindings --- frontends/verific/verific.cc | 38 +++++++++++------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 0e203a26..bf24c823 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()) From acda74c12cd39ae1a17d15f472728b49ad584e91 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Mar 2014 17:05:05 +0100 Subject: [PATCH 182/750] 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(-) diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys index 9e11cde0..6f63761a 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 bf24c823..8b42ca8c 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(); From a67cd2d4a284cb945af6d477cc215cef7bdd22a8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 01:56:00 +0100 Subject: [PATCH 183/750] Progress in Verific bindings --- frontends/verific/verific.cc | 2 ++ tests/simple/forgen01.v | 3 +++ tests/simple/mem_arst.v | 2 +- tests/tools/autotest.sh | 10 +++++++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 8b42ca8c..84e5e673 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) diff --git a/tests/simple/forgen01.v b/tests/simple/forgen01.v index 70ee7e66..8b7aa279 100644 --- a/tests/simple/forgen01.v +++ b/tests/simple/forgen01.v @@ -1,3 +1,6 @@ + +// VERIFIC-SKIP + module uut_forgen01(a, y); input [4:0] a; diff --git a/tests/simple/mem_arst.v b/tests/simple/mem_arst.v index 4022f57c..9bd38fcb 100644 --- a/tests/simple/mem_arst.v +++ b/tests/simple/mem_arst.v @@ -10,7 +10,7 @@ module MyMem #( output [DataWidth-1:0] Data_o, input WR_i); - reg Data_o; + reg [DataWidth-1:0] Data_o; localparam Size = 2**AddrWidth; diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index fafd044d..d459f988 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -82,7 +82,7 @@ do [[ "$bn" == *_tb ]] && continue echo -n "Test: $bn " - rm -f ${bn}.{err,log} + rm -f ${bn}.{err,log,sikp} mkdir -p ${bn}.out rm -rf ${bn}.out/* @@ -111,6 +111,11 @@ do test_count=$(( test_count + 1 )) } + if [ "$frontend" = "verific" -o "$frontend" = "verific_gates" ] && grep -q VERIFIC-SKIP $fn; then + touch ../${bn}.skip + return + fi + if [ -n "$scriptfiles" ]; then test_passes $fn $scriptfiles elif [ -n "$scriptopt" ]; then @@ -137,6 +142,9 @@ do if [ -f ${bn}.log ]; then mv ${bn}.err ${bn}.log echo "-> ok" + elif [ -f ${bn}.skip ]; then + mv ${bn}.err ${bn}.skip + echo "-> skip" else echo "-> ERROR!"; $keeprunning || exit 1; fi done From 0b0dcfda7d6a860713e67f3a0c50f6636be687d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 02:43:53 +0100 Subject: [PATCH 184/750] Progress in Verific bindings --- frontends/verific/verific.cc | 55 ++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 84e5e673..21aca6d4 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) From e164edc8d11356c0999c44dfdb52d0b2b337f212 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 14:41:41 +0100 Subject: [PATCH 185/750] Fixed typo in RTLIL::Module::addAdff() --- kernel/rtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2b28f323..1d53bc79 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1096,7 +1096,7 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; - cell->type = "$dffsr"; + cell->type = "$adff"; cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\ARST_POLARITY"] = arst_polarity; cell->parameters["\\ARST_VALUE"] = arst_value; From cdf12575651da53bff456617be2c5d1f825ba7fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 14:42:07 +0100 Subject: [PATCH 186/750] Progress in Verific bindings --- frontends/verific/verific.cc | 59 +++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 21aca6d4..1e15ef89 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()); From 9a34486bfbc8780d9a3af3164e99977e44d2a65f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 19 Mar 2014 10:05:01 +0100 Subject: [PATCH 187/750] Fixed performance problem in opt_mux with nets driven by many conflicting drivers --- passes/opt/opt_muxtree.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 47100869..3292a46c 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -309,13 +309,17 @@ struct OptMuxtreeWorker if (port_idx < int(muxinfo.ports.size())-1 && !muxinfo.ports[port_idx].const_activated) knowledge.known_active.push_back(muxinfo.ports[port_idx].ctrl_sigs); + std::vector parent_muxes; for (int m : muxinfo.ports[port_idx].input_muxes) { if (knowledge.visited_muxes.count(m) > 0) continue; knowledge.visited_muxes.insert(m); - eval_mux(knowledge, m); - knowledge.visited_muxes.erase(m); + parent_muxes.push_back(m); } + for (int m : parent_muxes) + eval_mux(knowledge, m); + for (int m : parent_muxes) + knowledge.visited_muxes.erase(m); if (port_idx < int(muxinfo.ports.size())-1 && !muxinfo.ports[port_idx].const_activated) knowledge.known_active.pop_back(); @@ -393,6 +397,7 @@ struct OptMuxtreeWorker void eval_root_mux(int mux_idx) { knowledge_t knowledge; + knowledge.visited_muxes.insert(mux_idx); eval_mux(knowledge, mux_idx); } }; From 470c2455e471318f4528da597e0dd8c7499b47ce Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Mar 2014 13:26:52 +0100 Subject: [PATCH 188/750] Fixed mapping of Verific FADD primitive with unconnected outputs --- frontends/verific/verific.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1e15ef89..cf72b781 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; From a3b9692a68e88bbe3e32e0dbbd30c5e20f3800b7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Mar 2014 13:40:01 +0100 Subject: [PATCH 189/750] Fixed mapping of Verific WIDE_DFFRS operator --- frontends/verific/verific.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cf72b781..7411e943 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; } From d4a1b0af5b41d1360c74a73fb2ae92ee5f6c3bd0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 31 Mar 2014 14:14:40 +0200 Subject: [PATCH 190/750] Added support for dlatchsr cells --- kernel/celltypes.h | 9 ++++ kernel/rtlil.cc | 59 ++++++++++++++++++++- kernel/rtlil.h | 4 ++ techlibs/common/simcells.v | 104 +++++++++++++++++++++++++++++++++++++ techlibs/common/simlib.v | 32 ++++++++++++ 5 files changed, 207 insertions(+), 1 deletion(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 4a600af9..76914583 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -108,6 +108,7 @@ struct CellTypes cell_types.insert("$dffsr"); cell_types.insert("$adff"); cell_types.insert("$dlatch"); + cell_types.insert("$dlatchsr"); cell_types.insert("$memrd"); cell_types.insert("$memwr"); cell_types.insert("$mem"); @@ -149,6 +150,14 @@ struct CellTypes cell_types.insert("$_DFFSR_PPP_"); cell_types.insert("$_DLATCH_N_"); cell_types.insert("$_DLATCH_P_"); + cell_types.insert("$_DLATCHSR_NNN_"); + cell_types.insert("$_DLATCHSR_NNP_"); + cell_types.insert("$_DLATCHSR_NPN_"); + cell_types.insert("$_DLATCHSR_NPP_"); + cell_types.insert("$_DLATCHSR_PNN_"); + cell_types.insert("$_DLATCHSR_PNP_"); + cell_types.insert("$_DLATCHSR_PPN_"); + cell_types.insert("$_DLATCHSR_PPP_"); } void clear() diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1d53bc79..1168102a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -569,6 +569,19 @@ namespace { return; } + if (cell->type == "$dlatchsr") { + param_bool("\\EN_POLARITY"); + param_bool("\\SET_POLARITY"); + param_bool("\\CLR_POLARITY"); + port("\\EN", 1); + port("\\SET", param("\\WIDTH")); + port("\\CLR", param("\\WIDTH")); + port("\\D", param("\\WIDTH")); + port("\\Q", param("\\WIDTH")); + check_expected(); + return; + } + if (cell->type == "$fsm") { param("\\NAME"); param_bool("\\CLK_POLARITY"); @@ -675,6 +688,15 @@ namespace { if (cell->type == "$_DLATCH_N_") { check_gate("EDQ"); return; } if (cell->type == "$_DLATCH_P_") { check_gate("EDQ"); return; } + if (cell->type == "$_DLATCHSR_NNN_") { check_gate("ESRDQ"); return; } + if (cell->type == "$_DLATCHSR_NNP_") { check_gate("ESRDQ"); return; } + if (cell->type == "$_DLATCHSR_NPN_") { check_gate("ESRDQ"); return; } + if (cell->type == "$_DLATCHSR_NPP_") { check_gate("ESRDQ"); return; } + if (cell->type == "$_DLATCHSR_PNN_") { check_gate("ESRDQ"); return; } + if (cell->type == "$_DLATCHSR_PNP_") { check_gate("ESRDQ"); return; } + if (cell->type == "$_DLATCHSR_PPN_") { check_gate("ESRDQ"); return; } + if (cell->type == "$_DLATCHSR_PPP_") { check_gate("ESRDQ"); return; } + error(__LINE__); } }; @@ -1113,7 +1135,7 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; - cell->type = "$dffsr"; + cell->type = "$dlatch"; cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\WIDTH"] = sig_q.width; cell->connections["\\EN"] = sig_en; @@ -1123,6 +1145,25 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e return cell; } +RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = "$dlatchsr"; + cell->parameters["\\EN_POLARITY"] = en_polarity; + cell->parameters["\\SET_POLARITY"] = set_polarity; + cell->parameters["\\CLR_POLARITY"] = clr_polarity; + cell->parameters["\\WIDTH"] = sig_q.width; + cell->connections["\\EN"] = sig_en; + cell->connections["\\SET"] = sig_set; + cell->connections["\\CLR"] = sig_clr; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity) { RTLIL::Cell *cell = new RTLIL::Cell; @@ -1176,6 +1217,22 @@ RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec s return cell; } +RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); + cell->connections["\\E"] = sig_en; + cell->connections["\\S"] = sig_set; + cell->connections["\\R"] = sig_clr; + cell->connections["\\D"] = sig_d; + cell->connections["\\Q"] = sig_q; + add(cell); + return cell; +} + + RTLIL::Wire::Wire() { width = 1; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 44142bf2..b95a0442 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -351,6 +351,8 @@ struct RTLIL::Module { RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true); RTLIL::Cell* addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true); + RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true); RTLIL::Cell* addInvGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y); RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); @@ -364,6 +366,8 @@ struct RTLIL::Module { RTLIL::Cell* addAdffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true); RTLIL::Cell* addDlatchGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true); + RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, + RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true); }; struct RTLIL::Wire { diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 10a809db..5ecec789 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -325,3 +325,107 @@ always @* begin end endmodule +module \$_DLATCHSR_NNN_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +module \$_DLATCHSR_NNP_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +module \$_DLATCHSR_NPN_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +module \$_DLATCHSR_NPP_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 0) + Q <= D; +end +endmodule + +module \$_DLATCHSR_PNN_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +module \$_DLATCHSR_PNP_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 0; + else if (S == 0) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +module \$_DLATCHSR_PPN_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 0) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + +module \$_DLATCHSR_PPP_ (E, S, R, D, Q); +input E, S, R, D; +output reg Q; +always @* begin + if (R == 1) + Q <= 0; + else if (S == 1) + Q <= 1; + else if (E == 1) + Q <= D; +end +endmodule + diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 4436abfe..908314f8 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1097,6 +1097,38 @@ endmodule // -------------------------------------------------------- +module \$dlatchsr (EN, SET, CLR, D, Q); + +parameter WIDTH = 0; +parameter EN_POLARITY = 1'b1; +parameter SET_POLARITY = 1'b1; +parameter CLR_POLARITY = 1'b1; + +input EN; +input [WIDTH-1:0] SET, CLR, D; +output reg [WIDTH-1:0] Q; + +wire pos_en = EN == EN_POLARITY; +wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET; +wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR; + +genvar i; +generate + for (i = 0; i < WIDTH; i = i+1) begin:bit + always @* + if (pos_clr[i]) + Q[i] <= 0; + else if (pos_set[i]) + Q[i] <= 1; + else if (pos_en) + Q[i] <= D[i]; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + module \$fsm (CLK, ARST, CTRL_IN, CTRL_OUT); parameter NAME = ""; From e24797add0ceb0e8c3571cec9351a2b0120e9b19 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Apr 2014 21:06:55 +0200 Subject: [PATCH 191/750] Added SIMLIB_NOSR to simlib.v --- techlibs/common/simlib.v | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 908314f8..16e6a1b2 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -977,6 +977,7 @@ end endmodule // -------------------------------------------------------- +`ifndef SIMLIB_NOSR module \$sr (SET, CLR, Q); @@ -1003,6 +1004,7 @@ endgenerate endmodule +`endif // -------------------------------------------------------- module \$dff (CLK, D, Q); @@ -1022,6 +1024,7 @@ end endmodule // -------------------------------------------------------- +`ifndef SIMLIB_NOSR module \$dffsr (CLK, SET, CLR, D, Q); @@ -1053,6 +1056,7 @@ endgenerate endmodule +`endif // -------------------------------------------------------- module \$adff (CLK, ARST, D, Q); @@ -1096,6 +1100,7 @@ end endmodule // -------------------------------------------------------- +`ifndef SIMLIB_NOSR module \$dlatchsr (EN, SET, CLR, D, Q); @@ -1127,6 +1132,7 @@ endgenerate endmodule +`endif // -------------------------------------------------------- module \$fsm (CLK, ARST, CTRL_IN, CTRL_OUT); From 7370ae01e978f0552f1565b88c0f44b402d09f4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Apr 2014 21:28:33 +0200 Subject: [PATCH 192/750] Added SIMLIB_NOLUT to simlib.v --- techlibs/common/simlib.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 16e6a1b2..be9d24f1 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -927,6 +927,7 @@ end endmodule // -------------------------------------------------------- +`ifndef SIMLIB_NOLUT module \$lut (I, O); @@ -961,6 +962,7 @@ endgenerate endmodule +`endif // -------------------------------------------------------- module \$assert (A, EN); From b950197da1e0a53c7d220dd666ff3afbb61a1f18 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 4 Apr 2014 16:39:03 -0600 Subject: [PATCH 193/750] Remove non-POSIX 'rm -v'. --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 45bdc47a..69fbf522 100644 --- a/Makefile +++ b/Makefile @@ -176,11 +176,11 @@ manual: $(TARGETS) $(EXTRA_TARGETS) cd manual && bash manual.sh clean: - rm -rvf share + rm -rf share cd manual && bash clean.sh - rm -vf $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) - rm -vf kernel/version_*.o kernel/version_*.cc abc/abc-[0-9a-f]* - rm -vf libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d + rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) + rm -f kernel/version_*.o kernel/version_*.cc abc/abc-[0-9a-f]* + rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d test ! -f libs/svgviewer/Makefile || make -C libs/svgviewer distclean mrproper: clean From 66a5da5edc41a2b33413c965337001bb179d30f6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 4 Apr 2014 16:51:27 -0600 Subject: [PATCH 194/750] POSIX find requires a path argument. --- libs/minisat/UPDATE.sh | 2 +- manual/clean.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/minisat/UPDATE.sh b/libs/minisat/UPDATE.sh index 539ee23f..a8429027 100644 --- a/libs/minisat/UPDATE.sh +++ b/libs/minisat/UPDATE.sh @@ -1,6 +1,6 @@ #!/bin/bash -rm -fv LICENSE *.cc *.h +rm -f LICENSE *.cc *.h git clone --depth 1 https://github.com/niklasso/minisat minisat_upstream rm minisat_upstream/minisat/*/Main.cc mv minisat_upstream/LICENSE minisat_upstream/minisat/*/*.{h,cc} . diff --git a/manual/clean.sh b/manual/clean.sh index 13554c01..f4a2ea83 100755 --- a/manual/clean.sh +++ b/manual/clean.sh @@ -1,2 +1,2 @@ #!/bin/bash -for f in $( find -name .gitignore ); do sed -re "s,^,find ${f%.gitignore} -name ',; s,$,' | xargs -r rm -vf,;" $f; done | bash -v +for f in $( find . -name .gitignore ); do sed -re "s,^,find ${f%.gitignore} -name ',; s,$,' | xargs -r rm -f,;" $f; done | bash -v From 9c1e578afe6af40be4600c20c883fa016fc7fa26 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 11 Apr 2014 02:42:59 -0600 Subject: [PATCH 195/750] Typos and grammar fixes through chapter 2. --- manual/CHAPTER_Basics.tex | 30 +++++++++++++++--------------- manual/CHAPTER_Intro.tex | 8 ++++---- manual/manual.tex | 4 ++-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/manual/CHAPTER_Basics.tex b/manual/CHAPTER_Basics.tex index 9cc4720e..c0eda0e8 100644 --- a/manual/CHAPTER_Basics.tex +++ b/manual/CHAPTER_Basics.tex @@ -56,7 +56,7 @@ and how they relate to different kinds of synthesis. Regardless of the way a lower level representation of a circuit is obtained (synthesis or manual design), the lower level representation is usually verified by comparing simulation results of the lower level and the higher level -representation \footnote{In the last years formal equivalence +representation \footnote{In recent years formal equivalence checking also became an important verification method for validating RTL and lower abstraction representation of the design.}. Therefore even if no synthesis is used, there must still be a simulatable @@ -71,7 +71,7 @@ be considered a ``High-Level Language'' today. \subsection{System Level} The System Level abstraction of a system only looks at its biggest building -blocks like CPUs and computing cores. On this level the circuit is usually described +blocks like CPUs and computing cores. At this level the circuit is usually described using traditional programming languages like C/C++ or Matlab. Sometimes special software libraries are used that are aimed at simulation circuits on the system level, such as SystemC. @@ -177,9 +177,9 @@ synthesis operations. \subsection{Logical Gate Level} -On the logical gate level the design is represented by a netlist that uses only +At the logical gate level the design is represented by a netlist that uses only cells from a small number of single-bit cells, such as basic logic gates (AND, -OR, NOT, XOR, etc.) and Registers (usually D-Type Flip-flops). +OR, NOT, XOR, etc.) and registers (usually D-Type Flip-flops). A number of netlist formats exists that can be used on this level, e.g.~the Electronic Design Interchange Format (EDIF), but for ease of simulation often a HDL netlist is used. The latter @@ -191,8 +191,8 @@ within the gate level netlist and second the optimal (or at least good) mapping gate netlist to an equivalent netlist of physically available gate types. The simplest approach to logic synthesis is {\it two-level logic synthesis}, where a logic function -is converted into a sum-of-products representation, e.g.~using a karnaugh map. -This is a simple approach, but has exponential worst-case effort and can not make efficient use of +is converted into a sum-of-products representation, e.g.~using a Karnaugh map. +This is a simple approach, but has exponential worst-case effort and cannot make efficient use of physical gates other than AND/NAND-, OR/NOR- and NOT-Gates. Therefore modern logic synthesis tools utilize much more complicated {\it multi-level logic @@ -287,7 +287,7 @@ applications to be used with a richer set of Verilog features. \subsection{Behavioural Modelling} Code that utilizes the Verilog {\tt always} statement is using {\it Behavioural -Modelling}. In behavioural, modelling a circuit is described by means of imperative +Modelling}. In behavioural modelling, a circuit is described by means of imperative program code that is executed on certain events, namely any change, a rising edge, or a falling edge of a signal. This is a very flexible construct during simulation but is only synthesizable when one of the following is modelled: @@ -457,7 +457,7 @@ Correctness is crucial. In some areas this is obvious (such as correct synthesis of basic behavioural models). But it is also crucial for the areas that concern minor details of the standard, such as the exact rules for handling signed expressions, even when the HDL code does not target -different synthesis tools. This is because (different to software source code that +different synthesis tools. This is because (unlike software source code that is only processed by compilers), in most design flows HDL code is not only processed by the synthesis tool but also by one or more simulators and sometimes even a formal verification tool. It is key for this verification process @@ -467,9 +467,9 @@ that all these tools use the same interpretation for the HDL code. Generally it is hard to give a one-dimensional description of how well a synthesis tool optimizes the design. First of all because not all optimizations are applicable to all -designs and all synthesis tasks. Some optimizations work (best) on a coarse grain level -(with complex cells such as adders or multipliers) and others work (best) on a fine -grain level (single bit gates). Some optimizations target area and others target speed. +designs and all synthesis tasks. Some optimizations work (best) on a coarse-grained level +(with complex cells such as adders or multipliers) and others work (best) on a fine-grained +level (single bit gates). Some optimizations target area and others target speed. Some work well on large designs while others don't scale well and can only be applied to small designs. @@ -610,7 +610,7 @@ The lexer is usually generated by a lexer generator (e.g.~{\tt flex} \citeweblin description file that is using regular expressions to specify the text pattern that should match the individual tokens. -The lexer is also responsible for skipping ignored characters (such as white spaces outside string +The lexer is also responsible for skipping ignored characters (such as whitespace outside string constants and comments in the case of Verilog) and converting the original text snippet to a token value. @@ -714,11 +714,11 @@ be connected in two different ways: through {\it Single-Pass Pipelining} and by Traditionally a parser and lexer are connected using the pipelined approach: The lexer provides a function that is called by the parser. This function reads data from the input until a complete lexical token has been read. Then this token is returned to the parser. So the lexer does not first generate a complete list of lexical tokens -and then passes it to the parser. Instead they are running concurrently and the parser can consume tokens as +and then pass it to the parser. Instead they run concurrently and the parser can consume tokens as the lexer produces them. -The single-pass pipelining approach has the advantage of lower memory footprint (at no time the complete design -must be kept in memory) but has the disadvantage of tighter coupling between the interacting components. +The single-pass pipelining approach has the advantage of lower memory footprint (at no time must the complete design +be kept in memory) but has the disadvantage of tighter coupling between the interacting components. Therefore single-pass pipelining should only be used when the lower memory footprint is required or the components are also conceptually tightly coupled. The latter certainly is the case for a parser and its lexer. diff --git a/manual/CHAPTER_Intro.tex b/manual/CHAPTER_Intro.tex index 675d2402..f735d46b 100644 --- a/manual/CHAPTER_Intro.tex +++ b/manual/CHAPTER_Intro.tex @@ -45,7 +45,7 @@ researched field. All the information required to write such tools has been open available for a long time, and it is therefore likely that a FOSS HDL synthesis tool with a feature-complete Verilog or VHDL front end must exist which can be used as a basis for a custom RTL synthesis tool. -Due to the authors preference for Verilog over VHDL it has been decided early +Due to the author's preference for Verilog over VHDL it was decided early on to go for Verilog instead of VHDL\footnote{A quick investigation into FOSS VHDL tools yielded similar grim results for FOSS VHDL synthesis tools.}. So the existing FOSS Verilog synthesis tools were evaluated (see @@ -56,12 +56,12 @@ is discussed in this document. \section{Structure of this Document} -The structure of this document is a follows: +The structure of this document is as follows: Chapter~\ref{chapter:intro} is this introduction. Chapter~\ref{chapter:basics} covers a short introduction to the world of HDL -synthesis. Basic principles and the terminology is outlined in this chapter. +synthesis. Basic principles and the terminology are outlined in this chapter. Chapter~\ref{chapter:approach} gives the quickest possible outline to how the problem of implementing a HDL synthesis tool is approached in the case of @@ -82,7 +82,7 @@ Yosys source code. The chapter concludes with an example loadable module for Yosys. Chapters~\ref{chapter:verilog}, \ref{chapter:opt}, and \ref{chapter:techmap} -cover three improtant pieces of the synthesis pileline: The Verilog frontend, +cover three important pieces of the synthesis pipeline: The Verilog frontend, the optimization passes and the technology mapping to the target architecture, respectively. diff --git a/manual/manual.tex b/manual/manual.tex index d6ffd95a..c305ecb0 100644 --- a/manual/manual.tex +++ b/manual/manual.tex @@ -140,7 +140,7 @@ bookmarksopen=false% \eject \chapter*{Abstract} -Most of todays digital design is done in HDL code (mostly Verilog or VHDL) and +Most of today's digital design is done in HDL code (mostly Verilog or VHDL) and with the help of HDL synthesis tools. In special cases such as synthesis for coarse-grain cell libraries or when @@ -158,7 +158,7 @@ by Yosys to perform advanced gate-level optimizations. An evaluation of Yosys based on real-world designs is included. It is shown that Yosys can be used as-is to synthesize such designs. The results produced by Yosys in this tests where successflly verified using formal verification -and are compareable in quality to the results produced by a commercial +and are comparable in quality to the results produced by a commercial synthesis tool. \bigskip From 12a3c05229a958a4ff3fb8ad782ceb28bab6dca1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Apr 2014 10:19:46 +0200 Subject: [PATCH 196/750] Updated README --- README | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/README b/README index 5a48a207..d021c886 100644 --- a/README +++ b/README @@ -56,20 +56,15 @@ and TCL for the scripting functionality. The extensive test suite requires Icarus Verilog. For example on Ubuntu Linux 12.04 LTS the following commands will install all prerequisites for building yosys: - $ sudo apt-get install git - $ sudo apt-get install g++ - $ sudo apt-get install clang - $ sudo apt-get install make - $ sudo apt-get install bison - $ sudo apt-get install flex - $ sudo apt-get install libreadline-dev - $ sudo apt-get install tcl8.5-dev - $ sudo apt-get install minisat - $ sudo apt-get install zlib1g-dev - $ sudo apt-get install libqt4-dev - $ sudo apt-get install mercurial - $ sudo apt-get install iverilog - $ sudo apt-get install graphviz + $ yosys_deps="git g++ clang make bison flex libreadline-dev + tcl8.5-dev zlib1g-dev libqt4-dev mercurial + iverilog graphviz" + $ sudo apt-get install $yosys_deps + +There are also pre-compiled packages for Yosys on Ubuntu. Visit the Yosys +download page to learn more about this: + + http://www.clifford.at/yosys/download.html To configure the build system to use a specific set of compiler and build configuration, use one of @@ -82,7 +77,8 @@ For other compilers and build configurations it might be necessary to make some changes to the config section of the Makefile. - $ vi Makefile + $ vi Makefile ..or.. + $ vi Makefile.conf To build Yosys simply type 'make' in this directory. @@ -90,9 +86,6 @@ To build Yosys simply type 'make' in this directory. $ make test $ sudo make install -If you encounter any problems during build, make sure to check the section -"Workarounds for known build problems" at the end of this README file. - Note that this also downloads, builds and installs ABC (using yosys-abc as executeable name). From d2d48996c4d6a81226f5dbdb8c6acf108ce26a5b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:17:40 +0200 Subject: [PATCH 197/750] minisat compile fix --- libs/minisat/PATCH_mkLit_default_arg.patch | 20 ++++++++++++++++++++ libs/minisat/SolverTypes.h | 4 ++-- libs/minisat/UPDATE.sh | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 libs/minisat/PATCH_mkLit_default_arg.patch diff --git a/libs/minisat/PATCH_mkLit_default_arg.patch b/libs/minisat/PATCH_mkLit_default_arg.patch new file mode 100644 index 00000000..e21683f9 --- /dev/null +++ b/libs/minisat/PATCH_mkLit_default_arg.patch @@ -0,0 +1,20 @@ +--- SolverTypes.h ++++ SolverTypes.h +@@ -52,7 +52,7 @@ struct Lit { + int x; + + // Use this as a constructor: +- friend Lit mkLit(Var var, bool sign = false); ++ friend Lit mkLit(Var var, bool sign); + + bool operator == (Lit p) const { return x == p.x; } + bool operator != (Lit p) const { return x != p.x; } +@@ -60,7 +60,7 @@ struct Lit { + }; + + +-inline Lit mkLit (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; } ++inline Lit mkLit (Var var, bool sign = false) { Lit p; p.x = var + var + (int)sign; return p; } + inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; } + inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; } + inline bool sign (Lit p) { return p.x & 1; } diff --git a/libs/minisat/SolverTypes.h b/libs/minisat/SolverTypes.h index be40a4c3..a47c2ce8 100644 --- a/libs/minisat/SolverTypes.h +++ b/libs/minisat/SolverTypes.h @@ -52,7 +52,7 @@ struct Lit { int x; // Use this as a constructor: - friend Lit mkLit(Var var, bool sign = false); + friend Lit mkLit(Var var, bool sign); bool operator == (Lit p) const { return x == p.x; } bool operator != (Lit p) const { return x != p.x; } @@ -60,7 +60,7 @@ struct Lit { }; -inline Lit mkLit (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; } +inline Lit mkLit (Var var, bool sign = false) { Lit p; p.x = var + var + (int)sign; return p; } inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; } inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; } inline bool sign (Lit p) { return p.x & 1; } diff --git a/libs/minisat/UPDATE.sh b/libs/minisat/UPDATE.sh index a8429027..68c7c60e 100644 --- a/libs/minisat/UPDATE.sh +++ b/libs/minisat/UPDATE.sh @@ -11,3 +11,6 @@ sed -i -e 's/Minisat::memUsedPeak()/Minisat::memUsedPeak(bool)/' System.cc sed -i -e 's/PRI[iu]64/ & /' Options.h Solver.cc sed -i -e '1 i #define __STDC_LIMIT_MACROS' *.cc sed -i -e '1 i #define __STDC_FORMAT_MACROS' *.cc + +patch -p0 < PATCH_mkLit_default_arg.patch + From a1be4816d602548f4454242dc17f8a85ccaa91bd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:22:11 +0200 Subject: [PATCH 198/750] Replaced depricated %name-prefix= bison directive --- frontends/ilang/parser.y | 2 +- frontends/verilog/parser.y | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index ebb4d309..6b41b087 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 4726f1aa..ed9be692 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; From 7188542155902bcf3880d482d472e91331f8a3ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:28:23 +0200 Subject: [PATCH 199/750] Fixed clang -Wdeprecated-register warnings --- frontends/ilang/lexer.l | 7 +++++++ frontends/verilog/lexer.l | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 00091927..6557f98a 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 e3e5e4ab..226a2670 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" From 154c9f8b513db97d0397ac8d4c3c5c7276f6260f Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 2 May 2014 03:08:40 -0600 Subject: [PATCH 200/750] Typos and grammar fixes through chapter 4. --- manual/CHAPTER_Approach.tex | 14 +++++------ manual/CHAPTER_Overview.tex | 50 ++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/manual/CHAPTER_Approach.tex b/manual/CHAPTER_Approach.tex index a2c40bea..69122580 100644 --- a/manual/CHAPTER_Approach.tex +++ b/manual/CHAPTER_Approach.tex @@ -8,7 +8,7 @@ approach followed in the effort to implement this tool. \section{Data- and Control-Flow} -The data- and control-flow of a typical synthesis-tool is very similar to the data- and control-flow of a typical +The data- and control-flow of a typical synthesis tool is very similar to the data- and control-flow of a typical compiler: different subsystems are called in a predetermined order, each consuming the data generated by the last subsystem and generating the data for the next subsystem (see Fig.~\ref{fig:approach_flow}). @@ -44,10 +44,10 @@ last subsystem and generating the data for the next subsystem (see Fig.~\ref{fig \end{figure} The first subsystem to be called is usually called a {\it frontend}. It does not process the data generated by -another subsystem but instead reads the user input; in the case of a HDL synthesis tool the behavioural +another subsystem but instead reads the user input---in the case of a HDL synthesis tool, the behavioural HDL code. -The subsystems that consume data from previous subsystems and produces data for the next subsystems (usually in the +The subsystems that consume data from previous subsystems and produce data for the next subsystems (usually in the same or a similar format) are called {\it passes}. The last subsystem that is executed transforms the data generated by the last pass into a suitable output @@ -61,7 +61,7 @@ script. Yosys uses two different internal formats. The first is used to store an abstract syntax tree (AST) of a verilog input file. This format is simply called {\it AST} and is generated by the Verilog Frontend. This data structure -is then consumed by a subsystem called {\it AST Frontend}\footnote{In Yosys the term {\it pass} is only used to +is consumed by a subsystem called {\it AST Frontend}\footnote{In Yosys the term {\it pass} is only used to refer to commands that operate on the RTLIL data structure.}. This AST Frontend then generates a design in Yosys' main internal format, the Register-Transfer-Level-Intermediate-Language (RTLIL) representation. It does that by first performing a number of simplifications within the AST representation and then generating RTLIL from @@ -71,10 +71,10 @@ The RTLIL representation is used by all passes as input and outputs. This has th using different representational formats between different passes: \begin{itemize} -\item The passes can be re-arranged in a different order and passes can be removed or inserted. +\item The passes can be rearranged in a different order and passes can be removed or inserted. \item Passes can simply pass-thru the parts of the design they don't change without the need to convert between formats. In fact Yosys passes output the same data structure they received - as input and perform all changes in place. + as input and performs all changes in place. \item All passes use the same interface, thus reducing the effort required to understand a pass when reading the Yosys source code, e.g.~when adding additional features. \end{itemize} @@ -95,7 +95,7 @@ The use of RTLIL also has the disadvantage of having a very powerful format between all passes, even when doing gate-level synthesis where the more advanced features are not needed. In order to reduce complexity for passes that operate on a low-level representation, these passes check the features used in -the input RTLIL and fail to run when non-supported high-level constructs are +the input RTLIL and fail to run when unsupported high-level constructs are used. In such cases a pass that transforms the higher-level constructs to lower-level constructs must be called from the synthesis script first. diff --git a/manual/CHAPTER_Overview.tex b/manual/CHAPTER_Overview.tex index b9df57d1..ec402231 100644 --- a/manual/CHAPTER_Overview.tex +++ b/manual/CHAPTER_Overview.tex @@ -3,8 +3,8 @@ \label{chapter:overview} Yosys is an extensible open source hardware synthesis tool. It is aimed at -designers who are looking for an easy accessible, universal, and vendor -independent synthesis tool, and scientists who do research in +designers who are looking for an easily accessible, universal, and +vendor-independent synthesis tool, as well as scientists who do research in electronic design automation (EDA) and are looking for an open synthesis framework that can be used to test algorithms on complex real-world designs. @@ -49,7 +49,7 @@ of the backends, namely the Verilog Backend for generating Verilog netlists and the ILANG Backend for writing the RTLIL data in the same format that is understood by the ILANG Frontend. -With the exception of the AST Frontend, that is called by the high-level HDL +With the exception of the AST Frontend, which is called by the high-level HDL frontends and can't be called directly by the user, all program modules are called by the user (usually using a synthesis script that contains text commands for Yosys). @@ -57,7 +57,7 @@ commands for Yosys). By combining passes in different ways and/or adding additional passes to Yosys it is possible to adapt Yosys to a wide range of applications. For this to be possible it is key that (1) all passes operate on the same data structure -(RTLIL) and (2) that this data structure is powerful enough represent the design +(RTLIL) and (2) that this data structure is powerful enough to represent the design in different stages of the synthesis. \begin{figure}[t] @@ -97,7 +97,7 @@ refers to the fact, that RTLIL also has a text representation, usually referred The only exception are the high-level frontends that use the AST representation as an intermediate step before generating RTLIL data. -In order to avoid re-inventing names for the RTLIL classes, they are simply referred to by their full C++ name, i.e.~including +In order to avoid reinventing names for the RTLIL classes, they are simply referred to by their full C++ name, i.e.~including the {\tt RTLIL::} namespace prefix, in this document. Figure~\ref{fig:Overview_RTLIL} shows a simplified Entity-Relationship Diagram (ER Diagram) of RTLIL. In $1:N$ relationships the arrow @@ -105,7 +105,7 @@ points from the $N$ side to the $1$. For example one RTLIL::Design contains $N$ A two-pointed arrow indicates a $1:1$ relationship. The RTLIL::Design is the root object of the RTLIL data structure. There is always one ``current design'' in memory -on which passes operate, frontends add data to it and backends convert to exportable formats. But in some cases passes +which passes operate on, frontends add data to and backends convert to exportable formats. But in some cases passes internally generate additional RTLIL::Design objects. For example when a pass is reading an auxiliary Verilog file such as a cell library, it might create an additional RTLIL::Design object and call the Verilog frontend with this other object to parse the cell library. @@ -154,12 +154,12 @@ transformed to an RTLIL-compatible representation by the HDL frontend. This incl Verilog-features such as generate-blocks, loops and parameters. The following sections contain a more detailed description of the different -parts of RTLIL and rationales behind some of the design decisions. +parts of RTLIL and rationale behind some of the design decisions. \subsection{RTLIL Identifiers} All identifiers in RTLIL (such as module names, port names, signal names, cell -types, etc.) follow the following naming convention: They must either start with +types, etc.) follow the following naming convention: they must either start with a backslash (\textbackslash) or a dollar sign (\$). Identifiers starting with a backslash are public visible identifiers. Usually @@ -172,13 +172,13 @@ identifiers that start with a backslash. This has three advantages: \begin{itemize} -\item Firstly it is impossible that an auto-generated identifier collides with +\item First, it is impossible that an auto-generated identifier collides with an identifier that was provided by the user. -\item Secondly the information about which identifiers were originally +\item Second, the information about which identifiers were originally provided by the user is always available which can help guide some optimizations. For example the ``opt\_rmunused'' -is trying to preserve signals with a user-provided name but doesn't hesitate to delete signals that have +tries to preserve signals with a user-provided name but doesn't hesitate to delete signals that have auto-generated names when they just duplicate other signals. -\item Thirdly the delicate job of finding suitable auto-generated public visible +\item Third, the delicate job of finding suitable auto-generated public visible names is deferred to one central location. Internally auto-generated names that may hold important information for Yosys developers can be used without disturbing external tools. For example the Verilog backend assigns names in the form {\tt \_{\it integer}\_}. @@ -216,7 +216,7 @@ Verilog and VHDL both support parametric modules (known as ``generic entities'' format does not support parametric modules itself. Instead each module contains a callback function into the AST frontend to generate a parametrized variation of the RTLIL::Module as needed. This callback then returns the auto-generated name of the parametrized variation of the module. (A hash -over the parameters and the module name is used to prohibit the same parametrized variation to be +over the parameters and the module name is used to prohibit the same parametrized variation from being generated twice. For modules with only a few parameters, a name directly containing all parameters is generated instead of a hash string.) @@ -233,7 +233,7 @@ An RTLIL::Wire object has the following properties: \begin{itemize} \item The wire name \item A list of attributes -\item A width (busses are just wires with a width > 1) +\item A width (buses are just wires with a width > 1) \item If the wire is a port: port number and direction (input/output/inout) \end{itemize} @@ -256,7 +256,7 @@ An RTLIL::Cell object has the following properties: \end{itemize} The connections of ports to wires are coded by assigning an RTLIL::SigSpec -to each cell ports. The RTLIL::SigSpec data type is described in the next section. +to each cell port. The RTLIL::SigSpec data type is described in the next section. \subsection{RTLIL::SigSpec} @@ -382,7 +382,7 @@ end This pass has transformed the outer RTLIL::SwitchRule into a modified RTLIL::SyncRule object for the {\tt \textbackslash{}reset} signal. Further processing converts the RTLIL::Process -e.g.~into a d-type flip-flop with asynchronous reset and a multiplexer for the enable signal: +into e.g.~a d-type flip-flop with asynchronous reset and a multiplexer for the enable signal: \begin{lstlisting}[numbers=left,frame=single,language=rtlil] cell $adff $procdff$6 @@ -442,31 +442,31 @@ The {\tt memory} pass performs this conversion and can (depending on the options to it) transform the memories directly to d-type flip-flops and address logic or yield multiport memory blocks (represented using {\tt \$mem} cells). -See Sec.~\ref{sec:memcells} for details on the memory cell types. +See Sec.~\ref{sec:memcells} for details about the memory cell types. \section{Command Interface and Synthesis Scripts} Yosys reads and processes commands from synthesis scripts, command line arguments and an interactive command prompt. Yosys commands consist of a command name and an optional -whitespace sparated list of arguments. Commands are terminated using the newline character +whitespace separated list of arguments. Commands are terminated using the newline character or a semicolon ({\tt ;}). Empty lines and lines starting with the hash sign ({\tt \#}) are ignored. See Sec.~\ref{sec:typusecase} for an example synthesis script. The command {\tt help} can be used to access the command reference manual. -Most commands can operate not only on the entire design but also only on {\it selected} +Most commands can operate not only on the entire design but also specifically on {\it selected} parts of the design. For example the command {\tt dump} will print all selected objects in the current design while {\tt dump foobar} will only print the module {\tt foobar} and {\tt dump *} will print the entire design regardless of the current selection. The selection mechanism is very powerful. For example the command {\tt dump */t:\$add \%x:+[A] */w:* \%i} will print all wires that are connected to the \B{A} port of -a {\tt \$add} cell. A detailed documentation of the select framework can be +a {\tt \$add} cell. Detailed documentation of the select framework can be found in the command reference for the {\tt select} command. \section{Source Tree and Build System} -The Yosys source tree is organized in the following top-level directories: +The Yosys source tree is organized into the following top-level directories: \begin{itemize} @@ -512,15 +512,15 @@ and a {\tt Makefile.inc}. The Yosys kernel automatically detects all commands li Yosys. So it is not needed to add additional commands to a central list of commands. \end{sloppypar} -A good starting point for reading example source code for learning how to write passes +Good starting points for reading example source code to learn how to write passes are {\tt passes/opt/opt\_rmdff.cc} and {\tt passes/opt/opt\_share.cc}. See the top-level README file for a quick {\it Getting Started} guide and build -instructions. Yosys is a pure Makefile based project. +instructions. The Yosys build is based solely on Makefiles. Users of the Qt Creator IDE can generate a QT Creator project file using {\tt make qtcreator}. Users of the Eclipse IDE can use the ``Makefile Project with Existing Code'' project type in the Eclipse ``New Project'' dialog (only -available after the CDT plugin has been installed) to create an Eclipse Project -for programming extensions to Yosys or just browsing the Yosys code base. +available after the CDT plugin has been installed) to create an Eclipse project +in order to programming extensions to Yosys or just browse the Yosys code base. From 75a5d6bd1ec6f23e508a52d04a6e384d247efd90 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 2 May 2014 13:22:26 +0200 Subject: [PATCH 201/750] workaround for OpenBSD 'stdin' implementation --- kernel/register.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/register.cc b/kernel/register.cc index 511afaac..cb8ad473 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -306,7 +306,8 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam if (f != NULL) { frontend_register[args[0]]->execute(f, filename, args, design); } else if (filename == "-") { - frontend_register[args[0]]->execute(stdin, "", args, design); + FILE *f_stdin = stdin; // workaround for OpenBSD 'stdin' implementation + frontend_register[args[0]]->execute(f_stdin, "", args, design); } else { if (!filename.empty()) args.push_back(filename); From a5a519a9d15f188b93723c84890d6005d2e9c4be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 3 May 2014 12:55:56 +0200 Subject: [PATCH 202/750] workaround for OpenBSD 'stdout' implementation --- kernel/register.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/register.cc b/kernel/register.cc index cb8ad473..5d882ab4 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -400,7 +400,8 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, if (f != NULL) { backend_register[args[0]]->execute(f, filename, args, design); } else if (filename == "-") { - backend_register[args[0]]->execute(stdout, "", args, design); + FILE *f_stdout = stdout; // workaround for OpenBSD 'stdout' implementation + backend_register[args[0]]->execute(f_stdout, "", args, design); } else { if (!filename.empty()) args.push_back(filename); From 30774ec6bc732478cce1a5ceff5f666893c416a6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 May 2014 13:48:25 +0200 Subject: [PATCH 203/750] Improved ezsat stand-alone tests --- libs/ezsat/Makefile | 4 +- libs/ezsat/ezsat.h | 2 +- libs/ezsat/puzzle3d.cc | 4 +- libs/ezsat/testbench.cc | 120 ++++++---------------------------------- 4 files changed, 24 insertions(+), 106 deletions(-) diff --git a/libs/ezsat/Makefile b/libs/ezsat/Makefile index da2355a9..e831cc6f 100644 --- a/libs/ezsat/Makefile +++ b/libs/ezsat/Makefile @@ -3,7 +3,7 @@ CC = clang CXX = clang CXXFLAGS = -MD -Wall -Wextra -ggdb CXXFLAGS += -std=c++11 -O0 -LDLIBS = -lminisat -lstdc++ +LDLIBS = -lminisat -lm -lstdc++ all: demo_vec demo_bit demo_cmp testbench puzzle3d @@ -20,7 +20,7 @@ test: all ./demo_cmp clean: - rm -f demo_bit demo_vec testbench puzzle3d *.o *.d + rm -f demo_bit demo_vec demo_cmp testbench puzzle3d *.o *.d .PHONY: all test clean diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index b0b731d0..85240556 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -168,7 +168,7 @@ public: int get(ezSAT *that) { if (name.empty()) return id; - return that->literal(name); + return that->frozen_literal(name); } }; diff --git a/libs/ezsat/puzzle3d.cc b/libs/ezsat/puzzle3d.cc index 56d29326..aee0044b 100644 --- a/libs/ezsat/puzzle3d.cc +++ b/libs/ezsat/puzzle3d.cc @@ -260,8 +260,10 @@ int main() std::vector modelExpressions; std::vector modelValues; - for (auto &it : blockinfo) + for (auto &it : blockinfo) { + ez.freeze(it.first); modelExpressions.push_back(it.first); + } int solution_counter = 0; while (1) diff --git a/libs/ezsat/testbench.cc b/libs/ezsat/testbench.cc index 8283686e..8332ad91 100644 --- a/libs/ezsat/testbench.cc +++ b/libs/ezsat/testbench.cc @@ -63,7 +63,7 @@ void test_simple() { printf("==== %s ====\n\n", __PRETTY_FUNCTION__); - ezSAT sat; + ezMiniSAT sat; sat.assume(sat.OR("A", "B")); sat.assume(sat.NOT(sat.AND("A", "B"))); test(sat); @@ -71,89 +71,6 @@ void test_simple() // ------------------------------------------------------------------------------------------------------------ -void test_basic_operators(ezSAT &sat, xorshift128 &rng, int iter, bool buildTrees, bool buildClusters, std::vector &log) -{ - int vars[6] = { - sat.VAR("A"), sat.VAR("B"), sat.VAR("C"), - sat.NOT("A"), sat.NOT("B"), sat.NOT("C") - }; - for (int i = 0; i < iter; i++) { - int assumption = 0, op = rng() % 6, to = rng() % 6; - int a = vars[rng() % 6], b = vars[rng() % 6], c = vars[rng() % 6]; - // printf("--> %d %d:%s %d:%s %d:%s\n", op, a, sat.to_string(a).c_str(), b, sat.to_string(b).c_str(), c, sat.to_string(c).c_str()); - switch (op) - { - case 0: - assumption = sat.NOT(a); - break; - case 1: - assumption = sat.AND(a, b); - break; - case 2: - assumption = sat.OR(a, b); - break; - case 3: - assumption = sat.XOR(a, b); - break; - case 4: - assumption = sat.IFF(a, b); - break; - case 5: - assumption = sat.ITE(a, b, c); - break; - } - // printf(" --> %d:%s\n", to, sat.to_string(assumption).c_str()); - if (buildTrees) - vars[to] = assumption; - if (!buildClusters) - sat.clear(); - sat.assume(assumption); - if (sat.numCnfVariables() < 15) { - printf("%d:\n", int(log.size())); - log.push_back(test(sat)); - } else { - // printf("** skipping large problem **\n"); - } - } -} - -void test_basic_operators(ezSAT &sat, std::vector &log) -{ - printf("-- %s --\n\n", __PRETTY_FUNCTION__); - - xorshift128 rng; - test_basic_operators(sat, rng, 1000, false, false, log); - for (int i = 0; i < 100; i++) - test_basic_operators(sat, rng, 10, true, false, log); - for (int i = 0; i < 100; i++) - test_basic_operators(sat, rng, 10, false, true, log); -} - -void test_basic_operators() -{ - printf("==== %s ====\n\n", __PRETTY_FUNCTION__); - - ezSAT sat; - ezMiniSAT miniSat; - std::vector logSat, logMiniSat; - - test_basic_operators(sat, logSat); - test_basic_operators(miniSat, logMiniSat); - - if (logSat != logMiniSat) { - printf("Differences between logSat and logMiniSat:"); - for (int i = 0; i < int(std::max(logSat.size(), logMiniSat.size())); i++) - if (i >= int(logSat.size()) || i >= int(logMiniSat.size()) || logSat[i] != logMiniSat[i]) - printf(" %d", i); - printf("\n"); - abort(); - } else { - printf("Completed %d tests with identical results with ezSAT and ezMiniSAT.\n\n", int(logSat.size())); - } -} - -// ------------------------------------------------------------------------------------------------------------ - void test_xorshift32_try(ezSAT &sat, uint32_t input_pattern) { uint32_t output_pattern = input_pattern; @@ -238,7 +155,7 @@ void check(const char *expr1_str, bool expr1, const char *expr2_str, bool expr2) void test_signed(int8_t a, int8_t b, int8_t c) { - ezSAT sat; + ezMiniSAT sat; std::vector av = sat.vec_const_signed(a, 8); std::vector bv = sat.vec_const_signed(b, 8); @@ -257,7 +174,7 @@ void test_signed(int8_t a, int8_t b, int8_t c) void test_unsigned(uint8_t a, uint8_t b, uint8_t c) { - ezSAT sat; + ezMiniSAT sat; if (b < c) b ^= c, c ^= b, b ^= c; @@ -279,7 +196,7 @@ void test_unsigned(uint8_t a, uint8_t b, uint8_t c) void test_count(uint32_t x) { - ezSAT sat; + ezMiniSAT sat; int count = 0; for (int i = 0; i < 32; i++) @@ -333,10 +250,10 @@ void test_onehot() printf("==== %s ====\n\n", __PRETTY_FUNCTION__); ezMiniSAT ez; - int a = ez.literal("a"); - int b = ez.literal("b"); - int c = ez.literal("c"); - int d = ez.literal("d"); + int a = ez.frozen_literal("a"); + int b = ez.frozen_literal("b"); + int c = ez.frozen_literal("c"); + int d = ez.frozen_literal("d"); std::vector abcd; abcd.push_back(a); @@ -387,10 +304,10 @@ void test_manyhot() printf("==== %s ====\n\n", __PRETTY_FUNCTION__); ezMiniSAT ez; - int a = ez.literal("a"); - int b = ez.literal("b"); - int c = ez.literal("c"); - int d = ez.literal("d"); + int a = ez.frozen_literal("a"); + int b = ez.frozen_literal("b"); + int c = ez.frozen_literal("c"); + int d = ez.frozen_literal("d"); std::vector abcd; abcd.push_back(a); @@ -441,13 +358,13 @@ void test_ordered() printf("==== %s ====\n\n", __PRETTY_FUNCTION__); ezMiniSAT ez; - int a = ez.literal("a"); - int b = ez.literal("b"); - int c = ez.literal("c"); + int a = ez.frozen_literal("a"); + int b = ez.frozen_literal("b"); + int c = ez.frozen_literal("c"); - int x = ez.literal("x"); - int y = ez.literal("y"); - int z = ez.literal("z"); + int x = ez.frozen_literal("x"); + int y = ez.frozen_literal("y"); + int z = ez.frozen_literal("z"); std::vector abc; abc.push_back(a); @@ -507,7 +424,6 @@ void test_ordered() int main() { test_simple(); - test_basic_operators(); test_xorshift32(); test_arith(); test_onehot(); From 51a615b26d95eddb39e7389d431c0ab7002d52bb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 May 2014 14:42:04 +0200 Subject: [PATCH 204/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 71 +++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index bf9b350f..7aa01424 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -789,11 +789,11 @@ extract -constports -ignore_parameters \ Unwrap in {\tt test2}: \hfil\begin{tikzpicture} +\node at (0,0) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf}}; +\node at (0,-4) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2e.pdf}}; \node at (1,-1.7) {\begin{lstlisting}[linewidth=5.5cm, frame=single, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] techmap -map macc_xilinx_unwrap_map.v ;; \end{lstlisting}}; -\node at (0,0) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2d.pdf}}; -\node at (0,-4) {\includegraphics[width=11cm,trim=1.5cm 1.5cm 1.5cm 1.5cm]{PRESENTATION_ExAdv/macc_xilinx_test2e.pdf}}; \draw[-latex] (4,-0.7) .. controls (5,-1.7) .. (4,-2.7); \end{tikzpicture} \end{frame} @@ -808,10 +808,67 @@ techmap -map macc_xilinx_unwrap_map.v ;; \subsectionpagesuffix \end{frame} -\subsubsection{TBD} +\subsubsection{Changing the design from Yosys} \begin{frame}{\subsubsecname} -TBD +Yosys commands can be used to change the design in memory. Examples of this are: + +\begin{itemize} +\item {\bf Changes in design hierarchy} \\ +Commands such as {\tt flatten} and {\tt submod} can be used to change the design hierarchy, i.e. +flatten the hierarchy or moving parts of a module to a submodule. This has applications in synthesis +scripts as well as in reverse engineering and analysis. + +\item {\bf Behavioral changes} \\ +Commands such as {\tt techmap} can be used to make behavioral changes to the design, for example +changing asynchonous resets to synchronous resets. This has applications in design space exploration +(evaluation of various architectures for one circuit). +\end{itemize} +\end{frame} + +\subsubsection{Example: Async reset to sync reset} + +\begin{frame}[t, fragile]{\subsubsecname} +The following techmap map file replaces all positive-edge async reset flip-flops with +positive-edge sync reset flip-flops. The code is taken from the example Yosys script +for ASIC synthesis of the Amber ARMv2 CPU. + +\begin{columns} +\column[t]{6cm} +\vbox to 0cm{ +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] +(* techmap_celltype = "$adff" *) +module adff2dff (CLK, ARST, D, Q); + + parameter WIDTH = 1; + parameter CLK_POLARITY = 1; + parameter ARST_POLARITY = 1; + parameter ARST_VALUE = 0; + + input CLK, ARST; + input [WIDTH-1:0] D; + output reg [WIDTH-1:0] Q; + + wire [1023:0] _TECHMAP_DO_ = "proc"; + + wire _TECHMAP_FAIL_ = !CLK_POLARITY || !ARST_POLARITY; +\end{lstlisting} +\vss} +\column[t]{4cm} +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] +// ..continued.. + + + always @(posedge CLK) + if (ARST) + Q <= ARST_VALUE; + else + <= D; + +endmodule +\end{lstlisting} +\end{columns} + \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -820,10 +877,8 @@ TBD \begin{frame}{\subsecname} \begin{itemize} -\item TBD -\item TBD -\item TBD -\item TBD +\item A lot can be achived in Yosys just with the standard set of commands. +\item The commands {\tt techmap} and {\tt extract} can be used to prototype many complex synthesis tasks. \end{itemize} \bigskip From bfd62268cc6a6115c540a0386c02301cd1ee2e22 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 9 May 2014 18:23:21 +0200 Subject: [PATCH 205/750] Updated ABC to 67c84cdd49e4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 69fbf522..54699e4d 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 2058c8ccea68 +ABCREV = 67c84cdd49e4 ABCPULL = 1 -include Makefile.conf From f69b5800c940557cafd20598b03d774dd6cf6f8d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 10 May 2014 16:22:56 +0200 Subject: [PATCH 206/750] fixed syntax error in dot file created by "show" command --- passes/cmds/show.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index bf37e5da..92fc5bd5 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -487,7 +487,7 @@ struct ShowWorker fprintf(f, "%s:e -> %s:w [%s, %s];\n", it.first.c_str(), it2.c_str(), nextColor(it.second.color).c_str(), widthLabel(it.second.bits).c_str()); } - fprintf(f, "};\n"); + fprintf(f, "}\n"); } ShowWorker(FILE *f, RTLIL::Design *design, std::vector &libs, uint32_t colorSeed, From 68c059565a3b75808e74eb481f14cb7f0c907f37 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 12 May 2014 12:45:47 +0200 Subject: [PATCH 207/750] Fixed bug in opt_reduce (see vloghammer issue_044) --- passes/opt/opt_reduce.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index fee8fb71..dfe21441 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -73,7 +73,10 @@ struct OptReduceWorker for (auto child_cell : drivers.find(chunk)) { if (child_cell->type == cell->type) { opt_reduce(cells, drivers, child_cell); - new_sig_a.append(child_cell->connections["\\A"]); + if (child_cell->connections["\\Y"].extract(0, 1) == chunk) + new_sig_a.append(child_cell->connections["\\A"]); + else + new_sig_a.append(RTLIL::State::S0); imported_children = true; } } From 684c85902d259a0db3ac5271b540549e98646306 Mon Sep 17 00:00:00 2001 From: Johann Glaser Date: Mon, 26 May 2014 17:13:41 +0200 Subject: [PATCH 208/750] be more verbose when techmap yielded processes --- passes/techmap/techmap.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 69ffb923..4c5a0feb 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -106,8 +106,12 @@ struct TechmapWorker if (tpl->memories.size() != 0) log_error("Technology map yielded memories -> this is not supported.\n"); - if (tpl->processes.size() != 0) + if (tpl->processes.size() != 0) { + log("Technology map yielded processes:\n"); + for (auto &it : tpl->processes) + log(" %s",RTLIL::id2cstr(it.first)); log_error("Technology map yielded processes -> this is not supported.\n"); + } // erase from namespace first for _TECHMAP_REPLACE_ to work module->cells.erase(cell->name); From 63dfbb18cfb34d72746565a3eb3ffbcd7451cdab Mon Sep 17 00:00:00 2001 From: Johann Glaser Date: Wed, 28 May 2014 16:50:13 +0200 Subject: [PATCH 209/750] new flags -ignore_miss_func and -ignore_miss_dir for read_liberty --- frontends/liberty/liberty.cc | 44 ++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 485d28ee..285491e0 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); From 278085fa01a9013051fbec842314cb6b5642e9bb Mon Sep 17 00:00:00 2001 From: Johann Glaser Date: Wed, 28 May 2014 18:05:38 +0200 Subject: [PATCH 210/750] added log_header to miter and expose pass, show cell type for exposed ports --- passes/sat/expose.cc | 8 +++++--- passes/sat/miter.cc | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 2ac7b35f..831a43aa 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -259,6 +259,8 @@ struct ExposePass : public Pass { bool flag_evert_dff = false; std::string sep = "."; + log_header("Executing EXPOSE pass (exposing internal signals as outputs).\n"); + size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -629,7 +631,7 @@ struct ExposePass : public Pass { w->port_input = true; add_new_wire(module, w); - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name)); + log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); RTLIL::SigSpec sig; if (cell->connections.count(p->name) != 0) @@ -654,7 +656,7 @@ struct ExposePass : public Pass { w->port_input = true; add_new_wire(module, w); - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name)); + log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); if (w->port_input) module->connections.push_back(RTLIL::SigSig(it.second, w)); @@ -667,7 +669,7 @@ struct ExposePass : public Pass { } for (auto &it : delete_cells) { - log("Removing cell: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it)); + log("Removing cell: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it), RTLIL::id2cstr(module->cells.at(it)->type)); delete module->cells.at(it); module->cells.erase(it); } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index db12cb57..6c8e2ff4 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -28,6 +28,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, bool flag_make_outcmp = false; bool flag_make_assert = false; + log_header("Executing MITER pass (creating miter circuit).\n"); + size_t argidx; for (argidx = 2; argidx < args.size(); argidx++) { @@ -102,6 +104,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, log_cmd_error("No matching port in gold module was found for %s!\n", it.second->name.c_str()); } + log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", RTLIL::id2cstr(miter_name), RTLIL::id2cstr(gold_name), RTLIL::id2cstr(gate_name)); + RTLIL::Module *miter_module = new RTLIL::Module; miter_module->name = miter_name; design->modules[miter_name] = miter_module; From d5497f770bf49b893c8a90879d325a73f4d13ee5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 29 May 2014 11:03:15 +0200 Subject: [PATCH 211/750] Updated ABC to rev fa4404b395f0 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 54699e4d..04bae3cf 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 67c84cdd49e4 +ABCREV = fa4404b395f0 ABCPULL = 1 -include Makefile.conf From 68c99bf7349cf56385ee803144dd7d8e219be8d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 1 Jun 2014 11:32:27 +0200 Subject: [PATCH 212/750] Fixed log messages in memory_dff --- passes/memory/memory_dff.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 2502a8b6..e8da6d64 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -111,6 +111,8 @@ static void handle_wr_cell(RTLIL::Module *module, RTLIL::Cell *cell) cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); log("merged $dff to cell.\n"); } + + log("no (compatible) $dff found.\n"); } static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) From 7020f7fc138ac9bad46f9f2b41150321f315f992 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 3 Jun 2014 09:23:31 +0200 Subject: [PATCH 213/750] added tee cmd --- passes/cmds/Makefile.inc | 1 + passes/cmds/tee.cc | 88 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 passes/cmds/tee.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 77cac2b4..3a4b2da7 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -15,5 +15,6 @@ OBJS += passes/cmds/copy.o OBJS += passes/cmds/splice.o OBJS += passes/cmds/scc.o OBJS += passes/cmds/log.o +OBJS += passes/cmds/tee.o OBJS += passes/cmds/connwrappers.o diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc new file mode 100644 index 00000000..dd959195 --- /dev/null +++ b/passes/cmds/tee.cc @@ -0,0 +1,88 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Johann Glaser + * + * 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/rtlil.h" +#include "kernel/log.h" + +struct TeePass : public Pass { + TeePass() : Pass("tee", "redirect command output to file") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" tee [-q] [-o logfile|-a logfile] cmd\n"); + log("\n"); + log("Execute the specified command, optionally writing the commands output to the\n"); + log("specified logfile(s).\n"); + log("\n"); + log(" -q\n"); + log(" Do not print output to the normal destination (console and/or log file)\n"); + log("\n"); + log(" -o logfile\n"); + log(" Write output to this file, truncate if exists.\n"); + log("\n"); + log(" -a logfile\n"); + log(" Write output to this file, append if exists.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + std::vector backup_log_files, files_to_close; + backup_log_files = log_files; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-q" && files_to_close.empty()) { + log_files.clear(); + continue; + } + if ((args[argidx] == "-o" || args[argidx] == "-a") && argidx+1 < args.size()) { + const char *open_mode = args[argidx] == "-o" ? "wt" : "at"; + FILE *f = fopen(args[++argidx].c_str(), open_mode); + if (f == NULL) { + for (auto cf : files_to_close) + fclose(cf); + log_cmd_error("Can't create file %s.\n", args[argidx].c_str()); + } + log_files.push_back(f); + files_to_close.push_back(f); + continue; + } + break; + } + + try { + std::vector new_args(args.begin() + argidx, args.end()); + Pass::call(design, new_args); + } catch (int ex) { + for (auto cf : files_to_close) + fclose(cf); + log_files = backup_log_files; + throw ex; + } + + for (auto cf : files_to_close) + fclose(cf); + log_files = backup_log_files; + } +} TeePass; + From f9c1cd5edba5acb4d9b9dd287c7265111cf22087 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 4 Jun 2014 09:10:50 +0200 Subject: [PATCH 214/750] Improved error message for options after front-end filename arguments --- frontends/verilog/verilog_frontend.cc | 2 +- kernel/register.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 8e9efa17..10821458 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"); diff --git a/kernel/register.cc b/kernel/register.cc index 5d882ab4..8da5a725 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -270,6 +270,10 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vector Date: Fri, 6 Jun 2014 17:40:04 +0200 Subject: [PATCH 215/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f2f2d0e6..105645f9 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 72a2a460..8f9c3534 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 226a2670..5300d1b2 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 ed9be692..a12dcf14 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); From ab54ce17c82e55cb26bf5c0dd7512decbd941b12 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 17:40:45 +0200 Subject: [PATCH 216/750] improved ast simplify of const functions --- frontends/ast/simplify.cc | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a20aacff..5f40b60a 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); From c82db39935e969ff95b0728dbb92231f0e9e9891 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 17:47:20 +0200 Subject: [PATCH 217/750] Added tests/simple/repwhile.v --- tests/simple/repwhile.v | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/simple/repwhile.v diff --git a/tests/simple/repwhile.v b/tests/simple/repwhile.v new file mode 100644 index 00000000..8c5b4b37 --- /dev/null +++ b/tests/simple/repwhile.v @@ -0,0 +1,20 @@ +module test001(output [63:0] y); + function [7:0] mylog2; + input [31:0] value; + begin + mylog2 = 0; + while (value > 0) begin + value = value >> 1; + mylog2 = mylog2 + 1; + end + end + endfunction + + genvar i; + generate + for (i = 0; i < 64; i = i+1) begin + localparam tmp = mylog2(i); + assign y[i] = tmp; + end + endgenerate +endmodule From 5c10d2ee364c8807d10069ba7be3d1da3d252fa1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 21:29:23 +0200 Subject: [PATCH 218/750] fix functions with no block (but single statement, loop, etc.) --- frontends/ast/simplify.cc | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5f40b60a..47ea880c 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); From 76da2fe172ed6b0822a9e4a8cf9483ef7c8f5f40 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 22:55:02 +0200 Subject: [PATCH 219/750] 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(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8f9c3534..6c5a0eae 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 c3025913..2efdee10 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 47ea880c..71e7cbc6 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()); From 5281562d0e9468c584e6db6f30908e3155a76ad2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 23:05:01 +0200 Subject: [PATCH 220/750] made the generate..endgenrate keywords optional --- frontends/verilog/parser.y | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index a12dcf14..42a8f91c 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(); }; From 7c8a7b2131aa672d04ee0ed641f3e6b120f3ec49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 00:02:05 +0200 Subject: [PATCH 221/750] 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(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6c5a0eae..3e69e3bc 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 2efdee10..9273636f 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 71e7cbc6..8a4d42e1 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; } From 0b1ce63a19025f73fe4d2a54253134ea9a4de625 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 10:47:53 +0200 Subject: [PATCH 222/750] Added support for repeat stmt in const functions --- frontends/ast/simplify.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8a4d42e1..e5e8980a 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(); From e275e8eef9ae47670075bd73a671f3acd3c0ca52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 11:48:50 +0200 Subject: [PATCH 223/750] 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 +++++++ kernel/rtlil.cc | 3 ++- passes/hierarchy/hierarchy.cc | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 105645f9..0780f7b5 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 3e69e3bc..802bf98f 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 e5e8980a..fc040baa 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 42a8f91c..f422258c 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: diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1168102a..028cd6d8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -740,7 +740,8 @@ void RTLIL::Module::check() for (auto &it2 : it.second->parameters) { assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); } - if (it.second->type[0] == '$' && it.second->type.substr(0, 3) != "$__" && it.second->type.substr(0, 8) != "$paramod" && it.second->type.substr(0, 9) != "$verific$") { + if (it.second->type[0] == '$' && it.second->type.substr(0, 3) != "$__" && it.second->type.substr(0, 8) != "$paramod" && + it.second->type.substr(0, 9) != "$verific$" && it.second->type.substr(0, 7) != "$array:") { InternalCellChecker checker(this, it.second); checker.check(); } diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 526d1729..6890cb9e 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -137,12 +137,23 @@ static void generate(RTLIL::Design *design, const std::vector &cell static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, std::vector &libdirs) { bool did_something = false; + std::map> array_cells; std::string filename; for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; + if (cell->type.substr(0, 7) == "$array:") { + int pos_idx = cell->type.find_first_of(':'); + int pos_num = cell->type.find_first_of(':', pos_idx + 1); + int pos_type = cell->type.find_first_of(':', pos_num + 1); + int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str()); + int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str()); + array_cells[cell] = std::pair(idx, num); + cell->type = cell->type.substr(pos_type + 1); + } + if (design->modules.count(cell->type) == 0) { if (design->modules.count("$abstract" + cell->type)) @@ -198,6 +209,29 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla did_something = true; } + for (auto &it : array_cells) + { + RTLIL::Cell *cell = it.first; + int idx = it.second.first, num = it.second.second; + + if (design->modules.count(cell->type) == 0) + log_error("Array cell `%s.%s' of unkown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + + RTLIL::Module *mod = design->modules[cell->type]; + + for (auto &conn : cell->connections) { + int conn_size = conn.second.width; + if (mod->wires.count(conn.first) == 0) + log_error("Array cell `%s.%s' connects to unkown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); + int port_size = mod->wires.at(conn.first)->width; + if (conn_size == port_size) + continue; + if (conn_size != port_size*num) + log_error("Array cell `%s.%s' has invalid port vs. signal size for port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); + conn.second = conn.second.extract(port_size*idx, port_size); + } + } + return did_something; } From 744e51846776a304828301914f5cd74fb7d0a5ca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 12:17:06 +0200 Subject: [PATCH 224/750] fixed cell array handling of positional arguments --- passes/hierarchy/hierarchy.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 6890cb9e..d8a23c72 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -221,9 +221,18 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla for (auto &conn : cell->connections) { int conn_size = conn.second.width; - if (mod->wires.count(conn.first) == 0) + std::string portname = conn.first; + if (portname.substr(0, 1) == "$") { + int port_id = atoi(portname.substr(1).c_str()); + for (auto &wire_it : mod->wires) + if (wire_it.second->port_id == port_id) { + portname = wire_it.first; + break; + } + } + if (mod->wires.count(portname) == 0) log_error("Array cell `%s.%s' connects to unkown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); - int port_size = mod->wires.at(conn.first)->width; + int port_size = mod->wires.at(portname)->width; if (conn_size == port_size) continue; if (conn_size != port_size*num) From 3af7c69d1e3c17d7aaa5d3a7da9f8a2ae12ed9bf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 12:18:00 +0200 Subject: [PATCH 225/750] added tests for new verilog features --- tests/simple/arraycells.v | 15 +++++++++++++++ tests/simple/repwhile.v | 30 +++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 tests/simple/arraycells.v diff --git a/tests/simple/arraycells.v b/tests/simple/arraycells.v new file mode 100644 index 00000000..ad509800 --- /dev/null +++ b/tests/simple/arraycells.v @@ -0,0 +1,15 @@ + +module test001(a, b, c, y); + input a; + input [31:0] b, c; + input [31:0] y; + + aoi12 p [31:0] (a, b, c, y); +endmodule + +module aoi12(a, b, c, y); + input a, b, c; + output y; + assign y = ~((a & b) | c); +endmodule + diff --git a/tests/simple/repwhile.v b/tests/simple/repwhile.v index 8c5b4b37..cde37c56 100644 --- a/tests/simple/repwhile.v +++ b/tests/simple/repwhile.v @@ -1,4 +1,5 @@ -module test001(output [63:0] y); +module test001(input [5:0] a, output [7:0] y, output [31:0] x); + function [7:0] mylog2; input [31:0] value; begin @@ -10,11 +11,26 @@ module test001(output [63:0] y); end endfunction - genvar i; - generate - for (i = 0; i < 64; i = i+1) begin - localparam tmp = mylog2(i); - assign y[i] = tmp; + function [31:0] myexp2; + input [7:0] value; + begin + myexp2 = 1; + repeat (value) + myexp2 = myexp2 << 1; end - endgenerate + endfunction + + reg [7:0] y_table [63:0]; + reg [31:0] x_table [63:0]; + + integer i; + initial begin + for (i = 0; i < 64; i = i+1) begin + y_table[i] <= mylog2(i); + x_table[i] <= myexp2(i); + end + end + + assign y = y_table[a]; + assign x = x_table[a]; endmodule From 94e9ee6baba2952c8dd055dbab45fb3c9c64121e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Jun 2014 10:12:39 +0200 Subject: [PATCH 226/750] Updated ABC to 7600ffb9340c --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 04bae3cf..38e404ce 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = fa4404b395f0 +ABCREV = 7600ffb9340c ABCPULL = 1 -include Makefile.conf From ca125bf41b6de9251f6396fd06ba7a50c7eb48c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Jun 2014 15:28:36 +0200 Subject: [PATCH 227/750] Tagging Yosys 0.3.0 --- CHANGELOG | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- Makefile | 2 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c014f458..77d7551b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,10 +3,54 @@ List of changes and major improvements between releases ======================================================= -Yosys 0.2.0 .. Yoys 0.2.0+ +Yosys 0.2.0 .. Yoys 0.3.0 -------------------------- - ... TBD ... + * Driver program and overall behavior: + - Added "design -push" and "design -pop" + - Added "tee" command for redirecting log output + + * Changes in the internal cell library: + - Added $dlatchsr and $_DLATCHSR_???_ cell types + + * Improvements in Verilog frontend: + - Improved support for const functions (case, always, repeat) + - The generate..endgenerate keywords are now optional + - Added support for arrays of module instances + - Added support for "`default_nettype" directive + - Added support for "`line" directive + + * Other front- and back-ends: + - Various changes to "write_blif" options + - Various improvements in EDIF backend + - Added "vhdl2verilog" pseudo-front-end + - Added "verific" pseudo-front-end + + * Improvements in technology mapping: + - Added support for recursive techmap + - Added CONSTMSK and CONSTVAL features to techmap + - Added _TECHMAP_CONNMAP_*_ feature to techmap + - Added _TECHMAP_REPLACE_ feature to techmap + - Added "connwrappers" command for wrap-extract-unwrap method + - Added "extract -map %" feature + - Added "extract -ignore_param ..." and "extract -ignore_parameters" + - Added "techmap -max_iter" option + + * Improvements to "eval" and "sat" framework: + - Now include a copy of Minisat (with build fixes applied) + - Switched to Minisat::SimpSolver as SAT back-end + - Added "sat -dump_vcd" feature + - Added "sat -dump_cnf" feature + - Added "sat -initsteps " feature + - Added "freduce -stop " feature + - Added "fredure -dump " feature + + * Integration with ABC: + - Updated ABC rev to 7600ffb9340c + + * Improvements in the internal APIs: + - Added RTLIL::Module::add... helper methods + - Various build fixes for OSX (Darwin) and OpenBSD Yosys 0.1.0 .. Yoys 0.2.0 diff --git a/Makefile b/Makefile index 38e404ce..c0c6fe3f 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ else LDLIBS += -lrt endif -YOSYS_VER := 0.2.0+ +YOSYS_VER := 0.3.0 GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o From 9a6cd64fc2ca46c9aed1bd03b6898c7734420c53 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Jun 2014 15:31:27 +0200 Subject: [PATCH 228/750] Now we are in Yoys 0.3.0+ development --- CHANGELOG | 6 ++++++ Makefile | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 77d7551b..35695729 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,12 @@ List of changes and major improvements between releases ======================================================= +Yosys 0.3.0 .. Yoys 0.3.0+ +-------------------------- + + ... TBD ... + + Yosys 0.2.0 .. Yoys 0.3.0 -------------------------- diff --git a/Makefile b/Makefile index c0c6fe3f..a84215b2 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ else LDLIBS += -lrt endif -YOSYS_VER := 0.3.0 +YOSYS_VER := 0.3.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o From 482d9208aa9dacb7afe21f08c882d4881581013a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jun 2014 11:54:20 +0200 Subject: [PATCH 229/750] Added read_verilog -sv options, added support for bit, logic, allways_ff, always_comb, and always_latch --- README | 16 +++++++++++++--- frontends/verilog/lexer.l | 17 ++++++++++++++++- frontends/verilog/parser.y | 10 ++++++++-- frontends/verilog/verilog_frontend.cc | 10 ++++++++++ frontends/verilog/verilog_frontend.h | 3 +++ tests/sat/asserts.ys | 2 +- tests/sat/asserts_seq.ys | 2 +- 7 files changed, 52 insertions(+), 8 deletions(-) diff --git a/README b/README index d021c886..05628a8e 100644 --- a/README +++ b/README @@ -263,14 +263,24 @@ Verilog Attributes and non-standard features for everything that comes after the {* ... *} statement. (Reset by adding an empty {* *} statement.) +- Sized constants (the syntax 's?[bodh]) support constant + expressions as . If the expresion is not a simple identifier, it + must be put in parentheses. Examples: WIDTH'd42, (4+2)'b101010 + + +Supported features from SystemVerilog +===================================== + +When read_verilog is called with -sv, it accepts some language features +from SystemVerilog: + - The "assert" statement from SystemVerilog is supported in its most basic form. In module context: "assert property ();" and within an always block: "assert();". It is transformed to a $assert cell that is supported by the "sat" and "write_btor" commands. -- Sized constants (the syntax 's?[bodh]) support constant - expressions as . If the expresion is not a simple identifier, it - must be put in parentheses. Examples: WIDTH'd42, (4+2)'b101010 +- The keywords "always_comb", "always_ff" and "always_latch", "logic" and + "bit" are supported. Roadmap / Large-scale TODOs diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 5300d1b2..8f4b4991 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 f422258c..cce8a8c4 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 10821458..437fc3ec 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 99b2164e..6d01a153 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 diff --git a/tests/sat/asserts.ys b/tests/sat/asserts.ys index de5e7c9a..d8f99492 100644 --- a/tests/sat/asserts.ys +++ b/tests/sat/asserts.ys @@ -1,3 +1,3 @@ -read_verilog asserts.v +read_verilog -sv asserts.v hierarchy; proc; opt sat -verify -seq 1 -set-at 1 rst 1 -tempinduct -prove-asserts diff --git a/tests/sat/asserts_seq.ys b/tests/sat/asserts_seq.ys index c622ef61..e9768664 100644 --- a/tests/sat/asserts_seq.ys +++ b/tests/sat/asserts_seq.ys @@ -1,4 +1,4 @@ -read_verilog asserts_seq.v +read_verilog -sv asserts_seq.v hierarchy; proc; opt sat -verify -prove-asserts -tempinduct -seq 1 test_001 From 7ef0da32cdcddb50de8ba8acf0c6421fe5732c55 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jun 2014 11:29:23 +0200 Subject: [PATCH 230/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0780f7b5..1ce7efc8 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 802bf98f..aeb56e35 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 8f4b4991..ed304572 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 cce8a8c4..e51712b3 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; From 9dd16fa41c01c8da2e4905184cce0391a7547fa3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 07:44:19 +0200 Subject: [PATCH 231/750] Added real->int convertion in ast genrtlil --- frontends/ast/genrtlil.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9273636f..5b43f57f 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 From 442a8e2875eab679ed3b31aee3d9725b87dbf4fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 08:51:22 +0200 Subject: [PATCH 232/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 1ce7efc8..3af08b9d 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 aeb56e35..95f0f142 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 fc040baa..7e4c265b 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; } From fc7b6d172a67965c89d84696e5f2cf1218855ea5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 11:27:05 +0200 Subject: [PATCH 233/750] Implemented more real arithmetic --- frontends/ast/simplify.cc | 97 ++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7e4c265b..77bab6b0 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); From 9bd7d5c46856f25fd7befcdfe20198fd8eb59ccd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 12:00:47 +0200 Subject: [PATCH 234/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3af08b9d..f3cf8fa7 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 77bab6b0..a5c4d023 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 ed304572..0839f5cf 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 e51712b3..57defd56 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++) From 406f86a91ec0ed024037e27d1cbf2a1bc73777d9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 12:01:17 +0200 Subject: [PATCH 235/750] Added realexpr.v test case --- tests/simple/realexpr.v | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/simple/realexpr.v diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v new file mode 100644 index 00000000..47f81214 --- /dev/null +++ b/tests/simple/realexpr.v @@ -0,0 +1,13 @@ +module demo_001(y1, y2, y3, y4); + output [7:0] y1, y2, y3, y4; + + localparam [7:0] p1 = 123.45; + localparam real p2 = 123.45; + localparam real p3 = 123; + localparam p4 = 123.45; + + assign y1 = p1 + 0.2; + assign y2 = p2 + 0.2; + assign y3 = p3 + 0.2; + assign y4 = p4 + 0.2; +endmodule From f3b4a9dd2466d243fdb1b4ebf8c5e1e0d05d21af Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 13:36:23 +0200 Subject: [PATCH 236/750] Added support for math functions --- frontends/ast/simplify.cc | 70 +++++++++++++++++++++++++++++++++++++++ tests/simple/realexpr.v | 57 +++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a5c4d023..89dc8ef7 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); } diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 47f81214..2b63ca6f 100644 --- a/tests/simple/realexpr.v +++ b/tests/simple/realexpr.v @@ -1,3 +1,4 @@ + module demo_001(y1, y2, y3, y4); output [7:0] y1, y2, y3, y4; @@ -11,3 +12,59 @@ module demo_001(y1, y2, y3, y4); assign y3 = p3 + 0.2; assign y4 = p4 + 0.2; endmodule + +module demo_002(s, a, y); + input [4:0] s; + input [3:0] a; + output [7:0] y; + + reg [7:0] data [21*16-1:0]; + integer i; + + initial begin + for (i = 0; i < 16; i = i+1) begin + data[ 0*16 + i] = 128 + 64 * $ln (i*0.2 - 0.8); + data[ 1*16 + i] = 128 + 64 * $log10 (i*0.2 - 0.8); + data[ 2*16 + i] = 128 + 64 * $exp (i*0.2 - 0.8); + data[ 3*16 + i] = 128 + 64 * $sqrt (i*0.2 - 0.8); + data[ 4*16 + i] = 128 + 64 * $floor (i*0.2 - 0.8); + data[ 5*16 + i] = 128 + 64 * $ceil (i*0.2 - 0.8); + data[ 6*16 + i] = 128 + 64 * $sin (i*0.2 - 0.8); + data[ 7*16 + i] = 128 + 64 * $cos (i*0.2 - 0.8); + data[ 8*16 + i] = 128 + 64 * $tan (i*0.2 - 0.8); + data[ 9*16 + i] = 128 + 64 * $asin (i*0.2 - 0.8); + data[10*16 + i] = 128 + 64 * $acos (i*0.2 - 0.8); + data[11*16 + i] = 128 + 64 * $atan (i*0.2 - 0.8); + data[12*16 + i] = 128 + 64 * $sinh (i*0.2 - 0.8); + data[13*16 + i] = 128 + 64 * $cosh (i*0.2 - 0.8); + data[14*16 + i] = 128 + 64 * $tanh (i*0.2 - 0.8); + data[15*16 + i] = 128 + 64 * $asinh (i*0.2 - 0.8); + data[16*16 + i] = 128 + 64 * $acosh (i*0.2 - 0.8); + data[17*16 + i] = 128 + 64 * $atanh (i*0.2 - 0.8); + end + end + + assign y = s < 18 ? data[s*16 + a] : 0; +endmodule + +module demo_003(s, a, b, y); + input [1:0] s; + input [3:0] a; + input [3:0] b; + output [7:0] y; + + reg [7:0] data [3*16*16-1:0]; + integer i, j; + + initial begin + for (i = 0; i < 16; i = i+1) + for (j = 0; j < 16; j = j+1) begin + data[0*256 + i*16 + j] = 128 + 64 * $pow (i*0.2 - 0.8, j*0.2 - 0.8); + data[1*256 + i*16 + j] = 128 + 64 * $atan2 (i*0.2 - 0.8, j*0.2 - 0.8); + data[2*256 + i*16 + j] = 128 + 64 * $hypot (i*0.2 - 0.8, j*0.2 - 0.8); + end + end + + assign y = s < 3 ? data[s*256 + a*16 + b] : 0; +endmodule + From 22a998903b14b93180b98fe71129160e27793e38 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 16:19:32 +0200 Subject: [PATCH 237/750] Added %D and %c select commands --- passes/cmds/select.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 59f936b0..38d43f8d 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -595,6 +595,13 @@ static void select_stmt(RTLIL::Design *design, std::string arg) select_op_diff(design, work_stack[work_stack.size()-2], work_stack[work_stack.size()-1]); work_stack.pop_back(); } else + if (arg == "%D") { + if (work_stack.size() < 2) + log_cmd_error("Must have at least two elements on the stack for operator %%d.\n"); + select_op_diff(design, work_stack[work_stack.size()-1], work_stack[work_stack.size()-2]); + work_stack[work_stack.size()-2] = work_stack[work_stack.size()-1]; + work_stack.pop_back(); + } else if (arg == "%i") { if (work_stack.size() < 2) log_cmd_error("Must have at least two elements on the stack for operator %%i.\n"); @@ -606,14 +613,19 @@ static void select_stmt(RTLIL::Design *design, std::string arg) log_cmd_error("Must have at least one element on the stack for operator %%s.\n"); select_op_submod(design, work_stack[work_stack.size()-1]); } else + if (arg == "%c") { + if (work_stack.size() < 1) + log_cmd_error("Must have at least one element on the stack for operator %%c.\n"); + work_stack.push_back(work_stack.back()); + } else if (arg == "%m") { if (work_stack.size() < 1) - log_cmd_error("Must have at least one element on the stack for operator %%s.\n"); + log_cmd_error("Must have at least one element on the stack for operator %%m.\n"); select_op_fullmod(design, work_stack[work_stack.size()-1]); } else if (arg == "%a") { if (work_stack.size() < 1) - log_cmd_error("Must have at least one element on the stack for operator %%s.\n"); + log_cmd_error("Must have at least one element on the stack for operator %%a.\n"); select_op_alias(design, work_stack[work_stack.size()-1]); } else if (arg == "%x" || (arg.size() > 2 && arg.substr(0, 2) == "%x" && (arg[2] == ':' || arg[2] == '*' || arg[2] == '.' || ('0' <= arg[2] && arg[2] <= '9')))) { @@ -958,6 +970,12 @@ struct SelectPass : public Pass { log(" %%d\n"); log(" pop the top set from the stack and subtract it from the new top\n"); log("\n"); + log(" %%D\n"); + log(" like %%d but swap the roles of two top sets on the stack\n"); + log("\n"); + log(" %%c\n"); + log(" create a copy of the top set rom the stack and push it\n"); + log("\n"); log(" %%x[|*][.][:[:..]]\n"); log(" expand top set num times according to the specified rules.\n"); log(" (i.e. select all cells connected to selected wires and select all\n"); From 1a487303a081849bd7561772641f90126dcce24e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 16:42:30 +0200 Subject: [PATCH 238/750] Progress in presentation --- manual/PRESENTATION_ExOth.tex | 66 ++++++++++++++++++++++++-- manual/PRESENTATION_ExOth/.gitignore | 1 + manual/PRESENTATION_ExOth/Makefile | 8 ++++ manual/PRESENTATION_ExOth/scrambler.v | 14 ++++++ manual/PRESENTATION_ExOth/scrambler.ys | 23 +++++++++ 5 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 manual/PRESENTATION_ExOth/.gitignore create mode 100644 manual/PRESENTATION_ExOth/Makefile create mode 100644 manual/PRESENTATION_ExOth/scrambler.v create mode 100644 manual/PRESENTATION_ExOth/scrambler.ys diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex index 13ec3d19..64c4af72 100644 --- a/manual/PRESENTATION_ExOth.tex +++ b/manual/PRESENTATION_ExOth.tex @@ -23,10 +23,70 @@ This section contains 3 subsections: \subsectionpagesuffix \end{frame} -\subsubsection{TBD} +\begin{frame}{\subsecname} +Yosys can also be used to investigate designs (or netlists created +from other tools). -\begin{frame}{\subsubsecname} -TBD +\begin{itemize} +\item +The selection mechanism (see slides ``Using Selections''), especially pattern such +as {\tt \%ci} and {\tt \%co}, can be used to figure out how parts of the design +are connected. + +\item +Commands such as {\tt submod}, {\tt expose}, {\tt splice}, \dots can be used +to transform the design into an equivialent design that is easier to analyse. + +\item +Commands such as {\tt eval} and {\tt sat} can be used to investigate the +behavior of the circuit. +\end{itemize} +\end{frame} + +\begin{frame}[t, fragile]{Example: Reorganizing a module} +\begin{columns} +\column[t]{4cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExOth/scrambler.v} +\column[t]{7cm} +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] +read_verilog scrambler.v + +hierarchy; proc;; + +cd scrambler +submod -name xorshift32 xs %c %ci %D \ + %c %ci:+[D] %D %ci*:-$dff \ + xs %co %ci %d +\end{lstlisting} +\end{columns} + +\hfil\includegraphics[width=11cm,trim=0 0cm 0 1.5cm]{PRESENTATION_ExOth/scrambler_p01.pdf} + +\hfil\includegraphics[width=11cm,trim=0 0cm 0 2cm]{PRESENTATION_ExOth/scrambler_p02.pdf} +\end{frame} + +\begin{frame}[t, fragile]{Example: Analysis of circuit behavior} +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] +> read_verilog scrambler.v +> hierarchy; proc;; cd scrambler +> submod -name xorshift32 xs %c %ci %D %c %ci:+[D] %D %ci*:-$dff xs %co %ci %d + +> cd xorshift32 +> rename n2 in +> rename n1 out + +> eval -set in 1 -show out +Eval result: \out = 270369. + +> eval -set in 270369 -show out +Eval result: \out = 67634689. + +> sat -set out 632435482 +Signal Name Dec Hex Bin +-------------------- ---------- ---------- ------------------------------------- +\in 745495504 2c6f5bd0 00101100011011110101101111010000 +\out 632435482 25b2331a 00100101101100100011001100011010 +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/manual/PRESENTATION_ExOth/.gitignore b/manual/PRESENTATION_ExOth/.gitignore new file mode 100644 index 00000000..cf658897 --- /dev/null +++ b/manual/PRESENTATION_ExOth/.gitignore @@ -0,0 +1 @@ +*.dot diff --git a/manual/PRESENTATION_ExOth/Makefile b/manual/PRESENTATION_ExOth/Makefile new file mode 100644 index 00000000..a12beada --- /dev/null +++ b/manual/PRESENTATION_ExOth/Makefile @@ -0,0 +1,8 @@ + +all: scrambler_p01.pdf scrambler_p02.pdf + +scrambler_p01.pdf: scrambler.ys scrambler.v + ../../yosys scrambler.ys + +scrambler_p02.pdf: scrambler_p01.pdf + diff --git a/manual/PRESENTATION_ExOth/scrambler.v b/manual/PRESENTATION_ExOth/scrambler.v new file mode 100644 index 00000000..d4c1fa2b --- /dev/null +++ b/manual/PRESENTATION_ExOth/scrambler.v @@ -0,0 +1,14 @@ +module scrambler( + input clk, rst, in_bit, + output reg out_bit +); + reg [31:0] xs; + always @(posedge clk) begin + if (rst) + xs = 1; + xs = xs ^ (xs << 13); + xs = xs ^ (xs >> 17); + xs = xs ^ (xs << 5); + out_bit <= in_bit ^ xs[0]; + end +endmodule diff --git a/manual/PRESENTATION_ExOth/scrambler.ys b/manual/PRESENTATION_ExOth/scrambler.ys new file mode 100644 index 00000000..2ef14c56 --- /dev/null +++ b/manual/PRESENTATION_ExOth/scrambler.ys @@ -0,0 +1,23 @@ + +read_verilog scrambler.v + +hierarchy; proc;; + +cd scrambler +submod -name xorshift32 xs %c %ci %D %c %ci:+[D] %D %ci*:-$dff xs %co %ci %d +cd .. + +show -prefix scrambler_p01 -format pdf -notitle scrambler +show -prefix scrambler_p02 -format pdf -notitle xorshift32 + +echo on + +cd xorshift32 +rename n2 in +rename n1 out + +eval -set in 1 -show out +eval -set in 270369 -show out + +sat -set out 632435482 + From ebe2d733302fea50b75d3dd43d1a115e43dcb523 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 19:24:01 +0200 Subject: [PATCH 239/750] added first draft of real math testcase generator --- tests/realmath/generate.py | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/realmath/generate.py diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py new file mode 100644 index 00000000..c7653321 --- /dev/null +++ b/tests/realmath/generate.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +from __future__ import division +from __future__ import print_function + +import sys +import random +from contextlib import contextmanager + +@contextmanager +def redirect_stdout(new_target): + old_target, sys.stdout = sys.stdout, new_target + try: + yield new_target + finally: + sys.stdout = old_target + +def random_expression(depth = 3, maxparam = 0): + def recursion(): + return random_expression(depth = depth-1, maxparam = maxparam) + if depth == 0: + if maxparam != 0 and random.randint(0, 1) != 0: + return 'p%02d' % random.randint(0, maxparam-1) + return random.choice([ '%e', '%f', '%g' ]) % random.uniform(-2, +2) + if random.randint(0, 4) == 0: + return recursion() + random.choice([ ' < ', ' <= ', ' == ', ' != ', ' >= ', ' > ' ]) + recursion() + ' ? ' + recursion() + ' : ' + recursion() + op_prefix = [ '+(', '-(' ] + op_infix = [ ' + ', ' - ', ' * ', ' / ' ] + op_func1 = [ '$ln', '$log10', '$exp', '$sqrt', '$floor', '$ceil', '$sin', '$cos', '$tan', '$asin', '$acos', '$atan', '$sinh', '$cosh', '$tanh', '$asinh', '$acosh', '$atanh' ] + op_func2 = [ '$pow', '$atan2', '$hypot' ] + op = random.choice(op_prefix + op_infix + op_func1 + op_func2) + if op in op_prefix: + return op + recursion() + ')' + if op in op_infix: + return '(' + recursion() + op + recursion() + ')' + if op in op_func1: + return op + '(' + recursion() + ')' + if op in op_func2: + return op + '(' + recursion() + ', ' + recursion() + ')' + raise + +for i in range(3): + with file('uut_%05d.v' % i, 'w') as f, redirect_stdout(f): + print('module uut_%05d(output [63:0] %s);\n' % (i, ', '.join(['y%02d' % i for i in range(100)]))) + for i in range(30): + print('localparam p%02d = %s;' % (i, random_expression())) + for i in range(30, 60): + print('localparam p%02d = %s;' % (i, random_expression(maxparam = 30))) + for i in range(100): + print('assign y%02d = %s;' % (i, random_expression(maxparam = 60))) + print('endmodule') + From d5765b5e14319c20a62a20f470e8ec5dc48d0010 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 19:33:58 +0200 Subject: [PATCH 240/750] Fixed relational operators for const real expressions --- frontends/ast/simplify.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 89dc8ef7..61bc03b9 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(); } } From 39eb347c67056f9b56ecfdab1704362d4cd276e1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 19:56:22 +0200 Subject: [PATCH 241/750] progress in realmath test bench --- tests/realmath/generate.py | 30 ++++++++++++++++++++++++++---- tests/realmath/run-test.sh | 19 +++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100755 tests/realmath/run-test.sh diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index c7653321..f280e1c3 100644 --- a/tests/realmath/generate.py +++ b/tests/realmath/generate.py @@ -39,14 +39,36 @@ def random_expression(depth = 3, maxparam = 0): return op + '(' + recursion() + ', ' + recursion() + ')' raise -for i in range(3): - with file('uut_%05d.v' % i, 'w') as f, redirect_stdout(f): - print('module uut_%05d(output [63:0] %s);\n' % (i, ', '.join(['y%02d' % i for i in range(100)]))) +for idx in range(100): + with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): + print('module uut_%05d(output [63:0] %s);\n' % (idx, ', '.join(['y%02d' % i for i in range(100)]))) for i in range(30): print('localparam p%02d = %s;' % (i, random_expression())) for i in range(30, 60): print('localparam p%02d = %s;' % (i, random_expression(maxparam = 30))) for i in range(100): - print('assign y%02d = %s;' % (i, random_expression(maxparam = 60))) + print('assign y%02d = 65536 * (%s);' % (i, random_expression(maxparam = 60))) + print('endmodule') + with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): + print('read_verilog uut_%05d.v' % idx) + print('rename uut_%05d uut_%05d_syn' % (idx, idx)) + print('write_verilog uut_%05d_syn.v' % idx) + with file('temp/uut_%05d_tb.v' % idx, 'w') as f, redirect_stdout(f): + print('module uut_%05d_tb;\n' % idx) + print('wire [63:0] %s;' % (', '.join(['r%02d' % i for i in range(100)]))) + print('wire [63:0] %s;' % (', '.join(['s%02d' % i for i in range(100)]))) + print('uut_%05d ref(%s);' % (idx, ', '.join(['r%02d' % i for i in range(100)]))) + print('uut_%05d_syn syn(%s);' % (idx, ', '.join(['s%02d' % i for i in range(100)]))) + print('task compare_ref_syn;') + print(' input [7:0] i;') + print(' input [63:0] r, s;') + print(' begin') + print(' $display("%d: %b %b", i, r, s);') + print(' end') + print('endtask') + print('initial begin #1;') + for i in range(100): + print(' compare_ref_syn(%2d, r%02d, s%02d);' % (i, i, i)) + print('end') print('endmodule') diff --git a/tests/realmath/run-test.sh b/tests/realmath/run-test.sh new file mode 100755 index 00000000..9568cdd6 --- /dev/null +++ b/tests/realmath/run-test.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +rm -rf temp +mkdir -p temp +echo "generating tests.." +python generate.py + +cd temp +echo "running tests.." +for ((i = 0; i < 100; i++)); do + echo -n "[$i]" + idx=$( printf "%05d" $i ) + ../../../yosys -q uut_${idx}.ys + iverilog -o uut_${idx}_tb uut_${idx}_tb.v uut_${idx}.v uut_${idx}_syn.v + ./uut_${idx}_tb > uut_${idx}.log +done +echo + From 149fe83a8dbe37fecc16326163bbc40400147a9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 20:38:05 +0200 Subject: [PATCH 242/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f3cf8fa7..25ea3a82 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 95f0f142..74a476b5 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 5b43f57f..8a57a0ee 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 61bc03b9..ed5ee172 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); From 11d2add1b9984a9dabe02e5073e09ca497024dd8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 20:38:40 +0200 Subject: [PATCH 243/750] improved realmath test bench --- tests/realmath/generate.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index f280e1c3..af7648b8 100644 --- a/tests/realmath/generate.py +++ b/tests/realmath/generate.py @@ -63,7 +63,10 @@ for idx in range(100): print(' input [7:0] i;') print(' input [63:0] r, s;') print(' begin') - print(' $display("%d: %b %b", i, r, s);') + print(' if (-3 < $signed(r-s) && $signed(r-s) < +3)') + print(' $display("%d: %b %b", i, r, s);') + print(' else') + print(' $display("%d: %b %b %s", i, r, s, r !== s ? "TRIG" : "");') print(' end') print('endtask') print('initial begin #1;') From 48dc6ab98dbd74bd7eb00f14b4bd8429531166f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:38:31 +0200 Subject: [PATCH 244/750] Improved AstNode::asReal for large integers --- frontends/ast/ast.cc | 21 ++++++++++++--------- frontends/ast/simplify.cc | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 25ea3a82..cc7f442b 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 ed5ee172..80fd28d5 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; From 7f57bc838517a5660beaf0645d7bb4cc6ed71ce9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:48:17 +0200 Subject: [PATCH 245/750] Improved parsing of large integer constants --- frontends/verilog/const2ast.cc | 39 ++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index c95ce5dc..8491a6b4 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); } From 656685fa31b54cebf0210518d3cac8aa496dddd7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:48:41 +0200 Subject: [PATCH 246/750] Improved realmath test bench --- tests/realmath/generate.py | 16 ++++++++++++---- tests/realmath/run-test.sh | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index af7648b8..58cedf02 100644 --- a/tests/realmath/generate.py +++ b/tests/realmath/generate.py @@ -62,11 +62,19 @@ for idx in range(100): print('task compare_ref_syn;') print(' input [7:0] i;') print(' input [63:0] r, s;') + print(' reg [64*8-1:0] buffer;') + print(' integer j;') print(' begin') - print(' if (-3 < $signed(r-s) && $signed(r-s) < +3)') - print(' $display("%d: %b %b", i, r, s);') - print(' else') - print(' $display("%d: %b %b %s", i, r, s, r !== s ? "TRIG" : "");') + print(' if (-1 <= $signed(r-s) && $signed(r-s) <= +1) begin') + print(' // $display("%d: %b %b", i, r, s);') + print(' end else if (r === s) begin ') + print(' // $display("%d: %b %b", i, r, s);') + print(' end else begin ') + print(' for (j = 0; j < 64; j = j+1)') + print(' buffer[j*8 +: 8] = r[j] !== s[j] ? "^" : " ";') + print(' $display("\\n%3d: %b %b", i, r, s);') + print(' $display(" %s %s", buffer, buffer);') + print(' end') print(' end') print('endtask') print('initial begin #1;') diff --git a/tests/realmath/run-test.sh b/tests/realmath/run-test.sh index 9568cdd6..48e87417 100755 --- a/tests/realmath/run-test.sh +++ b/tests/realmath/run-test.sh @@ -13,7 +13,7 @@ for ((i = 0; i < 100; i++)); do idx=$( printf "%05d" $i ) ../../../yosys -q uut_${idx}.ys iverilog -o uut_${idx}_tb uut_${idx}_tb.v uut_${idx}.v uut_${idx}_syn.v - ./uut_${idx}_tb > uut_${idx}.log + ./uut_${idx}_tb done echo From 4d1df128fa42a9e6718f38e794be8b2f8c2ff7c7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 09:27:09 +0200 Subject: [PATCH 247/750] Improved AstNode::realAsConst for large numbers --- frontends/ast/ast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index cc7f442b..967111d3 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()); } From a4ec19c25c97d68b9347d3d98637add7b18cf073 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 09:31:03 +0200 Subject: [PATCH 248/750] Added tests/realmath to "make test" --- Makefile | 1 + tests/asicworld/run-test.sh | 1 - tests/hana/run-test.sh | 1 - tests/realmath/run-test.sh | 6 +++++- tests/simple/run-test.sh | 1 - 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index a84215b2..61fb5dc4 100644 --- a/Makefile +++ b/Makefile @@ -161,6 +161,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) cd tests/simple && bash run-test.sh cd tests/hana && bash run-test.sh cd tests/asicworld && bash run-test.sh + cd tests/realmath && bash run-test.sh cd tests/techmap && bash run-test.sh cd tests/sat && bash run-test.sh diff --git a/tests/asicworld/run-test.sh b/tests/asicworld/run-test.sh index bf27d15f..9153f55f 100755 --- a/tests/asicworld/run-test.sh +++ b/tests/asicworld/run-test.sh @@ -1,3 +1,2 @@ #!/bin/bash -make -C ../.. || exit 1 exec bash ../tools/autotest.sh *.v diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh index b8e7231c..199bb916 100755 --- a/tests/hana/run-test.sh +++ b/tests/hana/run-test.sh @@ -1,3 +1,2 @@ #!/bin/bash -make -C ../.. || exit 1 exec bash ../tools/autotest.sh -l hana_vlib.v test_*.v diff --git a/tests/realmath/run-test.sh b/tests/realmath/run-test.sh index 48e87417..a28863d3 100755 --- a/tests/realmath/run-test.sh +++ b/tests/realmath/run-test.sh @@ -13,7 +13,11 @@ for ((i = 0; i < 100; i++)); do idx=$( printf "%05d" $i ) ../../../yosys -q uut_${idx}.ys iverilog -o uut_${idx}_tb uut_${idx}_tb.v uut_${idx}.v uut_${idx}_syn.v - ./uut_${idx}_tb + ./uut_${idx}_tb | tee uut_${idx}.err + if test -s uut_${idx}.err; then + exit 1 + fi + rm -f uut_${idx}.err done echo diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh index eb6fd10b..3d00c7eb 100755 --- a/tests/simple/run-test.sh +++ b/tests/simple/run-test.sh @@ -6,5 +6,4 @@ if ! which iverilog > /dev/null ; then exit 1 fi -make -C ../.. || exit 1 exec bash ../tools/autotest.sh *.v From 398482eced4c16a22a5617246f75bbd14eaa618f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 09:39:22 +0200 Subject: [PATCH 249/750] Removed long running tests from tests/simple/realexpr.v (replaced by tests/realmath) --- tests/simple/realexpr.v | 55 ----------------------------------------- 1 file changed, 55 deletions(-) diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 2b63ca6f..35166110 100644 --- a/tests/simple/realexpr.v +++ b/tests/simple/realexpr.v @@ -13,58 +13,3 @@ module demo_001(y1, y2, y3, y4); assign y4 = p4 + 0.2; endmodule -module demo_002(s, a, y); - input [4:0] s; - input [3:0] a; - output [7:0] y; - - reg [7:0] data [21*16-1:0]; - integer i; - - initial begin - for (i = 0; i < 16; i = i+1) begin - data[ 0*16 + i] = 128 + 64 * $ln (i*0.2 - 0.8); - data[ 1*16 + i] = 128 + 64 * $log10 (i*0.2 - 0.8); - data[ 2*16 + i] = 128 + 64 * $exp (i*0.2 - 0.8); - data[ 3*16 + i] = 128 + 64 * $sqrt (i*0.2 - 0.8); - data[ 4*16 + i] = 128 + 64 * $floor (i*0.2 - 0.8); - data[ 5*16 + i] = 128 + 64 * $ceil (i*0.2 - 0.8); - data[ 6*16 + i] = 128 + 64 * $sin (i*0.2 - 0.8); - data[ 7*16 + i] = 128 + 64 * $cos (i*0.2 - 0.8); - data[ 8*16 + i] = 128 + 64 * $tan (i*0.2 - 0.8); - data[ 9*16 + i] = 128 + 64 * $asin (i*0.2 - 0.8); - data[10*16 + i] = 128 + 64 * $acos (i*0.2 - 0.8); - data[11*16 + i] = 128 + 64 * $atan (i*0.2 - 0.8); - data[12*16 + i] = 128 + 64 * $sinh (i*0.2 - 0.8); - data[13*16 + i] = 128 + 64 * $cosh (i*0.2 - 0.8); - data[14*16 + i] = 128 + 64 * $tanh (i*0.2 - 0.8); - data[15*16 + i] = 128 + 64 * $asinh (i*0.2 - 0.8); - data[16*16 + i] = 128 + 64 * $acosh (i*0.2 - 0.8); - data[17*16 + i] = 128 + 64 * $atanh (i*0.2 - 0.8); - end - end - - assign y = s < 18 ? data[s*16 + a] : 0; -endmodule - -module demo_003(s, a, b, y); - input [1:0] s; - input [3:0] a; - input [3:0] b; - output [7:0] y; - - reg [7:0] data [3*16*16-1:0]; - integer i, j; - - initial begin - for (i = 0; i < 16; i = i+1) - for (j = 0; j < 16; j = j+1) begin - data[0*256 + i*16 + j] = 128 + 64 * $pow (i*0.2 - 0.8, j*0.2 - 0.8); - data[1*256 + i*16 + j] = 128 + 64 * $atan2 (i*0.2 - 0.8, j*0.2 - 0.8); - data[2*256 + i*16 + j] = 128 + 64 * $hypot (i*0.2 - 0.8, j*0.2 - 0.8); - end - end - - assign y = s < 3 ? data[s*256 + a*16 + b] : 0; -endmodule - From b1b96d199f7d0b97d203e3fd60af698ebaf03d73 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 11:51:51 +0200 Subject: [PATCH 250/750] Added more calls to "hierarchy" to README file --- README | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README b/README index 05628a8e..ba90e72a 100644 --- a/README +++ b/README @@ -109,6 +109,10 @@ writing the design to the console in yosys's internal format: yosys> write_ilang +elaborate design hierarchy: + + yosys> hierarchy + convert processes ("always" blocks) to netlist elements and perform some simple optimizations: @@ -132,13 +136,14 @@ write design netlist to a new verilog file: a similar synthesis can be performed using yosys command line options only: - $ ./yosys -o synth.v -p proc -p opt -p techmap -p opt tests/simple/fiedler-cooley.v + $ ./yosys -o synth.v -p hierarchy -p proc -p opt \ + -p techmap -p opt tests/simple/fiedler-cooley.v or using a simple synthesis script: $ cat synth.ys read_verilog tests/simple/fiedler-cooley.v - proc; opt; techmap; opt + hierarchy; proc; opt; techmap; opt write_verilog synth.v $ ./yosys synth.ys @@ -147,7 +152,7 @@ It is also possible to only have the synthesis commands but not the read/write commands in the synthesis script: $ cat synth.ys - proc; opt; techmap; opt + hierarchy; proc; opt; techmap; opt $ ./yosys -o synth.v tests/simple/fiedler-cooley.v synth.ys From 5bfe865cec15c12e2a9e764a0a57c01f97f8235e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:00:57 +0200 Subject: [PATCH 251/750] Added found_real feature to AstNode::detectSignWidth --- frontends/ast/ast.h | 4 ++-- frontends/ast/genrtlil.cc | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 74a476b5..f89af633 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 8a57a0ee..1f0ef445 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 From 0c4c79c4c6f8a433ef4b141b1523bccc261f8231 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:02:40 +0200 Subject: [PATCH 252/750] Fixed parsing of TOK_INTEGER (implies TOK_SIGNED) --- frontends/verilog/parser.y | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 57defd56..37c3232a 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: From 82bbd2f0772e62555eb669eb64883d75de4ca29a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:05:37 +0200 Subject: [PATCH 253/750] 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(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 967111d3..3f704bea 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 80fd28d5..3f712510 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; From 6c17d4f242ae2acb1581869b3ca904a0adbddc13 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:12:24 +0200 Subject: [PATCH 254/750] Improved ternary support for real values --- frontends/ast/simplify.cc | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 3f712510..7be287d1 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(); From 88470283c995860c593bae03373a0b26408b0e94 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:21:08 +0200 Subject: [PATCH 255/750] Little steps in realmath test bench --- tests/realmath/.gitignore | 1 + tests/realmath/generate.py | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 tests/realmath/.gitignore diff --git a/tests/realmath/.gitignore b/tests/realmath/.gitignore new file mode 100644 index 00000000..9c595a6f --- /dev/null +++ b/tests/realmath/.gitignore @@ -0,0 +1 @@ +temp diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index 58cedf02..9e48755c 100644 --- a/tests/realmath/generate.py +++ b/tests/realmath/generate.py @@ -44,8 +44,10 @@ for idx in range(100): print('module uut_%05d(output [63:0] %s);\n' % (idx, ', '.join(['y%02d' % i for i in range(100)]))) for i in range(30): print('localparam p%02d = %s;' % (i, random_expression())) + # print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression())) for i in range(30, 60): print('localparam p%02d = %s;' % (i, random_expression(maxparam = 30))) + # print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression(maxparam = 30))) for i in range(100): print('assign y%02d = 65536 * (%s);' % (i, random_expression(maxparam = 60))) print('endmodule') From 798ff88855a6e9b8eb82a48fb4d39f78807200d9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 12:47:51 +0200 Subject: [PATCH 256/750] Improved handling of relational op of real values --- frontends/ast/simplify.cc | 17 +++++++++-------- tests/realmath/generate.py | 12 ++++++++---- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7be287d1..7a98e271 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(); } } diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index 9e48755c..53015381 100644 --- a/tests/realmath/generate.py +++ b/tests/realmath/generate.py @@ -43,11 +43,15 @@ for idx in range(100): with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): print('module uut_%05d(output [63:0] %s);\n' % (idx, ', '.join(['y%02d' % i for i in range(100)]))) for i in range(30): - print('localparam p%02d = %s;' % (i, random_expression())) - # print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression())) + if idx < 10 or True: + print('localparam p%02d = %s;' % (i, random_expression())) + else: + print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression())) for i in range(30, 60): - print('localparam p%02d = %s;' % (i, random_expression(maxparam = 30))) - # print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression(maxparam = 30))) + if idx < 10 or True: + print('localparam p%02d = %s;' % (i, random_expression(maxparam = 30))) + else: + print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression(maxparam = 30))) for i in range(100): print('assign y%02d = 65536 * (%s);' % (i, random_expression(maxparam = 60))) print('endmodule') From 80e459469576b82975a5cf663b4aba2e044d9476 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 21:39:25 +0200 Subject: [PATCH 257/750] Added AstNode::MEM2REG_FL_CMPLX_LHS --- frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index f89af633..8253a205 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 7a98e271..0b0e46f2 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; From df76da8fd710394e7ea999e90994483da223f545 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 21:49:59 +0200 Subject: [PATCH 258/750] Added test case for AstNode::MEM2REG_FL_CMPLX_LHS --- tests/simple/mem2reg.v | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/simple/mem2reg.v b/tests/simple/mem2reg.v index e2c136dd..3630b57c 100644 --- a/tests/simple/mem2reg.v +++ b/tests/simple/mem2reg.v @@ -43,3 +43,15 @@ end endmodule +// ------------------------------------------------------ + +// http://www.reddit.com/r/yosys/comments/28d9lx/problem_with_concatenation_of_two_dimensional/ +module test3( input clk, input [8:0] din_a, output reg [7:0] dout_a, output [7:0] dout_b); +reg [7:0] dint_c [0:7]; +always @(posedge clk) + begin + {dout_a[0], dint_c[3]} <= din_a; + end +assign dout_b = dint_c[3]; +endmodule + From 1c85584fe5843a43590de3927fe9bde74a04e72e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 19 Jun 2014 12:29:29 +0200 Subject: [PATCH 259/750] Do not create $dffsr cells with no-op resets in proc_dff --- passes/proc/proc_dff.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 2ec498fb..c1844651 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -356,6 +356,11 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) rstval.optimize(); sig.optimize(); + if (rstval == sig) { + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.width); + sync_level = NULL; + } + if (sync_always) { if (sync_edge || sync_level || many_async_rules.size() > 0) log_error("Mixed always event with edge and/or level sensitive events!\n"); From b18fa95d2f1f4118cdb7c16e3415059bd81e2325 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 16:33:33 +0200 Subject: [PATCH 260/750] Progress in presentation --- manual/PRESENTATION_ExOth.tex | 115 ++++++++++++++++++--- manual/PRESENTATION_ExOth/Makefile | 10 +- manual/PRESENTATION_ExOth/axis_master.v | 27 +++++ manual/PRESENTATION_ExOth/axis_test.v | 27 +++++ manual/PRESENTATION_ExOth/axis_test.ys | 5 + manual/PRESENTATION_ExOth/equiv.ys | 17 +++ manual/PRESENTATION_ExSyn.tex | 2 +- manual/PRESENTATION_ExSyn/Makefile | 2 +- manual/PRESENTATION_ExSyn/techmap_01_map.v | 6 +- 9 files changed, 188 insertions(+), 23 deletions(-) create mode 100644 manual/PRESENTATION_ExOth/axis_master.v create mode 100644 manual/PRESENTATION_ExOth/axis_test.v create mode 100644 manual/PRESENTATION_ExOth/axis_test.ys create mode 100644 manual/PRESENTATION_ExOth/equiv.ys diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex index 64c4af72..3f0749cd 100644 --- a/manual/PRESENTATION_ExOth.tex +++ b/manual/PRESENTATION_ExOth.tex @@ -6,11 +6,10 @@ \end{frame} \begin{frame}{Overview} -This section contains 3 subsections: +This section contains 2 subsections: \begin{itemize} \item Interactive Design Investigation \item Symbolic Model Checking -\item Reverse Engineering \end{itemize} \end{frame} @@ -98,25 +97,107 @@ Signal Name Dec Hex Bin \subsectionpagesuffix \end{frame} -\subsubsection{TBD} +\begin{frame}{\subsecname} +Symbolic Model Checking (SMC) is used to formally prove that a circuit has +(or has not) a given property. -\begin{frame}{\subsubsecname} -TBD +\bigskip +One appliction is Formal Equivalence Checking: Proving that two circuits +are identical. For example this is a very useful feature when debugging custom +passes in Yosys. + +\bigskip +Other applications include checking if a module conforms to interface +standards. + +\bigskip +The {\tt sat} command in Yosys can be used to perform Symbolic Model Checking. \end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{frame}[t]{Example: Formal Equivalence Checking (1/2)} +Remember the following example? +\vskip1em -\subsection{Reverse Engineering} +\vbox to 0cm{ +\vskip-0.3cm +\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/techmap_01_map.v} +}\vbox to 0cm{ +\vskip-0.5cm +\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExSyn/techmap_01.v} +\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/techmap_01.ys}} -\begin{frame} -\subsectionpage -\subsectionpagesuffix +\vskip5cm\hskip5cm +Lets see if it is correct.. \end{frame} -\subsubsection{TBD} +\begin{frame}[t, fragile]{Example: Formal Equivalence Checking (2/2)} +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] +# read test design +read_verilog techmap_01.v +hierarchy -top test -\begin{frame}{\subsubsecname} -TBD +# create two version of the design: test_orig and test_mapped +copy test test_orig +rename test test_mapped + +# apply the techmap only to test_mapped +techmap -map techmap_01_map.v test_mapped + +# create a miter circuit to test equivialence +miter -equiv -make_assert -make_outputs test_orig test_mapped miter +flatten miter + +# run equivialence check +sat -verify -prove-asserts -show-inputs -show-outputs miter +\end{lstlisting} + +\dots +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] +Solving problem with 945 variables and 2505 clauses.. +SAT proof finished - no model found: SUCCESS! +\end{lstlisting} +\end{frame} + +\begin{frame}[t, fragile]{Example: Symbolic Model Checking (1/2)} +\small +The following AXI4 Stream Master has a bug. But the bug is not exposed if the +slave keeps {\tt tready} asserted all the time. (Somtheing a test bench might do.) + +\medskip +Symbolic Model Checking can be used to expose the bug and find a sequence +of values for {\tt tready} that yield the incorrect behavior. + +\vskip-1em +\begin{columns} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{5pt}{6pt}\selectfont, language=verilog]{PRESENTATION_ExOth/axis_master.v} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{5pt}{6pt}\selectfont, language=verilog]{PRESENTATION_ExOth/axis_test.v} +\end{columns} +\end{frame} + +\begin{frame}[t, fragile]{Example: Symbolic Model Checking (2/2)} +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single] +read_verilog -sv axis_master.v axis_test.v +hierarchy -top axis_test + +proc; flatten;; +sat -seq 50 -prove-asserts +\end{lstlisting} + +\bigskip +\dots with unmodified {\tt axis\_master.v}: +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] +Solving problem with 159344 variables and 442126 clauses.. +SAT proof finished - model found: FAIL! +\end{lstlisting} + +\bigskip +\dots with fixed {\tt axis\_master.v}: +\begin{lstlisting}[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] +Solving problem with 159144 variables and 441626 clauses.. +SAT proof finished - no model found: SUCCESS! +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -125,10 +206,10 @@ TBD \begin{frame}{\subsecname} \begin{itemize} -\item TBD -\item TBD -\item TBD -\item TBD +\item Yosys provides useful features beyond synthesis. +\item The commands {\tt sat} and {\tt eval} can be used to analyse the behavior of a circuit. +\item The {\tt sat} command can also be used for symbolic model checking. +\item This can be useful for debugging and testing designs and Yosys extensions alike. \end{itemize} \bigskip diff --git a/manual/PRESENTATION_ExOth/Makefile b/manual/PRESENTATION_ExOth/Makefile index a12beada..4864d8d5 100644 --- a/manual/PRESENTATION_ExOth/Makefile +++ b/manual/PRESENTATION_ExOth/Makefile @@ -1,8 +1,16 @@ -all: scrambler_p01.pdf scrambler_p02.pdf +all: scrambler_p01.pdf scrambler_p02.pdf equiv.log axis_test.log scrambler_p01.pdf: scrambler.ys scrambler.v ../../yosys scrambler.ys scrambler_p02.pdf: scrambler_p01.pdf +equiv.log: equiv.ys + ../../yosys -l equiv.log_new equiv.ys + mv equiv.log_new equiv.log + +axis_test.log: axis_test.ys axis_master.v axis_test.v + ../../yosys -l axis_test.log_new axis_test.ys + mv axis_test.log_new axis_test.log + diff --git a/manual/PRESENTATION_ExOth/axis_master.v b/manual/PRESENTATION_ExOth/axis_master.v new file mode 100644 index 00000000..25a1feee --- /dev/null +++ b/manual/PRESENTATION_ExOth/axis_master.v @@ -0,0 +1,27 @@ +module axis_master(aclk, aresetn, tvalid, tready, tdata); + input aclk, aresetn, tready; + output reg tvalid; + output reg [7:0] tdata; + + reg [31:0] state; + always @(posedge aclk) begin + if (!aresetn) begin + state <= 314159265; + tvalid <= 0; + tdata <= 'bx; + end else begin + if (tvalid && tready) + tvalid <= 0; + if (!tvalid || !tready) begin + // ^- should be not inverted! + state = state ^ state << 13; + state = state ^ state >> 7; + state = state ^ state << 17; + if (state[9:8] == 0) begin + tvalid <= 1; + tdata <= state; + end + end + end + end +endmodule diff --git a/manual/PRESENTATION_ExOth/axis_test.v b/manual/PRESENTATION_ExOth/axis_test.v new file mode 100644 index 00000000..0be833f1 --- /dev/null +++ b/manual/PRESENTATION_ExOth/axis_test.v @@ -0,0 +1,27 @@ +module axis_test(aclk, tready); + input aclk, tready; + wire aresetn, tvalid; + wire [7:0] tdata; + + integer counter = 0; + reg aresetn = 0; + + axis_master uut (aclk, aresetn, tvalid, tready, tdata); + + always @(posedge aclk) begin + if (aresetn && tready && tvalid) begin + if (counter == 0) assert(tdata == 19); + if (counter == 1) assert(tdata == 99); + if (counter == 2) assert(tdata == 1); + if (counter == 3) assert(tdata == 244); + if (counter == 4) assert(tdata == 133); + if (counter == 5) assert(tdata == 209); + if (counter == 6) assert(tdata == 241); + if (counter == 7) assert(tdata == 137); + if (counter == 8) assert(tdata == 176); + if (counter == 9) assert(tdata == 6); + counter <= counter + 1; + end + aresetn <= 1; + end +endmodule diff --git a/manual/PRESENTATION_ExOth/axis_test.ys b/manual/PRESENTATION_ExOth/axis_test.ys new file mode 100644 index 00000000..19663ac7 --- /dev/null +++ b/manual/PRESENTATION_ExOth/axis_test.ys @@ -0,0 +1,5 @@ +read_verilog -sv axis_master.v axis_test.v +hierarchy -top axis_test + +proc; flatten;; +sat -falsify -seq 50 -prove-asserts diff --git a/manual/PRESENTATION_ExOth/equiv.ys b/manual/PRESENTATION_ExOth/equiv.ys new file mode 100644 index 00000000..09a4045d --- /dev/null +++ b/manual/PRESENTATION_ExOth/equiv.ys @@ -0,0 +1,17 @@ +# read test design +read_verilog ../PRESENTATION_ExSyn/techmap_01.v +hierarchy -top test + +# create two version of the design: test_orig and test_mapped +copy test test_orig +rename test test_mapped + +# apply the techmap only to test_mapped +techmap -map ../PRESENTATION_ExSyn/techmap_01_map.v test_mapped + +# create a miter circuit to test equivialence +miter -equiv -make_assert -make_outputs test_orig test_mapped miter +flatten miter + +# run equivialence check +sat -verify -prove-asserts -show-inputs -show-outputs miter diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex index 432ce368..d1d8abe4 100644 --- a/manual/PRESENTATION_ExSyn.tex +++ b/manual/PRESENTATION_ExSyn.tex @@ -346,7 +346,7 @@ Finally the {\tt fsm\_map} command can be used to convert the (optimized) {\tt \subsection{The {\tt techmap} command} \begin{frame}[t]{\subsecname} -\vbox to 0cm{\includegraphics[width=12cm,trim=-18cm 0cm 0cm -34cm]{PRESENTATION_ExSyn/techmap_01.pdf}\vss} +\vbox to 0cm{\includegraphics[width=12cm,trim=-15cm 0cm 0cm -20cm]{PRESENTATION_ExSyn/techmap_01.pdf}\vss} \vskip-0.8cm The {\tt techmap} command replaces cells with implementations given as verilog source. For example implementing a 32 bit adder using 16 bit adders: diff --git a/manual/PRESENTATION_ExSyn/Makefile b/manual/PRESENTATION_ExSyn/Makefile index bcff48aa..c34eae3f 100644 --- a/manual/PRESENTATION_ExSyn/Makefile +++ b/manual/PRESENTATION_ExSyn/Makefile @@ -8,7 +8,7 @@ TARGETS += abc_01 all: $(addsuffix .pdf,$(TARGETS)) define make_pdf_template -$(1).pdf: $(1).v $(1).ys +$(1).pdf: $(1)*.v $(1)*.ys ../../yosys -p 'script $(1).ys; show -notitle -prefix $(1) -format pdf' endef diff --git a/manual/PRESENTATION_ExSyn/techmap_01_map.v b/manual/PRESENTATION_ExSyn/techmap_01_map.v index 64c0b87c..4fd86e85 100644 --- a/manual/PRESENTATION_ExSyn/techmap_01_map.v +++ b/manual/PRESENTATION_ExSyn/techmap_01_map.v @@ -13,9 +13,9 @@ output [Y_WIDTH-1:0] Y; generate if ((A_WIDTH == 32) && (B_WIDTH == 32)) begin - wire [15:0] CARRY = |{A[15:0], B[15:0]} && ~|Y[15:0]; - assign Y[15:0] = A[15:0] + B[15:0]; - assign Y[31:16] = A[31:16] + B[31:16] + CARRY; + wire [16:0] S1 = A[15:0] + B[15:0]; + wire [15:0] S2 = A[31:16] + B[31:16] + S1[16]; + assign Y = {S2[15:0], S1[15:0]}; end else wire _TECHMAP_FAIL_ = 1; From 072604f30f58ab535bfd8d004163607900adf86e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 21:13:18 +0200 Subject: [PATCH 261/750] fixed typo --- manual/PRESENTATION_ExOth.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex index 3f0749cd..9e7e9dc7 100644 --- a/manual/PRESENTATION_ExOth.tex +++ b/manual/PRESENTATION_ExOth.tex @@ -161,7 +161,7 @@ SAT proof finished - no model found: SUCCESS! \begin{frame}[t, fragile]{Example: Symbolic Model Checking (1/2)} \small The following AXI4 Stream Master has a bug. But the bug is not exposed if the -slave keeps {\tt tready} asserted all the time. (Somtheing a test bench might do.) +slave keeps {\tt tready} asserted all the time. (Something a test bench might do.) \medskip Symbolic Model Checking can be used to expose the bug and find a sequence From 65b2e9c0645c30d84a9d9be148430fd76d3e5f05 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 21:41:13 +0200 Subject: [PATCH 262/750] fixed signdness detection for expressions with reals --- frontends/ast/genrtlil.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 1f0ef445..9f18efce 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 From 3345fa0bab5d343a9cd5a9dde6486e4e876fe8da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 21:43:04 +0200 Subject: [PATCH 263/750] Little steps in realmath test bench --- tests/realmath/generate.py | 4 ++-- tests/simple/realexpr.v | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index 53015381..972021dc 100644 --- a/tests/realmath/generate.py +++ b/tests/realmath/generate.py @@ -43,12 +43,12 @@ for idx in range(100): with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): print('module uut_%05d(output [63:0] %s);\n' % (idx, ', '.join(['y%02d' % i for i in range(100)]))) for i in range(30): - if idx < 10 or True: + if idx < 10: print('localparam p%02d = %s;' % (i, random_expression())) else: print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression())) for i in range(30, 60): - if idx < 10 or True: + if idx < 10: print('localparam p%02d = %s;' % (i, random_expression(maxparam = 30))) else: print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression(maxparam = 30))) diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 35166110..2adffe2d 100644 --- a/tests/simple/realexpr.v +++ b/tests/simple/realexpr.v @@ -13,3 +13,9 @@ module demo_001(y1, y2, y3, y4); assign y4 = p4 + 0.2; endmodule +module demo_002(y1); + output [3:0] y1; + + assign y1 = 1'bx >= (-1 * -1.17); +endmodule + From a7aea179599045feafcaf26f5ed334a7318a69b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 22 Jun 2014 12:50:29 +0200 Subject: [PATCH 264/750] Progress in presentation --- manual/PRESENTATION_Prog.tex | 440 ++++++++++++++++++++++--- manual/PRESENTATION_Prog/.gitignore | 1 + manual/PRESENTATION_Prog/Makefile | 18 + manual/PRESENTATION_Prog/absval_ref.v | 3 + manual/PRESENTATION_Prog/my_cmd.cc | 78 +++++ manual/PRESENTATION_Prog/sigmap_test.v | 3 + manual/presentation.sh | 2 + 7 files changed, 503 insertions(+), 42 deletions(-) create mode 100644 manual/PRESENTATION_Prog/.gitignore create mode 100644 manual/PRESENTATION_Prog/Makefile create mode 100644 manual/PRESENTATION_Prog/absval_ref.v create mode 100644 manual/PRESENTATION_Prog/my_cmd.cc create mode 100644 manual/PRESENTATION_Prog/sigmap_test.v diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index 45f0cb0c..1e7f697b 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -7,14 +7,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Why writing Yosys extensions?} - -\begin{frame}{\subsecname} -TBD -\end{frame} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - \subsection{Program Components and Data Formats} \begin{frame}{\subsecname} @@ -109,55 +101,293 @@ For simplicity we only discuss this version of RTLIL in this presentation. \subsection{Using dump and show commands} \begin{frame}{\subsecname} -TBD +\begin{itemize} +\item The {\tt dump} command prints the design (or parts of it) in ILANG format. This is +a text representation of RTLIL. + +\bigskip +\item The {\tt show} command visualizes how the components in the design are connected. +\end{itemize} + +\bigskip +When trying to understand what a command does, create a small test case and +look at the output of {\tt dump} and {\tt show} before and after the command +has been executed. \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{The RTLIL::Const Structure} +\subsection{The RTLIL Data Structures} \begin{frame}{\subsecname} -TBD +The RTLIL data structures are simple structs utilizing C++ {\tt std::} +containers. + +\bigskip +\begin{itemize} +\item Most operations are performed directly on the RTLIL structs without +setter or getter functions. + +\bigskip +\item In debug builds a consistency checker is run over the in-memory design +between commands to make sure that the RTLIL representation is intact. + +\bigskip +\item Most RTLIL structs have helper methods that perform the most common operations. +\end{itemize} + +\bigskip +See {\tt yosys/kernel/rtlil.h} for details. \end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsubsection{RTLIL::IdString} -\subsection{The RTLIL::SigSpec Structure} +\begin{frame}{\subsubsecname}{} +{\tt RTLIL::IdString} is a simple wrapper for {\tt std::string}. It is used for names of RTLIL objects. -\begin{frame}{\subsecname} -TBD +\medskip +The first character of a {\tt RTLIL::IdString} specifies if the name is {\it public\/} or {\it private\/}: + +\medskip +\begin{itemize} +\item {\tt RTLIL::IdString[0] == '\textbackslash\textbackslash'}: \\ +This is a public name. Usually this means it is a name that was declared in a Verilog file. + +\bigskip +\item {\tt RTLIL::IdString[0] == '\$'}: \\ +This is a private name. It was assigned by Yosys. +\end{itemize} + +\bigskip +Use the {\tt NEW\_ID} macro to create a new unique private name. \end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsubsection{RTLIL::Design and RTLIL::Module} -\subsection{RTLIL::Design, RTLIL::Module} +\begin{frame}[t, fragile]{\subsubsecname} +The {\tt RTLIL::Design} and {\tt RTLIL::Module} structs are the top-level RTLIL +data structures. -\begin{frame}{\subsecname} -TBD +Yosys always operates on one active design, but can hold many designs in memory. + +\bigskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +struct RTLIL::Design { + std::map modules; + ... +}; + +struct RTLIL::Module { + RTLIL::IdString name; + std::map wires; + std::map cells; + std::vector connections; + ... +}; +\end{lstlisting} \end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsubsection{The RTLIL::Wire Structure} -\subsection{RTLIL::Wire and connections} +\begin{frame}[t, fragile]{\subsubsecname} +Each wire in the design is represented by a {\tt RTLIL::Wire} struct: -\begin{frame}{\subsecname} -TBD +\medskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +struct RTLIL::Wire { + RTLIL::IdString name; + int width, start_offset, port_id; + bool port_input, port_output; + ... +}; +\end{lstlisting} + +\medskip +\hfil\begin{tabular}{p{3cm}l} +{\tt width} \dotfill & The total number of bits. E.g. 10 for {\tt [9:0]}. \\ +{\tt start\_offset} \dotfill & The lowest bit index. E.g. 3 for {\tt [5:3]}. \\ +{\tt port\_id} \dotfill & Zero for non-ports. Positive index for ports. \\ +{\tt port\_input} \dotfill & True for {\tt input} and {\tt inout} ports. \\ +{\tt port\_output} \dotfill & True for {\tt output} and {\tt inout} ports. \\ +\end{tabular} \end{frame} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsubsection{RTLIL::State and RTLIL::Const} -\subsection{RTLIL::Cell} +\begin{frame}[t, fragile]{\subsubsecname} +The {\tt RTLIL::State} enum represents a simple 1-bit logic level: -\begin{frame}{\subsecname} -TBD +\smallskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +enum RTLIL::State { + S0 = 0, + S1 = 1, + Sx = 2, // undefined value or conflict + Sz = 3, // high-impedance / not-connected + Sa = 4, // don't care (used only in cases) + Sm = 5 // marker (used internally by some passes) +}; +\end{lstlisting} + +\bigskip +The {\tt RTLIL::Const} struct represents a constant multi-bit value: + +\smallskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +struct RTLIL::Const { + std::vector bits; + ... +}; +\end{lstlisting} + +\bigskip +Notice that Yosys is not using special {\tt VCC} or {\tt GND} driver cells to represent constants. Instead +constants are part of the RTLIL representation itself. +\end{frame} + +\subsubsection{The RTLIL::SigSpec Structure} + +\begin{frame}[t, fragile]{\subsubsecname} +The {\tt RTLIL::SigSpec} struct represents a signal vector. Each bit can either be a bit from a wire +or a constant value. Consecutive bits from a wire or consecutive constant bits are consolidated into +a {\tt RTLIL::SigChunk}: + +\bigskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +struct RTLIL::SigChunk { + RTLIL::Wire *wire; + RTLIL::Const data; // only used if wire == NULL, LSB at index 0 + int width, offset; + ... +}; + +struct RTLIL::SigSpec { + std::vector chunks; // LSB at index 0 + int width; + ... +}; +\end{lstlisting} + +\bigskip +The {\tt RTLIL::SigSpec} struct has a ton of additional helper methods to compare, analyze, and +manipulate instances of {\tt RTLIL::SigSpec}. +\end{frame} + +\subsubsection{The RTLIL::Cell Structure} + +\begin{frame}[t, fragile]{\subsubsecname (1/2)} +The {\tt RTLIL::Cell} strcut represents an instance of a module or library cell. + +\smallskip +The ports of the cell +are associated with {\tt RTLIL::SigSpec} instances and the parameters are associated with {\tt RTLIL::Const} +instances: + +\bigskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +struct RTLIL::Cell { + RTLIL::IdString name, type; + std::map connections; + std::map parameters; + ... +}; +\end{lstlisting} + +\bigskip +The {\tt type} may refer to another module in the same design, a cell name from a cell library, or a +cell name from the internal cell library: + +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont] +$not $pos $bu0 $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor +$reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod +$pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $safe_pmux $lut $assert $sr $dff +$dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_INV_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ +$_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_ +$_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_ +$_DFFSR_PNP_ $_DFFSR_PPN_ $_DFFSR_PPP_ $_DLATCH_N_ $_DLATCH_P_ $_DLATCHSR_NNN_ $_DLATCHSR_NNP_ +$_DLATCHSR_NPN_ $_DLATCHSR_NPP_ $_DLATCHSR_PNN_ $_DLATCHSR_PNP_ $_DLATCHSR_PPN_ $_DLATCHSR_PPP_ +\end{lstlisting} +\end{frame} + +\begin{frame}[t, fragile]{\subsubsecname (2/2)} +Simulation models (i.e. {\it documentation\/}) for the internal cell library: + +\smallskip +\hskip2em {\tt yosys/techlibs/common/simlib.v} and \\ +\hskip2em {\tt yosys/techlibs/common/simcells.v} + +\bigskip +The lower-case cell types (such as {\tt \$and}) are parameterized cells of variable +width. This so-called {\it RTL cells\/} are the cells described in {\tt simlib.v}. + +\bigskip +The upper-case cell types (such as {\tt \$\_AND\_}) single-bit cells that are not +parameterized. This so-called {\it internal Logic Gates} are the cells described +in {\tt simcells.v}. + +\bigskip +The consistency checker also checks the interfaces to the internal cell library. +If you want to use private cell types for your own purposes, use the {\tt \$\_\_}-prefix +to avoid name collisions. +\end{frame} + +\subsubsection{Connecting wires or constant drivers} + +\begin{frame}[t, fragile]{\subsubsecname} +Additional connections between wires or between wires and constants are modelled using +{\tt RTLIL::Module::connections}: + +\bigskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +typedef std::pair RTLIL::SigSig; + +struct RTLIL::Module { + ... + std::vector connections; + ... +}; +\end{lstlisting} + +\bigskip +{\tt RTLIL::SigSig::first} is the driven signal and {\tt RTLIL::SigSig::second} is the driving signal. +Example usage (setting wire {\tt foo} to value {\tt 42}): +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +module->connections.push_back(RTLIL::SigSig(module->wires.at("\\foo"), + RTLIL::SigSpec(42, module->wires.at("\\foo")->width))); +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Creating modules from scratch} -\begin{frame}{\subsecname} -TBD +\begin{frame}[t, fragile]{\subsecname} +Let's create the following module using the RTLIL API: + +\smallskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] +module absval(input signed [3:0] a, output [3:0] y); + assign y = a[3] ? -a : a; +endmodule +\end{lstlisting} + +\smallskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +RTLIL::Module *module = new RTLIL::Module; +module->name = "\\absval"; + +RTLIL::Wire *a = module->new_wire(4, "\\a"); +a->port_input = true; +a->port_id = 1; + +RTLIL::Wire *y = module->new_wire(4, "\\y"); +y->port_output = true; +y->port_id = 2; + +RTLIL::Wire *a_inv = module->new_wire(4, NEW_ID); +module->addNeg(NEW_ID, a, a_inv, true); +module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y); +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -165,39 +395,163 @@ TBD \subsection{Modifying modules} \begin{frame}{\subsecname} -TBD +Most commands modify existing modules, not create new ones. + +When modifying existing modules, stick to the following DOs and DON'Ts: + +\begin{itemize} +\item Do not remove wires. Simply disconnect them and let a successive {\tt clean} command worry about removing it. + +\item Use {\tt module->fixup\_ports()} after changing the {\tt port\_*} properties of wires. + +\item You can safely remove cells or change the {\tt connetions} property of a cell, but be careful when +changing the size of the {\tt SigSpec} connected to a cell port. + +\item Use the {\tt SigMap} helper class (see next slide) when you need a unique handle for each signal bit. +\end{itemize} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Using the SigMap helper class} -\begin{frame}{\subsecname} -TBD +\begin{frame}[t, fragile]{\subsecname} +Consider the following module: + +\smallskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=Verilog] +module test(input a, output x, y); + assign x = a, y = a; +endmodule +\end{lstlisting} + +In this case {\tt a}, {\tt x}, and {\tt y} are all different names for the same signal. However: + +\smallskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +RTLIL::SigSpec a(module->wires.at("\\a")), x(module->wires.at("\\x")), + y(module->wires.at("\\y")); +log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" +\end{lstlisting} + +The {\tt SigMap} helper class can be used to map all such aliasing signals to a +unique signal from the group (usually the wire that is directly driven by a cell or port). + +\smallskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +SigMap sigmap(module); +log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y), + sigmap(y) == sigmap(a)); // will print "1 1 1" +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Printing log messages} -\begin{frame}{\subsecname} -TBD +\begin{frame}[t, fragile]{\subsecname} +The {\tt log()} function is a {\tt printf()}-like function that can be used to create log messages. + +\medskip +Use {\tt log\_signal()} to create a C-string for a SigSpec object\footnote[frame]{The pointer returned +by {\tt log\_signal()} is automatically freed by the log framework at a later time.}: +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +log("Mapped signal x: %s\n", log_signal(sigmap(x))); +\end{lstlisting} + +\medskip +Use {\tt RTLIL::id2cstr()} to create a C-string for an {\tt RTLIL::IdString}: +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +log("Name of this module: %s\n", RTLIL::id2cstr(module->name)); +\end{lstlisting} + +\medskip +Use {\tt log\_header()} and {\tt log\_push()}/{\tt log\_pop()} to structure log messages: +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +log_header("Doing important stuff!\n"); +log_push(); +for (int i = 0; i < 10; i++) + log("Log message #%d.\n", i); +log_pop(); +\end{lstlisting} +\end{frame} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Error handling} + +\begin{frame}[t, fragile]{\subsecname} +Use {\tt log\_error()} to report a non-recoverable error: + +\medskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +if (design->modules.count(module->name) != 0) + log_error("A module with the name %s already exists!\n", + RTLIL::id2cstr(module->name)); +\end{lstlisting} + +\bigskip +Use {\tt log\_cmd\_error()} to report a recoverable error: +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +if (design->selection_stack.back().empty()) + log_cmd_error("This command can't operator on an empty selection!\n"); +\end{lstlisting} + +\bigskip +Use {\tt log\_assert()} and {\tt log\_abort()} instead of {\tt assert()} and {\tt abort()}. \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Creating a command} -\begin{frame}{\subsecname} -TBD +\begin{frame}[t, fragile]{\subsecname} +Simply create a global instance of a class derived from {\tt Pass} to create +a new yosys command: + +\bigskip +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] +#include "kernel/rtlil.h" +#include "kernel/register.h" +#include "kernel/log.h" + +struct MyPass : public Pass { + MyPass() : Pass("my_cmd", "just a simple test") { } + virtual void execute(std::vector args, RTLIL::Design *design) + { + log("Arguments to my_cmd:\n"); + for (auto &arg : args) + log(" %s\n", arg.c_str()); + + log("Modules in current design:\n"); + for (auto &mod : design->modules) + log(" %s (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), + mod.second->wires.size(), mod.second->cells.size()); + } +} MyPass; +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Creating a plugin} -\begin{frame}{\subsecname} -TBD +\begin{frame}[fragile]{\subsecname} +Yosys can be extended by adding additional C++ code to the Yosys code base, or +by loading plugins into Yosys. + +\bigskip +Use the following command to compile a Yosys plugin: +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] +yosys-config --exec --cxx --cxxflags --ldflags \ + -o my_cmd.so -shared my_cmd.cc --ldlibs +\end{lstlisting} + +\bigskip +Load the plugin using the yosys {\tt -m} option: +\begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] +yosys -m ./my_cmd.so -p 'my_cmd foo bar' +\end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -206,10 +560,12 @@ TBD \begin{frame}{\subsecname} \begin{itemize} -\item TBD -\item TBD -\item TBD -\item TBD +\item Writing Yosys extensions is very straight-forward. +\item \dots and even simpler if you don't need RTLIL::Memory or RTLIL::Process objects. + +\bigskip +\item Writing synthesis software? Consider learning the Yosys API and make your stuff +part of the Yosys framework. \end{itemize} \bigskip diff --git a/manual/PRESENTATION_Prog/.gitignore b/manual/PRESENTATION_Prog/.gitignore new file mode 100644 index 00000000..7fd56076 --- /dev/null +++ b/manual/PRESENTATION_Prog/.gitignore @@ -0,0 +1 @@ +my_cmd.so diff --git a/manual/PRESENTATION_Prog/Makefile b/manual/PRESENTATION_Prog/Makefile new file mode 100644 index 00000000..8da6bcd6 --- /dev/null +++ b/manual/PRESENTATION_Prog/Makefile @@ -0,0 +1,18 @@ + +all: test0.log test1.log test2.log + +my_cmd.so: my_cmd.cc + ../../yosys-config --exec --cxx --cxxflags --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs + +test0.log: my_cmd.so + ../../yosys -l test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v + mv test0.log_new test0.log + +test1.log: my_cmd.so + ../../yosys -l test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v + mv test1.log_new test1.log + +test2.log: my_cmd.so + ../../yosys -l test2.log_new -m ./my_cmd.so -p 'test2' sigmap_test.v + mv test2.log_new test2.log + diff --git a/manual/PRESENTATION_Prog/absval_ref.v b/manual/PRESENTATION_Prog/absval_ref.v new file mode 100644 index 00000000..ca0a115a --- /dev/null +++ b/manual/PRESENTATION_Prog/absval_ref.v @@ -0,0 +1,3 @@ +module absval_ref(input signed [3:0] a, output [3:0] y); + assign y = a[3] ? -a : a; +endmodule diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/manual/PRESENTATION_Prog/my_cmd.cc new file mode 100644 index 00000000..cf8a4add --- /dev/null +++ b/manual/PRESENTATION_Prog/my_cmd.cc @@ -0,0 +1,78 @@ +#include "kernel/rtlil.h" +#include "kernel/register.h" +#include "kernel/log.h" +#include "kernel/sigtools.h" + +struct MyPass : public Pass { + MyPass() : Pass("my_cmd", "just a simple test") { } + virtual void execute(std::vector args, RTLIL::Design *design) + { + log("Arguments to my_cmd:\n"); + for (auto &arg : args) + log(" %s\n", arg.c_str()); + + log("Modules in current design:\n"); + for (auto &mod : design->modules) + log(" %s (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), + mod.second->wires.size(), mod.second->cells.size()); + } +} MyPass; + + +struct Test1Pass : public Pass { + Test1Pass() : Pass("test1", "creating the absval module") { } + virtual void execute(std::vector, RTLIL::Design *design) + { + RTLIL::Module *module = new RTLIL::Module; + module->name = "\\absval"; + + RTLIL::Wire *a = module->new_wire(4, "\\a"); + a->port_input = true; + a->port_id = 1; + + RTLIL::Wire *y = module->new_wire(4, "\\y"); + y->port_output = true; + y->port_id = 2; + + RTLIL::Wire *a_inv = module->new_wire(4, NEW_ID); + module->addNeg(NEW_ID, a, a_inv, true); + module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y); + + log("Name of this module: %s\n", RTLIL::id2cstr(module->name)); + + if (design->modules.count(module->name) != 0) + log_error("A module with the name %s already exists!\n", + RTLIL::id2cstr(module->name)); + + design->modules[module->name] = module; + } +} Test1Pass; + + +struct Test2Pass : public Pass { + Test2Pass() : Pass("test2", "demonstrating sigmap on test module") { } + virtual void execute(std::vector, RTLIL::Design *design) + { + if (design->selection_stack.back().empty()) + log_cmd_error("This command can't operator on an empty selection!\n"); + + RTLIL::Module *module = design->modules.at("\\test"); + + RTLIL::SigSpec a(module->wires.at("\\a")), x(module->wires.at("\\x")), + y(module->wires.at("\\y")); + log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" + + SigMap sigmap(module); + log("%d %d %d\n", sigmap(a) == sigmap(x), sigmap(x) == sigmap(y), + sigmap(y) == sigmap(a)); // will print "1 1 1" + + log("Mapped signal x: %s\n", log_signal(sigmap(x))); + + log_header("Doing important stuff!\n"); + log_push(); + for (int i = 0; i < 10; i++) + log("Log message #%d.\n", i); + log_pop(); + } +} Test2Pass; + diff --git a/manual/PRESENTATION_Prog/sigmap_test.v b/manual/PRESENTATION_Prog/sigmap_test.v new file mode 100644 index 00000000..18dcf5eb --- /dev/null +++ b/manual/PRESENTATION_Prog/sigmap_test.v @@ -0,0 +1,3 @@ +module test(input a, output x, y); +assign x = a, y = a; +endmodule diff --git a/manual/presentation.sh b/manual/presentation.sh index 6771ba7c..980e1772 100755 --- a/manual/presentation.sh +++ b/manual/presentation.sh @@ -29,6 +29,8 @@ if ! $fast_mode; then make -C PRESENTATION_Intro make -C PRESENTATION_ExSyn make -C PRESENTATION_ExAdv + make -C PRESENTATION_ExOth + make -C PRESENTATION_Prog fi set -ex From 4fc43d19324eabcfe3a3788743a212ae684509cd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 24 Jun 2014 15:08:48 +0200 Subject: [PATCH 265/750] More found_real-related fixes to AstNode::detectSignWidthWorker --- frontends/ast/genrtlil.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9f18efce..787f4d2d 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: From 076182c34e34b5e59eb5d89d5001f7547102bb4d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 25 Jun 2014 10:05:36 +0200 Subject: [PATCH 266/750] Fixed handling of mixed real/int ternary expressions --- frontends/ast/simplify.cc | 16 ++++++++++++++++ tests/simple/realexpr.v | 9 ++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 0b0e46f2..db7f5ca3 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); diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 2adffe2d..5b756e6b 100644 --- a/tests/simple/realexpr.v +++ b/tests/simple/realexpr.v @@ -13,9 +13,12 @@ module demo_001(y1, y2, y3, y4); assign y4 = p4 + 0.2; endmodule -module demo_002(y1); - output [3:0] y1; +module demo_002(y0, y1, y2, y3); + output [63:0] y0, y1, y2, y3; - assign y1 = 1'bx >= (-1 * -1.17); + assign y0 = 1'bx >= (-1 * -1.17); + assign y1 = 1 ? 1 ? -1 : 'd0 : 0.0; + assign y2 = 1 ? -1 : 1 ? 'd0 : 0.0; + assign y3 = 1 ? -1 : 'd0; endmodule From 3e96ce86809fa0a4ea737fa4a9d3e6261f40a191 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 26 Jun 2014 22:05:39 +0200 Subject: [PATCH 267/750] Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 6 +- manual/PRESENTATION_ExOth.tex | 8 +- manual/PRESENTATION_ExSyn.tex | 20 ++--- manual/PRESENTATION_Intro.tex | 111 ++++++++++++++++----------- manual/PRESENTATION_Intro/counter.ys | 11 +-- manual/PRESENTATION_Prog.tex | 24 +++--- manual/presentation.tex | 4 +- 7 files changed, 105 insertions(+), 79 deletions(-) diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index 7aa01424..471516b4 100644 --- a/manual/PRESENTATION_ExAdv.tex +++ b/manual/PRESENTATION_ExAdv.tex @@ -94,7 +94,7 @@ tool for interactive design investigation. \subsubsection{Selecting by object property or type} \begin{frame}[fragile]{\subsubsecname} -Special pattern can be used to select by object property or type. For example: +Special patterns can be used to select by object property or type. For example: \bigskip \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] @@ -113,7 +113,7 @@ reference to the {\tt select} command. \subsubsection{Combining selection} \begin{frame}[fragile]{\subsubsecname} -When more than one selection expression is used in one statement they are +When more than one selection expression is used in one statement, then they are pushed on a stack. The final elements on the stack are combined into a union: \medskip @@ -169,7 +169,7 @@ See {\tt help select} for full documentation of this expressions. \subsubsection{Incremental selection} \begin{frame}[fragile]{\subsubsecname} -Sometime a selection can most easily described by a series of add/delete operations. +Sometimes a selection can most easily be described by a series of add/delete operations. The commands {\tt select -add} and {\tt select -del} respectively add or remove objects from the current selection instead of overwriting it. diff --git a/manual/PRESENTATION_ExOth.tex b/manual/PRESENTATION_ExOth.tex index 9e7e9dc7..f86dcd7a 100644 --- a/manual/PRESENTATION_ExOth.tex +++ b/manual/PRESENTATION_ExOth.tex @@ -28,7 +28,7 @@ from other tools). \begin{itemize} \item -The selection mechanism (see slides ``Using Selections''), especially pattern such +The selection mechanism (see slides ``Using Selections''), especially patterns such as {\tt \%ci} and {\tt \%co}, can be used to figure out how parts of the design are connected. @@ -53,9 +53,9 @@ read_verilog scrambler.v hierarchy; proc;; cd scrambler -submod -name xorshift32 xs %c %ci %D \ - %c %ci:+[D] %D %ci*:-$dff \ - xs %co %ci %d +submod -name xorshift32 \ + xs %c %ci %D %c %ci:+[D] %D \ + %ci*:-$dff xs %co %ci %d \end{lstlisting} \end{columns} diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex index d1d8abe4..f68b6f98 100644 --- a/manual/PRESENTATION_ExSyn.tex +++ b/manual/PRESENTATION_ExSyn.tex @@ -12,7 +12,7 @@ \begin{frame}{\subsecname} \begin{itemize} \item Reading and elaborating the design -\item High-level synthesis and optimization +\item Higher-level synthesis and optimization \begin{itemize} \item Converting {\tt always}-blocks to logic and registers \item Perform coarse-grain optimizations (resource sharing, const folding, ...) @@ -21,7 +21,7 @@ \end{itemize} \item Convert remaining logic to bit-level logic functions \item Perform optimizations on bit-level logic functions -\item Map bit-level logic and register to gates from cell library +\item Map bit-level logic gates and registers to cell library \item Write results to output file \end{itemize} \end{frame} @@ -64,8 +64,8 @@ all needed variations of parametric modules. # hierarchy -# recommended form. fail if parts of the design hierarchy are missing. remove -# everything that is unreachable by the top module. mark the top module. +# recommended form. fails if parts of the design hierarchy are missing, removes +# everything that is unreachable from the top module, and marks the top module. # hierarchy -check -top top_module \end{lstlisting} @@ -253,7 +253,7 @@ memory_dff # into one multi-port memory cell. memory_collect -# this takes the multi-port memory cells and transforms it to address decoder +# this takes the multi-port memory cell and transforms it to address decoder # logic and registers. This step is skipped if "memory" is called with -nomap. memory_map \end{lstlisting} @@ -279,7 +279,7 @@ memory -nomap; techmap -map my_memory_map.v; memory_map \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 2/2} -\vbox to 0cm{\hfill\includegraphics[width=7.5cm,trim=0cm 0cm 0cm -6cm]{PRESENTATION_ExSyn/memory_02.pdf}\vss} +\vbox to 0cm{\hfill\includegraphics[width=7.5cm,trim=0cm 0cm 0cm -5cm]{PRESENTATION_ExSyn/memory_02.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} @@ -303,11 +303,11 @@ fsm_detect # unless got option -nodetect fsm_extract fsm_opt -opt_clean +clean fsm_opt fsm_expand # if got option -expand -opt_clean # if got option -expand +clean # if got option -expand fsm_opt # if got option -expand fsm_recode # unless got option -norecode @@ -366,7 +366,7 @@ When {\tt techmap} is used without a map file, it uses a built-in map file to map all RTL cell types to a generic library of built-in logic gates and registers. \bigskip -\begin{block}{The build-in logic gate types are:} +\begin{block}{The built-in logic gate types are:} {\tt \$\_INV\_ \$\_AND\_ \$\_OR\_ \$\_XOR\_ \$\_MUX\_} \end{block} @@ -496,7 +496,7 @@ the next part (Section 3, ``Advanced Synthesis'') of this presentation.} \begin{itemize} \item Yosys provides commands for each phase of the synthesis. \item Each command solves a (more or less) simple problem. -\item Complex command are often only front-ends to simple commands. +\item Complex commands are often only front-ends to simple commands. \item {\tt proc; opt; memory; opt; fsm; opt; techmap; opt; abc;;} \end{itemize} diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 543fb41e..40b3c226 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -5,6 +5,7 @@ \sectionpage \end{frame} +\iffalse %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Representations of (digital) Circuits} @@ -51,6 +52,7 @@ \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\fi \subsection{Levels of Abstraction for Digital Circuits} @@ -74,7 +76,7 @@ \only<6>{Physical Gate Level}% \only<7>{Switch Level}} \only<1>{ - Overall view of the circuit: E.g. block-diagrams or instruction-set architecture descriptions + Overall view of the circuit. E.g. block-diagrams or instruction-set architecture descriptions. }% \only<2>{ Functional implementation of circuit in high-level programming language (C, C++, SystemC, Matlab, Python, etc.). @@ -94,7 +96,7 @@ \only<6>{ Netlist of cells that actually are available on the target architecture (such as CMOS gates in an ASCI or LUTs in an FPGA). Optimized for - area and/or and/or speed (static timing or number of logic levels). + area, power, and/or speed (static timing or number of logic levels). }% \only<7>{ Netlist of individual transistors. @@ -179,8 +181,8 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des This scripts contain three types of commands: \begin{itemize} \item {\bf Frontends}, that read input files (usually Verilog). - \item {\bf Passes}, that perform transformation on the design in memory. - \item {\bf Backends}, that write the design in memory to a file (various formats are available, e.g. Verilog, BLIF, EDIF, SPICE, BTOR, etc.). + \item {\bf Passes}, that perform transformations on the design in memory. + \item {\bf Backends}, that write the design in memory to a file (various formats are available: Verilog, BLIF, EDIF, SPICE, BTOR, \dots). \end{itemize} \bigskip @@ -247,26 +249,23 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Example Problem} +\subsection{Example Project} -\begin{frame}[fragile]{\subsecname{} -- Verilog Source: \tt counter.v} -\lstinputlisting[xleftmargin=1cm, language=Verilog]{PRESENTATION_Intro/counter.v} -\end{frame} - -\begin{frame}[fragile]{\subsecname{} -- Cell Library: \tt mycells.lib} -\begin{columns} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=liberty, lastline=20]{PRESENTATION_Intro/mycells.lib} -\column[t]{5cm} -\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=liberty, firstline=21]{PRESENTATION_Intro/mycells.lib} -\end{columns} +\begin{frame}[t]{\subsecname} +The following slides cover an example project. This project contains three files: +\begin{itemize} +\item A simple ASIC synthesis script +\item A digital design written in Verilog +\item A simple CMOS cell library +\end{itemize} +\vfill +Direct link to the files: \\ \footnotesize +\url{https://github.com/cliffordwolf/yosys/tree/master/manual/PRESENTATION_Intro} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Example Synthesis Script} - -\begin{frame}[t]{\subsecname} +\begin{frame}[t]{\subsecname{} -- Synthesis Script} \setbeamercolor{alerted text}{fg=white,bg=red} @@ -283,9 +282,6 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des \medskip {\color{YosysGreen}\# mapping to internal cell library}\\ \boxalert<9>{techmap}; \boxalert<10>{opt} - -\bigskip -\it continued\dots \end{minipage} \begin{minipage}[t]{5cm} \tt\scriptsize @@ -327,7 +323,7 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des }% \only<2>{ Elaborate the design hierarchy. Should always be the first - command after reading the design. + command after reading the design. Can re-run AST front-end. }% \only<3>{ Convert ``processes'' (the internal representation of behavioral @@ -373,6 +369,21 @@ as Qflow\footnote[frame]{\url{http://opencircuitdesign.com/qflow/}} for ASIC des %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{frame}[fragile]{\subsecname{} -- Verilog Source: \tt counter.v} +\lstinputlisting[xleftmargin=1cm, language=Verilog]{PRESENTATION_Intro/counter.v} +\end{frame} + +\begin{frame}[fragile]{\subsecname{} -- Cell Library: \tt mycells.lib} +\begin{columns} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=liberty, lastline=20]{PRESENTATION_Intro/mycells.lib} +\column[t]{5cm} +\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=liberty, firstline=21]{PRESENTATION_Intro/mycells.lib} +\end{columns} +\end{frame} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \subsection{Running the Synthesis Script} \begin{frame}[t, fragile]{\subsecname{} -- Step 1/4} @@ -410,8 +421,8 @@ abc -liberty mycells.lib clean \end{verbatim} -\vfill -\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_Intro/counter_03.pdf} +\vfill\hfil +\includegraphics[width=10cm,trim=0 0cm 0 0cm]{PRESENTATION_Intro/counter_03.pdf} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -422,7 +433,7 @@ clean Command reference: \begin{itemize} \item Use ``{\tt help}'' for a command list and ``{\tt help \it command}'' for details. -\item Or run ``{\tt yosys -H}'' and ``{\tt yosys -h \it command}''. +\item Or run ``{\tt yosys -H}'' or ``{\tt yosys -h \it command}''. \item Or go to \url{http://www.clifford.at/yosys/documentation.html}. \end{itemize} @@ -560,7 +571,7 @@ endmodule module cam(clk, wr_enable, wr_addr, wr_data, rd_data, rd_addr, rd_match); parameter WIDTH = 8; parameter DEPTH = 16; - localparam ADDR_BITS = $clog2(DEPTH); + localparam ADDR_BITS = $clog2(DEPTH-1); input clk, wr_enable; input [ADDR_BITS-1:0] wr_addr; @@ -595,7 +606,7 @@ Contiously checking the correctness of Yosys and making sure that new features do not break old ones is a high priority in Yosys. \bigskip -There are two external test suites build for Yosys: VlogHammer and yosys-bigsim +Two external test suites have been built for Yosys: VlogHammer and yosys-bigsim (see next slides) \bigskip @@ -608,8 +619,8 @@ the internal state after each command. \begin{frame}[fragile]{\subsecname{} -- VlogHammer} VlogHammer is a Verilog regression test suite developed to test the different -subsystems in Yosys by comparing them to each other and the implementations -generated by some proprietary tools (Xilinx Vivado, Xilinx XST, Altera Quartus II, ...). +subsystems in Yosys by comparing them to each other and to the output created +by some other tools (Xilinx Vivado, Xilinx XST, Altera Quartus II, ...). \bigskip Yosys Subsystems tested: Verilog frontend, const folding, const eval, technology mapping, @@ -624,8 +635,8 @@ assign y11 = (~&(-{(-3'sd3),($unsigned($signed($unsigned({p0,b4,b1}))))})); \end{lstlisting} \bigskip -Some bugs in Yosys where found and fixed thanks to VlogHammer. Over 20 bugs in -the proprietary tools used as external reference where found and reported. +Some bugs in Yosys where found and fixed thanks to VlogHammer. Over 50 bugs in +the other tools used as external reference where found and reported so far. \end{frame} \begin{frame}{\subsecname{} -- yosys-bigsim} @@ -634,7 +645,7 @@ benches. yosys-bigsim compares the testbench outpus of simulations of the origin Verilog code and synthesis results. \bigskip -The following designs are part of yosys-bigsim: +The following designs are included in yosys-bigsim (excerpt): \begin{itemize} \item {\tt openmsp430} -- an MSP430 compatible 16 bit CPU \item {\tt aes\_5cycle\_2stage} -- an AES encryption core @@ -651,6 +662,19 @@ The following designs are part of yosys-bigsim: \subsection{Benefits of Open Source HDL Synthesis} +\begin{frame}{\subsecname} +\begin{itemize} +\item Cost (also applies to ``free as in free beer'' solutions) +\item Availablity and Reproducability +\item Framework- and all-in-one-aspects +\item Educational Tool +\end{itemize} + +\bigskip + +Yosys is open source under the ISC license. +\end{frame} + \begin{frame}{\subsecname{} -- 1/3} \begin{itemize} \item Cost (also applies to ``free as in free beer'' solutions): \smallskip\par @@ -688,14 +712,13 @@ learn a new tool for each of this applications. \begin{frame}{\subsecname{} -- 3/3} \begin{itemize} \item Educational Tool: \smallskip\par -Propritaery synthesis tools are at times where secretive about their inner -workings. They often are ``black boxes'' where a design goes in and synthesis -results come out. Yosys is very open about its internals and it is easy to -observe the different steps of synthesis. +Propritaery synthesis tools are at times very secretive about their inner +workings. They often are ``black boxes''. Yosys is very open about its +internals and it is easy to observe the different steps of synthesis. \end{itemize} \bigskip -\begin{block}{BTW: Yosys is licensed under the ISC license:} +\begin{block}{Yosys is licensed under the ISC license:} 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. @@ -743,24 +766,24 @@ but also formal verification, reverse engineering, ...} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{What the Yosys project needs from you} +\subsection{Yosys needs you} \begin{frame}{\subsecname} -We need you as an active user: +\dots as an active user: \begin{itemize} -\item Use Yosys for on your own designs +\item Use Yosys for on your own projects \item .. even if you are not using it as final synthesis tool \item Join the discussion on the Subreddit \item Report bugs and send in feature requests \end{itemize} \bigskip -We need you as a developer: +\dots as a developer: \begin{itemize} -\item Use Yosys as environment for your research work +\item Use Yosys as environment for your (research) work \item .. you might also want to look into ABC for logic-level stuff \item Fork the project on github or create loadable plugins -\item We desperately need a VHDL frontend or a VHDL-to-Verilog converter +\item We need a VHDL frontend or a good VHDL-to-Verilog converter \end{itemize} \end{frame} diff --git a/manual/PRESENTATION_Intro/counter.ys b/manual/PRESENTATION_Intro/counter.ys index bcfe387e..8b3390ed 100644 --- a/manual/PRESENTATION_Intro/counter.ys +++ b/manual/PRESENTATION_Intro/counter.ys @@ -2,17 +2,18 @@ read_verilog counter.v hierarchy -check -top counter -show -stretch -format pdf -prefix counter_00 +show -notitle -stretch -format pdf -prefix counter_00 # the high-level stuff proc; opt; memory; opt; fsm; opt -show -stretch -format pdf -prefix counter_01 +show -notitle -stretch -format pdf -prefix counter_01 # mapping to internal cell library -techmap; splitnets -ports; opt +techmap; opt -show -stretch -format pdf -prefix counter_02 +splitnets -ports;; +show -notitle -stretch -format pdf -prefix counter_02 # mapping flip-flops to mycells.lib dfflibmap -liberty mycells.lib @@ -23,4 +24,4 @@ abc -liberty mycells.lib # cleanup clean -show -stretch -lib mycells.v -format pdf -prefix counter_03 +show -notitle -stretch -lib mycells.v -format pdf -prefix counter_03 diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index 1e7f697b..21a93d55 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -1,5 +1,5 @@ -\section{Programming Yosys Extensions} +\section{Writing Yosys extensions in C++} \begin{frame} \sectionpage @@ -43,8 +43,9 @@ \subsection{Simplified RTLIL Entity-Relationship Diagram} \begin{frame}{\subsecname} -Between passses and frontends/backends the design in stored in Yosys' internal RTLIL (RTL Intermediate Language) format. For -writing Yosys extensions it is key to understand this format. +Between passses and frontends/backends the design is stored in Yosys' internal +RTLIL (RTL Intermediate Language) format. For writing Yosys extensions it is +key to understand this format. \bigskip \begin{center} @@ -71,7 +72,8 @@ writing Yosys extensions it is key to understand this format. \subsection{RTLIL without memories and processes} \begin{frame}[fragile]{\subsecname} -After the command {\tt proc} and {\tt memory} (or {\tt memory -nomap}), we are left with a much simpler version of RTLIL: +After the commands {\tt proc} and {\tt memory} (or {\tt memory -nomap}), we are +left with a much simpler version of RTLIL: \begin{center} \begin{tikzpicture}[scale=0.6, every node/.style={transform shape}] @@ -85,7 +87,7 @@ After the command {\tt proc} and {\tt memory} (or {\tt memory -nomap}), we are l \end{center} \bigskip -Many command simply choose to only work on this simpler version: +Many commands simply choose to only work on this simpler version: \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont] if (module->processes.size() != 0 || module->memories.size() != 0) log_error("This command does not operate on modules with processes " @@ -256,7 +258,7 @@ a {\tt RTLIL::SigChunk}: \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=C++] struct RTLIL::SigChunk { RTLIL::Wire *wire; - RTLIL::Const data; // only used if wire == NULL, LSB at index 0 + RTLIL::Const data; // only used if wire == NULL int width, offset; ... }; @@ -276,7 +278,7 @@ manipulate instances of {\tt RTLIL::SigSpec}. \subsubsection{The RTLIL::Cell Structure} \begin{frame}[t, fragile]{\subsubsecname (1/2)} -The {\tt RTLIL::Cell} strcut represents an instance of a module or library cell. +The {\tt RTLIL::Cell} struct represents an instance of a module or library cell. \smallskip The ports of the cell @@ -310,7 +312,7 @@ $_DLATCHSR_NPN_ $_DLATCHSR_NPP_ $_DLATCHSR_PNN_ $_DLATCHSR_PNP_ $_DLATCHSR_PPN_ \end{frame} \begin{frame}[t, fragile]{\subsubsecname (2/2)} -Simulation models (i.e. {\it documentation\/}) for the internal cell library: +Simulation models (i.e. {\it documentation\/} :-) for the internal cell library: \smallskip \hskip2em {\tt yosys/techlibs/common/simlib.v} and \\ @@ -318,11 +320,11 @@ Simulation models (i.e. {\it documentation\/}) for the internal cell library: \bigskip The lower-case cell types (such as {\tt \$and}) are parameterized cells of variable -width. This so-called {\it RTL cells\/} are the cells described in {\tt simlib.v}. +width. This so-called {\it RTL Cells\/} are the cells described in {\tt simlib.v}. \bigskip -The upper-case cell types (such as {\tt \$\_AND\_}) single-bit cells that are not -parameterized. This so-called {\it internal Logic Gates} are the cells described +The upper-case cell types (such as {\tt \$\_AND\_}) are single-bit cells that are not +parameterized. This so-called {\it Internal Logic Gates} are the cells described in {\tt simcells.v}. \bigskip diff --git a/manual/presentation.tex b/manual/presentation.tex index 35a409cb..d098e815 100644 --- a/manual/presentation.tex +++ b/manual/presentation.tex @@ -81,7 +81,7 @@ \title{Yosys Open SYnthesis Suite} \author{Clifford Wolf} -\institute{http://www.clifford.at/} +\institute{http://www.clifford.at/yosys/} \usetheme{Madrid} \usecolortheme{seagull} @@ -133,7 +133,7 @@ Outline of this presentation: \item Yosys by example: synthesis \item Yosys by example: advanced synthesis \item Yosys by example: beyond synthesis -\item Programming Yosys extensions +\item Writing Yosys extensions in C++ \end{itemize} \end{frame} From 89c85cac419b7dc60e3776a250bcdc39dcb8980b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 28 Jun 2014 12:11:42 +0200 Subject: [PATCH 268/750] Added links to some liberty files to README --- README | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README b/README index ba90e72a..4384cfbd 100644 --- a/README +++ b/README @@ -192,6 +192,14 @@ for the given cell library: If you do not have a liberty file but want to test this synthesis script, you can use the file techlibs/cmos/cmos_cells.lib from the yosys sources. +Various more complex liberty files (for testing) can be found here: + + http://vlsiarch.ecen.okstate.edu/flows/MOSIS_SCMOS/latest/.. + ../cadence/lib/tsmc025/signalstorm/osu025_stdcells.lib + ../cadence/lib/ami035/signalstorm/osu035_stdcells.lib + ../cadence/lib/tsmc018/signalstorm/osu018_stdcells.lib + ../cadence/lib/ami05/signalstorm/osu05_stdcells.lib + Yosys is under construction. A more detailed documentation will follow. From 3a3f5d5923840f44a6fb30fc7d70b6ed6ad7ccbb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 29 Jun 2014 09:14:49 +0200 Subject: [PATCH 269/750] Progress in presentation --- manual/PRESENTATION_Intro.tex | 78 +++++++++++++++++++++++++++++++++++ manual/presentation.tex | 19 +++++++++ 2 files changed, 97 insertions(+) diff --git a/manual/PRESENTATION_Intro.tex b/manual/PRESENTATION_Intro.tex index 40b3c226..7697266d 100644 --- a/manual/PRESENTATION_Intro.tex +++ b/manual/PRESENTATION_Intro.tex @@ -599,6 +599,23 @@ endmodule %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Currently unsupported Verilog-2005 language features} + +\begin{frame}{\subsecname} +\begin{itemize} +\item Multi-dimensional arrays (memories) +\item Writing to arrays using bit- and part-selects (todo for 0.4.0) +\item The wor/wand wire types (maybe for 0.4.0) +\item Tri-state logic + +\bigskip +\item Latched logic (is synthesized as logic with feedback loops) +\item Some non-synthesizable features that should be ignored in synthesis are not supported by the parser and cause a parser error (file a bug report if you encounter this problem) +\end{itemize} +\end{frame} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \subsection{Verification of Yosys} \begin{frame}{\subsecname} @@ -744,6 +761,67 @@ but also formal verification, reverse engineering, ...} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\subsection{Projects (that I know of) using Yosys} + +\begin{frame}{\subsecname{} -- (1/2)} +\begin{itemize} +\item Ongoing PhD project on coarse grain synthesis \\ +{\setlength{\parindent}{0.5cm}\footnotesize +Johann Glaser and Clifford Wolf. Methodology and Example-Driven Interconnect +Synthesis for Designing Heterogeneous Coarse-Grain Reconfigurable +Architectures. In Jan Haase, editor, \it Models, Methods, and Tools for Complex +Chip Design. Lecture Notes in Electrical Engineering. Volume 265, 2014, pp +201-221. Springer, 2013.} + +\bigskip +\item I know several people that use Yosys simply as Verilog frontend for other +flows (using either the BLIF and BTOR backends). + +\bigskip +\item I know some analog chip designers that use Yosys for small digital +control logic because it is simpler than setting up a commercial flow. +\end{itemize} +\end{frame} + +\begin{frame}{\subsecname{} -- (2/2)} +\begin{itemize} +\item Efabless +\begin{itemize} +\smallskip \item Not much information on the website (\url{http://efabless.com}) yet. +\smallskip \item Very cheap 180nm prototyping process (partnering with various fabs) +\smallskip \item A semiconductor company, NOT an EDA company +\smallskip \item Web-based design environment +\smallskip \item HDL Synthesis using Yosys +\smallskip \item Custom place\&route tool + +\bigskip +\item efabless is building an Open Source IC as reference design. \\ +\hskip1cm (to be announced soon: \url{http://www.openic.io}) +\end{itemize} +\end{itemize} +\end{frame} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Supported Platforms} + +\begin{frame}{\subsecname} +\begin{itemize} +\item Main development OS: Kubuntu 14.04 +\item There is a PPA for ubuntu (not maintained by me) +\item Any current Debian-based system should work out of the box +\item When building on other Linux distributions: +\begin{itemize} +\item Needs compiler with some C++11 support +\item Post to the subreddit if you get stuck +\end{itemize} +\item Ported to OS X (Darwin) and OpenBSD +\item No win32 support (yet) +\end{itemize} +\end{frame} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \subsection{Other Open Source Tools} \begin{frame}{\subsecname} diff --git a/manual/presentation.tex b/manual/presentation.tex index d098e815..a76a1c00 100644 --- a/manual/presentation.tex +++ b/manual/presentation.tex @@ -122,6 +122,25 @@ non-synthesis applications (such as formal equivialence checking) and writing extensions to Yosys using the C++ API. \end{frame} +\section{About me} +\begin{frame}{About me} +Hi! I'm Clifford Wolf. + +\bigskip +I like writing open source software. For example: +\begin{itemize} +\item Yosys +\item OpenSCAD (now maintained by Marius Kintel) +\item SPL (a not very popular scripting language) +\item EmbedVM (a very simple colipler+vm for 8 bit micros) +\item Lib(X)SVF (a library to play SVF/XSVF files over JTAG, used at LHC) +\item ROCK Linux (inactive since 2010) +\end{itemize} + +\bigskip +What do I do for a living? Ask me off the record.. +\end{frame} + \section{Outline} \begin{frame}{Outline} Yosys is an Open Source Verilog synthesis tool, and more. From d26561cc44d90bd83a7c55d5270bf4cbade0a8f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 29 Jun 2014 09:27:03 +0200 Subject: [PATCH 270/750] Tiny fix in presentation --- manual/presentation.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manual/presentation.tex b/manual/presentation.tex index a76a1c00..cad9e9f1 100644 --- a/manual/presentation.tex +++ b/manual/presentation.tex @@ -102,7 +102,7 @@ \titlepage \end{frame} -\setcounter{section}{-2} +\setcounter{section}{-3} \section{Abstract} \begin{frame}{Abstract} From 1c81ab49e7b57f4c64e533a3617fe8bbe257cdb5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Jul 2014 06:16:31 +0200 Subject: [PATCH 271/750] small changes in presentation --- manual/presentation.tex | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/manual/presentation.tex b/manual/presentation.tex index cad9e9f1..9a876de0 100644 --- a/manual/presentation.tex +++ b/manual/presentation.tex @@ -132,13 +132,10 @@ I like writing open source software. For example: \item Yosys \item OpenSCAD (now maintained by Marius Kintel) \item SPL (a not very popular scripting language) -\item EmbedVM (a very simple colipler+vm for 8 bit micros) +\item EmbedVM (a very simple compiler+vm for 8 bit micros) \item Lib(X)SVF (a library to play SVF/XSVF files over JTAG, used at LHC) -\item ROCK Linux (inactive since 2010) +\item ROCK Linux (discontinued since 2010) \end{itemize} - -\bigskip -What do I do for a living? Ask me off the record.. \end{frame} \section{Outline} From ee8ad72fd950e1ee204e5c97155a50b8b1445dec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Jul 2014 06:27:04 +0200 Subject: [PATCH 272/750] fixed parsing of constant with comment between size and value --- frontends/verilog/parser.y | 7 +++++++ tests/simple/macros.v | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 37c3232a..ce7b9927 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) diff --git a/tests/simple/macros.v b/tests/simple/macros.v index cda46cb4..a3e8d70f 100644 --- a/tests/simple/macros.v +++ b/tests/simple/macros.v @@ -235,3 +235,10 @@ always @* begin end endmodule + +`define SIZE 4 // comment supported in this part +module test ( din_a, dout_a ); +input [`SIZE-1:0] din_a; +output [`SIZE-1:0] dout_a; +assign dout_a = din_a | `SIZE'ha; +endmodule From 3b52121d328d45a5d4269fd0e8de9af948c0216e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 5 Jul 2014 11:17:40 +0200 Subject: [PATCH 273/750] now ignore init attributes on non-register wires in sat command --- passes/sat/sat.cc | 28 ++++++++++++++++++++++++---- tests/sat/initval.v | 15 +++++++++++++++ tests/sat/initval.ys | 4 ++++ 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 tests/sat/initval.v create mode 100644 tests/sat/initval.ys diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 87bff4c4..a9a00d8a 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -103,10 +103,30 @@ struct SatHelper RTLIL::SigSpec rhs = it.second->attributes.at("\\init"); log_assert(lhs.width == rhs.width); - log("Import set-constraint from init attribute: %s = %s\n", log_signal(lhs), log_signal(rhs)); - big_lhs.remove2(lhs, &big_rhs); - big_lhs.append(lhs); - big_rhs.append(rhs); + RTLIL::SigSpec removed_bits; + for (int i = 0; i < lhs.width; i++) { + RTLIL::SigSpec bit = lhs.extract(i, 1); + if (!satgen.initial_state.check_all(bit)) { + removed_bits.append(bit); + lhs.remove(i, 1); + rhs.remove(i, 1); + i--; + } + } + + lhs.optimize(); + rhs.optimize(); + removed_bits.optimize(); + + if (removed_bits.width) + log("Warning: ignoring initial value on non-register: %s\n", log_signal(removed_bits)); + + if (lhs.width) { + log("Import set-constraint from init attribute: %s = %s\n", log_signal(lhs), log_signal(rhs)); + big_lhs.remove2(lhs, &big_rhs); + big_lhs.append(lhs); + big_rhs.append(rhs); + } } for (auto &s : sets_init) diff --git a/tests/sat/initval.v b/tests/sat/initval.v new file mode 100644 index 00000000..5b661f8d --- /dev/null +++ b/tests/sat/initval.v @@ -0,0 +1,15 @@ +module test(input clk, input [3:0] bar, output [3:0] foo); + reg [3:0] foo = 0; + reg [3:0] last_bar = 0; + + always @* + foo[1:0] <= bar[1:0]; + + always @(posedge clk) + foo[3:2] <= bar[3:2]; + + always @(posedge clk) + last_bar <= bar; + + assert property (foo == {last_bar[3:2], bar[1:0]}); +endmodule diff --git a/tests/sat/initval.ys b/tests/sat/initval.ys new file mode 100644 index 00000000..2079d2f3 --- /dev/null +++ b/tests/sat/initval.ys @@ -0,0 +1,4 @@ +read_verilog -sv initval.v +proc;; + +sat -seq 10 -prove-asserts From 55a1b8dbac91373979289c535bed61a32717f62b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 11 Jul 2014 13:05:53 +0200 Subject: [PATCH 274/750] Fixed processing of initial values for block-local variables --- frontends/ast/simplify.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index db7f5ca3..e547ede3 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)) From 847e2ee4a130559f7ee002542560a9fcbe1dfc71 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 11 Jul 2014 13:10:51 +0200 Subject: [PATCH 275/750] Use "verilog -sv" to parse .sv files --- kernel/driver.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/driver.cc b/kernel/driver.cc index da4962b8..577fbe3d 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -54,6 +54,8 @@ static void run_frontend(std::string filename, std::string command, RTLIL::Desig if (command == "auto") { if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") command = "verilog"; + else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") + command = "verilog -sv"; else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") command = "ilang"; else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") From 0f9ca49dc6047ad5634782de23040ec57601debd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 12 Jul 2014 10:02:39 +0200 Subject: [PATCH 276/750] Added passing of various options to vhdl2verilog --- frontends/vhdl2verilog/vhdl2verilog.cc | 41 ++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 83035d32..4392ed44 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()); From 964a67ac4194bb85fb3cb7a90a62dc1e4a685ea4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 10:03:07 +0200 Subject: [PATCH 277/750] Added note to "make test": use git checkout of iverilog --- tests/asicworld/run-test.sh | 2 +- tests/hana/run-test.sh | 2 +- tests/realmath/run-test.sh | 1 + tests/simple/run-test.sh | 2 +- tests/tools/autotest.sh | 13 +++++++++++-- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/tests/asicworld/run-test.sh b/tests/asicworld/run-test.sh index 9153f55f..a204360d 100755 --- a/tests/asicworld/run-test.sh +++ b/tests/asicworld/run-test.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec bash ../tools/autotest.sh *.v +exec bash ../tools/autotest.sh -G *.v diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh index 199bb916..89be6d05 100755 --- a/tests/hana/run-test.sh +++ b/tests/hana/run-test.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec bash ../tools/autotest.sh -l hana_vlib.v test_*.v +exec bash ../tools/autotest.sh -G -l hana_vlib.v test_*.v diff --git a/tests/realmath/run-test.sh b/tests/realmath/run-test.sh index a28863d3..b8e222ad 100755 --- a/tests/realmath/run-test.sh +++ b/tests/realmath/run-test.sh @@ -15,6 +15,7 @@ for ((i = 0; i < 100; i++)); do iverilog -o uut_${idx}_tb uut_${idx}_tb.v uut_${idx}.v uut_${idx}_syn.v ./uut_${idx}_tb | tee uut_${idx}.err if test -s uut_${idx}.err; then + echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of icarus verilog." exit 1 fi rm -f uut_${idx}.err diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh index 3d00c7eb..ec1802cb 100755 --- a/tests/simple/run-test.sh +++ b/tests/simple/run-test.sh @@ -6,4 +6,4 @@ if ! which iverilog > /dev/null ; then exit 1 fi -exec bash ../tools/autotest.sh *.v +exec bash ../tools/autotest.sh -G *.v diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index d459f988..ff431eaf 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -11,17 +11,20 @@ backend_opts="-noattr -noexpr" scriptfiles="" scriptopt="" toolsdir="$(cd $(dirname $0); pwd)" +warn_iverilog_git=false if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdata ]; then ( set -ex; gcc -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1 fi -while getopts xml:wkvrf:s:p: opt; do +while getopts xmGl:wkvrf:s:p: opt; do case "$opt" in x) use_xsim=true ;; m) use_modelsim=true ;; + G) + warn_iverilog_git=true ;; l) libs="$libs $(cd $(dirname $OPTARG); pwd)/$(basename $OPTARG)";; w) @@ -145,7 +148,13 @@ do elif [ -f ${bn}.skip ]; then mv ${bn}.err ${bn}.skip echo "-> skip" - else echo "-> ERROR!"; $keeprunning || exit 1; fi + else + echo "-> ERROR!" + if $warn_iverilog_git; then + echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of icarus verilog." + fi + $keeprunning || exit 1 + fi done exit 0 From 73e0e13d2f1b959a05d69ed715c8fdde84894d6f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 11:38:02 +0200 Subject: [PATCH 278/750] Changed the $mem/$memwr WR_EN input to a per-data-bit enable signal --- kernel/rtlil.cc | 4 ++-- manual/CHAPTER_CellLib.tex | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 028cd6d8..c4c08d5b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -619,7 +619,7 @@ namespace { param_bool("\\CLK_POLARITY"); param("\\PRIORITY"); port("\\CLK", 1); - port("\\EN", 1); + port("\\EN", param("\\WIDTH")); port("\\ADDR", param("\\ABITS")); port("\\DATA", param("\\WIDTH")); check_expected(); @@ -639,7 +639,7 @@ namespace { port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS")); port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH")); port("\\WR_CLK", param("\\WR_PORTS")); - port("\\WR_EN", param("\\WR_PORTS")); + port("\\WR_EN", param("\\WR_PORTS") * param("\\WIDTH")); port("\\WR_ADDR", param("\\WR_PORTS") * param("\\ABITS")); port("\\WR_DATA", param("\\WR_PORTS") * param("\\WIDTH")); check_expected(); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index e7895521..f09c4929 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -256,8 +256,9 @@ If this parameter is set to {\tt 1'b1}, a read and write to the same address in return the new value. Otherwise the old value is returned. \end{itemize} -The {\tt \$memwr} cells have a clock input \B{CLK}, an enable input \B{EN}, an address input \B{ADDR} -and a data input \B{DATA}. They also have the following parameters: +The {\tt \$memwr} cells have a clock input \B{CLK}, an enable input \B{EN} (one +enable bit for each data bit), an address input \B{ADDR} and a data input +\B{DATA}. They also have the following parameters: \begin{itemize} \item \B{MEMID} \\ @@ -341,7 +342,7 @@ This input is \B{RD\_PORTS}*\B{WIDTH} bits wide, containing all data signals for This input is \B{WR\_PORTS} bits wide, containing all clock signals for the write ports. \item \B{WR\_EN} \\ -This input is \B{WR\_PORTS} bits wide, containing all enable signals for the write ports. +This input is \B{WR\_PORTS}*\B{WIDTH} bits wide, containing all enable signals for the write ports. \item \B{WR\_ADDR} \\ This input is \B{WR\_PORTS}*\B{ABITS} bits wide, containing all address signals for the write ports. From dcdd5c11b4ebbf983f3ab7fc5304d980cc47302d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 11:46:40 +0200 Subject: [PATCH 279/750] Updated simlib to new $mem/$memwr interface --- techlibs/common/simlib.v | 85 ++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index be9d24f1..9c774dea 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1264,7 +1264,8 @@ parameter WIDTH = 8; parameter CLK_ENABLE = 0; parameter CLK_POLARITY = 0; -input CLK, EN; +input CLK; +input [WIDTH-1:0] EN; input [ABITS-1:0] ADDR; input [WIDTH-1:0] DATA; @@ -1300,7 +1301,8 @@ input [RD_PORTS-1:0] RD_CLK; input [RD_PORTS*ABITS-1:0] RD_ADDR; output reg [RD_PORTS*WIDTH-1:0] RD_DATA; -input [WR_PORTS-1:0] WR_CLK, WR_EN; +input [WR_PORTS-1:0] WR_CLK; +input [WR_PORTS*WIDTH-1:0] WR_EN; input [WR_PORTS*ABITS-1:0] WR_ADDR; input [WR_PORTS*WIDTH-1:0] WR_DATA; @@ -1338,46 +1340,69 @@ generate end for (i = 0; i < WR_PORTS; i = i+1) begin:wr - integer k; - reg found_collision; + integer k, n; + reg found_collision, run_update; if (WR_CLK_ENABLE[i] == 0) begin:wr_noclk always @(WR_ADDR or WR_DATA or WR_EN) begin - if (WR_EN[i]) begin - found_collision = 0; - for (k = i+1; k < WR_PORTS; k = k+1) - if (WR_EN[k] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) - found_collision = 1; - if (!found_collision) begin - data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ] <= WR_DATA[ i*WIDTH +: WIDTH ]; - update_async_rd <= 1; update_async_rd <= 0; + run_update = 0; + for (n = 0; n < WIDTH; n = n+1) begin + if (WR_EN[i][n]) begin + found_collision = 0; + for (k = i+1; k < WR_PORTS; k = k+1) + if (WR_EN[k][n] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) + found_collision = 1; + if (!found_collision) begin + data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ][n] <= WR_DATA[ i*WIDTH +: WIDTH ][n]; + run_update = 1; + end end end + if (run_update) begin + update_async_rd <= 1; + update_async_rd <= 0; + end end end else if (WR_CLK_POLARITY[i] == 1) begin:rd_posclk - always @(posedge WR_CLK[i]) - if (WR_EN[i]) begin - found_collision = 0; - for (k = i+1; k < WR_PORTS; k = k+1) - if (WR_EN[k] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) - found_collision = 1; - if (!found_collision) begin - data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ] <= WR_DATA[ i*WIDTH +: WIDTH ]; - update_async_rd <= 1; update_async_rd <= 0; + always @(posedge WR_CLK[i]) begin + run_update = 0; + for (n = 0; n < WIDTH; n = n+1) begin + if (WR_EN[i][n]) begin + found_collision = 0; + for (k = i+1; k < WR_PORTS; k = k+1) + if (WR_EN[k][n] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) + found_collision = 1; + if (!found_collision) begin + data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ][n] <= WR_DATA[ i*WIDTH +: WIDTH ][n]; + run_update = 1; + end end end + if (run_update) begin + update_async_rd <= 1; + update_async_rd <= 0; + end + end end else begin:rd_negclk - always @(negedge WR_CLK[i]) - if (WR_EN[i]) begin - found_collision = 0; - for (k = i+1; k < WR_PORTS; k = k+1) - if (WR_EN[k] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) - found_collision = 1; - if (!found_collision) begin - data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ] <= WR_DATA[ i*WIDTH +: WIDTH ]; - update_async_rd <= 1; update_async_rd <= 0; + always @(negedge WR_CLK[i]) begin + run_update = 0; + for (n = 0; n < WIDTH; n = n+1) begin + if (WR_EN[i][n]) begin + found_collision = 0; + for (k = i+1; k < WR_PORTS; k = k+1) + if (WR_EN[k][n] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) + found_collision = 1; + if (!found_collision) begin + data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ][n] <= WR_DATA[ i*WIDTH +: WIDTH ][n]; + run_update = 1; + end end end + if (run_update) begin + update_async_rd <= 1; + update_async_rd <= 0; + end + end end end From 765f172211c8d7d8f14b6010193d8b53f5ec5e8f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 12:13:13 +0200 Subject: [PATCH 280/750] Changes to "memory" pass for new $memwr/$mem WR_EN interface --- passes/memory/memory_collect.cc | 4 +- passes/memory/memory_map.cc | 88 ++++++++++++++++++++------------- passes/memory/memory_unpack.cc | 2 +- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 6fe5e162..028841f6 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -88,7 +88,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) clk_polarity.extend(1, false); addr.extend(addr_bits, false); data.extend(memory->width, false); - en.extend(1, false); + en.extend(memory->width, false); sig_wr_clk.append(clk); sig_wr_clk_enable.append(clk_enable); @@ -147,7 +147,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) assert(sig_wr_clk_polarity.width == wr_ports && sig_wr_clk_polarity.is_fully_const()); assert(sig_wr_addr.width == wr_ports * addr_bits); assert(sig_wr_data.width == wr_ports * memory->width); - assert(sig_wr_en.width == wr_ports); + assert(sig_wr_en.width == wr_ports * memory->width); mem->parameters["\\WR_PORTS"] = RTLIL::Const(wr_ports); mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.chunks[0].data : RTLIL::Const(0, 0); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index e0e3802d..10ab6e2f 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -69,8 +69,8 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec refclock; RTLIL::State refclock_pol = RTLIL::State::Sx; for (int i = 0; i < clocks.width; i++) { - RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(i, 1); - if (wr_en.is_fully_const() && wr_en.as_int() == 0) { + RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(i * mem_width, mem_width); + if (wr_en.is_fully_const() && !wr_en.as_bool()) { static_ports.insert(i); continue; } @@ -256,7 +256,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) { RTLIL::SigSpec wr_addr = cell->connections["\\WR_ADDR"].extract(j*mem_abits, mem_abits); RTLIL::SigSpec wr_data = cell->connections["\\WR_DATA"].extract(j*mem_width, mem_width); - RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(j, 1); + RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(j*mem_width, mem_width); RTLIL::Cell *c = new RTLIL::Cell; c->name = genid(cell->name, "$wreq", i, "", j); @@ -271,46 +271,64 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) module->cells[c->name] = c; count_wrmux++; - RTLIL::Wire *w = new RTLIL::Wire; - w->name = genid(cell->name, "$wreq", i, "", j, "$y"); - module->wires[w->name] = w; - c->connections["\\Y"] = RTLIL::SigSpec(w); + RTLIL::Wire *w_seladdr = new RTLIL::Wire; + w_seladdr->name = genid(cell->name, "$wreq", i, "", j, "$y"); + module->wires[w_seladdr->name] = w_seladdr; + c->connections["\\Y"] = w_seladdr; - if (wr_en != RTLIL::SigSpec(1, 1)) + int wr_offset = 0; + while (wr_offset < wr_en.width) { + int wr_width = 1; + RTLIL::SigSpec wr_bit = wr_en.extract(wr_offset, 1); + + while (wr_offset + wr_width < wr_en.width) { + RTLIL::SigSpec next_wr_bit = wr_en.extract(wr_offset + wr_width, 1); + if (next_wr_bit != wr_bit) + break; + wr_width++; + } + + RTLIL::Wire *w = w_seladdr; + + if (wr_bit != RTLIL::SigSpec(1, 1)) + { + c = new RTLIL::Cell; + c->name = genid(cell->name, "$wren", i, "", j, "", wr_offset); + c->type = "$and"; + c->parameters["\\A_SIGNED"] = RTLIL::Const(0); + c->parameters["\\B_SIGNED"] = RTLIL::Const(0); + c->parameters["\\A_WIDTH"] = RTLIL::Const(1); + c->parameters["\\B_WIDTH"] = RTLIL::Const(1); + c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); + c->connections["\\A"] = w; + c->connections["\\B"] = wr_bit; + module->cells[c->name] = c; + + w = new RTLIL::Wire; + w->name = genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"); + module->wires[w->name] = w; + c->connections["\\Y"] = RTLIL::SigSpec(w); + } + c = new RTLIL::Cell; - c->name = genid(cell->name, "$wren", i, "", j); - c->type = "$and"; - c->parameters["\\A_SIGNED"] = RTLIL::Const(0); - c->parameters["\\B_SIGNED"] = RTLIL::Const(0); - c->parameters["\\A_WIDTH"] = RTLIL::Const(1); - c->parameters["\\B_WIDTH"] = RTLIL::Const(1); - c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->connections["\\A"] = RTLIL::SigSpec(w); - c->connections["\\B"] = wr_en; + c->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset); + c->type = "$mux"; + c->parameters["\\WIDTH"] = wr_width; + c->connections["\\A"] = sig.extract(wr_offset, wr_width); + c->connections["\\B"] = wr_data.extract(wr_offset, wr_width); + c->connections["\\S"] = RTLIL::SigSpec(w); module->cells[c->name] = c; w = new RTLIL::Wire; - w->name = genid(cell->name, "$wren", i, "", j, "$y"); + w->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"); + w->width = wr_width; module->wires[w->name] = w; - c->connections["\\Y"] = RTLIL::SigSpec(w); + c->connections["\\Y"] = w; + + sig.replace(wr_offset, w); + wr_offset += wr_width; } - - c = new RTLIL::Cell; - c->name = genid(cell->name, "$wrmux", i, "", j); - c->type = "$mux"; - c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; - c->connections["\\A"] = sig; - c->connections["\\B"] = wr_data; - c->connections["\\S"] = RTLIL::SigSpec(w); - module->cells[c->name] = c; - - w = new RTLIL::Wire; - w->name = genid(cell->name, "$wrmux", i, "", j, "$y"); - w->width = mem_width; - module->wires[w->name] = w; - c->connections["\\Y"] = RTLIL::SigSpec(w); - sig = RTLIL::SigSpec(w); } module->connections.push_back(RTLIL::SigSig(data_reg_in[i], sig)); diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 782c0cd7..bbd01583 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -74,7 +74,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const(); cell->parameters["\\PRIORITY"] = i; cell->connections["\\CLK"] = memory->connections.at("\\WR_CLK").extract(i, 1); - cell->connections["\\EN"] = memory->connections.at("\\WR_EN").extract(i, 1); + cell->connections["\\EN"] = memory->connections.at("\\WR_EN").extract(i*mem->width, mem->width); cell->connections["\\ADDR"] = memory->connections.at("\\WR_ADDR").extract(i*abits, abits); cell->connections["\\DATA"] = memory->connections.at("\\WR_DATA").extract(i*mem->width, mem->width); module->add(cell); From 543551b80a257ce0d55ce2d97fed165da7750360 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 12:23:47 +0200 Subject: [PATCH 281/750] 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(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 787f4d2d..a2fdcf8b 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 e547ede3..ba0dca13 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); From d678b6533dfac431a36abd22c01e9df184b723a4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 13:37:41 +0200 Subject: [PATCH 282/750] improved opt_reduce for $mem/$memwr WR_EN multiplexers --- passes/opt/opt_reduce.cc | 80 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index dfe21441..d5bcb7f0 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -171,6 +171,66 @@ struct OptReduceWorker } } + void opt_mux_bits(RTLIL::Cell *cell) + { + std::vector sig_a = assign_map(cell->connections["\\A"]).to_sigbit_vector(); + std::vector sig_b = assign_map(cell->connections["\\B"]).to_sigbit_vector(); + std::vector sig_y = assign_map(cell->connections["\\Y"]).to_sigbit_vector(); + + std::vector new_sig_y; + RTLIL::SigSig old_sig_conn; + + std::vector> consolidated_in_tuples; + std::map, RTLIL::SigBit> consolidated_in_tuples_map; + + for (int i = 0; i < int(sig_y.size()); i++) + { + std::vector in_tuple; + in_tuple.push_back(sig_a.at(i)); + for (int j = i; j < int(sig_b.size()); j += int(sig_a.size())) + in_tuple.push_back(sig_b.at(j)); + + if (consolidated_in_tuples_map.count(in_tuple)) + { + old_sig_conn.first.append_bit(sig_y.at(i)); + old_sig_conn.second.append_bit(consolidated_in_tuples_map.at(in_tuple)); + } + else + { + consolidated_in_tuples_map[in_tuple] = sig_y.at(i); + consolidated_in_tuples.push_back(in_tuple); + new_sig_y.push_back(sig_y.at(i)); + } + } + + if (new_sig_y.size() != sig_y.size()) + { + log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); + log(" Old inputs: A=%s, B=%s\n", log_signal(cell->connections["\\A"]), log_signal(cell->connections["\\B"])); + + cell->connections["\\A"] = RTLIL::SigSpec(); + for (auto &in_tuple : consolidated_in_tuples) + cell->connections["\\A"].append(in_tuple.at(0)); + + cell->connections["\\B"] = RTLIL::SigSpec(); + for (int i = 1; i <= cell->connections["\\S"].width; i++) + for (auto &in_tuple : consolidated_in_tuples) + cell->connections["\\B"].append(in_tuple.at(i)); + + log(" New inputs: A=%s, B=%s\n", log_signal(cell->connections["\\A"]), log_signal(cell->connections["\\B"])); + + cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); + cell->connections["\\Y"] = new_sig_y; + + module->connections.push_back(old_sig_conn); + module->check(); + + did_something = true; + OPT_DID_SOMETHING = true; + total_count++; + } + } + OptReduceWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), assign_map(module) { @@ -179,6 +239,20 @@ struct OptReduceWorker total_count = 0; did_something = true; + SigPool mem_wren_sigs; + for (auto &cell_it : module->cells) { + RTLIL::Cell *cell = cell_it.second; + if (cell->type == "$mem") + mem_wren_sigs.add(assign_map(cell->connections["\\WR_EN"])); + if (cell->type == "$memwr") + mem_wren_sigs.add(assign_map(cell->connections["\\EN"])); + } + for (auto &cell_it : module->cells) { + RTLIL::Cell *cell = cell_it.second; + if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->connections["\\Q"]))) + mem_wren_sigs.add(assign_map(cell->connections["\\D"])); + } + while (did_something) { did_something = false; @@ -213,6 +287,12 @@ struct OptReduceWorker RTLIL::Cell *cell = cell_it.second; if ((cell->type != "$mux" && cell->type != "$pmux" && cell->type != "$safe_pmux") || !design->selected(module, cell)) continue; + + // this optimization is to aggressive for most coarse-grain applications. + // but we always want it for multiplexers driving write enable ports. + if (mem_wren_sigs.check_any(assign_map(cell->connections.at("\\Y")))) + opt_mux_bits(cell); + opt_mux(cell); } } From 73a345294a0c4639b6339ee20e5ca942c963f2f4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 13:46:27 +0200 Subject: [PATCH 283/750] Changed tests/techmap/mem_simple_4x1_map for new $mem/$memwr WR_EN interface --- tests/techmap/mem_simple_4x1_map.v | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/techmap/mem_simple_4x1_map.v b/tests/techmap/mem_simple_4x1_map.v index 5f93914c..820f89de 100644 --- a/tests/techmap/mem_simple_4x1_map.v +++ b/tests/techmap/mem_simple_4x1_map.v @@ -19,7 +19,8 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); input [RD_PORTS*ABITS-1:0] RD_ADDR; output reg [RD_PORTS*WIDTH-1:0] RD_DATA; - input [WR_PORTS-1:0] WR_CLK, WR_EN; + input [WR_PORTS-1:0] WR_CLK; + input [WR_PORTS*WIDTH-1:0] WR_EN; input [WR_PORTS*ABITS-1:0] WR_ADDR; input [WR_PORTS*WIDTH-1:0] WR_DATA; @@ -28,7 +29,11 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); parameter _TECHMAP_CONNMAP_RD_CLK_ = 0; parameter _TECHMAP_CONNMAP_WR_CLK_ = 0; + parameter _TECHMAP_BITS_CONNMAP_ = 0; + parameter _TECHMAP_CONNMAP_WR_EN_ = 0; + reg _TECHMAP_FAIL_; + integer k; initial begin _TECHMAP_FAIL_ <= 0; @@ -44,6 +49,12 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); if (!WR_CLK_ENABLE || !WR_CLK_POLARITY) _TECHMAP_FAIL_ <= 1; + // only one global write enable bit is supported + for (k = 1; k < WR_PORTS*WIDTH; k = k+1) + if (_TECHMAP_CONNMAP_WR_EN_[0 +: _TECHMAP_BITS_CONNMAP_] != + _TECHMAP_CONNMAP_WR_EN_[k*_TECHMAP_BITS_CONNMAP_ +: _TECHMAP_BITS_CONNMAP_]) + _TECHMAP_FAIL_ <= 1; + // read and write must be in same clock domain if (_TECHMAP_CONNMAP_RD_CLK_ != _TECHMAP_CONNMAP_WR_CLK_) _TECHMAP_FAIL_ <= 1; @@ -65,7 +76,7 @@ module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); .RD_DATA(RD_DATA[i]), .WR_ADDR(WR_ADDR), .WR_DATA(WR_DATA[i]), - .WR_EN(WR_EN) + .WR_EN(WR_EN[0]) ); end endgenerate From 24f58e57f3048f7f3e84115364b392389d124c7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:02:28 +0200 Subject: [PATCH 284/750] Fixed spelling of "direction" in read_liberty messages --- frontends/liberty/liberty.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 285491e0..7a74c5fc 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; } From 5057935722edca26b13cb3a158a443d16a6445da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:12:16 +0200 Subject: [PATCH 285/750] Set blackbox attribute in "read_liberty -lib" --- frontends/liberty/liberty.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 7a74c5fc..398e7a30 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; From b171a4c1bce1146c890f8238a723a277c8dc2efb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:12:46 +0200 Subject: [PATCH 286/750] Added "inout" ports support to read_liberty --- frontends/liberty/liberty.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 398e7a30..e7af9372 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; From 64a6906cc448b90777591006786e8bb3a85d2c49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 08:58:51 +0200 Subject: [PATCH 287/750] Added support for "blackbox" attribute to flatten/techmap --- passes/techmap/techmap.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 4c5a0feb..cb36c9e1 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -243,6 +243,9 @@ struct TechmapWorker RTLIL::Module *tpl = map->modules[tpl_name]; std::map parameters = cell->parameters; + if (tpl->get_bool_attribute("\\blackbox")) + continue; + if (!flatten_mode) { if (tpl->get_bool_attribute("\\techmap_simplemap")) { @@ -686,7 +689,7 @@ struct FlattenPass : public Pass { if (top_mod != NULL) { std::map new_modules; for (auto &mod_it : design->modules) - if (mod_it.second == top_mod) { + if (mod_it.second == top_mod || mod_it.second->get_bool_attribute("\\blackbox")) { new_modules[mod_it.first] = mod_it.second; } else { log("Deleting now unused module %s.\n", RTLIL::id2cstr(mod_it.first)); From b76bf05cda789219069c623d3f77cbc47c1eb57d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 08:59:07 +0200 Subject: [PATCH 288/750] Added support for "blackbox" attribute to iopadmap --- passes/techmap/iopadmap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index cc678516..eb2757f6 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -115,7 +115,7 @@ struct IopadmapPass : public Pass { { RTLIL::Module *module = it.second; - if (!design->selected(module)) + if (!design->selected(module) || module->get_bool_attribute("\\blackbox")) continue; for (auto &it2 : module->wires) From 274c51487937e3ca37c3520e98e996cb5918e982 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 12:10:57 +0200 Subject: [PATCH 289/750] Fixed RTLIL::SigSpec::append_bit() for appending constants --- kernel/rtlil.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c4c08d5b..c232dadd 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1716,9 +1716,10 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) chunks.push_back(bit); else if (bit.wire == NULL) - if (chunks.back().wire == NULL) + if (chunks.back().wire == NULL) { chunks.back().data.bits.push_back(bit.data); - else + chunks.back().width++; + } else chunks.push_back(bit); else if (chunks.back().wire == bit.wire && chunks.back().offset + chunks.back().width == bit.offset) From 1b00861d0a3bba0b609eecde504d8a4f2f9d973d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 12:12:04 +0200 Subject: [PATCH 290/750] Improved opt_reduce handling of mem wr_en mux bits --- passes/opt/opt_reduce.cc | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index d5bcb7f0..1e91d160 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -186,11 +186,21 @@ struct OptReduceWorker for (int i = 0; i < int(sig_y.size()); i++) { std::vector in_tuple; - in_tuple.push_back(sig_a.at(i)); - for (int j = i; j < int(sig_b.size()); j += int(sig_a.size())) - in_tuple.push_back(sig_b.at(j)); + bool all_tuple_bits_same = true; - if (consolidated_in_tuples_map.count(in_tuple)) + in_tuple.push_back(sig_a.at(i)); + for (int j = i; j < int(sig_b.size()); j += int(sig_a.size())) { + if (sig_b.at(j) != sig_a.at(i)) + all_tuple_bits_same = false; + in_tuple.push_back(sig_b.at(j)); + } + + if (all_tuple_bits_same) + { + old_sig_conn.first.append_bit(sig_y.at(i)); + old_sig_conn.second.append_bit(sig_a.at(i)); + } + else if (consolidated_in_tuples_map.count(in_tuple)) { old_sig_conn.first.append_bit(sig_y.at(i)); old_sig_conn.second.append_bit(consolidated_in_tuples_map.at(in_tuple)); @@ -206,7 +216,8 @@ struct OptReduceWorker if (new_sig_y.size() != sig_y.size()) { log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); - log(" Old inputs: A=%s, B=%s\n", log_signal(cell->connections["\\A"]), log_signal(cell->connections["\\B"])); + log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections["\\A"]), + log_signal(cell->connections["\\B"]), log_signal(cell->connections["\\Y"])); cell->connections["\\A"] = RTLIL::SigSpec(); for (auto &in_tuple : consolidated_in_tuples) @@ -217,11 +228,13 @@ struct OptReduceWorker for (auto &in_tuple : consolidated_in_tuples) cell->connections["\\B"].append(in_tuple.at(i)); - log(" New inputs: A=%s, B=%s\n", log_signal(cell->connections["\\A"]), log_signal(cell->connections["\\B"])); - cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); cell->connections["\\Y"] = new_sig_y; + log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections["\\A"]), + log_signal(cell->connections["\\B"]), log_signal(cell->connections["\\Y"])); + log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); + module->connections.push_back(old_sig_conn); module->check(); From 6d69d4aaa81f176ec97654b5103f6f59eb98c211 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 13:13:21 +0200 Subject: [PATCH 291/750] Added support for constant bit- or part-select for memory writes --- frontends/ast/simplify.cc | 45 +++++++++++++++++++++++++++++++-------- tests/simple/memory.v | 20 +++++++++++++++++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index ba0dca13..320c80d7 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); diff --git a/tests/simple/memory.v b/tests/simple/memory.v index 927ee043..aae3feac 100644 --- a/tests/simple/memory.v +++ b/tests/simple/memory.v @@ -114,3 +114,23 @@ assign rd_data = memory[rd_addr_buf]; endmodule +// ---------------------------------------------------------- + +module test05(clk, addr, wdata, rdata, wen); + +input clk; +input [1:0] addr; +input [7:0] wdata; +output reg [7:0] rdata; +input [3:0] wen; + +reg [7:0] mem [0:3]; + +integer i; +always @(posedge clk) begin + for (i = 0; i < 4; i = i+1) + if (wen[i]) mem[addr][i*2 +: 2] <= wdata[i*2 +: 2]; + rdata <= mem[addr]; +end + +endmodule From 5867f6bcdc10cbccc196a6889f5242c0f090a2f1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 13:49:32 +0200 Subject: [PATCH 292/750] Added support for bit/part select to mem2reg rewriter --- frontends/ast/simplify.cc | 9 +++++++++ tests/simple/memory.v | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 320c80d7..eee5a7b3 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); diff --git a/tests/simple/memory.v b/tests/simple/memory.v index aae3feac..21271b5e 100644 --- a/tests/simple/memory.v +++ b/tests/simple/memory.v @@ -134,3 +134,24 @@ always @(posedge clk) begin end endmodule + +// ---------------------------------------------------------- + +module test06(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); + (* gentb_constant=0 *) wire rst; + reg [7:0] test [0:7]; + integer i; + always @(posedge clk or posedge rst) begin + if (rst) begin + for (i=0; i<8; i=i+1) + test[i] <= 0; + end else begin + test[0][2] <= din[1]; + test[0][5] <= test[0][2]; + test[idx][3] <= din[idx]; + test[idx][6] <= test[idx][2]; + test[idx][idx] <= !test[idx][idx]; + end + end + assign dout = test[idx]; +endmodule From f1ca93a0a37a4e5f7188af21d2696219329fadfd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 16:48:36 +0200 Subject: [PATCH 293/750] Fixed simlib.v model for $mem --- techlibs/common/simlib.v | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 9c774dea..1b50959c 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1315,26 +1315,26 @@ generate for (i = 0; i < RD_PORTS; i = i+1) begin:rd if (RD_CLK_ENABLE[i] == 0) begin:rd_noclk always @(RD_ADDR or update_async_rd) - RD_DATA[ i*WIDTH +: WIDTH ] <= data[ RD_ADDR[ i*ABITS +: ABITS ] - OFFSET ]; + RD_DATA[i*WIDTH +: WIDTH] <= data[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; end else if (RD_TRANSPARENT[i] == 1) begin:rd_transparent reg [ABITS-1:0] addr_buf; if (RD_CLK_POLARITY[i] == 1) begin:rd_trans_posclk always @(posedge RD_CLK[i]) - addr_buf <= RD_ADDR[ i*ABITS +: ABITS ]; + addr_buf <= RD_ADDR[i*ABITS +: ABITS]; end else begin:rd_trans_negclk always @(negedge RD_CLK[i]) - addr_buf <= RD_ADDR[ i*ABITS +: ABITS ]; + addr_buf <= RD_ADDR[i*ABITS +: ABITS]; end always @(addr_buf or update_async_rd) - RD_DATA[ i*WIDTH +: WIDTH ] <= data[ addr_buf - OFFSET ]; + RD_DATA[i*WIDTH +: WIDTH] <= data[addr_buf - OFFSET]; end else begin:rd_notransparent if (RD_CLK_POLARITY[i] == 1) begin:rd_notrans_posclk always @(posedge RD_CLK[i]) - RD_DATA[ i*WIDTH +: WIDTH ] <= data[ RD_ADDR[ i*ABITS +: ABITS ] - OFFSET ]; + RD_DATA[i*WIDTH +: WIDTH] <= data[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; end else begin:rd_notrans_negclk always @(negedge RD_CLK[i]) - RD_DATA[ i*WIDTH +: WIDTH ] <= data[ RD_ADDR[ i*ABITS +: ABITS ] - OFFSET ]; + RD_DATA[i*WIDTH +: WIDTH] <= data[RD_ADDR[i*ABITS +: ABITS] - OFFSET]; end end end @@ -1346,13 +1346,13 @@ generate always @(WR_ADDR or WR_DATA or WR_EN) begin run_update = 0; for (n = 0; n < WIDTH; n = n+1) begin - if (WR_EN[i][n]) begin + if (WR_EN[i*WIDTH + n]) begin found_collision = 0; for (k = i+1; k < WR_PORTS; k = k+1) - if (WR_EN[k][n] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) + if (WR_EN[k*WIDTH + n] && WR_ADDR[i*ABITS +: ABITS] == WR_ADDR[k*ABITS +: ABITS]) found_collision = 1; if (!found_collision) begin - data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ][n] <= WR_DATA[ i*WIDTH +: WIDTH ][n]; + data[WR_ADDR[i*ABITS +: ABITS] - OFFSET][n] <= WR_DATA[i*WIDTH + n]; run_update = 1; end end @@ -1367,13 +1367,13 @@ generate always @(posedge WR_CLK[i]) begin run_update = 0; for (n = 0; n < WIDTH; n = n+1) begin - if (WR_EN[i][n]) begin + if (WR_EN[i*WIDTH + n]) begin found_collision = 0; for (k = i+1; k < WR_PORTS; k = k+1) - if (WR_EN[k][n] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) + if (WR_EN[k*WIDTH + n] && WR_ADDR[i*ABITS +: ABITS] == WR_ADDR[k*ABITS +: ABITS]) found_collision = 1; if (!found_collision) begin - data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ][n] <= WR_DATA[ i*WIDTH +: WIDTH ][n]; + data[WR_ADDR[i*ABITS +: ABITS] - OFFSET][n] <= WR_DATA[i*WIDTH + n]; run_update = 1; end end @@ -1387,13 +1387,13 @@ generate always @(negedge WR_CLK[i]) begin run_update = 0; for (n = 0; n < WIDTH; n = n+1) begin - if (WR_EN[i][n]) begin + if (WR_EN[i*WIDTH + n]) begin found_collision = 0; for (k = i+1; k < WR_PORTS; k = k+1) - if (WR_EN[k][n] && WR_ADDR[ i*ABITS +: ABITS ] == WR_ADDR[ k*ABITS +: ABITS ]) + if (WR_EN[k*WIDTH + n] && WR_ADDR[i*ABITS +: ABITS] == WR_ADDR[k*ABITS +: ABITS]) found_collision = 1; if (!found_collision) begin - data[ WR_ADDR[ i*ABITS +: ABITS ] - OFFSET ][n] <= WR_DATA[ i*WIDTH +: WIDTH ][n]; + data[WR_ADDR[i*ABITS +: ABITS] - OFFSET][n] <= WR_DATA[i*WIDTH + n]; run_update = 1; end end From 9b183539af4adf7d2a127042ca384806c7e73367 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 16:49:23 +0200 Subject: [PATCH 294/750] Implemented dynamic bit-/part-select for memory writes --- frontends/ast/simplify.cc | 28 ++++++++++++++++++++++++-- tests/simple/memory.v | 41 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index eee5a7b3..f819b250 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 diff --git a/tests/simple/memory.v b/tests/simple/memory.v index 21271b5e..ae63e8a1 100644 --- a/tests/simple/memory.v +++ b/tests/simple/memory.v @@ -137,7 +137,26 @@ endmodule // ---------------------------------------------------------- -module test06(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); +module test06_sync(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); + (* gentb_constant=0 *) wire rst; + reg [7:0] test [0:7]; + integer i; + always @(posedge clk) begin + if (rst) begin + for (i=0; i<8; i=i+1) + test[i] <= 0; + end else begin + test[0][2] <= din[1]; + test[0][5] <= test[0][2]; + test[idx][3] <= din[idx]; + test[idx][6] <= test[idx][2]; + test[idx][idx] <= !test[idx][idx]; + end + end + assign dout = test[idx]; +endmodule + +module test06_async(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); (* gentb_constant=0 *) wire rst; reg [7:0] test [0:7]; integer i; @@ -155,3 +174,23 @@ module test06(input clk, input rst, input [2:0] idx, input [7:0] din, output [7: end assign dout = test[idx]; endmodule + +// ---------------------------------------------------------- + +module test07(clk, addr, woffset, wdata, rdata); + +input clk; +input [1:0] addr; +input [3:0] wdata; +input [1:0] woffset; +output reg [7:0] rdata; + +reg [7:0] mem [0:3]; + +integer i; +always @(posedge clk) begin + mem[addr][woffset +: 4] <= wdata; + rdata <= mem[addr]; +end + +endmodule From ec3a798194342135d7aea21c334e6675701d66a6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 16:53:52 +0200 Subject: [PATCH 295/750] Also simulate unmapped memories in "make test" --- tests/tools/autotest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index ff431eaf..266691a6 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -128,7 +128,7 @@ do elif [ "$frontend" = "verific_gates" ]; then test_passes -p "verific -vlog2k $fn; verific -import -gates -all; opt; memory;;" else - test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt" $fn + test_passes -f "$frontend" -p "hierarchy; proc; opt; memory -nomap; opt; fsm; opt" $fn test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" $fn fi touch ../${bn}.log From a8cedb225709171b97e31c35dcac52d13c47b94f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 10:26:01 +0200 Subject: [PATCH 296/750] Added log_id() helper function --- kernel/log.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/log.h b/kernel/log.h index 5fbd2fc6..3e280a6f 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -52,6 +52,14 @@ void log_flush(); const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); +static inline const char *log_id(std::string id) { + return RTLIL::id2cstr(id); +} + +template static inline const char *log_id(T *obj) { + return RTLIL::id2cstr(obj->name); +} + #define log_abort() log_error("Abort in %s:%d.\n", __FILE__, __LINE__) #define log_assert(_assert_expr_) do { if (_assert_expr_) break; log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) From 2d69c309f9d4d3093eead620684a59e3804b3894 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 10:27:06 +0200 Subject: [PATCH 297/750] Added function-like cell creation helpers --- kernel/rtlil.cc | 176 ++++++++++++++++++++++++++++-------------------- kernel/rtlil.h | 55 +++++++++++++++ 2 files changed, 158 insertions(+), 73 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index c232dadd..dea0e105 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -869,8 +869,8 @@ void RTLIL::Module::fixup_ports() } -#define DEF_METHOD(_func, _type) \ - RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \ +#define DEF_METHOD(_func, _y_size, _type) \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \ RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ @@ -881,21 +881,26 @@ void RTLIL::Module::fixup_ports() cell->connections["\\Y"] = sig_y; \ add(cell); \ return cell; \ + } \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed) { \ + RTLIL::SigSpec sig_y = new_wire(_y_size, NEW_ID); \ + add ## _func(name, sig_a, sig_y, is_signed); \ + return sig_y; \ } -DEF_METHOD(addNot, "$not") -DEF_METHOD(addPos, "$pos") -DEF_METHOD(addBu0, "$bu0") -DEF_METHOD(addNeg, "$neg") -DEF_METHOD(addReduceAnd, "$reduce_and") -DEF_METHOD(addReduceOr, "$reduce_or") -DEF_METHOD(addReduceXor, "$reduce_xor") -DEF_METHOD(addReduceXnor, "$reduce_xnor") -DEF_METHOD(addReduceBool, "$reduce_bool") -DEF_METHOD(addLogicNot, "$logic_not") +DEF_METHOD(Not, sig_a.width, "$not") +DEF_METHOD(Pos, sig_a.width, "$pos") +DEF_METHOD(Bu0, sig_a.width, "$bu0") +DEF_METHOD(Neg, sig_a.width, "$neg") +DEF_METHOD(ReduceAnd, 1, "$reduce_and") +DEF_METHOD(ReduceOr, 1, "$reduce_or") +DEF_METHOD(ReduceXor, 1, "$reduce_xor") +DEF_METHOD(ReduceXnor, 1, "$reduce_xnor") +DEF_METHOD(ReduceBool, 1, "$reduce_bool") +DEF_METHOD(LogicNot, 1, "$logic_not") #undef DEF_METHOD -#define DEF_METHOD(_func, _type) \ - RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed) { \ +#define DEF_METHOD(_func, _y_size, _type) \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed) { \ RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ @@ -909,34 +914,39 @@ DEF_METHOD(addLogicNot, "$logic_not") cell->connections["\\Y"] = sig_y; \ add(cell); \ return cell; \ + } \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed) { \ + RTLIL::SigSpec sig_y = new_wire(_y_size, NEW_ID); \ + add ## _func(name, sig_a, sig_b, sig_y, is_signed); \ + return sig_y; \ } -DEF_METHOD(addAnd, "$and") -DEF_METHOD(addOr, "$or") -DEF_METHOD(addXor, "$xor") -DEF_METHOD(addXnor, "$xnor") -DEF_METHOD(addShl, "$shl") -DEF_METHOD(addShr, "$shr") -DEF_METHOD(addSshl, "$sshl") -DEF_METHOD(addSshr, "$sshr") -DEF_METHOD(addLt, "$lt") -DEF_METHOD(addLe, "$le") -DEF_METHOD(addEq, "$eq") -DEF_METHOD(addNe, "$ne") -DEF_METHOD(addEqx, "$eqx") -DEF_METHOD(addNex, "$nex") -DEF_METHOD(addGe, "$ge") -DEF_METHOD(addGt, "$gt") -DEF_METHOD(addAdd, "$add") -DEF_METHOD(addSub, "$sub") -DEF_METHOD(addMul, "$mul") -DEF_METHOD(addDiv, "$div") -DEF_METHOD(addMod, "$mod") -DEF_METHOD(addLogicAnd, "$logic_and") -DEF_METHOD(addLogicOr, "$logic_or") +DEF_METHOD(And, std::max(sig_a.width, sig_b.width), "$and") +DEF_METHOD(Or, std::max(sig_a.width, sig_b.width), "$or") +DEF_METHOD(Xor, std::max(sig_a.width, sig_b.width), "$xor") +DEF_METHOD(Xnor, std::max(sig_a.width, sig_b.width), "$xnor") +DEF_METHOD(Shl, sig_a.width, "$shl") +DEF_METHOD(Shr, sig_a.width, "$shr") +DEF_METHOD(Sshl, sig_a.width, "$sshl") +DEF_METHOD(Sshr, sig_a.width, "$sshr") +DEF_METHOD(Lt, 1, "$lt") +DEF_METHOD(Le, 1, "$le") +DEF_METHOD(Eq, 1, "$eq") +DEF_METHOD(Ne, 1, "$ne") +DEF_METHOD(Eqx, 1, "$eqx") +DEF_METHOD(Nex, 1, "$nex") +DEF_METHOD(Ge, 1, "$ge") +DEF_METHOD(Gt, 1, "$gt") +DEF_METHOD(Add, std::max(sig_a.width, sig_b.width), "$add") +DEF_METHOD(Sub, std::max(sig_a.width, sig_b.width), "$sub") +DEF_METHOD(Mul, std::max(sig_a.width, sig_b.width), "$mul") +DEF_METHOD(Div, std::max(sig_a.width, sig_b.width), "$div") +DEF_METHOD(Mod, std::max(sig_a.width, sig_b.width), "$mod") +DEF_METHOD(LogicAnd, 1, "$logic_and") +DEF_METHOD(LogicOr, 1, "$logic_or") #undef DEF_METHOD #define DEF_METHOD(_func, _type, _pmux) \ - RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y) { \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y) { \ RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ @@ -949,50 +959,70 @@ DEF_METHOD(addLogicOr, "$logic_or") cell->connections["\\Y"] = sig_y; \ add(cell); \ return cell; \ + } \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \ + RTLIL::SigSpec sig_y = new_wire(sig_a.width, NEW_ID); \ + add ## _func(name, sig_a, sig_b, sig_s, sig_y); \ + return sig_y; \ } -DEF_METHOD(addMux, "$mux", 0) -DEF_METHOD(addPmux, "$pmux", 1) -DEF_METHOD(addSafePmux, "$safe_pmux", 1) +DEF_METHOD(Mux, "$mux", 0) +DEF_METHOD(Pmux, "$pmux", 1) +DEF_METHOD(SafePmux, "$safe_pmux", 1) #undef DEF_METHOD #define DEF_METHOD_2(_func, _type, _P1, _P2) \ - RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ - cell->connections["\\" #_P1] = sig1; \ - cell->connections["\\" #_P2] = sig2; \ - add(cell); \ - return cell; \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->connections["\\" #_P1] = sig1; \ + cell->connections["\\" #_P2] = sig2; \ + add(cell); \ + return cell; \ + } \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1) { \ + RTLIL::SigSpec sig2 = new_wire(1, NEW_ID); \ + add ## _func(name, sig1, sig2); \ + return sig2; \ } #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ - RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ - cell->connections["\\" #_P1] = sig1; \ - cell->connections["\\" #_P2] = sig2; \ - cell->connections["\\" #_P3] = sig3; \ - add(cell); \ - return cell; \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->connections["\\" #_P1] = sig1; \ + cell->connections["\\" #_P2] = sig2; \ + cell->connections["\\" #_P3] = sig3; \ + add(cell); \ + return cell; \ + } \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ + RTLIL::SigSpec sig3 = new_wire(1, NEW_ID); \ + add ## _func(name, sig1, sig2, sig3); \ + return sig3; \ } #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ - RTLIL::Cell* RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3, RTLIL::SigSpec sig4) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ - cell->connections["\\" #_P1] = sig1; \ - cell->connections["\\" #_P2] = sig2; \ - cell->connections["\\" #_P3] = sig3; \ - cell->connections["\\" #_P4] = sig4; \ - add(cell); \ - return cell; \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3, RTLIL::SigSpec sig4) { \ + RTLIL::Cell *cell = new RTLIL::Cell; \ + cell->name = name; \ + cell->type = _type; \ + cell->connections["\\" #_P1] = sig1; \ + cell->connections["\\" #_P2] = sig2; \ + cell->connections["\\" #_P3] = sig3; \ + cell->connections["\\" #_P4] = sig4; \ + add(cell); \ + return cell; \ + } \ + RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ + RTLIL::SigSpec sig4 = new_wire(1, NEW_ID); \ + add ## _func(name, sig1, sig2, sig3, sig4); \ + return sig4; \ } -DEF_METHOD_2(addInvGate, "$_INV_", A, Y) -DEF_METHOD_3(addAndGate, "$_AND_", A, B, Y) -DEF_METHOD_3(addOrGate, "$_OR_", A, B, Y) -DEF_METHOD_3(addXorGate, "$_XOR_", A, B, Y) -DEF_METHOD_4(addMuxGate, "$_MUX_", A, B, S, Y) +DEF_METHOD_2(InvGate, "$_INV_", A, Y) +DEF_METHOD_3(AndGate, "$_AND_", A, B, Y) +DEF_METHOD_3(OrGate, "$_OR_", A, B, Y) +DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y) +DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y) #undef DEF_METHOD_2 #undef DEF_METHOD_3 #undef DEF_METHOD_4 diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b95a0442..17406d5d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -294,6 +294,8 @@ struct RTLIL::Module { void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; + // The add* methods create a cell and return the created cell. All signals must exist in advance. + RTLIL::Cell* addNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addPos (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addBu0 (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); @@ -368,6 +370,59 @@ struct RTLIL::Module { RTLIL::Cell* addDlatchGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true); RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true); + + // The methods without the add* prefix create a cell and an output signal. They return the newly created output signal. + + RTLIL::SigSpec Not (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec Pos (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec Bu0 (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec Neg (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + + RTLIL::SigSpec And (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Or (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Xor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Xnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + + RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec ReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec ReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec ReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + + RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + + RTLIL::SigSpec Lt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Le (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Eq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Ne (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Eqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Nex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Ge (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Gt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + + RTLIL::SigSpec Add (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Sub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Mul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Div (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Mod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Pow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool a_signed = false, bool b_signed = false); + + RTLIL::SigSpec LogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); + RTLIL::SigSpec LogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec LogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + + RTLIL::SigSpec Mux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); + RTLIL::SigSpec Pmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); + RTLIL::SigSpec SafePmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); + + RTLIL::SigSpec InvGate (RTLIL::IdString name, RTLIL::SigSpec sig_a); + RTLIL::SigSpec AndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); + RTLIL::SigSpec OrGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); + RTLIL::SigSpec XorGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); + RTLIL::SigSpec MuxGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); }; struct RTLIL::Wire { From 309ae98246cf9ff115b7d95ae14991faf72a5a38 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 10:28:45 +0200 Subject: [PATCH 298/750] Apply opt_reduce WR_EN opts to the whole mux tree driving the WR_EN port --- passes/opt/opt_reduce.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 1e91d160..a0c7a027 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -266,6 +266,21 @@ struct OptReduceWorker mem_wren_sigs.add(assign_map(cell->connections["\\D"])); } + bool keep_expanding_mem_wren_sigs = true; + while (keep_expanding_mem_wren_sigs) { + keep_expanding_mem_wren_sigs = false; + for (auto &cell_it : module->cells) { + RTLIL::Cell *cell = cell_it.second; + if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->connections["\\Y"]))) { + if (!mem_wren_sigs.check_all(assign_map(cell->connections["\\A"])) || + !mem_wren_sigs.check_all(assign_map(cell->connections["\\B"]))) + keep_expanding_mem_wren_sigs = true; + mem_wren_sigs.add(assign_map(cell->connections["\\A"])); + mem_wren_sigs.add(assign_map(cell->connections["\\B"])); + } + } + } + while (did_something) { did_something = false; From a721f7d768feb3ce68cb384805ea7f1fde3e08ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 11:36:34 +0200 Subject: [PATCH 299/750] Added automatic conversion from RTLIL::SigSpec to std::vector --- kernel/rtlil.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 17406d5d..3a22d137 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -542,6 +542,7 @@ struct RTLIL::SigSpec { static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str); static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); + operator std::vector() const { return to_sigbit_vector(); } }; inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { From ab4b26679ff4acdc5a86bc79faa5439c625c38f8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 12:40:01 +0200 Subject: [PATCH 300/750] Added memory_share --- passes/memory/Makefile.inc | 1 + passes/memory/memory.cc | 2 + passes/memory/memory_share.cc | 263 ++++++++++++++++++++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 passes/memory/memory_share.cc diff --git a/passes/memory/Makefile.inc b/passes/memory/Makefile.inc index 21f17db5..026c5ff8 100644 --- a/passes/memory/Makefile.inc +++ b/passes/memory/Makefile.inc @@ -1,6 +1,7 @@ OBJS += passes/memory/memory.o OBJS += passes/memory/memory_dff.o +OBJS += passes/memory/memory_share.o OBJS += passes/memory/memory_collect.o OBJS += passes/memory/memory_unpack.o OBJS += passes/memory/memory_map.o diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index 680657a7..a0c89a4d 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -33,6 +33,7 @@ struct MemoryPass : public Pass { log("This pass calls all the other memory_* passes in a useful order:\n"); log("\n"); log(" memory_dff\n"); + log(" memory_share\n"); log(" memory_collect\n"); log(" memory_map (skipped if called with -nomap)\n"); log("\n"); @@ -58,6 +59,7 @@ struct MemoryPass : public Pass { extra_args(args, argidx, design); Pass::call(design, "memory_dff"); + Pass::call(design, "memory_share"); Pass::call(design, "memory_collect"); if (!flag_nomap) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc new file mode 100644 index 00000000..69f3e739 --- /dev/null +++ b/passes/memory/memory_share.cc @@ -0,0 +1,263 @@ +/* + * 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/rtlil.h" +#include "kernel/sigtools.h" +#include "kernel/register.h" +#include "kernel/log.h" +#include + +static bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b) +{ + if (a->type == "$memrd" && b->type == "$memrd") + return a->name < b->name; + if (a->type == "$memrd" || b->type == "$memrd") + return (a->type == "$memrd") < (b->type == "$memrd"); + return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int(); +} + +struct MemoryShareWorker +{ + RTLIL::Design *design; + RTLIL::Module *module; + SigMap sigmap; + + RTLIL::SigSpec mask_en_naive(RTLIL::SigSpec do_mask, RTLIL::SigSpec bits, RTLIL::SigSpec mask_bits) + { + // this is the naive version of the function that does not care about grouping the EN bits. + + RTLIL::SigSpec inv_mask_bits = module->Not(NEW_ID, mask_bits); + RTLIL::SigSpec inv_mask_bits_filtered = module->Mux(NEW_ID, RTLIL::SigSpec(RTLIL::State::S1, bits.width), inv_mask_bits, do_mask); + RTLIL::SigSpec result = module->And(NEW_ID, inv_mask_bits_filtered, bits); + return result; + } + + RTLIL::SigSpec mask_en_grouped(RTLIL::SigSpec do_mask, RTLIL::SigSpec bits, RTLIL::SigSpec mask_bits) + { + // this version of the function preserves the bit grouping in the EN bits. + + std::vector v_bits = bits; + std::vector v_mask_bits = mask_bits; + + std::map, std::pair>> groups; + RTLIL::SigSpec grouped_bits, grouped_mask_bits; + + for (int i = 0; i < bits.width; i++) { + std::pair key(v_bits[i], v_mask_bits[i]); + if (groups.count(key) == 0) { + groups[key].first = grouped_bits.width; + grouped_bits.append_bit(v_bits[i]); + grouped_mask_bits.append_bit(v_mask_bits[i]); + } + groups[key].second.push_back(i); + } + + std::vector grouped_result = mask_en_naive(do_mask, grouped_bits, grouped_mask_bits); + RTLIL::SigSpec result; + + for (int i = 0; i < bits.width; i++) { + std::pair key(v_bits[i], v_mask_bits[i]); + result.append_bit(grouped_result.at(groups.at(key).first)); + } + + return result; + } + + void merge_en_data(RTLIL::SigSpec &merged_en, RTLIL::SigSpec &merged_data, RTLIL::SigSpec next_en, RTLIL::SigSpec next_data) + { + std::vector v_old_en = merged_en; + std::vector v_next_en = next_en; + + // The new merged_en signal is just the old merged_en signal and next_en OR'ed together. + // But of course we need to preserve the bit grouping.. + + std::map, int> groups; + std::vector grouped_old_en, grouped_next_en; + RTLIL::SigSpec new_merged_en; + + for (int i = 0; i < int(v_old_en.size()); i++) { + std::pair key(v_old_en[i], v_next_en[i]); + if (groups.count(key) == 0) { + groups[key] = grouped_old_en.size(); + grouped_old_en.push_back(key.first); + grouped_next_en.push_back(key.second); + } + } + + std::vector grouped_new_en = module->Or(NEW_ID, grouped_old_en, grouped_next_en); + + for (int i = 0; i < int(v_old_en.size()); i++) { + std::pair key(v_old_en[i], v_next_en[i]); + new_merged_en.append_bit(grouped_new_en.at(groups.at(key))); + } + + // Create the new merged_data signal. + + RTLIL::SigSpec new_merged_data(RTLIL::State::Sx, merged_data.width); + + RTLIL::SigSpec old_data_set = module->And(NEW_ID, merged_en, merged_data); + RTLIL::SigSpec old_data_unset = module->And(NEW_ID, merged_en, module->Not(NEW_ID, merged_data)); + + RTLIL::SigSpec new_data_set = module->And(NEW_ID, next_en, next_data); + RTLIL::SigSpec new_data_unset = module->And(NEW_ID, next_en, module->Not(NEW_ID, next_data)); + + new_merged_data = module->Or(NEW_ID, new_merged_data, old_data_set); + new_merged_data = module->And(NEW_ID, new_merged_data, module->Not(NEW_ID, old_data_unset)); + + new_merged_data = module->Or(NEW_ID, new_merged_data, new_data_set); + new_merged_data = module->And(NEW_ID, new_merged_data, module->Not(NEW_ID, new_data_unset)); + + // Update merged_* signals + + merged_en = new_merged_en; + merged_data = new_merged_data; + } + + void consolidate_wr_by_addr(std::string memid, std::vector &wr_ports) + { + log("Consolidating write ports of memory %s by address:\n", log_id(memid)); + + std::map last_port_by_addr; + + bool cache_clk_enable = false; + bool cache_clk_polarity = false; + RTLIL::SigSpec cache_clk; + + for (int i = 0; i < int(wr_ports.size()); i++) + { + RTLIL::Cell *cell = wr_ports.at(i); + RTLIL::SigSpec addr = sigmap(cell->connections.at("\\ADDR")); + + if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || + (cache_clk_enable && (sigmap(cell->connections.at("\\CLK")) != cache_clk || + cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) + { + cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); + cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); + cache_clk = sigmap(cell->connections.at("\\CLK")); + last_port_by_addr.clear(); + + if (cache_clk_enable) + log(" New clock domain: %s %s\n", cache_clk_polarity ? "posedge" : "negedge", log_signal(cache_clk)); + else + log(" New clock domain: unclocked\n"); + } + + log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr)); + + if (last_port_by_addr.count(addr)) + { + int last_i = last_port_by_addr.at(addr); + log(" Merging port %d into this one.\n", last_i); + + // Force this ports addr input to addr directly (skip don't care muxes) + + cell->connections.at("\\ADDR") = addr; + + // If any of the ports between `last_i' and `i' write to the same address, this + // will have priority over whatever `last_i` wrote. So we need to revisit those + // ports and mask the EN bits accordingly. + + RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->connections.at("\\EN")); + + for (int j = last_i+1; j < i; j++) + { + if (wr_ports[j] == NULL) + continue; + + RTLIL::SigSpec is_same_addr = module->new_wire(1, NEW_ID); + module->addEq(NEW_ID, addr, wr_ports[j]->connections.at("\\ADDR"), is_same_addr); + merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->connections.at("\\EN"))); + } + + // Then we need to merge the (masked) EN and the DATA signals. + // Note that we intentionally do not use sigmap() on the DATA ports. + + RTLIL::SigSpec merged_data = wr_ports[last_i]->connections.at("\\DATA"); + merge_en_data(merged_en, merged_data, sigmap(cell->connections.at("\\EN")), cell->connections.at("\\DATA")); + + // Connect the new EN and DATA signals and remove the old write port. + + cell->connections.at("\\EN") = merged_en; + cell->connections.at("\\DATA") = merged_data; + + module->cells.erase(wr_ports[last_i]->name); + delete wr_ports[last_i]; + wr_ports[last_i] = NULL; + } + + last_port_by_addr[addr] = i; + } + } + + MemoryShareWorker(RTLIL::Design *design, RTLIL::Module *module) : + design(design), module(module), sigmap(module) + { + std::map, std::vector>> memindex; + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + + if (cell->type == "$memrd") + memindex[cell->parameters.at("\\MEMID").decode_string()].first.push_back(cell); + + if (cell->type == "$memwr") + memindex[cell->parameters.at("\\MEMID").decode_string()].second.push_back(cell); + + if (cell->type == "$mux") + { + RTLIL::SigSpec sig_a = sigmap(cell->connections.at("\\A")); + RTLIL::SigSpec sig_b = sigmap(cell->connections.at("\\B")); + + if (sig_a.is_fully_undef()) + sigmap.add(cell->connections.at("\\Y"), sig_b); + else if (sig_b.is_fully_undef()) + sigmap.add(cell->connections.at("\\Y"), sig_a); + } + } + + for (auto &it : memindex) { + std::sort(it.second.first.begin(), it.second.first.end(), memcells_cmp); + std::sort(it.second.second.begin(), it.second.second.end(), memcells_cmp); + consolidate_wr_by_addr(it.first, it.second.second); + } + } +}; + +struct MemorySharePass : public Pass { + MemorySharePass() : Pass("memory_share", "consolidate memory ports") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" memory_share [selection]\n"); + log("\n"); + log("This pass merges share-able memory ports into single memory ports.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + log_header("Executing MEMORY_SHARE pass (consolidating $memrc/$memwr cells).\n"); + extra_args(args, 1, design); + for (auto &mod_it : design->modules) + if (design->selected(mod_it.second)) + MemoryShareWorker(design, mod_it.second); + } +} MemorySharePass; + From 5d9127418b7272ae926e917ee0167ce58b81a83e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 13:25:19 +0200 Subject: [PATCH 301/750] added tests/memories --- Makefile | 1 + tests/memories/.gitignore | 3 + tests/memories/amber23_sram_byte_en.v | 84 +++++++++++++++++++++++++++ tests/memories/run-test.sh | 19 ++++++ tests/memories/simple_sram_byte_en.v | 26 +++++++++ 5 files changed, 133 insertions(+) create mode 100644 tests/memories/.gitignore create mode 100644 tests/memories/amber23_sram_byte_en.v create mode 100755 tests/memories/run-test.sh create mode 100644 tests/memories/simple_sram_byte_en.v diff --git a/Makefile b/Makefile index 61fb5dc4..6d3d7d7c 100644 --- a/Makefile +++ b/Makefile @@ -163,6 +163,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) cd tests/asicworld && bash run-test.sh cd tests/realmath && bash run-test.sh cd tests/techmap && bash run-test.sh + cd tests/memories && bash run-test.sh cd tests/sat && bash run-test.sh install: $(TARGETS) $(EXTRA_TARGETS) diff --git a/tests/memories/.gitignore b/tests/memories/.gitignore new file mode 100644 index 00000000..90a0983a --- /dev/null +++ b/tests/memories/.gitignore @@ -0,0 +1,3 @@ +*.log +*.out +*.dmp diff --git a/tests/memories/amber23_sram_byte_en.v b/tests/memories/amber23_sram_byte_en.v new file mode 100644 index 00000000..3554af88 --- /dev/null +++ b/tests/memories/amber23_sram_byte_en.v @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////// +// // +// Generic Library SRAM with per byte write enable // +// // +// This file is part of the Amber project // +// http://www.opencores.org/project,amber // +// // +// Description // +// Configurable depth and width. The DATA_WIDTH must be a // +// multiple of 8. // +// // +// Author(s): // +// - Conor Santifort, csantifort.amber@gmail.com // +// // +////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2010 Authors and OPENCORES.ORG // +// // +// This source file may be used and distributed without // +// restriction provided that this copyright statement is not // +// removed from the file and that any derivative work contains // +// the original copyright notice and the associated disclaimer. // +// // +// This source file is free software; you can redistribute it // +// and/or modify it under the terms of the GNU Lesser General // +// Public License as published by the Free Software Foundation; // +// either version 2.1 of the License, or (at your option) any // +// later version. // +// // +// This source is distributed in the hope that it will be // +// useful, but WITHOUT ANY WARRANTY; without even the implied // +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // +// PURPOSE. See the GNU Lesser General Public License for more // +// details. // +// // +// You should have received a copy of the GNU Lesser General // +// Public License along with this source; if not, download it // +// from http://www.opencores.org/lgpl.shtml // +// // +////////////////////////////////////////////////////////////////// + +// expect-wr-ports 1 +// expect-rd-ports 1 + +module generic_sram_byte_en +#( +parameter DATA_WIDTH = 32, +parameter ADDRESS_WIDTH = 4 +) + +( +input i_clk, +input [DATA_WIDTH-1:0] i_write_data, +input i_write_enable, +input [ADDRESS_WIDTH-1:0] i_address, +input [DATA_WIDTH/8-1:0] i_byte_enable, +output reg [DATA_WIDTH-1:0] o_read_data + ); + +reg [DATA_WIDTH-1:0] mem [0:2**ADDRESS_WIDTH-1]; +integer i; + +always @(posedge i_clk) + begin + // read + o_read_data <= i_write_enable ? {DATA_WIDTH{1'd0}} : mem[i_address]; + + // write + if (i_write_enable) + for (i=0;i Date: Fri, 18 Jul 2014 13:45:25 +0200 Subject: [PATCH 302/750] Bugfix in tests/memories/run-test.sh --- tests/memories/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/memories/run-test.sh b/tests/memories/run-test.sh index eccd4010..c3b19618 100755 --- a/tests/memories/run-test.sh +++ b/tests/memories/run-test.sh @@ -7,11 +7,11 @@ for f in `egrep -l 'expect-(wr|rd)-ports' *.v`; do echo -n "Testing expectations for $f .." ../../yosys -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem" $f if grep -q expect-wr-ports $f; then - grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' amber23_sram_byte_en.v)\$" amber23_sram_byte_en.dmp || + grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected number of write ports."; false; } fi if grep -q expect-rd-ports $f; then - grep -q "parameter \\\\RD_PORTS $(gawk '/expect-rd-ports/ { print $3; }' amber23_sram_byte_en.v)\$" amber23_sram_byte_en.dmp || + grep -q "parameter \\\\RD_PORTS $(gawk '/expect-rd-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || { echo " ERROR: Unexpected number of read ports."; false; } fi echo " ok." From a3419319727ac1c2012602a702b62631570d7588 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 14:32:40 +0200 Subject: [PATCH 303/750] Only create collision detect logic in memory_share if necessary --- passes/memory/memory_share.cc | 51 ++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 69f3e739..140a4184 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -134,6 +134,7 @@ struct MemoryShareWorker log("Consolidating write ports of memory %s by address:\n", log_id(memid)); std::map last_port_by_addr; + std::vector> active_bits_on_port; bool cache_clk_enable = false; bool cache_clk_polarity = false; @@ -161,11 +162,27 @@ struct MemoryShareWorker log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr)); + log(" Active bits: "); + std::vector en_bits = sigmap(cell->connections.at("\\EN")); + active_bits_on_port.push_back(std::vector(en_bits.size())); + for (int k = int(en_bits.size())-1; k >= 0; k--) { + active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0; + log("%c", active_bits_on_port[i][k] ? '1' : '0'); + } + log("\n"); + if (last_port_by_addr.count(addr)) { int last_i = last_port_by_addr.at(addr); log(" Merging port %d into this one.\n", last_i); + bool found_overlapping_bits = false; + for (int k = 0; k < int(en_bits.size()); k++) { + if (active_bits_on_port[i][k] && active_bits_on_port[last_i][k]) + found_overlapping_bits = true; + active_bits_on_port[i][k] = active_bits_on_port[i][k] || active_bits_on_port[last_i][k]; + } + // Force this ports addr input to addr directly (skip don't care muxes) cell->connections.at("\\ADDR") = addr; @@ -181,16 +198,35 @@ struct MemoryShareWorker if (wr_ports[j] == NULL) continue; - RTLIL::SigSpec is_same_addr = module->new_wire(1, NEW_ID); - module->addEq(NEW_ID, addr, wr_ports[j]->connections.at("\\ADDR"), is_same_addr); - merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->connections.at("\\EN"))); + for (int k = 0; k < int(en_bits.size()); k++) + if (active_bits_on_port[i][k] && active_bits_on_port[j][k]) + goto found_overlapping_bits_i_j; + + if (0) { + found_overlapping_bits_i_j: + log(" Creating collosion-detect logic for port %d.\n", j); + RTLIL::SigSpec is_same_addr = module->new_wire(1, NEW_ID); + module->addEq(NEW_ID, addr, wr_ports[j]->connections.at("\\ADDR"), is_same_addr); + merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->connections.at("\\EN"))); + } } // Then we need to merge the (masked) EN and the DATA signals. // Note that we intentionally do not use sigmap() on the DATA ports. RTLIL::SigSpec merged_data = wr_ports[last_i]->connections.at("\\DATA"); - merge_en_data(merged_en, merged_data, sigmap(cell->connections.at("\\EN")), cell->connections.at("\\DATA")); + if (found_overlapping_bits) { + log(" Creating logic for merging DATA and EN ports.\n"); + merge_en_data(merged_en, merged_data, sigmap(cell->connections.at("\\EN")), cell->connections.at("\\DATA")); + } else { + for (int k = 0; k < int(en_bits.size()); k++) + if (!active_bits_on_port[last_i][k]) { + merged_en.replace(k, cell->connections.at("\\EN").extract(k, 1)); + merged_data.replace(k, cell->connections.at("\\DATA").extract(k, 1)); + } + merged_en.optimize(); + merged_data.optimize(); + } // Connect the new EN and DATA signals and remove the old write port. @@ -200,6 +236,13 @@ struct MemoryShareWorker module->cells.erase(wr_ports[last_i]->name); delete wr_ports[last_i]; wr_ports[last_i] = NULL; + + log(" Active bits: "); + std::vector en_bits = sigmap(cell->connections.at("\\EN")); + active_bits_on_port.push_back(std::vector(en_bits.size())); + for (int k = int(en_bits.size())-1; k >= 0; k--) + log("%c", active_bits_on_port[i][k] ? '1' : '0'); + log("\n"); } last_port_by_addr[addr] = i; From 44f13aff92146592fd9399bf96dfcb1f81fde708 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 16:44:45 +0200 Subject: [PATCH 304/750] Improved seeding of color rng in show command --- passes/cmds/show.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 92fc5bd5..eab42e6f 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -54,7 +54,7 @@ struct ShowWorker const std::vector> &color_selections; const std::vector> &label_selections; - uint32_t xorshift32(uint32_t x) { + static uint32_t xorshift32(uint32_t x) { x ^= x << 13; x ^= x >> 17; x ^= x << 5; @@ -655,6 +655,8 @@ struct ShowPass : public Pass { } if (arg == "-colors" && argidx+1 < args.size()) { colorSeed = atoi(args[++argidx].c_str()); + for (int i = 0; i < 100; i++) + colorSeed = ShowWorker::xorshift32(colorSeed); continue; } if (arg == "-format" && argidx+1 < args.size()) { From e441f07d895a673c0bf40dcdc76781b50834fe44 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 16:46:40 +0200 Subject: [PATCH 305/750] Added translation from read-feedback to en-signals in memory_share --- passes/memory/memory.cc | 4 + passes/memory/memory_share.cc | 246 ++++++++++++++++++++++++++++++++-- tests/memories/implicit_en.v | 24 ++++ 3 files changed, 264 insertions(+), 10 deletions(-) create mode 100644 tests/memories/implicit_en.v diff --git a/passes/memory/memory.cc b/passes/memory/memory.cc index a0c89a4d..fc309553 100644 --- a/passes/memory/memory.cc +++ b/passes/memory/memory.cc @@ -33,7 +33,9 @@ struct MemoryPass : public Pass { log("This pass calls all the other memory_* passes in a useful order:\n"); log("\n"); log(" memory_dff\n"); + log(" opt_clean\n"); log(" memory_share\n"); + log(" opt_clean\n"); log(" memory_collect\n"); log(" memory_map (skipped if called with -nomap)\n"); log("\n"); @@ -59,7 +61,9 @@ struct MemoryPass : public Pass { extra_args(args, argidx, design); Pass::call(design, "memory_dff"); + Pass::call(design, "opt_clean"); Pass::call(design, "memory_share"); + Pass::call(design, "opt_clean"); Pass::call(design, "memory_collect"); if (!flag_nomap) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 140a4184..e2fa168c 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -36,7 +36,209 @@ struct MemoryShareWorker { RTLIL::Design *design; RTLIL::Module *module; - SigMap sigmap; + SigMap sigmap, sigmap_xmux; + + std::map> sig_to_mux; + std::map>, RTLIL::SigBit> conditions_logic_cache; + + + // ----------------------------------------------------------------- + // Converting feedbacks to async read ports to proper enable signals + // ----------------------------------------------------------------- + + bool find_data_feedback(const std::set &async_rd_bits, RTLIL::SigBit sig, + std::map &state, std::set> &conditions) + { + if (async_rd_bits.count(sig)) { + conditions.insert(state); + return true; + } + + if (sig_to_mux.count(sig) == 0) + return false; + + RTLIL::Cell *cell = sig_to_mux.at(sig).first; + int bit_idx = sig_to_mux.at(sig).second; + + std::vector sig_a = sigmap(cell->connections.at("\\A")); + std::vector sig_b = sigmap(cell->connections.at("\\B")); + std::vector sig_s = sigmap(cell->connections.at("\\S")); + std::vector sig_y = sigmap(cell->connections.at("\\Y")); + log_assert(sig_y.at(bit_idx) == sig); + + for (int i = 0; i < int(sig_s.size()); i++) + if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { + if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) + cell->connections.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + return false; + } + + + for (int i = 0; i < int(sig_s.size()); i++) + { + if (state.count(sig_s[i]) && state.at(sig_s[i]) == false) + continue; + + std::map new_state = state; + new_state[sig_s[i]] = true; + + if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) + cell->connections.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + } + + std::map new_state = state; + for (int i = 0; i < int(sig_s.size()); i++) + new_state[sig_s[i]] = false; + + if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) + cell->connections.at("\\A").replace(bit_idx, RTLIL::State::Sx); + + return false; + } + + RTLIL::SigBit conditions_to_logic(std::set> &conditions, int &created_conditions) + { + if (conditions_logic_cache.count(conditions)) + return conditions_logic_cache.at(conditions); + + RTLIL::SigSpec terms; + for (auto &cond : conditions) { + RTLIL::SigSpec sig1, sig2; + for (auto &it : cond) { + sig1.append_bit(it.first); + sig2.append_bit(it.second ? RTLIL::State::S1 : RTLIL::State::S0); + } + terms.append(module->Ne(NEW_ID, sig1, sig2)); + created_conditions++; + } + + if (terms.width > 1) + terms = module->ReduceAnd(NEW_ID, terms); + + return conditions_logic_cache[conditions] = terms; + } + + void translate_rd_feedback_to_en(std::string memid, std::vector &rd_ports, std::vector &wr_ports) + { + std::vector> async_rd_bits; + std::map> muxtree_upstream_map; + std::set non_feedback_nets; + + for (auto wire_it : module->wires) + if (wire_it.second->port_output) { + std::vector bits = RTLIL::SigSpec(wire_it.second); + non_feedback_nets.insert(bits.begin(), bits.end()); + } + + for (auto cell_it : module->cells) + { + RTLIL::Cell *cell = cell_it.second; + bool ignore_data_port = false; + + if (cell->type == "$mux" || cell->type == "$pmux") + { + std::vector sig_a = sigmap(cell->connections.at("\\A")); + std::vector sig_b = sigmap(cell->connections.at("\\B")); + std::vector sig_s = sigmap(cell->connections.at("\\S")); + std::vector sig_y = sigmap(cell->connections.at("\\Y")); + + non_feedback_nets.insert(sig_s.begin(), sig_s.end()); + + for (int i = 0; i < int(sig_y.size()); i++) { + muxtree_upstream_map[sig_y[i]].insert(sig_a[i]); + for (int j = 0; j < int(sig_s.size()); j++) + muxtree_upstream_map[sig_y[i]].insert(sig_b[i + j*sig_y.size()]); + } + + continue; + } + + if ((cell->type == "$memwr" || cell->type == "$memrd") && + cell->parameters.at("\\MEMID").decode_string() == memid) + ignore_data_port = true; + + for (auto conn : cell_it.second->connections) + { + if (ignore_data_port && conn.first == "\\DATA") + continue; + std::vector bits = sigmap(conn.second); + non_feedback_nets.insert(bits.begin(), bits.end()); + } + } + + std::set expand_non_feedback_nets = non_feedback_nets; + while (!expand_non_feedback_nets.empty()) + { + std::set new_expand_non_feedback_nets; + + for (auto &bit : expand_non_feedback_nets) + if (muxtree_upstream_map.count(bit)) + for (auto &new_bit : muxtree_upstream_map.at(bit)) + if (!non_feedback_nets.count(new_bit)) { + non_feedback_nets.insert(new_bit); + new_expand_non_feedback_nets.insert(new_bit); + } + + expand_non_feedback_nets.swap(new_expand_non_feedback_nets); + } + + for (auto cell : rd_ports) + { + if (cell->parameters.at("\\CLK_ENABLE").as_bool()) + continue; + + std::vector sig_data = sigmap(cell->connections.at("\\DATA")); + + for (int i = 0; i < int(sig_data.size()); i++) + if (non_feedback_nets.count(sig_data[i])) + goto not_pure_feedback_port; + + async_rd_bits.resize(std::max(async_rd_bits.size(), sig_data.size())); + for (int i = 0; i < int(sig_data.size()); i++) + async_rd_bits[i].insert(sig_data[i]); + + not_pure_feedback_port:; + } + + if (async_rd_bits.empty()) + return; + + log("Populating enable bits on write ports of memory %s with aync read feedback:\n", log_id(memid)); + + for (auto cell : wr_ports) + { + log(" Analyzing write port %s.\n", log_id(cell)); + + std::vector cell_data = cell->connections.at("\\DATA"); + std::vector cell_en = cell->connections.at("\\EN"); + + int created_conditions = 0; + for (int i = 0; i < int(cell_data.size()); i++) + if (cell_en[i] != RTLIL::SigBit(RTLIL::State::S0)) + { + std::map state; + std::set> conditions; + + if (cell_en[i].wire != NULL) { + state[cell_en[i]] = false; + conditions.insert(state); + } + + find_data_feedback(async_rd_bits.at(i), cell_data[i], state, conditions); + cell_en[i] = conditions_to_logic(conditions, created_conditions); + } + + if (created_conditions) { + log(" Added enable logic for %d different cases.\n", created_conditions); + cell->connections.at("\\EN") = cell_en; + } + } + } + + + // ------------------------------------------------------ + // Consolidate write ports that write to the same address + // ------------------------------------------------------ RTLIL::SigSpec mask_en_naive(RTLIL::SigSpec do_mask, RTLIL::SigSpec bits, RTLIL::SigSpec mask_bits) { @@ -143,7 +345,7 @@ struct MemoryShareWorker for (int i = 0; i < int(wr_ports.size()); i++) { RTLIL::Cell *cell = wr_ports.at(i); - RTLIL::SigSpec addr = sigmap(cell->connections.at("\\ADDR")); + RTLIL::SigSpec addr = sigmap_xmux(cell->connections.at("\\ADDR")); if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || (cache_clk_enable && (sigmap(cell->connections.at("\\CLK")) != cache_clk || @@ -212,17 +414,18 @@ struct MemoryShareWorker } // Then we need to merge the (masked) EN and the DATA signals. - // Note that we intentionally do not use sigmap() on the DATA ports. RTLIL::SigSpec merged_data = wr_ports[last_i]->connections.at("\\DATA"); if (found_overlapping_bits) { log(" Creating logic for merging DATA and EN ports.\n"); - merge_en_data(merged_en, merged_data, sigmap(cell->connections.at("\\EN")), cell->connections.at("\\DATA")); + merge_en_data(merged_en, merged_data, sigmap(cell->connections.at("\\EN")), sigmap(cell->connections.at("\\DATA"))); } else { + RTLIL::SigSpec cell_en = sigmap(cell->connections.at("\\EN")); + RTLIL::SigSpec cell_data = sigmap(cell->connections.at("\\DATA")); for (int k = 0; k < int(en_bits.size()); k++) if (!active_bits_on_port[last_i][k]) { - merged_en.replace(k, cell->connections.at("\\EN").extract(k, 1)); - merged_data.replace(k, cell->connections.at("\\DATA").extract(k, 1)); + merged_en.replace(k, cell_en.extract(k, 1)); + merged_data.replace(k, cell_data.extract(k, 1)); } merged_en.optimize(); merged_data.optimize(); @@ -247,13 +450,28 @@ struct MemoryShareWorker last_port_by_addr[addr] = i; } + + // Clean up `wr_ports': remove all NULL entries + + std::vector wr_ports_with_nulls; + wr_ports_with_nulls.swap(wr_ports); + + for (auto cell : wr_ports_with_nulls) + if (cell != NULL) + wr_ports.push_back(cell); } + + // ------------- + // Setup and run + // ------------- + MemoryShareWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), sigmap(module) { std::map, std::vector>> memindex; + sigmap_xmux = sigmap; for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; @@ -266,19 +484,27 @@ struct MemoryShareWorker if (cell->type == "$mux") { - RTLIL::SigSpec sig_a = sigmap(cell->connections.at("\\A")); - RTLIL::SigSpec sig_b = sigmap(cell->connections.at("\\B")); + RTLIL::SigSpec sig_a = sigmap_xmux(cell->connections.at("\\A")); + RTLIL::SigSpec sig_b = sigmap_xmux(cell->connections.at("\\B")); if (sig_a.is_fully_undef()) - sigmap.add(cell->connections.at("\\Y"), sig_b); + sigmap_xmux.add(cell->connections.at("\\Y"), sig_b); else if (sig_b.is_fully_undef()) - sigmap.add(cell->connections.at("\\Y"), sig_a); + sigmap_xmux.add(cell->connections.at("\\Y"), sig_a); + } + + if (cell->type == "$mux" || cell->type == "$pmux") + { + std::vector sig_y = sigmap(cell->connections.at("\\Y")); + for (int i = 0; i < int(sig_y.size()); i++) + sig_to_mux[sig_y[i]] = std::pair(cell, i); } } for (auto &it : memindex) { std::sort(it.second.first.begin(), it.second.first.end(), memcells_cmp); std::sort(it.second.second.begin(), it.second.second.end(), memcells_cmp); + translate_rd_feedback_to_en(it.first, it.second.first, it.second.second); consolidate_wr_by_addr(it.first, it.second.second); } } diff --git a/tests/memories/implicit_en.v b/tests/memories/implicit_en.v new file mode 100644 index 00000000..cfce378b --- /dev/null +++ b/tests/memories/implicit_en.v @@ -0,0 +1,24 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 + +module test(clk, rd_addr, rd_data, wr_addr, wr_en, wr_data); + +input clk; + +input [3:0] rd_addr; +output reg [31:0] rd_data; + +input [3:0] wr_addr, wr_en; +input [31:0] wr_data; + +reg [31:0] mem [0:15]; + +always @(posedge clk) begin + mem[wr_addr][ 7: 0] <= wr_en[0] ? wr_data[ 7: 0] : mem[wr_addr][ 7: 0]; + mem[wr_addr][15: 8] <= wr_en[1] ? wr_data[15: 8] : mem[wr_addr][15: 8]; + mem[wr_addr][23:16] <= wr_en[2] ? wr_data[23:16] : mem[wr_addr][23:16]; + mem[wr_addr][31:24] <= wr_en[3] ? wr_data[31:24] : mem[wr_addr][31:24]; + rd_data <= mem[rd_addr]; +end + +endmodule From 26f982ac0b69deb3cb9eda69e5cf687a69de4606 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:32:14 +0200 Subject: [PATCH 306/750] Fixed bug in memory_share feedback-to-en code --- passes/memory/memory_share.cc | 16 ++++++++++++---- tests/memories/no_implicit_en.v | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 tests/memories/no_implicit_en.v diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index e2fa168c..4af0ebdc 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -120,7 +120,7 @@ struct MemoryShareWorker void translate_rd_feedback_to_en(std::string memid, std::vector &rd_ports, std::vector &wr_ports) { - std::vector> async_rd_bits; + std::map>> async_rd_bits; std::map> muxtree_upstream_map; std::set non_feedback_nets; @@ -187,15 +187,16 @@ struct MemoryShareWorker if (cell->parameters.at("\\CLK_ENABLE").as_bool()) continue; + RTLIL::SigSpec sig_addr = sigmap(cell->connections.at("\\ADDR")); std::vector sig_data = sigmap(cell->connections.at("\\DATA")); for (int i = 0; i < int(sig_data.size()); i++) if (non_feedback_nets.count(sig_data[i])) goto not_pure_feedback_port; - async_rd_bits.resize(std::max(async_rd_bits.size(), sig_data.size())); + async_rd_bits[sig_addr].resize(std::max(async_rd_bits.size(), sig_data.size())); for (int i = 0; i < int(sig_data.size()); i++) - async_rd_bits[i].insert(sig_data[i]); + async_rd_bits[sig_addr][i].insert(sig_data[i]); not_pure_feedback_port:; } @@ -207,6 +208,10 @@ struct MemoryShareWorker for (auto cell : wr_ports) { + RTLIL::SigSpec sig_addr = sigmap_xmux(cell->connections.at("\\ADDR")); + if (!async_rd_bits.count(sig_addr)) + continue; + log(" Analyzing write port %s.\n", log_id(cell)); std::vector cell_data = cell->connections.at("\\DATA"); @@ -224,7 +229,7 @@ struct MemoryShareWorker conditions.insert(state); } - find_data_feedback(async_rd_bits.at(i), cell_data[i], state, conditions); + find_data_feedback(async_rd_bits.at(sig_addr).at(i), cell_data[i], state, conditions); cell_en[i] = conditions_to_logic(conditions, created_conditions); } @@ -333,6 +338,9 @@ struct MemoryShareWorker void consolidate_wr_by_addr(std::string memid, std::vector &wr_ports) { + if (wr_ports.size() <= 1) + return; + log("Consolidating write ports of memory %s by address:\n", log_id(memid)); std::map last_port_by_addr; diff --git a/tests/memories/no_implicit_en.v b/tests/memories/no_implicit_en.v new file mode 100644 index 00000000..0e96e4ae --- /dev/null +++ b/tests/memories/no_implicit_en.v @@ -0,0 +1,24 @@ +// expect-wr-ports 1 +// expect-rd-ports 2 + +module test(clk, rd_addr, rd_data, cp_addr, wr_addr, wr_en, wr_data); + +input clk; + +input [3:0] rd_addr; +output reg [31:0] rd_data; + +input [3:0] cp_addr, wr_addr, wr_en; +input [31:0] wr_data; + +reg [31:0] mem [0:15]; + +always @(posedge clk) begin + mem[wr_addr][ 7: 0] <= wr_en[0] ? wr_data[ 7: 0] : mem[cp_addr][ 7: 0]; + mem[wr_addr][15: 8] <= wr_en[1] ? wr_data[15: 8] : mem[cp_addr][15: 8]; + mem[wr_addr][23:16] <= wr_en[2] ? wr_data[23:16] : mem[cp_addr][23:16]; + mem[wr_addr][31:24] <= wr_en[3] ? wr_data[31:24] : mem[cp_addr][31:24]; + rd_data <= mem[rd_addr]; +end + +endmodule From 1c288adcc03db49375dd0e214bbbc0b8b9099436 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:32:39 +0200 Subject: [PATCH 307/750] Some "const" cleanups in SigMap --- kernel/sigtools.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/sigtools.h b/kernel/sigtools.h index ae6a00f8..56497bb8 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -407,12 +407,12 @@ struct SigMap } // internal helper function - void map_bit(RTLIL::SigChunk &c) + void map_bit(RTLIL::SigChunk &c) const { assert(c.width == 1); bitDef_t bit(c.wire, c.offset); if (c.wire && bits.count(bit) > 0) - c = bits[bit]->chunk; + c = bits.at(bit)->chunk; } void add(RTLIL::SigSpec from, RTLIL::SigSpec to) @@ -459,7 +459,7 @@ struct SigMap unregister_bit(c); } - void apply(RTLIL::SigSpec &sig) + void apply(RTLIL::SigSpec &sig) const { sig.expand(); for (auto &c : sig.chunks) @@ -467,7 +467,7 @@ struct SigMap sig.optimize(); } - RTLIL::SigSpec operator()(RTLIL::SigSpec sig) + RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const { apply(sig); return sig; From 35edac0b31ff826c60d864febefc294263613716 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:33:00 +0200 Subject: [PATCH 308/750] Added ModWalker helper class --- kernel/modwalker.h | 298 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 kernel/modwalker.h diff --git a/kernel/modwalker.h b/kernel/modwalker.h new file mode 100644 index 00000000..6c3da5dd --- /dev/null +++ b/kernel/modwalker.h @@ -0,0 +1,298 @@ +/* + * 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. + * + */ + +#ifndef MODWALKER_H +#define MODWALKER_H + +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" + +struct ModWalker +{ + struct PortBit + { + RTLIL::Cell *cell; + RTLIL::IdString port; + int offset; + + bool operator<(const PortBit &other) const { + if (cell != other.cell) + return cell < other.cell; + if (port != other.port) + return port < other.port; + return offset < other.offset; + } + }; + + RTLIL::Design *design; + RTLIL::Module *module; + + CellTypes ct; + SigMap sigmap; + + std::map> signal_drivers; + std::map> signal_consumers; + std::set signal_inputs, signal_outputs; + + std::map> cell_outputs, cell_inputs; + + void add_wire(RTLIL::Wire *wire) + { + if (wire->port_input) { + std::vector bits = sigmap(wire); + for (auto bit : bits) + if (bit.wire != NULL) + signal_inputs.insert(bit); + } + + if (wire->port_output) { + std::vector bits = sigmap(wire); + for (auto bit : bits) + if (bit.wire != NULL) + signal_outputs.insert(bit); + } + } + + void add_cell_port(RTLIL::Cell *cell, RTLIL::IdString port, std::vector bits, bool is_output, bool is_input) + { + for (int i = 0; i < int(bits.size()); i++) + if (bits[i].wire != NULL) { + PortBit pbit = { cell, port, i }; + if (is_output) { + signal_drivers[bits[i]].insert(pbit); + cell_outputs[cell].insert(bits[i]); + } + if (is_input) { + signal_consumers[bits[i]].insert(pbit); + cell_inputs[cell].insert(bits[i]); + } + } + } + + void add_cell(RTLIL::Cell *cell) + { + if (ct.cell_known(cell->type)) { + for (auto &conn : cell->connections) + add_cell_port(cell, conn.first, sigmap(conn.second), + ct.cell_output(cell->type, conn.first), + ct.cell_input(cell->type, conn.first)); + } else { + for (auto &conn : cell->connections) + add_cell_port(cell, conn.first, sigmap(conn.second), true, true); + } + } + + ModWalker() : design(NULL), module(NULL) + { + } + + ModWalker(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL) + { + setup(design, module, filter_ct); + } + + void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL) + { + this->design = design; + this->module = module; + + ct.clear(); + ct.setup(design); + sigmap.set(module); + + signal_drivers.clear(); + signal_consumers.clear(); + signal_inputs.clear(); + signal_outputs.clear(); + + for (auto &it : module->wires) + add_wire(it.second); + for (auto &it : module->cells) + if (filter_ct == NULL || filter_ct->cell_known(it.second->type)) + add_cell(it.second); + } + + // get_* methods -- single RTLIL::SigBit + + template + inline bool get_drivers(std::set &result, RTLIL::SigBit bit) const + { + bool found = false; + if (signal_drivers.count(bit)) { + const std::set &r = signal_drivers.at(bit); + result.insert(r.begin(), r.end()); + found = true; + } + return found; + } + + template + inline bool get_consumers(std::set &result, RTLIL::SigBit bit) const + { + bool found = false; + if (signal_consumers.count(bit)) { + const std::set &r = signal_consumers.at(bit); + result.insert(r.begin(), r.end()); + found = true; + } + return found; + } + + template + inline bool get_inputs(std::set &result, RTLIL::SigBit bit) const + { + bool found = false; + if (signal_inputs.count(bit)) + result.insert(bit), found = true; + return found; + } + + template + inline bool get_outputs(std::set &result, RTLIL::SigBit bit) const + { + bool found = false; + if (signal_outputs.count(bit)) + result.insert(bit), found = true; + return found; + } + + // get_* methods -- container of RTLIL::SigBit's (always by reference) + + template + inline bool get_drivers(std::set &result, const T &bits) const + { + bool found = false; + for (RTLIL::SigBit bit : bits) + if (signal_drivers.count(bit)) { + const std::set &r = signal_drivers.at(bit); + result.insert(r.begin(), r.end()); + found = true; + } + return found; + } + + template + inline bool get_consumers(std::set &result, const T &bits) const + { + bool found = false; + for (RTLIL::SigBit bit : bits) + if (signal_consumers.count(bit)) { + const std::set &r = signal_consumers.at(bit); + result.insert(r.begin(), r.end()); + found = true; + } + return found; + } + + template + inline bool get_inputs(std::set &result, const T &bits) const + { + bool found = false; + for (RTLIL::SigBit bit : bits) + if (signal_inputs.count(bit)) + result.insert(bit), found = true; + return found; + } + + template + inline bool get_outputs(std::set &result, const T &bits) const + { + bool found = false; + for (RTLIL::SigBit bit : bits) + if (signal_outputs.count(bit)) + result.insert(bit), found = true; + return found; + } + + // get_* methods -- call by RTLIL::SigSpec (always by value) + + bool get_drivers(std::set &result, RTLIL::SigSpec signal) const + { + std::vector bits = sigmap(signal); + return get_drivers(result, bits); + } + + bool get_consumers(std::set &result, RTLIL::SigSpec signal) const + { + std::vector bits = sigmap(signal); + return get_consumers(result, bits); + } + + bool get_inputs(std::set &result, RTLIL::SigSpec signal) const + { + std::vector bits = sigmap(signal); + return get_inputs(result, bits); + } + + bool get_outputs(std::set &result, RTLIL::SigSpec signal) const + { + std::vector bits = sigmap(signal); + return get_outputs(result, bits); + } + + // has_* methods -- call by reference + + template + inline bool has_drivers(const T &sig) const { + std::set result; + return get_drivers(result, sig); + } + + template + inline bool has_consumers(const T &sig) const { + std::set result; + return get_consumers(result, sig); + } + + template + inline bool has_inputs(const T &sig) const { + std::set result; + return get_inputs(result, sig); + } + + template + inline bool has_outputs(const T &sig) const { + std::set result; + return get_outputs(result, sig); + } + + // has_* methods -- call by value + + inline bool has_drivers(RTLIL::SigSpec sig) const { + std::set result; + return get_drivers(result, sig); + } + + inline bool has_consumers(RTLIL::SigSpec sig) const { + std::set result; + return get_consumers(result, sig); + } + + inline bool has_inputs(RTLIL::SigSpec sig) const { + std::set result; + return get_inputs(result, sig); + } + + inline bool has_outputs(RTLIL::SigSpec sig) const { + std::set result; + return get_outputs(result, sig); + } +}; + +#endif From 297a0962ea399fcfa80656af2bc887c5725f5b82 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:33:55 +0200 Subject: [PATCH 309/750] Added SAT-based write-port sharing to memory_share --- passes/memory/memory_share.cc | 180 ++++++++++++++++++++++++++++++++++ tests/memories/shared_ports.v | 25 +++++ 2 files changed, 205 insertions(+) create mode 100644 tests/memories/shared_ports.v diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 4af0ebdc..20ff16de 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -18,7 +18,9 @@ */ #include "kernel/rtlil.h" +#include "kernel/satgen.h" #include "kernel/sigtools.h" +#include "kernel/modwalker.h" #include "kernel/register.h" #include "kernel/log.h" #include @@ -37,6 +39,8 @@ struct MemoryShareWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap, sigmap_xmux; + ModWalker modwalker; + CellTypes cone_ct; std::map> sig_to_mux; std::map>, RTLIL::SigBit> conditions_logic_cache; @@ -470,6 +474,167 @@ struct MemoryShareWorker } + // -------------------------------------------------------- + // Consolidate write ports using sat-based resource sharing + // -------------------------------------------------------- + + void consolidate_wr_using_sat(std::string memid, std::vector &wr_ports) + { + if (wr_ports.size() <= 1) + return; + + ezDefaultSAT ez; + SatGen satgen(&ez, &modwalker.sigmap); + + // find list of considered ports and port pairs + + std::set considered_ports; + std::set considered_port_pairs; + + for (int i = 0; i < int(wr_ports.size()); i++) { + std::vector bits = modwalker.sigmap(wr_ports[i]->connections.at("\\EN")); + for (auto bit : bits) + if (bit == RTLIL::State::S1) + goto port_is_always_active; + if (modwalker.has_drivers(bits)) + considered_ports.insert(i); + port_is_always_active:; + } + + log("Consolidating write ports of memory %s using sat-based resource sharing:\n", log_id(memid)); + + bool cache_clk_enable = false; + bool cache_clk_polarity = false; + RTLIL::SigSpec cache_clk; + + for (int i = 0; i < int(wr_ports.size()); i++) + { + RTLIL::Cell *cell = wr_ports.at(i); + + if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || + (cache_clk_enable && (sigmap(cell->connections.at("\\CLK")) != cache_clk || + cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) + { + cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); + cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); + cache_clk = sigmap(cell->connections.at("\\CLK")); + } + else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i)) + considered_port_pairs.insert(i); + + if (cache_clk_enable) + log(" Port %d (%s) on %s %s: %s\n", i, log_id(cell), + cache_clk_polarity ? "posedge" : "negedge", log_signal(cache_clk), + considered_ports.count(i) ? "considered" : "not considered"); + else + log(" Port %d (%s) unclocked: %s\n", i, log_id(cell), + considered_ports.count(i) ? "considered" : "not considered"); + } + + if (considered_port_pairs.size() < 1) { + log(" No two subsequent ports in same clock domain considered -> nothing to consolidate.\n"); + return; + } + + // create SAT representation of common input cone of all considered EN signals + + std::set sat_cells; + std::set bits_queue; + std::map port_to_sat_variable; + + for (int i = 0; i < int(wr_ports.size()); i++) + if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1)) + { + RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->connections.at("\\EN")); + port_to_sat_variable[i] = ez.expression(ez.OpOr, satgen.importSigSpec(sig)); + + std::vector bits = sig; + bits_queue.insert(bits.begin(), bits.end()); + } + + while (!bits_queue.empty()) + { + std::set portbits; + modwalker.get_drivers(portbits, bits_queue); + bits_queue.clear(); + + for (auto &pbit : portbits) + if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) { + std::set &cell_inputs = modwalker.cell_inputs[pbit.cell]; + bits_queue.insert(cell_inputs.begin(), cell_inputs.end()); + sat_cells.insert(pbit.cell); + } + } + + log(" Common input cone for all EN signals: %d cells.\n", int(sat_cells.size())); + + for (auto cell : sat_cells) + satgen.importCell(cell); + + log(" Size of unconstrained SAT problem: %d variables, %d clauses\n", ez.numCnfVariables(), ez.numCnfClauses()); + + // merge subsequent ports if possible + + for (int i = 0; i < int(wr_ports.size()); i++) + { + if (!considered_port_pairs.count(i)) + continue; + + if (ez.solve(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i))) { + log(" According to SAT solver sharing of port %d with port %d is not possible.\n", i-1, i); + continue; + } + + log(" Merging port %d into port %d.\n", i-1, i); + port_to_sat_variable.at(i) = ez.OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i)); + + RTLIL::SigSpec last_addr = wr_ports[i-1]->connections.at("\\ADDR"); + RTLIL::SigSpec last_data = wr_ports[i-1]->connections.at("\\DATA"); + std::vector last_en = modwalker.sigmap(wr_ports[i-1]->connections.at("\\EN")); + + RTLIL::SigSpec this_addr = wr_ports[i]->connections.at("\\ADDR"); + RTLIL::SigSpec this_data = wr_ports[i]->connections.at("\\DATA"); + std::vector this_en = modwalker.sigmap(wr_ports[i]->connections.at("\\EN")); + + RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); + + wr_ports[i]->connections.at("\\ADDR") = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); + wr_ports[i]->connections.at("\\DATA") = module->Mux(NEW_ID, last_data, this_data, this_en_active); + + std::map, int> groups_en; + RTLIL::SigSpec grouped_last_en, grouped_this_en, en; + RTLIL::Wire *grouped_en = module->new_wire(0, NEW_ID); + + for (int j = 0; j < int(this_en.size()); j++) { + std::pair key(last_en[j], this_en[j]); + if (!groups_en.count(key)) { + grouped_last_en.append_bit(last_en[j]); + grouped_this_en.append_bit(this_en[j]); + groups_en[key] = grouped_en->width; + grouped_en->width++; + } + en.append(RTLIL::SigSpec(grouped_en, 1, groups_en[key])); + } + + module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); + wr_ports[i]->connections.at("\\EN") = en; + + module->cells.erase(wr_ports[i-1]->name); + delete wr_ports[i-1]; + wr_ports[i-1] = NULL; + } + + // Clean up `wr_ports': remove all NULL entries + + std::vector wr_ports_with_nulls; + wr_ports_with_nulls.swap(wr_ports); + + for (auto cell : wr_ports_with_nulls) + if (cell != NULL) + wr_ports.push_back(cell); + } + + // ------------- // Setup and run // ------------- @@ -515,6 +680,21 @@ struct MemoryShareWorker translate_rd_feedback_to_en(it.first, it.second.first, it.second.second); consolidate_wr_by_addr(it.first, it.second.second); } + + cone_ct.setup_internals(); + cone_ct.cell_types.erase("$mul"); + cone_ct.cell_types.erase("$mod"); + cone_ct.cell_types.erase("$div"); + cone_ct.cell_types.erase("$pow"); + cone_ct.cell_types.erase("$shl"); + cone_ct.cell_types.erase("$shr"); + cone_ct.cell_types.erase("$sshl"); + cone_ct.cell_types.erase("$sshr"); + + modwalker.setup(design, module, &cone_ct); + + for (auto &it : memindex) + consolidate_wr_using_sat(it.first, it.second.second); } }; diff --git a/tests/memories/shared_ports.v b/tests/memories/shared_ports.v new file mode 100644 index 00000000..94bad53e --- /dev/null +++ b/tests/memories/shared_ports.v @@ -0,0 +1,25 @@ +// expect-wr-ports 1 +// expect-rd-ports 1 + +module test( + input clk, + input wr_en1, wr_en2, wr_en3, + input [3:0] wr_addr1, wr_addr2, wr_addr3, + input [15:0] wr_data, + input [3:0] rd_addr, + output reg [31:0] rd_data +); + +reg [31:0] mem [0:15]; + +always @(posedge clk) begin + if (wr_en1) + mem[wr_addr1][15:0] <= wr_data; + else if (wr_en2) + mem[wr_addr2][23:8] <= wr_data; + else if (wr_en3) + mem[wr_addr3][31:16] <= wr_data; + rd_data <= mem[rd_addr]; +end + +endmodule From e0a819dbe507c90e201279db317c2251b3c691eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:34:14 +0200 Subject: [PATCH 310/750] More verbose memory_share help message --- passes/memory/memory_share.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 20ff16de..cde5f218 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -708,6 +708,23 @@ struct MemorySharePass : public Pass { log("\n"); log("This pass merges share-able memory ports into single memory ports.\n"); log("\n"); + log("The following methods are used to consolidate the number of memory ports:\n"); + log("\n"); + log(" - When write ports are connected to async read ports accessing the same\n"); + log(" address, then this feedback path is converted to a write port with\n"); + log(" byte/part enable signals.\n"); + log("\n"); + log(" - When multiple write ports access the same adress then this is converted\n"); + log(" to a single write port with a more complex data and/or enable logic path.\n"); + log("\n"); + log(" - When multiple write ports are never accessed at the same time (a SAT\n"); + log(" solver is used to determine this), then the ports are merged into a single\n"); + log(" write port.\n"); + log("\n"); + log("Note that in addition to the algorithms implemented in this pass, the $memrd\n"); + log("and $memwr cells are also subject to generic resource sharing passes (and other\n"); + log("optimizations) such as opt_share.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing MEMORY_SHARE pass (consolidating $memrc/$memwr cells).\n"); From efd9604dfb92fda05c3efea67b7c32d812717fa8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:46:11 +0200 Subject: [PATCH 311/750] Improved memory_share log messages --- passes/memory/memory_share.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index cde5f218..dc015f96 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -208,7 +208,7 @@ struct MemoryShareWorker if (async_rd_bits.empty()) return; - log("Populating enable bits on write ports of memory %s with aync read feedback:\n", log_id(memid)); + log("Populating enable bits on write ports of memory %s.%s with aync read feedback:\n", log_id(module), log_id(memid)); for (auto cell : wr_ports) { @@ -345,7 +345,7 @@ struct MemoryShareWorker if (wr_ports.size() <= 1) return; - log("Consolidating write ports of memory %s by address:\n", log_id(memid)); + log("Consolidating write ports of memory %s.%s by address:\n", log_id(module), log_id(memid)); std::map last_port_by_addr; std::vector> active_bits_on_port; @@ -501,7 +501,7 @@ struct MemoryShareWorker port_is_always_active:; } - log("Consolidating write ports of memory %s using sat-based resource sharing:\n", log_id(memid)); + log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", log_id(module), log_id(memid)); bool cache_clk_enable = false; bool cache_clk_polarity = false; From 02f0acb3bce05f3af036495aa36049c67ffbdb52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 20:53:29 +0200 Subject: [PATCH 312/750] Fixed log_id() memory corruption --- kernel/log.cc | 8 ++++++++ kernel/log.h | 7 ++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index b2c92e4e..3108bddf 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -205,3 +205,11 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) return string_buf.back().c_str(); } +const char *log_id(std::string str) +{ + if (str.size() > 1 && str[0] == '\\' && str[1] != '$') + string_buf.push_back(str.substr(1)); + else + string_buf.push_back(str); + return string_buf.back().c_str(); +} diff --git a/kernel/log.h b/kernel/log.h index 3e280a6f..2c3597c9 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -51,13 +51,10 @@ void log_reset_stack(); void log_flush(); const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); - -static inline const char *log_id(std::string id) { - return RTLIL::id2cstr(id); -} +const char *log_id(std::string id); template static inline const char *log_id(T *obj) { - return RTLIL::id2cstr(obj->name); + return log_id(obj->name); } #define log_abort() log_error("Abort in %s:%d.\n", __FILE__, __LINE__) From 2278995bd8097558396ffdd3a5d24e324f22faa7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 20:54:32 +0200 Subject: [PATCH 313/750] Started to implement real resource sharing --- passes/sat/Makefile.inc | 1 + passes/sat/share.cc | 443 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 444 insertions(+) create mode 100644 passes/sat/share.cc diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index 4fa6bf0d..9aa80642 100644 --- a/passes/sat/Makefile.inc +++ b/passes/sat/Makefile.inc @@ -4,4 +4,5 @@ OBJS += passes/sat/freduce.o OBJS += passes/sat/eval.o OBJS += passes/sat/miter.o OBJS += passes/sat/expose.o +OBJS += passes/sat/share.o diff --git a/passes/sat/share.cc b/passes/sat/share.cc new file mode 100644 index 00000000..c04be7c8 --- /dev/null +++ b/passes/sat/share.cc @@ -0,0 +1,443 @@ +/* + * 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/rtlil.h" +#include "kernel/satgen.h" +#include "kernel/sigtools.h" +#include "kernel/modwalker.h" +#include "kernel/register.h" +#include "kernel/log.h" +#include + +struct ShareWorkerConfig +{ + bool opt_all; +}; + +struct ShareWorker +{ + ShareWorkerConfig config; + RTLIL::Design *design; + RTLIL::Module *module; + + CellTypes cone_ct; + ModWalker modwalker; + + // --------------------------------------------------- + // Find shareable cells and compatible groups of cells + // --------------------------------------------------- + + std::set shareable_cells; + + void find_shareable_cells() + { + std::vector candidates; + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + + if (!design->selected(module, cell) || !modwalker.ct.cell_known(cell->type)) + continue; + + if (config.opt_all) { + candidates.push_back(cell); + continue; + } + + if (cell->type == "$memrd") { + if (!cell->parameters.at("\\CLK_ENABLE").as_bool()) + candidates.push_back(cell); + continue; + } + + if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { + if (cell->parameters.at("\\Y_WIDTH").as_int() > 4) + candidates.push_back(cell); + continue; + } + + if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { + if (cell->parameters.at("\\Y_WIDTH").as_int() > 8) + candidates.push_back(cell); + continue; + } + } + + for (auto cell : candidates) + { + std::set driven_bits; + modwalker.get_consumers(driven_bits, modwalker.cell_outputs[cell]); + for (auto bit : driven_bits) { + if (bit.cell->type != "$mux" && bit.cell->type != "$pmux") + goto skip_candidate; + if (bit.port != "\\A" && bit.port != "\\B") + goto skip_candidate; + } + if (!modwalker.has_outputs(modwalker.cell_outputs[cell])) + shareable_cells.insert(cell); + skip_candidate:; + } + } + + bool is_shareable_pair(RTLIL::Cell *c1, RTLIL::Cell *c2) + { + if (c1->type != c2->type) + return false; + + if (c1->type == "$memrd") + { + if (c1->parameters.at("\\MEMID").decode_string() != c2->parameters.at("\\MEMID").decode_string()) + return false; + + return true; + } + + if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || + c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") + { + if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) + return false; + + if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) + return false; + + int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); + int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); + int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); + + int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); + int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); + int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); + + if (std::max(a1_width, a2_width) > 2 * std::min(a1_width, a2_width)) return false; + if (std::max(b1_width, b2_width) > 2 * std::min(b1_width, b2_width)) return false; + if (std::max(y1_width, y2_width) > 2 * std::min(y1_width, y2_width)) return false; + + return true; + } + + for (auto &it : c1->parameters) + if (c2->parameters.count(it.first) == 0 || c2->parameters.at(it.first) != it.second) + return false; + + for (auto &it : c2->parameters) + if (c1->parameters.count(it.first) == 0 || c1->parameters.at(it.first) != it.second) + return false; + + return true; + } + + void find_shareable_partners(std::vector &results, RTLIL::Cell *cell) + { + results.clear(); + for (auto c : shareable_cells) + if (c != cell && is_shareable_pair(c, cell)) + results.push_back(c); + } + + + // -------------------------------------------------------- + // Finding control inputs and activation pattern for a cell + // -------------------------------------------------------- + + std::map>> activation_patterns_cache; + + void follow_mux_data_cone(std::set> &patterns, + std::set> &state, RTLIL::SigSpec signal) + { + std::set consumers; + std::map> consumers_by_cell; + + if (modwalker.has_outputs(signal)) + goto signal_outside_mux_tree; + + modwalker.get_consumers(consumers, signal); + for (auto &bit : consumers) { + if ((bit.cell->type != "$mux" && bit.cell->type != "$pmux") || bit.port == "\\S") + goto signal_outside_mux_tree; + consumers_by_cell[bit.cell].insert(bit); + } + + if (0) { + signal_outside_mux_tree:; + RTLIL::SigSpec pattern_first, pattern_second; + for (auto &bit : state) { + pattern_first.append_bit(bit.first); + pattern_second.append_bit(bit.second); + } + patterns.insert(std::pair(pattern_first, pattern_second.as_const())); + return; + } + + for (auto &it : consumers_by_cell) + { + RTLIL::Cell *cell = it.first; + log_assert(cell->type == "$mux" || cell->type == "$pmux"); + + int width = cell->parameters.at("\\WIDTH").as_int(); + std::set used_in_b_parts; + bool used_in_a = false; + + for (auto &bit : it.second) { + if (bit.port == "\\A") + used_in_a = true; + else if (bit.port == "\\B") + used_in_b_parts.insert(bit.offset / width); + else + log_abort(); + } + + std::vector sig_s = modwalker.sigmap(cell->connections.at("\\S")).to_sigbit_vector(); + + if (used_in_a) { + std::set> new_state = state; + for (auto &bit : sig_s) { + std::pair this_state(bit, RTLIL::State::S0); + std::pair this_inv_state(bit, RTLIL::State::S1); + if (new_state.count(this_inv_state)) + goto conflict_in_a_port; + new_state.insert(this_state); + } + follow_mux_data_cone(patterns, new_state, modwalker.sigmap(cell->connections.at("\\Y"))); + conflict_in_a_port:; + } + + for (int part_idx : used_in_b_parts) { + std::set> new_state = state; + std::pair this_state(sig_s.at(part_idx), RTLIL::State::S1); + std::pair this_inv_state(sig_s.at(part_idx), RTLIL::State::S0); + if (new_state.count(this_inv_state)) + goto conflict_in_b_port; + new_state.insert(this_state); + follow_mux_data_cone(patterns, new_state, modwalker.sigmap(cell->connections.at("\\Y"))); + conflict_in_b_port:; + } + } + } + + const std::set> &find_cell_activation_patterns(RTLIL::Cell *cell) + { + if (activation_patterns_cache.count(cell)) + return activation_patterns_cache.at(cell); + + std::set> state; + RTLIL::SigSpec cell_output_signal; + + for (auto &bit : modwalker.cell_outputs[cell]) + cell_output_signal.append_bit(bit); + + follow_mux_data_cone(activation_patterns_cache[cell], state, cell_output_signal); + return activation_patterns_cache.at(cell); + } + + RTLIL::SigSpec bits_from_activation_patterns(const std::set> &activation_patterns) + { + std::set all_bits; + for (auto &it : activation_patterns) { + std::vector bits = it.first; + all_bits.insert(bits.begin(), bits.end()); + } + + RTLIL::SigSpec signal; + for (auto &bit : all_bits) + signal.append_bit(bit); + + return signal; + } + + + // ------------- + // Setup and run + // ------------- + + ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : + config(config), design(design), module(module) + { + cone_ct.setup_internals(); + cone_ct.cell_types.erase("$mul"); + cone_ct.cell_types.erase("$mod"); + cone_ct.cell_types.erase("$div"); + cone_ct.cell_types.erase("$pow"); + cone_ct.cell_types.erase("$shl"); + cone_ct.cell_types.erase("$shr"); + cone_ct.cell_types.erase("$sshl"); + cone_ct.cell_types.erase("$sshr"); + + modwalker.setup(design, module); + find_shareable_cells(); + + if (shareable_cells.size() < 2) + return; + + log("Found %d cells in module %s that may be considered for resource sharing.\n", + int(shareable_cells.size()), log_id(module)); + + while (!shareable_cells.empty()) + { + RTLIL::Cell *cell = *shareable_cells.begin(); + shareable_cells.erase(cell); + + log(" Analyzing resource sharing options for %s:\n", log_id(cell)); + + std::vector candidates; + find_shareable_partners(candidates, cell); + + if (candidates.empty()) { + log(" No candidates found.\n"); + continue; + } + + log(" Found %d candidates:", int(candidates.size())); + for (auto c : candidates) + log(" %s", log_id(c)); + log("\n"); + + const std::set> &cell_activation_patterns = find_cell_activation_patterns(cell); + RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns); + + log(" Found %d activation_patterns using ctrl signal %s.\n", int(cell_activation_patterns.size()), log_signal(cell_activation_signals)); + + if (cell_activation_patterns.empty()) + continue; + + for (auto other_cell : candidates) + { + log(" Analyzing resource sharing with %s:\n", log_id(other_cell)); + + const std::set> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell); + RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns); + + log(" Found %d activation_patterns using ctrl signal %s.\n", + int(other_cell_activation_patterns.size()), log_signal(other_cell_activation_signals)); + + if (other_cell_activation_patterns.empty()) + continue; + + ezDefaultSAT ez; + SatGen satgen(&ez, &modwalker.sigmap); + + std::set sat_cells; + std::set bits_queue; + + std::vector cell_active, other_cell_active; + RTLIL::SigSpec all_ctrl_signals; + + for (auto &p : cell_activation_patterns) { + log(" Activation pattern for cell %s: %s = %s\n", log_id(cell), log_signal(p.first), log_signal(p.second)); + cell_active.push_back(ez.vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second))); + all_ctrl_signals.append(p.first); + } + + for (auto &p : other_cell_activation_patterns) { + log(" Activation pattern for cell %s: %s = %s\n", log_id(other_cell), log_signal(p.first), log_signal(p.second)); + other_cell_active.push_back(ez.vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second))); + all_ctrl_signals.append(p.first); + } + + for (auto &bit : cell_activation_signals.to_sigbit_vector()) + bits_queue.insert(bit); + + for (auto &bit : other_cell_activation_signals.to_sigbit_vector()) + bits_queue.insert(bit); + + while (!bits_queue.empty()) + { + std::set portbits; + modwalker.get_drivers(portbits, bits_queue); + bits_queue.clear(); + + for (auto &pbit : portbits) + if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) { + // log(" Adding cell %s (%s) to SAT problem.\n", log_id(pbit.cell), log_id(pbit.cell->type)); + satgen.importCell(pbit.cell); + sat_cells.insert(pbit.cell); + } + } + + all_ctrl_signals.sort_and_unify(); + std::vector sat_model = satgen.importSigSpec(all_ctrl_signals); + std::vector sat_model_values; + + ez.assume(ez.AND(ez.expression(ez.OpOr, cell_active), ez.expression(ez.OpOr, other_cell_active))); + + log(" Size of SAT problem: %d cells, %d variables, %d clauses\n", + int(sat_cells.size()), ez.numCnfVariables(), ez.numCnfClauses()); + + if (ez.solve(sat_model, sat_model_values)) { + log(" According to the SAT solver this pair of cells can not be shared.\n"); + log(" Model from SAT solver: %s = %d'", log_signal(all_ctrl_signals), int(sat_model_values.size())); + for (int i = int(sat_model_values.size())-1; i >= 0; i--) + log("%c", sat_model_values[i] ? '1' : '0'); + log("\n"); + continue; + } + + log(" According to the SAT solver this pair of cells can be shared.\n"); + log(" WARNING: Actually sharing the cells is not implemented yet.\n"); + shareable_cells.erase(other_cell); + break; + } + } + } +}; + +struct SharePass : public Pass { + SharePass() : Pass("share", "perform sat-based resource sharing") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" share [options] [selection]\n"); + log("\n"); + log("This pass merges shareable resources into a single resource. A SAT solver\n"); + log("is used to determine if two resources are share-able.\n"); + log("\n"); + log(" -all\n"); + log(" Per default the selection of cells that is considered for sharing is\n"); + log(" narrowed using some built-in heuristics. With this option all selected\n"); + log(" cells are considered for resource sharing.\n"); + log("\n"); + log(" IMPORTANT NOTE: If the -all option is used then no cells with internal\n"); + log(" state must be selected!\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + ShareWorkerConfig config; + config.opt_all = false; + + log_header("Executing SHARE pass (SAT-based resource sharing).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-all") { + config.opt_all = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + for (auto &mod_it : design->modules) + if (design->selected(mod_it.second)) + ShareWorker(config, design, mod_it.second); + } +} SharePass; + From 0c67393313f125b6fca70614f10c2ec61116dd82 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 01:56:16 +0200 Subject: [PATCH 314/750] Added support for $bu0 to verilog backend --- backends/verilog/verilog_backend.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index d7fe4c4e..6be26329 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -581,6 +581,22 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) return true; } + if (cell->type == "$bu0") + { + fprintf(f, "%s" "assign ", indent.c_str()); + dump_sigspec(f, cell->connections["\\Y"]); + if (cell->parameters["\\A_SIGNED"].as_bool()) { + fprintf(f, " = $signed("); + dump_sigspec(f, cell->connections["\\A"]); + fprintf(f, ");\n"); + } else { + fprintf(f, " = { 1'b0, "); + dump_sigspec(f, cell->connections["\\A"]); + fprintf(f, " };\n"); + } + return true; + } + if (cell->type == "$concat") { fprintf(f, "%s" "assign ", indent.c_str()); From a30e2857c730c1adc1c6af2c995059af904eec0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 02:16:30 +0200 Subject: [PATCH 315/750] Use functions instead of always blocks for $mux/$pmux/$safe_pmux in verilog backend --- backends/verilog/verilog_backend.cc | 38 ++++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 6be26329..80ad7cb9 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -533,16 +533,18 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) { int width = cell->parameters["\\WIDTH"].as_int(); int s_width = cell->connections["\\S"].width; - std::string reg_name = cellname(cell); - fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), width-1, reg_name.c_str()); + std::string func_name = cellname(cell); - dump_attributes(f, indent, cell->attributes); + fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); + fprintf(f, "%s" " input [%d:0] a;\n", indent.c_str(), width-1); + fprintf(f, "%s" " input [%d:0] b;\n", indent.c_str(), s_width*width-1); + fprintf(f, "%s" " input [%d:0] s;\n", indent.c_str(), s_width-1); + + dump_attributes(f, indent + " ", cell->attributes); if (!noattr) - fprintf(f, "%s" "(* parallel_case *)\n", indent.c_str()); - fprintf(f, "%s" "always @*\n", indent.c_str()); - fprintf(f, "%s" " casez (", indent.c_str()); - dump_sigspec(f, cell->connections["\\S"]); - fprintf(f, noattr ? ") // synopsys parallel_case\n" : ")\n"); + fprintf(f, "%s" " (* parallel_case *)\n", indent.c_str()); + fprintf(f, "%s" " casez (s)", indent.c_str()); + fprintf(f, noattr ? " // synopsys parallel_case\n" : "\n"); for (int i = 0; i < s_width; i++) { @@ -552,22 +554,24 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, "%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?'); fprintf(f, ":\n"); - fprintf(f, "%s" " %s = ", indent.c_str(), reg_name.c_str()); - - RTLIL::SigSpec s = cell->connections["\\B"].extract(i * width, width); - dump_sigspec(f, s); - fprintf(f, ";\n"); + fprintf(f, "%s" " %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width); } fprintf(f, "%s" " default:\n", indent.c_str()); - fprintf(f, "%s" " %s = ", indent.c_str(), reg_name.c_str()); - dump_sigspec(f, cell->connections["\\A"]); - fprintf(f, ";\n"); + fprintf(f, "%s" " %s = a;\n", indent.c_str(), func_name.c_str()); fprintf(f, "%s" " endcase\n", indent.c_str()); + fprintf(f, "%s" "endfunction\n", indent.c_str()); + fprintf(f, "%s" "assign ", indent.c_str()); dump_sigspec(f, cell->connections["\\Y"]); - fprintf(f, " = %s;\n", reg_name.c_str()); + fprintf(f, " = %s(", func_name.c_str()); + dump_sigspec(f, cell->connections["\\A"]); + fprintf(f, ", "); + dump_sigspec(f, cell->connections["\\B"]); + fprintf(f, ", "); + dump_sigspec(f, cell->connections["\\S"]); + fprintf(f, ");\n"); return true; } From 3f9f0c047d46f8b84a5a73e6c9437d0ee3793324 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 02:19:44 +0200 Subject: [PATCH 316/750] Added tests/vloghtb --- tests/vloghtb/.gitignore | 7 +++++++ tests/vloghtb/run-test.sh | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/vloghtb/.gitignore create mode 100755 tests/vloghtb/run-test.sh diff --git a/tests/vloghtb/.gitignore b/tests/vloghtb/.gitignore new file mode 100644 index 00000000..da1ffa41 --- /dev/null +++ b/tests/vloghtb/.gitignore @@ -0,0 +1,7 @@ +Makefile +refdat +rtl +scripts +spec +check_yosys +vloghammer_tb.tar.bz2 diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh new file mode 100755 index 00000000..9bef4450 --- /dev/null +++ b/tests/vloghtb/run-test.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -ex + +rm -rf Makefile refdat rtl scripts spec vloghammer_tb.tar.bz2 +wget http://www.clifford.at/yosys/nogit/vloghammer_tb.tar.bz2 +tar --strip=1 -xjf vloghammer_tb.tar.bz2 + +make clean +make -j4 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys + From 15fd615da5a119b4ee9cded9f44ae36fd66820f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 03:03:04 +0200 Subject: [PATCH 317/750] Progress in "share" pass --- passes/sat/share.cc | 75 +++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index c04be7c8..aad53e13 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -27,7 +27,9 @@ struct ShareWorkerConfig { - bool opt_all; + bool opt_force; + bool opt_aggressive; + bool opt_fast; }; struct ShareWorker @@ -56,7 +58,7 @@ struct ShareWorker if (!design->selected(module, cell) || !modwalker.ct.cell_known(cell->type)) continue; - if (config.opt_all) { + if (config.opt_force) { candidates.push_back(cell); continue; } @@ -68,13 +70,19 @@ struct ShareWorker } if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { - if (cell->parameters.at("\\Y_WIDTH").as_int() > 4) + if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 4) candidates.push_back(cell); continue; } if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { - if (cell->parameters.at("\\Y_WIDTH").as_int() > 8) + if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 8) + candidates.push_back(cell); + continue; + } + + if (cell->type == "$add" || cell->type == "$sub") { + if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 10) candidates.push_back(cell); continue; } @@ -109,7 +117,7 @@ struct ShareWorker return true; } - if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || + if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || c1->type == "$add" || c1->type == "$sub" || c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") { if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) @@ -118,17 +126,20 @@ struct ShareWorker if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) return false; - int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); - int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); - int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); + if (!config.opt_aggressive) + { + int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); + int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); + int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); - int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); - int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); - int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); + int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); + int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); + int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); - if (std::max(a1_width, a2_width) > 2 * std::min(a1_width, a2_width)) return false; - if (std::max(b1_width, b2_width) > 2 * std::min(b1_width, b2_width)) return false; - if (std::max(y1_width, y2_width) > 2 * std::min(y1_width, y2_width)) return false; + if (std::max(a1_width, a2_width) > 2 * std::min(a1_width, a2_width)) return false; + if (std::max(b1_width, b2_width) > 2 * std::min(b1_width, b2_width)) return false; + if (std::max(y1_width, y2_width) > 2 * std::min(y1_width, y2_width)) return false; + } return true; } @@ -365,10 +376,15 @@ struct ShareWorker for (auto &pbit : portbits) if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) { + if (config.opt_fast && modwalker.cell_outputs[pbit.cell].size() >= 4) + continue; // log(" Adding cell %s (%s) to SAT problem.\n", log_id(pbit.cell), log_id(pbit.cell->type)); satgen.importCell(pbit.cell); sat_cells.insert(pbit.cell); } + + if (config.opt_fast && sat_cells.size() > 100) + break; } all_ctrl_signals.sort_and_unify(); @@ -409,26 +425,47 @@ struct SharePass : public Pass { log("This pass merges shareable resources into a single resource. A SAT solver\n"); log("is used to determine if two resources are share-able.\n"); log("\n"); - log(" -all\n"); + log(" -force\n"); log(" Per default the selection of cells that is considered for sharing is\n"); - log(" narrowed using some built-in heuristics. With this option all selected\n"); + log(" narrowed using a list of cell types. With this option all selected\n"); log(" cells are considered for resource sharing.\n"); log("\n"); log(" IMPORTANT NOTE: If the -all option is used then no cells with internal\n"); log(" state must be selected!\n"); log("\n"); + log(" -aggressive\n"); + log(" Per default some heuristics are used to reduce the number of cells\n"); + log(" considered for resource sharing to only large resources. This options\n"); + log(" turns this heuristics off, resulting in much more cells being considered\n"); + log(" for resource sharing.\n"); + log("\n"); + log(" -fast\n"); + log(" Only consider comparable primitive control logic in SAT solving, resulting\n"); + log(" in much easier SAT problems at the cost of maybe missing some oportunities\n"); + log(" for resource sharing.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { ShareWorkerConfig config; - config.opt_all = false; + config.opt_force = false; + config.opt_aggressive = false; + config.opt_fast = false; log_header("Executing SHARE pass (SAT-based resource sharing).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-all") { - config.opt_all = true; + if (args[argidx] == "-force") { + config.opt_force = true; + continue; + } + if (args[argidx] == "-aggressive") { + config.opt_aggressive = true; + continue; + } + if (args[argidx] == "-fast") { + config.opt_fast = true; continue; } break; From a6174aaf5eec37f1d1713afa978ae16286fc0b74 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 10:35:47 +0200 Subject: [PATCH 318/750] Added log_cell() --- kernel/log.cc | 15 +++++++++++++++ kernel/log.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/kernel/log.cc b/kernel/log.cc index 3108bddf..949bf432 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -213,3 +213,18 @@ const char *log_id(std::string str) string_buf.push_back(str); return string_buf.back().c_str(); } + +void log_cell(RTLIL::Cell *cell, std::string indent) +{ + char *ptr; + size_t size; + + FILE *f = open_memstream(&ptr, &size); + ILANG_BACKEND::dump_cell(f, indent, cell); + fputc(0, f); + fclose(f); + + log("%s", ptr); + free(ptr); +} + diff --git a/kernel/log.h b/kernel/log.h index 2c3597c9..f6dcc0ac 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -57,6 +57,8 @@ template static inline const char *log_id(T *obj) { return log_id(obj->name); } +void log_cell(RTLIL::Cell *cell, std::string indent = ""); + #define log_abort() log_error("Abort in %s:%d.\n", __FILE__, __LINE__) #define log_assert(_assert_expr_) do { if (_assert_expr_) break; log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) From efa78840261871616f9af15e5ad9a5bc89f95857 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 10:36:14 +0200 Subject: [PATCH 319/750] Added SIZE() macro --- kernel/rtlil.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 3a22d137..6290db21 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -26,7 +26,9 @@ #include #include +// various helpers (unrelated to RTLIL) std::string stringf(const char *fmt, ...); +#define SIZE(__obj) int(__obj.size()) namespace RTLIL { From e57db5e9b256d801c1d4337e44e1a7173a115d07 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 11:00:09 +0200 Subject: [PATCH 320/750] Added std::set to RTLIL::SigSpec conversion --- kernel/rtlil.cc | 13 ++++++++++--- kernel/rtlil.h | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index dea0e105..748deae3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1451,10 +1451,17 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) RTLIL::SigSpec::SigSpec(std::vector bits) { - chunks.reserve(bits.size()); + this->width = 0; for (auto &bit : bits) - chunks.push_back(bit); - this->width = bits.size(); + append_bit(bit); + check(); +} + +RTLIL::SigSpec::SigSpec(std::set bits) +{ + this->width = 0; + for (auto &bit : bits) + append_bit(bit); check(); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6290db21..64136de0 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -505,6 +505,7 @@ struct RTLIL::SigSpec { SigSpec(RTLIL::State bit, int width = 1); SigSpec(RTLIL::SigBit bit, int width = 1); SigSpec(std::vector bits); + SigSpec(std::set bits); void expand(); void optimize(); RTLIL::SigSpec optimized() const; From 8819493db4e2a02cef5d0ee751ff56605db5995b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 10:36:46 +0200 Subject: [PATCH 321/750] Progress in "share" pass --- passes/sat/share.cc | 297 +++++++++++++++++++++++++++----------------- 1 file changed, 185 insertions(+), 112 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index aad53e13..a1510a59 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -38,9 +38,77 @@ struct ShareWorker RTLIL::Design *design; RTLIL::Module *module; - CellTypes cone_ct; + CellTypes fwd_ct, cone_ct; ModWalker modwalker; + + // ------------------------------------------------------------------------------ + // Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree + // ------------------------------------------------------------------------------ + + std::set terminal_bits; + + void find_terminal_bits() + { + std::set queue_strong_bits, queue_weak_bits; + std::set visited_cells; + + queue_weak_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end()); + + for (auto &it : module->cells) + { + RTLIL::Cell *cell = it.second; + + if (cell->type == "$mux" || cell->type == "$pmux") + { + std::vector bits = modwalker.sigmap(cell->connections.at("\\S")); + queue_strong_bits.insert(bits.begin(), bits.end()); + } + else if (!fwd_ct.cell_known(cell->type)) + { + std::set &bits = modwalker.cell_inputs[cell]; + queue_weak_bits.insert(bits.begin(), bits.end()); + } + } + + terminal_bits.insert(queue_strong_bits.begin(), queue_strong_bits.end()); + terminal_bits.insert(queue_weak_bits.begin(), queue_weak_bits.end()); + + while (!queue_strong_bits.empty()) + { + std::set portbits; + modwalker.get_drivers(portbits, queue_strong_bits); + queue_strong_bits.clear(); + + for (auto &pbit : portbits) + if (fwd_ct.cell_known(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) { + std::set &bits = modwalker.cell_inputs[pbit.cell]; + terminal_bits.insert(bits.begin(), bits.end()); + queue_strong_bits.insert(bits.begin(), bits.end()); + visited_cells.insert(pbit.cell); + } + } + + while (!queue_weak_bits.empty()) + { + std::set portbits; + modwalker.get_drivers(portbits, queue_weak_bits); + queue_weak_bits.clear(); + + for (auto &pbit : portbits) { + if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") + continue; + if (fwd_ct.cell_known(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) { + std::set &bits = modwalker.cell_inputs[pbit.cell]; + terminal_bits.insert(bits.begin(), bits.end()); + queue_weak_bits.insert(bits.begin(), bits.end()); + visited_cells.insert(pbit.cell); + } + } + } + } + + // --------------------------------------------------- // Find shareable cells and compatible groups of cells // --------------------------------------------------- @@ -49,8 +117,6 @@ struct ShareWorker void find_shareable_cells() { - std::vector candidates; - for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; @@ -58,50 +124,43 @@ struct ShareWorker if (!design->selected(module, cell) || !modwalker.ct.cell_known(cell->type)) continue; + for (auto &bit : modwalker.cell_outputs[cell]) + if (terminal_bits.count(bit)) + goto not_a_muxed_cell; + + if (0) + not_a_muxed_cell: + continue; + if (config.opt_force) { - candidates.push_back(cell); + shareable_cells.insert(cell); continue; } if (cell->type == "$memrd") { if (!cell->parameters.at("\\CLK_ENABLE").as_bool()) - candidates.push_back(cell); + shareable_cells.insert(cell); continue; } if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 4) - candidates.push_back(cell); + shareable_cells.insert(cell); continue; } if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 8) - candidates.push_back(cell); + shareable_cells.insert(cell); continue; } if (cell->type == "$add" || cell->type == "$sub") { if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 10) - candidates.push_back(cell); + shareable_cells.insert(cell); continue; } } - - for (auto cell : candidates) - { - std::set driven_bits; - modwalker.get_consumers(driven_bits, modwalker.cell_outputs[cell]); - for (auto bit : driven_bits) { - if (bit.cell->type != "$mux" && bit.cell->type != "$pmux") - goto skip_candidate; - if (bit.port != "\\A" && bit.port != "\\B") - goto skip_candidate; - } - if (!modwalker.has_outputs(modwalker.cell_outputs[cell])) - shareable_cells.insert(cell); - skip_candidate:; - } } bool is_shareable_pair(RTLIL::Cell *c1, RTLIL::Cell *c2) @@ -170,77 +229,28 @@ struct ShareWorker std::map>> activation_patterns_cache; - void follow_mux_data_cone(std::set> &patterns, - std::set> &state, RTLIL::SigSpec signal) + bool sort_check_pattern(std::pair &p) { - std::set consumers; - std::map> consumers_by_cell; + std::map p_bits; - if (modwalker.has_outputs(signal)) - goto signal_outside_mux_tree; - - modwalker.get_consumers(consumers, signal); - for (auto &bit : consumers) { - if ((bit.cell->type != "$mux" && bit.cell->type != "$pmux") || bit.port == "\\S") - goto signal_outside_mux_tree; - consumers_by_cell[bit.cell].insert(bit); + std::vector p_first_bits = p.first; + for (int i = 0; i < SIZE(p_first_bits); i++) { + RTLIL::SigBit b = p_first_bits[i]; + RTLIL::State v = p.second.bits[i]; + if (p_bits.count(b) && p_bits.at(b) != v) + return false; + p_bits[b] = v; } - if (0) { - signal_outside_mux_tree:; - RTLIL::SigSpec pattern_first, pattern_second; - for (auto &bit : state) { - pattern_first.append_bit(bit.first); - pattern_second.append_bit(bit.second); - } - patterns.insert(std::pair(pattern_first, pattern_second.as_const())); - return; + p.first = RTLIL::SigSpec(); + p.second.bits.clear(); + + for (auto &it : p_bits) { + p.first.append_bit(it.first); + p.second.bits.push_back(it.second); } - for (auto &it : consumers_by_cell) - { - RTLIL::Cell *cell = it.first; - log_assert(cell->type == "$mux" || cell->type == "$pmux"); - - int width = cell->parameters.at("\\WIDTH").as_int(); - std::set used_in_b_parts; - bool used_in_a = false; - - for (auto &bit : it.second) { - if (bit.port == "\\A") - used_in_a = true; - else if (bit.port == "\\B") - used_in_b_parts.insert(bit.offset / width); - else - log_abort(); - } - - std::vector sig_s = modwalker.sigmap(cell->connections.at("\\S")).to_sigbit_vector(); - - if (used_in_a) { - std::set> new_state = state; - for (auto &bit : sig_s) { - std::pair this_state(bit, RTLIL::State::S0); - std::pair this_inv_state(bit, RTLIL::State::S1); - if (new_state.count(this_inv_state)) - goto conflict_in_a_port; - new_state.insert(this_state); - } - follow_mux_data_cone(patterns, new_state, modwalker.sigmap(cell->connections.at("\\Y"))); - conflict_in_a_port:; - } - - for (int part_idx : used_in_b_parts) { - std::set> new_state = state; - std::pair this_state(sig_s.at(part_idx), RTLIL::State::S1); - std::pair this_inv_state(sig_s.at(part_idx), RTLIL::State::S0); - if (new_state.count(this_inv_state)) - goto conflict_in_b_port; - new_state.insert(this_state); - follow_mux_data_cone(patterns, new_state, modwalker.sigmap(cell->connections.at("\\Y"))); - conflict_in_b_port:; - } - } + return true; } const std::set> &find_cell_activation_patterns(RTLIL::Cell *cell) @@ -248,14 +258,68 @@ struct ShareWorker if (activation_patterns_cache.count(cell)) return activation_patterns_cache.at(cell); - std::set> state; - RTLIL::SigSpec cell_output_signal; + const std::set &cell_out_bits = modwalker.cell_outputs[cell]; + std::set driven_cells; - for (auto &bit : modwalker.cell_outputs[cell]) - cell_output_signal.append_bit(bit); + for (auto &bit : cell_out_bits) + { + if (terminal_bits.count(bit)) { + // Terminal cells are always active: unconditional activation pattern + activation_patterns_cache[cell].insert(std::pair()); + return activation_patterns_cache.at(cell); + } + for (auto &pbit : modwalker.signal_consumers[bit]) { + log_assert(fwd_ct.cell_known(pbit.cell->type)); + driven_cells.insert(pbit.cell); + } + } - follow_mux_data_cone(activation_patterns_cache[cell], state, cell_output_signal); - return activation_patterns_cache.at(cell); + for (auto c : driven_cells) + { + const std::set> &c_patterns = find_cell_activation_patterns(c); + + if (c->type == "$mux" || c->type == "$pmux") + { + bool used_in_a = false; + std::set used_in_b_parts; + + int width = c->parameters.at("\\WIDTH").as_int(); + std::vector sig_a = modwalker.sigmap(c->connections.at("\\A")); + std::vector sig_b = modwalker.sigmap(c->connections.at("\\B")); + std::vector sig_s = modwalker.sigmap(c->connections.at("\\S")); + + for (auto &bit : sig_a) + if (cell_out_bits.count(bit)) + used_in_a = true; + + for (int i = 0; i < SIZE(sig_b); i++) + if (cell_out_bits.count(sig_b[i])) + used_in_b_parts.insert(i / width); + + if (used_in_a) + for (auto p : c_patterns) { + for (int i = 0; i < SIZE(sig_s); i++) + p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0); + if (sort_check_pattern(p)) + activation_patterns_cache[cell].insert(p); + } + + for (int idx : used_in_b_parts) + for (auto p : c_patterns) { + p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1); + if (sort_check_pattern(p)) + activation_patterns_cache[cell].insert(p); + } + } + else + { + // Not a mux: just copy the activation patterns + for (auto &p : c_patterns) + activation_patterns_cache[cell].insert(p); + } + } + + return activation_patterns_cache[cell]; } RTLIL::SigSpec bits_from_activation_patterns(const std::set> &activation_patterns) @@ -281,6 +345,8 @@ struct ShareWorker ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : config(config), design(design), module(module) { + fwd_ct.setup_internals(); + cone_ct.setup_internals(); cone_ct.cell_types.erase("$mul"); cone_ct.cell_types.erase("$mod"); @@ -292,13 +358,15 @@ struct ShareWorker cone_ct.cell_types.erase("$sshr"); modwalker.setup(design, module); + + find_terminal_bits(); find_shareable_cells(); if (shareable_cells.size() < 2) return; log("Found %d cells in module %s that may be considered for resource sharing.\n", - int(shareable_cells.size()), log_id(module)); + SIZE(shareable_cells), log_id(module)); while (!shareable_cells.empty()) { @@ -307,6 +375,16 @@ struct ShareWorker log(" Analyzing resource sharing options for %s:\n", log_id(cell)); + const std::set> &cell_activation_patterns = find_cell_activation_patterns(cell); + RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns); + + if (cell_activation_patterns.count(std::pair())) { + log (" Cell is always active. Therefore no sharing is possible.\n"); + continue; + } + + log(" Found %d activation_patterns using ctrl signal %s.\n", SIZE(cell_activation_patterns), log_signal(cell_activation_signals)); + std::vector candidates; find_shareable_partners(candidates, cell); @@ -315,19 +393,11 @@ struct ShareWorker continue; } - log(" Found %d candidates:", int(candidates.size())); + log(" Found %d candidates:", SIZE(candidates)); for (auto c : candidates) log(" %s", log_id(c)); log("\n"); - const std::set> &cell_activation_patterns = find_cell_activation_patterns(cell); - RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns); - - log(" Found %d activation_patterns using ctrl signal %s.\n", int(cell_activation_patterns.size()), log_signal(cell_activation_signals)); - - if (cell_activation_patterns.empty()) - continue; - for (auto other_cell : candidates) { log(" Analyzing resource sharing with %s:\n", log_id(other_cell)); @@ -335,11 +405,13 @@ struct ShareWorker const std::set> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell); RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns); - log(" Found %d activation_patterns using ctrl signal %s.\n", - int(other_cell_activation_patterns.size()), log_signal(other_cell_activation_signals)); - - if (other_cell_activation_patterns.empty()) + if (other_cell_activation_patterns.count(std::pair())) { + log (" Cell is always active. Therefore no sharing is possible.\n"); continue; + } + + log(" Found %d activation_patterns using ctrl signal %s.\n", + SIZE(other_cell_activation_patterns), log_signal(other_cell_activation_signals)); ezDefaultSAT ez; SatGen satgen(&ez, &modwalker.sigmap); @@ -379,6 +451,7 @@ struct ShareWorker if (config.opt_fast && modwalker.cell_outputs[pbit.cell].size() >= 4) continue; // log(" Adding cell %s (%s) to SAT problem.\n", log_id(pbit.cell), log_id(pbit.cell->type)); + bits_queue.insert(modwalker.cell_inputs[pbit.cell].begin(), modwalker.cell_inputs[pbit.cell].end()); satgen.importCell(pbit.cell); sat_cells.insert(pbit.cell); } @@ -394,12 +467,12 @@ struct ShareWorker ez.assume(ez.AND(ez.expression(ez.OpOr, cell_active), ez.expression(ez.OpOr, other_cell_active))); log(" Size of SAT problem: %d cells, %d variables, %d clauses\n", - int(sat_cells.size()), ez.numCnfVariables(), ez.numCnfClauses()); + SIZE(sat_cells), ez.numCnfVariables(), ez.numCnfClauses()); if (ez.solve(sat_model, sat_model_values)) { log(" According to the SAT solver this pair of cells can not be shared.\n"); - log(" Model from SAT solver: %s = %d'", log_signal(all_ctrl_signals), int(sat_model_values.size())); - for (int i = int(sat_model_values.size())-1; i >= 0; i--) + log(" Model from SAT solver: %s = %d'", log_signal(all_ctrl_signals), SIZE(sat_model_values)); + for (int i = SIZE(sat_model_values)-1; i >= 0; i--) log("%c", sat_model_values[i] ? '1' : '0'); log("\n"); continue; @@ -440,7 +513,7 @@ struct SharePass : public Pass { log(" for resource sharing.\n"); log("\n"); log(" -fast\n"); - log(" Only consider comparable primitive control logic in SAT solving, resulting\n"); + log(" Only consider the simple part of the control logic in SAT solving, resulting\n"); log(" in much easier SAT problems at the cost of maybe missing some oportunities\n"); log(" for resource sharing.\n"); log("\n"); From 7b98e46ac352e625be2d8da9b12e7252ed5179d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 11:41:57 +0200 Subject: [PATCH 322/750] Added removing of always inactive cells to "share" pass --- passes/sat/share.cc | 50 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index a1510a59..fd48b901 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -41,6 +41,8 @@ struct ShareWorker CellTypes fwd_ct, cone_ct; ModWalker modwalker; + std::set cells_to_remove; + // ------------------------------------------------------------------------------ // Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree @@ -229,7 +231,7 @@ struct ShareWorker std::map>> activation_patterns_cache; - bool sort_check_pattern(std::pair &p) + bool sort_check_activation_pattern(std::pair &p) { std::map p_bits; @@ -253,7 +255,13 @@ struct ShareWorker return true; } - const std::set> &find_cell_activation_patterns(RTLIL::Cell *cell) + void optimize_activation_patterns(std::set> & /* patterns */) + { + // TODO: Remove patterns that are contained in other patterns + // TODO: Consolidate pairs of patterns that only differ in the value for one signal bit + } + + const std::set> &find_cell_activation_patterns(RTLIL::Cell *cell, const char *indent) { if (activation_patterns_cache.count(cell)) return activation_patterns_cache.at(cell); @@ -276,7 +284,7 @@ struct ShareWorker for (auto c : driven_cells) { - const std::set> &c_patterns = find_cell_activation_patterns(c); + const std::set> &c_patterns = find_cell_activation_patterns(c, indent); if (c->type == "$mux" || c->type == "$pmux") { @@ -300,14 +308,14 @@ struct ShareWorker for (auto p : c_patterns) { for (int i = 0; i < SIZE(sig_s); i++) p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0); - if (sort_check_pattern(p)) + if (sort_check_activation_pattern(p)) activation_patterns_cache[cell].insert(p); } for (int idx : used_in_b_parts) for (auto p : c_patterns) { p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1); - if (sort_check_pattern(p)) + if (sort_check_activation_pattern(p)) activation_patterns_cache[cell].insert(p); } } @@ -319,6 +327,12 @@ struct ShareWorker } } + optimize_activation_patterns(activation_patterns_cache[cell]); + if (activation_patterns_cache[cell].empty()) { + log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); + cells_to_remove.insert(cell); + } + return activation_patterns_cache[cell]; } @@ -375,9 +389,14 @@ struct ShareWorker log(" Analyzing resource sharing options for %s:\n", log_id(cell)); - const std::set> &cell_activation_patterns = find_cell_activation_patterns(cell); + const std::set> &cell_activation_patterns = find_cell_activation_patterns(cell, " "); RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns); + if (cell_activation_patterns.empty()) { + log (" Cell is never active. Sharing is pointless, we simply remove it.\n"); + continue; + } + if (cell_activation_patterns.count(std::pair())) { log (" Cell is always active. Therefore no sharing is possible.\n"); continue; @@ -402,11 +421,17 @@ struct ShareWorker { log(" Analyzing resource sharing with %s:\n", log_id(other_cell)); - const std::set> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell); + const std::set> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell, " "); RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns); + if (other_cell_activation_patterns.empty()) { + log (" Cell is never active. Sharing is pointless, we simply remove it.\n"); + shareable_cells.erase(other_cell); + continue; + } + if (other_cell_activation_patterns.count(std::pair())) { - log (" Cell is always active. Therefore no sharing is possible.\n"); + log (" Cell is always active. Therefore no sharing is possible.\n"); continue; } @@ -484,6 +509,15 @@ struct ShareWorker break; } } + + if (!cells_to_remove.empty()) { + log("Removing %d cells in module %s:\n", SIZE(cells_to_remove), log_id(module)); + for (auto c : cells_to_remove) { + log(" Removing cell %s (%s).\n", log_id(c), log_id(c->type)); + module->cells.erase(c->name); + delete c; + } + } } }; From 5b3ee7a072ad0bd7fb1245a2fb3560a0ca034457 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:00:18 +0200 Subject: [PATCH 323/750] Added "share" supercell creation --- passes/sat/share.cc | 116 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index fd48b901..9ad1d621 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -134,6 +134,10 @@ struct ShareWorker not_a_muxed_cell: continue; + // FIXME: Creation of super cells is broken for this cell types + if (cell->type == "$shr" || cell->type == "$mod") + continue; + if (config.opt_force) { shareable_cells.insert(cell); continue; @@ -225,6 +229,71 @@ struct ShareWorker } + // ----------------------- + // Create replacement cell + // ----------------------- + + RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act) + { + if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || c1->type == "$add" || c1->type == "$sub" || + c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") + { + log_assert(c1->type == c2->type); + + bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); + bool b_signed = c1->parameters.at("\\B_SIGNED").as_bool(); + + log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); + log_assert(b_signed == c2->parameters.at("\\B_SIGNED").as_bool()); + + RTLIL::SigSpec a1 = c1->connections.at("\\A"); + RTLIL::SigSpec b1 = c1->connections.at("\\B"); + RTLIL::SigSpec y1 = c1->connections.at("\\Y"); + + RTLIL::SigSpec a2 = c2->connections.at("\\A"); + RTLIL::SigSpec b2 = c2->connections.at("\\B"); + RTLIL::SigSpec y2 = c2->connections.at("\\Y"); + + int a_width = std::max(a1.width, a2.width); + int b_width = std::max(b1.width, b2.width); + int y_width = std::max(y1.width, y2.width); + + if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y"); + + if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + if (b2.width != b_width) b2 = module->addPos(NEW_ID, b2, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y"); + + RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); + RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); + RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); + + RTLIL::Cell *supercell = new RTLIL::Cell; + supercell->name = NEW_ID; + supercell->type = c1->type; + supercell->parameters["\\A_SIGNED"] = a_signed; + supercell->parameters["\\B_SIGNED"] = b_signed; + supercell->parameters["\\A_WIDTH"] = a_width; + supercell->parameters["\\B_WIDTH"] = b_width; + supercell->parameters["\\Y_WIDTH"] = y_width; + supercell->connections["\\A"] = a; + supercell->connections["\\B"] = b; + supercell->connections["\\Y"] = y; + module->add(supercell); + + RTLIL::SigSpec new_y1(y, y1.width); + RTLIL::SigSpec new_y2(y, y2.width); + + module->connections.push_back(RTLIL::SigSig(y1, new_y1)); + module->connections.push_back(RTLIL::SigSig(y2, new_y2)); + + return supercell; + } + + log_abort(); + } + + // -------------------------------------------------------- // Finding control inputs and activation pattern for a cell // -------------------------------------------------------- @@ -330,6 +399,8 @@ struct ShareWorker optimize_activation_patterns(activation_patterns_cache[cell]); if (activation_patterns_cache[cell].empty()) { log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); + RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; + module->connections.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.width))); cells_to_remove.insert(cell); } @@ -351,6 +422,18 @@ struct ShareWorker return signal; } + RTLIL::SigSpec make_cell_activation_logic(const std::set> &activation_patterns) + { + RTLIL::Wire *all_cases_wire = module->new_wire(0, NEW_ID); + for (auto &p : activation_patterns) { + all_cases_wire->width++; + module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec(all_cases_wire, 1, all_cases_wire->width - 1)); + } + if (all_cases_wire->width == 1) + return all_cases_wire; + return module->ReduceOr(NEW_ID, all_cases_wire); + } + // ------------- // Setup and run @@ -504,8 +587,39 @@ struct ShareWorker } log(" According to the SAT solver this pair of cells can be shared.\n"); - log(" WARNING: Actually sharing the cells is not implemented yet.\n"); shareable_cells.erase(other_cell); + + int cell_select_score = 0; + int other_cell_select_score = 0; + + for (auto &p : cell_activation_patterns) + cell_select_score += p.first.width; + + for (auto &p : other_cell_activation_patterns) + other_cell_select_score += p.first.width; + + RTLIL::Cell *supercell; + if (cell_select_score <= other_cell_select_score) { + RTLIL::SigSpec act = make_cell_activation_logic(cell_activation_patterns); + supercell = make_supercell(cell, other_cell, act); + log(" Activation signal for %s: %s\n", log_id(cell), log_signal(act)); + } else { + RTLIL::SigSpec act = make_cell_activation_logic(other_cell_activation_patterns); + supercell = make_supercell(other_cell, cell, act); + log(" Activation signal for %s: %s\n", log_id(other_cell), log_signal(act)); + } + + log(" New cell: %s (%s)\n", log_id(supercell), log_id(supercell->type)); + + std::set> supercell_activation_patterns; + supercell_activation_patterns.insert(cell_activation_patterns.begin(), cell_activation_patterns.end()); + supercell_activation_patterns.insert(other_cell_activation_patterns.begin(), other_cell_activation_patterns.end()); + optimize_activation_patterns(supercell_activation_patterns); + activation_patterns_cache[supercell] = supercell_activation_patterns; + shareable_cells.insert(supercell); + + cells_to_remove.insert(cell); + cells_to_remove.insert(other_cell); break; } } From 6f450d0224a3ad09c61c5a150e3e7b3b6241338d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 14:55:10 +0200 Subject: [PATCH 324/750] Added tests/share for testing "share" supercell creation --- tests/share/.gitignore | 1 + tests/share/generate.py | 41 +++++++++++++++++++++++++++++++++++++++++ tests/share/run-test.sh | 16 ++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 tests/share/.gitignore create mode 100644 tests/share/generate.py create mode 100755 tests/share/run-test.sh diff --git a/tests/share/.gitignore b/tests/share/.gitignore new file mode 100644 index 00000000..9c595a6f --- /dev/null +++ b/tests/share/.gitignore @@ -0,0 +1 @@ +temp diff --git a/tests/share/generate.py b/tests/share/generate.py new file mode 100644 index 00000000..86be6b5e --- /dev/null +++ b/tests/share/generate.py @@ -0,0 +1,41 @@ +#!/usr/bin/python + +from __future__ import division +from __future__ import print_function + +import sys +import random +from contextlib import contextmanager + +@contextmanager +def redirect_stdout(new_target): + old_target, sys.stdout = sys.stdout, new_target + try: + yield new_target + finally: + sys.stdout = old_target + +for idx in range(100): + with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): + print('module uut_%05d(a, b, c, d, s, y);' % (idx)) + ac_signed = random.choice(['', ' signed']) + bd_signed = random.choice(['', ' signed']) + op = random.choice(['+', '-', '*', '/', '%', '<<', '>>', '<<<', '>>>']) + print(' input%s [%d:0] a;' % (ac_signed, random.randint(0, 8))) + print(' input%s [%d:0] b;' % (bd_signed, random.randint(0, 8))) + print(' input%s [%d:0] c;' % (ac_signed, random.randint(0, 8))) + print(' input%s [%d:0] d;' % (bd_signed, random.randint(0, 8))) + print(' input s;') + print(' output [%d:0] y;' % random.randint(0, 8)) + print(' assign y = s ? %s(a %s b) : %s(c %s d);' % (random.choice(['', '$signed', '$unsigned']), op, random.choice(['', '$signed', '$unsigned']), op)) + print('endmodule') + with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): + print('read_verilog temp/uut_%05d.v' % idx) + print('proc;;') + print('copy uut_%05d gold' % idx) + print('rename uut_%05d gate' % idx) + print('share -aggressive gate') + print('miter -equiv -ignore_gold_x -make_outputs -make_outcmp gold gate miter') + print('flatten miter') + print('sat -verify -prove trigger 0 -show-inputs -show-outputs miter') + diff --git a/tests/share/run-test.sh b/tests/share/run-test.sh new file mode 100755 index 00000000..d511c909 --- /dev/null +++ b/tests/share/run-test.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +rm -rf temp +mkdir -p temp +echo "generating tests.." +python generate.py + +echo "running tests.." +for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do + echo -n "[$i]" + idx=$( printf "%05d" $i ) + ../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys +done +echo + From 2e358bd6678aba687908fe4a359c82aa5dff110d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 13:20:52 +0200 Subject: [PATCH 325/750] Added tests/vloghtb/test_share.sh --- tests/vloghtb/.gitignore | 2 ++ tests/vloghtb/common.sh | 7 +++++++ tests/vloghtb/run-test.sh | 3 ++- tests/vloghtb/test_makefile | 9 +++++++++ tests/vloghtb/test_share.sh | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/vloghtb/common.sh create mode 100644 tests/vloghtb/test_makefile create mode 100644 tests/vloghtb/test_share.sh diff --git a/tests/vloghtb/.gitignore b/tests/vloghtb/.gitignore index da1ffa41..63db2fba 100644 --- a/tests/vloghtb/.gitignore +++ b/tests/vloghtb/.gitignore @@ -5,3 +5,5 @@ scripts spec check_yosys vloghammer_tb.tar.bz2 +temp +log_test_* diff --git a/tests/vloghtb/common.sh b/tests/vloghtb/common.sh new file mode 100644 index 00000000..dc8aec08 --- /dev/null +++ b/tests/vloghtb/common.sh @@ -0,0 +1,7 @@ +log_pass() { + printf "%-15s %s %s %s\n" "$1" "$2" "`printf "%20s" "$2" | tr -d a-zA-Z0-9_ | tr ' ' .`" "pass." +} + +log_fail() { + printf "%-15s %s %s %s\n" "$1" "$2" "`printf "%20s" "$2" | tr -d a-zA-Z0-9_ | tr ' ' .`" "FAIL." +} diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh index 9bef4450..6b3c2651 100755 --- a/tests/vloghtb/run-test.sh +++ b/tests/vloghtb/run-test.sh @@ -7,5 +7,6 @@ wget http://www.clifford.at/yosys/nogit/vloghammer_tb.tar.bz2 tar --strip=1 -xjf vloghammer_tb.tar.bz2 make clean -make -j4 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys +make -j4 EXIT_ON_ERROR=1 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys +make -j4 -f test_makefile MODE=share diff --git a/tests/vloghtb/test_makefile b/tests/vloghtb/test_makefile new file mode 100644 index 00000000..174dbbc2 --- /dev/null +++ b/tests/vloghtb/test_makefile @@ -0,0 +1,9 @@ + +MODE := share +TESTS := $(shell ls rtl/ | sed 's,\.v$$,,' ) + +run: $(addprefix log_test_$(MODE)/,$(addsuffix .txt,$(TESTS))) + +log_test_$(MODE)/%.txt: rtl/%.v + @bash test_$(MODE).sh $< + diff --git a/tests/vloghtb/test_share.sh b/tests/vloghtb/test_share.sh new file mode 100644 index 00000000..52b5a142 --- /dev/null +++ b/tests/vloghtb/test_share.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +set -e +mkdir -p log_test_share +source common.sh + +f=$1 +n=$(basename ${f%.v}) + +rm -f log_test_share/$n.txt +rm -f log_test_share/$n.err + +if ! ../../yosys -q -l log_test_share/$n.out - 2> /dev/null <<- EOT + read_verilog $f + proc;; + + copy $n gold + rename $n work + + cd work + share -aggressive + cd .. + + miter -equiv -ignore_gold_x -make_outputs -make_outcmp gold work miter + flatten miter + sat -verify -prove trigger 0 -show-inputs -show-outputs miter +EOT +then + log_fail test_share $n + mv log_test_share/$n.out log_test_share/$n.err + exit 1 +fi + +log_pass test_share $n +mv log_test_share/$n.out log_test_share/$n.txt +exit 0 + From 8d04ca7d22e375fbe075dee1f189669046ee8906 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:16:10 +0200 Subject: [PATCH 326/750] Added call_on_selection() and call_on_module() API --- kernel/register.cc | 34 ++++++++++++++++++++++++++++++---- kernel/register.h | 7 +++++-- passes/hierarchy/submod.cc | 2 +- passes/techmap/techmap.cc | 10 +--------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/kernel/register.cc b/kernel/register.cc index 8da5a725..84051948 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -198,11 +198,11 @@ void Pass::call(RTLIL::Design *design, std::vector args) design->check(); } -void Pass::call_newsel(RTLIL::Design *design, std::string command) +void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command) { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(RTLIL::Selection()); + design->selection_stack.push_back(selection); Pass::call(design, command); @@ -210,11 +210,37 @@ void Pass::call_newsel(RTLIL::Design *design, std::string command) design->selected_active_module = backup_selected_active_module; } -void Pass::call_newsel(RTLIL::Design *design, std::vector args) +void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::vector args) { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(RTLIL::Selection()); + design->selection_stack.push_back(selection); + + Pass::call(design, args); + + design->selection_stack.pop_back(); + design->selected_active_module = backup_selected_active_module; +} + +void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command) +{ + std::string backup_selected_active_module = design->selected_active_module; + design->selected_active_module = module->name; + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); + + Pass::call(design, command); + + design->selection_stack.pop_back(); + design->selected_active_module = backup_selected_active_module; +} + +void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vector args) +{ + std::string backup_selected_active_module = design->selected_active_module; + design->selected_active_module = module->name; + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); Pass::call(design, args); diff --git a/kernel/register.h b/kernel/register.h index f3d3f70a..b07c4617 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -60,8 +60,11 @@ struct Pass static void call(RTLIL::Design *design, std::string command); static void call(RTLIL::Design *design, std::vector args); - static void call_newsel(RTLIL::Design *design, std::string command); - static void call_newsel(RTLIL::Design *design, std::vector args); + static void call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command); + static void call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::vector args); + + static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command); + static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vector args); static void init_register(); static void done_register(); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 7d081125..55f5f048 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -338,7 +338,7 @@ struct SubmodPass : public Pass { if (module == NULL) log("Nothing selected -> do nothing.\n"); else { - Pass::call_newsel(design, stringf("opt_clean %s", module->name.c_str())); + Pass::call_on_module(design, module, "opt_clean"); log_header("Continuing SUBMOD pass.\n"); SubmodWorker worker(design, module, opt_name); } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index cb36c9e1..3ceff279 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -393,15 +393,7 @@ struct TechmapWorker tpl->add(data.wire); std::string cmd_string = data.value.as_const().decode_string(); - - RTLIL::Selection tpl_mod_sel(false); - std::string backup_active_module = map->selected_active_module; - map->selected_active_module = tpl->name; - tpl_mod_sel.select(tpl); - map->selection_stack.push_back(tpl_mod_sel); - Pass::call(map, cmd_string); - map->selection_stack.pop_back(); - map->selected_active_module = backup_active_module; + Pass::call_on_module(map, tpl, cmd_string); keep_running = true; break; From 4c38ec1cc81c95b79fbd717dafd9f79708c123e8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:23:08 +0200 Subject: [PATCH 327/750] Added "miter -equiv -flatten" --- passes/sat/miter.cc | 14 ++++++++++++++ tests/share/generate.py | 3 +-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 6c8e2ff4..0ef9e9aa 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -27,6 +27,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, bool flag_make_outputs = false; bool flag_make_outcmp = false; bool flag_make_assert = false; + bool flag_flatten = false; log_header("Executing MITER pass (creating miter circuit).\n"); @@ -49,6 +50,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, flag_make_assert = true; continue; } + if (args[argidx] == "-flatten") { + flag_flatten = true; + continue; + } break; } if (argidx+3 != args.size() || args[argidx].substr(0, 1) == "-") @@ -287,6 +292,12 @@ static void create_miter_equiv(struct Pass *that, std::vector args, miter_module->add(not_cell); miter_module->fixup_ports(); + + if (flag_flatten) { + log_push(); + Pass::call_on_module(design, miter_module, "flatten; opt_const -undriven;;"); + log_pop(); + } } struct MiterPass : public Pass { @@ -317,6 +328,9 @@ struct MiterPass : public Pass { log(" -make_assert\n"); log(" also create an 'assert' cell that checks if trigger is always low.\n"); log("\n"); + log(" -flatten\n"); + log(" call 'flatten; opt_const -undriven;;' on the miter circuit.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { diff --git a/tests/share/generate.py b/tests/share/generate.py index 86be6b5e..07821b72 100644 --- a/tests/share/generate.py +++ b/tests/share/generate.py @@ -35,7 +35,6 @@ for idx in range(100): print('copy uut_%05d gold' % idx) print('rename uut_%05d gate' % idx) print('share -aggressive gate') - print('miter -equiv -ignore_gold_x -make_outputs -make_outcmp gold gate miter') - print('flatten miter') + print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') print('sat -verify -prove trigger 0 -show-inputs -show-outputs miter') From dd23e9a9dbe4db96423a797f2383e79093dd62bb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:24:04 +0200 Subject: [PATCH 328/750] Activated tests/share in "make test" --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 6d3d7d7c..6f9daa04 100644 --- a/Makefile +++ b/Makefile @@ -162,6 +162,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) cd tests/hana && bash run-test.sh cd tests/asicworld && bash run-test.sh cd tests/realmath && bash run-test.sh + cd tests/share && bash run-test.sh cd tests/techmap && bash run-test.sh cd tests/memories && bash run-test.sh cd tests/sat && bash run-test.sh From 4af8d84f015edd229328a09c462c8ad81e06892f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 17:05:20 +0200 Subject: [PATCH 329/750] Small fix in tests/vloghtb/run-test.sh --- tests/vloghtb/run-test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh index 6b3c2651..0e01fd64 100755 --- a/tests/vloghtb/run-test.sh +++ b/tests/vloghtb/run-test.sh @@ -8,5 +8,7 @@ tar --strip=1 -xjf vloghammer_tb.tar.bz2 make clean make -j4 EXIT_ON_ERROR=1 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys + +rm -rf log_test_* make -j4 -f test_makefile MODE=share From ff28029fdb4fe97dca0e93b175dd2d6411671cb0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 17:06:36 +0200 Subject: [PATCH 330/750] Fixed creation of shift supercells in "share" pass --- passes/sat/share.cc | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 9ad1d621..27b21207 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -135,7 +135,7 @@ struct ShareWorker continue; // FIXME: Creation of super cells is broken for this cell types - if (cell->type == "$shr" || cell->type == "$mod") + if (cell->type == "$div" || cell->type == "$mod") continue; if (config.opt_force) { @@ -246,6 +246,9 @@ struct ShareWorker log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); log_assert(b_signed == c2->parameters.at("\\B_SIGNED").as_bool()); + if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") + b_signed = false; + RTLIL::SigSpec a1 = c1->connections.at("\\A"); RTLIL::SigSpec b1 = c1->connections.at("\\B"); RTLIL::SigSpec y1 = c1->connections.at("\\Y"); @@ -258,10 +261,23 @@ struct ShareWorker int b_width = std::max(b1.width, b2.width); int y_width = std::max(y1.width, y2.width); - if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); - if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y"); + if (c1->type == "$shr" && a_signed) + { + a_width = std::max(y_width, a_width); - if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + if (a1.width < y1.width) a1 = module->addPos(NEW_ID, a1, module->new_wire(y1.width, NEW_ID), true)->connections.at("\\Y"); + if (a2.width < y2.width) a2 = module->addPos(NEW_ID, a2, module->new_wire(y2.width, NEW_ID), true)->connections.at("\\Y"); + + if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), false)->connections.at("\\Y"); + if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), false)->connections.at("\\Y"); + } + else + { + if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + } + + if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y"); if (b2.width != b_width) b2 = module->addPos(NEW_ID, b2, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); From 7a6d578b81581f5217b717dcd601cfba2d4a4d0f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 17:06:57 +0200 Subject: [PATCH 331/750] Improved tests/share/generate.py --- tests/share/generate.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/share/generate.py b/tests/share/generate.py index 07821b72..fa17080f 100644 --- a/tests/share/generate.py +++ b/tests/share/generate.py @@ -15,9 +15,15 @@ def redirect_stdout(new_target): finally: sys.stdout = old_target +def maybe_plus_e(expr): + if random.randint(0, 4) == 0: + return "(%s + e)" % expr + else: + return expr + for idx in range(100): with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): - print('module uut_%05d(a, b, c, d, s, y);' % (idx)) + print('module uut_%05d(a, b, c, d, e, s, y);' % (idx)) ac_signed = random.choice(['', ' signed']) bd_signed = random.choice(['', ' signed']) op = random.choice(['+', '-', '*', '/', '%', '<<', '>>', '<<<', '>>>']) @@ -25,9 +31,13 @@ for idx in range(100): print(' input%s [%d:0] b;' % (bd_signed, random.randint(0, 8))) print(' input%s [%d:0] c;' % (ac_signed, random.randint(0, 8))) print(' input%s [%d:0] d;' % (bd_signed, random.randint(0, 8))) + print(' input signed [%d:0] e;' % random.randint(0, 8)) print(' input s;') print(' output [%d:0] y;' % random.randint(0, 8)) - print(' assign y = s ? %s(a %s b) : %s(c %s d);' % (random.choice(['', '$signed', '$unsigned']), op, random.choice(['', '$signed', '$unsigned']), op)) + print(' assign y = (s ? %s(%s %s %s) : %s(%s %s %s))%s;' % + (random.choice(['', '$signed', '$unsigned']), maybe_plus_e('a'), op, maybe_plus_e('b'), + random.choice(['', '$signed', '$unsigned']), maybe_plus_e('c'), op, maybe_plus_e('d'), + ' + e' if random.randint(0, 4) == 0 else '')) print('endmodule') with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): print('read_verilog temp/uut_%05d.v' % idx) From e9506bb2da9640cebc325e33a678d352d36a909e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 18:54:06 +0200 Subject: [PATCH 332/750] Supercell creation for $div/$mod worked all along, fixed test benches --- passes/sat/share.cc | 4 ---- tests/share/generate.py | 2 +- tests/vloghtb/test_share.sh | 5 ++--- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 27b21207..06549671 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -134,10 +134,6 @@ struct ShareWorker not_a_muxed_cell: continue; - // FIXME: Creation of super cells is broken for this cell types - if (cell->type == "$div" || cell->type == "$mod") - continue; - if (config.opt_force) { shareable_cells.insert(cell); continue; diff --git a/tests/share/generate.py b/tests/share/generate.py index fa17080f..9e5bef7a 100644 --- a/tests/share/generate.py +++ b/tests/share/generate.py @@ -46,5 +46,5 @@ for idx in range(100): print('rename uut_%05d gate' % idx) print('share -aggressive gate') print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') - print('sat -verify -prove trigger 0 -show-inputs -show-outputs miter') + print('sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter') diff --git a/tests/vloghtb/test_share.sh b/tests/vloghtb/test_share.sh index 52b5a142..88e04281 100644 --- a/tests/vloghtb/test_share.sh +++ b/tests/vloghtb/test_share.sh @@ -21,9 +21,8 @@ if ! ../../yosys -q -l log_test_share/$n.out - 2> /dev/null <<- EOT share -aggressive cd .. - miter -equiv -ignore_gold_x -make_outputs -make_outcmp gold work miter - flatten miter - sat -verify -prove trigger 0 -show-inputs -show-outputs miter + miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold work miter + sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter EOT then log_fail test_share $n From 1ce5e835553a99c3333af00ead1d8f3e40c5538a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 20:15:49 +0200 Subject: [PATCH 333/750] Added "select -assert-count" --- passes/cmds/select.cc | 49 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 38d43f8d..9ef60a28 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -857,6 +857,10 @@ struct SelectPass : public Pass { log(" selection is non-empty. i.e. produce an error if no object matching\n"); log(" the selection is found.\n"); log("\n"); + log(" -assert-count N\n"); + log(" do not modify the current selection. instead assert that the given\n"); + log(" selection contains exactly N objects.\n"); + log("\n"); log(" -list\n"); log(" list all objects in the current selection\n"); log("\n"); @@ -1021,6 +1025,7 @@ struct SelectPass : public Pass { bool got_module = false; bool assert_none = false; bool assert_any = false; + int assert_count = -1; std::string write_file; std::string set_name; std::string sel_str; @@ -1047,6 +1052,10 @@ struct SelectPass : public Pass { assert_any = true; continue; } + if (arg == "-assert-count" && argidx+1 < args.size()) { + assert_count = atoi(args[++argidx].c_str()); + continue; + } if (arg == "-clear") { clear_mode = true; continue; @@ -1091,14 +1100,14 @@ struct SelectPass : public Pass { if (none_mode && args.size() != 2) log_cmd_error("Option -none can not be combined with any other options.\n"); - if (add_mode + del_mode + assert_none + assert_any > 1) - log_cmd_error("Options -add, -del, -assert-none or -assert-any can not be combined.\n"); + if (add_mode + del_mode + assert_none + assert_any + (assert_count >= 0) > 1) + log_cmd_error("Options -add, -del, -assert-none, -assert-any or -assert-count can not be combined.\n"); - if ((list_mode || !write_file.empty() || count_mode) && (add_mode || del_mode || assert_none || assert_any)) - log_cmd_error("Options -list, -write and -count can not be combined with -add, -del, -assert-none or -assert-any.\n"); + if ((list_mode || !write_file.empty() || count_mode) && (add_mode || del_mode || assert_none || assert_any || assert_count >= 0)) + log_cmd_error("Options -list, -write and -count can not be combined with -add, -del, -assert-none, -assert-any or -assert-count.\n"); - if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || del_mode || assert_none || assert_any)) - log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -assert-none or -assert-any.\n"); + if (!set_name.empty() && (list_mode || !write_file.empty() || count_mode || add_mode || del_mode || assert_none || assert_any || assert_count >= 0)) + log_cmd_error("Option -set can not be combined with -list, -write, -count, -add, -del, -assert-none, -assert-any or -assert-count.\n"); if (work_stack.size() == 0 && got_module) { RTLIL::Selection sel; @@ -1201,6 +1210,34 @@ struct SelectPass : public Pass { return; } + if (assert_count >= 0) + { + int total_count = 0; + if (work_stack.size() == 0) + log_cmd_error("No selection to check.\n"); + RTLIL::Selection *sel = &work_stack.back(); + sel->optimize(design); + for (auto mod_it : design->modules) + if (sel->selected_module(mod_it.first)) { + for (auto &it : mod_it.second->wires) + if (sel->selected_member(mod_it.first, it.first)) + total_count++; + for (auto &it : mod_it.second->memories) + if (sel->selected_member(mod_it.first, it.first)) + total_count++; + for (auto &it : mod_it.second->cells) + if (sel->selected_member(mod_it.first, it.first)) + total_count++; + for (auto &it : mod_it.second->processes) + if (sel->selected_member(mod_it.first, it.first)) + total_count++; + } + if (assert_count != total_count) + log_error("Assertation failed: selection contains %d elements instead of the asserted %d:%s\n", + total_count, assert_count, sel_str.c_str()); + return; + } + if (!set_name.empty()) { if (work_stack.size() == 0) From 04fcb07213291f469d208ceca2a32fb8c2fe3215 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 20:44:14 +0200 Subject: [PATCH 334/750] Added support for resource sharing in mux control logic --- passes/sat/share.cc | 235 ++++++++++++++++++++++++++++---------------- 1 file changed, 152 insertions(+), 83 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 06549671..90daefc0 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -42,6 +42,7 @@ struct ShareWorker ModWalker modwalker; std::set cells_to_remove; + std::set recursion_state; // ------------------------------------------------------------------------------ @@ -52,58 +53,36 @@ struct ShareWorker void find_terminal_bits() { - std::set queue_strong_bits, queue_weak_bits; + std::set queue_bits; std::set visited_cells; - queue_weak_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end()); + queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end()); for (auto &it : module->cells) - { - RTLIL::Cell *cell = it.second; - - if (cell->type == "$mux" || cell->type == "$pmux") - { - std::vector bits = modwalker.sigmap(cell->connections.at("\\S")); - queue_strong_bits.insert(bits.begin(), bits.end()); + if (!fwd_ct.cell_known(it.second->type)) { + std::set &bits = modwalker.cell_inputs[it.second]; + queue_bits.insert(bits.begin(), bits.end()); } - else if (!fwd_ct.cell_known(cell->type)) - { - std::set &bits = modwalker.cell_inputs[cell]; - queue_weak_bits.insert(bits.begin(), bits.end()); - } - } - terminal_bits.insert(queue_strong_bits.begin(), queue_strong_bits.end()); - terminal_bits.insert(queue_weak_bits.begin(), queue_weak_bits.end()); + terminal_bits.insert(queue_bits.begin(), queue_bits.end()); - while (!queue_strong_bits.empty()) + while (!queue_bits.empty()) { std::set portbits; - modwalker.get_drivers(portbits, queue_strong_bits); - queue_strong_bits.clear(); - - for (auto &pbit : portbits) - if (fwd_ct.cell_known(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) { - std::set &bits = modwalker.cell_inputs[pbit.cell]; - terminal_bits.insert(bits.begin(), bits.end()); - queue_strong_bits.insert(bits.begin(), bits.end()); - visited_cells.insert(pbit.cell); - } - } - - while (!queue_weak_bits.empty()) - { - std::set portbits; - modwalker.get_drivers(portbits, queue_weak_bits); - queue_weak_bits.clear(); + modwalker.get_drivers(portbits, queue_bits); + queue_bits.clear(); for (auto &pbit : portbits) { - if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") - continue; + if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { + std::set bits = modwalker.sigmap(pbit.cell->connections.at("\\S")).to_sigbit_set(); + terminal_bits.insert(bits.begin(), bits.end()); + queue_bits.insert(bits.begin(), bits.end()); + visited_cells.insert(pbit.cell); + } if (fwd_ct.cell_known(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) { std::set &bits = modwalker.cell_inputs[pbit.cell]; terminal_bits.insert(bits.begin(), bits.end()); - queue_weak_bits.insert(bits.begin(), bits.end()); + queue_bits.insert(bits.begin(), bits.end()); visited_cells.insert(pbit.cell); } } @@ -306,6 +285,48 @@ struct ShareWorker } + // ------------------------------------------- + // Finding forbidden control inputs for a cell + // ------------------------------------------- + + std::map> forbidden_controls_cache; + + const std::set &find_forbidden_controls(RTLIL::Cell *cell) + { + if (recursion_state.count(cell)) { + static std::set empty_controls_set; + return empty_controls_set; + } + + if (forbidden_controls_cache.count(cell)) + return forbidden_controls_cache.at(cell); + + std::set pbits; + std::set consumer_cells; + + modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]); + + for (auto &bit : pbits) { + if ((bit.cell->type == "$mux" || bit.cell->type == "$pmux") && bit.port == "\\S") + forbidden_controls_cache[cell].insert(bit.cell->connections.at("\\S").extract(bit.offset, 1)); + consumer_cells.insert(bit.cell); + } + + recursion_state.insert(cell); + + for (auto c : consumer_cells) + if (fwd_ct.cell_known(c->type)) { + const std::set &bits = find_forbidden_controls(c); + forbidden_controls_cache[cell].insert(bits.begin(), bits.end()); + } + + log_assert(recursion_state.count(cell)); + recursion_state.erase(cell); + + return forbidden_controls_cache[cell]; + } + + // -------------------------------------------------------- // Finding control inputs and activation pattern for a cell // -------------------------------------------------------- @@ -344,11 +365,16 @@ struct ShareWorker const std::set> &find_cell_activation_patterns(RTLIL::Cell *cell, const char *indent) { + if (recursion_state.count(cell)) { + static std::set> empty_patterns_set; + return empty_patterns_set; + } + if (activation_patterns_cache.count(cell)) return activation_patterns_cache.at(cell); const std::set &cell_out_bits = modwalker.cell_outputs[cell]; - std::set driven_cells; + std::set driven_cells, driven_data_muxes; for (auto &bit : cell_out_bits) { @@ -359,55 +385,59 @@ struct ShareWorker } for (auto &pbit : modwalker.signal_consumers[bit]) { log_assert(fwd_ct.cell_known(pbit.cell->type)); - driven_cells.insert(pbit.cell); + if ((pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") && (pbit.port == "\\A" || pbit.port == "\\B")) + driven_data_muxes.insert(pbit.cell); + else + driven_cells.insert(pbit.cell); } } - for (auto c : driven_cells) + recursion_state.insert(cell); + + for (auto c : driven_data_muxes) { const std::set> &c_patterns = find_cell_activation_patterns(c, indent); - if (c->type == "$mux" || c->type == "$pmux") - { - bool used_in_a = false; - std::set used_in_b_parts; + bool used_in_a = false; + std::set used_in_b_parts; - int width = c->parameters.at("\\WIDTH").as_int(); - std::vector sig_a = modwalker.sigmap(c->connections.at("\\A")); - std::vector sig_b = modwalker.sigmap(c->connections.at("\\B")); - std::vector sig_s = modwalker.sigmap(c->connections.at("\\S")); + int width = c->parameters.at("\\WIDTH").as_int(); + std::vector sig_a = modwalker.sigmap(c->connections.at("\\A")); + std::vector sig_b = modwalker.sigmap(c->connections.at("\\B")); + std::vector sig_s = modwalker.sigmap(c->connections.at("\\S")); - for (auto &bit : sig_a) - if (cell_out_bits.count(bit)) - used_in_a = true; + for (auto &bit : sig_a) + if (cell_out_bits.count(bit)) + used_in_a = true; - for (int i = 0; i < SIZE(sig_b); i++) - if (cell_out_bits.count(sig_b[i])) - used_in_b_parts.insert(i / width); + for (int i = 0; i < SIZE(sig_b); i++) + if (cell_out_bits.count(sig_b[i])) + used_in_b_parts.insert(i / width); - if (used_in_a) - for (auto p : c_patterns) { - for (int i = 0; i < SIZE(sig_s); i++) - p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0); - if (sort_check_activation_pattern(p)) - activation_patterns_cache[cell].insert(p); - } + if (used_in_a) + for (auto p : c_patterns) { + for (int i = 0; i < SIZE(sig_s); i++) + p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0); + if (sort_check_activation_pattern(p)) + activation_patterns_cache[cell].insert(p); + } - for (int idx : used_in_b_parts) - for (auto p : c_patterns) { - p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1); - if (sort_check_activation_pattern(p)) - activation_patterns_cache[cell].insert(p); - } - } - else - { - // Not a mux: just copy the activation patterns - for (auto &p : c_patterns) - activation_patterns_cache[cell].insert(p); - } + for (int idx : used_in_b_parts) + for (auto p : c_patterns) { + p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1); + if (sort_check_activation_pattern(p)) + activation_patterns_cache[cell].insert(p); + } } + for (auto c : driven_cells) { + const std::set> &c_patterns = find_cell_activation_patterns(c, indent); + activation_patterns_cache[cell].insert(c_patterns.begin(), c_patterns.end()); + } + + log_assert(recursion_state.count(cell)); + recursion_state.erase(cell); + optimize_activation_patterns(activation_patterns_cache[cell]); if (activation_patterns_cache[cell].empty()) { log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); @@ -434,6 +464,24 @@ struct ShareWorker return signal; } + void filter_activation_patterns(std::set> &out, + const std::set> &in, const std::set &filter_bits) + { + for (auto &p : in) + { + std::vector p_first = p.first; + std::pair new_p; + + for (int i = 0; i < SIZE(p_first); i++) + if (filter_bits.count(p_first[i]) == 0) { + new_p.first.append_bit(p_first[i]); + new_p.second.bits.push_back(p.second.bits.at(i)); + } + + out.insert(new_p); + } + } + RTLIL::SigSpec make_cell_activation_logic(const std::set> &activation_patterns) { RTLIL::Wire *all_cases_wire = module->new_wire(0, NEW_ID); @@ -533,6 +581,25 @@ struct ShareWorker log(" Found %d activation_patterns using ctrl signal %s.\n", SIZE(other_cell_activation_patterns), log_signal(other_cell_activation_signals)); + const std::set &cell_forbidden_controls = find_forbidden_controls(cell); + const std::set &other_cell_forbidden_controls = find_forbidden_controls(other_cell); + + std::set union_forbidden_controls; + union_forbidden_controls.insert(cell_forbidden_controls.begin(), cell_forbidden_controls.end()); + union_forbidden_controls.insert(other_cell_forbidden_controls.begin(), other_cell_forbidden_controls.end()); + + if (!union_forbidden_controls.empty()) + log(" Forbidden control signals for this pair of cells: %s\n", log_signal(union_forbidden_controls)); + + std::set> filtered_cell_activation_patterns; + std::set> filtered_other_cell_activation_patterns; + + filter_activation_patterns(filtered_cell_activation_patterns, cell_activation_patterns, union_forbidden_controls); + filter_activation_patterns(filtered_other_cell_activation_patterns, other_cell_activation_patterns, union_forbidden_controls); + + optimize_activation_patterns(filtered_cell_activation_patterns); + optimize_activation_patterns(filtered_other_cell_activation_patterns); + ezDefaultSAT ez; SatGen satgen(&ez, &modwalker.sigmap); @@ -542,13 +609,13 @@ struct ShareWorker std::vector cell_active, other_cell_active; RTLIL::SigSpec all_ctrl_signals; - for (auto &p : cell_activation_patterns) { + for (auto &p : filtered_cell_activation_patterns) { log(" Activation pattern for cell %s: %s = %s\n", log_id(cell), log_signal(p.first), log_signal(p.second)); cell_active.push_back(ez.vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second))); all_ctrl_signals.append(p.first); } - for (auto &p : other_cell_activation_patterns) { + for (auto &p : filtered_other_cell_activation_patterns) { log(" Activation pattern for cell %s: %s = %s\n", log_id(other_cell), log_signal(p.first), log_signal(p.second)); other_cell_active.push_back(ez.vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second))); all_ctrl_signals.append(p.first); @@ -604,19 +671,19 @@ struct ShareWorker int cell_select_score = 0; int other_cell_select_score = 0; - for (auto &p : cell_activation_patterns) + for (auto &p : filtered_cell_activation_patterns) cell_select_score += p.first.width; - for (auto &p : other_cell_activation_patterns) + for (auto &p : filtered_other_cell_activation_patterns) other_cell_select_score += p.first.width; RTLIL::Cell *supercell; if (cell_select_score <= other_cell_select_score) { - RTLIL::SigSpec act = make_cell_activation_logic(cell_activation_patterns); + RTLIL::SigSpec act = make_cell_activation_logic(filtered_cell_activation_patterns); supercell = make_supercell(cell, other_cell, act); log(" Activation signal for %s: %s\n", log_id(cell), log_signal(act)); } else { - RTLIL::SigSpec act = make_cell_activation_logic(other_cell_activation_patterns); + RTLIL::SigSpec act = make_cell_activation_logic(filtered_other_cell_activation_patterns); supercell = make_supercell(other_cell, cell, act); log(" Activation signal for %s: %s\n", log_id(other_cell), log_signal(act)); } @@ -624,8 +691,8 @@ struct ShareWorker log(" New cell: %s (%s)\n", log_id(supercell), log_id(supercell->type)); std::set> supercell_activation_patterns; - supercell_activation_patterns.insert(cell_activation_patterns.begin(), cell_activation_patterns.end()); - supercell_activation_patterns.insert(other_cell_activation_patterns.begin(), other_cell_activation_patterns.end()); + supercell_activation_patterns.insert(filtered_cell_activation_patterns.begin(), filtered_cell_activation_patterns.end()); + supercell_activation_patterns.insert(filtered_other_cell_activation_patterns.begin(), filtered_other_cell_activation_patterns.end()); optimize_activation_patterns(supercell_activation_patterns); activation_patterns_cache[supercell] = supercell_activation_patterns; shareable_cells.insert(supercell); @@ -644,6 +711,8 @@ struct ShareWorker delete c; } } + + log_assert(recursion_state.empty()); } }; From 8836943693dcd6fc6e6b74141ca8c89e9b8c1f0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 20:45:01 +0200 Subject: [PATCH 335/750] Added yet another resource sharing test case --- tests/sat/share.v | 32 ++++++++++++++++++++++++++++++++ tests/sat/share.ys | 17 +++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/sat/share.v create mode 100644 tests/sat/share.ys diff --git a/tests/sat/share.v b/tests/sat/share.v new file mode 100644 index 00000000..e06fc8f1 --- /dev/null +++ b/tests/sat/share.v @@ -0,0 +1,32 @@ +module test_1( + input [7:0] a, b, c, + input s, x, + output [7:0] y1, y2 +); + wire [7:0] t1, t2; + assign t1 = s ? a*b : 0, t2 = !s ? b*c : 0; + assign y1 = x ? t2 : t1, y2 = x ? t1 : t2; +endmodule + + +module test_2( + input s, + input [7:0] a, b, c, + output reg [7:0] y +); + always @* begin + y <= 'bx; + if (s) begin + if (a * b > 8) + y <= b / c; + else + y <= c / b; + end else begin + if (b * c > 8) + y <= a / b; + else + y <= b / a; + end + end +endmodule + diff --git a/tests/sat/share.ys b/tests/sat/share.ys new file mode 100644 index 00000000..f2f5d649 --- /dev/null +++ b/tests/sat/share.ys @@ -0,0 +1,17 @@ +read_verilog share.v +proc;; + +copy test_1 gold_1 +copy test_2 gold_2 +share test_1 test_2;; + +select -assert-count 1 test_1/t:$mul +select -assert-count 1 test_2/t:$mul +select -assert-count 1 test_2/t:$div + +miter -equiv -flatten -make_outputs -make_outcmp gold_1 test_1 miter_1 +sat -verify -prove trigger 0 -show-inputs -show-outputs miter_1 + +miter -equiv -flatten -make_outputs -make_outcmp gold_2 test_2 miter_2 +sat -verify -prove trigger 0 -show-inputs -show-outputs miter_2 + From c6b3f4e0896a4447bad94d816c8677d01cea1e75 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:00:39 +0200 Subject: [PATCH 336/750] Using relative path names in minisat headers --- libs/minisat/UPDATE.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/minisat/UPDATE.sh b/libs/minisat/UPDATE.sh index 68c7c60e..fa72ba21 100644 --- a/libs/minisat/UPDATE.sh +++ b/libs/minisat/UPDATE.sh @@ -6,7 +6,7 @@ rm minisat_upstream/minisat/*/Main.cc mv minisat_upstream/LICENSE minisat_upstream/minisat/*/*.{h,cc} . rm -rf minisat_upstream -sed -i -e 's,^#include *"minisat/[^/]\+,#include "libs/minisat,' *.cc *.h +sed -i -e 's,^#include *"minisat/[^/]\+/\?,#include ",' *.cc *.h sed -i -e 's/Minisat::memUsedPeak()/Minisat::memUsedPeak(bool)/' System.cc sed -i -e 's/PRI[iu]64/ & /' Options.h Solver.cc sed -i -e '1 i #define __STDC_LIMIT_MACROS' *.cc From 92c9403249ba59e5f57b2adb8b8b0141c2c63f26 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:01:26 +0200 Subject: [PATCH 337/750] Updated minisat --- libs/minisat/Alg.h | 2 +- libs/minisat/Alloc.h | 4 ++-- libs/minisat/Dimacs.h | 4 ++-- libs/minisat/Heap.h | 4 ++-- libs/minisat/IntMap.h | 2 +- libs/minisat/Map.h | 4 ++-- libs/minisat/Options.cc | 6 +++--- libs/minisat/Options.h | 6 +++--- libs/minisat/ParseUtils.h | 2 +- libs/minisat/Queue.h | 2 +- libs/minisat/Rnd.h | 2 +- libs/minisat/SimpSolver.cc | 6 +++--- libs/minisat/SimpSolver.h | 4 ++-- libs/minisat/Solver.cc | 8 ++++---- libs/minisat/Solver.h | 12 ++++++------ libs/minisat/SolverTypes.h | 12 ++++++------ libs/minisat/Sort.h | 2 +- libs/minisat/System.cc | 2 +- libs/minisat/System.h | 2 +- libs/minisat/Vec.h | 4 ++-- 20 files changed, 45 insertions(+), 45 deletions(-) diff --git a/libs/minisat/Alg.h b/libs/minisat/Alg.h index 7f7eac61..ddb972e7 100644 --- a/libs/minisat/Alg.h +++ b/libs/minisat/Alg.h @@ -21,7 +21,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Alg_h #define Minisat_Alg_h -#include "libs/minisat/Vec.h" +#include "Vec.h" namespace Minisat { diff --git a/libs/minisat/Alloc.h b/libs/minisat/Alloc.h index 0de4f07c..6591dcd5 100644 --- a/libs/minisat/Alloc.h +++ b/libs/minisat/Alloc.h @@ -21,8 +21,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Alloc_h #define Minisat_Alloc_h -#include "libs/minisat/XAlloc.h" -#include "libs/minisat/Vec.h" +#include "XAlloc.h" +#include "Vec.h" namespace Minisat { diff --git a/libs/minisat/Dimacs.h b/libs/minisat/Dimacs.h index 383e894b..ccfa1c01 100644 --- a/libs/minisat/Dimacs.h +++ b/libs/minisat/Dimacs.h @@ -23,8 +23,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include -#include "libs/minisat/ParseUtils.h" -#include "libs/minisat/SolverTypes.h" +#include "ParseUtils.h" +#include "SolverTypes.h" namespace Minisat { diff --git a/libs/minisat/Heap.h b/libs/minisat/Heap.h index a7512462..057a3cdf 100644 --- a/libs/minisat/Heap.h +++ b/libs/minisat/Heap.h @@ -21,8 +21,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Heap_h #define Minisat_Heap_h -#include "libs/minisat/Vec.h" -#include "libs/minisat/IntMap.h" +#include "Vec.h" +#include "IntMap.h" namespace Minisat { diff --git a/libs/minisat/IntMap.h b/libs/minisat/IntMap.h index 61dd0f67..9a66315d 100644 --- a/libs/minisat/IntMap.h +++ b/libs/minisat/IntMap.h @@ -19,7 +19,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_IntMap_h #define Minisat_IntMap_h -#include "libs/minisat/Vec.h" +#include "Vec.h" namespace Minisat { diff --git a/libs/minisat/Map.h b/libs/minisat/Map.h index 93b6da31..a6f83200 100644 --- a/libs/minisat/Map.h +++ b/libs/minisat/Map.h @@ -20,8 +20,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Map_h #define Minisat_Map_h -#include "libs/minisat/IntTypes.h" -#include "libs/minisat/Vec.h" +#include "IntTypes.h" +#include "Vec.h" namespace Minisat { diff --git a/libs/minisat/Options.cc b/libs/minisat/Options.cc index b1b3e31b..1aff3fab 100644 --- a/libs/minisat/Options.cc +++ b/libs/minisat/Options.cc @@ -19,9 +19,9 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#include "libs/minisat/Sort.h" -#include "libs/minisat/Options.h" -#include "libs/minisat/ParseUtils.h" +#include "Sort.h" +#include "Options.h" +#include "ParseUtils.h" using namespace Minisat; diff --git a/libs/minisat/Options.h b/libs/minisat/Options.h index 7d140a1f..d602769c 100644 --- a/libs/minisat/Options.h +++ b/libs/minisat/Options.h @@ -25,9 +25,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include #include -#include "libs/minisat/IntTypes.h" -#include "libs/minisat/Vec.h" -#include "libs/minisat/ParseUtils.h" +#include "IntTypes.h" +#include "Vec.h" +#include "ParseUtils.h" namespace Minisat { diff --git a/libs/minisat/ParseUtils.h b/libs/minisat/ParseUtils.h index 7b2ddc55..1c9e7bf7 100644 --- a/libs/minisat/ParseUtils.h +++ b/libs/minisat/ParseUtils.h @@ -26,7 +26,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include -#include "libs/minisat/XAlloc.h" +#include "XAlloc.h" namespace Minisat { diff --git a/libs/minisat/Queue.h b/libs/minisat/Queue.h index 1cae4f5a..5ba50cd2 100644 --- a/libs/minisat/Queue.h +++ b/libs/minisat/Queue.h @@ -21,7 +21,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Queue_h #define Minisat_Queue_h -#include "libs/minisat/Vec.h" +#include "Vec.h" namespace Minisat { diff --git a/libs/minisat/Rnd.h b/libs/minisat/Rnd.h index cf706101..ccb94c6c 100644 --- a/libs/minisat/Rnd.h +++ b/libs/minisat/Rnd.h @@ -19,7 +19,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Rnd_h #define Minisat_Rnd_h -#include "libs/minisat/Vec.h" +#include "Vec.h" namespace Minisat { diff --git a/libs/minisat/SimpSolver.cc b/libs/minisat/SimpSolver.cc index 23236810..fd5774e0 100644 --- a/libs/minisat/SimpSolver.cc +++ b/libs/minisat/SimpSolver.cc @@ -20,9 +20,9 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#include "libs/minisat/Sort.h" -#include "libs/minisat/SimpSolver.h" -#include "libs/minisat/System.h" +#include "Sort.h" +#include "SimpSolver.h" +#include "System.h" using namespace Minisat; diff --git a/libs/minisat/SimpSolver.h b/libs/minisat/SimpSolver.h index fc9bb439..76d5aca1 100644 --- a/libs/minisat/SimpSolver.h +++ b/libs/minisat/SimpSolver.h @@ -21,8 +21,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_SimpSolver_h #define Minisat_SimpSolver_h -#include "libs/minisat/Queue.h" -#include "libs/minisat/Solver.h" +#include "Queue.h" +#include "Solver.h" namespace Minisat { diff --git a/libs/minisat/Solver.cc b/libs/minisat/Solver.cc index 14aa3935..ab476853 100644 --- a/libs/minisat/Solver.cc +++ b/libs/minisat/Solver.cc @@ -22,10 +22,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include -#include "libs/minisat/Alg.h" -#include "libs/minisat/Sort.h" -#include "libs/minisat/System.h" -#include "libs/minisat/Solver.h" +#include "Alg.h" +#include "Sort.h" +#include "System.h" +#include "Solver.h" using namespace Minisat; diff --git a/libs/minisat/Solver.h b/libs/minisat/Solver.h index 73fc7d4c..62a12f3c 100644 --- a/libs/minisat/Solver.h +++ b/libs/minisat/Solver.h @@ -21,12 +21,12 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Solver_h #define Minisat_Solver_h -#include "libs/minisat/Vec.h" -#include "libs/minisat/Heap.h" -#include "libs/minisat/Alg.h" -#include "libs/minisat/IntMap.h" -#include "libs/minisat/Options.h" -#include "libs/minisat/SolverTypes.h" +#include "Vec.h" +#include "Heap.h" +#include "Alg.h" +#include "IntMap.h" +#include "Options.h" +#include "SolverTypes.h" namespace Minisat { diff --git a/libs/minisat/SolverTypes.h b/libs/minisat/SolverTypes.h index a47c2ce8..a7df5785 100644 --- a/libs/minisat/SolverTypes.h +++ b/libs/minisat/SolverTypes.h @@ -24,12 +24,12 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include -#include "libs/minisat/IntTypes.h" -#include "libs/minisat/Alg.h" -#include "libs/minisat/Vec.h" -#include "libs/minisat/IntMap.h" -#include "libs/minisat/Map.h" -#include "libs/minisat/Alloc.h" +#include "IntTypes.h" +#include "Alg.h" +#include "Vec.h" +#include "IntMap.h" +#include "Map.h" +#include "Alloc.h" namespace Minisat { diff --git a/libs/minisat/Sort.h b/libs/minisat/Sort.h index 4a25a9b4..cc96486d 100644 --- a/libs/minisat/Sort.h +++ b/libs/minisat/Sort.h @@ -21,7 +21,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #ifndef Minisat_Sort_h #define Minisat_Sort_h -#include "libs/minisat/Vec.h" +#include "Vec.h" //================================================================================================= // Some sorting algorithms for vec's diff --git a/libs/minisat/System.cc b/libs/minisat/System.cc index df4155af..febe3b40 100644 --- a/libs/minisat/System.cc +++ b/libs/minisat/System.cc @@ -23,7 +23,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include #include -#include "libs/minisat/System.h" +#include "System.h" #if defined(__linux__) diff --git a/libs/minisat/System.h b/libs/minisat/System.h index eb8a7e4d..ee92a6e0 100644 --- a/libs/minisat/System.h +++ b/libs/minisat/System.h @@ -25,7 +25,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include #endif -#include "libs/minisat/IntTypes.h" +#include "IntTypes.h" //------------------------------------------------------------------------------------------------- diff --git a/libs/minisat/Vec.h b/libs/minisat/Vec.h index 2086e0bb..6e398801 100644 --- a/libs/minisat/Vec.h +++ b/libs/minisat/Vec.h @@ -25,8 +25,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include #include -#include "libs/minisat/IntTypes.h" -#include "libs/minisat/XAlloc.h" +#include "IntTypes.h" +#include "XAlloc.h" namespace Minisat { From ade659e617922171ad1b678a51765ba2046c27d8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:03:01 +0200 Subject: [PATCH 338/750] Fixed ezSAT stand-alone build --- libs/ezsat/Makefile | 3 ++- libs/ezsat/ezminisat.cc | 9 ++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/libs/ezsat/Makefile b/libs/ezsat/Makefile index e831cc6f..1dcb5d15 100644 --- a/libs/ezsat/Makefile +++ b/libs/ezsat/Makefile @@ -3,7 +3,8 @@ CC = clang CXX = clang CXXFLAGS = -MD -Wall -Wextra -ggdb CXXFLAGS += -std=c++11 -O0 -LDLIBS = -lminisat -lm -lstdc++ +LDLIBS = ../minisat/Options.cc ../minisat/SimpSolver.cc ../minisat/Solver.cc ../minisat/System.cc -lm -lstdc++ + all: demo_vec demo_bit demo_cmp testbench puzzle3d diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index caee73f8..6a6c075f 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -28,13 +28,8 @@ #include #include -#ifdef _YOSYS_ -# include "libs/minisat/Solver.h" -# include "libs/minisat/SimpSolver.h" -#else -# include -# include -#endif +#include "../minisat/Solver.h" +#include "../minisat/SimpSolver.h" ezMiniSAT::ezMiniSAT() : minisatSolver(NULL) { From b1d520949bdb5357f31f43d9dc4f4579dda9f269 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:49:59 +0200 Subject: [PATCH 339/750] Added ezSAT::keep_cnf() and ezSAT::non_incremental() --- libs/ezsat/Makefile | 3 ++- libs/ezsat/ezminisat.cc | 5 ++++- libs/ezsat/ezsat.cc | 46 ++++++++++++++++++++++++++++++++++++----- libs/ezsat/ezsat.h | 19 ++++++++++++++++- libs/ezsat/testbench.cc | 6 ++++++ 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/libs/ezsat/Makefile b/libs/ezsat/Makefile index 1dcb5d15..b1f86416 100644 --- a/libs/ezsat/Makefile +++ b/libs/ezsat/Makefile @@ -18,7 +18,8 @@ test: all ./testbench ./demo_bit ./demo_vec - ./demo_cmp + # ./demo_cmp + # ./puzzle3d clean: rm -f demo_bit demo_vec demo_cmp testbench puzzle3d *.o *.d diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 6a6c075f..3f43f3ec 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -63,7 +63,8 @@ void ezMiniSAT::clear() #if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL void ezMiniSAT::freeze(int id) { - cnfFrozenVars.insert(bind(id)); + if (!mode_non_incremental()) + cnfFrozenVars.insert(bind(id)); } bool ezMiniSAT::eliminated(int idx) @@ -89,6 +90,8 @@ void ezMiniSAT::alarmHandler(int) bool ezMiniSAT::solver(const std::vector &modelExpressions, std::vector &modelValues, const std::vector &assumptions) { + preSolverCallback(); + solverTimoutStatus = false; if (0) { diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 6da363fc..4c0b624b 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -30,6 +30,11 @@ const int ezSAT::FALSE = 2; ezSAT::ezSAT() { + flag_keep_cnf = false; + flag_non_incremental = false; + + non_incremental_solve_used_up = false; + cnfConsumed = false; cnfVariableCount = 0; cnfClausesCount = 0; @@ -588,19 +593,40 @@ int ezSAT::bind(int id, bool auto_freeze) void ezSAT::consumeCnf() { - cnfConsumed = true; + if (mode_keep_cnf()) + cnfClausesBackup.insert(cnfClausesBackup.end(), cnfClauses.begin(), cnfClauses.end()); + else + cnfConsumed = true; cnfClauses.clear(); } void ezSAT::consumeCnf(std::vector> &cnf) { - cnfConsumed = true; + if (mode_keep_cnf()) + cnfClausesBackup.insert(cnfClausesBackup.end(), cnfClauses.begin(), cnfClauses.end()); + else + cnfConsumed = true; cnf.swap(cnfClauses); cnfClauses.clear(); } +void ezSAT::getFullCnf(std::vector> &full_cnf) const +{ + assert(full_cnf.empty()); + full_cnf.insert(full_cnf.end(), cnfClausesBackup.begin(), cnfClausesBackup.end()); + full_cnf.insert(full_cnf.end(), cnfClauses.begin(), cnfClauses.end()); +} + +void ezSAT::preSolverCallback() +{ + assert(!non_incremental_solve_used_up); + if (mode_non_incremental()) + non_incremental_solve_used_up = true; +} + bool ezSAT::solver(const std::vector&, std::vector&, const std::vector&) { + preSolverCallback(); fprintf(stderr, "************************************************************************\n"); fprintf(stderr, "ERROR: You are trying to use the solve() method of the ezSAT base class!\n"); fprintf(stderr, "Use a dervied class like ezMiniSAT instead.\n"); @@ -1081,16 +1107,26 @@ void ezSAT::printDIMACS(FILE *f, bool verbose) const if (cnfExpressionVariables[i] != 0) fprintf(f, "c %*d: %s\n", digits, cnfExpressionVariables[i], to_string(-i-1).c_str()); + if (mode_keep_cnf()) { + fprintf(f, "c\n"); + fprintf(f, "c %d clauses from backup, %d from current buffer\n", + int(cnfClausesBackup.size()), int(cnfClauses.size())); + } + fprintf(f, "c\n"); } - fprintf(f, "p cnf %d %d\n", cnfVariableCount, int(cnfClauses.size())); + std::vector> all_clauses; + getFullCnf(all_clauses); + assert(cnfClausesCount == int(all_clauses.size())); + + fprintf(f, "p cnf %d %d\n", cnfVariableCount, cnfClausesCount); int maxClauseLen = 0; - for (auto &clause : cnfClauses) + for (auto &clause : all_clauses) maxClauseLen = std::max(int(clause.size()), maxClauseLen); if (!verbose) maxClauseLen = std::min(maxClauseLen, 3); - for (auto &clause : cnfClauses) { + for (auto &clause : all_clauses) { for (auto idx : clause) fprintf(f, " %*d", digits, idx); if (maxClauseLen >= int(clause.size())) diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 85240556..83e1b23c 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -48,6 +48,11 @@ public: static const int FALSE; private: + bool flag_keep_cnf; + bool flag_non_incremental; + + bool non_incremental_solve_used_up; + std::map literalsCache; std::vector literals; @@ -57,7 +62,7 @@ private: bool cnfConsumed; int cnfVariableCount, cnfClausesCount; std::vector cnfLiteralVariables, cnfExpressionVariables; - std::vector> cnfClauses; + std::vector> cnfClauses, cnfClausesBackup; void add_clause(const std::vector &args); void add_clause(const std::vector &args, bool argsPolarity, int a = 0, int b = 0, int c = 0); @@ -67,6 +72,9 @@ private: int bind_cnf_and(const std::vector &args); int bind_cnf_or(const std::vector &args); +protected: + void preSolverCallback(); + public: int solverTimeout; bool solverTimoutStatus; @@ -74,6 +82,12 @@ public: ezSAT(); virtual ~ezSAT(); + void keep_cnf() { flag_keep_cnf = true; } + void non_incremental() { flag_non_incremental = true; } + + bool mode_keep_cnf() const { return flag_keep_cnf; } + bool mode_non_incremental() const { return flag_non_incremental; } + // manage expressions int value(bool val); @@ -155,6 +169,9 @@ public: void consumeCnf(); void consumeCnf(std::vector> &cnf); + // use this function to get the full CNF in keep_cnf mode + void getFullCnf(std::vector> &full_cnf) const; + std::string cnfLiteralInfo(int idx) const; // simple helpers for build expressions easily diff --git a/libs/ezsat/testbench.cc b/libs/ezsat/testbench.cc index 8332ad91..d20258c3 100644 --- a/libs/ezsat/testbench.cc +++ b/libs/ezsat/testbench.cc @@ -64,6 +64,7 @@ void test_simple() printf("==== %s ====\n\n", __PRETTY_FUNCTION__); ezMiniSAT sat; + sat.non_incremental(); sat.assume(sat.OR("A", "B")); sat.assume(sat.NOT(sat.AND("A", "B"))); test(sat); @@ -121,6 +122,8 @@ void test_xorshift32() printf("==== %s ====\n\n", __PRETTY_FUNCTION__); ezMiniSAT sat; + sat.keep_cnf(); + xorshift128 rng; std::vector bits = sat.vec_var("i", 32); @@ -137,6 +140,9 @@ void test_xorshift32() test_xorshift32_try(sat, rng()); test_xorshift32_try(sat, rng()); test_xorshift32_try(sat, rng()); + + sat.printDIMACS(stdout, true); + printf("\n"); } // ------------------------------------------------------------------------------------------------------------ From b49beab1f30d0a7567c2917a3387fa52c84350fd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 02:08:38 +0200 Subject: [PATCH 340/750] Use ezSAT::non_incremental() in "share" pass --- passes/sat/share.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 90daefc0..8ef3396e 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -601,6 +601,8 @@ struct ShareWorker optimize_activation_patterns(filtered_other_cell_activation_patterns); ezDefaultSAT ez; + ez.non_incremental(); + SatGen satgen(&ez, &modwalker.sigmap); std::set sat_cells; From caae6e19dffde4d76b30af3fd1f9751f4ec37fdc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:01:45 +0200 Subject: [PATCH 341/750] Added log_ping() --- kernel/log.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/log.h b/kernel/log.h index f6dcc0ac..00265dbe 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -61,6 +61,7 @@ void log_cell(RTLIL::Cell *cell, std::string indent = ""); #define log_abort() log_error("Abort in %s:%d.\n", __FILE__, __LINE__) #define log_assert(_assert_expr_) do { if (_assert_expr_) break; log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) +#define log_ping() log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) // simple timer for performance measurements // toggle the '#if 1' to get a baseline for the perormance penalty added by the measurement From 54b0f2e659ac0c34c69b0c251c72b2a90fe8e6b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:02:55 +0200 Subject: [PATCH 342/750] Added module->remove(), module->addWire(), module->addCell(), cell->check() --- kernel/rtlil.cc | 47 +++++++++++++++++++++++++++++++++++++++-------- kernel/rtlil.h | 5 +++++ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 748deae3..b16b62ca 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -316,9 +316,9 @@ namespace { fputc(0, f); fclose(f); - log_error("Found error in internal cell %s.%s (%s) at %s:%d:\n%s", - module->name.c_str(), cell->name.c_str(), cell->type.c_str(), - __FILE__, linenr, ptr); + log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s", + module ? module->name.c_str() : "", module ? "." : "", + cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, ptr); } int param(const char *name) @@ -395,6 +395,10 @@ namespace { void check() { + if (cell->type[0] != '$' || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || + cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:") + return; + if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") { param_bool("\\A_SIGNED"); port("\\A", param("\\A_WIDTH")); @@ -740,11 +744,8 @@ void RTLIL::Module::check() for (auto &it2 : it.second->parameters) { assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); } - if (it.second->type[0] == '$' && it.second->type.substr(0, 3) != "$__" && it.second->type.substr(0, 8) != "$paramod" && - it.second->type.substr(0, 9) != "$verific$" && it.second->type.substr(0, 7) != "$array:") { - InternalCellChecker checker(this, it.second); - checker.check(); - } + InternalCellChecker checker(this, it.second); + checker.check(); } for (auto &it : processes) { @@ -841,6 +842,13 @@ void RTLIL::Module::add(RTLIL::Cell *cell) cells[cell->name] = cell; } +void RTLIL::Module::remove(RTLIL::Cell *cell) +{ + assert(cells.count(cell->name) != 0); + cells.erase(cell->name); + delete cell; +} + static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) { if (a->port_id && !b->port_id) @@ -868,6 +876,23 @@ void RTLIL::Module::fixup_ports() all_ports[i]->port_id = i+1; } +RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width) +{ + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = name; + wire->width = width; + add(wire); + return wire; +} + +RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = name; + cell->type = type; + add(cell); + return cell; +} #define DEF_METHOD(_func, _y_size, _type) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \ @@ -1285,6 +1310,12 @@ void RTLIL::Cell::optimize() it.second.optimize(); } +void RTLIL::Cell::check() +{ + InternalCellChecker checker(NULL, this); + checker.check(); +} + RTLIL::SigChunk::SigChunk() { wire = NULL; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 64136de0..19666481 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -290,12 +290,16 @@ struct RTLIL::Module { RTLIL::Wire *new_wire(int width, RTLIL::IdString name); void add(RTLIL::Wire *wire); void add(RTLIL::Cell *cell); + void remove(RTLIL::Cell *cell); void fixup_ports(); template void rewrite_sigspecs(T functor); void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; + RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); + RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); + // The add* methods create a cell and return the created cell. All signals must exist in advance. RTLIL::Cell* addNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); @@ -449,6 +453,7 @@ struct RTLIL::Cell { std::map parameters; RTLIL_ATTRIBUTE_MEMBERS void optimize(); + void check(); template void rewrite_sigspecs(T functor); }; From c54d1f2ad1a781363f9c35e4f7266f4560a6aba8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:03:41 +0200 Subject: [PATCH 343/750] Bugfix in satgen for cells with wider in- than outputs. --- kernel/satgen.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index 81d02929..281d2b26 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -166,7 +166,15 @@ struct SatGen void undefGating(std::vector &vec_y, std::vector &vec_yy, std::vector &vec_undef) { assert(model_undef); - ez->assume(ez->expression(ezSAT::OpAnd, ez->vec_or(vec_undef, ez->vec_iff(vec_y, vec_yy)))); + assert(vec_y.size() == vec_yy.size()); + if (vec_y.size() > vec_undef.size()) { + std::vector trunc_y(vec_y.begin(), vec_y.begin() + vec_undef.size()); + std::vector trunc_yy(vec_yy.begin(), vec_yy.begin() + vec_undef.size()); + ez->assume(ez->expression(ezSAT::OpAnd, ez->vec_or(vec_undef, ez->vec_iff(trunc_y, trunc_yy)))); + } else { + assert(vec_y.size() == vec_undef.size()); + ez->assume(ez->expression(ezSAT::OpAnd, ez->vec_or(vec_undef, ez->vec_iff(vec_y, vec_yy)))); + } } bool importCell(RTLIL::Cell *cell, int timestep = -1) From 3cb61d03f8722fddfa14877accae1b3ca51e3926 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:04:56 +0200 Subject: [PATCH 344/750] Wider range of cell types supported in "share" pass --- passes/sat/share.cc | 214 ++++++++++++++++++++++++++++++++++++---- tests/share/generate.py | 60 +++++++---- tests/share/run-test.sh | 11 +++ 3 files changed, 249 insertions(+), 36 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 8ef3396e..852d8078 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -30,11 +30,14 @@ struct ShareWorkerConfig bool opt_force; bool opt_aggressive; bool opt_fast; + std::set generic_uni_ops, generic_bin_ops, generic_cbin_ops; }; struct ShareWorker { ShareWorkerConfig config; + std::set generic_ops; + RTLIL::Design *design; RTLIL::Module *module; @@ -125,19 +128,19 @@ struct ShareWorker } if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { - if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 4) + if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 4) shareable_cells.insert(cell); continue; } if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { - if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 8) + if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 8) shareable_cells.insert(cell); continue; } - if (cell->type == "$add" || cell->type == "$sub") { - if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 10) + if (generic_ops.count(cell->type)) { + if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 10) shareable_cells.insert(cell); continue; } @@ -157,15 +160,25 @@ struct ShareWorker return true; } - if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || c1->type == "$add" || c1->type == "$sub" || - c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") + if (config.generic_uni_ops.count(c1->type)) { - if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) - return false; + if (!config.opt_aggressive) + { + int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); + int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); - if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) - return false; + int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); + int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); + if (std::max(a1_width, a2_width) > 2 * std::min(a1_width, a2_width)) return false; + if (std::max(y1_width, y2_width) > 2 * std::min(y1_width, y2_width)) return false; + } + + return true; + } + + if (config.generic_bin_ops.count(c1->type)) + { if (!config.opt_aggressive) { int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); @@ -184,6 +197,32 @@ struct ShareWorker return true; } + if (config.generic_cbin_ops.count(c1->type)) + { + if (!config.opt_aggressive) + { + int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); + int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); + int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); + + int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); + int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); + int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); + + int min1_width = std::min(a1_width, b1_width); + int max1_width = std::max(a1_width, b1_width); + + int min2_width = std::min(a2_width, b2_width); + int max2_width = std::max(a2_width, b2_width); + + if (std::max(min1_width, min2_width) > 2 * std::min(min1_width, min2_width)) return false; + if (std::max(max1_width, max2_width) > 2 * std::min(max1_width, max2_width)) return false; + if (std::max(y1_width, y2_width) > 2 * std::min(y1_width, y2_width)) return false; + } + + return true; + } + for (auto &it : c1->parameters) if (c2->parameters.count(it.first) == 0 || c2->parameters.at(it.first) != it.second) return false; @@ -210,10 +249,106 @@ struct ShareWorker RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act) { - if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || c1->type == "$add" || c1->type == "$sub" || - c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") + log_assert(c1->type == c2->type); + + if (config.generic_uni_ops.count(c1->type)) { - log_assert(c1->type == c2->type); + if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) + { + RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; + if (unsigned_cell->connections.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; + unsigned_cell->connections.at("\\A").append_bit(RTLIL::State::S0); + } + unsigned_cell->parameters.at("\\A_SIGNED") = true; + unsigned_cell->check(); + } + + bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); + log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); + + RTLIL::SigSpec a1 = c1->connections.at("\\A"); + RTLIL::SigSpec y1 = c1->connections.at("\\Y"); + + RTLIL::SigSpec a2 = c2->connections.at("\\A"); + RTLIL::SigSpec y2 = c2->connections.at("\\Y"); + + int a_width = std::max(a1.width, a2.width); + int y_width = std::max(y1.width, y2.width); + + if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + + RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); + RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); + + RTLIL::Cell *supercell = new RTLIL::Cell; + supercell->name = NEW_ID; + supercell->type = c1->type; + supercell->parameters["\\A_SIGNED"] = a_signed; + supercell->parameters["\\A_WIDTH"] = a_width; + supercell->parameters["\\Y_WIDTH"] = y_width; + supercell->connections["\\A"] = a; + supercell->connections["\\Y"] = y; + module->add(supercell); + + RTLIL::SigSpec new_y1(y, y1.width); + RTLIL::SigSpec new_y2(y, y2.width); + + module->connections.push_back(RTLIL::SigSig(y1, new_y1)); + module->connections.push_back(RTLIL::SigSig(y2, new_y2)); + + return supercell; + } + + if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type)) + { + bool modified_src_cells = false; + + if (config.generic_cbin_ops.count(c1->type)) + { + int score_unflipped = std::max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()) + + std::max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()); + + int score_flipped = std::max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()) + + std::max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()); + + if (score_flipped < score_unflipped) + { + std::swap(c2->connections.at("\\A"), c2->connections.at("\\B")); + std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); + std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); + modified_src_cells = true; + } + } + + if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) + + { + RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; + if (unsigned_cell->connections.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; + unsigned_cell->connections.at("\\A").append_bit(RTLIL::State::S0); + } + unsigned_cell->parameters.at("\\A_SIGNED") = true; + modified_src_cells = true; + } + + if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) + { + RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; + if (unsigned_cell->connections.at("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { + unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; + unsigned_cell->connections.at("\\B").append_bit(RTLIL::State::S0); + } + unsigned_cell->parameters.at("\\B_SIGNED") = true; + modified_src_cells = true; + } + + if (modified_src_cells) { + c1->check(); + c2->check(); + } bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); bool b_signed = c1->parameters.at("\\B_SIGNED").as_bool(); @@ -259,9 +394,7 @@ struct ShareWorker RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); - RTLIL::Cell *supercell = new RTLIL::Cell; - supercell->name = NEW_ID; - supercell->type = c1->type; + RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); supercell->parameters["\\A_SIGNED"] = a_signed; supercell->parameters["\\B_SIGNED"] = b_signed; supercell->parameters["\\A_WIDTH"] = a_width; @@ -270,7 +403,7 @@ struct ShareWorker supercell->connections["\\A"] = a; supercell->connections["\\B"] = b; supercell->connections["\\Y"] = y; - module->add(supercell); + supercell->check(); RTLIL::SigSpec new_y1(y, y1.width); RTLIL::SigSpec new_y2(y, y2.width); @@ -502,6 +635,10 @@ struct ShareWorker ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : config(config), design(design), module(module) { + generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end()); + generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end()); + generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end()); + fwd_ct.setup_internals(); cone_ct.setup_internals(); @@ -752,10 +889,53 @@ struct SharePass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { ShareWorkerConfig config; + config.opt_force = false; config.opt_aggressive = false; config.opt_fast = false; + config.generic_uni_ops.insert("$not"); + // config.generic_uni_ops.insert("$pos"); + // config.generic_uni_ops.insert("$bu0"); + config.generic_uni_ops.insert("$neg"); + + config.generic_uni_ops.insert("$reduce_and"); + config.generic_uni_ops.insert("$reduce_or"); + config.generic_uni_ops.insert("$reduce_xor"); + config.generic_uni_ops.insert("$reduce_xnor"); + config.generic_uni_ops.insert("$reduce_bool"); + + config.generic_cbin_ops.insert("$and"); + config.generic_cbin_ops.insert("$or"); + config.generic_cbin_ops.insert("$xor"); + config.generic_cbin_ops.insert("$xnor"); + + config.generic_bin_ops.insert("$shl"); + config.generic_bin_ops.insert("$shr"); + config.generic_bin_ops.insert("$sshl"); + config.generic_bin_ops.insert("$sshr"); + + config.generic_bin_ops.insert("$lt"); + config.generic_bin_ops.insert("$le"); + config.generic_bin_ops.insert("$eq"); + config.generic_bin_ops.insert("$ne"); + config.generic_bin_ops.insert("$eqx"); + config.generic_bin_ops.insert("$nex"); + config.generic_bin_ops.insert("$ge"); + config.generic_bin_ops.insert("$gt"); + + config.generic_cbin_ops.insert("$add"); + config.generic_cbin_ops.insert("$mul"); + + config.generic_bin_ops.insert("$sub"); + config.generic_bin_ops.insert("$div"); + config.generic_bin_ops.insert("$mod"); + // config.generic_bin_ops.insert("$pow"); + + config.generic_uni_ops.insert("$logic_not"); + config.generic_cbin_ops.insert("$logic_and"); + config.generic_cbin_ops.insert("$logic_or"); + log_header("Executing SHARE pass (SAT-based resource sharing).\n"); size_t argidx; diff --git a/tests/share/generate.py b/tests/share/generate.py index 9e5bef7a..e3b4bc96 100644 --- a/tests/share/generate.py +++ b/tests/share/generate.py @@ -15,36 +15,58 @@ def redirect_stdout(new_target): finally: sys.stdout = old_target -def maybe_plus_e(expr): +def random_plus_x(): + return "%s x" % random.choice(['+', '+', '+', '-', '-', '|', '&', '^']) + +def maybe_plus_x(expr): if random.randint(0, 4) == 0: - return "(%s + e)" % expr + return "(%s %s)" % (expr, random_plus_x()) else: return expr for idx in range(100): with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): - print('module uut_%05d(a, b, c, d, e, s, y);' % (idx)) - ac_signed = random.choice(['', ' signed']) - bd_signed = random.choice(['', ' signed']) - op = random.choice(['+', '-', '*', '/', '%', '<<', '>>', '<<<', '>>>']) - print(' input%s [%d:0] a;' % (ac_signed, random.randint(0, 8))) - print(' input%s [%d:0] b;' % (bd_signed, random.randint(0, 8))) - print(' input%s [%d:0] c;' % (ac_signed, random.randint(0, 8))) - print(' input%s [%d:0] d;' % (bd_signed, random.randint(0, 8))) - print(' input signed [%d:0] e;' % random.randint(0, 8)) - print(' input s;') - print(' output [%d:0] y;' % random.randint(0, 8)) - print(' assign y = (s ? %s(%s %s %s) : %s(%s %s %s))%s;' % - (random.choice(['', '$signed', '$unsigned']), maybe_plus_e('a'), op, maybe_plus_e('b'), - random.choice(['', '$signed', '$unsigned']), maybe_plus_e('c'), op, maybe_plus_e('d'), - ' + e' if random.randint(0, 4) == 0 else '')) - print('endmodule') + if random.choice(['bin', 'uni']) == 'bin': + print('module uut_%05d(a, b, c, d, x, s, y);' % (idx)) + op = random.choice([ + random.choice(['+', '-', '*', '/', '%']), + random.choice(['<', '<=', '==', '!=', '===', '!==', '>=', '>' ]), + random.choice(['<<', '>>', '<<<', '>>>']), + random.choice(['|', '&', '^', '~^', '||', '&&']), + ]) + print(' input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input%s [%d:0] c;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input%s [%d:0] d;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input s;') + print(' output [%d:0] y;' % random.randint(0, 8)) + print(' assign y = (s ? %s(%s %s %s) : %s(%s %s %s))%s;' % + (random.choice(['', '$signed', '$unsigned']), maybe_plus_x('a'), op, maybe_plus_x('b'), + random.choice(['', '$signed', '$unsigned']), maybe_plus_x('c'), op, maybe_plus_x('d'), + random_plus_x() if random.randint(0, 4) == 0 else '')) + print('endmodule') + else: + print('module uut_%05d(a, b, x, s, y);' % (idx)) + op = random.choice(['~', '-', '!']) + print(' input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 8))) + print(' input s;') + print(' output [%d:0] y;' % random.randint(0, 8)) + print(' assign y = (s ? %s(%s%s) : %s(%s%s))%s;' % + (random.choice(['', '$signed', '$unsigned']), op, maybe_plus_x('a'), + random.choice(['', '$signed', '$unsigned']), op, maybe_plus_x('b'), + random_plus_x() if random.randint(0, 4) == 0 else '')) + print('endmodule') with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): print('read_verilog temp/uut_%05d.v' % idx) print('proc;;') print('copy uut_%05d gold' % idx) print('rename uut_%05d gate' % idx) - print('share -aggressive gate') + print('tee -a temp/all_share_log.txt log') + print('tee -a temp/all_share_log.txt log #job# uut_%05d' % idx) + print('tee -a temp/all_share_log.txt share -aggressive gate') print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') print('sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter') diff --git a/tests/share/run-test.sh b/tests/share/run-test.sh index d511c909..203d6fcd 100755 --- a/tests/share/run-test.sh +++ b/tests/share/run-test.sh @@ -1,4 +1,8 @@ #!/bin/bash + +# run this test many times: +# time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' + set -e rm -rf temp @@ -14,3 +18,10 @@ for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do done echo +failed_share=$( echo $( gawk '/^#job#/ { j=$2; db[j]=0; } /^Removing [24] cells/ { delete db[j]; } END { for (j in db) print(j); }' temp/all_share_log.txt ) ) +if [ -n "$failed_share" ]; then + echo "Resource sharing failed for the following test cases: $failed_share" + false +fi + +exit 0 From 1d88f1cf9f2088de7825f5292db5b40d4f73d036 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:35:06 +0200 Subject: [PATCH 345/750] Removed deprecated module->new_wire() --- frontends/liberty/liberty.cc | 10 +++++----- kernel/rtlil.cc | 21 ++++++--------------- kernel/rtlil.h | 10 +++++----- passes/cmds/connect.cc | 2 +- passes/cmds/delete.cc | 2 +- passes/cmds/splice.cc | 4 ++-- passes/memory/memory_share.cc | 4 ++-- passes/sat/freduce.cc | 4 ++-- passes/sat/miter.cc | 12 ++++++------ passes/sat/share.cc | 26 +++++++++++++------------- passes/techmap/simplemap.cc | 8 ++++---- 11 files changed, 47 insertions(+), 56 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index e7af9372..cf243f63 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) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b16b62ca..d3d830d6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -819,15 +819,6 @@ RTLIL::Module *RTLIL::Module::clone() const return new_mod; } -RTLIL::Wire *RTLIL::Module::new_wire(int width, RTLIL::IdString name) -{ - RTLIL::Wire *wire = new RTLIL::Wire; - wire->width = width; - wire->name = name; - add(wire); - return wire; -} - void RTLIL::Module::add(RTLIL::Wire *wire) { assert(!wire->name.empty()); @@ -908,7 +899,7 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed) { \ - RTLIL::SigSpec sig_y = new_wire(_y_size, NEW_ID); \ + RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_y, is_signed); \ return sig_y; \ } @@ -941,7 +932,7 @@ DEF_METHOD(LogicNot, 1, "$logic_not") return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed) { \ - RTLIL::SigSpec sig_y = new_wire(_y_size, NEW_ID); \ + RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_b, sig_y, is_signed); \ return sig_y; \ } @@ -986,7 +977,7 @@ DEF_METHOD(LogicOr, 1, "$logic_or") return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \ - RTLIL::SigSpec sig_y = new_wire(sig_a.width, NEW_ID); \ + RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.width); \ add ## _func(name, sig_a, sig_b, sig_s, sig_y); \ return sig_y; \ } @@ -1006,7 +997,7 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1) { \ - RTLIL::SigSpec sig2 = new_wire(1, NEW_ID); \ + RTLIL::SigSpec sig2 = addWire(NEW_ID); \ add ## _func(name, sig1, sig2); \ return sig2; \ } @@ -1022,7 +1013,7 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ - RTLIL::SigSpec sig3 = new_wire(1, NEW_ID); \ + RTLIL::SigSpec sig3 = addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3); \ return sig3; \ } @@ -1039,7 +1030,7 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ - RTLIL::SigSpec sig4 = new_wire(1, NEW_ID); \ + RTLIL::SigSpec sig4 = addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3, sig4); \ return sig4; \ } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 19666481..3c6c9724 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -142,7 +142,7 @@ namespace RTLIL RTLIL::new_id(__FILE__, __LINE__, __FUNCTION__) #define NEW_WIRE(_mod, _width) \ - (_mod)->new_wire(_width, NEW_ID) + (_mod)->addWire(NEW_ID, _width) template struct sort_by_name { bool operator()(T *a, T *b) const { @@ -287,16 +287,16 @@ struct RTLIL::Module { virtual size_t count_id(RTLIL::IdString id); virtual void check(); virtual void optimize(); - RTLIL::Wire *new_wire(int width, RTLIL::IdString name); - void add(RTLIL::Wire *wire); - void add(RTLIL::Cell *cell); - void remove(RTLIL::Cell *cell); void fixup_ports(); template void rewrite_sigspecs(T functor); void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; + void add(RTLIL::Wire *wire); + void add(RTLIL::Cell *cell); + void remove(RTLIL::Cell *cell); + RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 7da2b951..f99cb9b5 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -27,7 +27,7 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & { CellTypes ct(design); - RTLIL::Wire *dummy_wire = module->new_wire(sig.width, NEW_ID); + RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.width); for (auto &it : module->cells) for (auto &port : it.second->connections) diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 1c02752c..ce6ac4af 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -30,7 +30,7 @@ struct DeleteWireWorker sig.optimize(); for (auto &c : sig.chunks) if (c.wire != NULL && delete_wires_p->count(c.wire->name)) { - c.wire = module->new_wire(c.width, NEW_ID); + c.wire = module->addWire(NEW_ID, c.width); c.offset = 0; } } diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 6d920dbc..a48a54a1 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -77,7 +77,7 @@ struct SpliceWorker cell->parameters["\\A_WIDTH"] = sig_a.width; cell->parameters["\\Y_WIDTH"] = sig.width; cell->connections["\\A"] = sig_a; - cell->connections["\\Y"] = module->new_wire(sig.width, NEW_ID); + cell->connections["\\Y"] = module->addWire(NEW_ID, sig.width); new_sig = cell->connections["\\Y"]; module->add(cell); } @@ -138,7 +138,7 @@ struct SpliceWorker cell->parameters["\\B_WIDTH"] = sig2.width; cell->connections["\\A"] = new_sig; cell->connections["\\B"] = sig2; - cell->connections["\\Y"] = module->new_wire(new_sig.width + sig2.width, NEW_ID); + cell->connections["\\Y"] = module->addWire(NEW_ID, new_sig.width + sig2.width); new_sig = cell->connections["\\Y"]; module->add(cell); } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index dc015f96..578007a0 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -419,7 +419,7 @@ struct MemoryShareWorker if (0) { found_overlapping_bits_i_j: log(" Creating collosion-detect logic for port %d.\n", j); - RTLIL::SigSpec is_same_addr = module->new_wire(1, NEW_ID); + RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID); module->addEq(NEW_ID, addr, wr_ports[j]->connections.at("\\ADDR"), is_same_addr); merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->connections.at("\\EN"))); } @@ -603,7 +603,7 @@ struct MemoryShareWorker std::map, int> groups_en; RTLIL::SigSpec grouped_last_en, grouped_this_en, en; - RTLIL::Wire *grouped_en = module->new_wire(0, NEW_ID); + RTLIL::Wire *grouped_en = module->addWire(NEW_ID, 0); for (int j = 0; j < int(this_en.size()); j++) { std::pair key(last_en[j], this_en[j]); diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index d4b7b5c1..ac041564 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -707,7 +707,7 @@ struct FreduceWorker log(" Connect slave%s: %s\n", grp[i].inverted ? " using inverter" : "", log_signal(grp[i].bit)); RTLIL::Cell *drv = drivers.at(grp[i].bit).first; - RTLIL::Wire *dummy_wire = module->new_wire(1, NEW_ID); + RTLIL::Wire *dummy_wire = module->addWire(NEW_ID); for (auto &port : drv->connections) if (ct.cell_output(drv->type, port.first)) sigmap(port.second).replace(grp[i].bit, dummy_wire, &port.second); @@ -716,7 +716,7 @@ struct FreduceWorker { if (inv_sig.width == 0) { - inv_sig = module->new_wire(1, NEW_ID); + inv_sig = module->addWire(NEW_ID); RTLIL::Cell *inv_cell = new RTLIL::Cell; inv_cell->name = NEW_ID; diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 0ef9e9aa..6e57fceb 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -164,7 +164,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, if (flag_ignore_gold_x) { - RTLIL::SigSpec gold_x = miter_module->new_wire(w2_gold->width, NEW_ID); + RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w2_gold->width); for (int i = 0; i < w2_gold->width; i++) { RTLIL::Cell *eqx_cell = new RTLIL::Cell; eqx_cell->name = NEW_ID; @@ -180,8 +180,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, miter_module->add(eqx_cell); } - RTLIL::SigSpec gold_masked = miter_module->new_wire(w2_gold->width, NEW_ID); - RTLIL::SigSpec gate_masked = miter_module->new_wire(w2_gate->width, NEW_ID); + RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width); + RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w2_gate->width); RTLIL::Cell *or_gold_cell = new RTLIL::Cell; or_gold_cell->name = NEW_ID; @@ -219,7 +219,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\B_SIGNED"] = 0; eq_cell->connections["\\A"] = gold_masked; eq_cell->connections["\\B"] = gate_masked; - eq_cell->connections["\\Y"] = miter_module->new_wire(1, NEW_ID); + eq_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); this_condition = eq_cell->connections["\\Y"]; miter_module->add(eq_cell); } @@ -235,7 +235,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\B_SIGNED"] = 0; eq_cell->connections["\\A"] = w2_gold; eq_cell->connections["\\B"] = w2_gate; - eq_cell->connections["\\Y"] = miter_module->new_wire(1, NEW_ID); + eq_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); this_condition = eq_cell->connections["\\Y"]; miter_module->add(eq_cell); } @@ -261,7 +261,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; reduce_cell->connections["\\A"] = all_conditions; - reduce_cell->connections["\\Y"] = miter_module->new_wire(1, NEW_ID); + reduce_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); all_conditions = reduce_cell->connections["\\Y"]; miter_module->add(reduce_cell); } diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 852d8078..42e59c47 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -276,11 +276,11 @@ struct ShareWorker int a_width = std::max(a1.width, a2.width); int y_width = std::max(y1.width, y2.width); - if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); - if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); - RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); + RTLIL::Wire *y = module->addWire(NEW_ID, y_width); RTLIL::Cell *supercell = new RTLIL::Cell; supercell->name = NEW_ID; @@ -375,24 +375,24 @@ struct ShareWorker { a_width = std::max(y_width, a_width); - if (a1.width < y1.width) a1 = module->addPos(NEW_ID, a1, module->new_wire(y1.width, NEW_ID), true)->connections.at("\\Y"); - if (a2.width < y2.width) a2 = module->addPos(NEW_ID, a2, module->new_wire(y2.width, NEW_ID), true)->connections.at("\\Y"); + if (a1.width < y1.width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.width), true)->connections.at("\\Y"); + if (a2.width < y2.width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.width), true)->connections.at("\\Y"); - if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), false)->connections.at("\\Y"); - if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), false)->connections.at("\\Y"); + if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); + if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); } else { - if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); - if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); + if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); } - if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y"); - if (b2.width != b_width) b2 = module->addPos(NEW_ID, b2, module->new_wire(b_width, NEW_ID), b_signed)->connections.at("\\Y"); + if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); + if (b2.width != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); - RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); + RTLIL::Wire *y = module->addWire(NEW_ID, y_width); RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); supercell->parameters["\\A_SIGNED"] = a_signed; @@ -617,7 +617,7 @@ struct ShareWorker RTLIL::SigSpec make_cell_activation_logic(const std::set> &activation_patterns) { - RTLIL::Wire *all_cases_wire = module->new_wire(0, NEW_ID); + RTLIL::Wire *all_cases_wire = module->addWire(NEW_ID, 0); for (auto &p : activation_patterns) { all_cases_wire->width++; module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec(all_cases_wire, 1, all_cases_wire->width - 1)); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index e67b1e05..91f3b612 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -89,7 +89,7 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$xnor") { - RTLIL::SigSpec sig_t = module->new_wire(width, NEW_ID); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, width); sig_t.expand(); for (int i = 0; i < width; i++) { @@ -158,7 +158,7 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) while (sig_a.width > 1) { - RTLIL::SigSpec sig_t = module->new_wire(sig_a.width / 2, NEW_ID); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.width / 2); sig_t.expand(); for (int i = 0; i < sig_a.width; i += 2) @@ -182,7 +182,7 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) } if (cell->type == "$reduce_xnor") { - RTLIL::SigSpec sig_t = module->new_wire(1, NEW_ID); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID); RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_INV_"; @@ -206,7 +206,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) while (sig.width > 1) { - RTLIL::SigSpec sig_t = module->new_wire(sig.width / 2, NEW_ID); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.width / 2); sig_t.expand(); for (int i = 0; i < sig.width; i += 2) From 361e0d62ffd90b87c94bfc98ed3cbee1a745cd8f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:41:29 +0200 Subject: [PATCH 346/750] Replaced depricated NEW_WIRE macro with module->addWire() calls --- frontends/liberty/liberty.cc | 20 ++++++++++---------- kernel/rtlil.h | 3 --- passes/proc/proc_dff.cc | 20 ++++++++++---------- passes/techmap/hilomap.cc | 4 ++-- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index cf243f63..9000d702 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); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 3c6c9724..9b3e4417 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -141,9 +141,6 @@ namespace RTLIL #define NEW_ID \ RTLIL::new_id(__FILE__, __LINE__, __FUNCTION__) -#define NEW_WIRE(_mod, _width) \ - (_mod)->addWire(NEW_ID, _width) - template struct sort_by_name { bool operator()(T *a, T *b) const { return a->name < b->name; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index c1844651..13e4e660 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -80,7 +80,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.width); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; - cell->connections["\\Y"] = sync_low_signals = NEW_WIRE(mod, 1); + cell->connections["\\Y"] = sync_low_signals = mod->addWire(NEW_ID); mod->add(cell); } @@ -92,7 +92,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.width); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; - cell->connections["\\Y"] = NEW_WIRE(mod, 1); + cell->connections["\\Y"] = mod->addWire(NEW_ID); sync_high_signals.append(cell->connections["\\Y"]); mod->add(cell); } @@ -105,7 +105,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.width); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_high_signals; - cell->connections["\\Y"] = sync_high_signals = NEW_WIRE(mod, 1); + cell->connections["\\Y"] = sync_high_signals = mod->addWire(NEW_ID); mod->add(cell); } @@ -116,7 +116,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.width); inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.width); inv_cell->connections["\\A"] = sync_value; - inv_cell->connections["\\Y"] = sync_value_inv = NEW_WIRE(mod, sig_d.width); + inv_cell->connections["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.width); mod->add(inv_cell); RTLIL::Cell *mux_set_cell = new RTLIL::Cell; @@ -126,7 +126,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S mux_set_cell->connections["\\A"] = sig_sr_set; mux_set_cell->connections["\\B"] = sync_value; mux_set_cell->connections["\\S"] = sync_high_signals; - mux_set_cell->connections["\\Y"] = sig_sr_set = NEW_WIRE(mod, sig_d.width); + mux_set_cell->connections["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.width); mod->add(mux_set_cell); RTLIL::Cell *mux_clr_cell = new RTLIL::Cell; @@ -136,7 +136,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S mux_clr_cell->connections["\\A"] = sig_sr_clr; mux_clr_cell->connections["\\B"] = sync_value_inv; mux_clr_cell->connections["\\S"] = sync_high_signals; - mux_clr_cell->connections["\\Y"] = sig_sr_clr = NEW_WIRE(mod, sig_d.width); + mux_clr_cell->connections["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.width); mod->add(mux_clr_cell); } @@ -168,9 +168,9 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec std::stringstream sstr; sstr << "$procdff$" << (RTLIL::autoidx++); - RTLIL::SigSpec sig_set_inv = NEW_WIRE(mod, sig_in.width); - RTLIL::SigSpec sig_sr_set = NEW_WIRE(mod, sig_in.width); - RTLIL::SigSpec sig_sr_clr = NEW_WIRE(mod, sig_in.width); + RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.width); + RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.width); + RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.width); RTLIL::Cell *inv_set = new RTLIL::Cell; inv_set->name = NEW_ID; @@ -315,7 +315,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) { sync_level = new RTLIL::SyncRule; sync_level->type = RTLIL::SyncType::ST1; - sync_level->signal = NEW_WIRE(mod, 1); + sync_level->signal = mod->addWire(NEW_ID); sync_level->actions.push_back(RTLIL::SigSig(sig, rstval)); free_sync_level = true; diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index bc5caa38..d24f557e 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -34,7 +34,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) for (auto &c : sig.chunks) { if (c.wire == NULL && (c.data.bits.at(0) == RTLIL::State::S1) && !hicell_celltype.empty()) { if (!singleton_mode || last_hi.width == 0) { - last_hi = RTLIL::SigChunk(NEW_WIRE(module, 1)); + last_hi = RTLIL::SigChunk(module->addWire(NEW_ID)); RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = RTLIL::escape_id(hicell_celltype); @@ -45,7 +45,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) } if (c.wire == NULL && (c.data.bits.at(0) == RTLIL::State::S0) && !locell_celltype.empty()) { if (!singleton_mode || last_lo.width == 0) { - last_lo = RTLIL::SigChunk(NEW_WIRE(module, 1)); + last_lo = RTLIL::SigChunk(module->addWire(NEW_ID)); RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = RTLIL::escape_id(locell_celltype); From 550ac3587302c6c95892c66db2cfa3788b2b5c42 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 13:28:12 +0200 Subject: [PATCH 347/750] Added support for scripts with labels --- kernel/driver.cc | 85 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 577fbe3d..e365e67c 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -49,7 +49,30 @@ bool fgetline(FILE *f, std::string &buffer) } } -static void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command) +static void handle_label(std::string &command, bool &from_to_active, const std::string &run_from, const std::string &run_to) +{ + int pos = 0; + std::string label; + + while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) + pos++; + + while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') + label += command[pos++]; + + if (label.back() == ':' && SIZE(label) > 1) + { + label = label.substr(0, SIZE(label)-1); + command = command.substr(pos); + + if (label == run_from) + from_to_active = true; + else if (label == run_to || (run_from == run_to && !run_from.empty())) + from_to_active = false; + } +} + +static void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) { if (command == "auto") { if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") @@ -66,13 +89,33 @@ static void run_frontend(std::string filename, std::string command, RTLIL::Desig log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str()); } - if (command == "script") { + if (command == "script") + { + std::string run_from, run_to; + bool from_to_active = true; + + if (from_to_label != NULL) { + size_t pos = from_to_label->find(':'); + if (pos == std::string::npos) { + run_from = *from_to_label; + run_to = *from_to_label; + } else { + run_from = from_to_label->substr(0, pos); + run_to = from_to_label->substr(pos+1); + } + from_to_active = run_from.empty(); + } + log("\n-- Executing script file `%s' --\n", filename.c_str()); + FILE *f = stdin; + if (filename != "-") f = fopen(filename.c_str(), "r"); + if (f == NULL) log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); + std::string command; while (fgetline(f, command)) { while (!command.empty() && command[command.size()-1] == '\\') { @@ -82,14 +125,23 @@ static void run_frontend(std::string filename, std::string command, RTLIL::Desig command.resize(command.size()-1); command += next_line; } - Pass::call(design, command); + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); } - if (!command.empty()) - Pass::call(design, command); + + if (!command.empty()) { + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + if (filename != "-") fclose(f); + if (backend_command != NULL && *backend_command == "auto") *backend_command = ""; + return; } @@ -340,17 +392,28 @@ struct ScriptPass : public Pass { ScriptPass() : Pass("script", "execute commands from script file") { } virtual void help() { log("\n"); - log(" script \n"); + log(" script [:]\n"); log("\n"); log("This command executes the yosys commands in the specified file.\n"); log("\n"); + log("The 2nd argument can be used to only execute the section of the\n"); + log("file between the specified labels. An empty from label is synonymous\n"); + log("for the beginning of the file and an empty to label is synonymous\n"); + log("for the end of the file.\n"); + log("\n"); + log("If only one label is specified (without ':') then only the block\n"); + log("marked with that label (until the next label) is executed.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { if (args.size() < 2) log_cmd_error("Missing script file.\n"); - if (args.size() > 2) - extra_args(args, 1, design, false); - run_frontend(args[1], "script", design, NULL); + else if (args.size() == 2) + run_frontend(args[1], "script", design, NULL, NULL); + else if (args.size() == 3) + run_frontend(args[1], "script", design, NULL, &args[2]); + else + extra_args(args, 2, design, false); } } ScriptPass; @@ -663,7 +726,7 @@ int main(int argc, char **argv) } while (optind < argc) - run_frontend(argv[optind++], frontend_command, yosys_design, output_filename == "-" ? &backend_command : NULL); + run_frontend(argv[optind++], frontend_command, yosys_design, output_filename == "-" ? &backend_command : NULL, NULL); if (!scriptfile.empty()) { if (scriptfile_tcl) { @@ -674,7 +737,7 @@ int main(int argc, char **argv) log_error("Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n"); #endif } else - run_frontend(scriptfile, "script", yosys_design, output_filename == "-" ? &backend_command : NULL); + run_frontend(scriptfile, "script", yosys_design, output_filename == "-" ? &backend_command : NULL, NULL); } for (auto it = passes_commands.begin(); it != passes_commands.end(); it++) From 668306d00f47989d1f66d139351e63fe2465961c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 14:08:13 +0200 Subject: [PATCH 348/750] Various improvements in test/vloghtb --- tests/vloghtb/common.sh | 39 ++++++++++++++++++++++++++++++++++-- tests/vloghtb/run-test.sh | 7 ++++--- tests/vloghtb/test_mapopt.sh | 11 ++++++++++ tests/vloghtb/test_share.sh | 27 +------------------------ 4 files changed, 53 insertions(+), 31 deletions(-) create mode 100644 tests/vloghtb/test_mapopt.sh diff --git a/tests/vloghtb/common.sh b/tests/vloghtb/common.sh index dc8aec08..704afdd9 100644 --- a/tests/vloghtb/common.sh +++ b/tests/vloghtb/common.sh @@ -1,7 +1,42 @@ -log_pass() { +log_pass() +{ printf "%-15s %s %s %s\n" "$1" "$2" "`printf "%20s" "$2" | tr -d a-zA-Z0-9_ | tr ' ' .`" "pass." } -log_fail() { +log_fail() +{ printf "%-15s %s %s %s\n" "$1" "$2" "`printf "%20s" "$2" | tr -d a-zA-Z0-9_ | tr ' ' .`" "FAIL." } + +test_equiv() +{ + # Usage: + # test_equiv + + mkdir -p log_test_$1 + rm -f log_test_$1/$4.txt + rm -f log_test_$1/$4.err + + if ! ../../yosys -q -l log_test_$1/$4.out - 2> /dev/null <<- EOT + read_verilog $5 + proc;; + + copy $4 gold + rename $4 work + + cd work + $2 + cd .. + + miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold work miter + sat $3 -verify -prove trigger 0 -show-inputs -show-outputs miter + EOT + then + log_fail test_$1 $4 + mv log_test_$1/$4.out log_test_$1/$4.err + exit 1 + fi + + log_pass test_$1 $4 + mv log_test_$1/$4.out log_test_$1/$4.txt +} diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh index 0e01fd64..3b8a3e9e 100755 --- a/tests/vloghtb/run-test.sh +++ b/tests/vloghtb/run-test.sh @@ -7,8 +7,9 @@ wget http://www.clifford.at/yosys/nogit/vloghammer_tb.tar.bz2 tar --strip=1 -xjf vloghammer_tb.tar.bz2 make clean -make -j4 EXIT_ON_ERROR=1 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys - rm -rf log_test_* -make -j4 -f test_makefile MODE=share + +make -j4 EXIT_ON_ERROR=1 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys +make -j4 -f test_makefile MODE=share +make -j4 -f test_makefile MODE=mapopt diff --git a/tests/vloghtb/test_mapopt.sh b/tests/vloghtb/test_mapopt.sh new file mode 100644 index 00000000..9099e2b7 --- /dev/null +++ b/tests/vloghtb/test_mapopt.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e +source common.sh + +f=$1 +n=$(basename ${f%.v}) + +test_equiv mapopt "opt; techmap; opt" "-set-def-inputs" $n $f + +exit 0 diff --git a/tests/vloghtb/test_share.sh b/tests/vloghtb/test_share.sh index 88e04281..da221162 100644 --- a/tests/vloghtb/test_share.sh +++ b/tests/vloghtb/test_share.sh @@ -1,36 +1,11 @@ #!/bin/bash set -e -mkdir -p log_test_share source common.sh f=$1 n=$(basename ${f%.v}) -rm -f log_test_share/$n.txt -rm -f log_test_share/$n.err +test_equiv share "share -aggressive" "-ignore_div_by_zero" $n $f -if ! ../../yosys -q -l log_test_share/$n.out - 2> /dev/null <<- EOT - read_verilog $f - proc;; - - copy $n gold - rename $n work - - cd work - share -aggressive - cd .. - - miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold work miter - sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter -EOT -then - log_fail test_share $n - mv log_test_share/$n.out log_test_share/$n.err - exit 1 -fi - -log_pass test_share $n -mv log_test_share/$n.out log_test_share/$n.txt exit 0 - From e035f1d886b30329c1c061894146a5c6f92b4f7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 14:09:11 +0200 Subject: [PATCH 349/750] Added opt_const support for simple identities --- passes/opt/opt_const.cc | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index da71ec30..76948344 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -288,6 +288,75 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } + // checking for simple identities + { + bool identity_bu0 = false; + bool identity_wrt_a = false; + bool identity_wrt_b = false; + + if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$or" || cell->type == "$xor") + { + RTLIL::SigSpec a = assign_map(cell->connections["\\A"]); + RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + + if (cell->type != "$sub" && a.is_fully_const() && a.as_bool() == false) + identity_wrt_b = true; + + if (b.is_fully_const() && b.as_bool() == false) + identity_wrt_a = true; + } + + if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") + { + RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + + if (b.is_fully_const() && b.as_bool() == false) + identity_wrt_a = true, identity_bu0 = true; + } + + if (cell->type == "$mul") + { + RTLIL::SigSpec a = assign_map(cell->connections["\\A"]); + RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + + if (a.is_fully_const() && a.width <= 32 && a.as_int() == 1) + identity_wrt_b = true; + + if (b.is_fully_const() && b.width <= 32 && b.as_int() == 1) + identity_wrt_a = true; + } + + if (cell->type == "$div") + { + RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + + if (b.is_fully_const() && b.width <= 32 && b.as_int() == 1) + identity_wrt_a = true; + } + + if (identity_wrt_a || identity_wrt_b) + { + log("Replacing %s cell `%s' in module `%s' with identity for port %c.\n", + cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); + + if (!identity_wrt_a) { + cell->connections.at("\\A") = cell->connections.at("\\B"); + cell->parameters.at("\\A_WIDTH") = cell->parameters.at("\\B_WIDTH"); + cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); + } + + cell->type = identity_bu0 ? "$bu0" : "$pos"; + cell->connections.erase("\\B"); + cell->parameters.erase("\\B_WIDTH"); + cell->parameters.erase("\\B_SIGNED"); + cell->check(); + + OPT_DID_SOMETHING = true; + did_something = true; + goto next_cell; + } + } + if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections["\\A"] == RTLIL::SigSpec(0, 1) && cell->connections["\\B"] == RTLIL::SigSpec(1, 1)) { replace_cell(module, cell, "mux_bool", "\\Y", cell->connections["\\S"]); From 4147b55c233013dd861172f13d0b9669598d234c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 15:15:18 +0200 Subject: [PATCH 350/750] Added "autoidx" statement to ilang file format --- backends/ilang/ilang_backend.cc | 15 ++++++++++++++- frontends/ilang/lexer.l | 27 +++------------------------ frontends/ilang/parser.y | 8 +++++++- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index b3d96b28..eaad7869 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -335,15 +335,26 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { + int init_autoidx = RTLIL::autoidx; + if (!flag_m) { int count_selected_mods = 0; - for (auto it = design->modules.begin(); it != design->modules.end(); it++) + for (auto it = design->modules.begin(); it != design->modules.end(); it++) { + if (design->selected_whole_module(it->first)) + flag_m = true; if (design->selected(it->second)) count_selected_mods++; + } if (count_selected_mods > 1) flag_m = true; } + if (!only_selected || flag_m) { + if (only_selected) + fprintf(f, "\n"); + fprintf(f, "autoidx %d\n", RTLIL::autoidx); + } + for (auto it = design->modules.begin(); it != design->modules.end(); it++) { if (!only_selected || design->selected(it->second)) { if (only_selected) @@ -351,6 +362,8 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ dump_module(f, "", it->second, design, only_selected, flag_m, flag_n); } } + + log_assert(init_autoidx == RTLIL::autoidx); } struct IlangBackend : public Backend { diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 6557f98a..c40b81af 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 6b41b087..d8ecf37b 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; From 1241a9fd5073d327d49f1af47db37214a4628ed8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 16:34:16 +0200 Subject: [PATCH 351/750] Added "opt_const -fine" and "opt_reduce -fine" --- passes/opt/opt.cc | 14 +++-- passes/opt/opt_const.cc | 121 +++++++++++++++++++++++++++++++++++++-- passes/opt/opt_reduce.cc | 24 ++++++-- tests/tools/autotest.sh | 2 +- 4 files changed, 145 insertions(+), 16 deletions(-) diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index 8f4725e1..62aa48be 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -31,7 +31,7 @@ struct OptPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" opt [-purge] [-mux_undef] [-mux_bool] [-undriven] [selection]\n"); + log(" opt [-purge] [-mux_undef] [-mux_bool] [-undriven] [-fine] [selection]\n"); log("\n"); log("This pass calls all the other opt_* passes in a useful order. This performs\n"); log("a series of trivial optimizations and cleanups. This pass executes the other\n"); @@ -42,11 +42,11 @@ struct OptPass : public Pass { log("\n"); log(" do\n"); log(" opt_muxtree\n"); - log(" opt_reduce\n"); + log(" opt_reduce [-fine]\n"); log(" opt_share\n"); log(" opt_rmdff\n"); log(" opt_clean [-purge]\n"); - log(" opt_const [-mux_undef] [-mux_bool] [-undriven]\n"); + log(" opt_const [-mux_undef] [-mux_bool] [-undriven] [-fine]\n"); log(" while [changed design]\n"); log("\n"); } @@ -54,6 +54,7 @@ struct OptPass : public Pass { { std::string opt_clean_args; std::string opt_const_args; + std::string opt_reduce_args; log_header("Executing OPT pass (performing simple optimizations).\n"); log_push(); @@ -76,6 +77,11 @@ struct OptPass : public Pass { opt_const_args += " -undriven"; continue; } + if (args[argidx] == "-fine") { + opt_const_args += " -fine"; + opt_reduce_args += " -fine"; + continue; + } break; } extra_args(args, argidx, design); @@ -88,7 +94,7 @@ struct OptPass : public Pass { while (1) { OPT_DID_SOMETHING = false; Pass::call(design, "opt_muxtree"); - Pass::call(design, "opt_reduce"); + Pass::call(design, "opt_reduce" + opt_reduce_args); Pass::call(design, "opt_share"); Pass::call(design, "opt_rmdff"); Pass::call(design, "opt_clean" + opt_clean_args); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 76948344..a17ca679 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -25,11 +25,11 @@ #include #include #include -#include +#include static bool did_something; -void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) +static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) { CellTypes ct(design); SigMap sigmap(module); @@ -71,7 +71,7 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) } } -void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) +static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { RTLIL::SigSpec Y = cell->connections[out_port]; log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", @@ -85,7 +85,103 @@ void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, st did_something = true; } -void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool) +static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, bool extend_u0, SigMap &sigmap) +{ + std::string b_name = cell->connections.count("\\B") ? "\\B" : "\\A"; + + bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool(); + bool b_signed = cell->parameters.at(b_name + "_SIGNED").as_bool(); + + RTLIL::SigSpec sig_a = sigmap(cell->connections.at("\\A")); + RTLIL::SigSpec sig_b = sigmap(cell->connections.at(b_name)); + RTLIL::SigSpec sig_y = sigmap(cell->connections.at("\\Y")); + + if (extend_u0) { + sig_a.extend_u0(sig_y.width, a_signed); + sig_b.extend_u0(sig_y.width, b_signed); + } else { + sig_a.extend(sig_y.width, a_signed); + sig_b.extend(sig_y.width, b_signed); + } + + std::vector bits_a = sig_a, bits_b = sig_b, bits_y = sig_y; + + enum { GRP_DYN, GRP_CONST_A, GRP_CONST_B, GRP_CONST_AB, GRP_N }; + std::map, std::set> grouped_bits[GRP_N]; + + for (int i = 0; i < SIZE(bits_y); i++) + { + int group_idx = GRP_DYN; + RTLIL::SigBit bit_a = bits_a[i], bit_b = bits_b[i]; + + if (bit_a.wire == NULL && bit_b.wire == NULL) + group_idx = GRP_CONST_AB; + else if (bit_a.wire == NULL) + group_idx = GRP_CONST_A; + else if (bit_b.wire == NULL && commutative) + group_idx = GRP_CONST_A, std::swap(bit_a, bit_b); + else if (bit_b.wire == NULL) + group_idx = GRP_CONST_B; + + grouped_bits[group_idx][std::pair(bit_a, bit_b)].insert(bits_y[i]); + } + + for (int i = 0; i < GRP_N; i++) + if (SIZE(grouped_bits[i]) == SIZE(bits_y)) + return false; + + log("Replacing %s cell `%s' in module `%s' with cells using grouped bits:\n", + log_id(cell->type), log_id(cell), log_id(module)); + + for (int i = 0; i < GRP_N; i++) + { + if (grouped_bits[i].empty()) + continue; + + RTLIL::Wire *new_y = module->addWire(NEW_ID, SIZE(grouped_bits[i])); + RTLIL::SigSpec new_a, new_b; + RTLIL::SigSig new_conn; + + for (auto &it : grouped_bits[i]) { + for (auto &bit : it.second) { + new_conn.first.append_bit(bit); + new_conn.second.append_bit(RTLIL::SigBit(new_y, new_a.width)); + } + new_a.append_bit(it.first.first); + new_b.append_bit(it.first.second); + } + + RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); + + c->connections["\\A"] = new_a; + c->parameters["\\A_WIDTH"] = new_a.width; + c->parameters["\\A_SIGNED"] = false; + + if (b_name == "\\B") { + c->connections["\\B"] = new_b; + c->parameters["\\B_WIDTH"] = new_b.width; + c->parameters["\\B_SIGNED"] = false; + } + + c->connections["\\Y"] = new_y; + c->parameters["\\Y_WIDTH"] = new_y->width; + c->check(); + + module->connections.push_back(new_conn); + + log(" New cell `%s': A=%s", log_id(c), log_signal(new_a)); + if (b_name == "\\B") + log(", B=%s", log_signal(new_b)); + log("\n"); + } + + module->remove(cell); + OPT_DID_SOMETHING = true; + did_something = true; + return true; +} + +static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine) { if (!design->selected(module)) return; @@ -108,6 +204,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons #define ACTION_DO(_p_, _s_) do { replace_cell(module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO_Y(_v_) ACTION_DO("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) + if (do_fine && (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || + cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor")) + if (group_cell_inputs(module, cell, true, cell->type != "$pos", assign_map)) + goto next_cell; + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].width == 1 && invert_map.count(assign_map(cell->connections["\\A"])) != 0) { replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections["\\A"]))); @@ -573,12 +674,16 @@ struct OptConstPass : public Pass { log(" -undriven\n"); log(" replace undriven nets with undef (x) constants\n"); log("\n"); + log(" -fine\n"); + log(" perform fine-grain optimizations\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { bool mux_undef = false; bool mux_bool = false; bool undriven = false; + bool do_fine = false; log_header("Executing OPT_CONST pass (perform const folding).\n"); log_push(); @@ -597,6 +702,10 @@ struct OptConstPass : public Pass { undriven = true; continue; } + if (args[argidx] == "-fine") { + do_fine = true; + continue; + } break; } extra_args(args, argidx, design); @@ -609,9 +718,9 @@ struct OptConstPass : public Pass { do { do { did_something = false; - replace_const_cells(design, mod_it.second, false, mux_undef, mux_bool); + replace_const_cells(design, mod_it.second, false, mux_undef, mux_bool, do_fine); } while (did_something); - replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool); + replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool, do_fine); } while (did_something); } diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index a0c7a027..93945e49 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -244,7 +244,7 @@ struct OptReduceWorker } } - OptReduceWorker(RTLIL::Design *design, RTLIL::Module *module) : + OptReduceWorker(RTLIL::Design *design, RTLIL::Module *module, bool do_fine) : design(design), module(module), assign_map(module) { log(" Optimizing cells in module %s.\n", module->name.c_str()); @@ -318,7 +318,7 @@ struct OptReduceWorker // this optimization is to aggressive for most coarse-grain applications. // but we always want it for multiplexers driving write enable ports. - if (mem_wren_sigs.check_any(assign_map(cell->connections.at("\\Y")))) + if (do_fine || mem_wren_sigs.check_any(assign_map(cell->connections.at("\\Y")))) opt_mux_bits(cell); opt_mux(cell); @@ -333,7 +333,7 @@ struct OptReducePass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" opt_reduce [selection]\n"); + log(" opt_reduce [options] [selection]\n"); log("\n"); log("This pass performs two interlinked optimizations:\n"); log("\n"); @@ -343,17 +343,31 @@ struct OptReducePass : public Pass { log("2. it identifies duplicated inputs to MUXes and replaces them with a single\n"); log("input with the original control signals OR'ed together.\n"); log("\n"); + log(" -fine\n"); + log(" perform fine-grain optimizations\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { + bool do_fine = false; + log_header("Executing OPT_REDUCE pass (consolidate $*mux and $reduce_* inputs).\n"); - extra_args(args, 1, design); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-fine") { + do_fine = true; + continue; + } + break; + } + extra_args(args, argidx, design); int total_count = 0; for (auto &mod_it : design->modules) { if (!design->selected(mod_it.second)) continue; - OptReduceWorker worker(design, mod_it.second); + OptReduceWorker worker(design, mod_it.second, do_fine); total_count += worker.total_count; } diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 266691a6..c383e19f 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -129,7 +129,7 @@ do test_passes -p "verific -vlog2k $fn; verific -import -gates -all; opt; memory;;" else test_passes -f "$frontend" -p "hierarchy; proc; opt; memory -nomap; opt; fsm; opt" $fn - test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt; techmap; opt; abc -dff; opt" $fn + test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt -fine; techmap; opt; abc -dff; opt" $fn fi touch ../${bn}.log } From 1873480ca5f5ec9ec6aa1b80b91ae047a6982002 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 17:19:50 +0200 Subject: [PATCH 352/750] Added mul to mux conversion to "opt_const -fine" --- passes/opt/opt_const.cc | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index a17ca679..4cfee59d 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -647,6 +647,61 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo ACTION_DO("\\Y", cell->connections["\\A"]); } + if (do_fine && cell->type == "$mul") + { + bool a_signed = cell->parameters["\\A_SIGNED"].as_bool(); + bool b_signed = cell->parameters["\\B_SIGNED"].as_bool(); + bool swapped_ab = false; + + RTLIL::SigSpec sig_a = assign_map(cell->connections["\\A"]); + RTLIL::SigSpec sig_b = assign_map(cell->connections["\\B"]); + RTLIL::SigSpec sig_y = assign_map(cell->connections["\\Y"]); + + if (sig_b.is_fully_const() && sig_b.width <= 32) + std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; + + if (sig_a.is_fully_def() && sig_a.width <= 32) + { + int a_val = sig_a.as_int(); + + if (a_val == 0) + { + log("Replacing multiply-by-zero cell `%s' in module `%s' with zero-driver.\n", + cell->name.c_str(), module->name.c_str()); + + module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.width))); + module->remove(cell); + + OPT_DID_SOMETHING = true; + did_something = true; + goto next_cell; + } + + for (int i = 0; i < sig_a.width - (a_signed ? 1 : 0); i++) + if (a_val == (1 << i)) + { + log("Replacing multiply-by-%d cell `%s' in module `%s' with shift-by-%d.\n", + a_val, cell->name.c_str(), module->name.c_str(), i); + + if (swapped_ab) { + cell->connections["\\A"] = cell->connections["\\B"]; + cell->parameters["\\A_WIDTH"] = cell->parameters["\\B_WIDTH"]; + cell->parameters["\\A_SIGNED"] = cell->parameters["\\B_SIGNED"]; + } + + cell->type = "$shl"; + cell->parameters["\\B_WIDTH"] = 6; + cell->parameters["\\B_SIGNED"] = false; + cell->connections["\\B"] = RTLIL::SigSpec(i, 6); + cell->check(); + + OPT_DID_SOMETHING = true; + did_something = true; + goto next_cell; + } + } + } + next_cell:; #undef ACTION_DO #undef ACTION_DO_Y From 137dbf3cf7edbec8c31dfdb2c9c0bcc413c5786d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 21:38:55 +0200 Subject: [PATCH 353/750] Added "opt_const -keepdc" --- passes/opt/opt.cc | 13 ++- passes/opt/opt_const.cc | 170 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 168 insertions(+), 15 deletions(-) diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index 62aa48be..33e1507b 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -31,7 +31,7 @@ struct OptPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" opt [-purge] [-mux_undef] [-mux_bool] [-undriven] [-fine] [selection]\n"); + log(" opt [options] [selection]\n"); log("\n"); log("This pass calls all the other opt_* passes in a useful order. This performs\n"); log("a series of trivial optimizations and cleanups. This pass executes the other\n"); @@ -46,8 +46,11 @@ struct OptPass : public Pass { log(" opt_share\n"); log(" opt_rmdff\n"); log(" opt_clean [-purge]\n"); - log(" opt_const [-mux_undef] [-mux_bool] [-undriven] [-fine]\n"); - log(" while [changed design]\n"); + log(" opt_const [-mux_undef] [-mux_bool] [-undriven] [-fine] [-keepdc]\n"); + log(" while \n"); + log("\n"); + log("Note: Options in square brackets (such as [-keepdc]) are passed through to\n"); + log("the opt_* commands when given to 'opt'.\n"); log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) @@ -82,6 +85,10 @@ struct OptPass : public Pass { opt_reduce_args += " -fine"; continue; } + if (args[argidx] == "-keepdc") { + opt_const_args += " -keepdc"; + continue; + } break; } extra_args(args, argidx, design); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 4cfee59d..e855e45e 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -74,6 +74,8 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { RTLIL::SigSpec Y = cell->connections[out_port]; + out_val.extend_u0(Y.width, false); + log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", cell->type.c_str(), cell->name.c_str(), info.c_str(), module->name.c_str(), log_signal(Y), log_signal(out_val)); @@ -114,6 +116,12 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com int group_idx = GRP_DYN; RTLIL::SigBit bit_a = bits_a[i], bit_b = bits_b[i]; + if (cell->type == "$or" && (bit_a == RTLIL::State::S1 || bit_b == RTLIL::State::S1)) + bit_a = bit_b = RTLIL::State::S1; + + if (cell->type == "$and" && (bit_a == RTLIL::State::S0 || bit_b == RTLIL::State::S0)) + bit_a = bit_b = RTLIL::State::S0; + if (bit_a.wire == NULL && bit_b.wire == NULL) group_idx = GRP_CONST_AB; else if (bit_a.wire == NULL) @@ -181,7 +189,7 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com return true; } -static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine) +static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc) { if (!design->selected(module)) return; @@ -204,10 +212,132 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo #define ACTION_DO(_p_, _s_) do { replace_cell(module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO_Y(_v_) ACTION_DO("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) - if (do_fine && (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || - cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor")) - if (group_cell_inputs(module, cell, true, cell->type != "$pos", assign_map)) + if (do_fine) + { + if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || + cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") + if (group_cell_inputs(module, cell, true, cell->type != "$pos", assign_map)) + goto next_cell; + + if (cell->type == "$reduce_and") + { + RTLIL::SigSpec sig_a = assign_map(cell->connections.at("\\A")); + + RTLIL::State new_a = RTLIL::State::S1; + for (auto &bit : sig_a.to_sigbit_vector()) + if (bit == RTLIL::State::Sx) { + if (new_a == RTLIL::State::S1) + new_a = RTLIL::State::Sx; + } else if (bit == RTLIL::State::S0) { + new_a = RTLIL::State::S0; + break; + } else if (bit.wire != NULL) { + new_a = RTLIL::State::Sm; + } + + if (new_a != RTLIL::State::Sm && RTLIL::SigSpec(new_a) != sig_a) { + log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", + cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); + cell->connections.at("\\A") = sig_a = new_a; + cell->parameters.at("\\A_WIDTH") = 1; + OPT_DID_SOMETHING = true; + did_something = true; + } + } + + if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") + { + RTLIL::SigSpec sig_a = assign_map(cell->connections.at("\\A")); + + RTLIL::State new_a = RTLIL::State::S0; + for (auto &bit : sig_a.to_sigbit_vector()) + if (bit == RTLIL::State::Sx) { + if (new_a == RTLIL::State::S0) + new_a = RTLIL::State::Sx; + } else if (bit == RTLIL::State::S1) { + new_a = RTLIL::State::S1; + break; + } else if (bit.wire != NULL) { + new_a = RTLIL::State::Sm; + } + + if (new_a != RTLIL::State::Sm && RTLIL::SigSpec(new_a) != sig_a) { + log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", + cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); + cell->connections.at("\\A") = sig_a = new_a; + cell->parameters.at("\\A_WIDTH") = 1; + OPT_DID_SOMETHING = true; + did_something = true; + } + } + + if (cell->type == "$logic_and" || cell->type == "$logic_or") + { + RTLIL::SigSpec sig_b = assign_map(cell->connections.at("\\B")); + + RTLIL::State new_b = RTLIL::State::S0; + for (auto &bit : sig_b.to_sigbit_vector()) + if (bit == RTLIL::State::Sx) { + if (new_b == RTLIL::State::S0) + new_b = RTLIL::State::Sx; + } else if (bit == RTLIL::State::S1) { + new_b = RTLIL::State::S1; + break; + } else if (bit.wire != NULL) { + new_b = RTLIL::State::Sm; + } + + if (new_b != RTLIL::State::Sm && RTLIL::SigSpec(new_b) != sig_b) { + log("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", + cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); + cell->connections.at("\\B") = sig_b = new_b; + cell->parameters.at("\\B_WIDTH") = 1; + OPT_DID_SOMETHING = true; + did_something = true; + } + } + } + + if (cell->type == "$logic_or" && (assign_map(cell->connections.at("\\A")) == RTLIL::State::S1 || assign_map(cell->connections.at("\\B")) == RTLIL::State::S1)) { + replace_cell(module, cell, "one high", "\\Y", RTLIL::State::S1); + goto next_cell; + } + + if (cell->type == "$logic_and" && (assign_map(cell->connections.at("\\A")) == RTLIL::State::S0 || assign_map(cell->connections.at("\\B")) == RTLIL::State::S0)) { + replace_cell(module, cell, "one low", "\\Y", RTLIL::State::S0); + goto next_cell; + } + + if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || + cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || + cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt" || + cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || + cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || cell->type == "$pow") + { + RTLIL::SigSpec sig_a = assign_map(cell->connections.at("\\A")); + RTLIL::SigSpec sig_b = cell->connections.count("\\B") ? assign_map(cell->connections.at("\\B")) : RTLIL::SigSpec(); + + if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") + sig_a = RTLIL::SigSpec(); + + for (auto &bit : sig_a.to_sigbit_vector()) + if (bit == RTLIL::State::Sx) + goto found_the_x_bit; + + for (auto &bit : sig_b.to_sigbit_vector()) + if (bit == RTLIL::State::Sx) + goto found_the_x_bit; + + if (0) { + found_the_x_bit: + if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || + cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") + replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); + else + replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections.at("\\Y").width)); goto next_cell; + } + } if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].width == 1 && invert_map.count(assign_map(cell->connections["\\A"])) != 0) { @@ -389,7 +519,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } } - // checking for simple identities + if (!keepdc) { bool identity_bu0 = false; bool identity_wrt_a = false; @@ -647,7 +777,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo ACTION_DO("\\Y", cell->connections["\\A"]); } - if (do_fine && cell->type == "$mul") + if (!keepdc && cell->type == "$mul") { bool a_signed = cell->parameters["\\A_SIGNED"].as_bool(); bool b_signed = cell->parameters["\\B_SIGNED"].as_bool(); @@ -677,22 +807,27 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - for (int i = 0; i < sig_a.width - (a_signed ? 1 : 0); i++) + for (int i = 1; i < (a_signed ? sig_a.width-1 : sig_a.width); i++) if (a_val == (1 << i)) { log("Replacing multiply-by-%d cell `%s' in module `%s' with shift-by-%d.\n", a_val, cell->name.c_str(), module->name.c_str(), i); - if (swapped_ab) { + if (!swapped_ab) { cell->connections["\\A"] = cell->connections["\\B"]; cell->parameters["\\A_WIDTH"] = cell->parameters["\\B_WIDTH"]; cell->parameters["\\A_SIGNED"] = cell->parameters["\\B_SIGNED"]; } + std::vector new_b = RTLIL::SigSpec(i, 6); + + while (SIZE(new_b) > 1 && new_b.back() == RTLIL::State::S0) + new_b.pop_back(); + cell->type = "$shl"; - cell->parameters["\\B_WIDTH"] = 6; + cell->parameters["\\B_WIDTH"] = SIZE(new_b); cell->parameters["\\B_SIGNED"] = false; - cell->connections["\\B"] = RTLIL::SigSpec(i, 6); + cell->connections["\\B"] = new_b; cell->check(); OPT_DID_SOMETHING = true; @@ -729,6 +864,12 @@ struct OptConstPass : public Pass { log(" -undriven\n"); log(" replace undriven nets with undef (x) constants\n"); log("\n"); + log(" -keepdc\n"); + log(" some optimizations change the behavior of the circuit with respect to\n"); + log(" don't-care bits. for example in 'a+0' a single x-bit in 'a' will cause\n"); + log(" all result bits to be set to x. this behavior changes when 'a+0' is\n"); + log(" replaced by 'a'. the -keepdc option disables all such optimizations.\n"); + log("\n"); log(" -fine\n"); log(" perform fine-grain optimizations\n"); log("\n"); @@ -739,6 +880,7 @@ struct OptConstPass : public Pass { bool mux_bool = false; bool undriven = false; bool do_fine = false; + bool keepdc = false; log_header("Executing OPT_CONST pass (perform const folding).\n"); log_push(); @@ -761,6 +903,10 @@ struct OptConstPass : public Pass { do_fine = true; continue; } + if (args[argidx] == "-keepdc") { + keepdc = true; + continue; + } break; } extra_args(args, argidx, design); @@ -773,9 +919,9 @@ struct OptConstPass : public Pass { do { do { did_something = false; - replace_const_cells(design, mod_it.second, false, mux_undef, mux_bool, do_fine); + replace_const_cells(design, mod_it.second, false, mux_undef, mux_bool, do_fine, keepdc); } while (did_something); - replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool, do_fine); + replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool, do_fine, keepdc); } while (did_something); } From 0229d68fc97276477b96cef4e2ba8604851ea9c6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 21:39:59 +0200 Subject: [PATCH 354/750] Use "opt -fine" in test/vloght/test_mapopt.sh --- tests/vloghtb/common.sh | 3 ++- tests/vloghtb/test_mapopt.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/vloghtb/common.sh b/tests/vloghtb/common.sh index 704afdd9..1c60d794 100644 --- a/tests/vloghtb/common.sh +++ b/tests/vloghtb/common.sh @@ -28,7 +28,8 @@ test_equiv() $2 cd .. - miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold work miter + miter -equiv -ignore_gold_x -make_outputs -make_outcmp gold work miter + flatten miter sat $3 -verify -prove trigger 0 -show-inputs -show-outputs miter EOT then diff --git a/tests/vloghtb/test_mapopt.sh b/tests/vloghtb/test_mapopt.sh index 9099e2b7..ad8b3ef6 100644 --- a/tests/vloghtb/test_mapopt.sh +++ b/tests/vloghtb/test_mapopt.sh @@ -6,6 +6,6 @@ source common.sh f=$1 n=$(basename ${f%.v}) -test_equiv mapopt "opt; techmap; opt" "-set-def-inputs" $n $f +test_equiv mapopt "opt -fine; techmap; opt" "-set-def-inputs" $n $f exit 0 From d6d0e08834560e824cc59027b720401a1c0b1fc7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:18:05 +0200 Subject: [PATCH 355/750] Fixed make rules for ilang parser --- frontends/ilang/Makefile.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc index 07ebf085..f81c8de9 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 From 3b5f4ff39c94a5a664043f35b95a50240ffe9d12 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:35:58 +0200 Subject: [PATCH 356/750] Fixed ilang parsing of process attributes --- frontends/ilang/parser.y | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index d8ecf37b..cb438775 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; From a233762a815fc180b371f699e865a7d7aed77bca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 19:56:17 +0200 Subject: [PATCH 357/750] SigSpec refactoring: renamed chunks and width to __chunks and __width --- backends/autotest/autotest.cc | 4 +- backends/blif/blif.cc | 24 +- backends/btor/btor.cc | 80 +++--- backends/edif/edif.cc | 20 +- backends/ilang/ilang_backend.cc | 8 +- backends/intersynth/intersynth.cc | 24 +- backends/spice/spice.cc | 22 +- backends/verilog/verilog_backend.cc | 58 ++--- frontends/ast/genrtlil.cc | 120 ++++----- frontends/ilang/parser.y | 28 +- frontends/liberty/liberty.cc | 16 +- kernel/bitpattern.h | 12 +- kernel/consteval.h | 18 +- kernel/rtlil.cc | 386 ++++++++++++++-------------- kernel/rtlil.h | 11 +- kernel/satgen.h | 14 +- kernel/sigtools.h | 50 ++-- passes/abc/abc.cc | 68 ++--- passes/abc/blifparse.cc | 10 +- passes/cmds/connect.cc | 2 +- passes/cmds/connwrappers.cc | 8 +- passes/cmds/delete.cc | 2 +- passes/cmds/scatter.cc | 2 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 2 +- passes/cmds/setundef.cc | 4 +- passes/cmds/show.cc | 34 +-- passes/cmds/splice.cc | 18 +- passes/cmds/splitnets.cc | 4 +- passes/fsm/fsm_detect.cc | 4 +- passes/fsm/fsm_expand.cc | 18 +- passes/fsm/fsm_extract.cc | 38 +-- passes/fsm/fsm_map.cc | 30 +-- passes/fsm/fsm_opt.cc | 18 +- passes/fsm/fsmdata.h | 8 +- passes/hierarchy/hierarchy.cc | 4 +- passes/hierarchy/submod.cc | 4 +- passes/memory/memory_collect.cc | 32 +-- passes/memory/memory_dff.cc | 12 +- passes/memory/memory_map.cc | 8 +- passes/memory/memory_share.cc | 12 +- passes/opt/opt_clean.cc | 28 +- passes/opt/opt_const.cc | 92 +++---- passes/opt/opt_muxtree.cc | 14 +- passes/opt/opt_reduce.cc | 28 +- passes/opt/opt_rmdff.cc | 14 +- passes/opt/opt_share.cc | 2 +- passes/proc/proc_arst.cc | 18 +- passes/proc/proc_clean.cc | 8 +- passes/proc/proc_dff.cc | 82 +++--- passes/proc/proc_init.cc | 12 +- passes/proc/proc_mux.cc | 44 ++-- passes/sat/eval.cc | 66 ++--- passes/sat/expose.cc | 2 +- passes/sat/freduce.cc | 2 +- passes/sat/miter.cc | 8 +- passes/sat/sat.cc | 46 ++-- passes/sat/share.cc | 44 ++-- passes/techmap/extract.cc | 24 +- passes/techmap/hilomap.cc | 2 +- passes/techmap/simplemap.cc | 112 ++++---- passes/techmap/techmap.cc | 18 +- 62 files changed, 954 insertions(+), 951 deletions(-) diff --git a/backends/autotest/autotest.cc b/backends/autotest/autotest.cc index 3e2fab00..e7fbfe7a 100644 --- a/backends/autotest/autotest.cc +++ b/backends/autotest/autotest.cc @@ -119,8 +119,8 @@ static void autotest(FILE *f, RTLIL::Design *design) if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1) continue; RTLIL::SigSpec &signal = (*it4)->signal; - for (size_t i = 0; i < signal.chunks.size(); i++) { - if (signal.chunks[i].wire == wire) + for (size_t i = 0; i < signal.__chunks.size(); i++) { + if (signal.__chunks[i].wire == wire) is_clksignal = true; } } diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 498f1351..2d446610 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -71,18 +71,18 @@ struct BlifDumper const char *cstr(RTLIL::SigSpec sig) { sig.optimize(); - log_assert(sig.width == 1); + log_assert(sig.__width == 1); - if (sig.chunks.at(0).wire == NULL) - return sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S1 ? "$true" : "$false"; + if (sig.__chunks.at(0).wire == NULL) + return sig.__chunks.at(0).data.bits.at(0) == RTLIL::State::S1 ? "$true" : "$false"; - std::string str = RTLIL::unescape_id(sig.chunks.at(0).wire->name); + std::string str = RTLIL::unescape_id(sig.__chunks.at(0).wire->name); for (size_t i = 0; i < str.size(); i++) if (str[i] == '#' || str[i] == '=') str[i] = '?'; - if (sig.chunks.at(0).wire->width != 1) - str += stringf("[%d]", sig.chunks.at(0).offset); + if (sig.__chunks.at(0).wire->width != 1) + str += stringf("[%d]", sig.__chunks.at(0).offset); cstr_buf.push_back(str); return cstr_buf.back().c_str(); @@ -194,12 +194,12 @@ struct BlifDumper fprintf(f, ".names"); auto &inputs = cell->connections.at("\\I"); auto width = cell->parameters.at("\\WIDTH").as_int(); - log_assert(inputs.width == width); - for (int i = 0; i < inputs.width; i++) { + log_assert(inputs.__width == width); + for (int i = 0; i < inputs.__width; i++) { fprintf(f, " %s", cstr(inputs.extract(i, 1))); } auto &output = cell->connections.at("\\O"); - log_assert(output.width == 1); + log_assert(output.__width == 1); fprintf(f, " %s", cstr(output)); fprintf(f, "\n"); auto mask = cell->parameters.at("\\LUT").as_string(); @@ -215,8 +215,8 @@ struct BlifDumper fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type)); for (auto &conn : cell->connections) - for (int i = 0; i < conn.second.width; i++) { - if (conn.second.width == 1) + for (int i = 0; i < conn.second.__width; i++) { + if (conn.second.__width == 1) fprintf(f, " %s", cstr(conn.first)); else fprintf(f, " %s[%d]", cstr(conn.first), i); @@ -244,7 +244,7 @@ struct BlifDumper } for (auto &conn : module->connections) - for (int i = 0; i < conn.first.width; i++) + for (int i = 0; i < conn.first.__width; i++) if (config->conn_mode) fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); else if (!config->buf_type.empty()) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 45f7b414..428e9a88 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -196,7 +196,7 @@ struct BtorDumper RTLIL::SigSpec* cell_output = get_cell_output(cell); int cell_line = dump_cell(cell); - if(dep_set.size()==1 && wire->width == cell_output->width) + if(dep_set.size()==1 && wire->width == cell_output->__width) { wire_line = cell_line; break; @@ -205,17 +205,17 @@ struct BtorDumper { int prev_wire_line=0; //previously dumped wire line int start_bit=0; - for(unsigned j=0; jchunks.size(); ++j) + for(unsigned j=0; j__chunks.size(); ++j) { - start_bit+=cell_output->chunks[j].width; - if(cell_output->chunks[j].wire->name == wire->name) + start_bit+=cell_output->__chunks[j].width; + if(cell_output->__chunks[j].wire->name == wire->name) { prev_wire_line = wire_line; wire_line = ++line_num; - str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks[j].width, - cell_line, start_bit-1, start_bit-cell_output->chunks[j].width); + str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->__chunks[j].width, + cell_line, start_bit-1, start_bit-cell_output->__chunks[j].width); fprintf(f, "%s\n", str.c_str()); - wire_width += cell_output->chunks[j].width; + wire_width += cell_output->__chunks[j].width; if(prev_wire_line!=0) { ++line_num; @@ -231,7 +231,7 @@ struct BtorDumper { log(" - checking sigmap\n"); RTLIL::SigSpec s = RTLIL::SigSpec(wire); - wire_line = dump_sigspec(&s, s.width); + wire_line = dump_sigspec(&s, s.__width); line_ref[wire->name]=wire_line; } line_ref[wire->name]=wire_line; @@ -320,21 +320,21 @@ struct BtorDumper auto it = sig_ref.find(s); if(it == std::end(sig_ref)) { - if (s.chunks.size() == 1) + if (s.__chunks.size() == 1) { - l = dump_sigchunk(&s.chunks[0]); + l = dump_sigchunk(&s.__chunks[0]); } else { int l1, l2, w1, w2; - l1 = dump_sigchunk(&s.chunks[0]); + l1 = dump_sigchunk(&s.__chunks[0]); log_assert(l1>0); - w1 = s.chunks[0].width; - for (unsigned i=1; i < s.chunks.size(); ++i) + w1 = s.__chunks[0].width; + for (unsigned i=1; i < s.__chunks.size(); ++i) { - l2 = dump_sigchunk(&s.chunks[i]); + l2 = dump_sigchunk(&s.__chunks[i]); log_assert(l2>0); - w2 = s.chunks[i].width; + w2 = s.__chunks[i].width; ++line_num; str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); fprintf(f, "%s\n", str.c_str()); @@ -350,22 +350,22 @@ struct BtorDumper l = it->second; } - if (expected_width != s.width) + if (expected_width != s.__width) { log(" - changing width of sigspec\n"); //TODO: this block may not be needed anymore, due to explicit type conversion by "splice" command - if(expected_width > s.width) + if(expected_width > s.__width) { //TODO: case the signal is signed ++line_num; - str = stringf ("%d zero %d", line_num, expected_width - s.width); + str = stringf ("%d zero %d", line_num, expected_width - s.__width); fprintf(f, "%s\n", str.c_str()); ++line_num; str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l); fprintf(f, "%s\n", str.c_str()); l = line_num; } - else if(expected_width < s.width) + else if(expected_width < s.__width) { ++line_num; str = stringf ("%d slice %d %d %d %d;3", line_num, expected_width, l, expected_width-1, 0); @@ -389,8 +389,8 @@ struct BtorDumper log("writing assert cell - %s\n", cstr(cell->type)); const RTLIL::SigSpec* expr = &cell->connections.at(RTLIL::IdString("\\A")); const RTLIL::SigSpec* en = &cell->connections.at(RTLIL::IdString("\\EN")); - log_assert(expr->width == 1); - log_assert(en->width == 1); + log_assert(expr->__width == 1); + log_assert(en->__width == 1); int expr_line = dump_sigspec(expr, 1); int en_line = dump_sigspec(en, 1); int one_line = ++line_num; @@ -649,13 +649,13 @@ struct BtorDumper const RTLIL::SigSpec* cell_output = &cell->connections.at(RTLIL::IdString("\\Q")); int value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\D")), output_width); unsigned start_bit = 0; - for(unsigned i=0; ichunks.size(); ++i) + for(unsigned i=0; i__chunks.size(); ++i) { - output_width = cell_output->chunks[i].width; - log_assert( output_width == cell_output->chunks[i].wire->width);//full reg is given the next value - int reg = dump_wire(cell_output->chunks[i].wire);//register + output_width = cell_output->__chunks[i].width; + log_assert( output_width == cell_output->__chunks[i].wire->width);//full reg is given the next value + int reg = dump_wire(cell_output->__chunks[i].wire);//register int slice = value; - if(cell_output->chunks.size()>1) + if(cell_output->__chunks.size()>1) { start_bit+=output_width; slice = ++line_num; @@ -759,11 +759,11 @@ struct BtorDumper log("writing slice cell\n"); const RTLIL::SigSpec* input = &cell->connections.at(RTLIL::IdString("\\A")); int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); - log_assert(input->width == input_width); + log_assert(input->__width == input_width); int input_line = dump_sigspec(input, input_width); const RTLIL::SigSpec* output = &cell->connections.at(RTLIL::IdString("\\Y")); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - log_assert(output->width == output_width); + log_assert(output->__width == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); ++line_num; str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, input_line, output_width+offset-1, offset); @@ -775,11 +775,11 @@ struct BtorDumper log("writing concat cell\n"); const RTLIL::SigSpec* input_a = &cell->connections.at(RTLIL::IdString("\\A")); int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); - log_assert(input_a->width == input_a_width); + log_assert(input_a->__width == input_a_width); int input_a_line = dump_sigspec(input_a, input_a_width); const RTLIL::SigSpec* input_b = &cell->connections.at(RTLIL::IdString("\\B")); int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); - log_assert(input_b->width == input_b_width); + log_assert(input_b->__width == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); ++line_num; str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), input_a_width+input_b_width, @@ -843,11 +843,11 @@ struct BtorDumper log(" - %s\n", cstr(it->second->type)); if (cell->type == "$memrd") { - for(unsigned i=0; ichunks.size(); ++i) + for(unsigned i=0; i__chunks.size(); ++i) { - RTLIL::Wire *w = output_sig->chunks[i].wire; + RTLIL::Wire *w = output_sig->__chunks[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->__chunks[i])); } } else if(cell->type == "$memwr") @@ -856,22 +856,22 @@ struct BtorDumper } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - RTLIL::IdString wire_id = output_sig->chunks[0].wire->name; - for(unsigned i=0; ichunks.size(); ++i) + RTLIL::IdString wire_id = output_sig->__chunks[0].wire->name; + for(unsigned i=0; i__chunks.size(); ++i) { - RTLIL::Wire *w = output_sig->chunks[i].wire; + RTLIL::Wire *w = output_sig->__chunks[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->__chunks[i])); basic_wires[wire_id] = true; } } else { - for(unsigned i=0; ichunks.size(); ++i) + for(unsigned i=0; i__chunks.size(); ++i) { - RTLIL::Wire *w = output_sig->chunks[i].wire; + RTLIL::Wire *w = output_sig->__chunks[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->__chunks[i])); } } } diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 8ac7cc7b..c239ef30 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -149,7 +149,7 @@ struct EdifBackend : public Backend { if (!design->modules.count(cell->type) || design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) { lib_cell_ports[cell->type]; for (auto p : cell->connections) { - if (p.second.width > 1) + if (p.second.__width > 1) log_error("Found multi-bit port %s on library cell %s.%s (%s): not supported in EDIF backend!\n", RTLIL::id2cstr(p.first), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); lib_cell_ports[cell->type].insert(p.first); @@ -307,9 +307,9 @@ struct EdifBackend : public Backend { for (auto &p : cell->connections) { RTLIL::SigSpec sig = sigmap(p.second); sig.expand(); - for (int i = 0; i < sig.width; i++) { - RTLIL::SigSpec sigbit(sig.chunks.at(i)); - if (sig.width == 1) + for (int i = 0; i < sig.__width; i++) { + RTLIL::SigSpec sigbit(sig.__chunks.at(i)); + if (sig.__width == 1) net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name))); else net_join_db[sigbit].insert(stringf("(portRef (member %s %d) (instanceRef %s))", EDIF_REF(p.first), i, EDIF_REF(cell->name))); @@ -319,9 +319,9 @@ struct EdifBackend : public Backend { for (auto &it : net_join_db) { RTLIL::SigSpec sig = it.first; sig.optimize(); - log_assert(sig.width == 1); - if (sig.chunks.at(0).wire == NULL) { - if (sig.chunks.at(0).data.bits.at(0) != RTLIL::State::S0 && sig.chunks.at(0).data.bits.at(0) != RTLIL::State::S1) + log_assert(sig.__width == 1); + if (sig.__chunks.at(0).wire == NULL) { + if (sig.__chunks.at(0).data.bits.at(0) != RTLIL::State::S0 && sig.__chunks.at(0).data.bits.at(0) != RTLIL::State::S1) continue; } std::string netname = log_signal(sig); @@ -331,10 +331,10 @@ struct EdifBackend : public Backend { fprintf(f, " (net %s (joined\n", EDIF_DEF(netname)); for (auto &ref : it.second) fprintf(f, " %s\n", ref.c_str()); - if (sig.chunks.at(0).wire == NULL) { - if (sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S0) + if (sig.__chunks.at(0).wire == NULL) { + if (sig.__chunks.at(0).data.bits.at(0) == RTLIL::State::S0) fprintf(f, " (portRef G (instanceRef GND))\n"); - if (sig.chunks.at(0).data.bits.at(0) == RTLIL::State::S1) + if (sig.__chunks.at(0).data.bits.at(0) == RTLIL::State::S1) fprintf(f, " (portRef P (instanceRef VCC))\n"); } fprintf(f, " ))\n"); diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index eaad7869..e1a8bfd4 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -102,11 +102,11 @@ void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool au void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint) { - if (sig.chunks.size() == 1) { - dump_sigchunk(f, sig.chunks[0], autoint); + if (sig.__chunks.size() == 1) { + dump_sigchunk(f, sig.__chunks[0], autoint); } else { fprintf(f, "{ "); - for (auto it = sig.chunks.rbegin(); it != sig.chunks.rend(); it++) { + for (auto it = sig.__chunks.rbegin(); it != sig.__chunks.rend(); it++) { dump_sigchunk(f, *it, false); fprintf(f, " "); } @@ -314,7 +314,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module if (only_selected) { RTLIL::SigSpec sigs = it->first; sigs.append(it->second); - for (auto &c : sigs.chunks) { + for (auto &c : sigs.__chunks) { if (c.wire == NULL || !design->selected(module, c.wire)) continue; show_conn = true; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 47c1125f..049a2ce8 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -30,23 +30,23 @@ static std::string netname(std::set &conntypes_code, std::setwidth) + if (sig.__chunks[0].offset != 0 || sig.__width != sig.__chunks[0].wire->width) goto error; - return RTLIL::unescape_id(sig.chunks[0].wire->name); + return RTLIL::unescape_id(sig.__chunks[0].wire->name); } struct IntersynthBackend : public Backend { @@ -177,9 +177,9 @@ struct IntersynthBackend : public Backend { node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); for (auto &port : cell->connections) { RTLIL::SigSpec sig = sigmap(port.second); - if (sig.width != 0) { - conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.width, sig.width, sig.width)); - celltype_code += stringf(" b%d %s%s", sig.width, ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first)); + if (sig.__width != 0) { + conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.__width, sig.__width, sig.__width)); + celltype_code += stringf(" b%d %s%s", sig.__width, ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first)); node_code += stringf(" %s %s", RTLIL::id2cstr(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str()); } } diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index e7926e90..c7f832c6 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -27,16 +27,16 @@ static void print_spice_net(FILE *f, RTLIL::SigSpec s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) { - log_assert(s.chunks.size() == 1 && s.chunks[0].width == 1); - if (s.chunks[0].wire) { - if (s.chunks[0].wire->width > 1) - fprintf(f, " %s[%d]", RTLIL::id2cstr(s.chunks[0].wire->name), s.chunks[0].offset); + log_assert(s.__chunks.size() == 1 && s.__chunks[0].width == 1); + if (s.__chunks[0].wire) { + if (s.__chunks[0].wire->width > 1) + fprintf(f, " %s[%d]", RTLIL::id2cstr(s.__chunks[0].wire->name), s.__chunks[0].offset); else - fprintf(f, " %s", RTLIL::id2cstr(s.chunks[0].wire->name)); + fprintf(f, " %s", RTLIL::id2cstr(s.__chunks[0].wire->name)); } else { - if (s.chunks[0].data.bits.at(0) == RTLIL::State::S0) + if (s.__chunks[0].data.bits.at(0) == RTLIL::State::S0) fprintf(f, " %s", neg.c_str()); - else if (s.chunks[0].data.bits.at(0) == RTLIL::State::S1) + else if (s.__chunks[0].data.bits.at(0) == RTLIL::State::S1) fprintf(f, " %s", pos.c_str()); else fprintf(f, " %s%d", ncpf.c_str(), nc_counter++); @@ -90,9 +90,9 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de } for (auto &sig : port_sigs) { - for (int i = 0; i < sig.width; i++) { - RTLIL::SigSpec s = sig.extract(big_endian ? sig.width - 1 - i : i, 1); - log_assert(s.chunks.size() == 1 && s.chunks[0].width == 1); + for (int i = 0; i < sig.__width; i++) { + RTLIL::SigSpec s = sig.extract(big_endian ? sig.__width - 1 - i : i, 1); + log_assert(s.__chunks.size() == 1 && s.__chunks[0].width == 1); print_spice_net(f, s, neg, pos, ncpf, nc_counter); } } @@ -101,7 +101,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de } for (auto &conn : module->connections) - for (int i = 0; i < conn.first.width; i++) { + for (int i = 0; i < conn.first.__width; i++) { fprintf(f, "V%d", conn_counter++); print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter); print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 80ad7cb9..6aeb5084 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -134,17 +134,17 @@ std::string id(std::string internal_id, bool may_rename = true) bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name) { sig.optimize(); - if (sig.chunks.size() != 1 || sig.chunks[0].wire == NULL) + if (sig.__chunks.size() != 1 || sig.__chunks[0].wire == NULL) return false; - if (reg_wires.count(sig.chunks[0].wire->name) == 0) + if (reg_wires.count(sig.__chunks[0].wire->name) == 0) return false; - reg_name = id(sig.chunks[0].wire->name); - if (sig.width != sig.chunks[0].wire->width) { - if (sig.width == 1) - reg_name += stringf("[%d]", sig.chunks[0].wire->start_offset + sig.chunks[0].offset); + reg_name = id(sig.__chunks[0].wire->name); + if (sig.__width != sig.__chunks[0].wire->width) { + if (sig.__width == 1) + reg_name += stringf("[%d]", sig.__chunks[0].wire->start_offset + sig.__chunks[0].offset); else - reg_name += stringf("[%d:%d]", sig.chunks[0].wire->start_offset + sig.chunks[0].offset + sig.chunks[0].width - 1, - sig.chunks[0].wire->start_offset + sig.chunks[0].offset); + reg_name += stringf("[%d:%d]", sig.__chunks[0].wire->start_offset + sig.__chunks[0].offset + sig.__chunks[0].width - 1, + sig.__chunks[0].wire->start_offset + sig.__chunks[0].offset); } return true; } @@ -221,12 +221,12 @@ void dump_sigchunk(FILE *f, RTLIL::SigChunk &chunk, bool no_decimal = false) void dump_sigspec(FILE *f, RTLIL::SigSpec &sig) { - if (sig.chunks.size() == 1) { - dump_sigchunk(f, sig.chunks[0]); + if (sig.__chunks.size() == 1) { + dump_sigchunk(f, sig.__chunks[0]); } else { fprintf(f, "{ "); - for (auto it = sig.chunks.rbegin(); it != sig.chunks.rend(); it++) { - if (it != sig.chunks.rbegin()) + for (auto it = sig.__chunks.rbegin(); it != sig.__chunks.rend(); it++) { + if (it != sig.__chunks.rbegin()) fprintf(f, ", "); dump_sigchunk(f, *it, true); } @@ -300,11 +300,11 @@ std::string cellname(RTLIL::Cell *cell) if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections.count("\\Q") > 0) { RTLIL::SigSpec sig = cell->connections["\\Q"]; - if (sig.width != 1 || sig.is_fully_const()) + if (sig.__width != 1 || sig.is_fully_const()) goto no_special_reg_name; sig.optimize(); - RTLIL::Wire *wire = sig.chunks[0].wire; + RTLIL::Wire *wire = sig.__chunks[0].wire; if (wire->name[0] != '\\') goto no_special_reg_name; @@ -318,7 +318,7 @@ std::string cellname(RTLIL::Cell *cell) cell_name = cell_name + "_reg"; if (wire->width != 1) - cell_name += stringf("[%d]", wire->start_offset + sig.chunks[0].offset); + cell_name += stringf("[%d]", wire->start_offset + sig.__chunks[0].offset); if (active_module && active_module->count_id(cell_name) > 0) goto no_special_reg_name; @@ -532,7 +532,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$pmux_safe") { int width = cell->parameters["\\WIDTH"].as_int(); - int s_width = cell->connections["\\S"].width; + int s_width = cell->connections["\\S"].__width; std::string func_name = cellname(cell); fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); @@ -725,7 +725,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, ","); first_arg = false; fprintf(f, "\n%s .%s(", indent.c_str(), id(it->first).c_str()); - if (it->second.width > 0) + if (it->second.__width > 0) dump_sigspec(f, it->second); fprintf(f, ")"); } @@ -751,7 +751,7 @@ void dump_case_body(FILE *f, std::string indent, RTLIL::CaseRule *cs, bool omit_ fprintf(f, "%s" "begin\n", indent.c_str()); for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) { - if (it->first.width == 0) + if (it->first.__width == 0) continue; fprintf(f, "%s ", indent.c_str()); dump_sigspec(f, it->first); @@ -772,7 +772,7 @@ void dump_case_body(FILE *f, std::string indent, RTLIL::CaseRule *cs, bool omit_ void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw) { - if (sw->signal.width == 0) { + if (sw->signal.__width == 0) { fprintf(f, "%s" "begin\n", indent.c_str()); for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) { if ((*it)->compare.size() == 0) @@ -811,9 +811,9 @@ void case_body_find_regs(RTLIL::CaseRule *cs) case_body_find_regs(*it2); for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) { - for (size_t i = 0; i < it->first.chunks.size(); i++) - if (it->first.chunks[i].wire) - reg_wires.insert(it->first.chunks[i].wire->name); + for (size_t i = 0; i < it->first.__chunks.size(); i++) + if (it->first.__chunks[i].wire) + reg_wires.insert(it->first.__chunks[i].wire->name); } } @@ -823,9 +823,9 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r case_body_find_regs(&proc->root_case); for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++) for (auto it2 = (*it)->actions.begin(); it2 != (*it)->actions.end(); it2++) { - for (size_t i = 0; i < it2->first.chunks.size(); i++) - if (it2->first.chunks[i].wire) - reg_wires.insert(it2->first.chunks[i].wire->name); + for (size_t i = 0; i < it2->first.__chunks.size(); i++) + if (it2->first.__chunks[i].wire) + reg_wires.insert(it2->first.__chunks[i].wire->name); } return; } @@ -876,7 +876,7 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r } for (auto it = sync->actions.begin(); it != sync->actions.end(); it++) { - if (it->first.width == 0) + if (it->first.__width == 0) continue; fprintf(f, "%s ", indent.c_str()); dump_sigspec(f, it->first); @@ -911,9 +911,9 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) RTLIL::SigSpec sig = cell->connections["\\Q"]; sig.optimize(); - if (sig.chunks.size() == 1 && sig.chunks[0].wire) - for (int i = 0; i < sig.chunks[0].width; i++) - reg_bits.insert(std::pair(sig.chunks[0].wire, sig.chunks[0].offset+i)); + if (sig.__chunks.size() == 1 && sig.__chunks[0].wire) + for (int i = 0; i < sig.__chunks[0].width; i++) + reg_bits.insert(std::pair(sig.__chunks[0].wire, sig.__chunks[0].offset+i)); } for (auto &it : module->wires) { diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index a2fdcf8b..dc9f566c 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 cb438775..e6d3d4c5 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 9000d702..c449a593 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; diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index aaefa50f..0ca26bb3 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -31,16 +31,16 @@ struct BitPatternPool BitPatternPool(RTLIL::SigSpec sig) { - width = sig.width; + width = sig.__width; if (width > 0) { std::vector pattern(width); sig.optimize(); for (int i = 0; i < width; i++) { RTLIL::SigSpec s = sig.extract(i, 1); s.optimize(); - assert(s.chunks.size() == 1); - if (s.chunks[0].wire == NULL && s.chunks[0].data.bits[0] <= RTLIL::State::S1) - pattern[i] = s.chunks[0].data.bits[0]; + assert(s.__chunks.size() == 1); + if (s.__chunks[0].wire == NULL && s.__chunks[0].data.bits[0] <= RTLIL::State::S1) + pattern[i] = s.__chunks[0].data.bits[0]; else pattern[i] = RTLIL::State::Sa; } @@ -63,8 +63,8 @@ struct BitPatternPool { sig.optimize(); assert(sig.is_fully_const()); - assert(sig.chunks.size() == 1); - bits_t bits = sig.chunks[0].data.bits; + assert(sig.__chunks.size() == 1); + bits_t bits = sig.__chunks[0].data.bits; for (auto &b : bits) if (b > RTLIL::State::S1) b = RTLIL::State::Sa; diff --git a/kernel/consteval.h b/kernel/consteval.h index 10116ccf..fa079e14 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -72,8 +72,8 @@ struct ConstEval #ifndef NDEBUG RTLIL::SigSpec current_val = values_map(sig); current_val.expand(); - for (size_t i = 0; i < current_val.chunks.size(); i++) { - RTLIL::SigChunk &chunk = current_val.chunks[i]; + for (size_t i = 0; i < current_val.__chunks.size(); i++) { + RTLIL::SigChunk &chunk = current_val.__chunks[i]; assert(chunk.wire != NULL || chunk.data.bits[0] == value.bits[i]); } #endif @@ -113,10 +113,10 @@ struct ConstEval int count_maybe_set_s_bits = 0; int count_set_s_bits = 0; - for (int i = 0; i < sig_s.width; i++) + for (int i = 0; i < sig_s.__width; i++) { RTLIL::State s_bit = sig_s.extract(i, 1).as_const().bits.at(0); - RTLIL::SigSpec b_slice = sig_b.extract(sig_y.width*i, sig_y.width); + RTLIL::SigSpec b_slice = sig_b.extract(sig_y.__width*i, sig_y.__width); if (s_bit == RTLIL::State::Sx || s_bit == RTLIL::State::S1) y_candidates.push_back(b_slice); @@ -162,9 +162,9 @@ struct ConstEval } else { - if (sig_a.width > 0 && !eval(sig_a, undef, cell)) + if (sig_a.__width > 0 && !eval(sig_a, undef, cell)) return false; - if (sig_b.width > 0 && !eval(sig_b, undef, cell)) + if (sig_b.__width > 0 && !eval(sig_b, undef, cell)) return false; set(sig_y, CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const())); } @@ -210,9 +210,9 @@ struct ConstEval if (sig.is_fully_const()) return true; - for (size_t i = 0; i < sig.chunks.size(); i++) - if (sig.chunks[i].wire != NULL) - undef.append(sig.chunks[i]); + for (size_t i = 0; i < sig.__chunks.size(); i++) + if (sig.__chunks[i].wire != NULL) + undef.append(sig.__chunks[i]); return false; } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d3d830d6..3a646dc6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -350,7 +350,7 @@ namespace { { if (cell->connections.count(name) == 0) error(__LINE__); - if (cell->connections.at(name).width != width) + if (cell->connections.at(name).__width != width) error(__LINE__); expected_ports.insert(name); } @@ -381,7 +381,7 @@ namespace { char portname[3] = { '\\', *p, 0 }; if (cell->connections.count(portname) == 0) error(__LINE__); - if (cell->connections.at(portname).width != 1) + if (cell->connections.at(portname).__width != 1) error(__LINE__); } @@ -755,7 +755,7 @@ void RTLIL::Module::check() } for (auto &it : connections) { - assert(it.first.width == it.second.width); + assert(it.first.__width == it.second.__width); it.first.check(); it.second.check(); } @@ -801,7 +801,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const RTLIL::Module *mod; void operator()(RTLIL::SigSpec &sig) { - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) if (c.wire != NULL) c.wire = mod->wires.at(c.wire->name); } @@ -891,8 +891,8 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) cell->name = name; \ cell->type = _type; \ cell->parameters["\\A_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.width; \ - cell->parameters["\\Y_WIDTH"] = sig_y.width; \ + cell->parameters["\\A_WIDTH"] = sig_a.__width; \ + cell->parameters["\\Y_WIDTH"] = sig_y.__width; \ cell->connections["\\A"] = sig_a; \ cell->connections["\\Y"] = sig_y; \ add(cell); \ @@ -903,10 +903,10 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) add ## _func(name, sig_a, sig_y, is_signed); \ return sig_y; \ } -DEF_METHOD(Not, sig_a.width, "$not") -DEF_METHOD(Pos, sig_a.width, "$pos") -DEF_METHOD(Bu0, sig_a.width, "$bu0") -DEF_METHOD(Neg, sig_a.width, "$neg") +DEF_METHOD(Not, sig_a.__width, "$not") +DEF_METHOD(Pos, sig_a.__width, "$pos") +DEF_METHOD(Bu0, sig_a.__width, "$bu0") +DEF_METHOD(Neg, sig_a.__width, "$neg") DEF_METHOD(ReduceAnd, 1, "$reduce_and") DEF_METHOD(ReduceOr, 1, "$reduce_or") DEF_METHOD(ReduceXor, 1, "$reduce_xor") @@ -922,9 +922,9 @@ DEF_METHOD(LogicNot, 1, "$logic_not") cell->type = _type; \ cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\B_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.width; \ - cell->parameters["\\B_WIDTH"] = sig_b.width; \ - cell->parameters["\\Y_WIDTH"] = sig_y.width; \ + cell->parameters["\\A_WIDTH"] = sig_a.__width; \ + cell->parameters["\\B_WIDTH"] = sig_b.__width; \ + cell->parameters["\\Y_WIDTH"] = sig_y.__width; \ cell->connections["\\A"] = sig_a; \ cell->connections["\\B"] = sig_b; \ cell->connections["\\Y"] = sig_y; \ @@ -936,14 +936,14 @@ DEF_METHOD(LogicNot, 1, "$logic_not") add ## _func(name, sig_a, sig_b, sig_y, is_signed); \ return sig_y; \ } -DEF_METHOD(And, std::max(sig_a.width, sig_b.width), "$and") -DEF_METHOD(Or, std::max(sig_a.width, sig_b.width), "$or") -DEF_METHOD(Xor, std::max(sig_a.width, sig_b.width), "$xor") -DEF_METHOD(Xnor, std::max(sig_a.width, sig_b.width), "$xnor") -DEF_METHOD(Shl, sig_a.width, "$shl") -DEF_METHOD(Shr, sig_a.width, "$shr") -DEF_METHOD(Sshl, sig_a.width, "$sshl") -DEF_METHOD(Sshr, sig_a.width, "$sshr") +DEF_METHOD(And, std::max(sig_a.__width, sig_b.__width), "$and") +DEF_METHOD(Or, std::max(sig_a.__width, sig_b.__width), "$or") +DEF_METHOD(Xor, std::max(sig_a.__width, sig_b.__width), "$xor") +DEF_METHOD(Xnor, std::max(sig_a.__width, sig_b.__width), "$xnor") +DEF_METHOD(Shl, sig_a.__width, "$shl") +DEF_METHOD(Shr, sig_a.__width, "$shr") +DEF_METHOD(Sshl, sig_a.__width, "$sshl") +DEF_METHOD(Sshr, sig_a.__width, "$sshr") DEF_METHOD(Lt, 1, "$lt") DEF_METHOD(Le, 1, "$le") DEF_METHOD(Eq, 1, "$eq") @@ -952,11 +952,11 @@ DEF_METHOD(Eqx, 1, "$eqx") DEF_METHOD(Nex, 1, "$nex") DEF_METHOD(Ge, 1, "$ge") DEF_METHOD(Gt, 1, "$gt") -DEF_METHOD(Add, std::max(sig_a.width, sig_b.width), "$add") -DEF_METHOD(Sub, std::max(sig_a.width, sig_b.width), "$sub") -DEF_METHOD(Mul, std::max(sig_a.width, sig_b.width), "$mul") -DEF_METHOD(Div, std::max(sig_a.width, sig_b.width), "$div") -DEF_METHOD(Mod, std::max(sig_a.width, sig_b.width), "$mod") +DEF_METHOD(Add, std::max(sig_a.__width, sig_b.__width), "$add") +DEF_METHOD(Sub, std::max(sig_a.__width, sig_b.__width), "$sub") +DEF_METHOD(Mul, std::max(sig_a.__width, sig_b.__width), "$mul") +DEF_METHOD(Div, std::max(sig_a.__width, sig_b.__width), "$div") +DEF_METHOD(Mod, std::max(sig_a.__width, sig_b.__width), "$mod") DEF_METHOD(LogicAnd, 1, "$logic_and") DEF_METHOD(LogicOr, 1, "$logic_or") #undef DEF_METHOD @@ -966,9 +966,9 @@ DEF_METHOD(LogicOr, 1, "$logic_or") RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->parameters["\\WIDTH"] = sig_a.width; \ - cell->parameters["\\WIDTH"] = sig_b.width; \ - if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.width; \ + cell->parameters["\\WIDTH"] = sig_a.__width; \ + cell->parameters["\\WIDTH"] = sig_b.__width; \ + if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.__width; \ cell->connections["\\A"] = sig_a; \ cell->connections["\\B"] = sig_b; \ cell->connections["\\S"] = sig_s; \ @@ -977,7 +977,7 @@ DEF_METHOD(LogicOr, 1, "$logic_or") return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.width); \ + RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.__width); \ add ## _func(name, sig_a, sig_b, sig_s, sig_y); \ return sig_y; \ } @@ -1050,9 +1050,9 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R cell->type = "$pow"; cell->parameters["\\A_SIGNED"] = a_signed; cell->parameters["\\B_SIGNED"] = b_signed; - cell->parameters["\\A_WIDTH"] = sig_a.width; - cell->parameters["\\B_WIDTH"] = sig_b.width; - cell->parameters["\\Y_WIDTH"] = sig_y.width; + cell->parameters["\\A_WIDTH"] = sig_a.__width; + cell->parameters["\\B_WIDTH"] = sig_b.__width; + cell->parameters["\\Y_WIDTH"] = sig_y.__width; cell->connections["\\A"] = sig_a; cell->connections["\\B"] = sig_b; cell->connections["\\Y"] = sig_y; @@ -1065,8 +1065,8 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = "$slice"; - cell->parameters["\\A_WIDTH"] = sig_a.width; - cell->parameters["\\Y_WIDTH"] = sig_y.width; + cell->parameters["\\A_WIDTH"] = sig_a.__width; + cell->parameters["\\Y_WIDTH"] = sig_y.__width; cell->parameters["\\OFFSET"] = offset; cell->connections["\\A"] = sig_a; cell->connections["\\Y"] = sig_y; @@ -1079,8 +1079,8 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = "$concat"; - cell->parameters["\\A_WIDTH"] = sig_a.width; - cell->parameters["\\B_WIDTH"] = sig_b.width; + cell->parameters["\\A_WIDTH"] = sig_a.__width; + cell->parameters["\\B_WIDTH"] = sig_b.__width; cell->connections["\\A"] = sig_a; cell->connections["\\B"] = sig_b; cell->connections["\\Y"] = sig_y; @@ -1094,7 +1094,7 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, R cell->name = name; cell->type = "$lut"; cell->parameters["\\LUT"] = lut; - cell->parameters["\\WIDTH"] = sig_i.width; + cell->parameters["\\WIDTH"] = sig_i.__width; cell->connections["\\I"] = sig_i; cell->connections["\\O"] = sig_o; add(cell); @@ -1119,7 +1119,7 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, cell->type = "$sr"; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.width; + cell->parameters["\\WIDTH"] = sig_q.__width; cell->connections["\\SET"] = sig_set; cell->connections["\\CLR"] = sig_clr; cell->connections["\\Q"] = sig_q; @@ -1133,7 +1133,7 @@ RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, cell->name = name; cell->type = "$dff"; cell->parameters["\\CLK_POLARITY"] = clk_polarity; - cell->parameters["\\WIDTH"] = sig_q.width; + cell->parameters["\\WIDTH"] = sig_q.__width; cell->connections["\\CLK"] = sig_clk; cell->connections["\\D"] = sig_d; cell->connections["\\Q"] = sig_q; @@ -1150,7 +1150,7 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.width; + cell->parameters["\\WIDTH"] = sig_q.__width; cell->connections["\\CLK"] = sig_clk; cell->connections["\\SET"] = sig_set; cell->connections["\\CLR"] = sig_clr; @@ -1169,7 +1169,7 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\ARST_POLARITY"] = arst_polarity; cell->parameters["\\ARST_VALUE"] = arst_value; - cell->parameters["\\WIDTH"] = sig_q.width; + cell->parameters["\\WIDTH"] = sig_q.__width; cell->connections["\\CLK"] = sig_clk; cell->connections["\\ARST"] = sig_arst; cell->connections["\\D"] = sig_d; @@ -1184,7 +1184,7 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e cell->name = name; cell->type = "$dlatch"; cell->parameters["\\EN_POLARITY"] = en_polarity; - cell->parameters["\\WIDTH"] = sig_q.width; + cell->parameters["\\WIDTH"] = sig_q.__width; cell->connections["\\EN"] = sig_en; cell->connections["\\D"] = sig_d; cell->connections["\\Q"] = sig_q; @@ -1201,7 +1201,7 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.width; + cell->parameters["\\WIDTH"] = sig_q.__width; cell->connections["\\EN"] = sig_en; cell->connections["\\SET"] = sig_set; cell->connections["\\CLR"] = sig_clr; @@ -1415,65 +1415,65 @@ bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const RTLIL::SigSpec::SigSpec() { - width = 0; + __width = 0; } RTLIL::SigSpec::SigSpec(const RTLIL::Const &data) { - chunks.push_back(RTLIL::SigChunk(data)); - width = chunks.back().width; + __chunks.push_back(RTLIL::SigChunk(data)); + __width = __chunks.back().width; check(); } RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) { - chunks.push_back(chunk); - width = chunks.back().width; + __chunks.push_back(chunk); + __width = __chunks.back().width; check(); } RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int width, int offset) { - chunks.push_back(RTLIL::SigChunk(wire, width, offset)); - this->width = chunks.back().width; + __chunks.push_back(RTLIL::SigChunk(wire, width, offset)); + __width = __chunks.back().width; check(); } RTLIL::SigSpec::SigSpec(const std::string &str) { - chunks.push_back(RTLIL::SigChunk(str)); - width = chunks.back().width; + __chunks.push_back(RTLIL::SigChunk(str)); + __width = __chunks.back().width; check(); } RTLIL::SigSpec::SigSpec(int val, int width) { - chunks.push_back(RTLIL::SigChunk(val, width)); - this->width = width; + __chunks.push_back(RTLIL::SigChunk(val, width)); + __width = width; check(); } RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) { - chunks.push_back(RTLIL::SigChunk(bit, width)); - this->width = width; + __chunks.push_back(RTLIL::SigChunk(bit, width)); + __width = width; check(); } RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) { if (bit.wire == NULL) - chunks.push_back(RTLIL::SigChunk(bit.data, width)); + __chunks.push_back(RTLIL::SigChunk(bit.data, width)); else for (int i = 0; i < width; i++) - chunks.push_back(bit); - this->width = width; + __chunks.push_back(bit); + __width = width; check(); } RTLIL::SigSpec::SigSpec(std::vector bits) { - this->width = 0; + __width = 0; for (auto &bit : bits) append_bit(bit); check(); @@ -1481,7 +1481,7 @@ RTLIL::SigSpec::SigSpec(std::vector bits) RTLIL::SigSpec::SigSpec(std::set bits) { - this->width = 0; + __width = 0; for (auto &bit : bits) append_bit(bit); check(); @@ -1490,18 +1490,18 @@ RTLIL::SigSpec::SigSpec(std::set bits) void RTLIL::SigSpec::expand() { std::vector new_chunks; - for (size_t i = 0; i < chunks.size(); i++) { - for (int j = 0; j < chunks[i].width; j++) - new_chunks.push_back(chunks[i].extract(j, 1)); + for (size_t i = 0; i < __chunks.size(); i++) { + for (int j = 0; j < __chunks[i].width; j++) + new_chunks.push_back(__chunks[i].extract(j, 1)); } - chunks.swap(new_chunks); + __chunks.swap(new_chunks); check(); } void RTLIL::SigSpec::optimize() { std::vector new_chunks; - for (auto &c : chunks) + for (auto &c : __chunks) if (new_chunks.size() == 0) { new_chunks.push_back(c); } else { @@ -1513,7 +1513,7 @@ void RTLIL::SigSpec::optimize() else new_chunks.push_back(c); } - chunks.swap(new_chunks); + __chunks.swap(new_chunks); check(); } @@ -1544,20 +1544,20 @@ bool RTLIL::SigChunk::compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b void RTLIL::SigSpec::sort() { expand(); - std::sort(chunks.begin(), chunks.end(), RTLIL::SigChunk::compare); + std::sort(__chunks.begin(), __chunks.end(), RTLIL::SigChunk::compare); optimize(); } void RTLIL::SigSpec::sort_and_unify() { expand(); - std::sort(chunks.begin(), chunks.end(), RTLIL::SigChunk::compare); - for (size_t i = 1; i < chunks.size(); i++) { - RTLIL::SigChunk &ch1 = chunks[i-1]; - RTLIL::SigChunk &ch2 = chunks[i]; + std::sort(__chunks.begin(), __chunks.end(), RTLIL::SigChunk::compare); + for (size_t i = 1; i < __chunks.size(); i++) { + RTLIL::SigChunk &ch1 = __chunks[i-1]; + RTLIL::SigChunk &ch2 = __chunks[i]; if (!RTLIL::SigChunk::compare(ch1, ch2) && !RTLIL::SigChunk::compare(ch2, ch1)) { - chunks.erase(chunks.begin()+i); - width -= chunks[i].width; + __chunks.erase(__chunks.begin()+i); + __width -= __chunks[i].width; i--; } } @@ -1572,13 +1572,13 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { int pos = 0, restart_pos = 0; - assert(other == NULL || width == other->width); - for (size_t i = 0; i < chunks.size(); i++) { + assert(other == NULL || __width == other->__width); + for (size_t i = 0; i < __chunks.size(); i++) { restart: - const RTLIL::SigChunk &ch1 = chunks[i]; - if (chunks[i].wire != NULL && pos >= restart_pos) - for (size_t j = 0, poff = 0; j < pattern.chunks.size(); j++) { - const RTLIL::SigChunk &ch2 = pattern.chunks[j]; + const RTLIL::SigChunk &ch1 = __chunks[i]; + if (__chunks[i].wire != NULL && pos >= restart_pos) + for (size_t j = 0, poff = 0; j < pattern.__chunks.size(); j++) { + const RTLIL::SigChunk &ch2 = pattern.__chunks[j]; assert(ch2.wire != NULL); if (ch1.wire == ch2.wire) { int lower = std::max(ch1.offset, ch2.offset); @@ -1591,7 +1591,7 @@ restart: } poff += ch2.width; } - pos += chunks[i].width; + pos += __chunks[i].width; } check(); } @@ -1610,13 +1610,13 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) { int pos = 0; - assert(other == NULL || width == other->width); - for (size_t i = 0; i < chunks.size(); i++) { + assert(other == NULL || __width == other->__width); + for (size_t i = 0; i < __chunks.size(); i++) { restart: - const RTLIL::SigChunk &ch1 = chunks[i]; - if (chunks[i].wire != NULL) - for (size_t j = 0; j < pattern.chunks.size(); j++) { - const RTLIL::SigChunk &ch2 = pattern.chunks[j]; + const RTLIL::SigChunk &ch1 = __chunks[i]; + if (__chunks[i].wire != NULL) + for (size_t j = 0; j < pattern.__chunks.size(); j++) { + const RTLIL::SigChunk &ch2 = pattern.__chunks[j]; assert(ch2.wire != NULL); if (ch1.wire == ch2.wire) { int lower = std::max(ch1.offset, ch2.offset); @@ -1625,20 +1625,20 @@ restart: if (other) other->remove(pos+lower-ch1.offset, upper-lower); remove(pos+lower-ch1.offset, upper-lower); - if (i == chunks.size()) + if (i == __chunks.size()) break; goto restart; } } } - pos += chunks[i].width; + pos += __chunks[i].width; } check(); } RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const { - assert(other == NULL || width == other->width); + assert(other == NULL || __width == other->__width); std::set pat = pattern.to_sigbit_set(); std::vector bits_match = to_sigbit_vector(); @@ -1646,11 +1646,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o if (other) { std::vector bits_other = other ? other->to_sigbit_vector() : bits_match; - for (int i = 0; i < width; i++) + for (int i = 0; i < __width; i++) if (bits_match[i].wire && pat.count(bits_match[i])) ret.append_bit(bits_other[i]); } else { - for (int i = 0; i < width; i++) + for (int i = 0; i < __width; i++) if (bits_match[i].wire && pat.count(bits_match[i])) ret.append_bit(bits_match[i]); } @@ -1663,31 +1663,31 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) { int pos = 0; assert(offset >= 0); - assert(with.width >= 0); - assert(offset+with.width <= width); - remove(offset, with.width); - for (size_t i = 0; i < chunks.size(); i++) { + assert(with.__width >= 0); + assert(offset+with.__width <= __width); + remove(offset, with.__width); + for (size_t i = 0; i < __chunks.size(); i++) { if (pos == offset) { - chunks.insert(chunks.begin()+i, with.chunks.begin(), with.chunks.end()); - width += with.width; + __chunks.insert(__chunks.begin()+i, with.__chunks.begin(), with.__chunks.end()); + __width += with.__width; check(); return; } - pos += chunks[i].width; + pos += __chunks[i].width; } assert(pos == offset); - chunks.insert(chunks.end(), with.chunks.begin(), with.chunks.end()); - width += with.width; + __chunks.insert(__chunks.end(), with.__chunks.begin(), with.__chunks.end()); + __width += with.__width; check(); } void RTLIL::SigSpec::remove_const() { - for (size_t i = 0; i < chunks.size(); i++) { - if (chunks[i].wire != NULL) + for (size_t i = 0; i < __chunks.size(); i++) { + if (__chunks[i].wire != NULL) continue; - width -= chunks[i].width; - chunks.erase(chunks.begin() + (i--)); + __width -= __chunks[i].width; + __chunks.erase(__chunks.begin() + (i--)); } check(); } @@ -1697,34 +1697,34 @@ void RTLIL::SigSpec::remove(int offset, int length) int pos = 0; assert(offset >= 0); assert(length >= 0); - assert(offset+length <= width); - for (size_t i = 0; i < chunks.size(); i++) { - int orig_width = chunks[i].width; - if (pos+chunks[i].width > offset && pos < offset+length) { + assert(offset+length <= __width); + for (size_t i = 0; i < __chunks.size(); i++) { + int orig_width = __chunks[i].width; + if (pos+__chunks[i].width > offset && pos < offset+length) { int off = offset - pos; int len = length; if (off < 0) { len += off; off = 0; } - if (len > chunks[i].width-off) - len = chunks[i].width-off; - RTLIL::SigChunk lsb_chunk = chunks[i].extract(0, off); - RTLIL::SigChunk msb_chunk = chunks[i].extract(off+len, chunks[i].width-off-len); + if (len > __chunks[i].width-off) + len = __chunks[i].width-off; + RTLIL::SigChunk lsb_chunk = __chunks[i].extract(0, off); + RTLIL::SigChunk msb_chunk = __chunks[i].extract(off+len, __chunks[i].width-off-len); if (lsb_chunk.width == 0 && msb_chunk.width == 0) { - chunks.erase(chunks.begin()+i); + __chunks.erase(__chunks.begin()+i); i--; } else if (lsb_chunk.width == 0 && msb_chunk.width != 0) { - chunks[i] = msb_chunk; + __chunks[i] = msb_chunk; } else if (lsb_chunk.width != 0 && msb_chunk.width == 0) { - chunks[i] = lsb_chunk; + __chunks[i] = lsb_chunk; } else if (lsb_chunk.width != 0 && msb_chunk.width != 0) { - chunks[i] = lsb_chunk; - chunks.insert(chunks.begin()+i+1, msb_chunk); + __chunks[i] = lsb_chunk; + __chunks.insert(__chunks.begin()+i+1, msb_chunk); i++; } else assert(0); - width -= len; + __width -= len; } pos += orig_width; } @@ -1737,23 +1737,23 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const RTLIL::SigSpec ret; assert(offset >= 0); assert(length >= 0); - assert(offset+length <= width); - for (size_t i = 0; i < chunks.size(); i++) { - if (pos+chunks[i].width > offset && pos < offset+length) { + assert(offset+length <= __width); + for (size_t i = 0; i < __chunks.size(); i++) { + if (pos+__chunks[i].width > offset && pos < offset+length) { int off = offset - pos; int len = length; if (off < 0) { len += off; off = 0; } - if (len > chunks[i].width-off) - len = chunks[i].width-off; - ret.chunks.push_back(chunks[i].extract(off, len)); - ret.width += len; + if (len > __chunks[i].width-off) + len = __chunks[i].width-off; + ret.__chunks.push_back(__chunks[i].extract(off, len)); + ret.__width += len; offset += len; length -= len; } - pos += chunks[i].width; + pos += __chunks[i].width; } assert(length == 0); ret.check(); @@ -1762,30 +1762,30 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) { - for (size_t i = 0; i < signal.chunks.size(); i++) { - chunks.push_back(signal.chunks[i]); - width += signal.chunks[i].width; + for (size_t i = 0; i < signal.__chunks.size(); i++) { + __chunks.push_back(signal.__chunks[i]); + __width += signal.__chunks[i].width; } // check(); } void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) { - if (chunks.size() == 0) - chunks.push_back(bit); + if (__chunks.size() == 0) + __chunks.push_back(bit); else if (bit.wire == NULL) - if (chunks.back().wire == NULL) { - chunks.back().data.bits.push_back(bit.data); - chunks.back().width++; + if (__chunks.back().wire == NULL) { + __chunks.back().data.bits.push_back(bit.data); + __chunks.back().width++; } else - chunks.push_back(bit); + __chunks.push_back(bit); else - if (chunks.back().wire == bit.wire && chunks.back().offset + chunks.back().width == bit.offset) - chunks.back().width++; + if (__chunks.back().wire == bit.wire && __chunks.back().offset + __chunks.back().width == bit.offset) + __chunks.back().width++; else - chunks.push_back(bit); - width++; + __chunks.push_back(bit); + __width++; // check(); } @@ -1793,22 +1793,22 @@ bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool { bool no_collisions = true; - assert(width == signal.width); + assert(__width == signal.__width); expand(); signal.expand(); - for (size_t i = 0; i < chunks.size(); i++) { - bool self_free = chunks[i].wire == NULL && chunks[i].data.bits[0] == freeState; - bool other_free = signal.chunks[i].wire == NULL && signal.chunks[i].data.bits[0] == freeState; + for (size_t i = 0; i < __chunks.size(); i++) { + bool self_free = __chunks[i].wire == NULL && __chunks[i].data.bits[0] == freeState; + bool other_free = signal.__chunks[i].wire == NULL && signal.__chunks[i].data.bits[0] == freeState; if (!self_free && !other_free) { if (override) - chunks[i] = signal.chunks[i]; + __chunks[i] = signal.__chunks[i]; else - chunks[i] = RTLIL::SigChunk(RTLIL::State::Sx, 1); + __chunks[i] = RTLIL::SigChunk(RTLIL::State::Sx, 1); no_collisions = false; } if (self_free && !other_free) - chunks[i] = signal.chunks[i]; + __chunks[i] = signal.__chunks[i]; } optimize(); @@ -1817,15 +1817,15 @@ bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool void RTLIL::SigSpec::extend(int width, bool is_signed) { - if (this->width > width) - remove(width, this->width - width); + if (__width > width) + remove(width, __width - width); - if (this->width < width) { - RTLIL::SigSpec padding = this->width > 0 ? extract(this->width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); + if (__width < width) { + RTLIL::SigSpec padding = __width > 0 ? extract(__width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); if (!is_signed && padding != RTLIL::SigSpec(RTLIL::State::Sx) && padding != RTLIL::SigSpec(RTLIL::State::Sz) && padding != RTLIL::SigSpec(RTLIL::State::Sa) && padding != RTLIL::SigSpec(RTLIL::State::Sm)) padding = RTLIL::SigSpec(RTLIL::State::S0); - while (this->width < width) + while (__width < width) append(padding); } @@ -1834,14 +1834,14 @@ void RTLIL::SigSpec::extend(int width, bool is_signed) void RTLIL::SigSpec::extend_u0(int width, bool is_signed) { - if (this->width > width) - remove(width, this->width - width); + if (__width > width) + remove(width, __width - width); - if (this->width < width) { - RTLIL::SigSpec padding = this->width > 0 ? extract(this->width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); + if (__width < width) { + RTLIL::SigSpec padding = __width > 0 ? extract(__width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); if (!is_signed) padding = RTLIL::SigSpec(RTLIL::State::S0); - while (this->width < width) + while (__width < width) append(padding); } @@ -1851,8 +1851,8 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed) void RTLIL::SigSpec::check() const { int w = 0; - for (size_t i = 0; i < chunks.size(); i++) { - const RTLIL::SigChunk chunk = chunks[i]; + for (size_t i = 0; i < __chunks.size(); i++) { + const RTLIL::SigChunk chunk = __chunks[i]; if (chunk.wire == NULL) { assert(chunk.offset == 0); assert(chunk.data.bits.size() == (size_t)chunk.width); @@ -1864,42 +1864,42 @@ void RTLIL::SigSpec::check() const } w += chunk.width; } - assert(w == width); + assert(w == __width); } bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const { - if (width != other.width) - return width < other.width; + if (__width != other.__width) + return __width < other.__width; RTLIL::SigSpec a = *this, b = other; a.optimize(); b.optimize(); - if (a.chunks.size() != b.chunks.size()) - return a.chunks.size() < b.chunks.size(); + if (a.__chunks.size() != b.__chunks.size()) + return a.__chunks.size() < b.__chunks.size(); - for (size_t i = 0; i < a.chunks.size(); i++) - if (a.chunks[i] != b.chunks[i]) - return a.chunks[i] < b.chunks[i]; + for (size_t i = 0; i < a.__chunks.size(); i++) + if (a.__chunks[i] != b.__chunks[i]) + return a.__chunks[i] < b.__chunks[i]; return false; } bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const { - if (width != other.width) + if (__width != other.__width) return false; RTLIL::SigSpec a = *this, b = other; a.optimize(); b.optimize(); - if (a.chunks.size() != b.chunks.size()) + if (a.__chunks.size() != b.__chunks.size()) return false; - for (size_t i = 0; i < a.chunks.size(); i++) - if (a.chunks[i] != b.chunks[i]) + for (size_t i = 0; i < a.__chunks.size(); i++) + if (a.__chunks[i] != b.__chunks[i]) return false; return true; @@ -1914,7 +1914,7 @@ bool RTLIL::SigSpec::operator !=(const RTLIL::SigSpec &other) const bool RTLIL::SigSpec::is_fully_const() const { - for (auto it = chunks.begin(); it != chunks.end(); it++) + for (auto it = __chunks.begin(); it != __chunks.end(); it++) if (it->width > 0 && it->wire != NULL) return false; return true; @@ -1922,7 +1922,7 @@ bool RTLIL::SigSpec::is_fully_const() const bool RTLIL::SigSpec::is_fully_def() const { - for (auto it = chunks.begin(); it != chunks.end(); it++) { + for (auto it = __chunks.begin(); it != __chunks.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; for (size_t i = 0; i < it->data.bits.size(); i++) @@ -1934,7 +1934,7 @@ bool RTLIL::SigSpec::is_fully_def() const bool RTLIL::SigSpec::is_fully_undef() const { - for (auto it = chunks.begin(); it != chunks.end(); it++) { + for (auto it = __chunks.begin(); it != __chunks.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; for (size_t i = 0; i < it->data.bits.size(); i++) @@ -1946,7 +1946,7 @@ bool RTLIL::SigSpec::is_fully_undef() const bool RTLIL::SigSpec::has_marked_bits() const { - for (auto it = chunks.begin(); it != chunks.end(); it++) + for (auto it = __chunks.begin(); it != __chunks.end(); it++) if (it->width > 0 && it->wire == NULL) { for (size_t i = 0; i < it->data.bits.size(); i++) if (it->data.bits[i] == RTLIL::State::Sm) @@ -1960,8 +1960,8 @@ bool RTLIL::SigSpec::as_bool() const assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); - if (sig.width) - return sig.chunks[0].data.as_bool(); + if (sig.__width) + return sig.__chunks[0].data.as_bool(); return false; } @@ -1970,16 +1970,16 @@ int RTLIL::SigSpec::as_int() const assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); - if (sig.width) - return sig.chunks[0].data.as_int(); + if (sig.__width) + return sig.__chunks[0].data.as_int(); return 0; } std::string RTLIL::SigSpec::as_string() const { std::string str; - for (size_t i = chunks.size(); i > 0; i--) { - const RTLIL::SigChunk &chunk = chunks[i-1]; + for (size_t i = __chunks.size(); i > 0; i--) { + const RTLIL::SigChunk &chunk = __chunks[i-1]; if (chunk.wire != NULL) for (int j = 0; j < chunk.width; j++) str += "?"; @@ -1994,8 +1994,8 @@ RTLIL::Const RTLIL::SigSpec::as_const() const assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); - if (sig.width) - return sig.chunks[0].data; + if (sig.__width) + return sig.__chunks[0].data; return RTLIL::Const(); } @@ -2022,7 +2022,7 @@ bool RTLIL::SigSpec::match(std::string pattern) const std::set RTLIL::SigSpec::to_sigbit_set() const { std::set sigbits; - for (auto &c : chunks) + for (auto &c : __chunks) for (int i = 0; i < c.width; i++) sigbits.insert(RTLIL::SigBit(c, i)); return sigbits; @@ -2031,8 +2031,8 @@ std::set RTLIL::SigSpec::to_sigbit_set() const std::vector RTLIL::SigSpec::to_sigbit_vector() const { std::vector sigbits; - sigbits.reserve(width); - for (auto &c : chunks) + sigbits.reserve(__width); + for (auto &c : __chunks) for (int i = 0; i < c.width; i++) sigbits.push_back(RTLIL::SigBit(c, i)); return sigbits; @@ -2040,8 +2040,8 @@ std::vector RTLIL::SigSpec::to_sigbit_vector() const RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const { - log_assert(width == 1); - for (auto &c : chunks) + log_assert(__width == 1); + for (auto &c : __chunks) if (c.width) return RTLIL::SigBit(c); log_abort(); @@ -2155,20 +2155,20 @@ bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str) { if (str == "0") { - sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.width); + sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.__width); return true; } if (str == "~0") { - sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.width); + sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.__width); return true; } - if (lhs.chunks.size() == 1) { + if (lhs.__chunks.size() == 1) { char *p = (char*)str.c_str(), *endptr; long long int val = strtoll(p, &endptr, 10); if (endptr && endptr != p && *endptr == 0) { - sig = RTLIL::SigSpec(val, lhs.width); + sig = RTLIL::SigSpec(val, lhs.__width); return true; } } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9b3e4417..0919b392 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -496,8 +496,11 @@ struct RTLIL::SigBit { }; struct RTLIL::SigSpec { - std::vector chunks; // LSB at index 0 - int width; +public: + std::vector __chunks; // LSB at index 0 + int __width; + +public: SigSpec(); SigSpec(const RTLIL::Const &data); SigSpec(const RTLIL::SigChunk &chunk); @@ -551,8 +554,8 @@ struct RTLIL::SigSpec { }; inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { - assert(sig.width == 1 && sig.chunks.size() == 1); - *this = SigBit(sig.chunks[0]); + assert(sig.__width == 1 && sig.__chunks.size() == 1); + *this = SigBit(sig.__chunks[0]); } struct RTLIL::CaseRule { diff --git a/kernel/satgen.h b/kernel/satgen.h index 281d2b26..012b6ab8 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -55,9 +55,9 @@ struct SatGen sig.expand(); std::vector vec; - vec.reserve(sig.chunks.size()); + vec.reserve(sig.__chunks.size()); - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) if (c.wire == NULL) { RTLIL::State bit = c.data.bits.at(0); if (model_undef && dup_undef && bit == RTLIL::State::Sx) @@ -118,7 +118,7 @@ struct SatGen if (timestep_rhs < 0) timestep_rhs = timestep_lhs; - assert(lhs.width == rhs.width); + assert(lhs.__width == rhs.__width); std::vector vec_lhs = importSigSpec(lhs, timestep_lhs); std::vector vec_rhs = importSigSpec(rhs, timestep_rhs); @@ -130,7 +130,7 @@ struct SatGen std::vector undef_rhs = importUndefSigSpec(rhs, timestep_rhs); std::vector eq_bits; - for (int i = 0; i < lhs.width; i++) + for (int i = 0; i < lhs.__width; i++) eq_bits.push_back(ez->AND(ez->IFF(undef_lhs.at(i), undef_rhs.at(i)), ez->IFF(ez->OR(vec_lhs.at(i), undef_lhs.at(i)), ez->OR(vec_rhs.at(i), undef_rhs.at(i))))); return ez->expression(ezSAT::OpAnd, eq_bits); @@ -742,11 +742,11 @@ struct SatGen only_first_one.at(0) = ez->TRUE; div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); } else { - div_zero_result.insert(div_zero_result.end(), cell->connections.at("\\A").width, ez->TRUE); + div_zero_result.insert(div_zero_result.end(), cell->connections.at("\\A").__width, ez->TRUE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->FALSE); } } else { - int copy_a_bits = std::min(cell->connections.at("\\A").width, cell->connections.at("\\B").width); + int copy_a_bits = std::min(cell->connections.at("\\A").__width, cell->connections.at("\\B").__width); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); @@ -768,7 +768,7 @@ struct SatGen { RTLIL::SigSpec a = cell->connections.at("\\A"); RTLIL::SigSpec y = cell->connections.at("\\Y"); - ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.width), y, timestep)); + ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.__width), y, timestep)); return true; } diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 56497bb8..c886ff16 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -38,7 +38,7 @@ struct SigPool void add(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -56,7 +56,7 @@ struct SigPool void del(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -75,10 +75,10 @@ struct SigPool { from.expand(); to.expand(); - assert(from.chunks.size() == to.chunks.size()); - for (size_t i = 0; i < from.chunks.size(); i++) { - bitDef_t bit_from(from.chunks[i].wire, from.chunks[i].offset); - bitDef_t bit_to(to.chunks[i].wire, to.chunks[i].offset); + assert(from.__chunks.size() == to.__chunks.size()); + for (size_t i = 0; i < from.__chunks.size(); i++) { + bitDef_t bit_from(from.__chunks[i].wire, from.__chunks[i].offset); + bitDef_t bit_to(to.__chunks[i].wire, to.__chunks[i].offset); if (bit_from.first == NULL || bit_to.first == NULL) continue; if (bits.count(bit_from) > 0) @@ -90,7 +90,7 @@ struct SigPool { RTLIL::SigSpec result; sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -104,7 +104,7 @@ struct SigPool { RTLIL::SigSpec result; sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -117,7 +117,7 @@ struct SigPool bool check_any(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -130,7 +130,7 @@ struct SigPool bool check_all(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -179,7 +179,7 @@ struct SigSet void insert(RTLIL::SigSpec sig, T data) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -191,7 +191,7 @@ struct SigSet void insert(RTLIL::SigSpec sig, const std::set &data) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -203,7 +203,7 @@ struct SigSet void erase(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -215,7 +215,7 @@ struct SigSet void erase(RTLIL::SigSpec sig, T data) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -227,7 +227,7 @@ struct SigSet void erase(RTLIL::SigSpec sig, const std::set &data) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -239,7 +239,7 @@ struct SigSet void find(RTLIL::SigSpec sig, std::set &result) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -259,7 +259,7 @@ struct SigSet bool has(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -420,11 +420,11 @@ struct SigMap from.expand(); to.expand(); - assert(from.chunks.size() == to.chunks.size()); - for (size_t i = 0; i < from.chunks.size(); i++) + assert(from.__chunks.size() == to.__chunks.size()); + for (size_t i = 0; i < from.__chunks.size(); i++) { - RTLIL::SigChunk &cf = from.chunks[i]; - RTLIL::SigChunk &ct = to.chunks[i]; + RTLIL::SigChunk &cf = from.__chunks[i]; + RTLIL::SigChunk &ct = to.__chunks[i]; if (cf.wire == NULL) continue; @@ -442,9 +442,9 @@ struct SigMap void add(RTLIL::SigSpec sig) { sig.expand(); - for (size_t i = 0; i < sig.chunks.size(); i++) + for (size_t i = 0; i < sig.__chunks.size(); i++) { - RTLIL::SigChunk &c = sig.chunks[i]; + RTLIL::SigChunk &c = sig.__chunks[i]; if (c.wire != NULL) { register_bit(c); set_bit(c, c); @@ -455,14 +455,14 @@ struct SigMap void del(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) unregister_bit(c); } void apply(RTLIL::SigSpec &sig) const { sig.expand(); - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) map_bit(c); sig.optimize(); } diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 30e78e58..e21be30b 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -69,8 +69,8 @@ static RTLIL::SigSpec clk_sig; static int map_signal(RTLIL::SigSpec sig, char gate_type = -1, int in1 = -1, int in2 = -1, int in3 = -1) { - assert(sig.width == 1); - assert(sig.chunks.size() == 1); + assert(sig.__width == 1); + assert(sig.__chunks.size() == 1); assign_map.apply(sig); @@ -105,7 +105,7 @@ static void mark_port(RTLIL::SigSpec sig) { assign_map.apply(sig); sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire != NULL && signal_map.count(c) > 0) signal_list[signal_map[c]].is_port = true; } @@ -124,7 +124,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) RTLIL::SigSpec sig_q = cell->connections["\\Q"]; if (keepff) - for (auto &c : sig_q.chunks) + for (auto &c : sig_q.__chunks) if (c.wire != NULL) c.wire->attributes["\\keep"] = 1; @@ -300,8 +300,8 @@ static void handle_loops() for (auto &edge_it : edges) { int id2 = edge_it.first; - RTLIL::Wire *w1 = signal_list[id1].sig.chunks[0].wire; - RTLIL::Wire *w2 = signal_list[id2].sig.chunks[0].wire; + RTLIL::Wire *w1 = signal_list[id1].sig.__chunks[0].wire; + RTLIL::Wire *w2 = signal_list[id2].sig.__chunks[0].wire; if (w1 != NULL) continue; else if (w2 == NULL) @@ -469,7 +469,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std clk_sig = assign_map(RTLIL::SigSpec(module->wires.at(RTLIL::escape_id(clk_str)), 1)); } - if (dff_mode && clk_sig.width == 0) + if (dff_mode && clk_sig.__width == 0) { int best_dff_counter = 0; std::map, int> dff_counters; @@ -490,13 +490,13 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } if (dff_mode || !clk_str.empty()) { - if (clk_sig.width == 0) + if (clk_sig.__width == 0) log("No (matching) clock domain found. Not extracting any FF cells.\n"); else log("Found (matching) %s clock domain: %s\n", clk_polarity ? "posedge" : "negedge", log_signal(clk_sig)); } - if (clk_sig.width != 0) + if (clk_sig.__width != 0) mark_port(clk_sig); std::vector cells; @@ -552,10 +552,10 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std fprintf(f, "# n%-5d %s\n", si.id, log_signal(si.sig)); for (auto &si : signal_list) { - assert(si.sig.width == 1 && si.sig.chunks.size() == 1); - if (si.sig.chunks[0].wire == NULL) { + assert(si.sig.__width == 1 && si.sig.__chunks.size() == 1); + if (si.sig.__chunks[0].wire == NULL) { fprintf(f, ".names n%d\n", si.id); - if (si.sig.chunks[0].data.bits[0] == RTLIL::State::S1) + if (si.sig.__chunks[0].data.bits[0] == RTLIL::State::S1) fprintf(f, "1\n"); } } @@ -716,15 +716,15 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); module->connections.push_back(conn); continue; } if (c->type == "\\BUF") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks[0].wire->name)]); - conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); module->connections.push_back(conn); continue; } @@ -732,8 +732,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_INV_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; @@ -742,9 +742,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_" + c->type.substr(1) + "_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks[0].wire->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].chunks[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); + cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].__chunks[0].wire->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; @@ -753,21 +753,21 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_MUX_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks[0].wire->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].chunks[0].wire->name)]); - cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].chunks[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); + cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].__chunks[0].wire->name)]); + cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].__chunks[0].wire->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; } if (c->type == "\\DFF") { - log_assert(clk_sig.width == 1); + log_assert(clk_sig.__width == 1); RTLIL::Cell *cell = new RTLIL::Cell; cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; cell->name = remap_name(c->name); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].chunks[0].wire->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].chunks[0].wire->name)]); + cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].__chunks[0].wire->name)]); + cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].__chunks[0].wire->name)]); cell->connections["\\C"] = clk_sig; module->cells[cell->name] = cell; design->select(module, cell); @@ -784,18 +784,18 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\_const0_" || c->type == "\\_const1_") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections.begin()->second.chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections.begin()->second.__chunks[0].wire->name)]); conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1); module->connections.push_back(conn); continue; } if (c->type == "\\_dff_") { - log_assert(clk_sig.width == 1); + log_assert(clk_sig.__width == 1); RTLIL::Cell *cell = new RTLIL::Cell; cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; cell->name = remap_name(c->name); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].chunks[0].wire->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].chunks[0].wire->name)]); + cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].__chunks[0].wire->name)]); + cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].__chunks[0].wire->name)]); cell->connections["\\C"] = clk_sig; module->cells[cell->name] = cell; design->select(module, cell); @@ -807,7 +807,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell->name = remap_name(c->name); for (auto &conn : c->connections) { RTLIL::SigSpec newsig; - for (auto &c : conn.second.chunks) { + for (auto &c : conn.second.__chunks) { if (c.width == 0) continue; assert(c.width == 1); @@ -822,9 +822,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std for (auto conn : mapped_mod->connections) { if (!conn.first.is_fully_const()) - conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.__chunks[0].wire->name)]); if (!conn.second.is_fully_const()) - conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.chunks[0].wire->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.__chunks[0].wire->name)]); module->connections.push_back(conn); } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 1d4da19a..65ebe541 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -177,10 +177,10 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) } input_sig.append(wire); } - output_sig = input_sig.extract(input_sig.width-1, 1); - input_sig = input_sig.extract(0, input_sig.width-1); + output_sig = input_sig.extract(input_sig.__width-1, 1); + input_sig = input_sig.extract(0, input_sig.__width-1); - if (input_sig.width == 0) { + if (input_sig.__width == 0) { RTLIL::State state = RTLIL::State::Sa; while (1) { if (!read_next_line(buffer, buffer_size, line_count, f)) @@ -218,8 +218,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$lut"; - cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.width); - cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.width); + cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.__width); + cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.__width); cell->connections["\\I"] = input_sig; cell->connections["\\O"] = output_sig; lutptr = &cell->parameters.at("\\LUT"); diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index f99cb9b5..f8f9e059 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -27,7 +27,7 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & { CellTypes ct(design); - RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.width); + RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.__width); for (auto &it : module->cells) for (auto &port : it.second->connections) diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index dd8b4fed..426d2b62 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -90,7 +90,7 @@ struct ConnwrappersWorker continue; int inner_width = cell->parameters.at(decl.widthparam).as_int(); - int outer_width = conn.second.width; + int outer_width = conn.second.__width; bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(decl.signparam).as_bool(); if (inner_width >= outer_width) @@ -124,20 +124,20 @@ struct ConnwrappersWorker int extend_width = 0; RTLIL::SigBit extend_bit = is_signed ? sigbits[i] : RTLIL::SigBit(RTLIL::State::S0); - while (extend_width < extend_sig.width && i + extend_width + 1 < sigbits.size() && + while (extend_width < extend_sig.__width && i + extend_width + 1 < sigbits.size() && sigbits[i + extend_width + 1] == extend_bit) extend_width++; if (extend_width == 0) continue; - if (old_sig.width == 0) + if (old_sig.__width == 0) old_sig = conn.second; conn.second.replace(i+1, extend_sig.extract(0, extend_width)); i += extend_width; } - if (old_sig.width) + if (old_sig.__width) log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second)); } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index ce6ac4af..16828e4f 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -28,7 +28,7 @@ struct DeleteWireWorker void operator()(RTLIL::SigSpec &sig) { sig.optimize(); - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) if (c.wire != NULL && delete_wires_p->count(c.wire->name)) { c.wire = module->addWire(NEW_ID, c.width); c.offset = 0; diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index e5f78830..da36c782 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -53,7 +53,7 @@ struct ScatterPass : public Pass { { RTLIL::Wire *wire = new RTLIL::Wire; wire->name = NEW_ID; - wire->width = p.second.width; + wire->width = p.second.__width; mod_it.second->add(wire); if (ct.cell_output(c.second->type, p.first)) { diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index f8c351a4..d668bc3a 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -191,7 +191,7 @@ struct SccWorker nextsig.sort_and_unify(); sig = prevsig.extract(nextsig); - for (auto &chunk : sig.chunks) + for (auto &chunk : sig.__chunks) if (chunk.wire != NULL) sel.selected_members[module->name].insert(chunk.wire->name); } diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 9ef60a28..068162eb 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -415,7 +415,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v include_match: is_input = mode == 'x' || ct.cell_input(cell.second->type, conn.first); is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first); - for (auto &chunk : conn.second.chunks) + for (auto &chunk : conn.second.__chunks) if (chunk.wire != NULL) { if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && lhs.selected_members[mod->name].count(cell.first) == 0) if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input)) diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 9d59834c..3a99c0ce 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -48,7 +48,7 @@ struct SetundefWorker void operator()(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) if (c.wire == NULL && c.data.bits.at(0) > RTLIL::State::S1) c.data.bits.at(0) = next_bit(); sig.optimize(); @@ -141,7 +141,7 @@ struct SetundefPass : public Pass { undriven_signals.del(sigmap(conn.second)); RTLIL::SigSpec sig = undriven_signals.export_all(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { RTLIL::SigSpec bits; for (int i = 0; i < c.width; i++) bits.append(next_bit()); diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index eab42e6f..0006a3ff 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -78,7 +78,7 @@ struct ShowWorker std::string nextColor(RTLIL::SigSpec sig, std::string defaultColor) { sig.sort_and_unify(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire != NULL) for (auto &s : color_selections) if (s.second.selected_members.count(module->name) > 0 && s.second.selected_members.at(module->name).count(c.wire->name) > 0) @@ -173,13 +173,13 @@ struct ShowWorker { sig.optimize(); - if (sig.chunks.size() == 0) { + if (sig.__chunks.size() == 0) { fprintf(f, "v%d [ label=\"\" ];\n", single_idx_count); return stringf("v%d", single_idx_count++); } - if (sig.chunks.size() == 1) { - RTLIL::SigChunk &c = sig.chunks[0]; + if (sig.__chunks.size() == 1) { + RTLIL::SigChunk &c = sig.__chunks[0]; if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) { if (!range_check || c.wire->width == c.width) return stringf("n%d", id2num(c.wire->name)); @@ -200,10 +200,10 @@ struct ShowWorker { std::string label_string; sig.optimize(); - int pos = sig.width-1; + int pos = sig.__width-1; int idx = single_idx_count++; - for (int i = int(sig.chunks.size())-1; i >= 0; i--) { - RTLIL::SigChunk &c = sig.chunks[i]; + for (int i = int(sig.__chunks.size())-1; i >= 0; i--) { + RTLIL::SigChunk &c = sig.__chunks[i]; net = gen_signode_simple(c, false); assert(!net.empty()); if (driver) { @@ -225,9 +225,9 @@ struct ShowWorker if (!port.empty()) { currentColor = xorshift32(currentColor); if (driver) - code += stringf("%s:e -> x%d:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", port.c_str(), idx, nextColor(sig).c_str(), widthLabel(sig.width).c_str()); + code += stringf("%s:e -> x%d:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", port.c_str(), idx, nextColor(sig).c_str(), widthLabel(sig.__width).c_str()); else - code += stringf("x%d:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", idx, port.c_str(), nextColor(sig).c_str(), widthLabel(sig.width).c_str()); + code += stringf("x%d:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", idx, port.c_str(), nextColor(sig).c_str(), widthLabel(sig.__width).c_str()); } if (node != NULL) *node = stringf("x%d", idx); @@ -239,7 +239,7 @@ struct ShowWorker net_conn_map[net].in.insert(port); else net_conn_map[net].out.insert(port); - net_conn_map[net].bits = sig.width; + net_conn_map[net].bits = sig.__width; net_conn_map[net].color = nextColor(sig, net_conn_map[net].color); } if (node != NULL) @@ -405,7 +405,7 @@ struct ShowWorker code += gen_portbox("", sig, false, &node); fprintf(f, "%s", code.c_str()); net_conn_map[node].out.insert(stringf("p%d", pidx)); - net_conn_map[node].bits = sig.width; + net_conn_map[node].bits = sig.__width; net_conn_map[node].color = nextColor(sig, net_conn_map[node].color); } @@ -414,7 +414,7 @@ struct ShowWorker code += gen_portbox("", sig, true, &node); fprintf(f, "%s", code.c_str()); net_conn_map[node].in.insert(stringf("p%d", pidx)); - net_conn_map[node].bits = sig.width; + net_conn_map[node].bits = sig.__width; net_conn_map[node].color = nextColor(sig, net_conn_map[node].color); } @@ -427,12 +427,12 @@ struct ShowWorker for (auto &conn : module->connections) { bool found_lhs_wire = false; - for (auto &c : conn.first.chunks) { + for (auto &c : conn.first.__chunks) { if (c.wire == NULL || design->selected_member(module->name, c.wire->name)) found_lhs_wire = true; } bool found_rhs_wire = false; - for (auto &c : conn.second.chunks) { + for (auto &c : conn.second.__chunks) { if (c.wire == NULL || design->selected_member(module->name, c.wire->name)) found_rhs_wire = true; } @@ -446,11 +446,11 @@ struct ShowWorker if (left_node[0] == 'x' && right_node[0] == 'x') { currentColor = xorshift32(currentColor); - fprintf(f, "%s:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", left_node.c_str(), right_node.c_str(), nextColor(conn).c_str(), widthLabel(conn.first.width).c_str()); + fprintf(f, "%s:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", left_node.c_str(), right_node.c_str(), nextColor(conn).c_str(), widthLabel(conn.first.__width).c_str()); } else { - net_conn_map[right_node].bits = conn.first.width; + net_conn_map[right_node].bits = conn.first.__width; net_conn_map[right_node].color = nextColor(conn, net_conn_map[right_node].color); - net_conn_map[left_node].bits = conn.first.width; + net_conn_map[left_node].bits = conn.first.__width; net_conn_map[left_node].color = nextColor(conn, net_conn_map[left_node].color); if (left_node[0] == 'x') { net_conn_map[right_node].in.insert(left_node); diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index a48a54a1..80a7f90c 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -52,7 +52,7 @@ struct SpliceWorker RTLIL::SigSpec get_sliced_signal(RTLIL::SigSpec sig) { - if (sig.width == 0 || sig.is_fully_const()) + if (sig.__width == 0 || sig.is_fully_const()) return sig; if (sliced_signals_cache.count(sig)) @@ -69,15 +69,15 @@ struct SpliceWorker RTLIL::SigSpec new_sig = sig; - if (sig_a.width != sig.width) { + if (sig_a.__width != sig.__width) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$slice"; cell->parameters["\\OFFSET"] = offset; - cell->parameters["\\A_WIDTH"] = sig_a.width; - cell->parameters["\\Y_WIDTH"] = sig.width; + cell->parameters["\\A_WIDTH"] = sig_a.__width; + cell->parameters["\\Y_WIDTH"] = sig.__width; cell->connections["\\A"] = sig_a; - cell->connections["\\Y"] = module->addWire(NEW_ID, sig.width); + cell->connections["\\Y"] = module->addWire(NEW_ID, sig.__width); new_sig = cell->connections["\\Y"]; module->add(cell); } @@ -90,7 +90,7 @@ struct SpliceWorker RTLIL::SigSpec get_spliced_signal(RTLIL::SigSpec sig) { - if (sig.width == 0 || sig.is_fully_const()) + if (sig.__width == 0 || sig.is_fully_const()) return sig; if (spliced_signals_cache.count(sig)) @@ -134,11 +134,11 @@ struct SpliceWorker RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$concat"; - cell->parameters["\\A_WIDTH"] = new_sig.width; - cell->parameters["\\B_WIDTH"] = sig2.width; + cell->parameters["\\A_WIDTH"] = new_sig.__width; + cell->parameters["\\B_WIDTH"] = sig2.__width; cell->connections["\\A"] = new_sig; cell->connections["\\B"] = sig2; - cell->connections["\\Y"] = module->addWire(NEW_ID, new_sig.width + sig2.width); + cell->connections["\\Y"] = module->addWire(NEW_ID, new_sig.__width + sig2.__width); new_sig = cell->connections["\\Y"]; module->add(cell); } diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 7e043bcf..7572baa3 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -63,7 +63,7 @@ struct SplitnetsWorker void operator()(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) if (splitmap.count(c.wire) > 0) c = splitmap.at(c.wire).at(c.offset); sig.optimize(); @@ -144,7 +144,7 @@ struct SplitnetsPass : public Pass { continue; RTLIL::SigSpec sig = p.second.optimized(); - for (auto &chunk : sig.chunks) { + for (auto &chunk : sig.__chunks) { if (chunk.wire == NULL) continue; if (chunk.wire->port_id == 0 || flag_ports) { diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index a8ec1912..523feae9 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -56,8 +56,8 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig RTLIL::SigSpec sig_b = assign_map(cellport.first->connections["\\B"]); if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) return false; - for (int i = 0; i < sig_b.width; i += sig_a.width) - if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.width), recursion_monitor)) + for (int i = 0; i < sig_b.__width; i += sig_a.__width) + if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.__width), recursion_monitor)) return false; muxtree_cells.insert(cellport.first); } diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 5756b10c..e4d20077 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -43,7 +43,7 @@ struct FsmExpand bool is_cell_merge_candidate(RTLIL::Cell *cell) { if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") - if (cell->connections.at("\\A").width < 2) + if (cell->connections.at("\\A").__width < 2) return true; RTLIL::SigSpec new_signals; @@ -62,7 +62,7 @@ struct FsmExpand new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_IN"])); new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_OUT"])); - if (new_signals.width > 3) + if (new_signals.__width > 3) return false; if (cell->connections.count("\\Y") > 0) { @@ -73,7 +73,7 @@ struct FsmExpand new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_OUT"])); } - if (new_signals.width > 2) + if (new_signals.__width > 2) return false; return true; @@ -145,8 +145,8 @@ struct FsmExpand std::vector truth_tab; - for (int i = 0; i < (1 << input_sig.width); i++) { - RTLIL::Const in_val(i, input_sig.width); + for (int i = 0; i < (1 << input_sig.__width); i++) { + RTLIL::Const in_val(i, input_sig.__width); RTLIL::SigSpec A, B, S; if (cell->connections.count("\\A") > 0) A = assign_map(cell->connections["\\A"]); @@ -166,17 +166,17 @@ struct FsmExpand FsmData fsm_data; fsm_data.copy_from_cell(fsm_cell); - fsm_data.num_inputs += input_sig.width; + fsm_data.num_inputs += input_sig.__width; fsm_cell->connections["\\CTRL_IN"].append(input_sig); - fsm_data.num_outputs += output_sig.width; + fsm_data.num_outputs += output_sig.__width; fsm_cell->connections["\\CTRL_OUT"].append(output_sig); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { - for (int i = 0; i < (1 << input_sig.width); i++) { + for (int i = 0; i < (1 << input_sig.__width); i++) { FsmData::transition_t new_tr = tr; - RTLIL::Const in_val(i, input_sig.width); + RTLIL::Const in_val(i, input_sig.__width); RTLIL::Const out_val = truth_tab[i]; RTLIL::SigSpec ctrl_in = new_tr.ctrl_in; RTLIL::SigSpec ctrl_out = new_tr.ctrl_out; diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 9cba904a..c0b5857f 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -36,7 +36,7 @@ static SigSet sig2driver, sig2trigger; static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL::SigSpec &ctrl, std::map &states, RTLIL::Const *reset_state = NULL) { - sig.extend(dff_out.width, false); + sig.extend(dff_out.__width, false); if (sig == dff_out) return true; @@ -44,10 +44,10 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL assign_map.apply(sig); if (sig.is_fully_const()) { sig.optimize(); - assert(sig.chunks.size() == 1); - if (states.count(sig.chunks[0].data) == 0) { + assert(sig.__chunks.size() == 1); + if (states.count(sig.__chunks[0].data) == 0) { log(" found state code: %s\n", log_signal(sig)); - states[sig.chunks[0].data] = -1; + states[sig.__chunks[0].data] = -1; } return true; } @@ -73,14 +73,14 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL break; log(" found reset state: %s (guessed from mux tree)\n", log_signal(*reset_state)); } while (0); - if (ctrl.extract(sig_s).width == 0) { + if (ctrl.extract(sig_s).__width == 0) { log(" found ctrl input: %s\n", log_signal(sig_s)); ctrl.append(sig_s); } if (!find_states(sig_a, dff_out, ctrl, states)) return false; - for (int i = 0; i < sig_b.width/sig_a.width; i++) { - if (!find_states(sig_b.extract(i*sig_a.width, sig_a.width), dff_out, ctrl, states)) + for (int i = 0; i < sig_b.__width/sig_a.__width; i++) { + if (!find_states(sig_b.extract(i*sig_a.__width, sig_a.__width), dff_out, ctrl, states)) return false; } } @@ -90,11 +90,11 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State noconst_state, RTLIL::SigSpec dont_care = RTLIL::SigSpec()) { - if (dont_care.width > 0) { + if (dont_care.__width > 0) { sig.expand(); - for (auto &chunk : sig.chunks) { + for (auto &chunk : sig.__chunks) { assert(chunk.width == 1); - if (dont_care.extract(chunk).width > 0) + if (dont_care.extract(chunk).__width > 0) chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); } sig.optimize(); @@ -104,17 +104,17 @@ static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State no ce.values_map.apply(sig); sig.expand(); - for (auto &chunk : sig.chunks) { + for (auto &chunk : sig.__chunks) { assert(chunk.width == 1); if (chunk.wire != NULL) chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); } sig.optimize(); - if (sig.width == 0) + if (sig.__width == 0) return RTLIL::Const(); - assert(sig.chunks.size() == 1 && sig.chunks[0].wire == NULL); - return sig.chunks[0].data; + assert(sig.__chunks.size() == 1 && sig.__chunks[0].wire == NULL); + return sig.__chunks[0].data; } static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_data, std::map &states, int state_in, RTLIL::SigSpec ctrl_in, RTLIL::SigSpec ctrl_out, RTLIL::SigSpec dff_in, RTLIL::SigSpec dont_care) @@ -144,7 +144,7 @@ static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_d return; } - log_assert(undef.width > 0); + log_assert(undef.__width > 0); log_assert(ce.stop_signals.check_all(undef)); undef = undef.extract(0, 1); @@ -258,8 +258,8 @@ static void extract_fsm(RTLIL::Wire *wire) // Initialize fsm data struct FsmData fsm_data; - fsm_data.num_inputs = ctrl_in.width; - fsm_data.num_outputs = ctrl_out.width; + fsm_data.num_inputs = ctrl_in.__width; + fsm_data.num_outputs = ctrl_out.__width; fsm_data.state_bits = wire->width; fsm_data.reset_state = -1; for (auto &it : states) { @@ -314,7 +314,7 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = new RTLIL::Wire; unconn_wire->name = stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++); - unconn_wire->width = unconn_sig.width; + unconn_wire->width = unconn_sig.__width; module->wires[unconn_wire->name] = unconn_wire; port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections[cellport.second]); } @@ -367,7 +367,7 @@ struct FsmExtractPass : public Pass { sig2driver.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); } if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->connections.count("\\Y") > 0 && - cell_it.second->connections["\\Y"].width == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { + cell_it.second->connections["\\Y"].__width == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); sig2trigger.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index c30cf1fe..f11d78b3 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -50,12 +50,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 0) + if (eq_sig_a.__width > 0) { RTLIL::Wire *eq_wire = new RTLIL::Wire; eq_wire->name = NEW_ID; @@ -69,17 +69,17 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapconnections["\\Y"] = RTLIL::SigSpec(eq_wire); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); - eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.width); - eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.width); + eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.__width); + eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.__width); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(eq_cell); and_sig.append(RTLIL::SigSpec(eq_wire)); } - if (or_sig.width < num_states-int(fullstate_cache.size())) + if (or_sig.__width < num_states-int(fullstate_cache.size())) { - if (or_sig.width == 1) + if (or_sig.__width == 1) { and_sig.append(or_sig); } @@ -95,7 +95,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapconnections["\\A"] = or_sig; or_cell->connections["\\Y"] = RTLIL::SigSpec(or_wire); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); - or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.width); + or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.__width); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(or_cell); @@ -103,7 +103,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 1) { + if (cases_vector.__width > 1) { RTLIL::Cell *or_cell = new RTLIL::Cell; or_cell->name = NEW_ID; or_cell->type = "$reduce_or"; or_cell->connections["\\A"] = cases_vector; or_cell->connections["\\Y"] = output; or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); - or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.width); + or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.__width); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(or_cell); - } else if (cases_vector.width == 1) { + } else if (cases_vector.__width == 1) { module->connections.push_back(RTLIL::SigSig(output, cases_vector)); } else { module->connections.push_back(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); @@ -237,8 +237,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) eq_cell->connections["\\Y"] = RTLIL::SigSpec(state_onehot, 1, i); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); - eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.width); - eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.width); + eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.__width); + eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.__width); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(eq_cell); } @@ -308,8 +308,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) mux_cell->connections["\\B"] = sig_b; mux_cell->connections["\\S"] = sig_s; mux_cell->connections["\\Y"] = RTLIL::SigSpec(next_state_wire); - mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.width); - mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.width); + mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.__width); + mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.__width); module->add(mux_cell); } diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 242a505e..6732d2ab 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -33,11 +33,11 @@ struct FsmOpt bool signal_is_unused(RTLIL::SigSpec sig) { - assert(sig.width == 1); + assert(sig.__width == 1); sig.optimize(); - RTLIL::Wire *wire = sig.chunks[0].wire; - int bit = sig.chunks[0].offset; + RTLIL::Wire *wire = sig.__chunks[0].wire; + int bit = sig.__chunks[0].offset; if (!wire || wire->attributes.count("\\unused_bits") == 0) return false; @@ -55,11 +55,11 @@ struct FsmOpt void opt_const_and_unused_inputs() { RTLIL::SigSpec ctrl_in = cell->connections["\\CTRL_IN"]; - std::vector ctrl_in_used(ctrl_in.width); + std::vector ctrl_in_used(ctrl_in.__width); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { - for (int i = 0; i < ctrl_in.width; i++) { + for (int i = 0; i < ctrl_in.__width; i++) { RTLIL::SigSpec ctrl_bit = ctrl_in.extract(i, 1); if (ctrl_bit.is_fully_const()) { if (tr.ctrl_in.bits[i] <= RTLIL::State::S1 && RTLIL::SigSpec(tr.ctrl_in.bits[i]) != ctrl_bit) @@ -112,8 +112,8 @@ struct FsmOpt { RTLIL::SigSpec &ctrl_in = cell->connections["\\CTRL_IN"]; - for (int i = 0; i < ctrl_in.width; i++) - for (int j = i+1; j < ctrl_in.width; j++) + for (int i = 0; i < ctrl_in.__width; i++) + for (int j = i+1; j < ctrl_in.__width; j++) if (ctrl_in.extract(i, 1) == ctrl_in.extract(j, 1)) { log(" Optimize handling of signal %s that is connected to inputs %d and %d.\n", log_signal(ctrl_in.extract(i, 1)), i, j); @@ -150,8 +150,8 @@ struct FsmOpt RTLIL::SigSpec &ctrl_in = cell->connections["\\CTRL_IN"]; RTLIL::SigSpec &ctrl_out = cell->connections["\\CTRL_OUT"]; - for (int j = 0; j < ctrl_out.width; j++) - for (int i = 0; i < ctrl_in.width; i++) + for (int j = 0; j < ctrl_out.__width; j++) + for (int i = 0; i < ctrl_in.__width; i++) if (ctrl_in.extract(i, 1) == ctrl_out.extract(j, 1)) { log(" Optimize handling of signal %s that is connected to input %d and output %d.\n", log_signal(ctrl_in.extract(i, 1)), i, j); diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index 225f34a9..6b175306 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -143,15 +143,15 @@ struct FsmData log(" Input signals:\n"); RTLIL::SigSpec sig_in = cell->connections["\\CTRL_IN"]; sig_in.expand(); - for (size_t i = 0; i < sig_in.chunks.size(); i++) - log(" %3zd: %s\n", i, log_signal(sig_in.chunks[i])); + for (size_t i = 0; i < sig_in.__chunks.size(); i++) + log(" %3zd: %s\n", i, log_signal(sig_in.__chunks[i])); log("\n"); log(" Output signals:\n"); RTLIL::SigSpec sig_out = cell->connections["\\CTRL_OUT"]; sig_out.expand(); - for (size_t i = 0; i < sig_out.chunks.size(); i++) - log(" %3zd: %s\n", i, log_signal(sig_out.chunks[i])); + for (size_t i = 0; i < sig_out.__chunks.size(); i++) + log(" %3zd: %s\n", i, log_signal(sig_out.__chunks[i])); log("\n"); log(" State encoding:\n"); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index d8a23c72..5d9dc18a 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -61,7 +61,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell for (auto &conn : i2.second->connections) { if (conn.first[0] != '$') portnames.insert(conn.first); - portwidths[conn.first] = std::max(portwidths[conn.first], conn.second.width); + portwidths[conn.first] = std::max(portwidths[conn.first], conn.second.__width); } for (auto ¶ : i2.second->parameters) parameters.insert(para.first); @@ -220,7 +220,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla RTLIL::Module *mod = design->modules[cell->type]; for (auto &conn : cell->connections) { - int conn_size = conn.second.width; + int conn_size = conn.second.__width; std::string portname = conn.first; if (portname.substr(0, 1) == "$") { int port_id = atoi(portname.substr(1).c_str()); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 55f5f048..f8f2b596 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -67,7 +67,7 @@ struct SubmodWorker void flag_signal(RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) if (c.wire != NULL) flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); } @@ -164,7 +164,7 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new RTLIL::Cell(*cell); for (auto &conn : new_cell->connections) - for (auto &c : conn.second.chunks) + for (auto &c : conn.second.__chunks) if (c.wire != NULL) { assert(wire_flags.count(c.wire) > 0); c.wire = wire_flags[c.wire].new_wire; diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 028841f6..6c9e1b77 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -142,16 +142,16 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) sig_wr_clk_enable.optimize(); sig_wr_clk_polarity.optimize(); - assert(sig_wr_clk.width == wr_ports); - assert(sig_wr_clk_enable.width == wr_ports && sig_wr_clk_enable.is_fully_const()); - assert(sig_wr_clk_polarity.width == wr_ports && sig_wr_clk_polarity.is_fully_const()); - assert(sig_wr_addr.width == wr_ports * addr_bits); - assert(sig_wr_data.width == wr_ports * memory->width); - assert(sig_wr_en.width == wr_ports * memory->width); + assert(sig_wr_clk.__width == wr_ports); + assert(sig_wr_clk_enable.__width == wr_ports && sig_wr_clk_enable.is_fully_const()); + assert(sig_wr_clk_polarity.__width == wr_ports && sig_wr_clk_polarity.is_fully_const()); + assert(sig_wr_addr.__width == wr_ports * addr_bits); + assert(sig_wr_data.__width == wr_ports * memory->width); + assert(sig_wr_en.__width == wr_ports * memory->width); mem->parameters["\\WR_PORTS"] = RTLIL::Const(wr_ports); - mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.chunks[0].data : RTLIL::Const(0, 0); - mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.chunks[0].data : RTLIL::Const(0, 0); + mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.__chunks[0].data : RTLIL::Const(0, 0); + mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.__chunks[0].data : RTLIL::Const(0, 0); mem->connections["\\WR_CLK"] = sig_wr_clk; mem->connections["\\WR_ADDR"] = sig_wr_addr; @@ -162,16 +162,16 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) sig_rd_clk_polarity.optimize(); sig_rd_transparent.optimize(); - assert(sig_rd_clk.width == rd_ports); - assert(sig_rd_clk_enable.width == rd_ports && sig_rd_clk_enable.is_fully_const()); - assert(sig_rd_clk_polarity.width == rd_ports && sig_rd_clk_polarity.is_fully_const()); - assert(sig_rd_addr.width == rd_ports * addr_bits); - assert(sig_rd_data.width == rd_ports * memory->width); + assert(sig_rd_clk.__width == rd_ports); + assert(sig_rd_clk_enable.__width == rd_ports && sig_rd_clk_enable.is_fully_const()); + assert(sig_rd_clk_polarity.__width == rd_ports && sig_rd_clk_polarity.is_fully_const()); + assert(sig_rd_addr.__width == rd_ports * addr_bits); + assert(sig_rd_data.__width == rd_ports * memory->width); mem->parameters["\\RD_PORTS"] = RTLIL::Const(rd_ports); - mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.chunks[0].data : RTLIL::Const(0, 0); - mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.chunks[0].data : RTLIL::Const(0, 0); - mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.chunks[0].data : RTLIL::Const(0, 0); + mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.__chunks[0].data : RTLIL::Const(0, 0); + mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.__chunks[0].data : RTLIL::Const(0, 0); + mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.__chunks[0].data : RTLIL::Const(0, 0); mem->connections["\\RD_CLK"] = sig_rd_clk; mem->connections["\\RD_ADDR"] = sig_rd_addr; diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index e8da6d64..174417bd 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -34,9 +34,9 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI normalize_sig(module, sig); sig.expand(); - 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; @@ -59,11 +59,11 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI normalize_sig(module, q_norm); RTLIL::SigSpec d = q_norm.extract(chunk, &cell->connections[after ? "\\Q" : "\\D"]); - if (d.width != 1) + if (d.__width != 1) continue; - assert(d.chunks.size() == 1); - chunk = d.chunks[0]; + assert(d.__chunks.size() == 1); + chunk = d.__chunks[0]; clk = cell->connections["\\CLK"]; clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); goto replaced_this_bit; @@ -125,7 +125,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) RTLIL::Wire *wire = new RTLIL::Wire; wire->name = sstr.str(); - wire->width = sig.width; + wire->width = sig.__width; module->wires[wire->name] = wire; RTLIL::SigSpec newsig(wire); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 10ab6e2f..b848e09e 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -68,7 +68,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"]; RTLIL::SigSpec refclock; RTLIL::State refclock_pol = RTLIL::State::Sx; - for (int i = 0; i < clocks.width; i++) { + for (int i = 0; i < clocks.__width; i++) { RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(i * mem_width, mem_width); if (wr_en.is_fully_const() && !wr_en.as_bool()) { static_ports.insert(i); @@ -89,7 +89,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) cell->name.c_str(), module->name.c_str(), i); return; } - if (refclock.width == 0) { + if (refclock.__width == 0) { refclock = clocks.extract(i, 1); refclock_pol = clocks_pol.bits[i]; } @@ -277,12 +277,12 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->connections["\\Y"] = w_seladdr; int wr_offset = 0; - while (wr_offset < wr_en.width) + while (wr_offset < wr_en.__width) { int wr_width = 1; RTLIL::SigSpec wr_bit = wr_en.extract(wr_offset, 1); - while (wr_offset + wr_width < wr_en.width) { + while (wr_offset + wr_width < wr_en.__width) { RTLIL::SigSpec next_wr_bit = wr_en.extract(wr_offset + wr_width, 1); if (next_wr_bit != wr_bit) break; diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 578007a0..e56d14b6 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -116,7 +116,7 @@ struct MemoryShareWorker created_conditions++; } - if (terms.width > 1) + if (terms.__width > 1) terms = module->ReduceAnd(NEW_ID, terms); return conditions_logic_cache[conditions] = terms; @@ -254,7 +254,7 @@ struct MemoryShareWorker // this is the naive version of the function that does not care about grouping the EN bits. RTLIL::SigSpec inv_mask_bits = module->Not(NEW_ID, mask_bits); - RTLIL::SigSpec inv_mask_bits_filtered = module->Mux(NEW_ID, RTLIL::SigSpec(RTLIL::State::S1, bits.width), inv_mask_bits, do_mask); + RTLIL::SigSpec inv_mask_bits_filtered = module->Mux(NEW_ID, RTLIL::SigSpec(RTLIL::State::S1, bits.__width), inv_mask_bits, do_mask); RTLIL::SigSpec result = module->And(NEW_ID, inv_mask_bits_filtered, bits); return result; } @@ -269,10 +269,10 @@ struct MemoryShareWorker std::map, std::pair>> groups; RTLIL::SigSpec grouped_bits, grouped_mask_bits; - for (int i = 0; i < bits.width; i++) { + for (int i = 0; i < bits.__width; i++) { std::pair key(v_bits[i], v_mask_bits[i]); if (groups.count(key) == 0) { - groups[key].first = grouped_bits.width; + groups[key].first = grouped_bits.__width; grouped_bits.append_bit(v_bits[i]); grouped_mask_bits.append_bit(v_mask_bits[i]); } @@ -282,7 +282,7 @@ struct MemoryShareWorker std::vector grouped_result = mask_en_naive(do_mask, grouped_bits, grouped_mask_bits); RTLIL::SigSpec result; - for (int i = 0; i < bits.width; i++) { + for (int i = 0; i < bits.__width; i++) { std::pair key(v_bits[i], v_mask_bits[i]); result.append_bit(grouped_result.at(groups.at(key).first)); } @@ -320,7 +320,7 @@ struct MemoryShareWorker // Create the new merged_data signal. - RTLIL::SigSpec new_merged_data(RTLIL::State::Sx, merged_data.width); + RTLIL::SigSpec new_merged_data(RTLIL::State::Sx, merged_data.__width); RTLIL::SigSpec old_data_set = module->And(NEW_ID, merged_en, merged_data); RTLIL::SigSpec old_data_unset = module->And(NEW_ID, merged_en, module->Not(NEW_ID, merged_data)); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index d330fb7b..8a097916 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -106,13 +106,13 @@ static int count_nontrivial_wire_attrs(RTLIL::Wire *w) static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2, SigPool ®s, SigPool &conns, std::set &direct_wires) { - assert(s1.width == 1); - assert(s2.width == 1); - assert(s1.chunks.size() == 1); - assert(s2.chunks.size() == 1); + assert(s1.__width == 1); + assert(s2.__width == 1); + assert(s1.__chunks.size() == 1); + assert(s2.__chunks.size() == 1); - RTLIL::Wire *w1 = s1.chunks[0].wire; - RTLIL::Wire *w2 = s2.chunks[0].wire; + RTLIL::Wire *w1 = s1.__chunks[0].wire; + RTLIL::Wire *w2 = s2.__chunks[0].wire; if (w1 == NULL || w2 == NULL) return w2 == NULL; @@ -235,14 +235,14 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } else { s1.expand(); s2.expand(); - assert(s1.chunks.size() == s2.chunks.size()); + assert(s1.__chunks.size() == s2.__chunks.size()); RTLIL::SigSig new_conn; - for (size_t i = 0; i < s1.chunks.size(); i++) - if (s1.chunks[i] != s2.chunks[i]) { - new_conn.first.append(s1.chunks[i]); - new_conn.second.append(s2.chunks[i]); + for (size_t i = 0; i < s1.__chunks.size(); i++) + if (s1.__chunks[i] != s2.__chunks[i]) { + new_conn.first.append(s1.__chunks[i]); + new_conn.second.append(s2.__chunks[i]); } - if (new_conn.first.width > 0) { + if (new_conn.first.__width > 0) { new_conn.first.optimize(); new_conn.second.optimize(); used_signals.add(new_conn.first); @@ -258,8 +258,8 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (!used_signals_nodrivers.check_any(sig)) { std::string unused_bits; sig.expand(); - for (size_t i = 0; i < sig.chunks.size(); i++) { - if (sig.chunks[i].wire == NULL) + for (size_t i = 0; i < sig.__chunks.size(); i++) { + if (sig.__chunks[i].wire == NULL) continue; if (!used_signals_nodrivers.check_any(sig)) { if (!unused_bits.empty()) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index e855e45e..bee86771 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -56,13 +56,13 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) all_signals.del(driven_signals); RTLIL::SigSpec undriven_signals = all_signals.export_all(); - for (auto &c : undriven_signals.chunks) + for (auto &c : undriven_signals.__chunks) { RTLIL::SigSpec sig = c; if (c.wire->name[0] == '$') sig = used_signals.extract(sig); - if (sig.width == 0) + if (sig.__width == 0) continue; log("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c)); @@ -74,7 +74,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { RTLIL::SigSpec Y = cell->connections[out_port]; - out_val.extend_u0(Y.width, false); + out_val.extend_u0(Y.__width, false); log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", cell->type.c_str(), cell->name.c_str(), info.c_str(), @@ -99,11 +99,11 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::SigSpec sig_y = sigmap(cell->connections.at("\\Y")); if (extend_u0) { - sig_a.extend_u0(sig_y.width, a_signed); - sig_b.extend_u0(sig_y.width, b_signed); + sig_a.extend_u0(sig_y.__width, a_signed); + sig_b.extend_u0(sig_y.__width, b_signed); } else { - sig_a.extend(sig_y.width, a_signed); - sig_b.extend(sig_y.width, b_signed); + sig_a.extend(sig_y.__width, a_signed); + sig_b.extend(sig_y.__width, b_signed); } std::vector bits_a = sig_a, bits_b = sig_b, bits_y = sig_y; @@ -153,7 +153,7 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com for (auto &it : grouped_bits[i]) { for (auto &bit : it.second) { new_conn.first.append_bit(bit); - new_conn.second.append_bit(RTLIL::SigBit(new_y, new_a.width)); + new_conn.second.append_bit(RTLIL::SigBit(new_y, new_a.__width)); } new_a.append_bit(it.first.first); new_b.append_bit(it.first.second); @@ -162,12 +162,12 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); c->connections["\\A"] = new_a; - c->parameters["\\A_WIDTH"] = new_a.width; + c->parameters["\\A_WIDTH"] = new_a.__width; c->parameters["\\A_SIGNED"] = false; if (b_name == "\\B") { c->connections["\\B"] = new_b; - c->parameters["\\B_WIDTH"] = new_b.width; + c->parameters["\\B_WIDTH"] = new_b.__width; c->parameters["\\B_SIGNED"] = false; } @@ -202,7 +202,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (auto &cell_it : module->cells) if (design->selected(module, cell_it.second)) { if ((cell_it.second->type == "$_INV_" || cell_it.second->type == "$not" || cell_it.second->type == "$logic_not") && - cell_it.second->connections["\\A"].width == 1 && cell_it.second->connections["\\Y"].width == 1) + cell_it.second->connections["\\A"].__width == 1 && cell_it.second->connections["\\Y"].__width == 1) invert_map[assign_map(cell_it.second->connections["\\Y"])] = assign_map(cell_it.second->connections["\\A"]); cells.push_back(cell_it.second); } @@ -334,12 +334,12 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); else - replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections.at("\\Y").width)); + replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections.at("\\Y").__width)); goto next_cell; } } - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].width == 1 && + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].__width == 1 && invert_map.count(assign_map(cell->connections["\\A"])) != 0) { replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections["\\A"]))); goto next_cell; @@ -460,35 +460,35 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec new_a, new_b; a.expand(), b.expand(); - assert(a.chunks.size() == b.chunks.size()); - for (size_t i = 0; i < a.chunks.size(); i++) { - if (a.chunks[i].wire == NULL && b.chunks[i].wire == NULL && a.chunks[i].data.bits[0] != b.chunks[i].data.bits[0] && - a.chunks[i].data.bits[0] <= RTLIL::State::S1 && b.chunks[i].data.bits[0] <= RTLIL::State::S1) { + assert(a.__chunks.size() == b.__chunks.size()); + for (size_t i = 0; i < a.__chunks.size(); i++) { + if (a.__chunks[i].wire == NULL && b.__chunks[i].wire == NULL && a.__chunks[i].data.bits[0] != b.__chunks[i].data.bits[0] && + a.__chunks[i].data.bits[0] <= RTLIL::State::S1 && b.__chunks[i].data.bits[0] <= RTLIL::State::S1) { RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S0 : RTLIL::State::S1); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(module, cell, "empty", "\\Y", new_y); goto next_cell; } - if (a.chunks[i] == b.chunks[i]) + if (a.__chunks[i] == b.__chunks[i]) continue; - new_a.append(a.chunks[i]); - new_b.append(b.chunks[i]); + new_a.append(a.__chunks[i]); + new_b.append(b.__chunks[i]); } - if (new_a.width == 0) { + if (new_a.__width == 0) { RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S1 : RTLIL::State::S0); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(module, cell, "empty", "\\Y", new_y); goto next_cell; } - if (new_a.width < a.width || new_b.width < b.width) { + if (new_a.__width < a.__width || new_b.__width < b.__width) { new_a.optimize(); new_b.optimize(); cell->connections["\\A"] = new_a; cell->connections["\\B"] = new_b; - cell->parameters["\\A_WIDTH"] = new_a.width; - cell->parameters["\\B_WIDTH"] = new_b.width; + cell->parameters["\\A_WIDTH"] = new_a.__width; + cell->parameters["\\B_WIDTH"] = new_b.__width; } } @@ -550,10 +550,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec a = assign_map(cell->connections["\\A"]); RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); - if (a.is_fully_const() && a.width <= 32 && a.as_int() == 1) + if (a.is_fully_const() && a.__width <= 32 && a.as_int() == 1) identity_wrt_b = true; - if (b.is_fully_const() && b.width <= 32 && b.as_int() == 1) + if (b.is_fully_const() && b.__width <= 32 && b.as_int() == 1) identity_wrt_a = true; } @@ -561,7 +561,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo { RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); - if (b.is_fully_const() && b.width <= 32 && b.as_int() == 1) + if (b.is_fully_const() && b.__width <= 32 && b.as_int() == 1) identity_wrt_a = true; } @@ -650,13 +650,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->connections.at("\\A").width; + int width = cell->connections.at("\\A").__width; if ((cell->connections.at("\\A").is_fully_undef() && cell->connections.at("\\B").is_fully_undef()) || cell->connections.at("\\S").is_fully_undef()) { replace_cell(module, cell, "mux undef", "\\Y", cell->connections.at("\\A")); goto next_cell; } - for (int i = 0; i < cell->connections.at("\\S").width; i++) { + for (int i = 0; i < cell->connections.at("\\S").__width; i++) { RTLIL::SigSpec old_b = cell->connections.at("\\B").extract(i*width, width); RTLIL::SigSpec old_s = cell->connections.at("\\S").extract(i, 1); if (old_b.is_fully_undef() || old_s.is_fully_undef()) @@ -665,12 +665,12 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo new_s.append(old_s); } new_a = cell->connections.at("\\A"); - if (new_a.is_fully_undef() && new_s.width > 0) { - new_a = new_b.extract((new_s.width-1)*width, width); - new_b = new_b.extract(0, (new_s.width-1)*width); - new_s = new_s.extract(0, new_s.width-1); + if (new_a.is_fully_undef() && new_s.__width > 0) { + new_a = new_b.extract((new_s.__width-1)*width, width); + new_b = new_b.extract(0, (new_s.__width-1)*width); + new_s = new_s.extract(0, new_s.__width-1); } - if (new_s.width == 0) { + if (new_s.__width == 0) { replace_cell(module, cell, "mux undef", "\\Y", new_a); goto next_cell; } @@ -678,13 +678,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo replace_cell(module, cell, "mux undef", "\\Y", new_s); goto next_cell; } - if (cell->connections.at("\\S").width != new_s.width) { + if (cell->connections.at("\\S").__width != new_s.__width) { cell->connections.at("\\A") = new_a; cell->connections.at("\\B") = new_b; cell->connections.at("\\S") = new_s; - if (new_s.width > 1) { + if (new_s.__width > 1) { cell->type = "$pmux"; - cell->parameters["\\S_WIDTH"] = new_s.width; + cell->parameters["\\S_WIDTH"] = new_s.__width; } else { cell->type = "$mux"; cell->parameters.erase("\\S_WIDTH"); @@ -700,9 +700,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo assign_map.apply(a); \ if (a.is_fully_const()) { \ a.optimize(); \ - if (a.chunks.empty()) a.chunks.push_back(RTLIL::SigChunk()); \ + if (a.__chunks.empty()) a.__chunks.push_back(RTLIL::SigChunk()); \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ - RTLIL::SigSpec y(RTLIL::const_ ## _t(a.chunks[0].data, dummy_arg, \ + RTLIL::SigSpec y(RTLIL::const_ ## _t(a.__chunks[0].data, dummy_arg, \ cell->parameters["\\A_SIGNED"].as_bool(), false, \ cell->parameters["\\Y_WIDTH"].as_int())); \ replace_cell(module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ @@ -716,9 +716,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ a.optimize(), b.optimize(); \ - if (a.chunks.empty()) a.chunks.push_back(RTLIL::SigChunk()); \ - if (b.chunks.empty()) b.chunks.push_back(RTLIL::SigChunk()); \ - RTLIL::SigSpec y(RTLIL::const_ ## _t(a.chunks[0].data, b.chunks[0].data, \ + if (a.__chunks.empty()) a.__chunks.push_back(RTLIL::SigChunk()); \ + if (b.__chunks.empty()) b.__chunks.push_back(RTLIL::SigChunk()); \ + RTLIL::SigSpec y(RTLIL::const_ ## _t(a.__chunks[0].data, b.__chunks[0].data, \ cell->parameters["\\A_SIGNED"].as_bool(), \ cell->parameters["\\B_SIGNED"].as_bool(), \ cell->parameters["\\Y_WIDTH"].as_int())); \ @@ -787,10 +787,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec sig_b = assign_map(cell->connections["\\B"]); RTLIL::SigSpec sig_y = assign_map(cell->connections["\\Y"]); - if (sig_b.is_fully_const() && sig_b.width <= 32) + if (sig_b.is_fully_const() && sig_b.__width <= 32) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; - if (sig_a.is_fully_def() && sig_a.width <= 32) + if (sig_a.is_fully_def() && sig_a.__width <= 32) { int a_val = sig_a.as_int(); @@ -799,7 +799,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo log("Replacing multiply-by-zero cell `%s' in module `%s' with zero-driver.\n", cell->name.c_str(), module->name.c_str()); - module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.width))); + module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); module->remove(cell); OPT_DID_SOMETHING = true; @@ -807,7 +807,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - for (int i = 1; i < (a_signed ? sig_a.width-1 : sig_a.width); i++) + for (int i = 1; i < (a_signed ? sig_a.__width-1 : sig_a.__width); i++) if (a_val == (1 << i)) { log("Replacing multiply-by-%d cell `%s' in module `%s' with shift-by-%d.\n", diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 3292a46c..e844a420 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -92,8 +92,8 @@ struct OptMuxtreeWorker muxinfo_t muxinfo; muxinfo.cell = cell; - for (int i = 0; i < sig_s.width; i++) { - RTLIL::SigSpec sig = sig_b.extract(i*sig_a.width, sig_a.width); + for (int i = 0; i < sig_s.__width; i++) { + RTLIL::SigSpec sig = sig_b.extract(i*sig_a.__width, sig_a.__width); RTLIL::SigSpec ctrl_sig = assign_map(sig_s.extract(i, 1)); portinfo_t portinfo; for (int idx : sig2bits(sig)) { @@ -201,7 +201,7 @@ struct OptMuxtreeWorker if (live_ports.size() == 1) { - RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.width, sig_a.width); + RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.__width, sig_a.__width); module->connections.push_back(RTLIL::SigSig(sig_y, sig_in)); module->cells.erase(mi.cell->name); delete mi.cell; @@ -211,7 +211,7 @@ struct OptMuxtreeWorker RTLIL::SigSpec new_sig_a, new_sig_b, new_sig_s; for (size_t i = 0; i < live_ports.size(); i++) { - RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[i]*sig_a.width, sig_a.width); + RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[i]*sig_a.__width, sig_a.__width); if (i == live_ports.size()-1) { new_sig_a = sig_in; } else { @@ -223,11 +223,11 @@ struct OptMuxtreeWorker mi.cell->connections["\\A"] = new_sig_a; mi.cell->connections["\\B"] = new_sig_b; mi.cell->connections["\\S"] = new_sig_s; - if (new_sig_s.width == 1) { + if (new_sig_s.__width == 1) { mi.cell->type = "$mux"; mi.cell->parameters.erase("\\S_WIDTH"); } else { - mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.width); + mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.__width); } } } @@ -260,7 +260,7 @@ struct OptMuxtreeWorker std::vector results; assign_map.apply(sig); sig.expand(); - for (auto &c : sig.chunks) + for (auto &c : sig.__chunks) if (c.wire != NULL) { bitDef_t bit(c.wire, c.offset); if (bit2num.count(bit) == 0) { diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 93945e49..4f1176d9 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -48,7 +48,7 @@ struct OptReduceWorker sig_a.expand(); RTLIL::SigSpec new_sig_a; - for (auto &chunk : sig_a.chunks) + for (auto &chunk : sig_a.__chunks) { if (chunk.wire == NULL && chunk.data.bits[0] == RTLIL::State::S0) { if (cell->type == "$reduce_and") { @@ -85,7 +85,7 @@ struct OptReduceWorker } new_sig_a.sort_and_unify(); - if (new_sig_a != sig_a || sig_a.width != cell->connections["\\A"].width) { + if (new_sig_a != sig_a || sig_a.__width != cell->connections["\\A"].__width) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; OPT_DID_SOMETHING = true; @@ -93,7 +93,7 @@ struct OptReduceWorker } cell->connections["\\A"] = new_sig_a; - cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.__width); return; } @@ -107,20 +107,20 @@ struct OptReduceWorker std::set handled_sig; handled_sig.insert(sig_a); - for (int i = 0; i < sig_s.width; i++) + for (int i = 0; i < sig_s.__width; i++) { - RTLIL::SigSpec this_b = sig_b.extract(i*sig_a.width, sig_a.width); + RTLIL::SigSpec this_b = sig_b.extract(i*sig_a.__width, sig_a.__width); if (handled_sig.count(this_b) > 0) continue; RTLIL::SigSpec this_s = sig_s.extract(i, 1); - for (int j = i+1; j < sig_s.width; j++) { - RTLIL::SigSpec that_b = sig_b.extract(j*sig_a.width, sig_a.width); + for (int j = i+1; j < sig_s.__width; j++) { + RTLIL::SigSpec that_b = sig_b.extract(j*sig_a.__width, sig_a.__width); if (this_b == that_b) this_s.append(sig_s.extract(j, 1)); } - if (this_s.width > 1) + if (this_s.__width > 1) { RTLIL::Wire *reduce_or_wire = new RTLIL::Wire; reduce_or_wire->name = NEW_ID; @@ -131,7 +131,7 @@ struct OptReduceWorker reduce_or_cell->type = "$reduce_or"; reduce_or_cell->connections["\\A"] = this_s; reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.width); + reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.__width); reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->cells[reduce_or_cell->name] = reduce_or_cell; @@ -144,14 +144,14 @@ struct OptReduceWorker handled_sig.insert(this_b); } - if (new_sig_s.width != sig_s.width) { + if (new_sig_s.__width != sig_s.__width) { log(" New ctrl vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_s)); did_something = true; OPT_DID_SOMETHING = true; total_count++; } - if (new_sig_s.width == 0) + if (new_sig_s.__width == 0) { module->connections.push_back(RTLIL::SigSig(cell->connections["\\Y"], cell->connections["\\A"])); assign_map.add(cell->connections["\\Y"], cell->connections["\\A"]); @@ -162,8 +162,8 @@ struct OptReduceWorker { cell->connections["\\B"] = new_sig_b; cell->connections["\\S"] = new_sig_s; - if (new_sig_s.width > 1) { - cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.width); + if (new_sig_s.__width > 1) { + cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.__width); } else { cell->type = "$mux"; cell->parameters.erase("\\S_WIDTH"); @@ -224,7 +224,7 @@ struct OptReduceWorker cell->connections["\\A"].append(in_tuple.at(0)); cell->connections["\\B"] = RTLIL::SigSpec(); - for (int i = 1; i <= cell->connections["\\S"].width; i++) + for (int i = 1; i <= cell->connections["\\S"].__width; i++) for (auto &in_tuple : consolidated_in_tuples) cell->connections["\\B"].append(in_tuple.at(i)); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 9a438537..879f7ddc 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -100,7 +100,7 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) } } - if (sig_c.is_fully_const() && (!sig_r.width || !has_init)) { + if (sig_c.is_fully_const() && (!sig_r.__width || !has_init)) { if (val_rv.bits.size() == 0) val_rv = val_init; RTLIL::SigSig conn(sig_q, val_rv); @@ -108,26 +108,26 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) goto delete_dff; } - if (sig_d.is_fully_undef() && sig_r.width && !has_init) { + if (sig_d.is_fully_undef() && sig_r.__width && !has_init) { RTLIL::SigSig conn(sig_q, val_rv); mod->connections.push_back(conn); goto delete_dff; } - if (sig_d.is_fully_undef() && !sig_r.width && has_init) { + if (sig_d.is_fully_undef() && !sig_r.__width && has_init) { RTLIL::SigSig conn(sig_q, val_init); mod->connections.push_back(conn); goto delete_dff; } - if (sig_d.is_fully_const() && !sig_r.width && !has_init) { + if (sig_d.is_fully_const() && !sig_r.__width && !has_init) { RTLIL::SigSig conn(sig_q, sig_d); mod->connections.push_back(conn); goto delete_dff; } - if (sig_d == sig_q && !(sig_r.width && has_init)) { - if (sig_r.width) { + if (sig_d == sig_q && !(sig_r.__width && has_init)) { + if (sig_r.__width) { RTLIL::SigSig conn(sig_q, val_rv); mod->connections.push_back(conn); } @@ -182,7 +182,7 @@ struct OptRmdffPass : public Pass { std::vector dff_list; for (auto &it : mod_it.second->cells) { if (it.second->type == "$mux" || it.second->type == "$pmux") { - if (it.second->connections.at("\\A").width == it.second->connections.at("\\B").width) + if (it.second->connections.at("\\A").__width == it.second->connections.at("\\B").__width) mux_drivers.insert(assign_map(it.second->connections.at("\\Y")), it.second); continue; } diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index eb639d8a..07e512cb 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -97,7 +97,7 @@ struct OptShareWorker RTLIL::SigSpec sig = it.second; assign_map.apply(sig); hash_string += "C " + it.first + "="; - for (auto &chunk : sig.chunks) { + for (auto &chunk : sig.__chunks) { if (chunk.wire) hash_string += "{" + chunk.wire->name + " " + int_to_hash_string(chunk.offset) + " " + diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 057378e7..a773e5e7 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -28,7 +28,7 @@ extern void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity) { - if (signal.width != 1) + if (signal.__width != 1) return false; if (signal == ref) return true; @@ -80,13 +80,13 @@ static void apply_const(RTLIL::Module *mod, const RTLIL::SigSpec rspec, RTLIL::S { for (auto &action : cs->actions) { if (unknown) - rspec.replace(action.first, RTLIL::SigSpec(RTLIL::State::Sm, action.second.width), &rval); + rspec.replace(action.first, RTLIL::SigSpec(RTLIL::State::Sm, action.second.__width), &rval); else rspec.replace(action.first, action.second, &rval); } for (auto sw : cs->switches) { - if (sw->signal.width == 0) { + if (sw->signal.__width == 0) { for (auto cs2 : sw->cases) apply_const(mod, rspec, rval, cs2, const_sig, polarity, unknown); } @@ -164,11 +164,11 @@ restart_proc_arst: } for (auto &action : sync->actions) { RTLIL::SigSpec rspec = action.second; - RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.width); + RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.__width); rspec.expand(), rval.expand(); - for (int i = 0; i < int(rspec.chunks.size()); i++) - if (rspec.chunks[i].wire == NULL) - rval.chunks[i] = rspec.chunks[i]; + for (int i = 0; i < int(rspec.__chunks.size()); i++) + if (rspec.__chunks[i].wire == NULL) + rval.__chunks[i] = rspec.__chunks[i]; rspec.optimize(), rval.optimize(); RTLIL::SigSpec last_rval; for (int count = 0; rval != last_rval; count++) { @@ -252,14 +252,14 @@ struct ProcArstPass : public Pass { if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) for (auto &act : sync->actions) { RTLIL::SigSpec arst_sig, arst_val; - for (auto &chunk : act.first.chunks) + for (auto &chunk : act.first.__chunks) if (chunk.wire && chunk.wire->attributes.count("\\init")) { RTLIL::SigSpec value = chunk.wire->attributes.at("\\init"); value.extend(chunk.wire->width, false); arst_sig.append(chunk); arst_val.append(value.extract(chunk.offset, chunk.width)); } - if (arst_sig.width) { + if (arst_sig.__width) { log("Added global reset to process %s: %s <- %s\n", proc_it.first.c_str(), log_signal(arst_sig), log_signal(arst_val)); arst_actions.push_back(RTLIL::SigSig(arst_sig, arst_val)); diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 83554df9..76866068 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -27,7 +27,7 @@ extern void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth) { - if (sw->signal.width > 0 && sw->signal.is_fully_const()) + if (sw->signal.__width > 0 && sw->signal.is_fully_const()) { int found_matching_case_idx = -1; for (int i = 0; i < int(sw->cases.size()) && found_matching_case_idx < 0; i++) @@ -59,7 +59,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did sw->signal = RTLIL::SigSpec(); } - if (sw->cases.size() == 1 && (sw->signal.width == 0 || sw->cases[0]->compare.empty())) + if (sw->cases.size() == 1 && (sw->signal.__width == 0 || sw->cases[0]->compare.empty())) { did_something = true; for (auto &action : sw->cases[0]->actions) @@ -91,7 +91,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth) { for (size_t i = 0; i < cs->actions.size(); i++) { - if (cs->actions[i].first.width == 0) { + if (cs->actions[i].first.__width == 0) { did_something = true; cs->actions.erase(cs->actions.begin() + (i--)); } @@ -114,7 +114,7 @@ static void proc_clean(RTLIL::Module *mod, RTLIL::Process *proc, int &total_coun bool did_something = true; for (size_t i = 0; i < proc->syncs.size(); i++) { for (size_t j = 0; j < proc->syncs[i]->actions.size(); j++) - if (proc->syncs[i]->actions[j].first.width == 0) + if (proc->syncs[i]->actions[j].first.__width == 0) proc->syncs[i]->actions.erase(proc->syncs[i]->actions.begin() + (j--)); if (proc->syncs[i]->actions.size() == 0) { delete proc->syncs[i]; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 13e4e660..d3dff8ef 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -32,7 +32,7 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) for (auto sync : proc->syncs) for (auto &action : sync->actions) - if (action.first.width > 0) { + if (action.first.__width > 0) { lvalue = action.first; lvalue.sort_and_unify(); break; @@ -44,7 +44,7 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) this_lvalue.append(action.first); this_lvalue.sort_and_unify(); RTLIL::SigSpec common_sig = this_lvalue.extract(lvalue); - if (common_sig.width > 0) + if (common_sig.__width > 0) lvalue = common_sig; } @@ -54,8 +54,8 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::SigSpec clk, bool clk_polarity, std::map> &async_rules, RTLIL::Process *proc) { - RTLIL::SigSpec sig_sr_set = RTLIL::SigSpec(0, sig_d.width); - RTLIL::SigSpec sig_sr_clr = RTLIL::SigSpec(0, sig_d.width); + RTLIL::SigSpec sig_sr_set = RTLIL::SigSpec(0, sig_d.__width); + RTLIL::SigSpec sig_sr_clr = RTLIL::SigSpec(0, sig_d.__width); for (auto &it : async_rules) { @@ -72,24 +72,24 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S else log_abort(); - if (sync_low_signals.width > 1) { + if (sync_low_signals.__width > 1) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$reduce_or"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.__width); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; cell->connections["\\Y"] = sync_low_signals = mod->addWire(NEW_ID); mod->add(cell); } - if (sync_low_signals.width > 0) { + if (sync_low_signals.__width > 0) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$not"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.__width); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; cell->connections["\\Y"] = mod->addWire(NEW_ID); @@ -97,12 +97,12 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S mod->add(cell); } - if (sync_high_signals.width > 1) { + if (sync_high_signals.__width > 1) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$reduce_or"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.__width); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_high_signals; cell->connections["\\Y"] = sync_high_signals = mod->addWire(NEW_ID); @@ -113,30 +113,30 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S inv_cell->name = NEW_ID; inv_cell->type = "$not"; inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.width); - inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.width); + inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.__width); + inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.__width); inv_cell->connections["\\A"] = sync_value; - inv_cell->connections["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.width); + inv_cell->connections["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.__width); mod->add(inv_cell); RTLIL::Cell *mux_set_cell = new RTLIL::Cell; mux_set_cell->name = NEW_ID; mux_set_cell->type = "$mux"; - mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.width); + mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.__width); mux_set_cell->connections["\\A"] = sig_sr_set; mux_set_cell->connections["\\B"] = sync_value; mux_set_cell->connections["\\S"] = sync_high_signals; - mux_set_cell->connections["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.width); + mux_set_cell->connections["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.__width); mod->add(mux_set_cell); RTLIL::Cell *mux_clr_cell = new RTLIL::Cell; mux_clr_cell->name = NEW_ID; mux_clr_cell->type = "$mux"; - mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.width); + mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.__width); mux_clr_cell->connections["\\A"] = sig_sr_clr; mux_clr_cell->connections["\\B"] = sync_value_inv; mux_clr_cell->connections["\\S"] = sync_high_signals; - mux_clr_cell->connections["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.width); + mux_clr_cell->connections["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.__width); mod->add(mux_clr_cell); } @@ -147,7 +147,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->name = sstr.str(); cell->type = "$dffsr"; cell->attributes = proc->attributes; - cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.width); + cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.__width); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); @@ -168,16 +168,16 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec std::stringstream sstr; sstr << "$procdff$" << (RTLIL::autoidx++); - RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.width); - RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.width); - RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.width); + RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.__width); + RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.__width); + RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.__width); RTLIL::Cell *inv_set = new RTLIL::Cell; inv_set->name = NEW_ID; inv_set->type = "$not"; inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0); - inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.width); - inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.width); + inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.__width); + inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.__width); inv_set->connections["\\A"] = sig_set; inv_set->connections["\\Y"] = sig_set_inv; mod->add(inv_set); @@ -185,8 +185,8 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec RTLIL::Cell *mux_sr_set = new RTLIL::Cell; mux_sr_set->name = NEW_ID; mux_sr_set->type = "$mux"; - mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.width); - mux_sr_set->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.width); + mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); + mux_sr_set->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.__width); mux_sr_set->connections[set_polarity ? "\\B" : "\\A"] = sig_set; mux_sr_set->connections["\\Y"] = sig_sr_set; mux_sr_set->connections["\\S"] = set; @@ -195,8 +195,8 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec RTLIL::Cell *mux_sr_clr = new RTLIL::Cell; mux_sr_clr->name = NEW_ID; mux_sr_clr->type = "$mux"; - mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.width); - mux_sr_clr->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.width); + mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); + mux_sr_clr->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.__width); mux_sr_clr->connections[set_polarity ? "\\B" : "\\A"] = sig_set_inv; mux_sr_clr->connections["\\Y"] = sig_sr_clr; mux_sr_clr->connections["\\S"] = set; @@ -206,7 +206,7 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec cell->name = sstr.str(); cell->type = "$dffsr"; cell->attributes = proc->attributes; - cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.width); + cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); @@ -233,7 +233,7 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ cell->attributes = proc->attributes; mod->cells[cell->name] = cell; - cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.width); + cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); if (arst) { cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity, 1); cell->parameters["\\ARST_VALUE"] = val_rst; @@ -259,14 +259,14 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) RTLIL::SigSpec sig = find_any_lvalue(proc); bool free_sync_level = false; - if (sig.width == 0) + if (sig.__width == 0) break; log("Creating register for signal `%s.%s' using process `%s.%s'.\n", mod->name.c_str(), log_signal(sig), mod->name.c_str(), proc->name.c_str()); - RTLIL::SigSpec insig = RTLIL::SigSpec(RTLIL::State::Sz, sig.width); - RTLIL::SigSpec rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.width); + RTLIL::SigSpec insig = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); + RTLIL::SigSpec rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); RTLIL::SyncRule *sync_level = NULL; RTLIL::SyncRule *sync_edge = NULL; RTLIL::SyncRule *sync_always = NULL; @@ -276,16 +276,16 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) for (auto sync : proc->syncs) for (auto &action : sync->actions) { - if (action.first.extract(sig).width == 0) + if (action.first.extract(sig).__width == 0) continue; if (sync->type == RTLIL::SyncType::ST0 || sync->type == RTLIL::SyncType::ST1) { if (sync_level != NULL && sync_level != sync) { // log_error("Multiple level sensitive events found for this signal!\n"); many_async_rules[rstval].insert(sync_level); - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); } - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); sig.replace(action.first, action.second, &rstval); sync_level = sync; } @@ -324,15 +324,15 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) inputs.append(it->signal); compare.append(it->type == RTLIL::SyncType::ST0 ? RTLIL::State::S1 : RTLIL::State::S0); } - assert(inputs.width == compare.width); + assert(inputs.__width == compare.__width); RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$ne"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(false, 1); cell->parameters["\\B_SIGNED"] = RTLIL::Const(false, 1); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.width); - cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.__width); + cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.__width); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = inputs; cell->connections["\\B"] = compare; @@ -343,7 +343,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) } else { - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); sync_level = NULL; } } @@ -357,7 +357,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) sig.optimize(); if (rstval == sig) { - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); sync_level = NULL; } @@ -386,7 +386,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) sync_edge->signal, sync_level->signal, proc); } else - gen_dff(mod, insig, rstval.chunks[0].data, sig, + gen_dff(mod, insig, rstval.__chunks[0].data, sig, sync_edge->type == RTLIL::SyncType::STp, sync_level && sync_level->type == RTLIL::SyncType::ST1, sync_edge->signal, sync_level ? &sync_level->signal : NULL, proc); diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index fca20fda..0ef17b22 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -60,13 +60,13 @@ static void proc_init(RTLIL::Module *mod, RTLIL::Process *proc) log_cmd_error("Failed to get a constant init value for %s: %s\n", log_signal(lhs), log_signal(rhs)); int offset = 0; - for (size_t i = 0; i < lhs.chunks.size(); i++) { - if (lhs.chunks[i].wire == NULL) + for (size_t i = 0; i < lhs.__chunks.size(); i++) { + if (lhs.__chunks[i].wire == NULL) continue; - RTLIL::Wire *wire = lhs.chunks[i].wire; - RTLIL::SigSpec value = rhs.extract(offset, lhs.chunks[i].width); - if (value.width != wire->width) - log_cmd_error("Init value is not for the entire wire: %s = %s\n", log_signal(lhs.chunks[i]), log_signal(value)); + RTLIL::Wire *wire = lhs.__chunks[i].wire; + RTLIL::SigSpec value = rhs.extract(offset, lhs.__chunks[i].width); + if (value.__width != wire->width) + log_cmd_error("Init value is not for the entire wire: %s = %s\n", log_signal(lhs.__chunks[i]), log_signal(value)); log(" Setting init value: %s = %s\n", log_signal(wire), log_signal(value)); wire->attributes["\\init"] = value.as_const(); offset += wire->width; diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 9b2f8388..2e24e786 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -28,14 +28,14 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::CaseRule *cs) { for (auto &action : cs->actions) { - if (action.first.width) + if (action.first.__width) return action.first; } for (auto sw : cs->switches) for (auto cs2 : sw->cases) { RTLIL::SigSpec sig = find_any_lvalue(cs2); - if (sig.width) + if (sig.__width) return sig; } @@ -46,7 +46,7 @@ static void extract_core_signal(const RTLIL::CaseRule *cs, RTLIL::SigSpec &sig) { for (auto &action : cs->actions) { RTLIL::SigSpec lvalue = action.first.extract(sig); - if (lvalue.width) + if (lvalue.__width) sig = lvalue; } @@ -72,18 +72,18 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, comp.expand(); // get rid of don't-care bits - assert(sig.width == comp.width); - for (int i = 0; i < comp.width; i++) - if (comp.chunks[i].wire == NULL && comp.chunks[i].data.bits[0] == RTLIL::State::Sa) { + assert(sig.__width == comp.__width); + for (int i = 0; i < comp.__width; i++) + if (comp.__chunks[i].wire == NULL && comp.__chunks[i].data.bits[0] == RTLIL::State::Sa) { sig.remove(i, 1); comp.remove(i--, 1); } - if (comp.width == 0) + if (comp.__width == 0) return RTLIL::SigSpec(); sig.optimize(); comp.optimize(); - if (sig.width == 1 && comp == RTLIL::SigSpec(1,1)) + if (sig.__width == 1 && comp == RTLIL::SigSpec(1,1)) { mod->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, 1, cmp_wire->width++), sig)); } @@ -101,8 +101,8 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0); - eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.width); - eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.width); + eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.__width); + eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.__width); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); eq_cell->connections["\\A"] = sig; @@ -143,7 +143,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::SigSpec else_signal, RTLIL::Cell *&last_mux_cell, RTLIL::SwitchRule *sw) { - assert(when_signal.width == else_signal.width); + assert(when_signal.__width == else_signal.__width); std::stringstream sstr; sstr << "$procmux$" << (RTLIL::autoidx++); @@ -154,14 +154,14 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, // compare results RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); - if (ctrl_sig.width == 0) + if (ctrl_sig.__width == 0) return when_signal; - assert(ctrl_sig.width == 1); + assert(ctrl_sig.__width == 1); // prepare multiplexer output signal RTLIL::Wire *result_wire = new RTLIL::Wire; result_wire->name = sstr.str() + "_Y"; - result_wire->width = when_signal.width; + result_wire->width = when_signal.__width; mod->wires[result_wire->name] = result_wire; // create the multiplexer itself @@ -171,7 +171,7 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, mux_cell->attributes = sw->attributes; mod->cells[mux_cell->name] = mux_cell; - mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.width); + mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.__width); mux_cell->connections["\\A"] = else_signal; mux_cell->connections["\\B"] = when_signal; mux_cell->connections["\\S"] = ctrl_sig; @@ -184,14 +184,14 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw) { assert(last_mux_cell != NULL); - assert(when_signal.width == last_mux_cell->connections["\\A"].width); + assert(when_signal.__width == last_mux_cell->connections["\\A"].__width); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); - assert(ctrl_sig.width == 1); + assert(ctrl_sig.__width == 1); last_mux_cell->type = "$pmux"; last_mux_cell->connections["\\S"].append(ctrl_sig); last_mux_cell->connections["\\B"].append(when_signal); - last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->connections["\\S"].width; + last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->connections["\\S"].__width; } static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs, const RTLIL::SigSpec &sig, const RTLIL::SigSpec &defval) @@ -208,7 +208,7 @@ static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs // detect groups of parallel cases std::vector pgroups(sw->cases.size()); if (!sw->get_bool_attribute("\\parallel_case")) { - BitPatternPool pool(sw->signal.width); + BitPatternPool pool(sw->signal.__width); bool extra_group_for_next_case = false; for (size_t i = 0; i < sw->cases.size(); i++) { RTLIL::CaseRule *cs2 = sw->cases[i]; @@ -224,7 +224,7 @@ static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs if (cs2->compare.empty()) pgroups[i] = pgroups[i-1]+1; if (pgroups[i] != pgroups[i-1]) - pool = BitPatternPool(sw->signal.width); + pool = BitPatternPool(sw->signal.__width); } for (auto pat : cs2->compare) if (!pat.is_fully_const()) @@ -258,7 +258,7 @@ static void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc) { RTLIL::SigSpec sig = find_any_lvalue(&proc->root_case); - if (sig.width == 0) + if (sig.__width == 0) break; if (first) { @@ -270,7 +270,7 @@ static void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc) log(" creating decoder for signal `%s'.\n", log_signal(sig)); - RTLIL::SigSpec value = signal_to_mux_tree(mod, &proc->root_case, sig, RTLIL::SigSpec(RTLIL::State::Sx, sig.width)); + RTLIL::SigSpec value = signal_to_mux_tree(mod, &proc->root_case, sig, RTLIL::SigSpec(RTLIL::State::Sx, sig.__width)); mod->connections.push_back(RTLIL::SigSig(sig, value)); } } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 5c38cc2c..5369617b 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -44,7 +44,7 @@ struct BruteForceEquivChecker void run_checker(RTLIL::SigSpec &inputs) { - if (inputs.width < mod1_inputs.width) { + if (inputs.__width < mod1_inputs.__width) { RTLIL::SigSpec inputs0 = inputs, inputs1 = inputs; inputs0.append(RTLIL::Const(0, 1)); inputs1.append(RTLIL::Const(1, 1)); @@ -71,9 +71,9 @@ struct BruteForceEquivChecker if (ignore_x_mod1) { sig1.expand(), sig2.expand(); - for (size_t i = 0; i < sig1.chunks.size(); i++) - if (sig1.chunks.at(i) == RTLIL::SigChunk(RTLIL::State::Sx)) - sig2.chunks.at(i) = RTLIL::SigChunk(RTLIL::State::Sx); + for (size_t i = 0; i < sig1.__chunks.size(); i++) + if (sig1.__chunks.at(i) == RTLIL::SigChunk(RTLIL::State::Sx)) + sig2.__chunks.at(i) = RTLIL::SigChunk(RTLIL::State::Sx); sig1.optimize(), sig2.optimize(); } @@ -172,11 +172,11 @@ struct VlogHammerReporter log_error("Failed to find solution to SAT problem.\n"); expected_y.expand(); - for (int i = 0; i < expected_y.width; i++) { + for (int i = 0; i < expected_y.__width; i++) { RTLIL::State solution_bit = y_values.at(i) ? RTLIL::State::S1 : RTLIL::State::S0; - RTLIL::State expected_bit = expected_y.chunks.at(i).data.bits.at(0); + RTLIL::State expected_bit = expected_y.__chunks.at(i).data.bits.at(0); if (model_undef) { - if (y_values.at(expected_y.width+i)) + if (y_values.at(expected_y.__width+i)) solution_bit = RTLIL::State::Sx; } else { if (expected_bit == RTLIL::State::Sx) @@ -184,17 +184,17 @@ struct VlogHammerReporter } if (solution_bit != expected_bit) { std::string sat_bits, rtl_bits; - for (int k = expected_y.width-1; k >= 0; k--) { - if (model_undef && y_values.at(expected_y.width+k)) + for (int k = expected_y.__width-1; k >= 0; k--) { + if (model_undef && y_values.at(expected_y.__width+k)) sat_bits += "x"; else sat_bits += y_values.at(k) ? "1" : "0"; - rtl_bits += expected_y.chunks.at(k).data.bits.at(0) == RTLIL::State::Sx ? "x" : - expected_y.chunks.at(k).data.bits.at(0) == RTLIL::State::S1 ? "1" : "0"; + rtl_bits += expected_y.__chunks.at(k).data.bits.at(0) == RTLIL::State::Sx ? "x" : + expected_y.__chunks.at(k).data.bits.at(0) == RTLIL::State::S1 ? "1" : "0"; } log_error("Found error in SAT model: y[%d] = %s, should be %s:\n SAT: %s\n RTL: %s\n %*s^\n", int(i), log_signal(solution_bit), log_signal(expected_bit), - sat_bits.c_str(), rtl_bits.c_str(), expected_y.width-i-1, ""); + sat_bits.c_str(), rtl_bits.c_str(), expected_y.__width-i-1, ""); } } @@ -203,16 +203,16 @@ struct VlogHammerReporter std::vector cmp_vars; std::vector cmp_vals; - std::vector y_undef(y_values.begin() + expected_y.width, y_values.end()); + std::vector y_undef(y_values.begin() + expected_y.__width, y_values.end()); - for (int i = 0; i < expected_y.width; i++) + for (int i = 0; i < expected_y.__width; i++) if (y_undef.at(i)) { log(" Toggling undef bit %d to test undef gating.\n", i); if (!ez.solve(y_vec, y_values, ez.IFF(y_vec.at(i), y_values.at(i) ? ez.FALSE : ez.TRUE))) log_error("Failed to find solution with toggled bit!\n"); - cmp_vars.push_back(y_vec.at(expected_y.width + i)); + cmp_vars.push_back(y_vec.at(expected_y.__width + i)); cmp_vals.push_back(true); } else @@ -220,7 +220,7 @@ struct VlogHammerReporter cmp_vars.push_back(y_vec.at(i)); cmp_vals.push_back(y_values.at(i)); - cmp_vars.push_back(y_vec.at(expected_y.width + i)); + cmp_vars.push_back(y_vec.at(expected_y.__width + i)); cmp_vals.push_back(false); } @@ -283,7 +283,7 @@ struct VlogHammerReporter while (!ce.eval(sig, undef)) { // log_error("Evaluation of y in module %s failed: sig=%s, undef=%s\n", RTLIL::id2cstr(module->name), log_signal(sig), log_signal(undef)); log("Warning: Setting signal %s in module %s to undef.\n", log_signal(undef), RTLIL::id2cstr(module->name)); - ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.width)); + ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.__width)); } log("++VAL++ %d %s %s #\n", idx, module_name.c_str(), sig.as_const().as_string().c_str()); @@ -293,13 +293,13 @@ struct VlogHammerReporter rtl_sig.expand(); sat_check(module, recorded_set_vars, recorded_set_vals, sig, false); sat_check(module, recorded_set_vars, recorded_set_vals, sig, true); - } else if (rtl_sig.width > 0) { + } else if (rtl_sig.__width > 0) { sig.expand(); - if (rtl_sig.width != sig.width) + if (rtl_sig.__width != sig.__width) log_error("Output (y) has a different width in module %s compared to rtl!\n", RTLIL::id2cstr(module->name)); - for (int i = 0; i < sig.width; i++) - if (rtl_sig.chunks.at(i).data.bits.at(0) == RTLIL::State::Sx) - sig.chunks.at(i).data.bits.at(0) = RTLIL::State::Sx; + for (int i = 0; i < sig.__width; i++) + if (rtl_sig.__chunks.at(i).data.bits.at(0) == RTLIL::State::Sx) + sig.__chunks.at(i).data.bits.at(0) = RTLIL::State::Sx; } log("++RPT++ %d%s %s %s\n", idx, input_pattern_list.c_str(), sig.as_const().as_string().c_str(), module_name.c_str()); @@ -350,7 +350,7 @@ struct VlogHammerReporter } if (!RTLIL::SigSpec::parse(sig, NULL, pattern) || !sig.is_fully_const()) log_error("Failed to parse pattern %s!\n", pattern.c_str()); - if (sig.width < total_input_width) + if (sig.__width < total_input_width) log_error("Pattern %s is to short!\n", pattern.c_str()); patterns.push_back(sig.as_const()); if (invert_pattern) { @@ -470,9 +470,9 @@ struct EvalPass : public Pass { log_cmd_error("Failed to parse rhs set expression `%s'.\n", it.second.c_str()); if (!rhs.is_fully_const()) log_cmd_error("Right-hand-side set expression `%s' is not constant.\n", it.second.c_str()); - if (lhs.width != rhs.width) + if (lhs.__width != rhs.__width) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - it.first.c_str(), log_signal(lhs), lhs.width, it.second.c_str(), log_signal(rhs), rhs.width); + it.first.c_str(), log_signal(lhs), lhs.__width, it.second.c_str(), log_signal(rhs), rhs.__width); ce.set(lhs, rhs.as_const()); } @@ -493,7 +493,7 @@ struct EvalPass : public Pass { if (set_undef) { while (!ce.eval(value, undef)) { log("Failed to evaluate signal %s: Missing value for %s. -> setting to undef\n", log_signal(signal), log_signal(undef)); - ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.width)); + ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.__width)); undef = RTLIL::SigSpec(); } log("Eval result: %s = %s.\n", log_signal(signal), log_signal(value)); @@ -526,15 +526,15 @@ struct EvalPass : public Pass { } std::vector tab_line; - for (auto &c : tabsigs.chunks) + for (auto &c : tabsigs.__chunks) tab_line.push_back(log_signal(c)); tab_sep_colidx = tab_line.size(); - for (auto &c : signal.chunks) + for (auto &c : signal.__chunks) tab_line.push_back(log_signal(c)); tab.push_back(tab_line); tab_line.clear(); - RTLIL::Const tabvals(0, tabsigs.width); + RTLIL::Const tabvals(0, tabsigs.__width); do { ce.push(); @@ -548,19 +548,19 @@ struct EvalPass : public Pass { log_signal(tabsigs), log_signal(tabvals), log_signal(this_undef)); return; } - ce.set(this_undef, RTLIL::Const(RTLIL::State::Sx, this_undef.width)); + ce.set(this_undef, RTLIL::Const(RTLIL::State::Sx, this_undef.__width)); undef.append(this_undef); this_undef = RTLIL::SigSpec(); } int pos = 0; - for (auto &c : tabsigs.chunks) { + for (auto &c : tabsigs.__chunks) { tab_line.push_back(log_signal(RTLIL::SigSpec(tabvals).extract(pos, c.width))); pos += c.width; } pos = 0; - for (auto &c : signal.chunks) { + for (auto &c : signal.__chunks) { tab_line.push_back(log_signal(value.extract(pos, c.width))); pos += c.width; } @@ -602,7 +602,7 @@ struct EvalPass : public Pass { } log("\n"); - if (undef.width > 0) { + if (undef.__width > 0) { undef.sort_and_unify(); log("Assumend undef (x) value for the following singals: %s\n\n", log_signal(undef)); } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 831a43aa..4308e736 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -649,7 +649,7 @@ struct ExposePass : public Pass { { RTLIL::Wire *w = new RTLIL::Wire; w->name = cell->name + sep + RTLIL::unescape_id(it.first); - w->width = it.second.width; + w->width = it.second.__width; if (ct.cell_input(cell->type, it.first)) w->port_output = true; if (ct.cell_output(cell->type, it.first)) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index ac041564..8cc59b29 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -714,7 +714,7 @@ struct FreduceWorker if (grp[i].inverted) { - if (inv_sig.width == 0) + if (inv_sig.__width == 0) { inv_sig = module->addWire(NEW_ID); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 6e57fceb..1cd794b5 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -253,11 +253,11 @@ static void create_miter_equiv(struct Pass *that, std::vector args, } } - if (all_conditions.width != 1) { + if (all_conditions.__width != 1) { RTLIL::Cell *reduce_cell = new RTLIL::Cell; reduce_cell->name = NEW_ID; reduce_cell->type = "$reduce_and"; - reduce_cell->parameters["\\A_WIDTH"] = all_conditions.width; + reduce_cell->parameters["\\A_WIDTH"] = all_conditions.__width; reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; reduce_cell->connections["\\A"] = all_conditions; @@ -283,8 +283,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::Cell *not_cell = new RTLIL::Cell; not_cell->name = NEW_ID; not_cell->type = "$not"; - not_cell->parameters["\\A_WIDTH"] = all_conditions.width; - not_cell->parameters["\\A_WIDTH"] = all_conditions.width; + not_cell->parameters["\\A_WIDTH"] = all_conditions.__width; + not_cell->parameters["\\A_WIDTH"] = all_conditions.__width; not_cell->parameters["\\Y_WIDTH"] = w_trigger->width; not_cell->parameters["\\A_SIGNED"] = 0; not_cell->connections["\\A"] = all_conditions; diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index a9a00d8a..16144932 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -101,10 +101,10 @@ struct SatHelper RTLIL::SigSpec lhs = sigmap(it.second); RTLIL::SigSpec rhs = it.second->attributes.at("\\init"); - log_assert(lhs.width == rhs.width); + log_assert(lhs.__width == rhs.__width); RTLIL::SigSpec removed_bits; - for (int i = 0; i < lhs.width; i++) { + for (int i = 0; i < lhs.__width; i++) { RTLIL::SigSpec bit = lhs.extract(i, 1); if (!satgen.initial_state.check_all(bit)) { removed_bits.append(bit); @@ -118,10 +118,10 @@ struct SatHelper rhs.optimize(); removed_bits.optimize(); - if (removed_bits.width) + if (removed_bits.__width) log("Warning: ignoring initial value on non-register: %s\n", log_signal(removed_bits)); - if (lhs.width) { + if (lhs.__width) { log("Import set-constraint from init attribute: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); big_lhs.append(lhs); @@ -140,9 +140,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.width != rhs.width) + if (lhs.__width != rhs.__width) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.width, s.second.c_str(), log_signal(rhs), rhs.width); + s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); log("Import set-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -166,17 +166,17 @@ struct SatHelper RTLIL::SigSpec rem = satgen.initial_state.export_all(); rem.remove(big_lhs); big_lhs.append(rem); - big_rhs.append(RTLIL::SigSpec(RTLIL::State::Sx, rem.width)); + big_rhs.append(RTLIL::SigSpec(RTLIL::State::Sx, rem.__width)); } if (set_init_zero) { RTLIL::SigSpec rem = satgen.initial_state.export_all(); rem.remove(big_lhs); big_lhs.append(rem); - big_rhs.append(RTLIL::SigSpec(RTLIL::State::S0, rem.width)); + big_rhs.append(RTLIL::SigSpec(RTLIL::State::S0, rem.__width)); } - if (big_lhs.width == 0) { + if (big_lhs.__width == 0) { log("No constraints for initial state found.\n\n"); return; } @@ -209,9 +209,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.width != rhs.width) + if (lhs.__width != rhs.__width) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.width, s.second.c_str(), log_signal(rhs), rhs.width); + s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); log("Import set-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -230,9 +230,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.width != rhs.width) + if (lhs.__width != rhs.__width) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.width, s.second.c_str(), log_signal(rhs), rhs.width); + s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); log("Import set-constraint for this timestep: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -358,9 +358,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.width != rhs.width) + if (lhs.__width != rhs.__width) log_cmd_error("Proof expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.width, s.second.c_str(), log_signal(rhs), rhs.width); + s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); log("Import proof-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -386,9 +386,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.width != rhs.width) + if (lhs.__width != rhs.__width) log_cmd_error("Proof-x expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.width, s.second.c_str(), log_signal(rhs), rhs.width); + s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); log("Import proof-x-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -413,8 +413,8 @@ struct SatHelper satgen.getAsserts(asserts_a, asserts_en, timestep); asserts_a.expand(); asserts_en.expand(); - for (size_t i = 0; i < asserts_a.chunks.size(); i++) - log("Import proof for assert: %s when %s.\n", log_signal(asserts_a.chunks[i]), log_signal(asserts_en.chunks[i])); + for (size_t i = 0; i < asserts_a.__chunks.size(); i++) + log("Import proof for assert: %s when %s.\n", log_signal(asserts_a.__chunks[i]), log_signal(asserts_en.__chunks[i])); prove_bits.push_back(satgen.importAsserts(timestep)); } @@ -543,12 +543,12 @@ struct SatHelper std::vector modelUndefExpressions; - for (auto &c : modelSig.chunks) + for (auto &c : modelSig.__chunks) if (c.wire != NULL) { ModelBlockInfo info; RTLIL::SigSpec chunksig = c; - info.width = chunksig.width; + info.width = chunksig.__width; info.description = log_signal(chunksig); for (int timestep = -1; timestep <= max_timestep; timestep++) @@ -573,7 +573,7 @@ struct SatHelper // Add initial state signals as collected by satgen // modelSig = satgen.initial_state.export_all(); - for (auto &c : modelSig.chunks) + for (auto &c : modelSig.__chunks) if (c.wire != NULL) { ModelBlockInfo info; @@ -581,7 +581,7 @@ struct SatHelper info.timestep = 0; info.offset = modelExpressions.size(); - info.width = chunksig.width; + info.width = chunksig.__width; info.description = log_signal(chunksig); modelInfo.insert(info); diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 42e59c47..95f35bb3 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -273,11 +273,11 @@ struct ShareWorker RTLIL::SigSpec a2 = c2->connections.at("\\A"); RTLIL::SigSpec y2 = c2->connections.at("\\Y"); - int a_width = std::max(a1.width, a2.width); - int y_width = std::max(y1.width, y2.width); + int a_width = std::max(a1.__width, a2.__width); + int y_width = std::max(y1.__width, y2.__width); - if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); - if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a1.__width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a2.__width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); @@ -292,8 +292,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; module->add(supercell); - RTLIL::SigSpec new_y1(y, y1.width); - RTLIL::SigSpec new_y2(y, y2.width); + RTLIL::SigSpec new_y1(y, y1.__width); + RTLIL::SigSpec new_y2(y, y2.__width); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -367,28 +367,28 @@ struct ShareWorker RTLIL::SigSpec b2 = c2->connections.at("\\B"); RTLIL::SigSpec y2 = c2->connections.at("\\Y"); - int a_width = std::max(a1.width, a2.width); - int b_width = std::max(b1.width, b2.width); - int y_width = std::max(y1.width, y2.width); + int a_width = std::max(a1.__width, a2.__width); + int b_width = std::max(b1.__width, b2.__width); + int y_width = std::max(y1.__width, y2.__width); if (c1->type == "$shr" && a_signed) { a_width = std::max(y_width, a_width); - if (a1.width < y1.width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.width), true)->connections.at("\\Y"); - if (a2.width < y2.width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.width), true)->connections.at("\\Y"); + if (a1.__width < y1.__width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.__width), true)->connections.at("\\Y"); + if (a2.__width < y2.__width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.__width), true)->connections.at("\\Y"); - if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); - if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); + if (a1.__width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); + if (a2.__width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); } else { - if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); - if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a1.__width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a2.__width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); } - if (b1.width != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); - if (b2.width != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); + if (b1.__width != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); + if (b2.__width != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); @@ -405,8 +405,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; supercell->check(); - RTLIL::SigSpec new_y1(y, y1.width); - RTLIL::SigSpec new_y2(y, y2.width); + RTLIL::SigSpec new_y1(y, y1.__width); + RTLIL::SigSpec new_y2(y, y2.__width); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -575,7 +575,7 @@ struct ShareWorker if (activation_patterns_cache[cell].empty()) { log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; - module->connections.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.width))); + module->connections.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.__width))); cells_to_remove.insert(cell); } @@ -811,10 +811,10 @@ struct ShareWorker int other_cell_select_score = 0; for (auto &p : filtered_cell_activation_patterns) - cell_select_score += p.first.width; + cell_select_score += p.first.__width; for (auto &p : filtered_other_cell_activation_patterns) - other_cell_select_score += p.first.width; + other_cell_select_score += p.first.__width; RTLIL::Cell *supercell; if (cell_select_score <= other_cell_select_score) { diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index d2193c7b..7e57aa0f 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -133,8 +133,8 @@ namespace needleSig.expand(); haystackSig.expand(); - for (int i = 0; i < std::min(needleSig.width, haystackSig.width); i++) { - RTLIL::Wire *needleWire = needleSig.chunks.at(i).wire, *haystackWire = haystackSig.chunks.at(i).wire; + for (int i = 0; i < std::min(needleSig.__width, haystackSig.__width); i++) { + RTLIL::Wire *needleWire = needleSig.__chunks.at(i).wire, *haystackWire = haystackSig.__chunks.at(i).wire; if (needleWire != lastNeedleWire || haystackWire != lastHaystackWire) if (!compareAttributes(wire_attr, needleWire ? needleWire->attributes : emptyAttr, haystackWire ? haystackWire->attributes : emptyAttr)) return false; @@ -193,7 +193,7 @@ namespace RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); conn_sig.expand(); - for (auto &chunk : conn_sig.chunks) + for (auto &chunk : conn_sig.__chunks) if (chunk.wire != NULL) sig_use_count[std::pair(chunk.wire, chunk.offset)]++; } @@ -213,7 +213,7 @@ namespace for (auto &conn : cell->connections) { - graph.createPort(cell->name, conn.first, conn.second.width); + graph.createPort(cell->name, conn.first, conn.second.__width); if (split && split->count(std::pair(cell->type, conn.first)) > 0) continue; @@ -222,9 +222,9 @@ namespace sigmap.apply(conn_sig); conn_sig.expand(); - for (size_t i = 0; i < conn_sig.chunks.size(); i++) + for (size_t i = 0; i < conn_sig.__chunks.size(); i++) { - auto &chunk = conn_sig.chunks[i]; + auto &chunk = conn_sig.__chunks[i]; assert(chunk.width == 1); if (chunk.wire == NULL) { @@ -269,7 +269,7 @@ namespace sigmap.apply(conn_sig); conn_sig.expand(); - for (auto &chunk : conn_sig.chunks) + for (auto &chunk : conn_sig.__chunks) if (sig_bit_ref.count(chunk) != 0) { bit_ref_t &bit_ref = sig_bit_ref[chunk]; graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit); @@ -287,7 +287,7 @@ namespace sigmap.apply(conn_sig); conn_sig.expand(); - for (auto &chunk : conn_sig.chunks) + for (auto &chunk : conn_sig.__chunks) if (sig_bit_ref.count(chunk) != 0) { bit_ref_t &bit_ref = sig_bit_ref[chunk]; graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit); @@ -334,8 +334,8 @@ namespace RTLIL::SigSpec sig = sigmap(conn.second); if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { sig.expand(); - for (int i = 0; i < sig.width; i++) - for (auto &port : sig2port.find(sig.chunks[i])) { + for (int i = 0; i < sig.__width; i++) + for (auto &port : sig2port.find(sig.__chunks[i])) { RTLIL::SigSpec bitsig = haystack_cell->connections.at(mapping.portMapping[conn.first]).extract(i, 1); cell->connections.at(port.first).replace(port.second, bitsig); } @@ -729,7 +729,7 @@ struct ExtractPass : public Pass { for (auto cell : cells) for (auto &conn : cell->connections) { RTLIL::SigSpec sig = sigmap(conn.second); - for (auto &chunk : sig.chunks) + for (auto &chunk : sig.__chunks) if (chunk.wire != NULL) wires.insert(chunk.wire); } @@ -756,7 +756,7 @@ struct ExtractPass : public Pass { newCell->parameters = cell->parameters; for (auto &conn : cell->connections) { RTLIL::SigSpec sig = sigmap(conn.second); - for (auto &chunk : sig.chunks) + for (auto &chunk : sig.__chunks) if (chunk.wire != NULL) chunk.wire = newMod->wires.at(chunk.wire->name); newCell->connections[conn.first] = sig; diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index d24f557e..22f4c7d1 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -31,7 +31,7 @@ static RTLIL::SigChunk last_hi, last_lo; void hilomap_worker(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.chunks) { + for (auto &c : sig.__chunks) { if (c.wire == NULL && (c.data.bits.at(0) == RTLIL::State::S1) && !hicell_celltype.empty()) { if (!singleton_mode || last_hi.width == 0) { last_hi = RTLIL::SigChunk(module->addWire(NEW_ID)); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 91f3b612..cef5cc89 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -42,8 +42,8 @@ static void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_INV_"; - gate->connections["\\A"] = sig_a.chunks.at(i); - gate->connections["\\Y"] = sig_y.chunks.at(i); + gate->connections["\\A"] = sig_a.__chunks.at(i); + gate->connections["\\Y"] = sig_y.__chunks.at(i); module->add(gate); } } @@ -96,8 +96,8 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_INV_"; - gate->connections["\\A"] = sig_t.chunks.at(i); - gate->connections["\\Y"] = sig_y.chunks.at(i); + gate->connections["\\A"] = sig_t.__chunks.at(i); + gate->connections["\\Y"] = sig_y.__chunks.at(i); module->add(gate); } @@ -115,9 +115,9 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\A"] = sig_a.chunks.at(i); - gate->connections["\\B"] = sig_b.chunks.at(i); - gate->connections["\\Y"] = sig_y.chunks.at(i); + gate->connections["\\A"] = sig_a.__chunks.at(i); + gate->connections["\\B"] = sig_b.__chunks.at(i); + gate->connections["\\Y"] = sig_y.__chunks.at(i); module->add(gate); } } @@ -129,20 +129,20 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - if (sig_y.width == 0) + if (sig_y.__width == 0) return; - if (sig_a.width == 0) { - if (cell->type == "$reduce_and") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.width))); - if (cell->type == "$reduce_or") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.width))); - if (cell->type == "$reduce_xor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.width))); - if (cell->type == "$reduce_xnor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.width))); - if (cell->type == "$reduce_bool") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.width))); + if (sig_a.__width == 0) { + if (cell->type == "$reduce_and") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.__width))); + if (cell->type == "$reduce_or") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); + if (cell->type == "$reduce_xor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); + if (cell->type == "$reduce_xnor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.__width))); + if (cell->type == "$reduce_bool") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); return; } - if (sig_y.width > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.width-1), RTLIL::SigSpec(0, sig_y.width-1))); + if (sig_y.__width > 1) { + module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.__width-1), RTLIL::SigSpec(0, sig_y.__width-1))); sig_y = sig_y.extract(0, 1); } @@ -156,24 +156,24 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec *last_output = NULL; - while (sig_a.width > 1) + while (sig_a.__width > 1) { - RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.width / 2); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.__width / 2); sig_t.expand(); - for (int i = 0; i < sig_a.width; i += 2) + for (int i = 0; i < sig_a.__width; i += 2) { - if (i+1 == sig_a.width) { - sig_t.append(sig_a.chunks.at(i)); + if (i+1 == sig_a.__width) { + sig_t.append(sig_a.__chunks.at(i)); continue; } RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\A"] = sig_a.chunks.at(i); - gate->connections["\\B"] = sig_a.chunks.at(i+1); - gate->connections["\\Y"] = sig_t.chunks.at(i/2); + gate->connections["\\A"] = sig_a.__chunks.at(i); + gate->connections["\\B"] = sig_a.__chunks.at(i+1); + gate->connections["\\Y"] = sig_t.__chunks.at(i/2); last_output = &gate->connections["\\Y"]; module->add(gate); } @@ -204,31 +204,31 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) { sig.expand(); - while (sig.width > 1) + while (sig.__width > 1) { - RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.width / 2); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.__width / 2); sig_t.expand(); - for (int i = 0; i < sig.width; i += 2) + for (int i = 0; i < sig.__width; i += 2) { - if (i+1 == sig.width) { - sig_t.append(sig.chunks.at(i)); + if (i+1 == sig.__width) { + sig_t.append(sig.__chunks.at(i)); continue; } RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_OR_"; - gate->connections["\\A"] = sig.chunks.at(i); - gate->connections["\\B"] = sig.chunks.at(i+1); - gate->connections["\\Y"] = sig_t.chunks.at(i/2); + gate->connections["\\A"] = sig.__chunks.at(i); + gate->connections["\\B"] = sig.__chunks.at(i+1); + gate->connections["\\Y"] = sig_t.__chunks.at(i/2); module->add(gate); } sig = sig_t; } - if (sig.width == 0) + if (sig.__width == 0) sig = RTLIL::SigSpec(0, 1); } @@ -239,11 +239,11 @@ static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - if (sig_y.width == 0) + if (sig_y.__width == 0) return; - if (sig_y.width > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.width-1), RTLIL::SigSpec(0, sig_y.width-1))); + if (sig_y.__width > 1) { + module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.__width-1), RTLIL::SigSpec(0, sig_y.__width-1))); sig_y = sig_y.extract(0, 1); } @@ -265,11 +265,11 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - if (sig_y.width == 0) + if (sig_y.__width == 0) return; - if (sig_y.width > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.width-1), RTLIL::SigSpec(0, sig_y.width-1))); + if (sig_y.__width > 1) { + module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.__width-1), RTLIL::SigSpec(0, sig_y.__width-1))); sig_y = sig_y.extract(0, 1); } @@ -304,10 +304,10 @@ static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_MUX_"; - gate->connections["\\A"] = sig_a.chunks.at(i); - gate->connections["\\B"] = sig_b.chunks.at(i); + gate->connections["\\A"] = sig_a.__chunks.at(i); + gate->connections["\\B"] = sig_b.__chunks.at(i); gate->connections["\\S"] = cell->connections.at("\\S"); - gate->connections["\\Y"] = sig_y.chunks.at(i); + gate->connections["\\Y"] = sig_y.__chunks.at(i); module->add(gate); } } @@ -317,7 +317,7 @@ static void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) int offset = cell->parameters.at("\\OFFSET").as_int(); RTLIL::SigSpec sig_a = cell->connections.at("\\A"); RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.width))); + module->connections.push_back(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.__width))); } static void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) @@ -349,9 +349,9 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\S"] = sig_s.chunks.at(i); - gate->connections["\\R"] = sig_r.chunks.at(i); - gate->connections["\\Q"] = sig_q.chunks.at(i); + gate->connections["\\S"] = sig_s.__chunks.at(i); + gate->connections["\\R"] = sig_r.__chunks.at(i); + gate->connections["\\Q"] = sig_q.__chunks.at(i); module->add(gate); } } @@ -376,8 +376,8 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\C"] = sig_clk; - gate->connections["\\D"] = sig_d.chunks.at(i); - gate->connections["\\Q"] = sig_q.chunks.at(i); + gate->connections["\\D"] = sig_d.__chunks.at(i); + gate->connections["\\Q"] = sig_q.__chunks.at(i); module->add(gate); } } @@ -410,10 +410,10 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\C"] = sig_clk; - gate->connections["\\S"] = sig_s.chunks.at(i); - gate->connections["\\R"] = sig_r.chunks.at(i); - gate->connections["\\D"] = sig_d.chunks.at(i); - gate->connections["\\Q"] = sig_q.chunks.at(i); + gate->connections["\\S"] = sig_s.__chunks.at(i); + gate->connections["\\R"] = sig_r.__chunks.at(i); + gate->connections["\\D"] = sig_d.__chunks.at(i); + gate->connections["\\Q"] = sig_q.__chunks.at(i); module->add(gate); } } @@ -446,8 +446,8 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) gate->type = rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0; gate->connections["\\C"] = sig_clk; gate->connections["\\R"] = sig_rst; - gate->connections["\\D"] = sig_d.chunks.at(i); - gate->connections["\\Q"] = sig_q.chunks.at(i); + gate->connections["\\D"] = sig_d.__chunks.at(i); + gate->connections["\\Q"] = sig_q.__chunks.at(i); module->add(gate); } } @@ -472,8 +472,8 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\E"] = sig_en; - gate->connections["\\D"] = sig_d.chunks.at(i); - gate->connections["\\Q"] = sig_q.chunks.at(i); + gate->connections["\\D"] = sig_d.__chunks.at(i); + gate->connections["\\Q"] = sig_q.__chunks.at(i); module->add(gate); } } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 3ceff279..f7d5efa0 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -41,13 +41,13 @@ static void apply_prefix(std::string prefix, std::string &id) static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module *module) { - for (size_t i = 0; i < sig.chunks.size(); i++) { - if (sig.chunks[i].wire == NULL) + for (size_t i = 0; i < sig.__chunks.size(); i++) { + if (sig.__chunks[i].wire == NULL) continue; - std::string wire_name = sig.chunks[i].wire->name; + std::string wire_name = sig.__chunks[i].wire->name; apply_prefix(prefix, wire_name); assert(module->wires.count(wire_name) > 0); - sig.chunks[i].wire = module->wires[wire_name]; + sig.__chunks[i].wire = module->wires[wire_name]; } } @@ -163,11 +163,11 @@ struct TechmapWorker c.second = it.second; apply_prefix(cell->name, c.first, module); } - if (c.second.width > c.first.width) - c.second.remove(c.first.width, c.second.width - c.first.width); - if (c.second.width < c.first.width) - c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.width - c.second.width)); - assert(c.first.width == c.second.width); + if (c.second.__width > c.first.__width) + c.second.remove(c.first.__width, c.second.__width - c.first.__width); + if (c.second.__width < c.first.__width) + c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.__width - c.second.__width)); + assert(c.first.__width == c.second.__width); if (flatten_mode) { // more conservative approach: // connect internal and external wires From 16e5ae0b92ac4b7568cb11a769e612e152c0042e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:12:15 +0200 Subject: [PATCH 358/750] SigSpec refactoring: renamed the SigSpec members to chunks_ and width_ and added accessor functions --- kernel/rtlil.cc | 298 ++++++++++++++++++++++++------------------------ kernel/rtlil.h | 12 +- 2 files changed, 158 insertions(+), 152 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3a646dc6..04332309 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1415,65 +1415,65 @@ bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const RTLIL::SigSpec::SigSpec() { - __width = 0; + width_ = 0; } RTLIL::SigSpec::SigSpec(const RTLIL::Const &data) { - __chunks.push_back(RTLIL::SigChunk(data)); - __width = __chunks.back().width; + chunks_.push_back(RTLIL::SigChunk(data)); + width_ = chunks_.back().width; check(); } RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) { - __chunks.push_back(chunk); - __width = __chunks.back().width; + chunks_.push_back(chunk); + width_ = chunks_.back().width; check(); } RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int width, int offset) { - __chunks.push_back(RTLIL::SigChunk(wire, width, offset)); - __width = __chunks.back().width; + chunks_.push_back(RTLIL::SigChunk(wire, width, offset)); + width_ = chunks_.back().width; check(); } RTLIL::SigSpec::SigSpec(const std::string &str) { - __chunks.push_back(RTLIL::SigChunk(str)); - __width = __chunks.back().width; + chunks_.push_back(RTLIL::SigChunk(str)); + width_ = chunks_.back().width; check(); } RTLIL::SigSpec::SigSpec(int val, int width) { - __chunks.push_back(RTLIL::SigChunk(val, width)); - __width = width; + chunks_.push_back(RTLIL::SigChunk(val, width)); + width_ = width; check(); } RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) { - __chunks.push_back(RTLIL::SigChunk(bit, width)); - __width = width; + chunks_.push_back(RTLIL::SigChunk(bit, width)); + width_ = width; check(); } RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) { if (bit.wire == NULL) - __chunks.push_back(RTLIL::SigChunk(bit.data, width)); + chunks_.push_back(RTLIL::SigChunk(bit.data, width)); else for (int i = 0; i < width; i++) - __chunks.push_back(bit); - __width = width; + chunks_.push_back(bit); + width_ = width; check(); } RTLIL::SigSpec::SigSpec(std::vector bits) { - __width = 0; + width_ = 0; for (auto &bit : bits) append_bit(bit); check(); @@ -1481,7 +1481,7 @@ RTLIL::SigSpec::SigSpec(std::vector bits) RTLIL::SigSpec::SigSpec(std::set bits) { - __width = 0; + width_ = 0; for (auto &bit : bits) append_bit(bit); check(); @@ -1490,18 +1490,18 @@ RTLIL::SigSpec::SigSpec(std::set bits) void RTLIL::SigSpec::expand() { std::vector new_chunks; - for (size_t i = 0; i < __chunks.size(); i++) { - for (int j = 0; j < __chunks[i].width; j++) - new_chunks.push_back(__chunks[i].extract(j, 1)); + for (size_t i = 0; i < chunks_.size(); i++) { + for (int j = 0; j < chunks_[i].width; j++) + new_chunks.push_back(chunks_[i].extract(j, 1)); } - __chunks.swap(new_chunks); + chunks_.swap(new_chunks); check(); } void RTLIL::SigSpec::optimize() { std::vector new_chunks; - for (auto &c : __chunks) + for (auto &c : chunks_) if (new_chunks.size() == 0) { new_chunks.push_back(c); } else { @@ -1513,7 +1513,7 @@ void RTLIL::SigSpec::optimize() else new_chunks.push_back(c); } - __chunks.swap(new_chunks); + chunks_.swap(new_chunks); check(); } @@ -1544,20 +1544,20 @@ bool RTLIL::SigChunk::compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b void RTLIL::SigSpec::sort() { expand(); - std::sort(__chunks.begin(), __chunks.end(), RTLIL::SigChunk::compare); + std::sort(chunks_.begin(), chunks_.end(), RTLIL::SigChunk::compare); optimize(); } void RTLIL::SigSpec::sort_and_unify() { expand(); - std::sort(__chunks.begin(), __chunks.end(), RTLIL::SigChunk::compare); - for (size_t i = 1; i < __chunks.size(); i++) { - RTLIL::SigChunk &ch1 = __chunks[i-1]; - RTLIL::SigChunk &ch2 = __chunks[i]; + std::sort(chunks_.begin(), chunks_.end(), RTLIL::SigChunk::compare); + for (size_t i = 1; i < chunks_.size(); i++) { + RTLIL::SigChunk &ch1 = chunks_[i-1]; + RTLIL::SigChunk &ch2 = chunks_[i]; if (!RTLIL::SigChunk::compare(ch1, ch2) && !RTLIL::SigChunk::compare(ch2, ch1)) { - __chunks.erase(__chunks.begin()+i); - __width -= __chunks[i].width; + chunks_.erase(chunks_.begin()+i); + width_ -= chunks_[i].width; i--; } } @@ -1572,13 +1572,13 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { int pos = 0, restart_pos = 0; - assert(other == NULL || __width == other->__width); - for (size_t i = 0; i < __chunks.size(); i++) { + assert(other == NULL || width_ == other->width_); + for (size_t i = 0; i < chunks_.size(); i++) { restart: - const RTLIL::SigChunk &ch1 = __chunks[i]; - if (__chunks[i].wire != NULL && pos >= restart_pos) - for (size_t j = 0, poff = 0; j < pattern.__chunks.size(); j++) { - const RTLIL::SigChunk &ch2 = pattern.__chunks[j]; + const RTLIL::SigChunk &ch1 = chunks_[i]; + if (chunks_[i].wire != NULL && pos >= restart_pos) + for (size_t j = 0, poff = 0; j < pattern.chunks_.size(); j++) { + const RTLIL::SigChunk &ch2 = pattern.chunks_[j]; assert(ch2.wire != NULL); if (ch1.wire == ch2.wire) { int lower = std::max(ch1.offset, ch2.offset); @@ -1591,7 +1591,7 @@ restart: } poff += ch2.width; } - pos += __chunks[i].width; + pos += chunks_[i].width; } check(); } @@ -1610,13 +1610,13 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) { int pos = 0; - assert(other == NULL || __width == other->__width); - for (size_t i = 0; i < __chunks.size(); i++) { + assert(other == NULL || width_ == other->width_); + for (size_t i = 0; i < chunks_.size(); i++) { restart: - const RTLIL::SigChunk &ch1 = __chunks[i]; - if (__chunks[i].wire != NULL) - for (size_t j = 0; j < pattern.__chunks.size(); j++) { - const RTLIL::SigChunk &ch2 = pattern.__chunks[j]; + const RTLIL::SigChunk &ch1 = chunks_[i]; + if (chunks_[i].wire != NULL) + for (size_t j = 0; j < pattern.chunks_.size(); j++) { + const RTLIL::SigChunk &ch2 = pattern.chunks_[j]; assert(ch2.wire != NULL); if (ch1.wire == ch2.wire) { int lower = std::max(ch1.offset, ch2.offset); @@ -1625,20 +1625,20 @@ restart: if (other) other->remove(pos+lower-ch1.offset, upper-lower); remove(pos+lower-ch1.offset, upper-lower); - if (i == __chunks.size()) + if (i == chunks_.size()) break; goto restart; } } } - pos += __chunks[i].width; + pos += chunks_[i].width; } check(); } RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const { - assert(other == NULL || __width == other->__width); + assert(other == NULL || width_ == other->width_); std::set pat = pattern.to_sigbit_set(); std::vector bits_match = to_sigbit_vector(); @@ -1646,11 +1646,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o if (other) { std::vector bits_other = other ? other->to_sigbit_vector() : bits_match; - for (int i = 0; i < __width; i++) + for (int i = 0; i < width_; i++) if (bits_match[i].wire && pat.count(bits_match[i])) ret.append_bit(bits_other[i]); } else { - for (int i = 0; i < __width; i++) + for (int i = 0; i < width_; i++) if (bits_match[i].wire && pat.count(bits_match[i])) ret.append_bit(bits_match[i]); } @@ -1663,31 +1663,31 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) { int pos = 0; assert(offset >= 0); - assert(with.__width >= 0); - assert(offset+with.__width <= __width); - remove(offset, with.__width); - for (size_t i = 0; i < __chunks.size(); i++) { + assert(with.width_ >= 0); + assert(offset+with.width_ <= width_); + remove(offset, with.width_); + for (size_t i = 0; i < chunks_.size(); i++) { if (pos == offset) { - __chunks.insert(__chunks.begin()+i, with.__chunks.begin(), with.__chunks.end()); - __width += with.__width; + chunks_.insert(chunks_.begin()+i, with.chunks_.begin(), with.chunks_.end()); + width_ += with.width_; check(); return; } - pos += __chunks[i].width; + pos += chunks_[i].width; } assert(pos == offset); - __chunks.insert(__chunks.end(), with.__chunks.begin(), with.__chunks.end()); - __width += with.__width; + chunks_.insert(chunks_.end(), with.chunks_.begin(), with.chunks_.end()); + width_ += with.width_; check(); } void RTLIL::SigSpec::remove_const() { - for (size_t i = 0; i < __chunks.size(); i++) { - if (__chunks[i].wire != NULL) + for (size_t i = 0; i < chunks_.size(); i++) { + if (chunks_[i].wire != NULL) continue; - __width -= __chunks[i].width; - __chunks.erase(__chunks.begin() + (i--)); + width_ -= chunks_[i].width; + chunks_.erase(chunks_.begin() + (i--)); } check(); } @@ -1697,34 +1697,34 @@ void RTLIL::SigSpec::remove(int offset, int length) int pos = 0; assert(offset >= 0); assert(length >= 0); - assert(offset+length <= __width); - for (size_t i = 0; i < __chunks.size(); i++) { - int orig_width = __chunks[i].width; - if (pos+__chunks[i].width > offset && pos < offset+length) { + assert(offset+length <= width_); + for (size_t i = 0; i < chunks_.size(); i++) { + int orig_width = chunks_[i].width; + if (pos+chunks_[i].width > offset && pos < offset+length) { int off = offset - pos; int len = length; if (off < 0) { len += off; off = 0; } - if (len > __chunks[i].width-off) - len = __chunks[i].width-off; - RTLIL::SigChunk lsb_chunk = __chunks[i].extract(0, off); - RTLIL::SigChunk msb_chunk = __chunks[i].extract(off+len, __chunks[i].width-off-len); + if (len > chunks_[i].width-off) + len = chunks_[i].width-off; + RTLIL::SigChunk lsb_chunk = chunks_[i].extract(0, off); + RTLIL::SigChunk msb_chunk = chunks_[i].extract(off+len, chunks_[i].width-off-len); if (lsb_chunk.width == 0 && msb_chunk.width == 0) { - __chunks.erase(__chunks.begin()+i); + chunks_.erase(chunks_.begin()+i); i--; } else if (lsb_chunk.width == 0 && msb_chunk.width != 0) { - __chunks[i] = msb_chunk; + chunks_[i] = msb_chunk; } else if (lsb_chunk.width != 0 && msb_chunk.width == 0) { - __chunks[i] = lsb_chunk; + chunks_[i] = lsb_chunk; } else if (lsb_chunk.width != 0 && msb_chunk.width != 0) { - __chunks[i] = lsb_chunk; - __chunks.insert(__chunks.begin()+i+1, msb_chunk); + chunks_[i] = lsb_chunk; + chunks_.insert(chunks_.begin()+i+1, msb_chunk); i++; } else assert(0); - __width -= len; + width_ -= len; } pos += orig_width; } @@ -1737,23 +1737,23 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const RTLIL::SigSpec ret; assert(offset >= 0); assert(length >= 0); - assert(offset+length <= __width); - for (size_t i = 0; i < __chunks.size(); i++) { - if (pos+__chunks[i].width > offset && pos < offset+length) { + assert(offset+length <= width_); + for (size_t i = 0; i < chunks_.size(); i++) { + if (pos+chunks_[i].width > offset && pos < offset+length) { int off = offset - pos; int len = length; if (off < 0) { len += off; off = 0; } - if (len > __chunks[i].width-off) - len = __chunks[i].width-off; - ret.__chunks.push_back(__chunks[i].extract(off, len)); - ret.__width += len; + if (len > chunks_[i].width-off) + len = chunks_[i].width-off; + ret.chunks_.push_back(chunks_[i].extract(off, len)); + ret.width_ += len; offset += len; length -= len; } - pos += __chunks[i].width; + pos += chunks_[i].width; } assert(length == 0); ret.check(); @@ -1762,30 +1762,30 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) { - for (size_t i = 0; i < signal.__chunks.size(); i++) { - __chunks.push_back(signal.__chunks[i]); - __width += signal.__chunks[i].width; + for (size_t i = 0; i < signal.chunks_.size(); i++) { + chunks_.push_back(signal.chunks_[i]); + width_ += signal.chunks_[i].width; } // check(); } void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) { - if (__chunks.size() == 0) - __chunks.push_back(bit); + if (chunks_.size() == 0) + chunks_.push_back(bit); else if (bit.wire == NULL) - if (__chunks.back().wire == NULL) { - __chunks.back().data.bits.push_back(bit.data); - __chunks.back().width++; + if (chunks_.back().wire == NULL) { + chunks_.back().data.bits.push_back(bit.data); + chunks_.back().width++; } else - __chunks.push_back(bit); + chunks_.push_back(bit); else - if (__chunks.back().wire == bit.wire && __chunks.back().offset + __chunks.back().width == bit.offset) - __chunks.back().width++; + if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset) + chunks_.back().width++; else - __chunks.push_back(bit); - __width++; + chunks_.push_back(bit); + width_++; // check(); } @@ -1793,22 +1793,22 @@ bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool { bool no_collisions = true; - assert(__width == signal.__width); + assert(width_ == signal.width_); expand(); signal.expand(); - for (size_t i = 0; i < __chunks.size(); i++) { - bool self_free = __chunks[i].wire == NULL && __chunks[i].data.bits[0] == freeState; - bool other_free = signal.__chunks[i].wire == NULL && signal.__chunks[i].data.bits[0] == freeState; + for (size_t i = 0; i < chunks_.size(); i++) { + bool self_free = chunks_[i].wire == NULL && chunks_[i].data.bits[0] == freeState; + bool other_free = signal.chunks_[i].wire == NULL && signal.chunks_[i].data.bits[0] == freeState; if (!self_free && !other_free) { if (override) - __chunks[i] = signal.__chunks[i]; + chunks_[i] = signal.chunks_[i]; else - __chunks[i] = RTLIL::SigChunk(RTLIL::State::Sx, 1); + chunks_[i] = RTLIL::SigChunk(RTLIL::State::Sx, 1); no_collisions = false; } if (self_free && !other_free) - __chunks[i] = signal.__chunks[i]; + chunks_[i] = signal.chunks_[i]; } optimize(); @@ -1817,15 +1817,15 @@ bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool void RTLIL::SigSpec::extend(int width, bool is_signed) { - if (__width > width) - remove(width, __width - width); + if (width_ > width) + remove(width, width_ - width); - if (__width < width) { - RTLIL::SigSpec padding = __width > 0 ? extract(__width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); + if (width_ < width) { + RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); if (!is_signed && padding != RTLIL::SigSpec(RTLIL::State::Sx) && padding != RTLIL::SigSpec(RTLIL::State::Sz) && padding != RTLIL::SigSpec(RTLIL::State::Sa) && padding != RTLIL::SigSpec(RTLIL::State::Sm)) padding = RTLIL::SigSpec(RTLIL::State::S0); - while (__width < width) + while (width_ < width) append(padding); } @@ -1834,14 +1834,14 @@ void RTLIL::SigSpec::extend(int width, bool is_signed) void RTLIL::SigSpec::extend_u0(int width, bool is_signed) { - if (__width > width) - remove(width, __width - width); + if (width_ > width) + remove(width, width_ - width); - if (__width < width) { - RTLIL::SigSpec padding = __width > 0 ? extract(__width - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); + if (width_ < width) { + RTLIL::SigSpec padding = width_ > 0 ? extract(width_ - 1, 1) : RTLIL::SigSpec(RTLIL::State::S0); if (!is_signed) padding = RTLIL::SigSpec(RTLIL::State::S0); - while (__width < width) + while (width_ < width) append(padding); } @@ -1851,8 +1851,8 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed) void RTLIL::SigSpec::check() const { int w = 0; - for (size_t i = 0; i < __chunks.size(); i++) { - const RTLIL::SigChunk chunk = __chunks[i]; + for (size_t i = 0; i < chunks_.size(); i++) { + const RTLIL::SigChunk chunk = chunks_[i]; if (chunk.wire == NULL) { assert(chunk.offset == 0); assert(chunk.data.bits.size() == (size_t)chunk.width); @@ -1864,42 +1864,42 @@ void RTLIL::SigSpec::check() const } w += chunk.width; } - assert(w == __width); + assert(w == width_); } bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const { - if (__width != other.__width) - return __width < other.__width; + if (width_ != other.width_) + return width_ < other.width_; RTLIL::SigSpec a = *this, b = other; a.optimize(); b.optimize(); - if (a.__chunks.size() != b.__chunks.size()) - return a.__chunks.size() < b.__chunks.size(); + if (a.chunks_.size() != b.chunks_.size()) + return a.chunks_.size() < b.chunks_.size(); - for (size_t i = 0; i < a.__chunks.size(); i++) - if (a.__chunks[i] != b.__chunks[i]) - return a.__chunks[i] < b.__chunks[i]; + for (size_t i = 0; i < a.chunks_.size(); i++) + if (a.chunks_[i] != b.chunks_[i]) + return a.chunks_[i] < b.chunks_[i]; return false; } bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const { - if (__width != other.__width) + if (width_ != other.width_) return false; RTLIL::SigSpec a = *this, b = other; a.optimize(); b.optimize(); - if (a.__chunks.size() != b.__chunks.size()) + if (a.chunks_.size() != b.chunks_.size()) return false; - for (size_t i = 0; i < a.__chunks.size(); i++) - if (a.__chunks[i] != b.__chunks[i]) + for (size_t i = 0; i < a.chunks_.size(); i++) + if (a.chunks_[i] != b.chunks_[i]) return false; return true; @@ -1914,7 +1914,7 @@ bool RTLIL::SigSpec::operator !=(const RTLIL::SigSpec &other) const bool RTLIL::SigSpec::is_fully_const() const { - for (auto it = __chunks.begin(); it != __chunks.end(); it++) + for (auto it = chunks_.begin(); it != chunks_.end(); it++) if (it->width > 0 && it->wire != NULL) return false; return true; @@ -1922,7 +1922,7 @@ bool RTLIL::SigSpec::is_fully_const() const bool RTLIL::SigSpec::is_fully_def() const { - for (auto it = __chunks.begin(); it != __chunks.end(); it++) { + for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; for (size_t i = 0; i < it->data.bits.size(); i++) @@ -1934,7 +1934,7 @@ bool RTLIL::SigSpec::is_fully_def() const bool RTLIL::SigSpec::is_fully_undef() const { - for (auto it = __chunks.begin(); it != __chunks.end(); it++) { + for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; for (size_t i = 0; i < it->data.bits.size(); i++) @@ -1946,7 +1946,7 @@ bool RTLIL::SigSpec::is_fully_undef() const bool RTLIL::SigSpec::has_marked_bits() const { - for (auto it = __chunks.begin(); it != __chunks.end(); it++) + for (auto it = chunks_.begin(); it != chunks_.end(); it++) if (it->width > 0 && it->wire == NULL) { for (size_t i = 0; i < it->data.bits.size(); i++) if (it->data.bits[i] == RTLIL::State::Sm) @@ -1960,8 +1960,8 @@ bool RTLIL::SigSpec::as_bool() const assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); - if (sig.__width) - return sig.__chunks[0].data.as_bool(); + if (sig.width_) + return sig.chunks_[0].data.as_bool(); return false; } @@ -1970,16 +1970,16 @@ int RTLIL::SigSpec::as_int() const assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); - if (sig.__width) - return sig.__chunks[0].data.as_int(); + if (sig.width_) + return sig.chunks_[0].data.as_int(); return 0; } std::string RTLIL::SigSpec::as_string() const { std::string str; - for (size_t i = __chunks.size(); i > 0; i--) { - const RTLIL::SigChunk &chunk = __chunks[i-1]; + for (size_t i = chunks_.size(); i > 0; i--) { + const RTLIL::SigChunk &chunk = chunks_[i-1]; if (chunk.wire != NULL) for (int j = 0; j < chunk.width; j++) str += "?"; @@ -1994,8 +1994,8 @@ RTLIL::Const RTLIL::SigSpec::as_const() const assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); - if (sig.__width) - return sig.__chunks[0].data; + if (sig.width_) + return sig.chunks_[0].data; return RTLIL::Const(); } @@ -2022,7 +2022,7 @@ bool RTLIL::SigSpec::match(std::string pattern) const std::set RTLIL::SigSpec::to_sigbit_set() const { std::set sigbits; - for (auto &c : __chunks) + for (auto &c : chunks_) for (int i = 0; i < c.width; i++) sigbits.insert(RTLIL::SigBit(c, i)); return sigbits; @@ -2031,8 +2031,8 @@ std::set RTLIL::SigSpec::to_sigbit_set() const std::vector RTLIL::SigSpec::to_sigbit_vector() const { std::vector sigbits; - sigbits.reserve(__width); - for (auto &c : __chunks) + sigbits.reserve(width_); + for (auto &c : chunks_) for (int i = 0; i < c.width; i++) sigbits.push_back(RTLIL::SigBit(c, i)); return sigbits; @@ -2040,8 +2040,8 @@ std::vector RTLIL::SigSpec::to_sigbit_vector() const RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const { - log_assert(__width == 1); - for (auto &c : __chunks) + log_assert(width_ == 1); + for (auto &c : chunks_) if (c.width) return RTLIL::SigBit(c); log_abort(); @@ -2155,20 +2155,20 @@ bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str) { if (str == "0") { - sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.__width); + sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.width_); return true; } if (str == "~0") { - sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.__width); + sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.width_); return true; } - if (lhs.__chunks.size() == 1) { + if (lhs.chunks_.size() == 1) { char *p = (char*)str.c_str(), *endptr; long long int val = strtoll(p, &endptr, 10); if (endptr && endptr != p && *endptr == 0) { - sig = RTLIL::SigSpec(val, lhs.__width); + sig = RTLIL::SigSpec(val, lhs.width_); return true; } } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0919b392..7fb416f1 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -496,11 +496,17 @@ struct RTLIL::SigBit { }; struct RTLIL::SigSpec { -public: - std::vector __chunks; // LSB at index 0 - int __width; +private: + std::vector chunks_; // LSB at index 0 + int width_; public: + std::vector &chunks() { return chunks_; } + const std::vector &chunks() const { return chunks_; } + + int &size() { return width_; } + const int &size() const { return width_; } + SigSpec(); SigSpec(const RTLIL::Const &data); SigSpec(const RTLIL::SigChunk &chunk); From 4b4048bc5feba1ab05c7a63f12c0a17879cb7e04 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:15:14 +0200 Subject: [PATCH 359/750] SigSpec refactoring: using the accessor functions everywhere --- backends/autotest/autotest.cc | 4 +- backends/blif/blif.cc | 24 +++--- backends/btor/btor.cc | 80 +++++++++---------- backends/edif/edif.cc | 20 ++--- backends/ilang/ilang_backend.cc | 8 +- backends/intersynth/intersynth.cc | 24 +++--- backends/spice/spice.cc | 22 ++--- backends/verilog/verilog_backend.cc | 58 +++++++------- frontends/ast/genrtlil.cc | 120 ++++++++++++++-------------- frontends/ilang/parser.y | 28 +++---- frontends/liberty/liberty.cc | 16 ++-- kernel/bitpattern.h | 12 +-- kernel/consteval.h | 18 ++--- kernel/rtlil.cc | 88 ++++++++++---------- kernel/rtlil.h | 4 +- kernel/satgen.h | 14 ++-- kernel/sigtools.h | 50 ++++++------ passes/abc/abc.cc | 68 ++++++++-------- passes/abc/blifparse.cc | 10 +-- passes/cmds/connect.cc | 2 +- passes/cmds/connwrappers.cc | 8 +- passes/cmds/delete.cc | 2 +- passes/cmds/scatter.cc | 2 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 2 +- passes/cmds/setundef.cc | 4 +- passes/cmds/show.cc | 34 ++++---- passes/cmds/splice.cc | 18 ++--- passes/cmds/splitnets.cc | 4 +- passes/fsm/fsm_detect.cc | 4 +- passes/fsm/fsm_expand.cc | 18 ++--- passes/fsm/fsm_extract.cc | 38 ++++----- passes/fsm/fsm_map.cc | 30 +++---- passes/fsm/fsm_opt.cc | 18 ++--- passes/fsm/fsmdata.h | 8 +- passes/hierarchy/hierarchy.cc | 4 +- passes/hierarchy/submod.cc | 4 +- passes/memory/memory_collect.cc | 32 ++++---- passes/memory/memory_dff.cc | 12 +-- passes/memory/memory_map.cc | 8 +- passes/memory/memory_share.cc | 12 +-- passes/opt/opt_clean.cc | 28 +++---- passes/opt/opt_const.cc | 92 ++++++++++----------- passes/opt/opt_muxtree.cc | 14 ++-- passes/opt/opt_reduce.cc | 28 +++---- passes/opt/opt_rmdff.cc | 14 ++-- passes/opt/opt_share.cc | 2 +- passes/proc/proc_arst.cc | 18 ++--- passes/proc/proc_clean.cc | 8 +- passes/proc/proc_dff.cc | 82 +++++++++---------- passes/proc/proc_init.cc | 12 +-- passes/proc/proc_mux.cc | 44 +++++----- passes/sat/eval.cc | 66 +++++++-------- passes/sat/expose.cc | 2 +- passes/sat/freduce.cc | 2 +- passes/sat/miter.cc | 8 +- passes/sat/sat.cc | 46 +++++------ passes/sat/share.cc | 44 +++++----- passes/techmap/extract.cc | 24 +++--- passes/techmap/hilomap.cc | 2 +- passes/techmap/simplemap.cc | 112 +++++++++++++------------- passes/techmap/techmap.cc | 18 ++--- 62 files changed, 800 insertions(+), 800 deletions(-) diff --git a/backends/autotest/autotest.cc b/backends/autotest/autotest.cc index e7fbfe7a..028d1f37 100644 --- a/backends/autotest/autotest.cc +++ b/backends/autotest/autotest.cc @@ -119,8 +119,8 @@ static void autotest(FILE *f, RTLIL::Design *design) if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1) continue; RTLIL::SigSpec &signal = (*it4)->signal; - for (size_t i = 0; i < signal.__chunks.size(); i++) { - if (signal.__chunks[i].wire == wire) + for (size_t i = 0; i < signal.chunks().size(); i++) { + if (signal.chunks()[i].wire == wire) is_clksignal = true; } } diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 2d446610..90d1b3fc 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -71,18 +71,18 @@ struct BlifDumper const char *cstr(RTLIL::SigSpec sig) { sig.optimize(); - log_assert(sig.__width == 1); + log_assert(sig.size() == 1); - if (sig.__chunks.at(0).wire == NULL) - return sig.__chunks.at(0).data.bits.at(0) == RTLIL::State::S1 ? "$true" : "$false"; + if (sig.chunks().at(0).wire == NULL) + return sig.chunks().at(0).data.bits.at(0) == RTLIL::State::S1 ? "$true" : "$false"; - std::string str = RTLIL::unescape_id(sig.__chunks.at(0).wire->name); + std::string str = RTLIL::unescape_id(sig.chunks().at(0).wire->name); for (size_t i = 0; i < str.size(); i++) if (str[i] == '#' || str[i] == '=') str[i] = '?'; - if (sig.__chunks.at(0).wire->width != 1) - str += stringf("[%d]", sig.__chunks.at(0).offset); + if (sig.chunks().at(0).wire->width != 1) + str += stringf("[%d]", sig.chunks().at(0).offset); cstr_buf.push_back(str); return cstr_buf.back().c_str(); @@ -194,12 +194,12 @@ struct BlifDumper fprintf(f, ".names"); auto &inputs = cell->connections.at("\\I"); auto width = cell->parameters.at("\\WIDTH").as_int(); - log_assert(inputs.__width == width); - for (int i = 0; i < inputs.__width; i++) { + log_assert(inputs.size() == width); + for (int i = 0; i < inputs.size(); i++) { fprintf(f, " %s", cstr(inputs.extract(i, 1))); } auto &output = cell->connections.at("\\O"); - log_assert(output.__width == 1); + log_assert(output.size() == 1); fprintf(f, " %s", cstr(output)); fprintf(f, "\n"); auto mask = cell->parameters.at("\\LUT").as_string(); @@ -215,8 +215,8 @@ struct BlifDumper fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type)); for (auto &conn : cell->connections) - for (int i = 0; i < conn.second.__width; i++) { - if (conn.second.__width == 1) + for (int i = 0; i < conn.second.size(); i++) { + if (conn.second.size() == 1) fprintf(f, " %s", cstr(conn.first)); else fprintf(f, " %s[%d]", cstr(conn.first), i); @@ -244,7 +244,7 @@ struct BlifDumper } for (auto &conn : module->connections) - for (int i = 0; i < conn.first.__width; i++) + for (int i = 0; i < conn.first.size(); i++) if (config->conn_mode) fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); else if (!config->buf_type.empty()) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 428e9a88..7853160e 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -196,7 +196,7 @@ struct BtorDumper RTLIL::SigSpec* cell_output = get_cell_output(cell); int cell_line = dump_cell(cell); - if(dep_set.size()==1 && wire->width == cell_output->__width) + if(dep_set.size()==1 && wire->width == cell_output->size()) { wire_line = cell_line; break; @@ -205,17 +205,17 @@ struct BtorDumper { int prev_wire_line=0; //previously dumped wire line int start_bit=0; - for(unsigned j=0; j__chunks.size(); ++j) + for(unsigned j=0; jchunks().size(); ++j) { - start_bit+=cell_output->__chunks[j].width; - if(cell_output->__chunks[j].wire->name == wire->name) + start_bit+=cell_output->chunks()[j].width; + if(cell_output->chunks()[j].wire->name == wire->name) { prev_wire_line = wire_line; wire_line = ++line_num; - str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->__chunks[j].width, - cell_line, start_bit-1, start_bit-cell_output->__chunks[j].width); + str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks()[j].width, + cell_line, start_bit-1, start_bit-cell_output->chunks()[j].width); fprintf(f, "%s\n", str.c_str()); - wire_width += cell_output->__chunks[j].width; + wire_width += cell_output->chunks()[j].width; if(prev_wire_line!=0) { ++line_num; @@ -231,7 +231,7 @@ struct BtorDumper { log(" - checking sigmap\n"); RTLIL::SigSpec s = RTLIL::SigSpec(wire); - wire_line = dump_sigspec(&s, s.__width); + wire_line = dump_sigspec(&s, s.size()); line_ref[wire->name]=wire_line; } line_ref[wire->name]=wire_line; @@ -320,21 +320,21 @@ struct BtorDumper auto it = sig_ref.find(s); if(it == std::end(sig_ref)) { - if (s.__chunks.size() == 1) + if (s.chunks().size() == 1) { - l = dump_sigchunk(&s.__chunks[0]); + l = dump_sigchunk(&s.chunks()[0]); } else { int l1, l2, w1, w2; - l1 = dump_sigchunk(&s.__chunks[0]); + l1 = dump_sigchunk(&s.chunks()[0]); log_assert(l1>0); - w1 = s.__chunks[0].width; - for (unsigned i=1; i < s.__chunks.size(); ++i) + w1 = s.chunks()[0].width; + for (unsigned i=1; i < s.chunks().size(); ++i) { - l2 = dump_sigchunk(&s.__chunks[i]); + l2 = dump_sigchunk(&s.chunks()[i]); log_assert(l2>0); - w2 = s.__chunks[i].width; + w2 = s.chunks()[i].width; ++line_num; str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); fprintf(f, "%s\n", str.c_str()); @@ -350,22 +350,22 @@ struct BtorDumper l = it->second; } - if (expected_width != s.__width) + if (expected_width != s.size()) { log(" - changing width of sigspec\n"); //TODO: this block may not be needed anymore, due to explicit type conversion by "splice" command - if(expected_width > s.__width) + if(expected_width > s.size()) { //TODO: case the signal is signed ++line_num; - str = stringf ("%d zero %d", line_num, expected_width - s.__width); + str = stringf ("%d zero %d", line_num, expected_width - s.size()); fprintf(f, "%s\n", str.c_str()); ++line_num; str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l); fprintf(f, "%s\n", str.c_str()); l = line_num; } - else if(expected_width < s.__width) + else if(expected_width < s.size()) { ++line_num; str = stringf ("%d slice %d %d %d %d;3", line_num, expected_width, l, expected_width-1, 0); @@ -389,8 +389,8 @@ struct BtorDumper log("writing assert cell - %s\n", cstr(cell->type)); const RTLIL::SigSpec* expr = &cell->connections.at(RTLIL::IdString("\\A")); const RTLIL::SigSpec* en = &cell->connections.at(RTLIL::IdString("\\EN")); - log_assert(expr->__width == 1); - log_assert(en->__width == 1); + log_assert(expr->size() == 1); + log_assert(en->size() == 1); int expr_line = dump_sigspec(expr, 1); int en_line = dump_sigspec(en, 1); int one_line = ++line_num; @@ -649,13 +649,13 @@ struct BtorDumper const RTLIL::SigSpec* cell_output = &cell->connections.at(RTLIL::IdString("\\Q")); int value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\D")), output_width); unsigned start_bit = 0; - for(unsigned i=0; i__chunks.size(); ++i) + for(unsigned i=0; ichunks().size(); ++i) { - output_width = cell_output->__chunks[i].width; - log_assert( output_width == cell_output->__chunks[i].wire->width);//full reg is given the next value - int reg = dump_wire(cell_output->__chunks[i].wire);//register + output_width = cell_output->chunks()[i].width; + log_assert( output_width == cell_output->chunks()[i].wire->width);//full reg is given the next value + int reg = dump_wire(cell_output->chunks()[i].wire);//register int slice = value; - if(cell_output->__chunks.size()>1) + if(cell_output->chunks().size()>1) { start_bit+=output_width; slice = ++line_num; @@ -759,11 +759,11 @@ struct BtorDumper log("writing slice cell\n"); const RTLIL::SigSpec* input = &cell->connections.at(RTLIL::IdString("\\A")); int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); - log_assert(input->__width == input_width); + log_assert(input->size() == input_width); int input_line = dump_sigspec(input, input_width); const RTLIL::SigSpec* output = &cell->connections.at(RTLIL::IdString("\\Y")); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - log_assert(output->__width == output_width); + log_assert(output->size() == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); ++line_num; str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, input_line, output_width+offset-1, offset); @@ -775,11 +775,11 @@ struct BtorDumper log("writing concat cell\n"); const RTLIL::SigSpec* input_a = &cell->connections.at(RTLIL::IdString("\\A")); int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); - log_assert(input_a->__width == input_a_width); + log_assert(input_a->size() == input_a_width); int input_a_line = dump_sigspec(input_a, input_a_width); const RTLIL::SigSpec* input_b = &cell->connections.at(RTLIL::IdString("\\B")); int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); - log_assert(input_b->__width == input_b_width); + log_assert(input_b->size() == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); ++line_num; str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), input_a_width+input_b_width, @@ -843,11 +843,11 @@ struct BtorDumper log(" - %s\n", cstr(it->second->type)); if (cell->type == "$memrd") { - for(unsigned i=0; i__chunks.size(); ++i) + for(unsigned i=0; ichunks().size(); ++i) { - RTLIL::Wire *w = output_sig->__chunks[i].wire; + RTLIL::Wire *w = output_sig->chunks()[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->__chunks[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks()[i])); } } else if(cell->type == "$memwr") @@ -856,22 +856,22 @@ struct BtorDumper } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - RTLIL::IdString wire_id = output_sig->__chunks[0].wire->name; - for(unsigned i=0; i__chunks.size(); ++i) + RTLIL::IdString wire_id = output_sig->chunks()[0].wire->name; + for(unsigned i=0; ichunks().size(); ++i) { - RTLIL::Wire *w = output_sig->__chunks[i].wire; + RTLIL::Wire *w = output_sig->chunks()[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->__chunks[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks()[i])); basic_wires[wire_id] = true; } } else { - for(unsigned i=0; i__chunks.size(); ++i) + for(unsigned i=0; ichunks().size(); ++i) { - RTLIL::Wire *w = output_sig->__chunks[i].wire; + RTLIL::Wire *w = output_sig->chunks()[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->__chunks[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks()[i])); } } } diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index c239ef30..bb2b26e2 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -149,7 +149,7 @@ struct EdifBackend : public Backend { if (!design->modules.count(cell->type) || design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) { lib_cell_ports[cell->type]; for (auto p : cell->connections) { - if (p.second.__width > 1) + if (p.second.size() > 1) log_error("Found multi-bit port %s on library cell %s.%s (%s): not supported in EDIF backend!\n", RTLIL::id2cstr(p.first), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); lib_cell_ports[cell->type].insert(p.first); @@ -307,9 +307,9 @@ struct EdifBackend : public Backend { for (auto &p : cell->connections) { RTLIL::SigSpec sig = sigmap(p.second); sig.expand(); - for (int i = 0; i < sig.__width; i++) { - RTLIL::SigSpec sigbit(sig.__chunks.at(i)); - if (sig.__width == 1) + for (int i = 0; i < sig.size(); i++) { + RTLIL::SigSpec sigbit(sig.chunks().at(i)); + if (sig.size() == 1) net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name))); else net_join_db[sigbit].insert(stringf("(portRef (member %s %d) (instanceRef %s))", EDIF_REF(p.first), i, EDIF_REF(cell->name))); @@ -319,9 +319,9 @@ struct EdifBackend : public Backend { for (auto &it : net_join_db) { RTLIL::SigSpec sig = it.first; sig.optimize(); - log_assert(sig.__width == 1); - if (sig.__chunks.at(0).wire == NULL) { - if (sig.__chunks.at(0).data.bits.at(0) != RTLIL::State::S0 && sig.__chunks.at(0).data.bits.at(0) != RTLIL::State::S1) + log_assert(sig.size() == 1); + if (sig.chunks().at(0).wire == NULL) { + if (sig.chunks().at(0).data.bits.at(0) != RTLIL::State::S0 && sig.chunks().at(0).data.bits.at(0) != RTLIL::State::S1) continue; } std::string netname = log_signal(sig); @@ -331,10 +331,10 @@ struct EdifBackend : public Backend { fprintf(f, " (net %s (joined\n", EDIF_DEF(netname)); for (auto &ref : it.second) fprintf(f, " %s\n", ref.c_str()); - if (sig.__chunks.at(0).wire == NULL) { - if (sig.__chunks.at(0).data.bits.at(0) == RTLIL::State::S0) + if (sig.chunks().at(0).wire == NULL) { + if (sig.chunks().at(0).data.bits.at(0) == RTLIL::State::S0) fprintf(f, " (portRef G (instanceRef GND))\n"); - if (sig.__chunks.at(0).data.bits.at(0) == RTLIL::State::S1) + if (sig.chunks().at(0).data.bits.at(0) == RTLIL::State::S1) fprintf(f, " (portRef P (instanceRef VCC))\n"); } fprintf(f, " ))\n"); diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index e1a8bfd4..a312b02c 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -102,11 +102,11 @@ void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool au void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint) { - if (sig.__chunks.size() == 1) { - dump_sigchunk(f, sig.__chunks[0], autoint); + if (sig.chunks().size() == 1) { + dump_sigchunk(f, sig.chunks()[0], autoint); } else { fprintf(f, "{ "); - for (auto it = sig.__chunks.rbegin(); it != sig.__chunks.rend(); it++) { + for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) { dump_sigchunk(f, *it, false); fprintf(f, " "); } @@ -314,7 +314,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module if (only_selected) { RTLIL::SigSpec sigs = it->first; sigs.append(it->second); - for (auto &c : sigs.__chunks) { + for (auto &c : sigs.chunks()) { if (c.wire == NULL || !design->selected(module, c.wire)) continue; show_conn = true; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 049a2ce8..832922de 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -30,23 +30,23 @@ static std::string netname(std::set &conntypes_code, std::setwidth) + if (sig.chunks()[0].offset != 0 || sig.size() != sig.chunks()[0].wire->width) goto error; - return RTLIL::unescape_id(sig.__chunks[0].wire->name); + return RTLIL::unescape_id(sig.chunks()[0].wire->name); } struct IntersynthBackend : public Backend { @@ -177,9 +177,9 @@ struct IntersynthBackend : public Backend { node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); for (auto &port : cell->connections) { RTLIL::SigSpec sig = sigmap(port.second); - if (sig.__width != 0) { - conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.__width, sig.__width, sig.__width)); - celltype_code += stringf(" b%d %s%s", sig.__width, ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first)); + if (sig.size() != 0) { + conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size())); + celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first)); node_code += stringf(" %s %s", RTLIL::id2cstr(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str()); } } diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index c7f832c6..8e894caf 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -27,16 +27,16 @@ static void print_spice_net(FILE *f, RTLIL::SigSpec s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) { - log_assert(s.__chunks.size() == 1 && s.__chunks[0].width == 1); - if (s.__chunks[0].wire) { - if (s.__chunks[0].wire->width > 1) - fprintf(f, " %s[%d]", RTLIL::id2cstr(s.__chunks[0].wire->name), s.__chunks[0].offset); + log_assert(s.chunks().size() == 1 && s.chunks()[0].width == 1); + if (s.chunks()[0].wire) { + if (s.chunks()[0].wire->width > 1) + fprintf(f, " %s[%d]", RTLIL::id2cstr(s.chunks()[0].wire->name), s.chunks()[0].offset); else - fprintf(f, " %s", RTLIL::id2cstr(s.__chunks[0].wire->name)); + fprintf(f, " %s", RTLIL::id2cstr(s.chunks()[0].wire->name)); } else { - if (s.__chunks[0].data.bits.at(0) == RTLIL::State::S0) + if (s.chunks()[0].data.bits.at(0) == RTLIL::State::S0) fprintf(f, " %s", neg.c_str()); - else if (s.__chunks[0].data.bits.at(0) == RTLIL::State::S1) + else if (s.chunks()[0].data.bits.at(0) == RTLIL::State::S1) fprintf(f, " %s", pos.c_str()); else fprintf(f, " %s%d", ncpf.c_str(), nc_counter++); @@ -90,9 +90,9 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de } for (auto &sig : port_sigs) { - for (int i = 0; i < sig.__width; i++) { - RTLIL::SigSpec s = sig.extract(big_endian ? sig.__width - 1 - i : i, 1); - log_assert(s.__chunks.size() == 1 && s.__chunks[0].width == 1); + for (int i = 0; i < sig.size(); i++) { + RTLIL::SigSpec s = sig.extract(big_endian ? sig.size() - 1 - i : i, 1); + log_assert(s.chunks().size() == 1 && s.chunks()[0].width == 1); print_spice_net(f, s, neg, pos, ncpf, nc_counter); } } @@ -101,7 +101,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de } for (auto &conn : module->connections) - for (int i = 0; i < conn.first.__width; i++) { + for (int i = 0; i < conn.first.size(); i++) { fprintf(f, "V%d", conn_counter++); print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter); print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 6aeb5084..4b60f0fb 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -134,17 +134,17 @@ std::string id(std::string internal_id, bool may_rename = true) bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name) { sig.optimize(); - if (sig.__chunks.size() != 1 || sig.__chunks[0].wire == NULL) + if (sig.chunks().size() != 1 || sig.chunks()[0].wire == NULL) return false; - if (reg_wires.count(sig.__chunks[0].wire->name) == 0) + if (reg_wires.count(sig.chunks()[0].wire->name) == 0) return false; - reg_name = id(sig.__chunks[0].wire->name); - if (sig.__width != sig.__chunks[0].wire->width) { - if (sig.__width == 1) - reg_name += stringf("[%d]", sig.__chunks[0].wire->start_offset + sig.__chunks[0].offset); + reg_name = id(sig.chunks()[0].wire->name); + if (sig.size() != sig.chunks()[0].wire->width) { + if (sig.size() == 1) + reg_name += stringf("[%d]", sig.chunks()[0].wire->start_offset + sig.chunks()[0].offset); else - reg_name += stringf("[%d:%d]", sig.__chunks[0].wire->start_offset + sig.__chunks[0].offset + sig.__chunks[0].width - 1, - sig.__chunks[0].wire->start_offset + sig.__chunks[0].offset); + reg_name += stringf("[%d:%d]", sig.chunks()[0].wire->start_offset + sig.chunks()[0].offset + sig.chunks()[0].width - 1, + sig.chunks()[0].wire->start_offset + sig.chunks()[0].offset); } return true; } @@ -221,12 +221,12 @@ void dump_sigchunk(FILE *f, RTLIL::SigChunk &chunk, bool no_decimal = false) void dump_sigspec(FILE *f, RTLIL::SigSpec &sig) { - if (sig.__chunks.size() == 1) { - dump_sigchunk(f, sig.__chunks[0]); + if (sig.chunks().size() == 1) { + dump_sigchunk(f, sig.chunks()[0]); } else { fprintf(f, "{ "); - for (auto it = sig.__chunks.rbegin(); it != sig.__chunks.rend(); it++) { - if (it != sig.__chunks.rbegin()) + for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) { + if (it != sig.chunks().rbegin()) fprintf(f, ", "); dump_sigchunk(f, *it, true); } @@ -300,11 +300,11 @@ std::string cellname(RTLIL::Cell *cell) if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections.count("\\Q") > 0) { RTLIL::SigSpec sig = cell->connections["\\Q"]; - if (sig.__width != 1 || sig.is_fully_const()) + if (sig.size() != 1 || sig.is_fully_const()) goto no_special_reg_name; sig.optimize(); - RTLIL::Wire *wire = sig.__chunks[0].wire; + RTLIL::Wire *wire = sig.chunks()[0].wire; if (wire->name[0] != '\\') goto no_special_reg_name; @@ -318,7 +318,7 @@ std::string cellname(RTLIL::Cell *cell) cell_name = cell_name + "_reg"; if (wire->width != 1) - cell_name += stringf("[%d]", wire->start_offset + sig.__chunks[0].offset); + cell_name += stringf("[%d]", wire->start_offset + sig.chunks()[0].offset); if (active_module && active_module->count_id(cell_name) > 0) goto no_special_reg_name; @@ -532,7 +532,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$pmux_safe") { int width = cell->parameters["\\WIDTH"].as_int(); - int s_width = cell->connections["\\S"].__width; + int s_width = cell->connections["\\S"].size(); std::string func_name = cellname(cell); fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); @@ -725,7 +725,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, ","); first_arg = false; fprintf(f, "\n%s .%s(", indent.c_str(), id(it->first).c_str()); - if (it->second.__width > 0) + if (it->second.size() > 0) dump_sigspec(f, it->second); fprintf(f, ")"); } @@ -751,7 +751,7 @@ void dump_case_body(FILE *f, std::string indent, RTLIL::CaseRule *cs, bool omit_ fprintf(f, "%s" "begin\n", indent.c_str()); for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) { - if (it->first.__width == 0) + if (it->first.size() == 0) continue; fprintf(f, "%s ", indent.c_str()); dump_sigspec(f, it->first); @@ -772,7 +772,7 @@ void dump_case_body(FILE *f, std::string indent, RTLIL::CaseRule *cs, bool omit_ void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw) { - if (sw->signal.__width == 0) { + if (sw->signal.size() == 0) { fprintf(f, "%s" "begin\n", indent.c_str()); for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) { if ((*it)->compare.size() == 0) @@ -811,9 +811,9 @@ void case_body_find_regs(RTLIL::CaseRule *cs) case_body_find_regs(*it2); for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) { - for (size_t i = 0; i < it->first.__chunks.size(); i++) - if (it->first.__chunks[i].wire) - reg_wires.insert(it->first.__chunks[i].wire->name); + for (size_t i = 0; i < it->first.chunks().size(); i++) + if (it->first.chunks()[i].wire) + reg_wires.insert(it->first.chunks()[i].wire->name); } } @@ -823,9 +823,9 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r case_body_find_regs(&proc->root_case); for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++) for (auto it2 = (*it)->actions.begin(); it2 != (*it)->actions.end(); it2++) { - for (size_t i = 0; i < it2->first.__chunks.size(); i++) - if (it2->first.__chunks[i].wire) - reg_wires.insert(it2->first.__chunks[i].wire->name); + for (size_t i = 0; i < it2->first.chunks().size(); i++) + if (it2->first.chunks()[i].wire) + reg_wires.insert(it2->first.chunks()[i].wire->name); } return; } @@ -876,7 +876,7 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r } for (auto it = sync->actions.begin(); it != sync->actions.end(); it++) { - if (it->first.__width == 0) + if (it->first.size() == 0) continue; fprintf(f, "%s ", indent.c_str()); dump_sigspec(f, it->first); @@ -911,9 +911,9 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) RTLIL::SigSpec sig = cell->connections["\\Q"]; sig.optimize(); - if (sig.__chunks.size() == 1 && sig.__chunks[0].wire) - for (int i = 0; i < sig.__chunks[0].width; i++) - reg_bits.insert(std::pair(sig.__chunks[0].wire, sig.__chunks[0].offset+i)); + if (sig.chunks().size() == 1 && sig.chunks()[0].wire) + for (int i = 0; i < sig.chunks()[0].width; i++) + reg_bits.insert(std::pair(sig.chunks()[0].wire, sig.chunks()[0].offset+i)); } for (auto &it : module->wires) { diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dc9f566c..681b3486 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 e6d3d4c5..e8af447b 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 c449a593..3fe227be 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; diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 0ca26bb3..934796d2 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -31,16 +31,16 @@ struct BitPatternPool BitPatternPool(RTLIL::SigSpec sig) { - width = sig.__width; + width = sig.size(); if (width > 0) { std::vector pattern(width); sig.optimize(); for (int i = 0; i < width; i++) { RTLIL::SigSpec s = sig.extract(i, 1); s.optimize(); - assert(s.__chunks.size() == 1); - if (s.__chunks[0].wire == NULL && s.__chunks[0].data.bits[0] <= RTLIL::State::S1) - pattern[i] = s.__chunks[0].data.bits[0]; + assert(s.chunks().size() == 1); + if (s.chunks()[0].wire == NULL && s.chunks()[0].data.bits[0] <= RTLIL::State::S1) + pattern[i] = s.chunks()[0].data.bits[0]; else pattern[i] = RTLIL::State::Sa; } @@ -63,8 +63,8 @@ struct BitPatternPool { sig.optimize(); assert(sig.is_fully_const()); - assert(sig.__chunks.size() == 1); - bits_t bits = sig.__chunks[0].data.bits; + assert(sig.chunks().size() == 1); + bits_t bits = sig.chunks()[0].data.bits; for (auto &b : bits) if (b > RTLIL::State::S1) b = RTLIL::State::Sa; diff --git a/kernel/consteval.h b/kernel/consteval.h index fa079e14..564098c6 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -72,8 +72,8 @@ struct ConstEval #ifndef NDEBUG RTLIL::SigSpec current_val = values_map(sig); current_val.expand(); - for (size_t i = 0; i < current_val.__chunks.size(); i++) { - RTLIL::SigChunk &chunk = current_val.__chunks[i]; + for (size_t i = 0; i < current_val.chunks().size(); i++) { + RTLIL::SigChunk &chunk = current_val.chunks()[i]; assert(chunk.wire != NULL || chunk.data.bits[0] == value.bits[i]); } #endif @@ -113,10 +113,10 @@ struct ConstEval int count_maybe_set_s_bits = 0; int count_set_s_bits = 0; - for (int i = 0; i < sig_s.__width; i++) + for (int i = 0; i < sig_s.size(); i++) { RTLIL::State s_bit = sig_s.extract(i, 1).as_const().bits.at(0); - RTLIL::SigSpec b_slice = sig_b.extract(sig_y.__width*i, sig_y.__width); + RTLIL::SigSpec b_slice = sig_b.extract(sig_y.size()*i, sig_y.size()); if (s_bit == RTLIL::State::Sx || s_bit == RTLIL::State::S1) y_candidates.push_back(b_slice); @@ -162,9 +162,9 @@ struct ConstEval } else { - if (sig_a.__width > 0 && !eval(sig_a, undef, cell)) + if (sig_a.size() > 0 && !eval(sig_a, undef, cell)) return false; - if (sig_b.__width > 0 && !eval(sig_b, undef, cell)) + if (sig_b.size() > 0 && !eval(sig_b, undef, cell)) return false; set(sig_y, CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const())); } @@ -210,9 +210,9 @@ struct ConstEval if (sig.is_fully_const()) return true; - for (size_t i = 0; i < sig.__chunks.size(); i++) - if (sig.__chunks[i].wire != NULL) - undef.append(sig.__chunks[i]); + for (size_t i = 0; i < sig.chunks().size(); i++) + if (sig.chunks()[i].wire != NULL) + undef.append(sig.chunks()[i]); return false; } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 04332309..43511304 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -350,7 +350,7 @@ namespace { { if (cell->connections.count(name) == 0) error(__LINE__); - if (cell->connections.at(name).__width != width) + if (cell->connections.at(name).size() != width) error(__LINE__); expected_ports.insert(name); } @@ -381,7 +381,7 @@ namespace { char portname[3] = { '\\', *p, 0 }; if (cell->connections.count(portname) == 0) error(__LINE__); - if (cell->connections.at(portname).__width != 1) + if (cell->connections.at(portname).size() != 1) error(__LINE__); } @@ -755,7 +755,7 @@ void RTLIL::Module::check() } for (auto &it : connections) { - assert(it.first.__width == it.second.__width); + assert(it.first.size() == it.second.size()); it.first.check(); it.second.check(); } @@ -801,7 +801,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const RTLIL::Module *mod; void operator()(RTLIL::SigSpec &sig) { - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) if (c.wire != NULL) c.wire = mod->wires.at(c.wire->name); } @@ -891,8 +891,8 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) cell->name = name; \ cell->type = _type; \ cell->parameters["\\A_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.__width; \ - cell->parameters["\\Y_WIDTH"] = sig_y.__width; \ + cell->parameters["\\A_WIDTH"] = sig_a.size(); \ + cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ cell->connections["\\A"] = sig_a; \ cell->connections["\\Y"] = sig_y; \ add(cell); \ @@ -903,10 +903,10 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) add ## _func(name, sig_a, sig_y, is_signed); \ return sig_y; \ } -DEF_METHOD(Not, sig_a.__width, "$not") -DEF_METHOD(Pos, sig_a.__width, "$pos") -DEF_METHOD(Bu0, sig_a.__width, "$bu0") -DEF_METHOD(Neg, sig_a.__width, "$neg") +DEF_METHOD(Not, sig_a.size(), "$not") +DEF_METHOD(Pos, sig_a.size(), "$pos") +DEF_METHOD(Bu0, sig_a.size(), "$bu0") +DEF_METHOD(Neg, sig_a.size(), "$neg") DEF_METHOD(ReduceAnd, 1, "$reduce_and") DEF_METHOD(ReduceOr, 1, "$reduce_or") DEF_METHOD(ReduceXor, 1, "$reduce_xor") @@ -922,9 +922,9 @@ DEF_METHOD(LogicNot, 1, "$logic_not") cell->type = _type; \ cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\B_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.__width; \ - cell->parameters["\\B_WIDTH"] = sig_b.__width; \ - cell->parameters["\\Y_WIDTH"] = sig_y.__width; \ + cell->parameters["\\A_WIDTH"] = sig_a.size(); \ + cell->parameters["\\B_WIDTH"] = sig_b.size(); \ + cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ cell->connections["\\A"] = sig_a; \ cell->connections["\\B"] = sig_b; \ cell->connections["\\Y"] = sig_y; \ @@ -936,14 +936,14 @@ DEF_METHOD(LogicNot, 1, "$logic_not") add ## _func(name, sig_a, sig_b, sig_y, is_signed); \ return sig_y; \ } -DEF_METHOD(And, std::max(sig_a.__width, sig_b.__width), "$and") -DEF_METHOD(Or, std::max(sig_a.__width, sig_b.__width), "$or") -DEF_METHOD(Xor, std::max(sig_a.__width, sig_b.__width), "$xor") -DEF_METHOD(Xnor, std::max(sig_a.__width, sig_b.__width), "$xnor") -DEF_METHOD(Shl, sig_a.__width, "$shl") -DEF_METHOD(Shr, sig_a.__width, "$shr") -DEF_METHOD(Sshl, sig_a.__width, "$sshl") -DEF_METHOD(Sshr, sig_a.__width, "$sshr") +DEF_METHOD(And, std::max(sig_a.size(), sig_b.size()), "$and") +DEF_METHOD(Or, std::max(sig_a.size(), sig_b.size()), "$or") +DEF_METHOD(Xor, std::max(sig_a.size(), sig_b.size()), "$xor") +DEF_METHOD(Xnor, std::max(sig_a.size(), sig_b.size()), "$xnor") +DEF_METHOD(Shl, sig_a.size(), "$shl") +DEF_METHOD(Shr, sig_a.size(), "$shr") +DEF_METHOD(Sshl, sig_a.size(), "$sshl") +DEF_METHOD(Sshr, sig_a.size(), "$sshr") DEF_METHOD(Lt, 1, "$lt") DEF_METHOD(Le, 1, "$le") DEF_METHOD(Eq, 1, "$eq") @@ -952,11 +952,11 @@ DEF_METHOD(Eqx, 1, "$eqx") DEF_METHOD(Nex, 1, "$nex") DEF_METHOD(Ge, 1, "$ge") DEF_METHOD(Gt, 1, "$gt") -DEF_METHOD(Add, std::max(sig_a.__width, sig_b.__width), "$add") -DEF_METHOD(Sub, std::max(sig_a.__width, sig_b.__width), "$sub") -DEF_METHOD(Mul, std::max(sig_a.__width, sig_b.__width), "$mul") -DEF_METHOD(Div, std::max(sig_a.__width, sig_b.__width), "$div") -DEF_METHOD(Mod, std::max(sig_a.__width, sig_b.__width), "$mod") +DEF_METHOD(Add, std::max(sig_a.size(), sig_b.size()), "$add") +DEF_METHOD(Sub, std::max(sig_a.size(), sig_b.size()), "$sub") +DEF_METHOD(Mul, std::max(sig_a.size(), sig_b.size()), "$mul") +DEF_METHOD(Div, std::max(sig_a.size(), sig_b.size()), "$div") +DEF_METHOD(Mod, std::max(sig_a.size(), sig_b.size()), "$mod") DEF_METHOD(LogicAnd, 1, "$logic_and") DEF_METHOD(LogicOr, 1, "$logic_or") #undef DEF_METHOD @@ -966,9 +966,9 @@ DEF_METHOD(LogicOr, 1, "$logic_or") RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->parameters["\\WIDTH"] = sig_a.__width; \ - cell->parameters["\\WIDTH"] = sig_b.__width; \ - if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.__width; \ + cell->parameters["\\WIDTH"] = sig_a.size(); \ + cell->parameters["\\WIDTH"] = sig_b.size(); \ + if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ cell->connections["\\A"] = sig_a; \ cell->connections["\\B"] = sig_b; \ cell->connections["\\S"] = sig_s; \ @@ -977,7 +977,7 @@ DEF_METHOD(LogicOr, 1, "$logic_or") return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \ - RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.__width); \ + RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \ add ## _func(name, sig_a, sig_b, sig_s, sig_y); \ return sig_y; \ } @@ -1050,9 +1050,9 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R cell->type = "$pow"; cell->parameters["\\A_SIGNED"] = a_signed; cell->parameters["\\B_SIGNED"] = b_signed; - cell->parameters["\\A_WIDTH"] = sig_a.__width; - cell->parameters["\\B_WIDTH"] = sig_b.__width; - cell->parameters["\\Y_WIDTH"] = sig_y.__width; + cell->parameters["\\A_WIDTH"] = sig_a.size(); + cell->parameters["\\B_WIDTH"] = sig_b.size(); + cell->parameters["\\Y_WIDTH"] = sig_y.size(); cell->connections["\\A"] = sig_a; cell->connections["\\B"] = sig_b; cell->connections["\\Y"] = sig_y; @@ -1065,8 +1065,8 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = "$slice"; - cell->parameters["\\A_WIDTH"] = sig_a.__width; - cell->parameters["\\Y_WIDTH"] = sig_y.__width; + cell->parameters["\\A_WIDTH"] = sig_a.size(); + cell->parameters["\\Y_WIDTH"] = sig_y.size(); cell->parameters["\\OFFSET"] = offset; cell->connections["\\A"] = sig_a; cell->connections["\\Y"] = sig_y; @@ -1079,8 +1079,8 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = "$concat"; - cell->parameters["\\A_WIDTH"] = sig_a.__width; - cell->parameters["\\B_WIDTH"] = sig_b.__width; + cell->parameters["\\A_WIDTH"] = sig_a.size(); + cell->parameters["\\B_WIDTH"] = sig_b.size(); cell->connections["\\A"] = sig_a; cell->connections["\\B"] = sig_b; cell->connections["\\Y"] = sig_y; @@ -1094,7 +1094,7 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, R cell->name = name; cell->type = "$lut"; cell->parameters["\\LUT"] = lut; - cell->parameters["\\WIDTH"] = sig_i.__width; + cell->parameters["\\WIDTH"] = sig_i.size(); cell->connections["\\I"] = sig_i; cell->connections["\\O"] = sig_o; add(cell); @@ -1119,7 +1119,7 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, cell->type = "$sr"; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.__width; + cell->parameters["\\WIDTH"] = sig_q.size(); cell->connections["\\SET"] = sig_set; cell->connections["\\CLR"] = sig_clr; cell->connections["\\Q"] = sig_q; @@ -1133,7 +1133,7 @@ RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, cell->name = name; cell->type = "$dff"; cell->parameters["\\CLK_POLARITY"] = clk_polarity; - cell->parameters["\\WIDTH"] = sig_q.__width; + cell->parameters["\\WIDTH"] = sig_q.size(); cell->connections["\\CLK"] = sig_clk; cell->connections["\\D"] = sig_d; cell->connections["\\Q"] = sig_q; @@ -1150,7 +1150,7 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.__width; + cell->parameters["\\WIDTH"] = sig_q.size(); cell->connections["\\CLK"] = sig_clk; cell->connections["\\SET"] = sig_set; cell->connections["\\CLR"] = sig_clr; @@ -1169,7 +1169,7 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\ARST_POLARITY"] = arst_polarity; cell->parameters["\\ARST_VALUE"] = arst_value; - cell->parameters["\\WIDTH"] = sig_q.__width; + cell->parameters["\\WIDTH"] = sig_q.size(); cell->connections["\\CLK"] = sig_clk; cell->connections["\\ARST"] = sig_arst; cell->connections["\\D"] = sig_d; @@ -1184,7 +1184,7 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e cell->name = name; cell->type = "$dlatch"; cell->parameters["\\EN_POLARITY"] = en_polarity; - cell->parameters["\\WIDTH"] = sig_q.__width; + cell->parameters["\\WIDTH"] = sig_q.size(); cell->connections["\\EN"] = sig_en; cell->connections["\\D"] = sig_d; cell->connections["\\Q"] = sig_q; @@ -1201,7 +1201,7 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; - cell->parameters["\\WIDTH"] = sig_q.__width; + cell->parameters["\\WIDTH"] = sig_q.size(); cell->connections["\\EN"] = sig_en; cell->connections["\\SET"] = sig_set; cell->connections["\\CLR"] = sig_clr; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7fb416f1..88ed2f6a 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -560,8 +560,8 @@ public: }; inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { - assert(sig.__width == 1 && sig.__chunks.size() == 1); - *this = SigBit(sig.__chunks[0]); + assert(sig.size() == 1 && sig.chunks().size() == 1); + *this = SigBit(sig.chunks()[0]); } struct RTLIL::CaseRule { diff --git a/kernel/satgen.h b/kernel/satgen.h index 012b6ab8..9e227707 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -55,9 +55,9 @@ struct SatGen sig.expand(); std::vector vec; - vec.reserve(sig.__chunks.size()); + vec.reserve(sig.chunks().size()); - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) if (c.wire == NULL) { RTLIL::State bit = c.data.bits.at(0); if (model_undef && dup_undef && bit == RTLIL::State::Sx) @@ -118,7 +118,7 @@ struct SatGen if (timestep_rhs < 0) timestep_rhs = timestep_lhs; - assert(lhs.__width == rhs.__width); + assert(lhs.size() == rhs.size()); std::vector vec_lhs = importSigSpec(lhs, timestep_lhs); std::vector vec_rhs = importSigSpec(rhs, timestep_rhs); @@ -130,7 +130,7 @@ struct SatGen std::vector undef_rhs = importUndefSigSpec(rhs, timestep_rhs); std::vector eq_bits; - for (int i = 0; i < lhs.__width; i++) + for (int i = 0; i < lhs.size(); i++) eq_bits.push_back(ez->AND(ez->IFF(undef_lhs.at(i), undef_rhs.at(i)), ez->IFF(ez->OR(vec_lhs.at(i), undef_lhs.at(i)), ez->OR(vec_rhs.at(i), undef_rhs.at(i))))); return ez->expression(ezSAT::OpAnd, eq_bits); @@ -742,11 +742,11 @@ struct SatGen only_first_one.at(0) = ez->TRUE; div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); } else { - div_zero_result.insert(div_zero_result.end(), cell->connections.at("\\A").__width, ez->TRUE); + div_zero_result.insert(div_zero_result.end(), cell->connections.at("\\A").size(), ez->TRUE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->FALSE); } } else { - int copy_a_bits = std::min(cell->connections.at("\\A").__width, cell->connections.at("\\B").__width); + int copy_a_bits = std::min(cell->connections.at("\\A").size(), cell->connections.at("\\B").size()); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); @@ -768,7 +768,7 @@ struct SatGen { RTLIL::SigSpec a = cell->connections.at("\\A"); RTLIL::SigSpec y = cell->connections.at("\\Y"); - ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.__width), y, timestep)); + ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.size()), y, timestep)); return true; } diff --git a/kernel/sigtools.h b/kernel/sigtools.h index c886ff16..27abd867 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -38,7 +38,7 @@ struct SigPool void add(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -56,7 +56,7 @@ struct SigPool void del(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -75,10 +75,10 @@ struct SigPool { from.expand(); to.expand(); - assert(from.__chunks.size() == to.__chunks.size()); - for (size_t i = 0; i < from.__chunks.size(); i++) { - bitDef_t bit_from(from.__chunks[i].wire, from.__chunks[i].offset); - bitDef_t bit_to(to.__chunks[i].wire, to.__chunks[i].offset); + assert(from.chunks().size() == to.chunks().size()); + for (size_t i = 0; i < from.chunks().size(); i++) { + bitDef_t bit_from(from.chunks()[i].wire, from.chunks()[i].offset); + bitDef_t bit_to(to.chunks()[i].wire, to.chunks()[i].offset); if (bit_from.first == NULL || bit_to.first == NULL) continue; if (bits.count(bit_from) > 0) @@ -90,7 +90,7 @@ struct SigPool { RTLIL::SigSpec result; sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -104,7 +104,7 @@ struct SigPool { RTLIL::SigSpec result; sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -117,7 +117,7 @@ struct SigPool bool check_any(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -130,7 +130,7 @@ struct SigPool bool check_all(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; bitDef_t bit(c.wire, c.offset); @@ -179,7 +179,7 @@ struct SigSet void insert(RTLIL::SigSpec sig, T data) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -191,7 +191,7 @@ struct SigSet void insert(RTLIL::SigSpec sig, const std::set &data) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -203,7 +203,7 @@ struct SigSet void erase(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -215,7 +215,7 @@ struct SigSet void erase(RTLIL::SigSpec sig, T data) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -227,7 +227,7 @@ struct SigSet void erase(RTLIL::SigSpec sig, const std::set &data) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -239,7 +239,7 @@ struct SigSet void find(RTLIL::SigSpec sig, std::set &result) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -259,7 +259,7 @@ struct SigSet bool has(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL) continue; assert(c.width == 1); @@ -420,11 +420,11 @@ struct SigMap from.expand(); to.expand(); - assert(from.__chunks.size() == to.__chunks.size()); - for (size_t i = 0; i < from.__chunks.size(); i++) + assert(from.chunks().size() == to.chunks().size()); + for (size_t i = 0; i < from.chunks().size(); i++) { - RTLIL::SigChunk &cf = from.__chunks[i]; - RTLIL::SigChunk &ct = to.__chunks[i]; + RTLIL::SigChunk &cf = from.chunks()[i]; + RTLIL::SigChunk &ct = to.chunks()[i]; if (cf.wire == NULL) continue; @@ -442,9 +442,9 @@ struct SigMap void add(RTLIL::SigSpec sig) { sig.expand(); - for (size_t i = 0; i < sig.__chunks.size(); i++) + for (size_t i = 0; i < sig.chunks().size(); i++) { - RTLIL::SigChunk &c = sig.__chunks[i]; + RTLIL::SigChunk &c = sig.chunks()[i]; if (c.wire != NULL) { register_bit(c); set_bit(c, c); @@ -455,14 +455,14 @@ struct SigMap void del(RTLIL::SigSpec sig) { sig.expand(); - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) unregister_bit(c); } void apply(RTLIL::SigSpec &sig) const { sig.expand(); - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) map_bit(c); sig.optimize(); } diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index e21be30b..2d921b7b 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -69,8 +69,8 @@ static RTLIL::SigSpec clk_sig; static int map_signal(RTLIL::SigSpec sig, char gate_type = -1, int in1 = -1, int in2 = -1, int in3 = -1) { - assert(sig.__width == 1); - assert(sig.__chunks.size() == 1); + assert(sig.size() == 1); + assert(sig.chunks().size() == 1); assign_map.apply(sig); @@ -105,7 +105,7 @@ static void mark_port(RTLIL::SigSpec sig) { assign_map.apply(sig); sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire != NULL && signal_map.count(c) > 0) signal_list[signal_map[c]].is_port = true; } @@ -124,7 +124,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) RTLIL::SigSpec sig_q = cell->connections["\\Q"]; if (keepff) - for (auto &c : sig_q.__chunks) + for (auto &c : sig_q.chunks()) if (c.wire != NULL) c.wire->attributes["\\keep"] = 1; @@ -300,8 +300,8 @@ static void handle_loops() for (auto &edge_it : edges) { int id2 = edge_it.first; - RTLIL::Wire *w1 = signal_list[id1].sig.__chunks[0].wire; - RTLIL::Wire *w2 = signal_list[id2].sig.__chunks[0].wire; + RTLIL::Wire *w1 = signal_list[id1].sig.chunks()[0].wire; + RTLIL::Wire *w2 = signal_list[id2].sig.chunks()[0].wire; if (w1 != NULL) continue; else if (w2 == NULL) @@ -469,7 +469,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std clk_sig = assign_map(RTLIL::SigSpec(module->wires.at(RTLIL::escape_id(clk_str)), 1)); } - if (dff_mode && clk_sig.__width == 0) + if (dff_mode && clk_sig.size() == 0) { int best_dff_counter = 0; std::map, int> dff_counters; @@ -490,13 +490,13 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } if (dff_mode || !clk_str.empty()) { - if (clk_sig.__width == 0) + if (clk_sig.size() == 0) log("No (matching) clock domain found. Not extracting any FF cells.\n"); else log("Found (matching) %s clock domain: %s\n", clk_polarity ? "posedge" : "negedge", log_signal(clk_sig)); } - if (clk_sig.__width != 0) + if (clk_sig.size() != 0) mark_port(clk_sig); std::vector cells; @@ -552,10 +552,10 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std fprintf(f, "# n%-5d %s\n", si.id, log_signal(si.sig)); for (auto &si : signal_list) { - assert(si.sig.__width == 1 && si.sig.__chunks.size() == 1); - if (si.sig.__chunks[0].wire == NULL) { + assert(si.sig.size() == 1 && si.sig.chunks().size() == 1); + if (si.sig.chunks()[0].wire == NULL) { fprintf(f, ".names n%d\n", si.id); - if (si.sig.__chunks[0].data.bits[0] == RTLIL::State::S1) + if (si.sig.chunks()[0].data.bits[0] == RTLIL::State::S1) fprintf(f, "1\n"); } } @@ -716,15 +716,15 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); module->connections.push_back(conn); continue; } if (c->type == "\\BUF") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); - conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); module->connections.push_back(conn); continue; } @@ -732,8 +732,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_INV_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; @@ -742,9 +742,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_" + c->type.substr(1) + "_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].__chunks[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); + cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].chunks()[0].wire->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; @@ -753,21 +753,21 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_MUX_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].__chunks[0].wire->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].__chunks[0].wire->name)]); - cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].__chunks[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].__chunks[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); + cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].chunks()[0].wire->name)]); + cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].chunks()[0].wire->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; } if (c->type == "\\DFF") { - log_assert(clk_sig.__width == 1); + log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = new RTLIL::Cell; cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; cell->name = remap_name(c->name); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].__chunks[0].wire->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].__chunks[0].wire->name)]); + cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].chunks()[0].wire->name)]); + cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].chunks()[0].wire->name)]); cell->connections["\\C"] = clk_sig; module->cells[cell->name] = cell; design->select(module, cell); @@ -784,18 +784,18 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\_const0_" || c->type == "\\_const1_") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections.begin()->second.__chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections.begin()->second.chunks()[0].wire->name)]); conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1); module->connections.push_back(conn); continue; } if (c->type == "\\_dff_") { - log_assert(clk_sig.__width == 1); + log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = new RTLIL::Cell; cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; cell->name = remap_name(c->name); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].__chunks[0].wire->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].__chunks[0].wire->name)]); + cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].chunks()[0].wire->name)]); + cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].chunks()[0].wire->name)]); cell->connections["\\C"] = clk_sig; module->cells[cell->name] = cell; design->select(module, cell); @@ -807,7 +807,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell->name = remap_name(c->name); for (auto &conn : c->connections) { RTLIL::SigSpec newsig; - for (auto &c : conn.second.__chunks) { + for (auto &c : conn.second.chunks()) { if (c.width == 0) continue; assert(c.width == 1); @@ -822,9 +822,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std for (auto conn : mapped_mod->connections) { if (!conn.first.is_fully_const()) - conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.__chunks[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.chunks()[0].wire->name)]); if (!conn.second.is_fully_const()) - conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.__chunks[0].wire->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.chunks()[0].wire->name)]); module->connections.push_back(conn); } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 65ebe541..47fa0f82 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -177,10 +177,10 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) } input_sig.append(wire); } - output_sig = input_sig.extract(input_sig.__width-1, 1); - input_sig = input_sig.extract(0, input_sig.__width-1); + output_sig = input_sig.extract(input_sig.size()-1, 1); + input_sig = input_sig.extract(0, input_sig.size()-1); - if (input_sig.__width == 0) { + if (input_sig.size() == 0) { RTLIL::State state = RTLIL::State::Sa; while (1) { if (!read_next_line(buffer, buffer_size, line_count, f)) @@ -218,8 +218,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$lut"; - cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.__width); - cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.__width); + cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size()); + cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size()); cell->connections["\\I"] = input_sig; cell->connections["\\O"] = output_sig; lutptr = &cell->parameters.at("\\LUT"); diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index f8f9e059..dcd5fc96 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -27,7 +27,7 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & { CellTypes ct(design); - RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.__width); + RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size()); for (auto &it : module->cells) for (auto &port : it.second->connections) diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 426d2b62..6cb2a892 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -90,7 +90,7 @@ struct ConnwrappersWorker continue; int inner_width = cell->parameters.at(decl.widthparam).as_int(); - int outer_width = conn.second.__width; + int outer_width = conn.second.size(); bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(decl.signparam).as_bool(); if (inner_width >= outer_width) @@ -124,20 +124,20 @@ struct ConnwrappersWorker int extend_width = 0; RTLIL::SigBit extend_bit = is_signed ? sigbits[i] : RTLIL::SigBit(RTLIL::State::S0); - while (extend_width < extend_sig.__width && i + extend_width + 1 < sigbits.size() && + while (extend_width < extend_sig.size() && i + extend_width + 1 < sigbits.size() && sigbits[i + extend_width + 1] == extend_bit) extend_width++; if (extend_width == 0) continue; - if (old_sig.__width == 0) + if (old_sig.size() == 0) old_sig = conn.second; conn.second.replace(i+1, extend_sig.extract(0, extend_width)); i += extend_width; } - if (old_sig.__width) + if (old_sig.size()) log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second)); } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 16828e4f..c5aa196c 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -28,7 +28,7 @@ struct DeleteWireWorker void operator()(RTLIL::SigSpec &sig) { sig.optimize(); - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) if (c.wire != NULL && delete_wires_p->count(c.wire->name)) { c.wire = module->addWire(NEW_ID, c.width); c.offset = 0; diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index da36c782..d5976dcb 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -53,7 +53,7 @@ struct ScatterPass : public Pass { { RTLIL::Wire *wire = new RTLIL::Wire; wire->name = NEW_ID; - wire->width = p.second.__width; + wire->width = p.second.size(); mod_it.second->add(wire); if (ct.cell_output(c.second->type, p.first)) { diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index d668bc3a..49e79bd4 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -191,7 +191,7 @@ struct SccWorker nextsig.sort_and_unify(); sig = prevsig.extract(nextsig); - for (auto &chunk : sig.__chunks) + for (auto &chunk : sig.chunks()) if (chunk.wire != NULL) sel.selected_members[module->name].insert(chunk.wire->name); } diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 068162eb..123483a3 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -415,7 +415,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v include_match: is_input = mode == 'x' || ct.cell_input(cell.second->type, conn.first); is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first); - for (auto &chunk : conn.second.__chunks) + for (auto &chunk : conn.second.chunks()) if (chunk.wire != NULL) { if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && lhs.selected_members[mod->name].count(cell.first) == 0) if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input)) diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 3a99c0ce..7558a4e9 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -48,7 +48,7 @@ struct SetundefWorker void operator()(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) if (c.wire == NULL && c.data.bits.at(0) > RTLIL::State::S1) c.data.bits.at(0) = next_bit(); sig.optimize(); @@ -141,7 +141,7 @@ struct SetundefPass : public Pass { undriven_signals.del(sigmap(conn.second)); RTLIL::SigSpec sig = undriven_signals.export_all(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { RTLIL::SigSpec bits; for (int i = 0; i < c.width; i++) bits.append(next_bit()); diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 0006a3ff..fde96d53 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -78,7 +78,7 @@ struct ShowWorker std::string nextColor(RTLIL::SigSpec sig, std::string defaultColor) { sig.sort_and_unify(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire != NULL) for (auto &s : color_selections) if (s.second.selected_members.count(module->name) > 0 && s.second.selected_members.at(module->name).count(c.wire->name) > 0) @@ -173,13 +173,13 @@ struct ShowWorker { sig.optimize(); - if (sig.__chunks.size() == 0) { + if (sig.chunks().size() == 0) { fprintf(f, "v%d [ label=\"\" ];\n", single_idx_count); return stringf("v%d", single_idx_count++); } - if (sig.__chunks.size() == 1) { - RTLIL::SigChunk &c = sig.__chunks[0]; + if (sig.chunks().size() == 1) { + RTLIL::SigChunk &c = sig.chunks()[0]; if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) { if (!range_check || c.wire->width == c.width) return stringf("n%d", id2num(c.wire->name)); @@ -200,10 +200,10 @@ struct ShowWorker { std::string label_string; sig.optimize(); - int pos = sig.__width-1; + int pos = sig.size()-1; int idx = single_idx_count++; - for (int i = int(sig.__chunks.size())-1; i >= 0; i--) { - RTLIL::SigChunk &c = sig.__chunks[i]; + for (int i = int(sig.chunks().size())-1; i >= 0; i--) { + RTLIL::SigChunk &c = sig.chunks()[i]; net = gen_signode_simple(c, false); assert(!net.empty()); if (driver) { @@ -225,9 +225,9 @@ struct ShowWorker if (!port.empty()) { currentColor = xorshift32(currentColor); if (driver) - code += stringf("%s:e -> x%d:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", port.c_str(), idx, nextColor(sig).c_str(), widthLabel(sig.__width).c_str()); + code += stringf("%s:e -> x%d:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", port.c_str(), idx, nextColor(sig).c_str(), widthLabel(sig.size()).c_str()); else - code += stringf("x%d:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", idx, port.c_str(), nextColor(sig).c_str(), widthLabel(sig.__width).c_str()); + code += stringf("x%d:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", idx, port.c_str(), nextColor(sig).c_str(), widthLabel(sig.size()).c_str()); } if (node != NULL) *node = stringf("x%d", idx); @@ -239,7 +239,7 @@ struct ShowWorker net_conn_map[net].in.insert(port); else net_conn_map[net].out.insert(port); - net_conn_map[net].bits = sig.__width; + net_conn_map[net].bits = sig.size(); net_conn_map[net].color = nextColor(sig, net_conn_map[net].color); } if (node != NULL) @@ -405,7 +405,7 @@ struct ShowWorker code += gen_portbox("", sig, false, &node); fprintf(f, "%s", code.c_str()); net_conn_map[node].out.insert(stringf("p%d", pidx)); - net_conn_map[node].bits = sig.__width; + net_conn_map[node].bits = sig.size(); net_conn_map[node].color = nextColor(sig, net_conn_map[node].color); } @@ -414,7 +414,7 @@ struct ShowWorker code += gen_portbox("", sig, true, &node); fprintf(f, "%s", code.c_str()); net_conn_map[node].in.insert(stringf("p%d", pidx)); - net_conn_map[node].bits = sig.__width; + net_conn_map[node].bits = sig.size(); net_conn_map[node].color = nextColor(sig, net_conn_map[node].color); } @@ -427,12 +427,12 @@ struct ShowWorker for (auto &conn : module->connections) { bool found_lhs_wire = false; - for (auto &c : conn.first.__chunks) { + for (auto &c : conn.first.chunks()) { if (c.wire == NULL || design->selected_member(module->name, c.wire->name)) found_lhs_wire = true; } bool found_rhs_wire = false; - for (auto &c : conn.second.__chunks) { + for (auto &c : conn.second.chunks()) { if (c.wire == NULL || design->selected_member(module->name, c.wire->name)) found_rhs_wire = true; } @@ -446,11 +446,11 @@ struct ShowWorker if (left_node[0] == 'x' && right_node[0] == 'x') { currentColor = xorshift32(currentColor); - fprintf(f, "%s:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", left_node.c_str(), right_node.c_str(), nextColor(conn).c_str(), widthLabel(conn.first.__width).c_str()); + fprintf(f, "%s:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", left_node.c_str(), right_node.c_str(), nextColor(conn).c_str(), widthLabel(conn.first.size()).c_str()); } else { - net_conn_map[right_node].bits = conn.first.__width; + net_conn_map[right_node].bits = conn.first.size(); net_conn_map[right_node].color = nextColor(conn, net_conn_map[right_node].color); - net_conn_map[left_node].bits = conn.first.__width; + net_conn_map[left_node].bits = conn.first.size(); net_conn_map[left_node].color = nextColor(conn, net_conn_map[left_node].color); if (left_node[0] == 'x') { net_conn_map[right_node].in.insert(left_node); diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 80a7f90c..aed9c076 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -52,7 +52,7 @@ struct SpliceWorker RTLIL::SigSpec get_sliced_signal(RTLIL::SigSpec sig) { - if (sig.__width == 0 || sig.is_fully_const()) + if (sig.size() == 0 || sig.is_fully_const()) return sig; if (sliced_signals_cache.count(sig)) @@ -69,15 +69,15 @@ struct SpliceWorker RTLIL::SigSpec new_sig = sig; - if (sig_a.__width != sig.__width) { + if (sig_a.size() != sig.size()) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$slice"; cell->parameters["\\OFFSET"] = offset; - cell->parameters["\\A_WIDTH"] = sig_a.__width; - cell->parameters["\\Y_WIDTH"] = sig.__width; + cell->parameters["\\A_WIDTH"] = sig_a.size(); + cell->parameters["\\Y_WIDTH"] = sig.size(); cell->connections["\\A"] = sig_a; - cell->connections["\\Y"] = module->addWire(NEW_ID, sig.__width); + cell->connections["\\Y"] = module->addWire(NEW_ID, sig.size()); new_sig = cell->connections["\\Y"]; module->add(cell); } @@ -90,7 +90,7 @@ struct SpliceWorker RTLIL::SigSpec get_spliced_signal(RTLIL::SigSpec sig) { - if (sig.__width == 0 || sig.is_fully_const()) + if (sig.size() == 0 || sig.is_fully_const()) return sig; if (spliced_signals_cache.count(sig)) @@ -134,11 +134,11 @@ struct SpliceWorker RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$concat"; - cell->parameters["\\A_WIDTH"] = new_sig.__width; - cell->parameters["\\B_WIDTH"] = sig2.__width; + cell->parameters["\\A_WIDTH"] = new_sig.size(); + cell->parameters["\\B_WIDTH"] = sig2.size(); cell->connections["\\A"] = new_sig; cell->connections["\\B"] = sig2; - cell->connections["\\Y"] = module->addWire(NEW_ID, new_sig.__width + sig2.__width); + cell->connections["\\Y"] = module->addWire(NEW_ID, new_sig.size() + sig2.size()); new_sig = cell->connections["\\Y"]; module->add(cell); } diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 7572baa3..8cc6a515 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -63,7 +63,7 @@ struct SplitnetsWorker void operator()(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) if (splitmap.count(c.wire) > 0) c = splitmap.at(c.wire).at(c.offset); sig.optimize(); @@ -144,7 +144,7 @@ struct SplitnetsPass : public Pass { continue; RTLIL::SigSpec sig = p.second.optimized(); - for (auto &chunk : sig.__chunks) { + for (auto &chunk : sig.chunks()) { if (chunk.wire == NULL) continue; if (chunk.wire->port_id == 0 || flag_ports) { diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 523feae9..2ba4c72b 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -56,8 +56,8 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig RTLIL::SigSpec sig_b = assign_map(cellport.first->connections["\\B"]); if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) return false; - for (int i = 0; i < sig_b.__width; i += sig_a.__width) - if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.__width), recursion_monitor)) + for (int i = 0; i < sig_b.size(); i += sig_a.size()) + if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.size()), recursion_monitor)) return false; muxtree_cells.insert(cellport.first); } diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index e4d20077..0dd328db 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -43,7 +43,7 @@ struct FsmExpand bool is_cell_merge_candidate(RTLIL::Cell *cell) { if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") - if (cell->connections.at("\\A").__width < 2) + if (cell->connections.at("\\A").size() < 2) return true; RTLIL::SigSpec new_signals; @@ -62,7 +62,7 @@ struct FsmExpand new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_IN"])); new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_OUT"])); - if (new_signals.__width > 3) + if (new_signals.size() > 3) return false; if (cell->connections.count("\\Y") > 0) { @@ -73,7 +73,7 @@ struct FsmExpand new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_OUT"])); } - if (new_signals.__width > 2) + if (new_signals.size() > 2) return false; return true; @@ -145,8 +145,8 @@ struct FsmExpand std::vector truth_tab; - for (int i = 0; i < (1 << input_sig.__width); i++) { - RTLIL::Const in_val(i, input_sig.__width); + for (int i = 0; i < (1 << input_sig.size()); i++) { + RTLIL::Const in_val(i, input_sig.size()); RTLIL::SigSpec A, B, S; if (cell->connections.count("\\A") > 0) A = assign_map(cell->connections["\\A"]); @@ -166,17 +166,17 @@ struct FsmExpand FsmData fsm_data; fsm_data.copy_from_cell(fsm_cell); - fsm_data.num_inputs += input_sig.__width; + fsm_data.num_inputs += input_sig.size(); fsm_cell->connections["\\CTRL_IN"].append(input_sig); - fsm_data.num_outputs += output_sig.__width; + fsm_data.num_outputs += output_sig.size(); fsm_cell->connections["\\CTRL_OUT"].append(output_sig); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { - for (int i = 0; i < (1 << input_sig.__width); i++) { + for (int i = 0; i < (1 << input_sig.size()); i++) { FsmData::transition_t new_tr = tr; - RTLIL::Const in_val(i, input_sig.__width); + RTLIL::Const in_val(i, input_sig.size()); RTLIL::Const out_val = truth_tab[i]; RTLIL::SigSpec ctrl_in = new_tr.ctrl_in; RTLIL::SigSpec ctrl_out = new_tr.ctrl_out; diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index c0b5857f..701b09bd 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -36,7 +36,7 @@ static SigSet sig2driver, sig2trigger; static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL::SigSpec &ctrl, std::map &states, RTLIL::Const *reset_state = NULL) { - sig.extend(dff_out.__width, false); + sig.extend(dff_out.size(), false); if (sig == dff_out) return true; @@ -44,10 +44,10 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL assign_map.apply(sig); if (sig.is_fully_const()) { sig.optimize(); - assert(sig.__chunks.size() == 1); - if (states.count(sig.__chunks[0].data) == 0) { + assert(sig.chunks().size() == 1); + if (states.count(sig.chunks()[0].data) == 0) { log(" found state code: %s\n", log_signal(sig)); - states[sig.__chunks[0].data] = -1; + states[sig.chunks()[0].data] = -1; } return true; } @@ -73,14 +73,14 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL break; log(" found reset state: %s (guessed from mux tree)\n", log_signal(*reset_state)); } while (0); - if (ctrl.extract(sig_s).__width == 0) { + if (ctrl.extract(sig_s).size() == 0) { log(" found ctrl input: %s\n", log_signal(sig_s)); ctrl.append(sig_s); } if (!find_states(sig_a, dff_out, ctrl, states)) return false; - for (int i = 0; i < sig_b.__width/sig_a.__width; i++) { - if (!find_states(sig_b.extract(i*sig_a.__width, sig_a.__width), dff_out, ctrl, states)) + for (int i = 0; i < sig_b.size()/sig_a.size(); i++) { + if (!find_states(sig_b.extract(i*sig_a.size(), sig_a.size()), dff_out, ctrl, states)) return false; } } @@ -90,11 +90,11 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State noconst_state, RTLIL::SigSpec dont_care = RTLIL::SigSpec()) { - if (dont_care.__width > 0) { + if (dont_care.size() > 0) { sig.expand(); - for (auto &chunk : sig.__chunks) { + for (auto &chunk : sig.chunks()) { assert(chunk.width == 1); - if (dont_care.extract(chunk).__width > 0) + if (dont_care.extract(chunk).size() > 0) chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); } sig.optimize(); @@ -104,17 +104,17 @@ static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State no ce.values_map.apply(sig); sig.expand(); - for (auto &chunk : sig.__chunks) { + for (auto &chunk : sig.chunks()) { assert(chunk.width == 1); if (chunk.wire != NULL) chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); } sig.optimize(); - if (sig.__width == 0) + if (sig.size() == 0) return RTLIL::Const(); - assert(sig.__chunks.size() == 1 && sig.__chunks[0].wire == NULL); - return sig.__chunks[0].data; + assert(sig.chunks().size() == 1 && sig.chunks()[0].wire == NULL); + return sig.chunks()[0].data; } static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_data, std::map &states, int state_in, RTLIL::SigSpec ctrl_in, RTLIL::SigSpec ctrl_out, RTLIL::SigSpec dff_in, RTLIL::SigSpec dont_care) @@ -144,7 +144,7 @@ static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_d return; } - log_assert(undef.__width > 0); + log_assert(undef.size() > 0); log_assert(ce.stop_signals.check_all(undef)); undef = undef.extract(0, 1); @@ -258,8 +258,8 @@ static void extract_fsm(RTLIL::Wire *wire) // Initialize fsm data struct FsmData fsm_data; - fsm_data.num_inputs = ctrl_in.__width; - fsm_data.num_outputs = ctrl_out.__width; + fsm_data.num_inputs = ctrl_in.size(); + fsm_data.num_outputs = ctrl_out.size(); fsm_data.state_bits = wire->width; fsm_data.reset_state = -1; for (auto &it : states) { @@ -314,7 +314,7 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = new RTLIL::Wire; unconn_wire->name = stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++); - unconn_wire->width = unconn_sig.__width; + unconn_wire->width = unconn_sig.size(); module->wires[unconn_wire->name] = unconn_wire; port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections[cellport.second]); } @@ -367,7 +367,7 @@ struct FsmExtractPass : public Pass { sig2driver.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); } if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->connections.count("\\Y") > 0 && - cell_it.second->connections["\\Y"].__width == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { + cell_it.second->connections["\\Y"].size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); sig2trigger.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index f11d78b3..f8ffee52 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -50,12 +50,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 0) + if (eq_sig_a.size() > 0) { RTLIL::Wire *eq_wire = new RTLIL::Wire; eq_wire->name = NEW_ID; @@ -69,17 +69,17 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapconnections["\\Y"] = RTLIL::SigSpec(eq_wire); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); - eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.__width); - eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.__width); + eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size()); + eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(eq_cell); and_sig.append(RTLIL::SigSpec(eq_wire)); } - if (or_sig.__width < num_states-int(fullstate_cache.size())) + if (or_sig.size() < num_states-int(fullstate_cache.size())) { - if (or_sig.__width == 1) + if (or_sig.size() == 1) { and_sig.append(or_sig); } @@ -95,7 +95,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapconnections["\\A"] = or_sig; or_cell->connections["\\Y"] = RTLIL::SigSpec(or_wire); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); - or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.__width); + or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(or_cell); @@ -103,7 +103,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 1) { + if (cases_vector.size() > 1) { RTLIL::Cell *or_cell = new RTLIL::Cell; or_cell->name = NEW_ID; or_cell->type = "$reduce_or"; or_cell->connections["\\A"] = cases_vector; or_cell->connections["\\Y"] = output; or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); - or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.__width); + or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(or_cell); - } else if (cases_vector.__width == 1) { + } else if (cases_vector.size() == 1) { module->connections.push_back(RTLIL::SigSig(output, cases_vector)); } else { module->connections.push_back(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); @@ -237,8 +237,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) eq_cell->connections["\\Y"] = RTLIL::SigSpec(state_onehot, 1, i); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); - eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.__width); - eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.__width); + eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size()); + eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->add(eq_cell); } @@ -308,8 +308,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) mux_cell->connections["\\B"] = sig_b; mux_cell->connections["\\S"] = sig_s; mux_cell->connections["\\Y"] = RTLIL::SigSpec(next_state_wire); - mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.__width); - mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.__width); + mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); + mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); module->add(mux_cell); } diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 6732d2ab..367b38eb 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -33,11 +33,11 @@ struct FsmOpt bool signal_is_unused(RTLIL::SigSpec sig) { - assert(sig.__width == 1); + assert(sig.size() == 1); sig.optimize(); - RTLIL::Wire *wire = sig.__chunks[0].wire; - int bit = sig.__chunks[0].offset; + RTLIL::Wire *wire = sig.chunks()[0].wire; + int bit = sig.chunks()[0].offset; if (!wire || wire->attributes.count("\\unused_bits") == 0) return false; @@ -55,11 +55,11 @@ struct FsmOpt void opt_const_and_unused_inputs() { RTLIL::SigSpec ctrl_in = cell->connections["\\CTRL_IN"]; - std::vector ctrl_in_used(ctrl_in.__width); + std::vector ctrl_in_used(ctrl_in.size()); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { - for (int i = 0; i < ctrl_in.__width; i++) { + for (int i = 0; i < ctrl_in.size(); i++) { RTLIL::SigSpec ctrl_bit = ctrl_in.extract(i, 1); if (ctrl_bit.is_fully_const()) { if (tr.ctrl_in.bits[i] <= RTLIL::State::S1 && RTLIL::SigSpec(tr.ctrl_in.bits[i]) != ctrl_bit) @@ -112,8 +112,8 @@ struct FsmOpt { RTLIL::SigSpec &ctrl_in = cell->connections["\\CTRL_IN"]; - for (int i = 0; i < ctrl_in.__width; i++) - for (int j = i+1; j < ctrl_in.__width; j++) + for (int i = 0; i < ctrl_in.size(); i++) + for (int j = i+1; j < ctrl_in.size(); j++) if (ctrl_in.extract(i, 1) == ctrl_in.extract(j, 1)) { log(" Optimize handling of signal %s that is connected to inputs %d and %d.\n", log_signal(ctrl_in.extract(i, 1)), i, j); @@ -150,8 +150,8 @@ struct FsmOpt RTLIL::SigSpec &ctrl_in = cell->connections["\\CTRL_IN"]; RTLIL::SigSpec &ctrl_out = cell->connections["\\CTRL_OUT"]; - for (int j = 0; j < ctrl_out.__width; j++) - for (int i = 0; i < ctrl_in.__width; i++) + for (int j = 0; j < ctrl_out.size(); j++) + for (int i = 0; i < ctrl_in.size(); i++) if (ctrl_in.extract(i, 1) == ctrl_out.extract(j, 1)) { log(" Optimize handling of signal %s that is connected to input %d and output %d.\n", log_signal(ctrl_in.extract(i, 1)), i, j); diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index 6b175306..718b9704 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -143,15 +143,15 @@ struct FsmData log(" Input signals:\n"); RTLIL::SigSpec sig_in = cell->connections["\\CTRL_IN"]; sig_in.expand(); - for (size_t i = 0; i < sig_in.__chunks.size(); i++) - log(" %3zd: %s\n", i, log_signal(sig_in.__chunks[i])); + for (size_t i = 0; i < sig_in.chunks().size(); i++) + log(" %3zd: %s\n", i, log_signal(sig_in.chunks()[i])); log("\n"); log(" Output signals:\n"); RTLIL::SigSpec sig_out = cell->connections["\\CTRL_OUT"]; sig_out.expand(); - for (size_t i = 0; i < sig_out.__chunks.size(); i++) - log(" %3zd: %s\n", i, log_signal(sig_out.__chunks[i])); + for (size_t i = 0; i < sig_out.chunks().size(); i++) + log(" %3zd: %s\n", i, log_signal(sig_out.chunks()[i])); log("\n"); log(" State encoding:\n"); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 5d9dc18a..90f377e0 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -61,7 +61,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell for (auto &conn : i2.second->connections) { if (conn.first[0] != '$') portnames.insert(conn.first); - portwidths[conn.first] = std::max(portwidths[conn.first], conn.second.__width); + portwidths[conn.first] = std::max(portwidths[conn.first], conn.second.size()); } for (auto ¶ : i2.second->parameters) parameters.insert(para.first); @@ -220,7 +220,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla RTLIL::Module *mod = design->modules[cell->type]; for (auto &conn : cell->connections) { - int conn_size = conn.second.__width; + int conn_size = conn.second.size(); std::string portname = conn.first; if (portname.substr(0, 1) == "$") { int port_id = atoi(portname.substr(1).c_str()); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index f8f2b596..fa8043c8 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -67,7 +67,7 @@ struct SubmodWorker void flag_signal(RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) if (c.wire != NULL) flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used); } @@ -164,7 +164,7 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new RTLIL::Cell(*cell); for (auto &conn : new_cell->connections) - for (auto &c : conn.second.__chunks) + for (auto &c : conn.second.chunks()) if (c.wire != NULL) { assert(wire_flags.count(c.wire) > 0); c.wire = wire_flags[c.wire].new_wire; diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 6c9e1b77..5f06438f 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -142,16 +142,16 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) sig_wr_clk_enable.optimize(); sig_wr_clk_polarity.optimize(); - assert(sig_wr_clk.__width == wr_ports); - assert(sig_wr_clk_enable.__width == wr_ports && sig_wr_clk_enable.is_fully_const()); - assert(sig_wr_clk_polarity.__width == wr_ports && sig_wr_clk_polarity.is_fully_const()); - assert(sig_wr_addr.__width == wr_ports * addr_bits); - assert(sig_wr_data.__width == wr_ports * memory->width); - assert(sig_wr_en.__width == wr_ports * memory->width); + assert(sig_wr_clk.size() == wr_ports); + assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const()); + assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const()); + assert(sig_wr_addr.size() == wr_ports * addr_bits); + assert(sig_wr_data.size() == wr_ports * memory->width); + assert(sig_wr_en.size() == wr_ports * memory->width); mem->parameters["\\WR_PORTS"] = RTLIL::Const(wr_ports); - mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.__chunks[0].data : RTLIL::Const(0, 0); - mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.__chunks[0].data : RTLIL::Const(0, 0); + mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.chunks()[0].data : RTLIL::Const(0, 0); + mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.chunks()[0].data : RTLIL::Const(0, 0); mem->connections["\\WR_CLK"] = sig_wr_clk; mem->connections["\\WR_ADDR"] = sig_wr_addr; @@ -162,16 +162,16 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) sig_rd_clk_polarity.optimize(); sig_rd_transparent.optimize(); - assert(sig_rd_clk.__width == rd_ports); - assert(sig_rd_clk_enable.__width == rd_ports && sig_rd_clk_enable.is_fully_const()); - assert(sig_rd_clk_polarity.__width == rd_ports && sig_rd_clk_polarity.is_fully_const()); - assert(sig_rd_addr.__width == rd_ports * addr_bits); - assert(sig_rd_data.__width == rd_ports * memory->width); + assert(sig_rd_clk.size() == rd_ports); + assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); + assert(sig_rd_clk_polarity.size() == rd_ports && sig_rd_clk_polarity.is_fully_const()); + assert(sig_rd_addr.size() == rd_ports * addr_bits); + assert(sig_rd_data.size() == rd_ports * memory->width); mem->parameters["\\RD_PORTS"] = RTLIL::Const(rd_ports); - mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.__chunks[0].data : RTLIL::Const(0, 0); - mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.__chunks[0].data : RTLIL::Const(0, 0); - mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.__chunks[0].data : RTLIL::Const(0, 0); + mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.chunks()[0].data : RTLIL::Const(0, 0); + mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.chunks()[0].data : RTLIL::Const(0, 0); + mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.chunks()[0].data : RTLIL::Const(0, 0); mem->connections["\\RD_CLK"] = sig_rd_clk; mem->connections["\\RD_ADDR"] = sig_rd_addr; diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 174417bd..8bae24cf 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -34,9 +34,9 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI normalize_sig(module, sig); sig.expand(); - 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; @@ -59,11 +59,11 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI normalize_sig(module, q_norm); RTLIL::SigSpec d = q_norm.extract(chunk, &cell->connections[after ? "\\Q" : "\\D"]); - if (d.__width != 1) + if (d.size() != 1) continue; - assert(d.__chunks.size() == 1); - chunk = d.__chunks[0]; + assert(d.chunks().size() == 1); + chunk = d.chunks()[0]; clk = cell->connections["\\CLK"]; clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); goto replaced_this_bit; @@ -125,7 +125,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) RTLIL::Wire *wire = new RTLIL::Wire; wire->name = sstr.str(); - wire->width = sig.__width; + wire->width = sig.size(); module->wires[wire->name] = wire; RTLIL::SigSpec newsig(wire); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index b848e09e..e605e6e5 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -68,7 +68,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"]; RTLIL::SigSpec refclock; RTLIL::State refclock_pol = RTLIL::State::Sx; - for (int i = 0; i < clocks.__width; i++) { + for (int i = 0; i < clocks.size(); i++) { RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(i * mem_width, mem_width); if (wr_en.is_fully_const() && !wr_en.as_bool()) { static_ports.insert(i); @@ -89,7 +89,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) cell->name.c_str(), module->name.c_str(), i); return; } - if (refclock.__width == 0) { + if (refclock.size() == 0) { refclock = clocks.extract(i, 1); refclock_pol = clocks_pol.bits[i]; } @@ -277,12 +277,12 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->connections["\\Y"] = w_seladdr; int wr_offset = 0; - while (wr_offset < wr_en.__width) + while (wr_offset < wr_en.size()) { int wr_width = 1; RTLIL::SigSpec wr_bit = wr_en.extract(wr_offset, 1); - while (wr_offset + wr_width < wr_en.__width) { + while (wr_offset + wr_width < wr_en.size()) { RTLIL::SigSpec next_wr_bit = wr_en.extract(wr_offset + wr_width, 1); if (next_wr_bit != wr_bit) break; diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index e56d14b6..5c349f70 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -116,7 +116,7 @@ struct MemoryShareWorker created_conditions++; } - if (terms.__width > 1) + if (terms.size() > 1) terms = module->ReduceAnd(NEW_ID, terms); return conditions_logic_cache[conditions] = terms; @@ -254,7 +254,7 @@ struct MemoryShareWorker // this is the naive version of the function that does not care about grouping the EN bits. RTLIL::SigSpec inv_mask_bits = module->Not(NEW_ID, mask_bits); - RTLIL::SigSpec inv_mask_bits_filtered = module->Mux(NEW_ID, RTLIL::SigSpec(RTLIL::State::S1, bits.__width), inv_mask_bits, do_mask); + RTLIL::SigSpec inv_mask_bits_filtered = module->Mux(NEW_ID, RTLIL::SigSpec(RTLIL::State::S1, bits.size()), inv_mask_bits, do_mask); RTLIL::SigSpec result = module->And(NEW_ID, inv_mask_bits_filtered, bits); return result; } @@ -269,10 +269,10 @@ struct MemoryShareWorker std::map, std::pair>> groups; RTLIL::SigSpec grouped_bits, grouped_mask_bits; - for (int i = 0; i < bits.__width; i++) { + for (int i = 0; i < bits.size(); i++) { std::pair key(v_bits[i], v_mask_bits[i]); if (groups.count(key) == 0) { - groups[key].first = grouped_bits.__width; + groups[key].first = grouped_bits.size(); grouped_bits.append_bit(v_bits[i]); grouped_mask_bits.append_bit(v_mask_bits[i]); } @@ -282,7 +282,7 @@ struct MemoryShareWorker std::vector grouped_result = mask_en_naive(do_mask, grouped_bits, grouped_mask_bits); RTLIL::SigSpec result; - for (int i = 0; i < bits.__width; i++) { + for (int i = 0; i < bits.size(); i++) { std::pair key(v_bits[i], v_mask_bits[i]); result.append_bit(grouped_result.at(groups.at(key).first)); } @@ -320,7 +320,7 @@ struct MemoryShareWorker // Create the new merged_data signal. - RTLIL::SigSpec new_merged_data(RTLIL::State::Sx, merged_data.__width); + RTLIL::SigSpec new_merged_data(RTLIL::State::Sx, merged_data.size()); RTLIL::SigSpec old_data_set = module->And(NEW_ID, merged_en, merged_data); RTLIL::SigSpec old_data_unset = module->And(NEW_ID, merged_en, module->Not(NEW_ID, merged_data)); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 8a097916..68fb2e72 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -106,13 +106,13 @@ static int count_nontrivial_wire_attrs(RTLIL::Wire *w) static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2, SigPool ®s, SigPool &conns, std::set &direct_wires) { - assert(s1.__width == 1); - assert(s2.__width == 1); - assert(s1.__chunks.size() == 1); - assert(s2.__chunks.size() == 1); + assert(s1.size() == 1); + assert(s2.size() == 1); + assert(s1.chunks().size() == 1); + assert(s2.chunks().size() == 1); - RTLIL::Wire *w1 = s1.__chunks[0].wire; - RTLIL::Wire *w2 = s2.__chunks[0].wire; + RTLIL::Wire *w1 = s1.chunks()[0].wire; + RTLIL::Wire *w2 = s2.chunks()[0].wire; if (w1 == NULL || w2 == NULL) return w2 == NULL; @@ -235,14 +235,14 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } else { s1.expand(); s2.expand(); - assert(s1.__chunks.size() == s2.__chunks.size()); + assert(s1.chunks().size() == s2.chunks().size()); RTLIL::SigSig new_conn; - for (size_t i = 0; i < s1.__chunks.size(); i++) - if (s1.__chunks[i] != s2.__chunks[i]) { - new_conn.first.append(s1.__chunks[i]); - new_conn.second.append(s2.__chunks[i]); + for (size_t i = 0; i < s1.chunks().size(); i++) + if (s1.chunks()[i] != s2.chunks()[i]) { + new_conn.first.append(s1.chunks()[i]); + new_conn.second.append(s2.chunks()[i]); } - if (new_conn.first.__width > 0) { + if (new_conn.first.size() > 0) { new_conn.first.optimize(); new_conn.second.optimize(); used_signals.add(new_conn.first); @@ -258,8 +258,8 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (!used_signals_nodrivers.check_any(sig)) { std::string unused_bits; sig.expand(); - for (size_t i = 0; i < sig.__chunks.size(); i++) { - if (sig.__chunks[i].wire == NULL) + for (size_t i = 0; i < sig.chunks().size(); i++) { + if (sig.chunks()[i].wire == NULL) continue; if (!used_signals_nodrivers.check_any(sig)) { if (!unused_bits.empty()) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index bee86771..1a1f0fe4 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -56,13 +56,13 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) all_signals.del(driven_signals); RTLIL::SigSpec undriven_signals = all_signals.export_all(); - for (auto &c : undriven_signals.__chunks) + for (auto &c : undriven_signals.chunks()) { RTLIL::SigSpec sig = c; if (c.wire->name[0] == '$') sig = used_signals.extract(sig); - if (sig.__width == 0) + if (sig.size() == 0) continue; log("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c)); @@ -74,7 +74,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { RTLIL::SigSpec Y = cell->connections[out_port]; - out_val.extend_u0(Y.__width, false); + out_val.extend_u0(Y.size(), false); log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", cell->type.c_str(), cell->name.c_str(), info.c_str(), @@ -99,11 +99,11 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::SigSpec sig_y = sigmap(cell->connections.at("\\Y")); if (extend_u0) { - sig_a.extend_u0(sig_y.__width, a_signed); - sig_b.extend_u0(sig_y.__width, b_signed); + sig_a.extend_u0(sig_y.size(), a_signed); + sig_b.extend_u0(sig_y.size(), b_signed); } else { - sig_a.extend(sig_y.__width, a_signed); - sig_b.extend(sig_y.__width, b_signed); + sig_a.extend(sig_y.size(), a_signed); + sig_b.extend(sig_y.size(), b_signed); } std::vector bits_a = sig_a, bits_b = sig_b, bits_y = sig_y; @@ -153,7 +153,7 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com for (auto &it : grouped_bits[i]) { for (auto &bit : it.second) { new_conn.first.append_bit(bit); - new_conn.second.append_bit(RTLIL::SigBit(new_y, new_a.__width)); + new_conn.second.append_bit(RTLIL::SigBit(new_y, new_a.size())); } new_a.append_bit(it.first.first); new_b.append_bit(it.first.second); @@ -162,12 +162,12 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); c->connections["\\A"] = new_a; - c->parameters["\\A_WIDTH"] = new_a.__width; + c->parameters["\\A_WIDTH"] = new_a.size(); c->parameters["\\A_SIGNED"] = false; if (b_name == "\\B") { c->connections["\\B"] = new_b; - c->parameters["\\B_WIDTH"] = new_b.__width; + c->parameters["\\B_WIDTH"] = new_b.size(); c->parameters["\\B_SIGNED"] = false; } @@ -202,7 +202,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (auto &cell_it : module->cells) if (design->selected(module, cell_it.second)) { if ((cell_it.second->type == "$_INV_" || cell_it.second->type == "$not" || cell_it.second->type == "$logic_not") && - cell_it.second->connections["\\A"].__width == 1 && cell_it.second->connections["\\Y"].__width == 1) + cell_it.second->connections["\\A"].size() == 1 && cell_it.second->connections["\\Y"].size() == 1) invert_map[assign_map(cell_it.second->connections["\\Y"])] = assign_map(cell_it.second->connections["\\A"]); cells.push_back(cell_it.second); } @@ -334,12 +334,12 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); else - replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections.at("\\Y").__width)); + replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections.at("\\Y").size())); goto next_cell; } } - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].__width == 1 && + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].size() == 1 && invert_map.count(assign_map(cell->connections["\\A"])) != 0) { replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections["\\A"]))); goto next_cell; @@ -460,35 +460,35 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec new_a, new_b; a.expand(), b.expand(); - assert(a.__chunks.size() == b.__chunks.size()); - for (size_t i = 0; i < a.__chunks.size(); i++) { - if (a.__chunks[i].wire == NULL && b.__chunks[i].wire == NULL && a.__chunks[i].data.bits[0] != b.__chunks[i].data.bits[0] && - a.__chunks[i].data.bits[0] <= RTLIL::State::S1 && b.__chunks[i].data.bits[0] <= RTLIL::State::S1) { + assert(a.chunks().size() == b.chunks().size()); + for (size_t i = 0; i < a.chunks().size(); i++) { + if (a.chunks()[i].wire == NULL && b.chunks()[i].wire == NULL && a.chunks()[i].data.bits[0] != b.chunks()[i].data.bits[0] && + a.chunks()[i].data.bits[0] <= RTLIL::State::S1 && b.chunks()[i].data.bits[0] <= RTLIL::State::S1) { RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S0 : RTLIL::State::S1); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(module, cell, "empty", "\\Y", new_y); goto next_cell; } - if (a.__chunks[i] == b.__chunks[i]) + if (a.chunks()[i] == b.chunks()[i]) continue; - new_a.append(a.__chunks[i]); - new_b.append(b.__chunks[i]); + new_a.append(a.chunks()[i]); + new_b.append(b.chunks()[i]); } - if (new_a.__width == 0) { + if (new_a.size() == 0) { RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S1 : RTLIL::State::S0); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(module, cell, "empty", "\\Y", new_y); goto next_cell; } - if (new_a.__width < a.__width || new_b.__width < b.__width) { + if (new_a.size() < a.size() || new_b.size() < b.size()) { new_a.optimize(); new_b.optimize(); cell->connections["\\A"] = new_a; cell->connections["\\B"] = new_b; - cell->parameters["\\A_WIDTH"] = new_a.__width; - cell->parameters["\\B_WIDTH"] = new_b.__width; + cell->parameters["\\A_WIDTH"] = new_a.size(); + cell->parameters["\\B_WIDTH"] = new_b.size(); } } @@ -550,10 +550,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec a = assign_map(cell->connections["\\A"]); RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); - if (a.is_fully_const() && a.__width <= 32 && a.as_int() == 1) + if (a.is_fully_const() && a.size() <= 32 && a.as_int() == 1) identity_wrt_b = true; - if (b.is_fully_const() && b.__width <= 32 && b.as_int() == 1) + if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) identity_wrt_a = true; } @@ -561,7 +561,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo { RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); - if (b.is_fully_const() && b.__width <= 32 && b.as_int() == 1) + if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) identity_wrt_a = true; } @@ -650,13 +650,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->connections.at("\\A").__width; + int width = cell->connections.at("\\A").size(); if ((cell->connections.at("\\A").is_fully_undef() && cell->connections.at("\\B").is_fully_undef()) || cell->connections.at("\\S").is_fully_undef()) { replace_cell(module, cell, "mux undef", "\\Y", cell->connections.at("\\A")); goto next_cell; } - for (int i = 0; i < cell->connections.at("\\S").__width; i++) { + for (int i = 0; i < cell->connections.at("\\S").size(); i++) { RTLIL::SigSpec old_b = cell->connections.at("\\B").extract(i*width, width); RTLIL::SigSpec old_s = cell->connections.at("\\S").extract(i, 1); if (old_b.is_fully_undef() || old_s.is_fully_undef()) @@ -665,12 +665,12 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo new_s.append(old_s); } new_a = cell->connections.at("\\A"); - if (new_a.is_fully_undef() && new_s.__width > 0) { - new_a = new_b.extract((new_s.__width-1)*width, width); - new_b = new_b.extract(0, (new_s.__width-1)*width); - new_s = new_s.extract(0, new_s.__width-1); + if (new_a.is_fully_undef() && new_s.size() > 0) { + new_a = new_b.extract((new_s.size()-1)*width, width); + new_b = new_b.extract(0, (new_s.size()-1)*width); + new_s = new_s.extract(0, new_s.size()-1); } - if (new_s.__width == 0) { + if (new_s.size() == 0) { replace_cell(module, cell, "mux undef", "\\Y", new_a); goto next_cell; } @@ -678,13 +678,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo replace_cell(module, cell, "mux undef", "\\Y", new_s); goto next_cell; } - if (cell->connections.at("\\S").__width != new_s.__width) { + if (cell->connections.at("\\S").size() != new_s.size()) { cell->connections.at("\\A") = new_a; cell->connections.at("\\B") = new_b; cell->connections.at("\\S") = new_s; - if (new_s.__width > 1) { + if (new_s.size() > 1) { cell->type = "$pmux"; - cell->parameters["\\S_WIDTH"] = new_s.__width; + cell->parameters["\\S_WIDTH"] = new_s.size(); } else { cell->type = "$mux"; cell->parameters.erase("\\S_WIDTH"); @@ -700,9 +700,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo assign_map.apply(a); \ if (a.is_fully_const()) { \ a.optimize(); \ - if (a.__chunks.empty()) a.__chunks.push_back(RTLIL::SigChunk()); \ + if (a.chunks().empty()) a.chunks().push_back(RTLIL::SigChunk()); \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ - RTLIL::SigSpec y(RTLIL::const_ ## _t(a.__chunks[0].data, dummy_arg, \ + RTLIL::SigSpec y(RTLIL::const_ ## _t(a.chunks()[0].data, dummy_arg, \ cell->parameters["\\A_SIGNED"].as_bool(), false, \ cell->parameters["\\Y_WIDTH"].as_int())); \ replace_cell(module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ @@ -716,9 +716,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ a.optimize(), b.optimize(); \ - if (a.__chunks.empty()) a.__chunks.push_back(RTLIL::SigChunk()); \ - if (b.__chunks.empty()) b.__chunks.push_back(RTLIL::SigChunk()); \ - RTLIL::SigSpec y(RTLIL::const_ ## _t(a.__chunks[0].data, b.__chunks[0].data, \ + if (a.chunks().empty()) a.chunks().push_back(RTLIL::SigChunk()); \ + if (b.chunks().empty()) b.chunks().push_back(RTLIL::SigChunk()); \ + RTLIL::SigSpec y(RTLIL::const_ ## _t(a.chunks()[0].data, b.chunks()[0].data, \ cell->parameters["\\A_SIGNED"].as_bool(), \ cell->parameters["\\B_SIGNED"].as_bool(), \ cell->parameters["\\Y_WIDTH"].as_int())); \ @@ -787,10 +787,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec sig_b = assign_map(cell->connections["\\B"]); RTLIL::SigSpec sig_y = assign_map(cell->connections["\\Y"]); - if (sig_b.is_fully_const() && sig_b.__width <= 32) + if (sig_b.is_fully_const() && sig_b.size() <= 32) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; - if (sig_a.is_fully_def() && sig_a.__width <= 32) + if (sig_a.is_fully_def() && sig_a.size() <= 32) { int a_val = sig_a.as_int(); @@ -799,7 +799,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo log("Replacing multiply-by-zero cell `%s' in module `%s' with zero-driver.\n", cell->name.c_str(), module->name.c_str()); - module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); + module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); module->remove(cell); OPT_DID_SOMETHING = true; @@ -807,7 +807,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - for (int i = 1; i < (a_signed ? sig_a.__width-1 : sig_a.__width); i++) + for (int i = 1; i < (a_signed ? sig_a.size()-1 : sig_a.size()); i++) if (a_val == (1 << i)) { log("Replacing multiply-by-%d cell `%s' in module `%s' with shift-by-%d.\n", diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index e844a420..61147f67 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -92,8 +92,8 @@ struct OptMuxtreeWorker muxinfo_t muxinfo; muxinfo.cell = cell; - for (int i = 0; i < sig_s.__width; i++) { - RTLIL::SigSpec sig = sig_b.extract(i*sig_a.__width, sig_a.__width); + for (int i = 0; i < sig_s.size(); i++) { + RTLIL::SigSpec sig = sig_b.extract(i*sig_a.size(), sig_a.size()); RTLIL::SigSpec ctrl_sig = assign_map(sig_s.extract(i, 1)); portinfo_t portinfo; for (int idx : sig2bits(sig)) { @@ -201,7 +201,7 @@ struct OptMuxtreeWorker if (live_ports.size() == 1) { - RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.__width, sig_a.__width); + RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.size(), sig_a.size()); module->connections.push_back(RTLIL::SigSig(sig_y, sig_in)); module->cells.erase(mi.cell->name); delete mi.cell; @@ -211,7 +211,7 @@ struct OptMuxtreeWorker RTLIL::SigSpec new_sig_a, new_sig_b, new_sig_s; for (size_t i = 0; i < live_ports.size(); i++) { - RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[i]*sig_a.__width, sig_a.__width); + RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[i]*sig_a.size(), sig_a.size()); if (i == live_ports.size()-1) { new_sig_a = sig_in; } else { @@ -223,11 +223,11 @@ struct OptMuxtreeWorker mi.cell->connections["\\A"] = new_sig_a; mi.cell->connections["\\B"] = new_sig_b; mi.cell->connections["\\S"] = new_sig_s; - if (new_sig_s.__width == 1) { + if (new_sig_s.size() == 1) { mi.cell->type = "$mux"; mi.cell->parameters.erase("\\S_WIDTH"); } else { - mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.__width); + mi.cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); } } } @@ -260,7 +260,7 @@ struct OptMuxtreeWorker std::vector results; assign_map.apply(sig); sig.expand(); - for (auto &c : sig.__chunks) + for (auto &c : sig.chunks()) if (c.wire != NULL) { bitDef_t bit(c.wire, c.offset); if (bit2num.count(bit) == 0) { diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 4f1176d9..7ab7233c 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -48,7 +48,7 @@ struct OptReduceWorker sig_a.expand(); RTLIL::SigSpec new_sig_a; - for (auto &chunk : sig_a.__chunks) + for (auto &chunk : sig_a.chunks()) { if (chunk.wire == NULL && chunk.data.bits[0] == RTLIL::State::S0) { if (cell->type == "$reduce_and") { @@ -85,7 +85,7 @@ struct OptReduceWorker } new_sig_a.sort_and_unify(); - if (new_sig_a != sig_a || sig_a.__width != cell->connections["\\A"].__width) { + if (new_sig_a != sig_a || sig_a.size() != cell->connections["\\A"].size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; OPT_DID_SOMETHING = true; @@ -93,7 +93,7 @@ struct OptReduceWorker } cell->connections["\\A"] = new_sig_a; - cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.size()); return; } @@ -107,20 +107,20 @@ struct OptReduceWorker std::set handled_sig; handled_sig.insert(sig_a); - for (int i = 0; i < sig_s.__width; i++) + for (int i = 0; i < sig_s.size(); i++) { - RTLIL::SigSpec this_b = sig_b.extract(i*sig_a.__width, sig_a.__width); + RTLIL::SigSpec this_b = sig_b.extract(i*sig_a.size(), sig_a.size()); if (handled_sig.count(this_b) > 0) continue; RTLIL::SigSpec this_s = sig_s.extract(i, 1); - for (int j = i+1; j < sig_s.__width; j++) { - RTLIL::SigSpec that_b = sig_b.extract(j*sig_a.__width, sig_a.__width); + for (int j = i+1; j < sig_s.size(); j++) { + RTLIL::SigSpec that_b = sig_b.extract(j*sig_a.size(), sig_a.size()); if (this_b == that_b) this_s.append(sig_s.extract(j, 1)); } - if (this_s.__width > 1) + if (this_s.size() > 1) { RTLIL::Wire *reduce_or_wire = new RTLIL::Wire; reduce_or_wire->name = NEW_ID; @@ -131,7 +131,7 @@ struct OptReduceWorker reduce_or_cell->type = "$reduce_or"; reduce_or_cell->connections["\\A"] = this_s; reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.__width); + reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size()); reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); module->cells[reduce_or_cell->name] = reduce_or_cell; @@ -144,14 +144,14 @@ struct OptReduceWorker handled_sig.insert(this_b); } - if (new_sig_s.__width != sig_s.__width) { + if (new_sig_s.size() != sig_s.size()) { log(" New ctrl vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_s)); did_something = true; OPT_DID_SOMETHING = true; total_count++; } - if (new_sig_s.__width == 0) + if (new_sig_s.size() == 0) { module->connections.push_back(RTLIL::SigSig(cell->connections["\\Y"], cell->connections["\\A"])); assign_map.add(cell->connections["\\Y"], cell->connections["\\A"]); @@ -162,8 +162,8 @@ struct OptReduceWorker { cell->connections["\\B"] = new_sig_b; cell->connections["\\S"] = new_sig_s; - if (new_sig_s.__width > 1) { - cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.__width); + if (new_sig_s.size() > 1) { + cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); } else { cell->type = "$mux"; cell->parameters.erase("\\S_WIDTH"); @@ -224,7 +224,7 @@ struct OptReduceWorker cell->connections["\\A"].append(in_tuple.at(0)); cell->connections["\\B"] = RTLIL::SigSpec(); - for (int i = 1; i <= cell->connections["\\S"].__width; i++) + for (int i = 1; i <= cell->connections["\\S"].size(); i++) for (auto &in_tuple : consolidated_in_tuples) cell->connections["\\B"].append(in_tuple.at(i)); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 879f7ddc..4215a7b5 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -100,7 +100,7 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) } } - if (sig_c.is_fully_const() && (!sig_r.__width || !has_init)) { + if (sig_c.is_fully_const() && (!sig_r.size() || !has_init)) { if (val_rv.bits.size() == 0) val_rv = val_init; RTLIL::SigSig conn(sig_q, val_rv); @@ -108,26 +108,26 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) goto delete_dff; } - if (sig_d.is_fully_undef() && sig_r.__width && !has_init) { + if (sig_d.is_fully_undef() && sig_r.size() && !has_init) { RTLIL::SigSig conn(sig_q, val_rv); mod->connections.push_back(conn); goto delete_dff; } - if (sig_d.is_fully_undef() && !sig_r.__width && has_init) { + if (sig_d.is_fully_undef() && !sig_r.size() && has_init) { RTLIL::SigSig conn(sig_q, val_init); mod->connections.push_back(conn); goto delete_dff; } - if (sig_d.is_fully_const() && !sig_r.__width && !has_init) { + if (sig_d.is_fully_const() && !sig_r.size() && !has_init) { RTLIL::SigSig conn(sig_q, sig_d); mod->connections.push_back(conn); goto delete_dff; } - if (sig_d == sig_q && !(sig_r.__width && has_init)) { - if (sig_r.__width) { + if (sig_d == sig_q && !(sig_r.size() && has_init)) { + if (sig_r.size()) { RTLIL::SigSig conn(sig_q, val_rv); mod->connections.push_back(conn); } @@ -182,7 +182,7 @@ struct OptRmdffPass : public Pass { std::vector dff_list; for (auto &it : mod_it.second->cells) { if (it.second->type == "$mux" || it.second->type == "$pmux") { - if (it.second->connections.at("\\A").__width == it.second->connections.at("\\B").__width) + if (it.second->connections.at("\\A").size() == it.second->connections.at("\\B").size()) mux_drivers.insert(assign_map(it.second->connections.at("\\Y")), it.second); continue; } diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 07e512cb..819a0e46 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -97,7 +97,7 @@ struct OptShareWorker RTLIL::SigSpec sig = it.second; assign_map.apply(sig); hash_string += "C " + it.first + "="; - for (auto &chunk : sig.__chunks) { + for (auto &chunk : sig.chunks()) { if (chunk.wire) hash_string += "{" + chunk.wire->name + " " + int_to_hash_string(chunk.offset) + " " + diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index a773e5e7..b5763508 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -28,7 +28,7 @@ extern void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity) { - if (signal.__width != 1) + if (signal.size() != 1) return false; if (signal == ref) return true; @@ -80,13 +80,13 @@ static void apply_const(RTLIL::Module *mod, const RTLIL::SigSpec rspec, RTLIL::S { for (auto &action : cs->actions) { if (unknown) - rspec.replace(action.first, RTLIL::SigSpec(RTLIL::State::Sm, action.second.__width), &rval); + rspec.replace(action.first, RTLIL::SigSpec(RTLIL::State::Sm, action.second.size()), &rval); else rspec.replace(action.first, action.second, &rval); } for (auto sw : cs->switches) { - if (sw->signal.__width == 0) { + if (sw->signal.size() == 0) { for (auto cs2 : sw->cases) apply_const(mod, rspec, rval, cs2, const_sig, polarity, unknown); } @@ -164,11 +164,11 @@ restart_proc_arst: } for (auto &action : sync->actions) { RTLIL::SigSpec rspec = action.second; - RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.__width); + RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.size()); rspec.expand(), rval.expand(); - for (int i = 0; i < int(rspec.__chunks.size()); i++) - if (rspec.__chunks[i].wire == NULL) - rval.__chunks[i] = rspec.__chunks[i]; + for (int i = 0; i < int(rspec.chunks().size()); i++) + if (rspec.chunks()[i].wire == NULL) + rval.chunks()[i] = rspec.chunks()[i]; rspec.optimize(), rval.optimize(); RTLIL::SigSpec last_rval; for (int count = 0; rval != last_rval; count++) { @@ -252,14 +252,14 @@ struct ProcArstPass : public Pass { if (sync->type == RTLIL::SyncType::STp || sync->type == RTLIL::SyncType::STn) for (auto &act : sync->actions) { RTLIL::SigSpec arst_sig, arst_val; - for (auto &chunk : act.first.__chunks) + for (auto &chunk : act.first.chunks()) if (chunk.wire && chunk.wire->attributes.count("\\init")) { RTLIL::SigSpec value = chunk.wire->attributes.at("\\init"); value.extend(chunk.wire->width, false); arst_sig.append(chunk); arst_val.append(value.extract(chunk.offset, chunk.width)); } - if (arst_sig.__width) { + if (arst_sig.size()) { log("Added global reset to process %s: %s <- %s\n", proc_it.first.c_str(), log_signal(arst_sig), log_signal(arst_val)); arst_actions.push_back(RTLIL::SigSig(arst_sig, arst_val)); diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 76866068..682515c5 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -27,7 +27,7 @@ extern void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth) { - if (sw->signal.__width > 0 && sw->signal.is_fully_const()) + if (sw->signal.size() > 0 && sw->signal.is_fully_const()) { int found_matching_case_idx = -1; for (int i = 0; i < int(sw->cases.size()) && found_matching_case_idx < 0; i++) @@ -59,7 +59,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did sw->signal = RTLIL::SigSpec(); } - if (sw->cases.size() == 1 && (sw->signal.__width == 0 || sw->cases[0]->compare.empty())) + if (sw->cases.size() == 1 && (sw->signal.size() == 0 || sw->cases[0]->compare.empty())) { did_something = true; for (auto &action : sw->cases[0]->actions) @@ -91,7 +91,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth) { for (size_t i = 0; i < cs->actions.size(); i++) { - if (cs->actions[i].first.__width == 0) { + if (cs->actions[i].first.size() == 0) { did_something = true; cs->actions.erase(cs->actions.begin() + (i--)); } @@ -114,7 +114,7 @@ static void proc_clean(RTLIL::Module *mod, RTLIL::Process *proc, int &total_coun bool did_something = true; for (size_t i = 0; i < proc->syncs.size(); i++) { for (size_t j = 0; j < proc->syncs[i]->actions.size(); j++) - if (proc->syncs[i]->actions[j].first.__width == 0) + if (proc->syncs[i]->actions[j].first.size() == 0) proc->syncs[i]->actions.erase(proc->syncs[i]->actions.begin() + (j--)); if (proc->syncs[i]->actions.size() == 0) { delete proc->syncs[i]; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index d3dff8ef..8e5fbe8f 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -32,7 +32,7 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) for (auto sync : proc->syncs) for (auto &action : sync->actions) - if (action.first.__width > 0) { + if (action.first.size() > 0) { lvalue = action.first; lvalue.sort_and_unify(); break; @@ -44,7 +44,7 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) this_lvalue.append(action.first); this_lvalue.sort_and_unify(); RTLIL::SigSpec common_sig = this_lvalue.extract(lvalue); - if (common_sig.__width > 0) + if (common_sig.size() > 0) lvalue = common_sig; } @@ -54,8 +54,8 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::SigSpec clk, bool clk_polarity, std::map> &async_rules, RTLIL::Process *proc) { - RTLIL::SigSpec sig_sr_set = RTLIL::SigSpec(0, sig_d.__width); - RTLIL::SigSpec sig_sr_clr = RTLIL::SigSpec(0, sig_d.__width); + RTLIL::SigSpec sig_sr_set = RTLIL::SigSpec(0, sig_d.size()); + RTLIL::SigSpec sig_sr_clr = RTLIL::SigSpec(0, sig_d.size()); for (auto &it : async_rules) { @@ -72,24 +72,24 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S else log_abort(); - if (sync_low_signals.__width > 1) { + if (sync_low_signals.size() > 1) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$reduce_or"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; cell->connections["\\Y"] = sync_low_signals = mod->addWire(NEW_ID); mod->add(cell); } - if (sync_low_signals.__width > 0) { + if (sync_low_signals.size() > 0) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$not"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; cell->connections["\\Y"] = mod->addWire(NEW_ID); @@ -97,12 +97,12 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S mod->add(cell); } - if (sync_high_signals.__width > 1) { + if (sync_high_signals.size() > 1) { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$reduce_or"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_high_signals; cell->connections["\\Y"] = sync_high_signals = mod->addWire(NEW_ID); @@ -113,30 +113,30 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S inv_cell->name = NEW_ID; inv_cell->type = "$not"; inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); - inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.__width); - inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.__width); + inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size()); + inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size()); inv_cell->connections["\\A"] = sync_value; - inv_cell->connections["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.__width); + inv_cell->connections["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.size()); mod->add(inv_cell); RTLIL::Cell *mux_set_cell = new RTLIL::Cell; mux_set_cell->name = NEW_ID; mux_set_cell->type = "$mux"; - mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.__width); + mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); mux_set_cell->connections["\\A"] = sig_sr_set; mux_set_cell->connections["\\B"] = sync_value; mux_set_cell->connections["\\S"] = sync_high_signals; - mux_set_cell->connections["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.__width); + mux_set_cell->connections["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.size()); mod->add(mux_set_cell); RTLIL::Cell *mux_clr_cell = new RTLIL::Cell; mux_clr_cell->name = NEW_ID; mux_clr_cell->type = "$mux"; - mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.__width); + mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); mux_clr_cell->connections["\\A"] = sig_sr_clr; mux_clr_cell->connections["\\B"] = sync_value_inv; mux_clr_cell->connections["\\S"] = sync_high_signals; - mux_clr_cell->connections["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.__width); + mux_clr_cell->connections["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()); mod->add(mux_clr_cell); } @@ -147,7 +147,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->name = sstr.str(); cell->type = "$dffsr"; cell->attributes = proc->attributes; - cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.__width); + cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); @@ -168,16 +168,16 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec std::stringstream sstr; sstr << "$procdff$" << (RTLIL::autoidx++); - RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.__width); - RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.__width); - RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.__width); + RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.size()); + RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size()); + RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.size()); RTLIL::Cell *inv_set = new RTLIL::Cell; inv_set->name = NEW_ID; inv_set->type = "$not"; inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0); - inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.__width); - inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.__width); + inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size()); + inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size()); inv_set->connections["\\A"] = sig_set; inv_set->connections["\\Y"] = sig_set_inv; mod->add(inv_set); @@ -185,8 +185,8 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec RTLIL::Cell *mux_sr_set = new RTLIL::Cell; mux_sr_set->name = NEW_ID; mux_sr_set->type = "$mux"; - mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); - mux_sr_set->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.__width); + mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); + mux_sr_set->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); mux_sr_set->connections[set_polarity ? "\\B" : "\\A"] = sig_set; mux_sr_set->connections["\\Y"] = sig_sr_set; mux_sr_set->connections["\\S"] = set; @@ -195,8 +195,8 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec RTLIL::Cell *mux_sr_clr = new RTLIL::Cell; mux_sr_clr->name = NEW_ID; mux_sr_clr->type = "$mux"; - mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); - mux_sr_clr->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.__width); + mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); + mux_sr_clr->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); mux_sr_clr->connections[set_polarity ? "\\B" : "\\A"] = sig_set_inv; mux_sr_clr->connections["\\Y"] = sig_sr_clr; mux_sr_clr->connections["\\S"] = set; @@ -206,7 +206,7 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec cell->name = sstr.str(); cell->type = "$dffsr"; cell->attributes = proc->attributes; - cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); + cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); @@ -233,7 +233,7 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ cell->attributes = proc->attributes; mod->cells[cell->name] = cell; - cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.__width); + cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); if (arst) { cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity, 1); cell->parameters["\\ARST_VALUE"] = val_rst; @@ -259,14 +259,14 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) RTLIL::SigSpec sig = find_any_lvalue(proc); bool free_sync_level = false; - if (sig.__width == 0) + if (sig.size() == 0) break; log("Creating register for signal `%s.%s' using process `%s.%s'.\n", mod->name.c_str(), log_signal(sig), mod->name.c_str(), proc->name.c_str()); - RTLIL::SigSpec insig = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); - RTLIL::SigSpec rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); + RTLIL::SigSpec insig = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); + RTLIL::SigSpec rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); RTLIL::SyncRule *sync_level = NULL; RTLIL::SyncRule *sync_edge = NULL; RTLIL::SyncRule *sync_always = NULL; @@ -276,16 +276,16 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) for (auto sync : proc->syncs) for (auto &action : sync->actions) { - if (action.first.extract(sig).__width == 0) + if (action.first.extract(sig).size() == 0) continue; if (sync->type == RTLIL::SyncType::ST0 || sync->type == RTLIL::SyncType::ST1) { if (sync_level != NULL && sync_level != sync) { // log_error("Multiple level sensitive events found for this signal!\n"); many_async_rules[rstval].insert(sync_level); - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); } - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); sig.replace(action.first, action.second, &rstval); sync_level = sync; } @@ -324,15 +324,15 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) inputs.append(it->signal); compare.append(it->type == RTLIL::SyncType::ST0 ? RTLIL::State::S1 : RTLIL::State::S0); } - assert(inputs.__width == compare.__width); + assert(inputs.size() == compare.size()); RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$ne"; cell->parameters["\\A_SIGNED"] = RTLIL::Const(false, 1); cell->parameters["\\B_SIGNED"] = RTLIL::Const(false, 1); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.__width); - cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size()); + cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = inputs; cell->connections["\\B"] = compare; @@ -343,7 +343,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) } else { - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); sync_level = NULL; } } @@ -357,7 +357,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) sig.optimize(); if (rstval == sig) { - rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.__width); + rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); sync_level = NULL; } @@ -386,7 +386,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) sync_edge->signal, sync_level->signal, proc); } else - gen_dff(mod, insig, rstval.__chunks[0].data, sig, + gen_dff(mod, insig, rstval.chunks()[0].data, sig, sync_edge->type == RTLIL::SyncType::STp, sync_level && sync_level->type == RTLIL::SyncType::ST1, sync_edge->signal, sync_level ? &sync_level->signal : NULL, proc); diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index 0ef17b22..ba1fb5ab 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -60,13 +60,13 @@ static void proc_init(RTLIL::Module *mod, RTLIL::Process *proc) log_cmd_error("Failed to get a constant init value for %s: %s\n", log_signal(lhs), log_signal(rhs)); int offset = 0; - for (size_t i = 0; i < lhs.__chunks.size(); i++) { - if (lhs.__chunks[i].wire == NULL) + for (size_t i = 0; i < lhs.chunks().size(); i++) { + if (lhs.chunks()[i].wire == NULL) continue; - RTLIL::Wire *wire = lhs.__chunks[i].wire; - RTLIL::SigSpec value = rhs.extract(offset, lhs.__chunks[i].width); - if (value.__width != wire->width) - log_cmd_error("Init value is not for the entire wire: %s = %s\n", log_signal(lhs.__chunks[i]), log_signal(value)); + RTLIL::Wire *wire = lhs.chunks()[i].wire; + RTLIL::SigSpec value = rhs.extract(offset, lhs.chunks()[i].width); + if (value.size() != wire->width) + log_cmd_error("Init value is not for the entire wire: %s = %s\n", log_signal(lhs.chunks()[i]), log_signal(value)); log(" Setting init value: %s = %s\n", log_signal(wire), log_signal(value)); wire->attributes["\\init"] = value.as_const(); offset += wire->width; diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 2e24e786..cd459d94 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -28,14 +28,14 @@ static RTLIL::SigSpec find_any_lvalue(const RTLIL::CaseRule *cs) { for (auto &action : cs->actions) { - if (action.first.__width) + if (action.first.size()) return action.first; } for (auto sw : cs->switches) for (auto cs2 : sw->cases) { RTLIL::SigSpec sig = find_any_lvalue(cs2); - if (sig.__width) + if (sig.size()) return sig; } @@ -46,7 +46,7 @@ static void extract_core_signal(const RTLIL::CaseRule *cs, RTLIL::SigSpec &sig) { for (auto &action : cs->actions) { RTLIL::SigSpec lvalue = action.first.extract(sig); - if (lvalue.__width) + if (lvalue.size()) sig = lvalue; } @@ -72,18 +72,18 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, comp.expand(); // get rid of don't-care bits - assert(sig.__width == comp.__width); - for (int i = 0; i < comp.__width; i++) - if (comp.__chunks[i].wire == NULL && comp.__chunks[i].data.bits[0] == RTLIL::State::Sa) { + assert(sig.size() == comp.size()); + for (int i = 0; i < comp.size(); i++) + if (comp.chunks()[i].wire == NULL && comp.chunks()[i].data.bits[0] == RTLIL::State::Sa) { sig.remove(i, 1); comp.remove(i--, 1); } - if (comp.__width == 0) + if (comp.size() == 0) return RTLIL::SigSpec(); sig.optimize(); comp.optimize(); - if (sig.__width == 1 && comp == RTLIL::SigSpec(1,1)) + if (sig.size() == 1 && comp == RTLIL::SigSpec(1,1)) { mod->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, 1, cmp_wire->width++), sig)); } @@ -101,8 +101,8 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0); - eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.__width); - eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.__width); + eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); + eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); eq_cell->connections["\\A"] = sig; @@ -143,7 +143,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::SigSpec else_signal, RTLIL::Cell *&last_mux_cell, RTLIL::SwitchRule *sw) { - assert(when_signal.__width == else_signal.__width); + assert(when_signal.size() == else_signal.size()); std::stringstream sstr; sstr << "$procmux$" << (RTLIL::autoidx++); @@ -154,14 +154,14 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, // compare results RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); - if (ctrl_sig.__width == 0) + if (ctrl_sig.size() == 0) return when_signal; - assert(ctrl_sig.__width == 1); + assert(ctrl_sig.size() == 1); // prepare multiplexer output signal RTLIL::Wire *result_wire = new RTLIL::Wire; result_wire->name = sstr.str() + "_Y"; - result_wire->width = when_signal.__width; + result_wire->width = when_signal.size(); mod->wires[result_wire->name] = result_wire; // create the multiplexer itself @@ -171,7 +171,7 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, mux_cell->attributes = sw->attributes; mod->cells[mux_cell->name] = mux_cell; - mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.__width); + mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size()); mux_cell->connections["\\A"] = else_signal; mux_cell->connections["\\B"] = when_signal; mux_cell->connections["\\S"] = ctrl_sig; @@ -184,14 +184,14 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw) { assert(last_mux_cell != NULL); - assert(when_signal.__width == last_mux_cell->connections["\\A"].__width); + assert(when_signal.size() == last_mux_cell->connections["\\A"].size()); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); - assert(ctrl_sig.__width == 1); + assert(ctrl_sig.size() == 1); last_mux_cell->type = "$pmux"; last_mux_cell->connections["\\S"].append(ctrl_sig); last_mux_cell->connections["\\B"].append(when_signal); - last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->connections["\\S"].__width; + last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->connections["\\S"].size(); } static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs, const RTLIL::SigSpec &sig, const RTLIL::SigSpec &defval) @@ -208,7 +208,7 @@ static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs // detect groups of parallel cases std::vector pgroups(sw->cases.size()); if (!sw->get_bool_attribute("\\parallel_case")) { - BitPatternPool pool(sw->signal.__width); + BitPatternPool pool(sw->signal.size()); bool extra_group_for_next_case = false; for (size_t i = 0; i < sw->cases.size(); i++) { RTLIL::CaseRule *cs2 = sw->cases[i]; @@ -224,7 +224,7 @@ static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs if (cs2->compare.empty()) pgroups[i] = pgroups[i-1]+1; if (pgroups[i] != pgroups[i-1]) - pool = BitPatternPool(sw->signal.__width); + pool = BitPatternPool(sw->signal.size()); } for (auto pat : cs2->compare) if (!pat.is_fully_const()) @@ -258,7 +258,7 @@ static void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc) { RTLIL::SigSpec sig = find_any_lvalue(&proc->root_case); - if (sig.__width == 0) + if (sig.size() == 0) break; if (first) { @@ -270,7 +270,7 @@ static void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc) log(" creating decoder for signal `%s'.\n", log_signal(sig)); - RTLIL::SigSpec value = signal_to_mux_tree(mod, &proc->root_case, sig, RTLIL::SigSpec(RTLIL::State::Sx, sig.__width)); + RTLIL::SigSpec value = signal_to_mux_tree(mod, &proc->root_case, sig, RTLIL::SigSpec(RTLIL::State::Sx, sig.size())); mod->connections.push_back(RTLIL::SigSig(sig, value)); } } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 5369617b..03a86246 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -44,7 +44,7 @@ struct BruteForceEquivChecker void run_checker(RTLIL::SigSpec &inputs) { - if (inputs.__width < mod1_inputs.__width) { + if (inputs.size() < mod1_inputs.size()) { RTLIL::SigSpec inputs0 = inputs, inputs1 = inputs; inputs0.append(RTLIL::Const(0, 1)); inputs1.append(RTLIL::Const(1, 1)); @@ -71,9 +71,9 @@ struct BruteForceEquivChecker if (ignore_x_mod1) { sig1.expand(), sig2.expand(); - for (size_t i = 0; i < sig1.__chunks.size(); i++) - if (sig1.__chunks.at(i) == RTLIL::SigChunk(RTLIL::State::Sx)) - sig2.__chunks.at(i) = RTLIL::SigChunk(RTLIL::State::Sx); + for (size_t i = 0; i < sig1.chunks().size(); i++) + if (sig1.chunks().at(i) == RTLIL::SigChunk(RTLIL::State::Sx)) + sig2.chunks().at(i) = RTLIL::SigChunk(RTLIL::State::Sx); sig1.optimize(), sig2.optimize(); } @@ -172,11 +172,11 @@ struct VlogHammerReporter log_error("Failed to find solution to SAT problem.\n"); expected_y.expand(); - for (int i = 0; i < expected_y.__width; i++) { + for (int i = 0; i < expected_y.size(); i++) { RTLIL::State solution_bit = y_values.at(i) ? RTLIL::State::S1 : RTLIL::State::S0; - RTLIL::State expected_bit = expected_y.__chunks.at(i).data.bits.at(0); + RTLIL::State expected_bit = expected_y.chunks().at(i).data.bits.at(0); if (model_undef) { - if (y_values.at(expected_y.__width+i)) + if (y_values.at(expected_y.size()+i)) solution_bit = RTLIL::State::Sx; } else { if (expected_bit == RTLIL::State::Sx) @@ -184,17 +184,17 @@ struct VlogHammerReporter } if (solution_bit != expected_bit) { std::string sat_bits, rtl_bits; - for (int k = expected_y.__width-1; k >= 0; k--) { - if (model_undef && y_values.at(expected_y.__width+k)) + for (int k = expected_y.size()-1; k >= 0; k--) { + if (model_undef && y_values.at(expected_y.size()+k)) sat_bits += "x"; else sat_bits += y_values.at(k) ? "1" : "0"; - rtl_bits += expected_y.__chunks.at(k).data.bits.at(0) == RTLIL::State::Sx ? "x" : - expected_y.__chunks.at(k).data.bits.at(0) == RTLIL::State::S1 ? "1" : "0"; + rtl_bits += expected_y.chunks().at(k).data.bits.at(0) == RTLIL::State::Sx ? "x" : + expected_y.chunks().at(k).data.bits.at(0) == RTLIL::State::S1 ? "1" : "0"; } log_error("Found error in SAT model: y[%d] = %s, should be %s:\n SAT: %s\n RTL: %s\n %*s^\n", int(i), log_signal(solution_bit), log_signal(expected_bit), - sat_bits.c_str(), rtl_bits.c_str(), expected_y.__width-i-1, ""); + sat_bits.c_str(), rtl_bits.c_str(), expected_y.size()-i-1, ""); } } @@ -203,16 +203,16 @@ struct VlogHammerReporter std::vector cmp_vars; std::vector cmp_vals; - std::vector y_undef(y_values.begin() + expected_y.__width, y_values.end()); + std::vector y_undef(y_values.begin() + expected_y.size(), y_values.end()); - for (int i = 0; i < expected_y.__width; i++) + for (int i = 0; i < expected_y.size(); i++) if (y_undef.at(i)) { log(" Toggling undef bit %d to test undef gating.\n", i); if (!ez.solve(y_vec, y_values, ez.IFF(y_vec.at(i), y_values.at(i) ? ez.FALSE : ez.TRUE))) log_error("Failed to find solution with toggled bit!\n"); - cmp_vars.push_back(y_vec.at(expected_y.__width + i)); + cmp_vars.push_back(y_vec.at(expected_y.size() + i)); cmp_vals.push_back(true); } else @@ -220,7 +220,7 @@ struct VlogHammerReporter cmp_vars.push_back(y_vec.at(i)); cmp_vals.push_back(y_values.at(i)); - cmp_vars.push_back(y_vec.at(expected_y.__width + i)); + cmp_vars.push_back(y_vec.at(expected_y.size() + i)); cmp_vals.push_back(false); } @@ -283,7 +283,7 @@ struct VlogHammerReporter while (!ce.eval(sig, undef)) { // log_error("Evaluation of y in module %s failed: sig=%s, undef=%s\n", RTLIL::id2cstr(module->name), log_signal(sig), log_signal(undef)); log("Warning: Setting signal %s in module %s to undef.\n", log_signal(undef), RTLIL::id2cstr(module->name)); - ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.__width)); + ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.size())); } log("++VAL++ %d %s %s #\n", idx, module_name.c_str(), sig.as_const().as_string().c_str()); @@ -293,13 +293,13 @@ struct VlogHammerReporter rtl_sig.expand(); sat_check(module, recorded_set_vars, recorded_set_vals, sig, false); sat_check(module, recorded_set_vars, recorded_set_vals, sig, true); - } else if (rtl_sig.__width > 0) { + } else if (rtl_sig.size() > 0) { sig.expand(); - if (rtl_sig.__width != sig.__width) + if (rtl_sig.size() != sig.size()) log_error("Output (y) has a different width in module %s compared to rtl!\n", RTLIL::id2cstr(module->name)); - for (int i = 0; i < sig.__width; i++) - if (rtl_sig.__chunks.at(i).data.bits.at(0) == RTLIL::State::Sx) - sig.__chunks.at(i).data.bits.at(0) = RTLIL::State::Sx; + for (int i = 0; i < sig.size(); i++) + if (rtl_sig.chunks().at(i).data.bits.at(0) == RTLIL::State::Sx) + sig.chunks().at(i).data.bits.at(0) = RTLIL::State::Sx; } log("++RPT++ %d%s %s %s\n", idx, input_pattern_list.c_str(), sig.as_const().as_string().c_str(), module_name.c_str()); @@ -350,7 +350,7 @@ struct VlogHammerReporter } if (!RTLIL::SigSpec::parse(sig, NULL, pattern) || !sig.is_fully_const()) log_error("Failed to parse pattern %s!\n", pattern.c_str()); - if (sig.__width < total_input_width) + if (sig.size() < total_input_width) log_error("Pattern %s is to short!\n", pattern.c_str()); patterns.push_back(sig.as_const()); if (invert_pattern) { @@ -470,9 +470,9 @@ struct EvalPass : public Pass { log_cmd_error("Failed to parse rhs set expression `%s'.\n", it.second.c_str()); if (!rhs.is_fully_const()) log_cmd_error("Right-hand-side set expression `%s' is not constant.\n", it.second.c_str()); - if (lhs.__width != rhs.__width) + if (lhs.size() != rhs.size()) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - it.first.c_str(), log_signal(lhs), lhs.__width, it.second.c_str(), log_signal(rhs), rhs.__width); + it.first.c_str(), log_signal(lhs), lhs.size(), it.second.c_str(), log_signal(rhs), rhs.size()); ce.set(lhs, rhs.as_const()); } @@ -493,7 +493,7 @@ struct EvalPass : public Pass { if (set_undef) { while (!ce.eval(value, undef)) { log("Failed to evaluate signal %s: Missing value for %s. -> setting to undef\n", log_signal(signal), log_signal(undef)); - ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.__width)); + ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.size())); undef = RTLIL::SigSpec(); } log("Eval result: %s = %s.\n", log_signal(signal), log_signal(value)); @@ -526,15 +526,15 @@ struct EvalPass : public Pass { } std::vector tab_line; - for (auto &c : tabsigs.__chunks) + for (auto &c : tabsigs.chunks()) tab_line.push_back(log_signal(c)); tab_sep_colidx = tab_line.size(); - for (auto &c : signal.__chunks) + for (auto &c : signal.chunks()) tab_line.push_back(log_signal(c)); tab.push_back(tab_line); tab_line.clear(); - RTLIL::Const tabvals(0, tabsigs.__width); + RTLIL::Const tabvals(0, tabsigs.size()); do { ce.push(); @@ -548,19 +548,19 @@ struct EvalPass : public Pass { log_signal(tabsigs), log_signal(tabvals), log_signal(this_undef)); return; } - ce.set(this_undef, RTLIL::Const(RTLIL::State::Sx, this_undef.__width)); + ce.set(this_undef, RTLIL::Const(RTLIL::State::Sx, this_undef.size())); undef.append(this_undef); this_undef = RTLIL::SigSpec(); } int pos = 0; - for (auto &c : tabsigs.__chunks) { + for (auto &c : tabsigs.chunks()) { tab_line.push_back(log_signal(RTLIL::SigSpec(tabvals).extract(pos, c.width))); pos += c.width; } pos = 0; - for (auto &c : signal.__chunks) { + for (auto &c : signal.chunks()) { tab_line.push_back(log_signal(value.extract(pos, c.width))); pos += c.width; } @@ -602,7 +602,7 @@ struct EvalPass : public Pass { } log("\n"); - if (undef.__width > 0) { + if (undef.size() > 0) { undef.sort_and_unify(); log("Assumend undef (x) value for the following singals: %s\n\n", log_signal(undef)); } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 4308e736..c9363f4b 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -649,7 +649,7 @@ struct ExposePass : public Pass { { RTLIL::Wire *w = new RTLIL::Wire; w->name = cell->name + sep + RTLIL::unescape_id(it.first); - w->width = it.second.__width; + w->width = it.second.size(); if (ct.cell_input(cell->type, it.first)) w->port_output = true; if (ct.cell_output(cell->type, it.first)) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 8cc59b29..1e47e7de 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -714,7 +714,7 @@ struct FreduceWorker if (grp[i].inverted) { - if (inv_sig.__width == 0) + if (inv_sig.size() == 0) { inv_sig = module->addWire(NEW_ID); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 1cd794b5..79857c5e 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -253,11 +253,11 @@ static void create_miter_equiv(struct Pass *that, std::vector args, } } - if (all_conditions.__width != 1) { + if (all_conditions.size() != 1) { RTLIL::Cell *reduce_cell = new RTLIL::Cell; reduce_cell->name = NEW_ID; reduce_cell->type = "$reduce_and"; - reduce_cell->parameters["\\A_WIDTH"] = all_conditions.__width; + reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size(); reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; reduce_cell->connections["\\A"] = all_conditions; @@ -283,8 +283,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::Cell *not_cell = new RTLIL::Cell; not_cell->name = NEW_ID; not_cell->type = "$not"; - not_cell->parameters["\\A_WIDTH"] = all_conditions.__width; - not_cell->parameters["\\A_WIDTH"] = all_conditions.__width; + not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); + not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); not_cell->parameters["\\Y_WIDTH"] = w_trigger->width; not_cell->parameters["\\A_SIGNED"] = 0; not_cell->connections["\\A"] = all_conditions; diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 16144932..24968aa2 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -101,10 +101,10 @@ struct SatHelper RTLIL::SigSpec lhs = sigmap(it.second); RTLIL::SigSpec rhs = it.second->attributes.at("\\init"); - log_assert(lhs.__width == rhs.__width); + log_assert(lhs.size() == rhs.size()); RTLIL::SigSpec removed_bits; - for (int i = 0; i < lhs.__width; i++) { + for (int i = 0; i < lhs.size(); i++) { RTLIL::SigSpec bit = lhs.extract(i, 1); if (!satgen.initial_state.check_all(bit)) { removed_bits.append(bit); @@ -118,10 +118,10 @@ struct SatHelper rhs.optimize(); removed_bits.optimize(); - if (removed_bits.__width) + if (removed_bits.size()) log("Warning: ignoring initial value on non-register: %s\n", log_signal(removed_bits)); - if (lhs.__width) { + if (lhs.size()) { log("Import set-constraint from init attribute: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); big_lhs.append(lhs); @@ -140,9 +140,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.__width != rhs.__width) + if (lhs.size() != rhs.size()) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); + s.first.c_str(), log_signal(lhs), lhs.size(), s.second.c_str(), log_signal(rhs), rhs.size()); log("Import set-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -166,17 +166,17 @@ struct SatHelper RTLIL::SigSpec rem = satgen.initial_state.export_all(); rem.remove(big_lhs); big_lhs.append(rem); - big_rhs.append(RTLIL::SigSpec(RTLIL::State::Sx, rem.__width)); + big_rhs.append(RTLIL::SigSpec(RTLIL::State::Sx, rem.size())); } if (set_init_zero) { RTLIL::SigSpec rem = satgen.initial_state.export_all(); rem.remove(big_lhs); big_lhs.append(rem); - big_rhs.append(RTLIL::SigSpec(RTLIL::State::S0, rem.__width)); + big_rhs.append(RTLIL::SigSpec(RTLIL::State::S0, rem.size())); } - if (big_lhs.__width == 0) { + if (big_lhs.size() == 0) { log("No constraints for initial state found.\n\n"); return; } @@ -209,9 +209,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.__width != rhs.__width) + if (lhs.size() != rhs.size()) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); + s.first.c_str(), log_signal(lhs), lhs.size(), s.second.c_str(), log_signal(rhs), rhs.size()); log("Import set-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -230,9 +230,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.__width != rhs.__width) + if (lhs.size() != rhs.size()) log_cmd_error("Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); + s.first.c_str(), log_signal(lhs), lhs.size(), s.second.c_str(), log_signal(rhs), rhs.size()); log("Import set-constraint for this timestep: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -358,9 +358,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.__width != rhs.__width) + if (lhs.size() != rhs.size()) log_cmd_error("Proof expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); + s.first.c_str(), log_signal(lhs), lhs.size(), s.second.c_str(), log_signal(rhs), rhs.size()); log("Import proof-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -386,9 +386,9 @@ struct SatHelper show_signal_pool.add(sigmap(lhs)); show_signal_pool.add(sigmap(rhs)); - if (lhs.__width != rhs.__width) + if (lhs.size() != rhs.size()) log_cmd_error("Proof-x expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n", - s.first.c_str(), log_signal(lhs), lhs.__width, s.second.c_str(), log_signal(rhs), rhs.__width); + s.first.c_str(), log_signal(lhs), lhs.size(), s.second.c_str(), log_signal(rhs), rhs.size()); log("Import proof-x-constraint: %s = %s\n", log_signal(lhs), log_signal(rhs)); big_lhs.remove2(lhs, &big_rhs); @@ -413,8 +413,8 @@ struct SatHelper satgen.getAsserts(asserts_a, asserts_en, timestep); asserts_a.expand(); asserts_en.expand(); - for (size_t i = 0; i < asserts_a.__chunks.size(); i++) - log("Import proof for assert: %s when %s.\n", log_signal(asserts_a.__chunks[i]), log_signal(asserts_en.__chunks[i])); + for (size_t i = 0; i < asserts_a.chunks().size(); i++) + log("Import proof for assert: %s when %s.\n", log_signal(asserts_a.chunks()[i]), log_signal(asserts_en.chunks()[i])); prove_bits.push_back(satgen.importAsserts(timestep)); } @@ -543,12 +543,12 @@ struct SatHelper std::vector modelUndefExpressions; - for (auto &c : modelSig.__chunks) + for (auto &c : modelSig.chunks()) if (c.wire != NULL) { ModelBlockInfo info; RTLIL::SigSpec chunksig = c; - info.width = chunksig.__width; + info.width = chunksig.size(); info.description = log_signal(chunksig); for (int timestep = -1; timestep <= max_timestep; timestep++) @@ -573,7 +573,7 @@ struct SatHelper // Add initial state signals as collected by satgen // modelSig = satgen.initial_state.export_all(); - for (auto &c : modelSig.__chunks) + for (auto &c : modelSig.chunks()) if (c.wire != NULL) { ModelBlockInfo info; @@ -581,7 +581,7 @@ struct SatHelper info.timestep = 0; info.offset = modelExpressions.size(); - info.width = chunksig.__width; + info.width = chunksig.size(); info.description = log_signal(chunksig); modelInfo.insert(info); diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 95f35bb3..738b0bd6 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -273,11 +273,11 @@ struct ShareWorker RTLIL::SigSpec a2 = c2->connections.at("\\A"); RTLIL::SigSpec y2 = c2->connections.at("\\Y"); - int a_width = std::max(a1.__width, a2.__width); - int y_width = std::max(y1.__width, y2.__width); + int a_width = std::max(a1.size(), a2.size()); + int y_width = std::max(y1.size(), y2.size()); - if (a1.__width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); - if (a2.__width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); @@ -292,8 +292,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; module->add(supercell); - RTLIL::SigSpec new_y1(y, y1.__width); - RTLIL::SigSpec new_y2(y, y2.__width); + RTLIL::SigSpec new_y1(y, y1.size()); + RTLIL::SigSpec new_y2(y, y2.size()); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -367,28 +367,28 @@ struct ShareWorker RTLIL::SigSpec b2 = c2->connections.at("\\B"); RTLIL::SigSpec y2 = c2->connections.at("\\Y"); - int a_width = std::max(a1.__width, a2.__width); - int b_width = std::max(b1.__width, b2.__width); - int y_width = std::max(y1.__width, y2.__width); + int a_width = std::max(a1.size(), a2.size()); + int b_width = std::max(b1.size(), b2.size()); + int y_width = std::max(y1.size(), y2.size()); if (c1->type == "$shr" && a_signed) { a_width = std::max(y_width, a_width); - if (a1.__width < y1.__width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.__width), true)->connections.at("\\Y"); - if (a2.__width < y2.__width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.__width), true)->connections.at("\\Y"); + if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->connections.at("\\Y"); + if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->connections.at("\\Y"); - if (a1.__width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); - if (a2.__width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); } else { - if (a1.__width != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); - if (a2.__width != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); } - if (b1.__width != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); - if (b2.__width != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); + if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); + if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); @@ -405,8 +405,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; supercell->check(); - RTLIL::SigSpec new_y1(y, y1.__width); - RTLIL::SigSpec new_y2(y, y2.__width); + RTLIL::SigSpec new_y1(y, y1.size()); + RTLIL::SigSpec new_y2(y, y2.size()); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -575,7 +575,7 @@ struct ShareWorker if (activation_patterns_cache[cell].empty()) { log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; - module->connections.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.__width))); + module->connections.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); cells_to_remove.insert(cell); } @@ -811,10 +811,10 @@ struct ShareWorker int other_cell_select_score = 0; for (auto &p : filtered_cell_activation_patterns) - cell_select_score += p.first.__width; + cell_select_score += p.first.size(); for (auto &p : filtered_other_cell_activation_patterns) - other_cell_select_score += p.first.__width; + other_cell_select_score += p.first.size(); RTLIL::Cell *supercell; if (cell_select_score <= other_cell_select_score) { diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 7e57aa0f..a960f2ba 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -133,8 +133,8 @@ namespace needleSig.expand(); haystackSig.expand(); - for (int i = 0; i < std::min(needleSig.__width, haystackSig.__width); i++) { - RTLIL::Wire *needleWire = needleSig.__chunks.at(i).wire, *haystackWire = haystackSig.__chunks.at(i).wire; + for (int i = 0; i < std::min(needleSig.size(), haystackSig.size()); i++) { + RTLIL::Wire *needleWire = needleSig.chunks().at(i).wire, *haystackWire = haystackSig.chunks().at(i).wire; if (needleWire != lastNeedleWire || haystackWire != lastHaystackWire) if (!compareAttributes(wire_attr, needleWire ? needleWire->attributes : emptyAttr, haystackWire ? haystackWire->attributes : emptyAttr)) return false; @@ -193,7 +193,7 @@ namespace RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); conn_sig.expand(); - for (auto &chunk : conn_sig.__chunks) + for (auto &chunk : conn_sig.chunks()) if (chunk.wire != NULL) sig_use_count[std::pair(chunk.wire, chunk.offset)]++; } @@ -213,7 +213,7 @@ namespace for (auto &conn : cell->connections) { - graph.createPort(cell->name, conn.first, conn.second.__width); + graph.createPort(cell->name, conn.first, conn.second.size()); if (split && split->count(std::pair(cell->type, conn.first)) > 0) continue; @@ -222,9 +222,9 @@ namespace sigmap.apply(conn_sig); conn_sig.expand(); - for (size_t i = 0; i < conn_sig.__chunks.size(); i++) + for (size_t i = 0; i < conn_sig.chunks().size(); i++) { - auto &chunk = conn_sig.__chunks[i]; + auto &chunk = conn_sig.chunks()[i]; assert(chunk.width == 1); if (chunk.wire == NULL) { @@ -269,7 +269,7 @@ namespace sigmap.apply(conn_sig); conn_sig.expand(); - for (auto &chunk : conn_sig.__chunks) + for (auto &chunk : conn_sig.chunks()) if (sig_bit_ref.count(chunk) != 0) { bit_ref_t &bit_ref = sig_bit_ref[chunk]; graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit); @@ -287,7 +287,7 @@ namespace sigmap.apply(conn_sig); conn_sig.expand(); - for (auto &chunk : conn_sig.__chunks) + for (auto &chunk : conn_sig.chunks()) if (sig_bit_ref.count(chunk) != 0) { bit_ref_t &bit_ref = sig_bit_ref[chunk]; graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit); @@ -334,8 +334,8 @@ namespace RTLIL::SigSpec sig = sigmap(conn.second); if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { sig.expand(); - for (int i = 0; i < sig.__width; i++) - for (auto &port : sig2port.find(sig.__chunks[i])) { + for (int i = 0; i < sig.size(); i++) + for (auto &port : sig2port.find(sig.chunks()[i])) { RTLIL::SigSpec bitsig = haystack_cell->connections.at(mapping.portMapping[conn.first]).extract(i, 1); cell->connections.at(port.first).replace(port.second, bitsig); } @@ -729,7 +729,7 @@ struct ExtractPass : public Pass { for (auto cell : cells) for (auto &conn : cell->connections) { RTLIL::SigSpec sig = sigmap(conn.second); - for (auto &chunk : sig.__chunks) + for (auto &chunk : sig.chunks()) if (chunk.wire != NULL) wires.insert(chunk.wire); } @@ -756,7 +756,7 @@ struct ExtractPass : public Pass { newCell->parameters = cell->parameters; for (auto &conn : cell->connections) { RTLIL::SigSpec sig = sigmap(conn.second); - for (auto &chunk : sig.__chunks) + for (auto &chunk : sig.chunks()) if (chunk.wire != NULL) chunk.wire = newMod->wires.at(chunk.wire->name); newCell->connections[conn.first] = sig; diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index 22f4c7d1..ac41e47c 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -31,7 +31,7 @@ static RTLIL::SigChunk last_hi, last_lo; void hilomap_worker(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.__chunks) { + for (auto &c : sig.chunks()) { if (c.wire == NULL && (c.data.bits.at(0) == RTLIL::State::S1) && !hicell_celltype.empty()) { if (!singleton_mode || last_hi.width == 0) { last_hi = RTLIL::SigChunk(module->addWire(NEW_ID)); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index cef5cc89..1eb5c063 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -42,8 +42,8 @@ static void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_INV_"; - gate->connections["\\A"] = sig_a.__chunks.at(i); - gate->connections["\\Y"] = sig_y.__chunks.at(i); + gate->connections["\\A"] = sig_a.chunks().at(i); + gate->connections["\\Y"] = sig_y.chunks().at(i); module->add(gate); } } @@ -96,8 +96,8 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_INV_"; - gate->connections["\\A"] = sig_t.__chunks.at(i); - gate->connections["\\Y"] = sig_y.__chunks.at(i); + gate->connections["\\A"] = sig_t.chunks().at(i); + gate->connections["\\Y"] = sig_y.chunks().at(i); module->add(gate); } @@ -115,9 +115,9 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\A"] = sig_a.__chunks.at(i); - gate->connections["\\B"] = sig_b.__chunks.at(i); - gate->connections["\\Y"] = sig_y.__chunks.at(i); + gate->connections["\\A"] = sig_a.chunks().at(i); + gate->connections["\\B"] = sig_b.chunks().at(i); + gate->connections["\\Y"] = sig_y.chunks().at(i); module->add(gate); } } @@ -129,20 +129,20 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - if (sig_y.__width == 0) + if (sig_y.size() == 0) return; - if (sig_a.__width == 0) { - if (cell->type == "$reduce_and") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.__width))); - if (cell->type == "$reduce_or") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); - if (cell->type == "$reduce_xor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); - if (cell->type == "$reduce_xnor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.__width))); - if (cell->type == "$reduce_bool") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.__width))); + if (sig_a.size() == 0) { + if (cell->type == "$reduce_and") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == "$reduce_or") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_xor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_xnor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == "$reduce_bool") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); return; } - if (sig_y.__width > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.__width-1), RTLIL::SigSpec(0, sig_y.__width-1))); + if (sig_y.size() > 1) { + module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } @@ -156,24 +156,24 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec *last_output = NULL; - while (sig_a.__width > 1) + while (sig_a.size() > 1) { - RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.__width / 2); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.size() / 2); sig_t.expand(); - for (int i = 0; i < sig_a.__width; i += 2) + for (int i = 0; i < sig_a.size(); i += 2) { - if (i+1 == sig_a.__width) { - sig_t.append(sig_a.__chunks.at(i)); + if (i+1 == sig_a.size()) { + sig_t.append(sig_a.chunks().at(i)); continue; } RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\A"] = sig_a.__chunks.at(i); - gate->connections["\\B"] = sig_a.__chunks.at(i+1); - gate->connections["\\Y"] = sig_t.__chunks.at(i/2); + gate->connections["\\A"] = sig_a.chunks().at(i); + gate->connections["\\B"] = sig_a.chunks().at(i+1); + gate->connections["\\Y"] = sig_t.chunks().at(i/2); last_output = &gate->connections["\\Y"]; module->add(gate); } @@ -204,31 +204,31 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) { sig.expand(); - while (sig.__width > 1) + while (sig.size() > 1) { - RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.__width / 2); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.size() / 2); sig_t.expand(); - for (int i = 0; i < sig.__width; i += 2) + for (int i = 0; i < sig.size(); i += 2) { - if (i+1 == sig.__width) { - sig_t.append(sig.__chunks.at(i)); + if (i+1 == sig.size()) { + sig_t.append(sig.chunks().at(i)); continue; } RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_OR_"; - gate->connections["\\A"] = sig.__chunks.at(i); - gate->connections["\\B"] = sig.__chunks.at(i+1); - gate->connections["\\Y"] = sig_t.__chunks.at(i/2); + gate->connections["\\A"] = sig.chunks().at(i); + gate->connections["\\B"] = sig.chunks().at(i+1); + gate->connections["\\Y"] = sig_t.chunks().at(i/2); module->add(gate); } sig = sig_t; } - if (sig.__width == 0) + if (sig.size() == 0) sig = RTLIL::SigSpec(0, 1); } @@ -239,11 +239,11 @@ static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - if (sig_y.__width == 0) + if (sig_y.size() == 0) return; - if (sig_y.__width > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.__width-1), RTLIL::SigSpec(0, sig_y.__width-1))); + if (sig_y.size() > 1) { + module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } @@ -265,11 +265,11 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - if (sig_y.__width == 0) + if (sig_y.size() == 0) return; - if (sig_y.__width > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.__width-1), RTLIL::SigSpec(0, sig_y.__width-1))); + if (sig_y.size() > 1) { + module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } @@ -304,10 +304,10 @@ static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_MUX_"; - gate->connections["\\A"] = sig_a.__chunks.at(i); - gate->connections["\\B"] = sig_b.__chunks.at(i); + gate->connections["\\A"] = sig_a.chunks().at(i); + gate->connections["\\B"] = sig_b.chunks().at(i); gate->connections["\\S"] = cell->connections.at("\\S"); - gate->connections["\\Y"] = sig_y.__chunks.at(i); + gate->connections["\\Y"] = sig_y.chunks().at(i); module->add(gate); } } @@ -317,7 +317,7 @@ static void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) int offset = cell->parameters.at("\\OFFSET").as_int(); RTLIL::SigSpec sig_a = cell->connections.at("\\A"); RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.__width))); + module->connections.push_back(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); } static void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) @@ -349,9 +349,9 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\S"] = sig_s.__chunks.at(i); - gate->connections["\\R"] = sig_r.__chunks.at(i); - gate->connections["\\Q"] = sig_q.__chunks.at(i); + gate->connections["\\S"] = sig_s.chunks().at(i); + gate->connections["\\R"] = sig_r.chunks().at(i); + gate->connections["\\Q"] = sig_q.chunks().at(i); module->add(gate); } } @@ -376,8 +376,8 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\C"] = sig_clk; - gate->connections["\\D"] = sig_d.__chunks.at(i); - gate->connections["\\Q"] = sig_q.__chunks.at(i); + gate->connections["\\D"] = sig_d.chunks().at(i); + gate->connections["\\Q"] = sig_q.chunks().at(i); module->add(gate); } } @@ -410,10 +410,10 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\C"] = sig_clk; - gate->connections["\\S"] = sig_s.__chunks.at(i); - gate->connections["\\R"] = sig_r.__chunks.at(i); - gate->connections["\\D"] = sig_d.__chunks.at(i); - gate->connections["\\Q"] = sig_q.__chunks.at(i); + gate->connections["\\S"] = sig_s.chunks().at(i); + gate->connections["\\R"] = sig_r.chunks().at(i); + gate->connections["\\D"] = sig_d.chunks().at(i); + gate->connections["\\Q"] = sig_q.chunks().at(i); module->add(gate); } } @@ -446,8 +446,8 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) gate->type = rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0; gate->connections["\\C"] = sig_clk; gate->connections["\\R"] = sig_rst; - gate->connections["\\D"] = sig_d.__chunks.at(i); - gate->connections["\\Q"] = sig_q.__chunks.at(i); + gate->connections["\\D"] = sig_d.chunks().at(i); + gate->connections["\\Q"] = sig_q.chunks().at(i); module->add(gate); } } @@ -472,8 +472,8 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\E"] = sig_en; - gate->connections["\\D"] = sig_d.__chunks.at(i); - gate->connections["\\Q"] = sig_q.__chunks.at(i); + gate->connections["\\D"] = sig_d.chunks().at(i); + gate->connections["\\Q"] = sig_q.chunks().at(i); module->add(gate); } } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index f7d5efa0..d3e7e20f 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -41,13 +41,13 @@ static void apply_prefix(std::string prefix, std::string &id) static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module *module) { - for (size_t i = 0; i < sig.__chunks.size(); i++) { - if (sig.__chunks[i].wire == NULL) + for (size_t i = 0; i < sig.chunks().size(); i++) { + if (sig.chunks()[i].wire == NULL) continue; - std::string wire_name = sig.__chunks[i].wire->name; + std::string wire_name = sig.chunks()[i].wire->name; apply_prefix(prefix, wire_name); assert(module->wires.count(wire_name) > 0); - sig.__chunks[i].wire = module->wires[wire_name]; + sig.chunks()[i].wire = module->wires[wire_name]; } } @@ -163,11 +163,11 @@ struct TechmapWorker c.second = it.second; apply_prefix(cell->name, c.first, module); } - if (c.second.__width > c.first.__width) - c.second.remove(c.first.__width, c.second.__width - c.first.__width); - if (c.second.__width < c.first.__width) - c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.__width - c.second.__width)); - assert(c.first.__width == c.second.__width); + if (c.second.size() > c.first.size()) + c.second.remove(c.first.size(), c.second.size() - c.first.size()); + if (c.second.size() < c.first.size()) + c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.size() - c.second.size())); + assert(c.first.size() == c.second.size()); if (flatten_mode) { // more conservative approach: // connect internal and external wires From 7bffde6abdaf6fc2ed090946442f90b2438e6126 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:39:13 +0200 Subject: [PATCH 360/750] SigSpec refactoring: change RTLIL::SigSpec::size() to be read-only --- frontends/ast/genrtlil.cc | 66 +++++++-------------------------------- frontends/ilang/parser.y | 43 ++++--------------------- kernel/rtlil.h | 3 +- 3 files changed, 18 insertions(+), 94 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 681b3486..34a3f1ba 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 e8af447b..e4d12f3a 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; } | diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 88ed2f6a..6bbf6960 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -504,8 +504,7 @@ public: std::vector &chunks() { return chunks_; } const std::vector &chunks() const { return chunks_; } - int &size() { return width_; } - const int &size() const { return width_; } + int size() const { return width_; } SigSpec(); SigSpec(const RTLIL::Const &data); From 28b3fd05fa9cf6d469fdec95e247a7ffe5bc001d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:58:44 +0200 Subject: [PATCH 361/750] SigSpec refactoring: change RTLIL::SigSpec::chunks() to be read-only, created interim RTLIL::SigSpec::chunks_rw() --- backends/btor/btor.cc | 4 ++-- backends/verilog/verilog_backend.cc | 4 ++-- frontends/ast/genrtlil.cc | 2 +- kernel/consteval.h | 2 +- kernel/rtlil.cc | 2 +- kernel/rtlil.h | 2 +- kernel/sigtools.h | 8 ++++---- passes/cmds/delete.cc | 2 +- passes/cmds/setundef.cc | 2 +- passes/cmds/show.cc | 4 ++-- passes/cmds/splitnets.cc | 2 +- passes/fsm/fsm_extract.cc | 4 ++-- passes/hierarchy/submod.cc | 2 +- passes/memory/memory_dff.cc | 2 +- passes/opt/opt_const.cc | 9 ++------- passes/proc/proc_arst.cc | 2 +- passes/sat/eval.cc | 4 ++-- passes/techmap/extract.cc | 2 +- passes/techmap/hilomap.cc | 2 +- passes/techmap/techmap.cc | 2 +- 20 files changed, 29 insertions(+), 34 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 7853160e..9139749c 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -45,9 +45,9 @@ struct BtorDumperConfig struct WireInfo { RTLIL::IdString cell_name; - RTLIL::SigChunk *chunk; + const RTLIL::SigChunk *chunk; - WireInfo(RTLIL::IdString c, RTLIL::SigChunk* ch) : cell_name(c), chunk(ch) { } + WireInfo(RTLIL::IdString c, const RTLIL::SigChunk* ch) : cell_name(c), chunk(ch) { } }; struct WireInfoOrder diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 4b60f0fb..16083508 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -149,7 +149,7 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name) return true; } -void dump_const(FILE *f, RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false) +void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false) { if (width < 0) width = data.bits.size() - offset; @@ -203,7 +203,7 @@ void dump_const(FILE *f, RTLIL::Const &data, int width = -1, int offset = 0, boo } } -void dump_sigchunk(FILE *f, RTLIL::SigChunk &chunk, bool no_decimal = false) +void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool no_decimal = false) { if (chunk.wire == NULL) { dump_const(f, chunk.data, chunk.width, chunk.offset, no_decimal); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 34a3f1ba..a51064c3 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; diff --git a/kernel/consteval.h b/kernel/consteval.h index 564098c6..5836cdd5 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -73,7 +73,7 @@ struct ConstEval RTLIL::SigSpec current_val = values_map(sig); current_val.expand(); for (size_t i = 0; i < current_val.chunks().size(); i++) { - RTLIL::SigChunk &chunk = current_val.chunks()[i]; + const RTLIL::SigChunk &chunk = current_val.chunks()[i]; assert(chunk.wire != NULL || chunk.data.bits[0] == value.bits[i]); } #endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 43511304..361cd5f0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -801,7 +801,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const RTLIL::Module *mod; void operator()(RTLIL::SigSpec &sig) { - for (auto &c : sig.chunks()) + for (auto &c : sig.chunks_rw()) if (c.wire != NULL) c.wire = mod->wires.at(c.wire->name); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6bbf6960..9d5b3b30 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -501,7 +501,7 @@ private: int width_; public: - std::vector &chunks() { return chunks_; } + std::vector &chunks_rw() { return chunks_; } const std::vector &chunks() const { return chunks_; } int size() const { return width_; } diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 27abd867..826f8417 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -423,8 +423,8 @@ struct SigMap assert(from.chunks().size() == to.chunks().size()); for (size_t i = 0; i < from.chunks().size(); i++) { - RTLIL::SigChunk &cf = from.chunks()[i]; - RTLIL::SigChunk &ct = to.chunks()[i]; + const RTLIL::SigChunk &cf = from.chunks()[i]; + const RTLIL::SigChunk &ct = to.chunks()[i]; if (cf.wire == NULL) continue; @@ -444,7 +444,7 @@ struct SigMap sig.expand(); for (size_t i = 0; i < sig.chunks().size(); i++) { - RTLIL::SigChunk &c = sig.chunks()[i]; + const RTLIL::SigChunk &c = sig.chunks()[i]; if (c.wire != NULL) { register_bit(c); set_bit(c, c); @@ -462,7 +462,7 @@ struct SigMap void apply(RTLIL::SigSpec &sig) const { sig.expand(); - for (auto &c : sig.chunks()) + for (auto &c : sig.chunks_rw()) map_bit(c); sig.optimize(); } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index c5aa196c..f433c4b4 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -28,7 +28,7 @@ struct DeleteWireWorker void operator()(RTLIL::SigSpec &sig) { sig.optimize(); - for (auto &c : sig.chunks()) + for (auto &c : sig.chunks_rw()) if (c.wire != NULL && delete_wires_p->count(c.wire->name)) { c.wire = module->addWire(NEW_ID, c.width); c.offset = 0; diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 7558a4e9..619930b3 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -48,7 +48,7 @@ struct SetundefWorker void operator()(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.chunks()) + for (auto &c : sig.chunks_rw()) if (c.wire == NULL && c.data.bits.at(0) > RTLIL::State::S1) c.data.bits.at(0) = next_bit(); sig.optimize(); diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index fde96d53..37fe4404 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -179,7 +179,7 @@ struct ShowWorker } if (sig.chunks().size() == 1) { - RTLIL::SigChunk &c = sig.chunks()[0]; + const RTLIL::SigChunk &c = sig.chunks()[0]; if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) { if (!range_check || c.wire->width == c.width) return stringf("n%d", id2num(c.wire->name)); @@ -203,7 +203,7 @@ struct ShowWorker int pos = sig.size()-1; int idx = single_idx_count++; for (int i = int(sig.chunks().size())-1; i >= 0; i--) { - RTLIL::SigChunk &c = sig.chunks()[i]; + const RTLIL::SigChunk &c = sig.chunks()[i]; net = gen_signode_simple(c, false); assert(!net.empty()); if (driver) { diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 8cc6a515..d71e9727 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -63,7 +63,7 @@ struct SplitnetsWorker void operator()(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.chunks()) + for (auto &c : sig.chunks_rw()) if (splitmap.count(c.wire) > 0) c = splitmap.at(c.wire).at(c.offset); sig.optimize(); diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 701b09bd..c3bb1933 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -92,7 +92,7 @@ static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State no { if (dont_care.size() > 0) { sig.expand(); - for (auto &chunk : sig.chunks()) { + for (auto &chunk : sig.chunks_rw()) { assert(chunk.width == 1); if (dont_care.extract(chunk).size() > 0) chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); @@ -104,7 +104,7 @@ static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State no ce.values_map.apply(sig); sig.expand(); - for (auto &chunk : sig.chunks()) { + for (auto &chunk : sig.chunks_rw()) { assert(chunk.width == 1); if (chunk.wire != NULL) chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index fa8043c8..b983a840 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -164,7 +164,7 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new RTLIL::Cell(*cell); for (auto &conn : new_cell->connections) - for (auto &c : conn.second.chunks()) + for (auto &c : conn.second.chunks_rw()) if (c.wire != NULL) { assert(wire_flags.count(c.wire) > 0); c.wire = wire_flags[c.wire].new_wire; diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 8bae24cf..dee48597 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -36,7 +36,7 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI 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; diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 1a1f0fe4..9b89291b 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -699,10 +699,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec a = cell->connections["\\A"]; \ assign_map.apply(a); \ if (a.is_fully_const()) { \ - a.optimize(); \ - if (a.chunks().empty()) a.chunks().push_back(RTLIL::SigChunk()); \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ - RTLIL::SigSpec y(RTLIL::const_ ## _t(a.chunks()[0].data, dummy_arg, \ + RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), dummy_arg, \ cell->parameters["\\A_SIGNED"].as_bool(), false, \ cell->parameters["\\Y_WIDTH"].as_int())); \ replace_cell(module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ @@ -715,10 +713,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec b = cell->connections["\\B"]; \ assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ - a.optimize(), b.optimize(); \ - if (a.chunks().empty()) a.chunks().push_back(RTLIL::SigChunk()); \ - if (b.chunks().empty()) b.chunks().push_back(RTLIL::SigChunk()); \ - RTLIL::SigSpec y(RTLIL::const_ ## _t(a.chunks()[0].data, b.chunks()[0].data, \ + RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \ cell->parameters["\\A_SIGNED"].as_bool(), \ cell->parameters["\\B_SIGNED"].as_bool(), \ cell->parameters["\\Y_WIDTH"].as_int())); \ diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index b5763508..6cb560f5 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -168,7 +168,7 @@ restart_proc_arst: rspec.expand(), rval.expand(); for (int i = 0; i < int(rspec.chunks().size()); i++) if (rspec.chunks()[i].wire == NULL) - rval.chunks()[i] = rspec.chunks()[i]; + rval.chunks_rw()[i] = rspec.chunks()[i]; rspec.optimize(), rval.optimize(); RTLIL::SigSpec last_rval; for (int count = 0; rval != last_rval; count++) { diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 03a86246..73235e93 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -73,7 +73,7 @@ struct BruteForceEquivChecker sig1.expand(), sig2.expand(); for (size_t i = 0; i < sig1.chunks().size(); i++) if (sig1.chunks().at(i) == RTLIL::SigChunk(RTLIL::State::Sx)) - sig2.chunks().at(i) = RTLIL::SigChunk(RTLIL::State::Sx); + sig2.chunks_rw().at(i) = RTLIL::SigChunk(RTLIL::State::Sx); sig1.optimize(), sig2.optimize(); } @@ -299,7 +299,7 @@ struct VlogHammerReporter log_error("Output (y) has a different width in module %s compared to rtl!\n", RTLIL::id2cstr(module->name)); for (int i = 0; i < sig.size(); i++) if (rtl_sig.chunks().at(i).data.bits.at(0) == RTLIL::State::Sx) - sig.chunks().at(i).data.bits.at(0) = RTLIL::State::Sx; + sig.chunks_rw().at(i).data.bits.at(0) = RTLIL::State::Sx; } log("++RPT++ %d%s %s %s\n", idx, input_pattern_list.c_str(), sig.as_const().as_string().c_str(), module_name.c_str()); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index a960f2ba..5a729808 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -756,7 +756,7 @@ struct ExtractPass : public Pass { newCell->parameters = cell->parameters; for (auto &conn : cell->connections) { RTLIL::SigSpec sig = sigmap(conn.second); - for (auto &chunk : sig.chunks()) + for (auto &chunk : sig.chunks_rw()) if (chunk.wire != NULL) chunk.wire = newMod->wires.at(chunk.wire->name); newCell->connections[conn.first] = sig; diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index ac41e47c..53c5d104 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -31,7 +31,7 @@ static RTLIL::SigChunk last_hi, last_lo; void hilomap_worker(RTLIL::SigSpec &sig) { sig.expand(); - for (auto &c : sig.chunks()) { + for (auto &c : sig.chunks_rw()) { if (c.wire == NULL && (c.data.bits.at(0) == RTLIL::State::S1) && !hicell_celltype.empty()) { if (!singleton_mode || last_hi.width == 0) { last_hi = RTLIL::SigChunk(module->addWire(NEW_ID)); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index d3e7e20f..f3b1a0ef 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -47,7 +47,7 @@ static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module std::string wire_name = sig.chunks()[i].wire->name; apply_prefix(prefix, wire_name); assert(module->wires.count(wire_name) > 0); - sig.chunks()[i].wire = module->wires[wire_name]; + sig.chunks_rw()[i].wire = module->wires[wire_name]; } } From 08e1e251698edfec7e0634a8ccdc321f42e8f27f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 21:33:52 +0200 Subject: [PATCH 362/750] SigSpec refactoring: added RTLIL::SigSpec::bits() and pack/unpack api --- kernel/rtlil.cc | 111 ++++++++++++++++++++++++++++++++++++++++++++---- kernel/rtlil.h | 42 +++++++++++++----- 2 files changed, 135 insertions(+), 18 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 361cd5f0..8058f69c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1487,8 +1487,48 @@ RTLIL::SigSpec::SigSpec(std::set bits) check(); } +void RTLIL::SigSpec::pack() const +{ + RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; + + if (that->bits_.empty()) + return; + + log_assert(that->chunks_.empty()); + + std::vector old_bits; + old_bits.swap(that->bits_); + + that->width_ = 0; + for (auto &bit : old_bits) + that->append_bit(bit); +} + +void RTLIL::SigSpec::unpack() const +{ + RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; + + if (that->chunks_.empty()) + return; + + log_assert(that->bits_.empty()); + + that->bits_.reserve(that->width_); + for (auto &c : that->chunks_) + for (int i = 0; i < c.width; i++) + that->bits_.push_back(RTLIL::SigBit(c, i)); + + that->chunks_.clear(); +} + +bool RTLIL::SigSpec::packed() const +{ + return bits_.empty(); +} + void RTLIL::SigSpec::expand() { + pack(); std::vector new_chunks; for (size_t i = 0; i < chunks_.size(); i++) { for (int j = 0; j < chunks_[i].width; j++) @@ -1500,6 +1540,7 @@ void RTLIL::SigSpec::expand() void RTLIL::SigSpec::optimize() { + pack(); std::vector new_chunks; for (auto &c : chunks_) if (new_chunks.size() == 0) { @@ -1519,6 +1560,7 @@ void RTLIL::SigSpec::optimize() RTLIL::SigSpec RTLIL::SigSpec::optimized() const { + pack(); RTLIL::SigSpec ret = *this; ret.optimize(); return ret; @@ -1543,6 +1585,7 @@ bool RTLIL::SigChunk::compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b void RTLIL::SigSpec::sort() { + pack(); expand(); std::sort(chunks_.begin(), chunks_.end(), RTLIL::SigChunk::compare); optimize(); @@ -1550,6 +1593,7 @@ void RTLIL::SigSpec::sort() void RTLIL::SigSpec::sort_and_unify() { + pack(); expand(); std::sort(chunks_.begin(), chunks_.end(), RTLIL::SigChunk::compare); for (size_t i = 1; i < chunks_.size(); i++) { @@ -1571,6 +1615,13 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { + pack(); + pattern.pack(); + with.pack(); + + if (other != NULL) + other->pack(); + int pos = 0, restart_pos = 0; assert(other == NULL || width_ == other->width_); for (size_t i = 0; i < chunks_.size(); i++) { @@ -1609,6 +1660,12 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) { + pack(); + pattern.pack(); + + if (other != NULL) + other->pack(); + int pos = 0; assert(other == NULL || width_ == other->width_); for (size_t i = 0; i < chunks_.size(); i++) { @@ -1638,6 +1695,12 @@ restart: RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const { + pack(); + pattern.pack(); + + if (other != NULL) + other->pack(); + assert(other == NULL || width_ == other->width_); std::set pat = pattern.to_sigbit_set(); @@ -1661,6 +1724,9 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) { + pack(); + with.pack(); + int pos = 0; assert(offset >= 0); assert(with.width_ >= 0); @@ -1683,6 +1749,7 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) void RTLIL::SigSpec::remove_const() { + pack(); for (size_t i = 0; i < chunks_.size(); i++) { if (chunks_[i].wire != NULL) continue; @@ -1694,6 +1761,7 @@ void RTLIL::SigSpec::remove_const() void RTLIL::SigSpec::remove(int offset, int length) { + pack(); int pos = 0; assert(offset >= 0); assert(length >= 0); @@ -1733,6 +1801,7 @@ void RTLIL::SigSpec::remove(int offset, int length) RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const { + pack(); int pos = 0; RTLIL::SigSpec ret; assert(offset >= 0); @@ -1762,6 +1831,9 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) { + pack(); + signal.pack(); + for (size_t i = 0; i < signal.chunks_.size(); i++) { chunks_.push_back(signal.chunks_[i]); width_ += signal.chunks_[i].width; @@ -1771,6 +1843,7 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) { + pack(); if (chunks_.size() == 0) chunks_.push_back(bit); else @@ -1789,8 +1862,11 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) // check(); } -bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool override) +bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool do_override) { + pack(); + signal.pack(); + bool no_collisions = true; assert(width_ == signal.width_); @@ -1801,7 +1877,7 @@ bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool bool self_free = chunks_[i].wire == NULL && chunks_[i].data.bits[0] == freeState; bool other_free = signal.chunks_[i].wire == NULL && signal.chunks_[i].data.bits[0] == freeState; if (!self_free && !other_free) { - if (override) + if (do_override) chunks_[i] = signal.chunks_[i]; else chunks_[i] = RTLIL::SigChunk(RTLIL::State::Sx, 1); @@ -1817,6 +1893,8 @@ bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool void RTLIL::SigSpec::extend(int width, bool is_signed) { + pack(); + if (width_ > width) remove(width, width_ - width); @@ -1834,6 +1912,8 @@ void RTLIL::SigSpec::extend(int width, bool is_signed) void RTLIL::SigSpec::extend_u0(int width, bool is_signed) { + pack(); + if (width_ > width) remove(width, width_ - width); @@ -1850,6 +1930,8 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed) void RTLIL::SigSpec::check() const { + pack(); + int w = 0; for (size_t i = 0; i < chunks_.size(); i++) { const RTLIL::SigChunk chunk = chunks_[i]; @@ -1869,6 +1951,9 @@ void RTLIL::SigSpec::check() const bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const { + pack(); + other.pack(); + if (width_ != other.width_) return width_ < other.width_; @@ -1888,6 +1973,9 @@ bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const { + pack(); + other.pack(); + if (width_ != other.width_) return false; @@ -1914,6 +2002,7 @@ bool RTLIL::SigSpec::operator !=(const RTLIL::SigSpec &other) const bool RTLIL::SigSpec::is_fully_const() const { + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) if (it->width > 0 && it->wire != NULL) return false; @@ -1922,6 +2011,7 @@ bool RTLIL::SigSpec::is_fully_const() const bool RTLIL::SigSpec::is_fully_def() const { + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; @@ -1934,6 +2024,7 @@ bool RTLIL::SigSpec::is_fully_def() const bool RTLIL::SigSpec::is_fully_undef() const { + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; @@ -1946,6 +2037,7 @@ bool RTLIL::SigSpec::is_fully_undef() const bool RTLIL::SigSpec::has_marked_bits() const { + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) if (it->width > 0 && it->wire == NULL) { for (size_t i = 0; i < it->data.bits.size(); i++) @@ -1957,6 +2049,7 @@ bool RTLIL::SigSpec::has_marked_bits() const bool RTLIL::SigSpec::as_bool() const { + pack(); assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); @@ -1967,6 +2060,7 @@ bool RTLIL::SigSpec::as_bool() const int RTLIL::SigSpec::as_int() const { + pack(); assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); @@ -1977,6 +2071,7 @@ int RTLIL::SigSpec::as_int() const std::string RTLIL::SigSpec::as_string() const { + pack(); std::string str; for (size_t i = chunks_.size(); i > 0; i--) { const RTLIL::SigChunk &chunk = chunks_[i-1]; @@ -1991,6 +2086,7 @@ std::string RTLIL::SigSpec::as_string() const RTLIL::Const RTLIL::SigSpec::as_const() const { + pack(); assert(is_fully_const()); SigSpec sig = *this; sig.optimize(); @@ -2001,6 +2097,7 @@ RTLIL::Const RTLIL::SigSpec::as_const() const bool RTLIL::SigSpec::match(std::string pattern) const { + pack(); std::string str = as_string(); assert(pattern.size() == str.size()); @@ -2021,6 +2118,7 @@ bool RTLIL::SigSpec::match(std::string pattern) const std::set RTLIL::SigSpec::to_sigbit_set() const { + pack(); std::set sigbits; for (auto &c : chunks_) for (int i = 0; i < c.width; i++) @@ -2030,16 +2128,13 @@ std::set RTLIL::SigSpec::to_sigbit_set() const std::vector RTLIL::SigSpec::to_sigbit_vector() const { - std::vector sigbits; - sigbits.reserve(width_); - for (auto &c : chunks_) - for (int i = 0; i < c.width; i++) - sigbits.push_back(RTLIL::SigBit(c, i)); - return sigbits; + unpack(); + return bits_; } RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const { + pack(); log_assert(width_ == 1); for (auto &c : chunks_) if (c.width) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9d5b3b30..1d84dd3b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -498,14 +498,14 @@ struct RTLIL::SigBit { struct RTLIL::SigSpec { private: std::vector chunks_; // LSB at index 0 + std::vector bits_; // LSB at index 0 int width_; + void pack() const; + void unpack() const; + bool packed() const; + public: - std::vector &chunks_rw() { return chunks_; } - const std::vector &chunks() const { return chunks_; } - - int size() const { return width_; } - SigSpec(); SigSpec(const RTLIL::Const &data); SigSpec(const RTLIL::SigChunk &chunk); @@ -516,46 +516,68 @@ public: SigSpec(RTLIL::SigBit bit, int width = 1); SigSpec(std::vector bits); SigSpec(std::set bits); + + std::vector &chunks_rw() { pack(); return chunks_; } + const std::vector &chunks() const { pack(); return chunks_; } + const std::vector &bits() const { unpack(); return bits_; } + + int size() const { return width_; } + void expand(); void optimize(); RTLIL::SigSpec optimized() const; + void sort(); void sort_and_unify(); + void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with); void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const; + void replace(int offset, const RTLIL::SigSpec &with); + void remove(const RTLIL::SigSpec &pattern); void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const; void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other); - RTLIL::SigSpec extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other = NULL) const; - void replace(int offset, const RTLIL::SigSpec &with); + void remove(int offset, int length = 1); void remove_const(); - void remove(int offset, int length); + + RTLIL::SigSpec extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(int offset, int length) const; + void append(const RTLIL::SigSpec &signal); void append_bit(const RTLIL::SigBit &bit); - bool combine(RTLIL::SigSpec signal, RTLIL::State freeState = RTLIL::State::Sz, bool override = false); + + bool combine(RTLIL::SigSpec signal, RTLIL::State freeState = RTLIL::State::Sz, bool do_override = false); + void extend(int width, bool is_signed = false); void extend_u0(int width, bool is_signed = false); - void check() const; + bool operator <(const RTLIL::SigSpec &other) const; bool operator ==(const RTLIL::SigSpec &other) const; bool operator !=(const RTLIL::SigSpec &other) const; + bool is_fully_const() const; bool is_fully_def() const; bool is_fully_undef() const; bool has_marked_bits() const; + bool as_bool() const; int as_int() const; std::string as_string() const; RTLIL::Const as_const() const; + bool match(std::string pattern) const; + std::set to_sigbit_set() const; std::vector to_sigbit_vector() const; RTLIL::SigBit to_single_sigbit() const; + static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str); static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); + operator std::vector() const { return to_sigbit_vector(); } + + void check() const; }; inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { From a97be0828a3998d1eb5128e8e24c75af2016f27b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 21:40:52 +0200 Subject: [PATCH 363/750] Removed RTLIL::SigChunk::compare() --- kernel/rtlil.cc | 29 +++++------------------------ kernel/rtlil.h | 1 - 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8058f69c..937dcbce 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1382,6 +1382,7 @@ bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk &other) const if (wire && other.wire) if (wire->name != other.wire->name) return wire->name < other.wire->name; + if (wire != other.wire) return wire < other.wire; @@ -1391,10 +1392,7 @@ bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk &other) const if (width != other.width) return width < other.width; - if (data.bits != other.data.bits) - return data.bits < other.data.bits; - - return false; + return data.bits < other.data.bits; } bool RTLIL::SigChunk::operator ==(const RTLIL::SigChunk &other) const @@ -1566,28 +1564,11 @@ RTLIL::SigSpec RTLIL::SigSpec::optimized() const return ret; } -bool RTLIL::SigChunk::compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b) -{ - if (a.wire != b.wire) { - if (a.wire == NULL || b.wire == NULL) - return a.wire < b.wire; - else if (a.wire->name != b.wire->name) - return a.wire->name < b.wire->name; - else - return a.wire < b.wire; - } - if (a.offset != b.offset) - return a.offset < b.offset; - if (a.width != b.width) - return a.width < b.width; - return a.data.bits < b.data.bits; -} - void RTLIL::SigSpec::sort() { pack(); expand(); - std::sort(chunks_.begin(), chunks_.end(), RTLIL::SigChunk::compare); + std::sort(chunks_.begin(), chunks_.end()); optimize(); } @@ -1595,11 +1576,11 @@ void RTLIL::SigSpec::sort_and_unify() { pack(); expand(); - std::sort(chunks_.begin(), chunks_.end(), RTLIL::SigChunk::compare); + std::sort(chunks_.begin(), chunks_.end()); for (size_t i = 1; i < chunks_.size(); i++) { RTLIL::SigChunk &ch1 = chunks_[i-1]; RTLIL::SigChunk &ch2 = chunks_[i]; - if (!RTLIL::SigChunk::compare(ch1, ch2) && !RTLIL::SigChunk::compare(ch2, ch1)) { + if (ch1 == ch2) { chunks_.erase(chunks_.begin()+i); width_ -= chunks_[i].width; i--; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1d84dd3b..facd43db 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -470,7 +470,6 @@ struct RTLIL::SigChunk { bool operator <(const RTLIL::SigChunk &other) const; bool operator ==(const RTLIL::SigChunk &other) const; bool operator !=(const RTLIL::SigChunk &other) const; - static bool compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b); }; struct RTLIL::SigBit { From fd4cbe627527561fb08bc77467f2b6a250d5dc4d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:26:30 +0200 Subject: [PATCH 364/750] SigSpec refactoring: rewrote some RTLIL::SigSpec methods to use unpacked form --- kernel/rtlil.cc | 297 +++++++++++++++++++----------------------------- 1 file changed, 114 insertions(+), 183 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 937dcbce..d4601405 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1566,27 +1566,13 @@ RTLIL::SigSpec RTLIL::SigSpec::optimized() const void RTLIL::SigSpec::sort() { - pack(); - expand(); - std::sort(chunks_.begin(), chunks_.end()); - optimize(); + unpack(); + std::sort(bits_.begin(), bits_.end()); } void RTLIL::SigSpec::sort_and_unify() { - pack(); - expand(); - std::sort(chunks_.begin(), chunks_.end()); - for (size_t i = 1; i < chunks_.size(); i++) { - RTLIL::SigChunk &ch1 = chunks_[i-1]; - RTLIL::SigChunk &ch2 = chunks_[i]; - if (ch1 == ch2) { - chunks_.erase(chunks_.begin()+i); - width_ -= chunks_[i].width; - i--; - } - } - optimize(); + *this = this->to_sigbit_set(); } void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with) @@ -1596,36 +1582,26 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { - pack(); - pattern.pack(); - with.pack(); + unpack(); + pattern.unpack(); + with.unpack(); - if (other != NULL) - other->pack(); + assert(other != NULL); + assert(width_ == other->width_); + other->unpack(); - int pos = 0, restart_pos = 0; - assert(other == NULL || width_ == other->width_); - for (size_t i = 0; i < chunks_.size(); i++) { -restart: - const RTLIL::SigChunk &ch1 = chunks_[i]; - if (chunks_[i].wire != NULL && pos >= restart_pos) - for (size_t j = 0, poff = 0; j < pattern.chunks_.size(); j++) { - const RTLIL::SigChunk &ch2 = pattern.chunks_[j]; - assert(ch2.wire != NULL); - if (ch1.wire == ch2.wire) { - int lower = std::max(ch1.offset, ch2.offset); - int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width); - if (lower < upper) { - restart_pos = pos+upper-ch1.offset; - other->replace(pos+lower-ch1.offset, with.extract(poff+lower-ch2.offset, upper-lower)); - goto restart; - } - } - poff += ch2.width; - } - pos += chunks_[i].width; - } - check(); + assert(pattern.width_ == with.width_); + + std::map pattern_map; + for (int i = 0; i < SIZE(pattern.bits_); i++) + if (pattern.bits_[i].wire != NULL) + pattern_map[pattern.bits_[i]] = with.bits_[i]; + + for (int i = 0; i < SIZE(bits_); i++) + if (pattern_map.count(bits_[i])) + other->bits_[i] = pattern_map.at(bits_[i]); + + other->check(); } void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern) @@ -1641,36 +1617,32 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) { - pack(); - pattern.pack(); + unpack(); - if (other != NULL) - other->pack(); - - int pos = 0; - assert(other == NULL || width_ == other->width_); - for (size_t i = 0; i < chunks_.size(); i++) { -restart: - const RTLIL::SigChunk &ch1 = chunks_[i]; - if (chunks_[i].wire != NULL) - for (size_t j = 0; j < pattern.chunks_.size(); j++) { - const RTLIL::SigChunk &ch2 = pattern.chunks_[j]; - assert(ch2.wire != NULL); - if (ch1.wire == ch2.wire) { - int lower = std::max(ch1.offset, ch2.offset); - int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width); - if (lower < upper) { - if (other) - other->remove(pos+lower-ch1.offset, upper-lower); - remove(pos+lower-ch1.offset, upper-lower); - if (i == chunks_.size()) - break; - goto restart; - } - } - } - pos += chunks_[i].width; + if (other != NULL) { + assert(width_ == other->width_); + other->unpack(); } + + std::set pattern_bits = pattern.to_sigbit_set(); + std::vector new_bits, new_other_bits; + + for (int i = 0; i < SIZE(bits_); i++) { + if (bits_[i].wire != NULL && pattern_bits.count(bits_[i])) + continue; + if (other != NULL) + new_other_bits.push_back(other->bits_[i]); + new_bits.push_back(bits_[i]); + } + + bits_.swap(new_bits); + width_ = SIZE(bits_); + + if (other != NULL) { + other->bits_.swap(new_other_bits); + other->width_ = SIZE(other->bits_); + } + check(); } @@ -1705,109 +1677,54 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) { - pack(); - with.pack(); + unpack(); + with.unpack(); - int pos = 0; assert(offset >= 0); assert(with.width_ >= 0); assert(offset+with.width_ <= width_); - remove(offset, with.width_); - for (size_t i = 0; i < chunks_.size(); i++) { - if (pos == offset) { - chunks_.insert(chunks_.begin()+i, with.chunks_.begin(), with.chunks_.end()); - width_ += with.width_; - check(); - return; - } - pos += chunks_[i].width; - } - assert(pos == offset); - chunks_.insert(chunks_.end(), with.chunks_.begin(), with.chunks_.end()); - width_ += with.width_; + + for (int i = 0; i < with.width_; i++) + bits_.at(offset + i) = with.bits_.at(i); + check(); } void RTLIL::SigSpec::remove_const() { - pack(); - for (size_t i = 0; i < chunks_.size(); i++) { - if (chunks_[i].wire != NULL) - continue; - width_ -= chunks_[i].width; - chunks_.erase(chunks_.begin() + (i--)); - } + unpack(); + + std::vector new_bits; + new_bits.reserve(width_); + + for (auto &bit : bits_) + if (bit.wire != NULL) + new_bits.push_back(bit); + + bits_.swap(new_bits); + width_ = bits_.size(); + check(); } void RTLIL::SigSpec::remove(int offset, int length) { - pack(); - int pos = 0; + unpack(); + assert(offset >= 0); assert(length >= 0); - assert(offset+length <= width_); - for (size_t i = 0; i < chunks_.size(); i++) { - int orig_width = chunks_[i].width; - if (pos+chunks_[i].width > offset && pos < offset+length) { - int off = offset - pos; - int len = length; - if (off < 0) { - len += off; - off = 0; - } - if (len > chunks_[i].width-off) - len = chunks_[i].width-off; - RTLIL::SigChunk lsb_chunk = chunks_[i].extract(0, off); - RTLIL::SigChunk msb_chunk = chunks_[i].extract(off+len, chunks_[i].width-off-len); - if (lsb_chunk.width == 0 && msb_chunk.width == 0) { - chunks_.erase(chunks_.begin()+i); - i--; - } else if (lsb_chunk.width == 0 && msb_chunk.width != 0) { - chunks_[i] = msb_chunk; - } else if (lsb_chunk.width != 0 && msb_chunk.width == 0) { - chunks_[i] = lsb_chunk; - } else if (lsb_chunk.width != 0 && msb_chunk.width != 0) { - chunks_[i] = lsb_chunk; - chunks_.insert(chunks_.begin()+i+1, msb_chunk); - i++; - } else - assert(0); - width_ -= len; - } - pos += orig_width; - } + assert(offset + length <= width_); + + bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length); + width_ = bits_.size(); + check(); } RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const { - pack(); - int pos = 0; - RTLIL::SigSpec ret; - assert(offset >= 0); - assert(length >= 0); - assert(offset+length <= width_); - for (size_t i = 0; i < chunks_.size(); i++) { - if (pos+chunks_[i].width > offset && pos < offset+length) { - int off = offset - pos; - int len = length; - if (off < 0) { - len += off; - off = 0; - } - if (len > chunks_[i].width-off) - len = chunks_[i].width-off; - ret.chunks_.push_back(chunks_[i].extract(off, len)); - ret.width_ += len; - offset += len; - length -= len; - } - pos += chunks_[i].width; - } - assert(length == 0); - ret.check(); - return ret; + unpack(); + return std::vector(bits_.begin() + offset, bits_.begin() + offset + length); } void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) @@ -1819,27 +1736,34 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) chunks_.push_back(signal.chunks_[i]); width_ += signal.chunks_[i].width; } + // check(); } void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) { - pack(); - if (chunks_.size() == 0) - chunks_.push_back(bit); - else - if (bit.wire == NULL) - if (chunks_.back().wire == NULL) { - chunks_.back().data.bits.push_back(bit.data); - chunks_.back().width++; - } else - chunks_.push_back(bit); + if (packed()) + { + if (chunks_.size() == 0) + chunks_.push_back(bit); else - if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset) - chunks_.back().width++; + if (bit.wire == NULL) + if (chunks_.back().wire == NULL) { + chunks_.back().data.bits.push_back(bit.data); + chunks_.back().width++; + } else + chunks_.push_back(bit); else - chunks_.push_back(bit); + if (chunks_.back().wire == bit.wire && chunks_.back().offset + chunks_.back().width == bit.offset) + chunks_.back().width++; + else + chunks_.push_back(bit); + } + else + bits_.push_back(bit); + width_++; + // check(); } @@ -1911,23 +1835,30 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed) void RTLIL::SigSpec::check() const { - pack(); - - int w = 0; - for (size_t i = 0; i < chunks_.size(); i++) { - const RTLIL::SigChunk chunk = chunks_[i]; - if (chunk.wire == NULL) { - assert(chunk.offset == 0); - assert(chunk.data.bits.size() == (size_t)chunk.width); - } else { - assert(chunk.offset >= 0); - assert(chunk.width >= 0); - assert(chunk.offset + chunk.width <= chunk.wire->width); - assert(chunk.data.bits.size() == 0); + if (packed()) + { + int w = 0; + for (size_t i = 0; i < chunks_.size(); i++) { + const RTLIL::SigChunk chunk = chunks_[i]; + if (chunk.wire == NULL) { + assert(chunk.offset == 0); + assert(chunk.data.bits.size() == (size_t)chunk.width); + } else { + assert(chunk.offset >= 0); + assert(chunk.width >= 0); + assert(chunk.offset + chunk.width <= chunk.wire->width); + assert(chunk.data.bits.size() == 0); + } + w += chunk.width; } - w += chunk.width; + assert(w == width_); + assert(bits_.empty()); + } + else + { + assert(width_ == SIZE(bits_)); + assert(chunks_.empty()); } - assert(w == width_); } bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const From e7e30f1c86d978131a5f4c6e62b5b8d822696cd1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:52:57 +0200 Subject: [PATCH 365/750] fixed memory leak in fsm_opt --- passes/fsm/fsm_opt.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 367b38eb..d5a9b71f 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -44,8 +44,10 @@ struct FsmOpt char *str = strdup(wire->attributes["\\unused_bits"].decode_string().c_str()); for (char *tok = strtok(str, " "); tok != NULL; tok = strtok(NULL, " ")) { - if (tok[0] && bit == atoi(tok)) + if (tok[0] && bit == atoi(tok)) { + free(str); return true; + } } free(str); From f80da7b41dd9c12d3bd65ceab6c0c6748a70a78c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:54:03 +0200 Subject: [PATCH 366/750] SigSpec refactoring: added RTLIL::SigSpec::operator[] --- kernel/rtlil.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index facd43db..da3a2661 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -522,6 +522,9 @@ public: int size() const { return width_; } + RTLIL::SigBit &operator[](int index) { unpack(); return bits_.at(index); } + const RTLIL::SigBit &operator[](int index) const { unpack(); return bits_.at(index); } + void expand(); void optimize(); RTLIL::SigSpec optimized() const; @@ -540,7 +543,7 @@ public: void remove_const(); RTLIL::SigSpec extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other = NULL) const; - RTLIL::SigSpec extract(int offset, int length) const; + RTLIL::SigSpec extract(int offset, int length = 1) const; void append(const RTLIL::SigSpec &signal); void append_bit(const RTLIL::SigBit &bit); From 65a939cb2767623b95adcd2ec5e783b828c1f9eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:54:39 +0200 Subject: [PATCH 367/750] Fixed memory corruption with new SigSpec API in proc_mux --- passes/proc/proc_mux.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index cd459d94..50ba8fa1 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -68,20 +68,16 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, for (auto comp : compare) { RTLIL::SigSpec sig = signal; - sig.expand(); - comp.expand(); // get rid of don't-care bits assert(sig.size() == comp.size()); for (int i = 0; i < comp.size(); i++) - if (comp.chunks()[i].wire == NULL && comp.chunks()[i].data.bits[0] == RTLIL::State::Sa) { - sig.remove(i, 1); - comp.remove(i--, 1); + if (comp[i] == RTLIL::State::Sa) { + sig.remove(i); + comp.remove(i--); } if (comp.size() == 0) return RTLIL::SigSpec(); - sig.optimize(); - comp.optimize(); if (sig.size() == 1 && comp == RTLIL::SigSpec(1,1)) { From 4a6d234ec7acff085e3c923d3872d0863c766ad1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 23:07:42 +0200 Subject: [PATCH 368/750] SigSpec refactoring: cleanup of old SigSpec usage in fsm_* commands --- passes/fsm/fsm_extract.cc | 31 +++++++++---------------------- passes/fsm/fsm_opt.cc | 12 ++++-------- passes/fsm/fsmdata.h | 14 ++++++-------- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index c3bb1933..dfd025a5 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -43,11 +43,9 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL assign_map.apply(sig); if (sig.is_fully_const()) { - sig.optimize(); - assert(sig.chunks().size() == 1); - if (states.count(sig.chunks()[0].data) == 0) { + if (states.count(sig.as_const()) == 0) { log(" found state code: %s\n", log_signal(sig)); - states[sig.chunks()[0].data] = -1; + states[sig.as_const()] = -1; } return true; } @@ -91,30 +89,19 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State noconst_state, RTLIL::SigSpec dont_care = RTLIL::SigSpec()) { if (dont_care.size() > 0) { - sig.expand(); - for (auto &chunk : sig.chunks_rw()) { - assert(chunk.width == 1); - if (dont_care.extract(chunk).size() > 0) - chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); - } - sig.optimize(); + for (int i = 0; i < SIZE(sig); i++) + if (dont_care.extract(sig[i]).size() > 0) + sig[i] = noconst_state; } ce.assign_map.apply(sig); ce.values_map.apply(sig); - sig.expand(); - for (auto &chunk : sig.chunks_rw()) { - assert(chunk.width == 1); - if (chunk.wire != NULL) - chunk.wire = NULL, chunk.data = RTLIL::Const(noconst_state); - } - sig.optimize(); + for (int i = 0; i < SIZE(sig); i++) + if (sig[i].wire != NULL) + sig[i] = noconst_state; - if (sig.size() == 0) - return RTLIL::Const(); - assert(sig.chunks().size() == 1 && sig.chunks()[0].wire == NULL); - return sig.chunks()[0].data; + return sig.as_const(); } static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_data, std::map &states, int state_in, RTLIL::SigSpec ctrl_in, RTLIL::SigSpec ctrl_out, RTLIL::SigSpec dff_in, RTLIL::SigSpec dont_care) diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index d5a9b71f..efa61245 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -33,18 +33,14 @@ struct FsmOpt bool signal_is_unused(RTLIL::SigSpec sig) { - assert(sig.size() == 1); - sig.optimize(); + RTLIL::SigBit bit = sig.to_single_sigbit(); - RTLIL::Wire *wire = sig.chunks()[0].wire; - int bit = sig.chunks()[0].offset; - - if (!wire || wire->attributes.count("\\unused_bits") == 0) + if (bit.wire == NULL || bit.wire->attributes.count("\\unused_bits") == 0) return false; - char *str = strdup(wire->attributes["\\unused_bits"].decode_string().c_str()); + char *str = strdup(bit.wire->attributes["\\unused_bits"].decode_string().c_str()); for (char *tok = strtok(str, " "); tok != NULL; tok = strtok(NULL, " ")) { - if (tok[0] && bit == atoi(tok)) { + if (tok[0] && bit.offset == atoi(tok)) { free(str); return true; } diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index 718b9704..d0be71c5 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -142,26 +142,24 @@ struct FsmData log("\n"); log(" Input signals:\n"); RTLIL::SigSpec sig_in = cell->connections["\\CTRL_IN"]; - sig_in.expand(); - for (size_t i = 0; i < sig_in.chunks().size(); i++) - log(" %3zd: %s\n", i, log_signal(sig_in.chunks()[i])); + for (int i = 0; i < SIZE(sig_in); i++) + log(" %3zd: %s\n", i, log_signal(sig_in[i])); log("\n"); log(" Output signals:\n"); RTLIL::SigSpec sig_out = cell->connections["\\CTRL_OUT"]; - sig_out.expand(); - for (size_t i = 0; i < sig_out.chunks().size(); i++) - log(" %3zd: %s\n", i, log_signal(sig_out.chunks()[i])); + for (int i = 0; i < SIZE(sig_out); i++) + log(" %3zd: %s\n", i, log_signal(sig_out[i])); log("\n"); log(" State encoding:\n"); - for (size_t i = 0; i < state_table.size(); i++) + for (int i = 0; i < SIZE(state_table); i++) log(" %3zd: %10s%s\n", i, log_signal(state_table[i], false), int(i) == reset_state ? " " : ""); log("\n"); log(" Transition Table (state_in, ctrl_in, state_out, ctrl_out):\n"); - for (size_t i = 0; i < transition_table.size(); i++) { + for (int i = 0; i < SIZE(transition_table); i++) { transition_t &tr = transition_table[i]; log(" %5zd: %5d %s -> %5d %s\n", i, tr.state_in, log_signal(tr.ctrl_in), tr.state_out, log_signal(tr.ctrl_out)); } From 9e94f41b89bca54f8a3ce2e8e54c0467a7e8c43d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 23:49:26 +0200 Subject: [PATCH 369/750] SigSpec refactoring: Added RTLIL::SigSpecIterator --- kernel/rtlil.h | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index da3a2661..53770088 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -69,6 +69,7 @@ namespace RTLIL struct Cell; struct SigChunk; struct SigBit; + struct SigSpecIterator; struct SigSpec; struct CaseRule; struct SwitchRule; @@ -494,6 +495,14 @@ struct RTLIL::SigBit { } }; +struct RTLIL::SigSpecIterator { + RTLIL::SigSpec *sig_p; + int index; + inline RTLIL::SigBit &operator*() const; + inline bool operator!=(const RTLIL::SigSpecIterator &other) { return index != other.index; } + inline void operator++() { index++; } +}; + struct RTLIL::SigSpec { private: std::vector chunks_; // LSB at index 0 @@ -504,6 +513,11 @@ private: void unpack() const; bool packed() const; + inline void inline_unpack() const { + if (!chunks_.empty()) + unpack(); + } + public: SigSpec(); SigSpec(const RTLIL::Const &data); @@ -513,17 +527,21 @@ public: SigSpec(int val, int width = 32); SigSpec(RTLIL::State bit, int width = 1); SigSpec(RTLIL::SigBit bit, int width = 1); + SigSpec(std::vector chunks); SigSpec(std::vector bits); SigSpec(std::set bits); - std::vector &chunks_rw() { pack(); return chunks_; } - const std::vector &chunks() const { pack(); return chunks_; } - const std::vector &bits() const { unpack(); return bits_; } + inline std::vector &chunks_rw() { pack(); return chunks_; } + inline const std::vector &chunks() const { pack(); return chunks_; } + inline const std::vector &bits() const { inline_unpack(); return bits_; } - int size() const { return width_; } + inline int size() const { return width_; } - RTLIL::SigBit &operator[](int index) { unpack(); return bits_.at(index); } - const RTLIL::SigBit &operator[](int index) const { unpack(); return bits_.at(index); } + inline RTLIL::SigBit &operator[](int index) { inline_unpack(); return bits_.at(index); } + inline const RTLIL::SigBit &operator[](int index) const { inline_unpack(); return bits_.at(index); } + + inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; } + inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; } void expand(); void optimize(); @@ -582,6 +600,10 @@ public: void check() const; }; +inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { + return (*sig_p)[index]; +} + inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { assert(sig.size() == 1 && sig.chunks().size() == 1); *this = SigBit(sig.chunks()[0]); From 115dd959d9dbf68aa30f8374df0e62fba8646f1e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 23:50:21 +0200 Subject: [PATCH 370/750] SigSpec refactoring: More cleanups of old SigSpec use pattern --- frontends/ast/genrtlil.cc | 9 ++-- kernel/rtlil.cc | 12 ++++- kernel/sigtools.h | 93 ++++++++++++++++----------------------- 3 files changed, 56 insertions(+), 58 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index a51064c3..18ae008c 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 diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d4601405..6757d5dc 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -801,9 +801,11 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const RTLIL::Module *mod; void operator()(RTLIL::SigSpec &sig) { - for (auto &c : sig.chunks_rw()) + std::vector chunks = sig.chunks(); + for (auto &c : chunks) if (c.wire != NULL) c.wire = mod->wires.at(c.wire->name); + sig = chunks; } }; @@ -1469,6 +1471,14 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) check(); } +RTLIL::SigSpec::SigSpec(std::vector chunks) +{ + width_ = 0; + for (auto &c : chunks) + append(c); + check(); +} + RTLIL::SigSpec::SigSpec(std::vector bits) { width_ = 0; diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 826f8417..e93780b4 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -276,7 +276,7 @@ struct SigMap typedef std::pair bitDef_t; struct shared_bit_data_t { - RTLIL::SigChunk chunk; + RTLIL::SigBit map_to; std::set bits; }; @@ -304,7 +304,7 @@ struct SigMap clear(); for (auto &bit : other.bits) { bits[bit.first] = new shared_bit_data_t; - bits[bit.first]->chunk = bit.second->chunk; + bits[bit.first]->map_to = bit.second->map_to; bits[bit.first]->bits = bit.second->bits; } } @@ -337,24 +337,22 @@ struct SigMap } // internal helper function - void register_bit(const RTLIL::SigChunk &c) + void register_bit(const RTLIL::SigBit &b) { - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - if (c.wire && bits.count(bit) == 0) { + bitDef_t bit(b.wire, b.offset); + if (b.wire && bits.count(bit) == 0) { shared_bit_data_t *bd = new shared_bit_data_t; - bd->chunk = c; + bd->map_to = b; bd->bits.insert(bit); bits[bit] = bd; } } // internal helper function - void unregister_bit(const RTLIL::SigChunk &c) + void unregister_bit(const RTLIL::SigBit &b) { - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - if (c.wire && bits.count(bit) > 0) { + bitDef_t bit(b.wire, b.offset); + if (b.wire && bits.count(bit) > 0) { shared_bit_data_t *bd = bits[bit]; bd->bits.erase(bit); if (bd->bits.size() == 0) @@ -364,13 +362,12 @@ struct SigMap } // internal helper function - void merge_bit(const RTLIL::SigChunk &c1, const RTLIL::SigChunk &c2) + void merge_bit(const RTLIL::SigBit &bit1, const RTLIL::SigBit &bit2) { - assert(c1.wire != NULL && c2.wire != NULL); - assert(c1.width == 1 && c2.width == 1); + assert(bit1.wire != NULL && bit2.wire != NULL); - bitDef_t b1(c1.wire, c1.offset); - bitDef_t b2(c2.wire, c2.offset); + bitDef_t b1(bit1.wire, bit1.offset); + bitDef_t b2(bit2.wire, bit2.offset); shared_bit_data_t *bd1 = bits[b1]; shared_bit_data_t *bd2 = bits[b2]; @@ -388,7 +385,7 @@ struct SigMap } else { - bd1->chunk = bd2->chunk; + bd1->map_to = bd2->map_to; for (auto &bit : bd2->bits) bits[bit] = bd1; bd1->bits.insert(bd2->bits.begin(), bd2->bits.end()); @@ -397,74 +394,62 @@ struct SigMap } // internal helper function - void set_bit(const RTLIL::SigChunk &c1, const RTLIL::SigChunk &c2) + void set_bit(const RTLIL::SigBit &b1, const RTLIL::SigBit &b2) { - assert(c1.wire != NULL); - assert(c1.width == 1 && c2.width == 1); - bitDef_t bit(c1.wire, c1.offset); + assert(b1.wire != NULL); + bitDef_t bit(b1.wire, b1.offset); assert(bits.count(bit) > 0); - bits[bit]->chunk = c2; + bits[bit]->map_to = b2; } // internal helper function - void map_bit(RTLIL::SigChunk &c) const + void map_bit(RTLIL::SigBit &b) const { - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - if (c.wire && bits.count(bit) > 0) - c = bits.at(bit)->chunk; + bitDef_t bit(b.wire, b.offset); + if (b.wire && bits.count(bit) > 0) + b = bits.at(bit)->map_to; } void add(RTLIL::SigSpec from, RTLIL::SigSpec to) { - from.expand(); - to.expand(); + assert(SIZE(from) == SIZE(to)); - assert(from.chunks().size() == to.chunks().size()); - for (size_t i = 0; i < from.chunks().size(); i++) + for (int i = 0; i < SIZE(from); i++) { - const RTLIL::SigChunk &cf = from.chunks()[i]; - const RTLIL::SigChunk &ct = to.chunks()[i]; + RTLIL::SigBit &bf = from[i]; + RTLIL::SigBit &bt = to[i]; - if (cf.wire == NULL) + if (bf.wire == NULL) continue; - register_bit(cf); - register_bit(ct); + register_bit(bf); + register_bit(bt); - if (ct.wire != NULL) - merge_bit(cf, ct); + if (bt.wire != NULL) + merge_bit(bf, bt); else - set_bit(cf, ct); + set_bit(bf, bt); } } void add(RTLIL::SigSpec sig) { - sig.expand(); - for (size_t i = 0; i < sig.chunks().size(); i++) - { - const RTLIL::SigChunk &c = sig.chunks()[i]; - if (c.wire != NULL) { - register_bit(c); - set_bit(c, c); - } + for (auto &bit : sig) { + register_bit(bit); + set_bit(bit, bit); } } void del(RTLIL::SigSpec sig) { - sig.expand(); - for (auto &c : sig.chunks()) - unregister_bit(c); + for (auto &bit : sig) + unregister_bit(bit); } void apply(RTLIL::SigSpec &sig) const { - sig.expand(); - for (auto &c : sig.chunks_rw()) - map_bit(c); - sig.optimize(); + for (auto &bit : sig) + map_bit(bit); } RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const From c61467a32c4bd3ec4b9e0cb6d36d602f0e4dea81 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 08:59:54 +0200 Subject: [PATCH 371/750] Some cleanups in RTLIL::SigChunk::SigChunk(const RTLIL::Const&) --- kernel/rtlil.cc | 8 ++++---- kernel/rtlil.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 6757d5dc..2ab4a8c6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1316,10 +1316,10 @@ RTLIL::SigChunk::SigChunk() offset = 0; } -RTLIL::SigChunk::SigChunk(const RTLIL::Const &data) +RTLIL::SigChunk::SigChunk(const RTLIL::Const &value) { wire = NULL; - this->data = data; + data = value; width = data.bits.size(); offset = 0; } @@ -1418,9 +1418,9 @@ RTLIL::SigSpec::SigSpec() width_ = 0; } -RTLIL::SigSpec::SigSpec(const RTLIL::Const &data) +RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) { - chunks_.push_back(RTLIL::SigChunk(data)); + chunks_.push_back(RTLIL::SigChunk(value)); width_ = chunks_.back().width; check(); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 53770088..0e74c958 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -461,7 +461,7 @@ struct RTLIL::SigChunk { RTLIL::Const data; // only used if wire == NULL, LSB at index 0 int width, offset; SigChunk(); - SigChunk(const RTLIL::Const &data); + SigChunk(const RTLIL::Const &value); SigChunk(RTLIL::Wire *wire, int width, int offset); SigChunk(const std::string &str); SigChunk(int val, int width = 32); @@ -520,7 +520,7 @@ private: public: SigSpec(); - SigSpec(const RTLIL::Const &data); + SigSpec(const RTLIL::Const &value); SigSpec(const RTLIL::SigChunk &chunk); SigSpec(RTLIL::Wire *wire, int width = -1, int offset = 0); SigSpec(const std::string &str); From 260c19ec5a3adb292158658dd69a352b9325ab64 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 09:00:16 +0200 Subject: [PATCH 372/750] Refactoring {SigSpec|SigChunk}(RTLIL::Wire *wire, ..) constructor -- step 1/3 --- kernel/rtlil.cc | 32 ++++++++++++++++++++++++++++++++ kernel/rtlil.h | 10 ++++++++-- passes/abc/abc.cc | 2 +- passes/sat/share.cc | 8 ++++---- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2ab4a8c6..acfba057 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1324,6 +1324,13 @@ RTLIL::SigChunk::SigChunk(const RTLIL::Const &value) offset = 0; } +RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire) +{ + this->wire = wire; + this->width = wire->width; + this->offset = 0; +} + RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int width, int offset) { this->wire = wire; @@ -1331,6 +1338,15 @@ RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int width, int offset) this->offset = offset; } +RTLIL::SigChunk RTLIL::SigChunk::grml(RTLIL::Wire *wire, int offset, int width) +{ + RTLIL::SigChunk chunk; + chunk.wire = wire; + chunk.width = width; + chunk.offset = offset; + return chunk; +} + RTLIL::SigChunk::SigChunk(const std::string &str) { wire = NULL; @@ -1432,6 +1448,13 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) check(); } +RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) +{ + chunks_.push_back(RTLIL::SigChunk(wire)); + width_ = chunks_.back().width; + check(); +} + RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int width, int offset) { chunks_.push_back(RTLIL::SigChunk(wire, width, offset)); @@ -1439,6 +1462,15 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int width, int offset) check(); } +RTLIL::SigSpec RTLIL::SigSpec::grml(RTLIL::Wire *wire, int offset, int width) +{ + RTLIL::SigSpec sig; + sig.chunks_.push_back(RTLIL::SigChunk::grml(wire, offset, width)); + sig.width_ = sig.chunks_.back().width; + sig.check(); + return sig; +} + RTLIL::SigSpec::SigSpec(const std::string &str) { chunks_.push_back(RTLIL::SigChunk(str)); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0e74c958..542e685d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -462,7 +462,10 @@ struct RTLIL::SigChunk { int width, offset; SigChunk(); SigChunk(const RTLIL::Const &value); - SigChunk(RTLIL::Wire *wire, int width, int offset); + SigChunk(RTLIL::Wire *wire); + SigChunk(RTLIL::Wire *wire, int width); // <-- using this will cause a linker error + SigChunk(RTLIL::Wire *wire, int width, int offset) __attribute__((deprecated)); + static SigChunk grml(RTLIL::Wire *wire, int offset, int width = 1); SigChunk(const std::string &str); SigChunk(int val, int width = 32); SigChunk(RTLIL::State bit, int width = 1); @@ -522,7 +525,10 @@ public: SigSpec(); SigSpec(const RTLIL::Const &value); SigSpec(const RTLIL::SigChunk &chunk); - SigSpec(RTLIL::Wire *wire, int width = -1, int offset = 0); + SigSpec(RTLIL::Wire *wire); + SigSpec(RTLIL::Wire *wire, int width); // <-- using this will cause a linker error + SigSpec(RTLIL::Wire *wire, int width, int offset) __attribute__((deprecated)); + static SigSpec grml(RTLIL::Wire *wire, int offset, int width = 1); SigSpec(const std::string &str); SigSpec(int val, int width = 32); SigSpec(RTLIL::State bit, int width = 1); diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 2d921b7b..e7371ec5 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -466,7 +466,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std clk_str = clk_str.substr(1); } if (module->wires.count(RTLIL::escape_id(clk_str)) != 0) - clk_sig = assign_map(RTLIL::SigSpec(module->wires.at(RTLIL::escape_id(clk_str)), 1)); + clk_sig = assign_map(RTLIL::SigSpec(module->wires.at(RTLIL::escape_id(clk_str)), 1, 0)); } if (dff_mode && clk_sig.size() == 0) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 738b0bd6..724bc3f9 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -292,8 +292,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; module->add(supercell); - RTLIL::SigSpec new_y1(y, y1.size()); - RTLIL::SigSpec new_y2(y, y2.size()); + RTLIL::SigSpec new_y1(y, y1.size(), 0); + RTLIL::SigSpec new_y2(y, y2.size(), 0); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -405,8 +405,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; supercell->check(); - RTLIL::SigSpec new_y1(y, y1.size()); - RTLIL::SigSpec new_y2(y, y2.size()); + RTLIL::SigSpec new_y1(y, y1.size(), 0); + RTLIL::SigSpec new_y2(y, y2.size(), 0); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); From a8d3a68971ccc4e47c54a906aae374a9a54b1415 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 08:40:31 +0200 Subject: [PATCH 373/750] Refactoring {SigSpec|SigChunk}(RTLIL::Wire *wire, ..) constructor -- step 2/3 --- backends/blif/blif.cc | 4 ++-- backends/edif/edif.cc | 2 +- frontends/ilang/parser.y | 4 ++-- kernel/rtlil.cc | 18 ++---------------- kernel/sigtools.h | 4 ++-- passes/abc/abc.cc | 2 +- passes/fsm/fsm_map.cc | 16 ++++++++-------- passes/memory/memory_share.cc | 2 +- passes/opt/opt_clean.cc | 2 +- passes/proc/proc_mux.cc | 4 ++-- passes/sat/eval.cc | 4 ++-- passes/sat/miter.cc | 2 +- passes/sat/share.cc | 10 +++++----- passes/techmap/extract.cc | 2 +- passes/techmap/iopadmap.cc | 4 ++-- 15 files changed, 33 insertions(+), 47 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 90d1b3fc..edb6809e 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -118,7 +118,7 @@ struct BlifDumper for (auto &it : inputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i))); + fprintf(f, " %s", cstr(RTLIL::SigSpec::grml(wire, i))); } fprintf(f, "\n"); @@ -126,7 +126,7 @@ struct BlifDumper for (auto &it : outputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, 1, i))); + fprintf(f, " %s", cstr(RTLIL::SigSpec::grml(wire, i))); } fprintf(f, "\n"); diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index bb2b26e2..f003c750 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -271,7 +271,7 @@ struct EdifBackend : public Backend { } else { fprintf(f, " (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir); for (int i = 0; i < wire->width; i++) { - RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, 1, i)); + RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec::grml(wire, i)); net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), i)); } } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e4d12f3a..dcb51d44 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 '}' { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index acfba057..f5b84bc6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1331,13 +1331,6 @@ RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire) this->offset = 0; } -RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int width, int offset) -{ - this->wire = wire; - this->width = width >= 0 ? width : wire->width; - this->offset = offset; -} - RTLIL::SigChunk RTLIL::SigChunk::grml(RTLIL::Wire *wire, int offset, int width) { RTLIL::SigChunk chunk; @@ -1455,13 +1448,6 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) check(); } -RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int width, int offset) -{ - chunks_.push_back(RTLIL::SigChunk(wire, width, offset)); - width_ = chunks_.back().width; - check(); -} - RTLIL::SigSpec RTLIL::SigSpec::grml(RTLIL::Wire *wire, int offset, int width) { RTLIL::SigSpec sig; @@ -2166,7 +2152,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri std::vector index_tokens; sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':'); if (index_tokens.size() == 1) - sig.append(RTLIL::SigSpec(wire, 1, atoi(index_tokens.at(0).c_str()))); + sig.append(RTLIL::SigSpec::grml(wire, atoi(index_tokens.at(0).c_str()))); else { int a = atoi(index_tokens.at(0).c_str()); int b = atoi(index_tokens.at(1).c_str()); @@ -2174,7 +2160,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri int tmp = a; a = b, b = tmp; } - sig.append(RTLIL::SigSpec(wire, b-a+1, a)); + sig.append(RTLIL::SigSpec::grml(wire, a, b-a+1)); } } else sig.append(wire); diff --git a/kernel/sigtools.h b/kernel/sigtools.h index e93780b4..d011b0ef 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -144,7 +144,7 @@ struct SigPool { RTLIL::SigSpec sig; for (auto &bit : bits) { - sig.append(RTLIL::SigSpec(bit.first, 1, bit.second)); + sig.append(RTLIL::SigSpec::grml(bit.first, bit.second)); break; } return sig; @@ -154,7 +154,7 @@ struct SigPool { RTLIL::SigSpec sig; for (auto &bit : bits) - sig.append(RTLIL::SigSpec(bit.first, 1, bit.second)); + sig.append(RTLIL::SigSpec::grml(bit.first, bit.second)); sig.sort_and_unify(); return sig; } diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index e7371ec5..fa2c4960 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -466,7 +466,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std clk_str = clk_str.substr(1); } if (module->wires.count(RTLIL::escape_id(clk_str)) != 0) - clk_sig = assign_map(RTLIL::SigSpec(module->wires.at(RTLIL::escape_id(clk_str)), 1, 0)); + clk_sig = assign_map(RTLIL::SigSpec::grml(module->wires.at(RTLIL::escape_id(clk_str)), 0)); } if (dff_mode && clk_sig.size() == 0) diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index f8ffee52..1ac9664a 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -30,7 +30,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapconnections.push_back(RTLIL::SigSig(RTLIL::SigSpec(state_onehot, 1, i), sig_a)); + module->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec::grml(state_onehot, i), sig_a)); } else { @@ -234,7 +234,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) eq_cell->type = "$eq"; eq_cell->connections["\\A"] = sig_a; eq_cell->connections["\\B"] = sig_b; - eq_cell->connections["\\Y"] = RTLIL::SigSpec(state_onehot, 1, i); + eq_cell->connections["\\Y"] = RTLIL::SigSpec::grml(state_onehot, i); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size()); @@ -266,7 +266,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) fullstate_cache.erase(tr.state_in); } - implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec(next_state_onehot, 1, i)); + implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec::grml(next_state_onehot, i)); } if (encoding_is_onehot) @@ -279,7 +279,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) if (state.bits[j] == RTLIL::State::S1) bit_idx = j; if (bit_idx >= 0) - next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, 1, i)); + next_state_sig.replace(bit_idx, RTLIL::SigSpec::grml(next_state_onehot, i)); } log_assert(!next_state_sig.has_marked_bits()); module->connections.push_back(RTLIL::SigSig(next_state_wire, next_state_sig)); @@ -297,7 +297,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) sig_a = RTLIL::SigSpec(state); } else { sig_b.append(RTLIL::SigSpec(state)); - sig_s.append(RTLIL::SigSpec(next_state_onehot, 1, i)); + sig_s.append(RTLIL::SigSpec::grml(next_state_onehot, i)); } } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 5c349f70..45c01f74 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -613,7 +613,7 @@ struct MemoryShareWorker groups_en[key] = grouped_en->width; grouped_en->width++; } - en.append(RTLIL::SigSpec(grouped_en, 1, groups_en[key])); + en.append(RTLIL::SigSpec::grml(grouped_en, groups_en[key])); } module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 68fb2e72..165bb25c 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -189,7 +189,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it : module->wires) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) { - RTLIL::SigSpec s1 = RTLIL::SigSpec(wire, 1, i), s2 = assign_map(s1); + RTLIL::SigSpec s1 = RTLIL::SigSpec::grml(wire, i), s2 = assign_map(s1); if (!compare_signals(s1, s2, register_signals, connected_signals, direct_wires)) assign_map.add(s1); } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 50ba8fa1..0fe76573 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -81,7 +81,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, if (sig.size() == 1 && comp == RTLIL::SigSpec(1,1)) { - mod->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, 1, cmp_wire->width++), sig)); + mod->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec::grml(cmp_wire, cmp_wire->width++), sig)); } else { @@ -103,7 +103,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, eq_cell->connections["\\A"] = sig; eq_cell->connections["\\B"] = comp; - eq_cell->connections["\\Y"] = RTLIL::SigSpec(cmp_wire, 1, cmp_wire->width++); + eq_cell->connections["\\Y"] = RTLIL::SigSpec::grml(cmp_wire, cmp_wire->width++); } } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 73235e93..91b42812 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -260,8 +260,8 @@ struct VlogHammerReporter for (int i = 0; i < int(inputs.size()); i++) { RTLIL::Wire *wire = module->wires.at(inputs[i]); for (int j = input_widths[i]-1; j >= 0; j--) { - ce.set(RTLIL::SigSpec(wire, 1, j), bits.back()); - recorded_set_vars.append(RTLIL::SigSpec(wire, 1, j)); + ce.set(RTLIL::SigSpec::grml(wire, j), bits.back()); + recorded_set_vars.append(RTLIL::SigSpec::grml(wire, j)); recorded_set_vals.bits.push_back(bits.back()); bits.pop_back(); } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 79857c5e..51cf3ae0 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -174,7 +174,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eqx_cell->parameters["\\Y_WIDTH"] = 1; eqx_cell->parameters["\\A_SIGNED"] = 0; eqx_cell->parameters["\\B_SIGNED"] = 0; - eqx_cell->connections["\\A"] = RTLIL::SigSpec(w2_gold, 1, i); + eqx_cell->connections["\\A"] = RTLIL::SigSpec::grml(w2_gold, i); eqx_cell->connections["\\B"] = RTLIL::State::Sx; eqx_cell->connections["\\Y"] = gold_x.extract(i, 1); miter_module->add(eqx_cell); diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 724bc3f9..c209e8ed 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -292,8 +292,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; module->add(supercell); - RTLIL::SigSpec new_y1(y, y1.size(), 0); - RTLIL::SigSpec new_y2(y, y2.size(), 0); + RTLIL::SigSpec new_y1 = RTLIL::SigSpec::grml(y, 0, y1.size()); + RTLIL::SigSpec new_y2 = RTLIL::SigSpec::grml(y, 0, y2.size()); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -405,8 +405,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; supercell->check(); - RTLIL::SigSpec new_y1(y, y1.size(), 0); - RTLIL::SigSpec new_y2(y, y2.size(), 0); + RTLIL::SigSpec new_y1 = RTLIL::SigSpec::grml(y, 0, y1.size()); + RTLIL::SigSpec new_y2 = RTLIL::SigSpec::grml(y, 0, y2.size()); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -620,7 +620,7 @@ struct ShareWorker RTLIL::Wire *all_cases_wire = module->addWire(NEW_ID, 0); for (auto &p : activation_patterns) { all_cases_wire->width++; - module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec(all_cases_wire, 1, all_cases_wire->width - 1)); + module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec::grml(all_cases_wire, all_cases_wire->width - 1)); } if (all_cases_wire->width == 1) return all_cases_wire; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 5a729808..988917b1 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -315,7 +315,7 @@ namespace RTLIL::Wire *wire = it.second; if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) - sig2port.insert(sigmap(RTLIL::SigSpec(wire, 1, i)), std::pair(wire->name, i)); + sig2port.insert(sigmap(RTLIL::SigSpec::grml(wire, i)), std::pair(wire->name, i)); cell->connections[wire->name] = RTLIL::SigSpec(RTLIL::State::Sz, wire->width); } } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index eb2757f6..2cb76014 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -179,9 +179,9 @@ struct IopadmapPass : public Pass { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = RTLIL::escape_id(celltype); - cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, 1, i); + cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec::grml(wire, i); if (!portname2.empty()) - cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, 1, i); + cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec::grml(new_wire, i); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) From ec923652e2eb721aa16657e54a67666f855c3d65 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 09:48:26 +0200 Subject: [PATCH 374/750] Refactoring {SigSpec|SigChunk}(RTLIL::Wire *wire, ..) constructor -- step 3/3 --- backends/blif/blif.cc | 4 ++-- backends/edif/edif.cc | 2 +- frontends/ilang/parser.y | 4 ++-- kernel/rtlil.cc | 24 ++++++++++-------------- kernel/rtlil.h | 8 ++------ kernel/sigtools.h | 4 ++-- passes/abc/abc.cc | 2 +- passes/fsm/fsm_map.cc | 16 ++++++++-------- passes/memory/memory_share.cc | 2 +- passes/opt/opt_clean.cc | 2 +- passes/proc/proc_mux.cc | 4 ++-- passes/sat/eval.cc | 4 ++-- passes/sat/miter.cc | 2 +- passes/sat/share.cc | 10 +++++----- passes/techmap/extract.cc | 2 +- passes/techmap/iopadmap.cc | 4 ++-- 16 files changed, 43 insertions(+), 51 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index edb6809e..a240d2a2 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -118,7 +118,7 @@ struct BlifDumper for (auto &it : inputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - fprintf(f, " %s", cstr(RTLIL::SigSpec::grml(wire, i))); + fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, i))); } fprintf(f, "\n"); @@ -126,7 +126,7 @@ struct BlifDumper for (auto &it : outputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - fprintf(f, " %s", cstr(RTLIL::SigSpec::grml(wire, i))); + fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, i))); } fprintf(f, "\n"); diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index f003c750..74cf2499 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -271,7 +271,7 @@ struct EdifBackend : public Backend { } else { fprintf(f, " (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir); for (int i = 0; i < wire->width; i++) { - RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec::grml(wire, i)); + RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, i)); net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), i)); } } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index dcb51d44..3fe5199f 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 '}' { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f5b84bc6..6bb3e612 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1331,13 +1331,11 @@ RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire) this->offset = 0; } -RTLIL::SigChunk RTLIL::SigChunk::grml(RTLIL::Wire *wire, int offset, int width) +RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int offset, int width) { - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = width; - chunk.offset = offset; - return chunk; + this->wire = wire; + this->width = width; + this->offset = offset; } RTLIL::SigChunk::SigChunk(const std::string &str) @@ -1448,13 +1446,11 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) check(); } -RTLIL::SigSpec RTLIL::SigSpec::grml(RTLIL::Wire *wire, int offset, int width) +RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width) { - RTLIL::SigSpec sig; - sig.chunks_.push_back(RTLIL::SigChunk::grml(wire, offset, width)); - sig.width_ = sig.chunks_.back().width; - sig.check(); - return sig; + chunks_.push_back(RTLIL::SigChunk(wire, offset, width)); + width_ = chunks_.back().width; + check(); } RTLIL::SigSpec::SigSpec(const std::string &str) @@ -2152,7 +2148,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri std::vector index_tokens; sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':'); if (index_tokens.size() == 1) - sig.append(RTLIL::SigSpec::grml(wire, atoi(index_tokens.at(0).c_str()))); + sig.append(RTLIL::SigSpec(wire, atoi(index_tokens.at(0).c_str()))); else { int a = atoi(index_tokens.at(0).c_str()); int b = atoi(index_tokens.at(1).c_str()); @@ -2160,7 +2156,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri int tmp = a; a = b, b = tmp; } - sig.append(RTLIL::SigSpec::grml(wire, a, b-a+1)); + sig.append(RTLIL::SigSpec(wire, a, b-a+1)); } } else sig.append(wire); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 542e685d..83214659 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -463,9 +463,7 @@ struct RTLIL::SigChunk { SigChunk(); SigChunk(const RTLIL::Const &value); SigChunk(RTLIL::Wire *wire); - SigChunk(RTLIL::Wire *wire, int width); // <-- using this will cause a linker error - SigChunk(RTLIL::Wire *wire, int width, int offset) __attribute__((deprecated)); - static SigChunk grml(RTLIL::Wire *wire, int offset, int width = 1); + SigChunk(RTLIL::Wire *wire, int offset, int width = 1); SigChunk(const std::string &str); SigChunk(int val, int width = 32); SigChunk(RTLIL::State bit, int width = 1); @@ -526,9 +524,7 @@ public: SigSpec(const RTLIL::Const &value); SigSpec(const RTLIL::SigChunk &chunk); SigSpec(RTLIL::Wire *wire); - SigSpec(RTLIL::Wire *wire, int width); // <-- using this will cause a linker error - SigSpec(RTLIL::Wire *wire, int width, int offset) __attribute__((deprecated)); - static SigSpec grml(RTLIL::Wire *wire, int offset, int width = 1); + SigSpec(RTLIL::Wire *wire, int offset, int width = 1); SigSpec(const std::string &str); SigSpec(int val, int width = 32); SigSpec(RTLIL::State bit, int width = 1); diff --git a/kernel/sigtools.h b/kernel/sigtools.h index d011b0ef..cd179ebf 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -144,7 +144,7 @@ struct SigPool { RTLIL::SigSpec sig; for (auto &bit : bits) { - sig.append(RTLIL::SigSpec::grml(bit.first, bit.second)); + sig.append(RTLIL::SigSpec(bit.first, bit.second)); break; } return sig; @@ -154,7 +154,7 @@ struct SigPool { RTLIL::SigSpec sig; for (auto &bit : bits) - sig.append(RTLIL::SigSpec::grml(bit.first, bit.second)); + sig.append(RTLIL::SigSpec(bit.first, bit.second)); sig.sort_and_unify(); return sig; } diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index fa2c4960..8cdd39b7 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -466,7 +466,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std clk_str = clk_str.substr(1); } if (module->wires.count(RTLIL::escape_id(clk_str)) != 0) - clk_sig = assign_map(RTLIL::SigSpec::grml(module->wires.at(RTLIL::escape_id(clk_str)), 0)); + clk_sig = assign_map(RTLIL::SigSpec(module->wires.at(RTLIL::escape_id(clk_str)), 0)); } if (dff_mode && clk_sig.size() == 0) diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 1ac9664a..9dda2ba8 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -30,7 +30,7 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapconnections.push_back(RTLIL::SigSig(RTLIL::SigSpec::grml(state_onehot, i), sig_a)); + module->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec(state_onehot, i), sig_a)); } else { @@ -234,7 +234,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) eq_cell->type = "$eq"; eq_cell->connections["\\A"] = sig_a; eq_cell->connections["\\B"] = sig_b; - eq_cell->connections["\\Y"] = RTLIL::SigSpec::grml(state_onehot, i); + eq_cell->connections["\\Y"] = RTLIL::SigSpec(state_onehot, i); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size()); @@ -266,7 +266,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) fullstate_cache.erase(tr.state_in); } - implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec::grml(next_state_onehot, i)); + implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec(next_state_onehot, i)); } if (encoding_is_onehot) @@ -279,7 +279,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) if (state.bits[j] == RTLIL::State::S1) bit_idx = j; if (bit_idx >= 0) - next_state_sig.replace(bit_idx, RTLIL::SigSpec::grml(next_state_onehot, i)); + next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, i)); } log_assert(!next_state_sig.has_marked_bits()); module->connections.push_back(RTLIL::SigSig(next_state_wire, next_state_sig)); @@ -297,7 +297,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) sig_a = RTLIL::SigSpec(state); } else { sig_b.append(RTLIL::SigSpec(state)); - sig_s.append(RTLIL::SigSpec::grml(next_state_onehot, i)); + sig_s.append(RTLIL::SigSpec(next_state_onehot, i)); } } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 45c01f74..38eff996 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -613,7 +613,7 @@ struct MemoryShareWorker groups_en[key] = grouped_en->width; grouped_en->width++; } - en.append(RTLIL::SigSpec::grml(grouped_en, groups_en[key])); + en.append(RTLIL::SigSpec(grouped_en, groups_en[key])); } module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 165bb25c..23fc48d5 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -189,7 +189,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it : module->wires) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) { - RTLIL::SigSpec s1 = RTLIL::SigSpec::grml(wire, i), s2 = assign_map(s1); + RTLIL::SigSpec s1 = RTLIL::SigSpec(wire, i), s2 = assign_map(s1); if (!compare_signals(s1, s2, register_signals, connected_signals, direct_wires)) assign_map.add(s1); } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 0fe76573..804c51fd 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -81,7 +81,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, if (sig.size() == 1 && comp == RTLIL::SigSpec(1,1)) { - mod->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec::grml(cmp_wire, cmp_wire->width++), sig)); + mod->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, cmp_wire->width++), sig)); } else { @@ -103,7 +103,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, eq_cell->connections["\\A"] = sig; eq_cell->connections["\\B"] = comp; - eq_cell->connections["\\Y"] = RTLIL::SigSpec::grml(cmp_wire, cmp_wire->width++); + eq_cell->connections["\\Y"] = RTLIL::SigSpec(cmp_wire, cmp_wire->width++); } } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 91b42812..902dedb6 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -260,8 +260,8 @@ struct VlogHammerReporter for (int i = 0; i < int(inputs.size()); i++) { RTLIL::Wire *wire = module->wires.at(inputs[i]); for (int j = input_widths[i]-1; j >= 0; j--) { - ce.set(RTLIL::SigSpec::grml(wire, j), bits.back()); - recorded_set_vars.append(RTLIL::SigSpec::grml(wire, j)); + ce.set(RTLIL::SigSpec(wire, j), bits.back()); + recorded_set_vars.append(RTLIL::SigSpec(wire, j)); recorded_set_vals.bits.push_back(bits.back()); bits.pop_back(); } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 51cf3ae0..12384e2c 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -174,7 +174,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eqx_cell->parameters["\\Y_WIDTH"] = 1; eqx_cell->parameters["\\A_SIGNED"] = 0; eqx_cell->parameters["\\B_SIGNED"] = 0; - eqx_cell->connections["\\A"] = RTLIL::SigSpec::grml(w2_gold, i); + eqx_cell->connections["\\A"] = RTLIL::SigSpec(w2_gold, i); eqx_cell->connections["\\B"] = RTLIL::State::Sx; eqx_cell->connections["\\Y"] = gold_x.extract(i, 1); miter_module->add(eqx_cell); diff --git a/passes/sat/share.cc b/passes/sat/share.cc index c209e8ed..ede2fa88 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -292,8 +292,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; module->add(supercell); - RTLIL::SigSpec new_y1 = RTLIL::SigSpec::grml(y, 0, y1.size()); - RTLIL::SigSpec new_y2 = RTLIL::SigSpec::grml(y, 0, y2.size()); + RTLIL::SigSpec new_y1(y, 0, y1.size()); + RTLIL::SigSpec new_y2(y, 0, y2.size()); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -405,8 +405,8 @@ struct ShareWorker supercell->connections["\\Y"] = y; supercell->check(); - RTLIL::SigSpec new_y1 = RTLIL::SigSpec::grml(y, 0, y1.size()); - RTLIL::SigSpec new_y2 = RTLIL::SigSpec::grml(y, 0, y2.size()); + RTLIL::SigSpec new_y1(y, 0, y1.size()); + RTLIL::SigSpec new_y2(y, 0, y2.size()); module->connections.push_back(RTLIL::SigSig(y1, new_y1)); module->connections.push_back(RTLIL::SigSig(y2, new_y2)); @@ -620,7 +620,7 @@ struct ShareWorker RTLIL::Wire *all_cases_wire = module->addWire(NEW_ID, 0); for (auto &p : activation_patterns) { all_cases_wire->width++; - module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec::grml(all_cases_wire, all_cases_wire->width - 1)); + module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec(all_cases_wire, all_cases_wire->width - 1)); } if (all_cases_wire->width == 1) return all_cases_wire; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 988917b1..1687a1ff 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -315,7 +315,7 @@ namespace RTLIL::Wire *wire = it.second; if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) - sig2port.insert(sigmap(RTLIL::SigSpec::grml(wire, i)), std::pair(wire->name, i)); + sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair(wire->name, i)); cell->connections[wire->name] = RTLIL::SigSpec(RTLIL::State::Sz, wire->width); } } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 2cb76014..09147383 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -179,9 +179,9 @@ struct IopadmapPass : public Pass { RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = RTLIL::escape_id(celltype); - cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec::grml(wire, i); + cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, i); if (!portname2.empty()) - cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec::grml(new_wire, i); + cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, i); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) From 85db102e13bbd6decda3f99ef640d0991ee24b33 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 15:35:09 +0200 Subject: [PATCH 375/750] Replaced RTLIL::SigSpec::operator!=() with inline version --- kernel/rtlil.cc | 7 ------- kernel/rtlil.h | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 6bb3e612..f907ff64 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1929,13 +1929,6 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const return true; } -bool RTLIL::SigSpec::operator !=(const RTLIL::SigSpec &other) const -{ - if (*this == other) - return false; - return true; -} - bool RTLIL::SigSpec::is_fully_const() const { pack(); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 83214659..80007ab8 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -575,7 +575,7 @@ public: bool operator <(const RTLIL::SigSpec &other) const; bool operator ==(const RTLIL::SigSpec &other) const; - bool operator !=(const RTLIL::SigSpec &other) const; + inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); } bool is_fully_const() const; bool is_fully_def() const; From 4e802eb7f6fe5858f8657be7cd3e6638cc0f2ece Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 15:36:09 +0200 Subject: [PATCH 376/750] Fixed all users of SigSpec::chunks_rw() and removed it --- kernel/rtlil.h | 4 +-- passes/cmds/delete.cc | 5 +-- passes/cmds/setundef.cc | 63 ++++++++++++++++++------------------- passes/cmds/splitnets.cc | 8 ++--- passes/hierarchy/submod.cc | 8 ++--- passes/memory/memory_dff.cc | 12 +++---- passes/proc/proc_arst.cc | 8 ++--- passes/sat/eval.cc | 14 ++++----- passes/techmap/extract.cc | 6 ++-- passes/techmap/hilomap.cc | 26 +++++++-------- passes/techmap/techmap.cc | 17 +++++----- 11 files changed, 80 insertions(+), 91 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 80007ab8..e1c5b1a6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -533,7 +533,6 @@ public: SigSpec(std::vector bits); SigSpec(std::set bits); - inline std::vector &chunks_rw() { pack(); return chunks_; } inline const std::vector &chunks() const { pack(); return chunks_; } inline const std::vector &bits() const { inline_unpack(); return bits_; } @@ -597,7 +596,8 @@ public: static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str); static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); - operator std::vector() const { return to_sigbit_vector(); } + operator std::vector() const { return chunks(); } + operator std::vector() const { return bits(); } void check() const; }; diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index f433c4b4..7fe95b0a 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -27,12 +27,13 @@ struct DeleteWireWorker std::set *delete_wires_p; void operator()(RTLIL::SigSpec &sig) { - sig.optimize(); - for (auto &c : sig.chunks_rw()) + std::vector chunks = sig; + for (auto &c : chunks) if (c.wire != NULL && delete_wires_p->count(c.wire->name)) { c.wire = module->addWire(NEW_ID, c.width); c.offset = 0; } + sig = chunks; } }; diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 619930b3..63d5bb9a 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -23,35 +23,33 @@ #include "kernel/rtlil.h" #include "kernel/log.h" -static int next_bit_mode; -static uint32_t next_bit_state; - -static RTLIL::State next_bit() -{ - if (next_bit_mode == 0) - return RTLIL::State::S0; - - if (next_bit_mode == 1) - return RTLIL::State::S1; - - // xorshift32 - next_bit_state ^= next_bit_state << 13; - next_bit_state ^= next_bit_state >> 17; - next_bit_state ^= next_bit_state << 5; - log_assert(next_bit_state != 0); - - return ((next_bit_state >> (next_bit_state & 15)) & 16) ? RTLIL::State::S0 : RTLIL::State::S1; -} - struct SetundefWorker { + int next_bit_mode; + uint32_t next_bit_state; + + RTLIL::State next_bit() + { + if (next_bit_mode == 0) + return RTLIL::State::S0; + + if (next_bit_mode == 1) + return RTLIL::State::S1; + + // xorshift32 + next_bit_state ^= next_bit_state << 13; + next_bit_state ^= next_bit_state >> 17; + next_bit_state ^= next_bit_state << 5; + log_assert(next_bit_state != 0); + + return ((next_bit_state >> (next_bit_state & 15)) & 16) ? RTLIL::State::S0 : RTLIL::State::S1; + } + void operator()(RTLIL::SigSpec &sig) { - sig.expand(); - for (auto &c : sig.chunks_rw()) - if (c.wire == NULL && c.data.bits.at(0) > RTLIL::State::S1) - c.data.bits.at(0) = next_bit(); - sig.optimize(); + for (auto &bit : sig) + if (bit.wire == NULL && bit.data > RTLIL::State::S1) + bit = next_bit(); } }; @@ -83,6 +81,7 @@ struct SetundefPass : public Pass { { bool got_value = false; bool undriven_mode = false; + SetundefWorker worker; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -93,20 +92,20 @@ struct SetundefPass : public Pass { } if (args[argidx] == "-zero") { got_value = true; - next_bit_mode = 0; + worker.next_bit_mode = 0; continue; } if (args[argidx] == "-one") { got_value = true; - next_bit_mode = 1; + worker.next_bit_mode = 1; continue; } if (args[argidx] == "-random" && !got_value && argidx+1 < args.size()) { got_value = true; - next_bit_mode = 2; - next_bit_state = atoi(args[++argidx].c_str()) + 1; + worker.next_bit_mode = 2; + worker.next_bit_state = atoi(args[++argidx].c_str()) + 1; for (int i = 0; i < 10; i++) - next_bit(); + worker.next_bit(); continue; } break; @@ -144,13 +143,13 @@ struct SetundefPass : public Pass { for (auto &c : sig.chunks()) { RTLIL::SigSpec bits; for (int i = 0; i < c.width; i++) - bits.append(next_bit()); + bits.append(worker.next_bit()); bits.optimize(); module->connections.push_back(RTLIL::SigSig(c, bits)); } } - module->rewrite_sigspecs(SetundefWorker()); + module->rewrite_sigspecs(worker); } } } SetundefPass; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index d71e9727..c40ff2c4 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -62,11 +62,9 @@ struct SplitnetsWorker void operator()(RTLIL::SigSpec &sig) { - sig.expand(); - for (auto &c : sig.chunks_rw()) - if (splitmap.count(c.wire) > 0) - c = splitmap.at(c.wire).at(c.offset); - sig.optimize(); + for (auto &bit : sig) + if (splitmap.count(bit.wire) > 0) + bit = splitmap.at(bit.wire).at(bit.offset); } }; diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index b983a840..25730188 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -164,10 +164,10 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new RTLIL::Cell(*cell); for (auto &conn : new_cell->connections) - for (auto &c : conn.second.chunks_rw()) - if (c.wire != NULL) { - assert(wire_flags.count(c.wire) > 0); - c.wire = wire_flags[c.wire].new_wire; + for (auto &bit : conn.second) + if (bit.wire != NULL) { + assert(wire_flags.count(bit.wire) > 0); + bit.wire = wire_flags[bit.wire].new_wire; } log(" cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str()); new_mod->cells[new_cell->name] = new_cell; diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index dee48597..b1f1e22b 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -32,13 +32,10 @@ static void normalize_sig(RTLIL::Module *module, RTLIL::SigSpec &sig) static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, bool after = false) { normalize_sig(module, sig); - sig.expand(); - for (size_t i = 0; i < sig.chunks().size(); i++) + for (auto &bit : sig) { - RTLIL::SigChunk &chunk = sig.chunks_rw()[i]; - - if (chunk.wire == NULL) + if (bit.wire == NULL) continue; for (auto &cell_it : module->cells) @@ -58,12 +55,11 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI RTLIL::SigSpec q_norm = cell->connections[after ? "\\D" : "\\Q"]; normalize_sig(module, q_norm); - RTLIL::SigSpec d = q_norm.extract(chunk, &cell->connections[after ? "\\Q" : "\\D"]); + RTLIL::SigSpec d = q_norm.extract(bit, &cell->connections[after ? "\\Q" : "\\D"]); if (d.size() != 1) continue; - assert(d.chunks().size() == 1); - chunk = d.chunks()[0]; + bit = d; clk = cell->connections["\\CLK"]; clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); goto replaced_this_bit; diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 6cb560f5..145abfa4 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -165,11 +165,9 @@ restart_proc_arst: for (auto &action : sync->actions) { RTLIL::SigSpec rspec = action.second; RTLIL::SigSpec rval = RTLIL::SigSpec(RTLIL::State::Sm, rspec.size()); - rspec.expand(), rval.expand(); - for (int i = 0; i < int(rspec.chunks().size()); i++) - if (rspec.chunks()[i].wire == NULL) - rval.chunks_rw()[i] = rspec.chunks()[i]; - rspec.optimize(), rval.optimize(); + for (int i = 0; i < SIZE(rspec); i++) + if (rspec[i].wire == NULL) + rval[i] = rspec[i]; RTLIL::SigSpec last_rval; for (int count = 0; rval != last_rval; count++) { last_rval = rval; diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 902dedb6..090f7463 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -70,11 +70,9 @@ struct BruteForceEquivChecker log_signal(undef2), log_signal(mod1_inputs), log_signal(inputs)); if (ignore_x_mod1) { - sig1.expand(), sig2.expand(); - for (size_t i = 0; i < sig1.chunks().size(); i++) - if (sig1.chunks().at(i) == RTLIL::SigChunk(RTLIL::State::Sx)) - sig2.chunks_rw().at(i) = RTLIL::SigChunk(RTLIL::State::Sx); - sig1.optimize(), sig2.optimize(); + for (int i = 0; i < SIZE(sig1); i++) + if (sig1[i] == RTLIL::State::Sx) + sig2[i] = RTLIL::State::Sx; } if (sig1 != sig2) { @@ -297,9 +295,9 @@ struct VlogHammerReporter sig.expand(); if (rtl_sig.size() != sig.size()) log_error("Output (y) has a different width in module %s compared to rtl!\n", RTLIL::id2cstr(module->name)); - for (int i = 0; i < sig.size(); i++) - if (rtl_sig.chunks().at(i).data.bits.at(0) == RTLIL::State::Sx) - sig.chunks_rw().at(i).data.bits.at(0) = RTLIL::State::Sx; + for (int i = 0; i < SIZE(sig); i++) + if (rtl_sig[i] == RTLIL::State::Sx) + sig[i] = RTLIL::State::Sx; } log("++RPT++ %d%s %s %s\n", idx, input_pattern_list.c_str(), sig.as_const().as_string().c_str(), module_name.c_str()); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 1687a1ff..e5055c9c 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -755,11 +755,11 @@ struct ExtractPass : public Pass { newCell->type = cell->type; newCell->parameters = cell->parameters; for (auto &conn : cell->connections) { - RTLIL::SigSpec sig = sigmap(conn.second); - for (auto &chunk : sig.chunks_rw()) + std::vector chunks = sigmap(conn.second); + for (auto &chunk : chunks) if (chunk.wire != NULL) chunk.wire = newMod->wires.at(chunk.wire->name); - newCell->connections[conn.first] = sig; + newCell->connections[conn.first] = chunks; } newMod->add(newCell); } diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index 53c5d104..51b8802c 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -26,36 +26,34 @@ static std::string locell_celltype, locell_portname; static bool singleton_mode; static RTLIL::Module *module; -static RTLIL::SigChunk last_hi, last_lo; +static RTLIL::SigBit last_hi, last_lo; void hilomap_worker(RTLIL::SigSpec &sig) { - sig.expand(); - for (auto &c : sig.chunks_rw()) { - if (c.wire == NULL && (c.data.bits.at(0) == RTLIL::State::S1) && !hicell_celltype.empty()) { - if (!singleton_mode || last_hi.width == 0) { - last_hi = RTLIL::SigChunk(module->addWire(NEW_ID)); + for (auto &bit : sig) { + if (bit == RTLIL::State::S1 && !hicell_celltype.empty()) { + if (!singleton_mode || last_hi == RTLIL::State::Sm) { + last_hi = module->addWire(NEW_ID); RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = RTLIL::escape_id(hicell_celltype); cell->connections[RTLIL::escape_id(hicell_portname)] = last_hi; module->add(cell); } - c = last_hi; + bit = last_hi; } - if (c.wire == NULL && (c.data.bits.at(0) == RTLIL::State::S0) && !locell_celltype.empty()) { - if (!singleton_mode || last_lo.width == 0) { - last_lo = RTLIL::SigChunk(module->addWire(NEW_ID)); + if (bit == RTLIL::State::S0 && !locell_celltype.empty()) { + if (!singleton_mode || last_lo == RTLIL::State::Sm) { + last_lo = module->addWire(NEW_ID); RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = RTLIL::escape_id(locell_celltype); cell->connections[RTLIL::escape_id(locell_portname)] = last_lo; module->add(cell); } - c = last_lo; + bit = last_lo; } } - sig.optimize(); } struct HilomapPass : public Pass { @@ -119,8 +117,8 @@ struct HilomapPass : public Pass { if (!design->selected(module)) continue; - last_hi = RTLIL::SigChunk(); - last_lo = RTLIL::SigChunk(); + last_hi = RTLIL::State::Sm; + last_lo = RTLIL::State::Sm; module->rewrite_sigspecs(hilomap_worker); } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index f3b1a0ef..8d7b21e0 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -41,14 +41,15 @@ static void apply_prefix(std::string prefix, std::string &id) static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module *module) { - for (size_t i = 0; i < sig.chunks().size(); i++) { - if (sig.chunks()[i].wire == NULL) - continue; - std::string wire_name = sig.chunks()[i].wire->name; - apply_prefix(prefix, wire_name); - assert(module->wires.count(wire_name) > 0); - sig.chunks_rw()[i].wire = module->wires[wire_name]; - } + std::vector chunks = sig; + for (auto &chunk : chunks) + if (chunk.wire != NULL) { + std::string wire_name = chunk.wire->name; + apply_prefix(prefix, wire_name); + assert(module->wires.count(wire_name) > 0); + chunk.wire = module->wires[wire_name]; + } + sig = chunks; } struct TechmapWorker From 54552f680938fd933b07fa38597937ba6d367be7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 19:30:21 +0200 Subject: [PATCH 377/750] Added eclipse .setting folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f251d2b6..bb50d357 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .*.swp /.cproject /.project +/.settings /qtcreator.files /qtcreator.includes /qtcreator.config From a62c21c9c64ad5b3e0dae5d4ee4857425f73068e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 16:09:27 +0200 Subject: [PATCH 378/750] Removed RTLIL::SigSpec::expand() method --- backends/edif/edif.cc | 9 +- kernel/consteval.h | 7 +- kernel/rtlil.cc | 41 ------ kernel/rtlil.h | 3 - kernel/satgen.h | 10 +- kernel/sigtools.h | 225 ++++++++++++-------------------- manual/CHAPTER_Prog/stubnets.cc | 19 +-- passes/abc/abc.cc | 53 ++++---- passes/opt/opt_clean.cc | 17 +-- passes/opt/opt_const.cc | 14 +- passes/opt/opt_muxtree.cc | 12 +- passes/opt/opt_reduce.cc | 36 ++--- passes/sat/eval.cc | 8 +- passes/sat/sat.cc | 6 +- passes/techmap/extract.cc | 57 ++++---- passes/techmap/simplemap.cc | 143 +++++++------------- 16 files changed, 231 insertions(+), 429 deletions(-) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 74cf2499..3b9a4337 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -306,14 +306,11 @@ struct EdifBackend : public Backend { fprintf(f, ")\n"); for (auto &p : cell->connections) { RTLIL::SigSpec sig = sigmap(p.second); - sig.expand(); - for (int i = 0; i < sig.size(); i++) { - RTLIL::SigSpec sigbit(sig.chunks().at(i)); + for (int i = 0; i < SIZE(sig); i++) if (sig.size() == 1) - net_join_db[sigbit].insert(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name))); + net_join_db[sig[i]].insert(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name))); else - net_join_db[sigbit].insert(stringf("(portRef (member %s %d) (instanceRef %s))", EDIF_REF(p.first), i, EDIF_REF(cell->name))); - } + net_join_db[sig[i]].insert(stringf("(portRef (member %s %d) (instanceRef %s))", EDIF_REF(p.first), i, EDIF_REF(cell->name))); } } for (auto &it : net_join_db) { diff --git a/kernel/consteval.h b/kernel/consteval.h index 5836cdd5..3a8ef44a 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -71,11 +71,8 @@ struct ConstEval assign_map.apply(sig); #ifndef NDEBUG RTLIL::SigSpec current_val = values_map(sig); - current_val.expand(); - for (size_t i = 0; i < current_val.chunks().size(); i++) { - const RTLIL::SigChunk &chunk = current_val.chunks()[i]; - assert(chunk.wire != NULL || chunk.data.bits[0] == value.bits[i]); - } + for (int i = 0; i < SIZE(current_val); i++) + assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]); #endif values_map.add(sig, RTLIL::SigSpec(value)); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f907ff64..7dcf32b7 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1548,18 +1548,6 @@ bool RTLIL::SigSpec::packed() const return bits_.empty(); } -void RTLIL::SigSpec::expand() -{ - pack(); - std::vector new_chunks; - for (size_t i = 0; i < chunks_.size(); i++) { - for (int j = 0; j < chunks_[i].width; j++) - new_chunks.push_back(chunks_[i].extract(j, 1)); - } - chunks_.swap(new_chunks); - check(); -} - void RTLIL::SigSpec::optimize() { pack(); @@ -1791,35 +1779,6 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) // check(); } -bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool do_override) -{ - pack(); - signal.pack(); - - bool no_collisions = true; - - assert(width_ == signal.width_); - expand(); - signal.expand(); - - for (size_t i = 0; i < chunks_.size(); i++) { - bool self_free = chunks_[i].wire == NULL && chunks_[i].data.bits[0] == freeState; - bool other_free = signal.chunks_[i].wire == NULL && signal.chunks_[i].data.bits[0] == freeState; - if (!self_free && !other_free) { - if (do_override) - chunks_[i] = signal.chunks_[i]; - else - chunks_[i] = RTLIL::SigChunk(RTLIL::State::Sx, 1); - no_collisions = false; - } - if (self_free && !other_free) - chunks_[i] = signal.chunks_[i]; - } - - optimize(); - return no_collisions; -} - void RTLIL::SigSpec::extend(int width, bool is_signed) { pack(); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e1c5b1a6..6c0a7b66 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -544,7 +544,6 @@ public: inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; } inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; } - void expand(); void optimize(); RTLIL::SigSpec optimized() const; @@ -567,8 +566,6 @@ public: void append(const RTLIL::SigSpec &signal); void append_bit(const RTLIL::SigBit &bit); - bool combine(RTLIL::SigSpec signal, RTLIL::State freeState = RTLIL::State::Sz, bool do_override = false); - void extend(int width, bool is_signed = false); void extend_u0(int width, bool is_signed = false); diff --git a/kernel/satgen.h b/kernel/satgen.h index 9e227707..ea04cb40 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -52,20 +52,18 @@ struct SatGen { log_assert(!undef_mode || model_undef); sigmap->apply(sig); - sig.expand(); std::vector vec; - vec.reserve(sig.chunks().size()); + vec.reserve(SIZE(sig)); - for (auto &c : sig.chunks()) - if (c.wire == NULL) { - RTLIL::State bit = c.data.bits.at(0); + for (auto &bit : sig) + if (bit.wire == NULL) { if (model_undef && dup_undef && bit == RTLIL::State::Sx) vec.push_back(ez->frozen_literal()); else vec.push_back(bit == (undef_mode ? RTLIL::State::Sx : RTLIL::State::S1) ? ez->TRUE : ez->FALSE); } else { - std::string name = pf + stringf(c.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(c.wire->name), c.offset); + std::string name = pf + stringf(bit.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(bit.wire->name), bit.offset); vec.push_back(ez->frozen_literal(name)); } return vec; diff --git a/kernel/sigtools.h b/kernel/sigtools.h index cd179ebf..1a84194e 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -27,7 +27,11 @@ struct SigPool { - typedef std::pair bitDef_t; + struct bitDef_t : public std::pair { + bitDef_t() : std::pair(NULL, 0) { } + bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } + }; + std::set bits; void clear() @@ -37,14 +41,9 @@ struct SigPool void add(RTLIL::SigSpec sig) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - bits.insert(bit); - } + for (auto &bit : sig) + if (bit.wire != NULL) + bits.insert(bit); } void add(const SigPool &other) @@ -55,14 +54,9 @@ struct SigPool void del(RTLIL::SigSpec sig) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - bits.erase(bit); - } + for (auto &bit : sig) + if (bit.wire != NULL) + bits.erase(bit); } void del(const SigPool &other) @@ -73,15 +67,10 @@ struct SigPool void expand(RTLIL::SigSpec from, RTLIL::SigSpec to) { - from.expand(); - to.expand(); - assert(from.chunks().size() == to.chunks().size()); - for (size_t i = 0; i < from.chunks().size(); i++) { - bitDef_t bit_from(from.chunks()[i].wire, from.chunks()[i].offset); - bitDef_t bit_to(to.chunks()[i].wire, to.chunks()[i].offset); - if (bit_from.first == NULL || bit_to.first == NULL) - continue; - if (bits.count(bit_from) > 0) + assert(SIZE(from) == SIZE(to)); + for (int i = 0; i < SIZE(from); i++) { + bitDef_t bit_from(from[i]), bit_to(to[i]); + if (bit_from.first != NULL && bit_to.first != NULL && bits.count(bit_from) > 0) bits.insert(bit_to); } } @@ -89,73 +78,49 @@ struct SigPool RTLIL::SigSpec extract(RTLIL::SigSpec sig) { RTLIL::SigSpec result; - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - bitDef_t bit(c.wire, c.offset); - if (bits.count(bit) > 0) - result.append(c); - } + for (auto &bit : sig) + if (bit.wire != NULL && bits.count(bit)) + result.append_bit(bit); return result; } RTLIL::SigSpec remove(RTLIL::SigSpec sig) { RTLIL::SigSpec result; - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - bitDef_t bit(c.wire, c.offset); - if (bits.count(bit) == 0) - result.append(c); - } + for (auto &bit : sig) + if (bit.wire != NULL && bits.count(bit) == 0) + result.append(bit); return result; } bool check_any(RTLIL::SigSpec sig) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - bitDef_t bit(c.wire, c.offset); - if (bits.count(bit) != 0) + for (auto &bit : sig) + if (bit.wire != NULL && bits.count(bit)) return true; - } return false; } bool check_all(RTLIL::SigSpec sig) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - bitDef_t bit(c.wire, c.offset); - if (bits.count(bit) == 0) + for (auto &bit : sig) + if (bit.wire != NULL && bits.count(bit) == 0) return false; - } return true; } RTLIL::SigSpec export_one() { - RTLIL::SigSpec sig; - for (auto &bit : bits) { - sig.append(RTLIL::SigSpec(bit.first, bit.second)); - break; - } - return sig; + for (auto &bit : bits) + return RTLIL::SigSpec(bit.first, bit.second); + return RTLIL::SigSpec(); } RTLIL::SigSpec export_all() { - RTLIL::SigSpec sig; + std::set sig; for (auto &bit : bits) - sig.append(RTLIL::SigSpec(bit.first, bit.second)); - sig.sort_and_unify(); + sig.insert(RTLIL::SigBit(bit.first, bit.second)); return sig; } @@ -168,7 +133,11 @@ struct SigPool template > struct SigSet { - typedef std::pair bitDef_t; + struct bitDef_t : public std::pair { + bitDef_t() : std::pair(NULL, 0) { } + bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } + }; + std::map> bits; void clear() @@ -178,75 +147,46 @@ struct SigSet void insert(RTLIL::SigSpec sig, T data) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - bits[bit].insert(data); - } + for (auto &bit : sig) + if (bit.wire != NULL) + bits[bit].insert(data); } void insert(RTLIL::SigSpec sig, const std::set &data) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - bits[bit].insert(data.begin(), data.end()); - } + for (auto &bit : sig) + if (bit.wire != NULL) + bits[bit].insert(data.begin(), data.end()); } void erase(RTLIL::SigSpec sig) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - bits[bit].clear(); - } + for (auto &bit : sig) + if (bit.wire != NULL) + bits[bit].clear(); } void erase(RTLIL::SigSpec sig, T data) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - bits[bit].erase(data); - } + for (auto &bit : sig) + if (bit.wire != NULL) + bits[bit].erase(data); } void erase(RTLIL::SigSpec sig, const std::set &data) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - bits[bit].erase(data.begin(), data.end()); - } + for (auto &bit : sig) + if (bit.wire != NULL) + bits[bit].erase(data.begin(), data.end()); } void find(RTLIL::SigSpec sig, std::set &result) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - for (auto &data : bits[bit]) - result.insert(data); - } + for (auto &bit : sig) + if (bit.wire != NULL) { + auto &data = bits[bit]; + result.insert(data.begin(), data.end()); + } } std::set find(RTLIL::SigSpec sig) @@ -258,22 +198,19 @@ struct SigSet bool has(RTLIL::SigSpec sig) { - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire == NULL) - continue; - assert(c.width == 1); - bitDef_t bit(c.wire, c.offset); - if (bits.count(bit)) + for (auto &bit : sig) + if (bit.wire != NULL && bits.count(bit)) return true; - } return false; } }; struct SigMap { - typedef std::pair bitDef_t; + struct bitDef_t : public std::pair { + bitDef_t() : std::pair(NULL, 0) { } + bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } + }; struct shared_bit_data_t { RTLIL::SigBit map_to; @@ -337,22 +274,20 @@ struct SigMap } // internal helper function - void register_bit(const RTLIL::SigBit &b) + void register_bit(const RTLIL::SigBit &bit) { - bitDef_t bit(b.wire, b.offset); - if (b.wire && bits.count(bit) == 0) { + if (bit.wire && bits.count(bit) == 0) { shared_bit_data_t *bd = new shared_bit_data_t; - bd->map_to = b; + bd->map_to = bit; bd->bits.insert(bit); bits[bit] = bd; } } // internal helper function - void unregister_bit(const RTLIL::SigBit &b) + void unregister_bit(const RTLIL::SigBit &bit) { - bitDef_t bit(b.wire, b.offset); - if (b.wire && bits.count(bit) > 0) { + if (bit.wire && bits.count(bit) > 0) { shared_bit_data_t *bd = bits[bit]; bd->bits.erase(bit); if (bd->bits.size() == 0) @@ -366,11 +301,8 @@ struct SigMap { assert(bit1.wire != NULL && bit2.wire != NULL); - bitDef_t b1(bit1.wire, bit1.offset); - bitDef_t b2(bit2.wire, bit2.offset); - - shared_bit_data_t *bd1 = bits[b1]; - shared_bit_data_t *bd2 = bits[b2]; + shared_bit_data_t *bd1 = bits[bit1]; + shared_bit_data_t *bd2 = bits[bit2]; assert(bd1 != NULL && bd2 != NULL); if (bd1 == bd2) @@ -394,20 +326,18 @@ struct SigMap } // internal helper function - void set_bit(const RTLIL::SigBit &b1, const RTLIL::SigBit &b2) + void set_bit(const RTLIL::SigBit &bit1, const RTLIL::SigBit &bit2) { - assert(b1.wire != NULL); - bitDef_t bit(b1.wire, b1.offset); - assert(bits.count(bit) > 0); - bits[bit]->map_to = b2; + assert(bit1.wire != NULL); + assert(bits.count(bit1) > 0); + bits[bit1]->map_to = bit2; } // internal helper function - void map_bit(RTLIL::SigBit &b) const + void map_bit(RTLIL::SigBit &bit) const { - bitDef_t bit(b.wire, b.offset); - if (b.wire && bits.count(bit) > 0) - b = bits.at(bit)->map_to; + if (bit.wire && bits.count(bit) > 0) + bit = bits.at(bit)->map_to; } void add(RTLIL::SigSpec from, RTLIL::SigSpec to) @@ -446,6 +376,11 @@ struct SigMap unregister_bit(bit); } + void apply(RTLIL::SigBit &bit) const + { + map_bit(bit); + } + void apply(RTLIL::SigSpec &sig) const { for (auto &bit : sig) diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index 1c71f78b..efb3ca95 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -21,7 +21,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re SigMap sigmap(module); // count how many times a single-bit signal is used - std::map bit_usage_count; + std::map bit_usage_count; // count ouput lines for this module (needed only for summary output at the end) int line_count = 0; @@ -36,13 +36,10 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // (use sigmap to get a uniqe signal name) RTLIL::SigSpec sig = sigmap(conn.second); - // split the signal up into single-bit chunks - sig.expand(); - - // add each chunk to bit_usage_count, unless it is a constant - for (auto &c : sig.chunks) - if (c.wire != NULL) - bit_usage_count[c]++; + // add each bit to bit_usage_count, unless it is a constant + for (auto &bit : sig) + if (bit.wire != NULL) + bit_usage_count[bit]++; } // for each wire in the module @@ -62,13 +59,11 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // get a signal description for this wire and split it into seperate bits RTLIL::SigSpec sig = sigmap(wire); - sig.expand(); // for each bit (unless it is a constant): // check if it is used at least two times and add to stub_bits otherwise - for (size_t i = 0; i < sig.chunks.size(); i++) - if (sig.chunks[i].wire != NULL && (bit_usage_count[sig.chunks[i]] + - usage_offset) < 2) + for (size_t i = 0; i < SIZE(sig); i++) + if (sig[i].wire != NULL && (bit_usage_count[sig[i]] + usage_offset) < 2) stub_bits.insert(i); // continue if no stub bits found diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 8cdd39b7..ba27a3fc 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -55,26 +55,23 @@ struct gate_t char type; int in1, in2, in3; bool is_port; - RTLIL::SigSpec sig; + RTLIL::SigBit bit; }; static int map_autoidx; static SigMap assign_map; static RTLIL::Module *module; static std::vector signal_list; -static std::map signal_map; +static std::map signal_map; static bool clk_polarity; static RTLIL::SigSpec clk_sig; -static int map_signal(RTLIL::SigSpec sig, char gate_type = -1, int in1 = -1, int in2 = -1, int in3 = -1) +static int map_signal(RTLIL::SigBit bit, char gate_type = -1, int in1 = -1, int in2 = -1, int in3 = -1) { - assert(sig.size() == 1); - assert(sig.chunks().size() == 1); + assign_map.apply(bit); - assign_map.apply(sig); - - if (signal_map.count(sig) == 0) { + if (signal_map.count(bit) == 0) { gate_t gate; gate.id = signal_list.size(); gate.type = -1; @@ -82,12 +79,12 @@ static int map_signal(RTLIL::SigSpec sig, char gate_type = -1, int in1 = -1, int gate.in2 = -1; gate.in3 = -1; gate.is_port = false; - gate.sig = sig; + gate.bit = bit; signal_list.push_back(gate); - signal_map[sig] = gate.id; + signal_map[bit] = gate.id; } - gate_t &gate = signal_list[signal_map[sig]]; + gate_t &gate = signal_list[signal_map[bit]]; if (gate_type >= 0) gate.type = gate_type; @@ -103,12 +100,9 @@ static int map_signal(RTLIL::SigSpec sig, char gate_type = -1, int in1 = -1, int static void mark_port(RTLIL::SigSpec sig) { - assign_map.apply(sig); - sig.expand(); - for (auto &c : sig.chunks()) { - if (c.wire != NULL && signal_map.count(c) > 0) - signal_list[signal_map[c]].is_port = true; - } + for (auto &bit : assign_map(sig)) + if (bit.wire != NULL && signal_map.count(bit) > 0) + signal_list[signal_map[bit]].is_port = true; } static void extract_cell(RTLIL::Cell *cell, bool keepff) @@ -229,7 +223,7 @@ static void dump_loop_graph(FILE *f, int &nr, std::map> &edge } for (auto n : nodes) - fprintf(f, " n%d [label=\"%s\\nid=%d, count=%d\"%s];\n", n, log_signal(signal_list[n].sig), + fprintf(f, " n%d [label=\"%s\\nid=%d, count=%d\"%s];\n", n, log_signal(signal_list[n].bit), n, in_counts[n], workpool.count(n) ? ", shape=box" : ""); for (auto &e : edges) @@ -280,7 +274,7 @@ static void handle_loops() int id = *workpool.begin(); workpool.erase(id); - // log("Removing non-loop node %d from graph: %s\n", id, log_signal(signal_list[id].sig)); + // log("Removing non-loop node %d from graph: %s\n", id, log_signal(signal_list[id].bit)); for (int id2 : edges[id]) { assert(in_edges_count[id2] > 0); @@ -300,8 +294,8 @@ static void handle_loops() for (auto &edge_it : edges) { int id2 = edge_it.first; - RTLIL::Wire *w1 = signal_list[id1].sig.chunks()[0].wire; - RTLIL::Wire *w2 = signal_list[id2].sig.chunks()[0].wire; + RTLIL::Wire *w1 = signal_list[id1].bit.wire; + RTLIL::Wire *w2 = signal_list[id2].bit.wire; if (w1 != NULL) continue; else if (w2 == NULL) @@ -333,10 +327,10 @@ static void handle_loops() for (int id2 : edges[id1]) { if (first_line) log("Breaking loop using new signal %s: %s -> %s\n", log_signal(RTLIL::SigSpec(wire)), - log_signal(signal_list[id1].sig), log_signal(signal_list[id2].sig)); + log_signal(signal_list[id1].bit), log_signal(signal_list[id2].bit)); else log(" %*s %s -> %s\n", int(strlen(log_signal(RTLIL::SigSpec(wire)))), "", - log_signal(signal_list[id1].sig), log_signal(signal_list[id2].sig)); + log_signal(signal_list[id1].bit), log_signal(signal_list[id2].bit)); first_line = false; } @@ -357,7 +351,7 @@ static void handle_loops() } edges[id1].swap(edges[id3]); - module->connections.push_back(RTLIL::SigSig(signal_list[id3].sig, signal_list[id1].sig)); + module->connections.push_back(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count); } } @@ -549,13 +543,12 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std fprintf(f, "\n"); for (auto &si : signal_list) - fprintf(f, "# n%-5d %s\n", si.id, log_signal(si.sig)); + fprintf(f, "# n%-5d %s\n", si.id, log_signal(si.bit)); for (auto &si : signal_list) { - assert(si.sig.size() == 1 && si.sig.chunks().size() == 1); - if (si.sig.chunks()[0].wire == NULL) { + if (si.bit.wire == NULL) { fprintf(f, ".names n%d\n", si.id); - if (si.sig.chunks()[0].data.bits[0] == RTLIL::State::S1) + if (si.bit == RTLIL::State::S1) fprintf(f, "1\n"); } } @@ -837,12 +830,12 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std snprintf(buffer, 100, "\\n%d", si.id); RTLIL::SigSig conn; if (si.type >= 0) { - conn.first = si.sig; + conn.first = si.bit; conn.second = RTLIL::SigSpec(module->wires[remap_name(buffer)]); out_wires++; } else { conn.first = RTLIL::SigSpec(module->wires[remap_name(buffer)]); - conn.second = si.sig; + conn.second = si.bit; in_wires++; } module->connections.push_back(conn); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 23fc48d5..0be36606 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -233,14 +233,12 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (!used_signals.check_any(s2) && wire->port_id == 0 && !wire->get_bool_attribute("\\keep")) { del_wires.push_back(wire); } else { - s1.expand(); - s2.expand(); - assert(s1.chunks().size() == s2.chunks().size()); + assert(SIZE(s1) == SIZE(s2)); RTLIL::SigSig new_conn; - for (size_t i = 0; i < s1.chunks().size(); i++) - if (s1.chunks()[i] != s2.chunks()[i]) { - new_conn.first.append(s1.chunks()[i]); - new_conn.second.append(s2.chunks()[i]); + for (int i = 0; i < SIZE(s1); i++) + if (s1[i] != s2[i]) { + new_conn.first.append_bit(s1[i]); + new_conn.second.append_bit(s2[i]); } if (new_conn.first.size() > 0) { new_conn.first.optimize(); @@ -257,9 +255,8 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool RTLIL::SigSpec sig = assign_map(RTLIL::SigSpec(wire)); if (!used_signals_nodrivers.check_any(sig)) { std::string unused_bits; - sig.expand(); - for (size_t i = 0; i < sig.chunks().size(); i++) { - if (sig.chunks()[i].wire == NULL) + for (int i = 0; i < SIZE(sig); i++) { + if (sig[i].wire == NULL) continue; if (!used_signals_nodrivers.check_any(sig)) { if (!unused_bits.empty()) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 9b89291b..ff139854 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -458,21 +458,19 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } RTLIL::SigSpec new_a, new_b; - a.expand(), b.expand(); - assert(a.chunks().size() == b.chunks().size()); - for (size_t i = 0; i < a.chunks().size(); i++) { - if (a.chunks()[i].wire == NULL && b.chunks()[i].wire == NULL && a.chunks()[i].data.bits[0] != b.chunks()[i].data.bits[0] && - a.chunks()[i].data.bits[0] <= RTLIL::State::S1 && b.chunks()[i].data.bits[0] <= RTLIL::State::S1) { + assert(SIZE(a) == SIZE(b)); + for (int i = 0; i < SIZE(a); i++) { + if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) { RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S0 : RTLIL::State::S1); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(module, cell, "empty", "\\Y", new_y); goto next_cell; } - if (a.chunks()[i] == b.chunks()[i]) + if (a[i] == b[i]) continue; - new_a.append(a.chunks()[i]); - new_b.append(b.chunks()[i]); + new_a.append(a[i]); + new_b.append(b[i]); } if (new_a.size() == 0) { diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 61147f67..dfcd5512 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -36,7 +36,11 @@ struct OptMuxtreeWorker SigMap assign_map; int removed_count; - typedef std::pair bitDef_t; + struct bitDef_t : public std::pair { + bitDef_t() : std::pair(NULL, 0) { } + bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } + }; + struct bitinfo_t { int num; @@ -259,10 +263,8 @@ struct OptMuxtreeWorker { std::vector results; assign_map.apply(sig); - sig.expand(); - for (auto &c : sig.chunks()) - if (c.wire != NULL) { - bitDef_t bit(c.wire, c.offset); + for (auto &bit : sig) + if (bit.wire != NULL) { if (bit2num.count(bit) == 0) { bitinfo_t info; info.num = bit2info.size(); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 7ab7233c..913855f4 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -44,46 +44,48 @@ struct OptReduceWorker cells.erase(cell); RTLIL::SigSpec sig_a = assign_map(cell->connections["\\A"]); - sig_a.sort_and_unify(); - sig_a.expand(); + std::set new_sig_a_bits; - RTLIL::SigSpec new_sig_a; - for (auto &chunk : sig_a.chunks()) + for (auto &bit : sig_a.to_sigbit_set()) { - if (chunk.wire == NULL && chunk.data.bits[0] == RTLIL::State::S0) { + if (bit == RTLIL::State::S0) { if (cell->type == "$reduce_and") { - new_sig_a = RTLIL::SigSpec(RTLIL::State::S0); + new_sig_a_bits.clear(); + new_sig_a_bits.insert(RTLIL::State::S0); break; } continue; } - if (chunk.wire == NULL && chunk.data.bits[0] == RTLIL::State::S1) { + if (bit == RTLIL::State::S1) { if (cell->type == "$reduce_or") { - new_sig_a = RTLIL::SigSpec(RTLIL::State::S1); + new_sig_a_bits.clear(); + new_sig_a_bits.insert(RTLIL::State::S1); break; } continue; } - if (chunk.wire == NULL) { - new_sig_a.append(chunk); + if (bit.wire == NULL) { + new_sig_a_bits.insert(bit); continue; } bool imported_children = false; - for (auto child_cell : drivers.find(chunk)) { + for (auto child_cell : drivers.find(bit)) { if (child_cell->type == cell->type) { opt_reduce(cells, drivers, child_cell); - if (child_cell->connections["\\Y"].extract(0, 1) == chunk) - new_sig_a.append(child_cell->connections["\\A"]); - else - new_sig_a.append(RTLIL::State::S0); + if (child_cell->connections["\\Y"][0] == bit) { + std::set child_sig_a_bits = assign_map(child_cell->connections["\\A"]).to_sigbit_set(); + new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); + } else + new_sig_a_bits.insert(RTLIL::State::S0); imported_children = true; } } if (!imported_children) - new_sig_a.append(chunk); + new_sig_a_bits.insert(bit); } - new_sig_a.sort_and_unify(); + + RTLIL::SigSpec new_sig_a(new_sig_a_bits); if (new_sig_a != sig_a || sig_a.size() != cell->connections["\\A"].size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 090f7463..9b8c3536 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -169,10 +169,9 @@ struct VlogHammerReporter if (!ez.solve(y_vec, y_values)) log_error("Failed to find solution to SAT problem.\n"); - expected_y.expand(); for (int i = 0; i < expected_y.size(); i++) { RTLIL::State solution_bit = y_values.at(i) ? RTLIL::State::S1 : RTLIL::State::S0; - RTLIL::State expected_bit = expected_y.chunks().at(i).data.bits.at(0); + RTLIL::State expected_bit = expected_y[i].data; if (model_undef) { if (y_values.at(expected_y.size()+i)) solution_bit = RTLIL::State::Sx; @@ -187,8 +186,7 @@ struct VlogHammerReporter sat_bits += "x"; else sat_bits += y_values.at(k) ? "1" : "0"; - rtl_bits += expected_y.chunks().at(k).data.bits.at(0) == RTLIL::State::Sx ? "x" : - expected_y.chunks().at(k).data.bits.at(0) == RTLIL::State::S1 ? "1" : "0"; + rtl_bits += expected_y[k] == RTLIL::State::Sx ? "x" : expected_y[k] == RTLIL::State::S1 ? "1" : "0"; } log_error("Found error in SAT model: y[%d] = %s, should be %s:\n SAT: %s\n RTL: %s\n %*s^\n", int(i), log_signal(solution_bit), log_signal(expected_bit), @@ -288,11 +286,9 @@ struct VlogHammerReporter if (module_name == "rtl") { rtl_sig = sig; - rtl_sig.expand(); sat_check(module, recorded_set_vars, recorded_set_vals, sig, false); sat_check(module, recorded_set_vars, recorded_set_vals, sig, true); } else if (rtl_sig.size() > 0) { - sig.expand(); if (rtl_sig.size() != sig.size()) log_error("Output (y) has a different width in module %s compared to rtl!\n", RTLIL::id2cstr(module->name)); for (int i = 0; i < SIZE(sig); i++) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 24968aa2..34becaee 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -411,10 +411,8 @@ struct SatHelper if (prove_asserts) { RTLIL::SigSpec asserts_a, asserts_en; satgen.getAsserts(asserts_a, asserts_en, timestep); - asserts_a.expand(); - asserts_en.expand(); - for (size_t i = 0; i < asserts_a.chunks().size(); i++) - log("Import proof for assert: %s when %s.\n", log_signal(asserts_a.chunks()[i]), log_signal(asserts_en.chunks()[i])); + for (int i = 0; i < SIZE(asserts_a); i++) + log("Import proof for assert: %s when %s.\n", log_signal(asserts_a[i]), log_signal(asserts_en[i])); prove_bits.push_back(satgen.importAsserts(timestep)); } diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index e5055c9c..4c3aec31 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -130,11 +130,8 @@ namespace RTLIL::SigSpec needleSig = conn.second; RTLIL::SigSpec haystackSig = haystackCell->connections.at(portMapping.at(conn.first)); - needleSig.expand(); - haystackSig.expand(); - for (int i = 0; i < std::min(needleSig.size(), haystackSig.size()); i++) { - RTLIL::Wire *needleWire = needleSig.chunks().at(i).wire, *haystackWire = haystackSig.chunks().at(i).wire; + RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire; if (needleWire != lastNeedleWire || haystackWire != lastHaystackWire) if (!compareAttributes(wire_attr, needleWire ? needleWire->attributes : emptyAttr, haystackWire ? haystackWire->attributes : emptyAttr)) return false; @@ -156,7 +153,7 @@ namespace int max_fanout = -1, std::set> *split = NULL) { SigMap sigmap(mod); - std::map sig_bit_ref; + std::map sig_bit_ref; if (sel && !sel->selected(mod)) { log(" Skipping module %s as it is not selected.\n", id2cstr(mod->name)); @@ -192,10 +189,9 @@ namespace for (auto &conn : cell->connections) { RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); - conn_sig.expand(); - for (auto &chunk : conn_sig.chunks()) - if (chunk.wire != NULL) - sig_use_count[std::pair(chunk.wire, chunk.offset)]++; + for (auto &bit : conn_sig) + if (bit.wire != NULL) + sig_use_count[std::pair(bit.wire, bit.offset)]++; } } @@ -220,39 +216,37 @@ namespace RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); - conn_sig.expand(); - for (size_t i = 0; i < conn_sig.chunks().size(); i++) + for (int i = 0; i < conn_sig.size(); i++) { - auto &chunk = conn_sig.chunks()[i]; - assert(chunk.width == 1); + auto &bit = conn_sig[i]; - if (chunk.wire == NULL) { + if (bit.wire == NULL) { if (constports) { std::string node = "$const$x"; - if (chunk.data.bits[0] == RTLIL::State::S0) node = "$const$0"; - if (chunk.data.bits[0] == RTLIL::State::S1) node = "$const$1"; - if (chunk.data.bits[0] == RTLIL::State::Sz) node = "$const$z"; + if (bit == RTLIL::State::S0) node = "$const$0"; + if (bit == RTLIL::State::S1) node = "$const$1"; + if (bit == RTLIL::State::Sz) node = "$const$z"; graph.createConnection(cell->name, conn.first, i, node, "\\Y", 0); } else - graph.createConstant(cell->name, conn.first, i, int(chunk.data.bits[0])); + graph.createConstant(cell->name, conn.first, i, int(bit.data)); continue; } - if (max_fanout > 0 && sig_use_count[std::pair(chunk.wire, chunk.offset)] > max_fanout) + if (max_fanout > 0 && sig_use_count[std::pair(bit.wire, bit.offset)] > max_fanout) continue; - if (sel && !sel->selected(mod, chunk.wire)) + if (sel && !sel->selected(mod, bit.wire)) continue; - if (sig_bit_ref.count(chunk) == 0) { - bit_ref_t &bit_ref = sig_bit_ref[chunk]; + if (sig_bit_ref.count(bit) == 0) { + bit_ref_t &bit_ref = sig_bit_ref[bit]; bit_ref.cell = cell->name; bit_ref.port = conn.first; bit_ref.bit = i; } - bit_ref_t &bit_ref = sig_bit_ref[chunk]; + bit_ref_t &bit_ref = sig_bit_ref[bit]; graph.createConnection(bit_ref.cell, bit_ref.port, bit_ref.bit, cell->name, conn.first, i); } } @@ -267,11 +261,10 @@ namespace { RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); - conn_sig.expand(); - for (auto &chunk : conn_sig.chunks()) - if (sig_bit_ref.count(chunk) != 0) { - bit_ref_t &bit_ref = sig_bit_ref[chunk]; + for (auto &bit : conn_sig) + if (sig_bit_ref.count(bit) != 0) { + bit_ref_t &bit_ref = sig_bit_ref[bit]; graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit); } } @@ -285,11 +278,10 @@ namespace { RTLIL::SigSpec conn_sig(wire); sigmap.apply(conn_sig); - conn_sig.expand(); - for (auto &chunk : conn_sig.chunks()) - if (sig_bit_ref.count(chunk) != 0) { - bit_ref_t &bit_ref = sig_bit_ref[chunk]; + for (auto &bit : conn_sig) + if (sig_bit_ref.count(bit) != 0) { + bit_ref_t &bit_ref = sig_bit_ref[bit]; graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit); } } @@ -333,9 +325,8 @@ namespace for (auto &conn : needle_cell->connections) { RTLIL::SigSpec sig = sigmap(conn.second); if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { - sig.expand(); for (int i = 0; i < sig.size(); i++) - for (auto &port : sig2port.find(sig.chunks()[i])) { + for (auto &port : sig2port.find(sig[i])) { RTLIL::SigSpec bitsig = haystack_cell->connections.at(mapping.portMapping[conn.first]).extract(i, 1); cell->connections.at(port.first).replace(port.second, bitsig); } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 1eb5c063..034677d3 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -29,75 +29,60 @@ extern void simplemap_get_mappers(std::mapparameters.at("\\Y_WIDTH").as_int(); - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - sig_a.extend(width, cell->parameters.at("\\A_SIGNED").as_bool()); - sig_a.expand(); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - sig_y.expand(); - for (int i = 0; i < width; i++) { + sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); + + for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_INV_"; - gate->connections["\\A"] = sig_a.chunks().at(i); - gate->connections["\\Y"] = sig_y.chunks().at(i); + gate->connections["\\A"] = sig_a[i]; + gate->connections["\\Y"] = sig_y[i]; module->add(gate); } } static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\Y_WIDTH").as_int(); - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - sig_a.extend(width, cell->parameters.at("\\A_SIGNED").as_bool()); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); + module->connections.push_back(RTLIL::SigSig(sig_y, sig_a)); } static void simplemap_bu0(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\Y_WIDTH").as_int(); - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - sig_a.extend_u0(width, cell->parameters.at("\\A_SIGNED").as_bool()); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); + module->connections.push_back(RTLIL::SigSig(sig_y, sig_a)); } static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\Y_WIDTH").as_int(); - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - sig_a.extend_u0(width, cell->parameters.at("\\A_SIGNED").as_bool()); - sig_a.expand(); - RTLIL::SigSpec sig_b = cell->connections.at("\\B"); - sig_b.extend_u0(width, cell->parameters.at("\\B_SIGNED").as_bool()); - sig_b.expand(); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - sig_y.expand(); + + sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); + sig_b.extend_u0(SIZE(sig_y), cell->parameters.at("\\B_SIGNED").as_bool()); if (cell->type == "$xnor") { - RTLIL::SigSpec sig_t = module->addWire(NEW_ID, width); - sig_t.expand(); + RTLIL::SigSpec sig_t = module->addWire(NEW_ID, SIZE(sig_y)); - for (int i = 0; i < width; i++) { + for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_INV_"; - gate->connections["\\A"] = sig_t.chunks().at(i); - gate->connections["\\Y"] = sig_y.chunks().at(i); + gate->connections["\\A"] = sig_t[i]; + gate->connections["\\Y"] = sig_y[i]; module->add(gate); } @@ -111,13 +96,13 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$xnor") gate_type = "$_XOR_"; log_assert(!gate_type.empty()); - for (int i = 0; i < width; i++) { + for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\A"] = sig_a.chunks().at(i); - gate->connections["\\B"] = sig_b.chunks().at(i); - gate->connections["\\Y"] = sig_y.chunks().at(i); + gate->connections["\\A"] = sig_a[i]; + gate->connections["\\B"] = sig_b[i]; + gate->connections["\\Y"] = sig_y[i]; module->add(gate); } } @@ -125,8 +110,6 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) { RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - sig_a.expand(); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); if (sig_y.size() == 0) @@ -159,21 +142,20 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) while (sig_a.size() > 1) { RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.size() / 2); - sig_t.expand(); for (int i = 0; i < sig_a.size(); i += 2) { if (i+1 == sig_a.size()) { - sig_t.append(sig_a.chunks().at(i)); + sig_t.append(sig_a[i]); continue; } RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\A"] = sig_a.chunks().at(i); - gate->connections["\\B"] = sig_a.chunks().at(i+1); - gate->connections["\\Y"] = sig_t.chunks().at(i/2); + gate->connections["\\A"] = sig_a[i]; + gate->connections["\\B"] = sig_a[i+1]; + gate->connections["\\Y"] = sig_t[i/2]; last_output = &gate->connections["\\Y"]; module->add(gate); } @@ -202,26 +184,23 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) { - sig.expand(); - while (sig.size() > 1) { RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.size() / 2); - sig_t.expand(); for (int i = 0; i < sig.size(); i += 2) { if (i+1 == sig.size()) { - sig_t.append(sig.chunks().at(i)); + sig_t.append(sig[i]); continue; } RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_OR_"; - gate->connections["\\A"] = sig.chunks().at(i); - gate->connections["\\B"] = sig.chunks().at(i+1); - gate->connections["\\Y"] = sig_t.chunks().at(i/2); + gate->connections["\\A"] = sig[i]; + gate->connections["\\B"] = sig[i+1]; + gate->connections["\\Y"] = sig_t[i/2]; module->add(gate); } @@ -289,25 +268,18 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) { - int width = cell->parameters.at("\\WIDTH").as_int(); - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - sig_a.expand(); - RTLIL::SigSpec sig_b = cell->connections.at("\\B"); - sig_b.expand(); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - sig_y.expand(); - for (int i = 0; i < width; i++) { + for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = "$_MUX_"; - gate->connections["\\A"] = sig_a.chunks().at(i); - gate->connections["\\B"] = sig_b.chunks().at(i); + gate->connections["\\A"] = sig_a[i]; + gate->connections["\\B"] = sig_b[i]; gate->connections["\\S"] = cell->connections.at("\\S"); - gate->connections["\\Y"] = sig_y.chunks().at(i); + gate->connections["\\Y"] = sig_y[i]; module->add(gate); } } @@ -335,13 +307,8 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; RTLIL::SigSpec sig_s = cell->connections.at("\\SET"); - sig_s.expand(); - RTLIL::SigSpec sig_r = cell->connections.at("\\CLR"); - sig_r.expand(); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); - sig_q.expand(); std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol); @@ -349,9 +316,9 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = new RTLIL::Cell; gate->name = NEW_ID; gate->type = gate_type; - gate->connections["\\S"] = sig_s.chunks().at(i); - gate->connections["\\R"] = sig_r.chunks().at(i); - gate->connections["\\Q"] = sig_q.chunks().at(i); + gate->connections["\\S"] = sig_s[i]; + gate->connections["\\R"] = sig_r[i]; + gate->connections["\\Q"] = sig_q[i]; module->add(gate); } } @@ -362,12 +329,8 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; RTLIL::SigSpec sig_clk = cell->connections.at("\\CLK"); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - sig_d.expand(); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); - sig_q.expand(); std::string gate_type = stringf("$_DFF_%c_", clk_pol); @@ -376,8 +339,8 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\C"] = sig_clk; - gate->connections["\\D"] = sig_d.chunks().at(i); - gate->connections["\\Q"] = sig_q.chunks().at(i); + gate->connections["\\D"] = sig_d[i]; + gate->connections["\\Q"] = sig_q[i]; module->add(gate); } } @@ -390,18 +353,10 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; RTLIL::SigSpec sig_clk = cell->connections.at("\\CLK"); - RTLIL::SigSpec sig_s = cell->connections.at("\\SET"); - sig_s.expand(); - RTLIL::SigSpec sig_r = cell->connections.at("\\CLR"); - sig_r.expand(); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - sig_d.expand(); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); - sig_q.expand(); std::string gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol); @@ -410,10 +365,10 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\C"] = sig_clk; - gate->connections["\\S"] = sig_s.chunks().at(i); - gate->connections["\\R"] = sig_r.chunks().at(i); - gate->connections["\\D"] = sig_d.chunks().at(i); - gate->connections["\\Q"] = sig_q.chunks().at(i); + gate->connections["\\S"] = sig_s[i]; + gate->connections["\\R"] = sig_r[i]; + gate->connections["\\D"] = sig_d[i]; + gate->connections["\\Q"] = sig_q[i]; module->add(gate); } } @@ -430,12 +385,8 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_clk = cell->connections.at("\\CLK"); RTLIL::SigSpec sig_rst = cell->connections.at("\\ARST"); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - sig_d.expand(); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); - sig_q.expand(); std::string gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); std::string gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol); @@ -446,8 +397,8 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) gate->type = rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0; gate->connections["\\C"] = sig_clk; gate->connections["\\R"] = sig_rst; - gate->connections["\\D"] = sig_d.chunks().at(i); - gate->connections["\\Q"] = sig_q.chunks().at(i); + gate->connections["\\D"] = sig_d[i]; + gate->connections["\\Q"] = sig_q[i]; module->add(gate); } } @@ -458,12 +409,8 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) char en_pol = cell->parameters.at("\\EN_POLARITY").as_bool() ? 'P' : 'N'; RTLIL::SigSpec sig_en = cell->connections.at("\\EN"); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - sig_d.expand(); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); - sig_q.expand(); std::string gate_type = stringf("$_DLATCH_%c_", en_pol); @@ -472,8 +419,8 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) gate->name = NEW_ID; gate->type = gate_type; gate->connections["\\E"] = sig_en; - gate->connections["\\D"] = sig_d.chunks().at(i); - gate->connections["\\Q"] = sig_q.chunks().at(i); + gate->connections["\\D"] = sig_d[i]; + gate->connections["\\Q"] = sig_q[i]; module->add(gate); } } From 3ec785b881a7bbceb5ac4db1e761b75c07f8642a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 19:36:43 +0200 Subject: [PATCH 379/750] Fixed manual/CHAPTER_Prog/stubnets.cc --- manual/CHAPTER_Prog/stubnets.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index efb3ca95..3f8d553a 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -62,7 +62,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // for each bit (unless it is a constant): // check if it is used at least two times and add to stub_bits otherwise - for (size_t i = 0; i < SIZE(sig); i++) + for (int i = 0; i < SIZE(sig); i++) if (sig[i].wire != NULL && (bit_usage_count[sig[i]] + usage_offset) < 2) stub_bits.insert(i); @@ -72,7 +72,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // report stub bits and/or stub wires, don't report single bits // if called with report_bits set to false. - if (int(stub_bits.size()) == sig.width) { + if (SIZE(stub_bits) == SIZE(sig)) { log(" found stub wire: %s\n", RTLIL::id2cstr(wire->name)); } else { if (!report_bits) From 8fd8e4a468fb650fe5dcbe892c07010f627e2c2b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:11:55 +0200 Subject: [PATCH 380/750] Turned RTLIL::SigSpec::optimize() to a no-op: a packed SigSpec is now always optimized --- kernel/rtlil.cc | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7dcf32b7..32a6b277 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1550,6 +1550,7 @@ bool RTLIL::SigSpec::packed() const void RTLIL::SigSpec::optimize() { +#if 0 pack(); std::vector new_chunks; for (auto &c : chunks_) @@ -1566,14 +1567,19 @@ void RTLIL::SigSpec::optimize() } chunks_.swap(new_chunks); check(); +#endif } RTLIL::SigSpec RTLIL::SigSpec::optimized() const { +#if 0 pack(); RTLIL::SigSpec ret = *this; ret.optimize(); return ret; +#else + return *this; +#endif } void RTLIL::SigSpec::sort() @@ -1741,15 +1747,40 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) { - pack(); - signal.pack(); + if (signal.width_ == 0) + return; - for (size_t i = 0; i < signal.chunks_.size(); i++) { - chunks_.push_back(signal.chunks_[i]); - width_ += signal.chunks_[i].width; + if (width_ == 0) { + *this = signal; + return; } - // check(); + if (packed() != signal.packed()) { + pack(); + signal.pack(); + } + + if (packed()) + for (auto &other_c : signal.chunks_) + { + auto &my_last_c = chunks_.back(); + if (my_last_c.wire == NULL && other_c.wire == NULL) { + auto &this_data = my_last_c.data.bits; + auto &other_data = other_c.data.bits; + this_data.insert(this_data.end(), other_data.begin(), other_data.end()); + my_last_c.width += other_c.width; + } else + if (my_last_c.wire == other_c.wire && my_last_c.offset + my_last_c.width == other_c.offset) { + my_last_c.width += other_c.width; + } else + chunks_.push_back(other_c); + } + else + bits_.insert(bits_.end(), signal.bits_.begin(), signal.bits_.end()); + + width_ += signal.width_; + + check(); } void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) @@ -1776,7 +1807,7 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) width_++; - // check(); + check(); } void RTLIL::SigSpec::extend(int width, bool is_signed) @@ -1824,9 +1855,13 @@ void RTLIL::SigSpec::check() const for (size_t i = 0; i < chunks_.size(); i++) { const RTLIL::SigChunk chunk = chunks_[i]; if (chunk.wire == NULL) { + if (i > 0) + assert(chunks_[i-1].wire != NULL); assert(chunk.offset == 0); assert(chunk.data.bits.size() == (size_t)chunk.width); } else { + if (i > 0 && chunks_[i-1].wire == chunk.wire) + assert(chunk.offset != chunks_[i-1].offset + chunks_[i-1].width); assert(chunk.offset >= 0); assert(chunk.width >= 0); assert(chunk.offset + chunk.width <= chunk.wire->width); From c094c53de83707a5bf1b268640283f1dde235873 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:32:28 +0200 Subject: [PATCH 381/750] Removed RTLIL::SigSpec::optimize() --- backends/blif/blif.cc | 1 - backends/edif/edif.cc | 1 - backends/intersynth/intersynth.cc | 2 - backends/verilog/verilog_backend.cc | 3 - frontends/ast/genrtlil.cc | 11 --- kernel/bitpattern.h | 3 - kernel/rtlil.cc | 114 +++------------------------- kernel/rtlil.h | 7 -- passes/abc/blifparse.cc | 3 - passes/cmds/setundef.cc | 1 - passes/cmds/show.cc | 3 - passes/cmds/splice.cc | 2 - passes/cmds/splitnets.cc | 2 +- passes/fsm/fsm_map.cc | 5 -- passes/memory/memory_collect.cc | 7 -- passes/memory/memory_dff.cc | 1 - passes/memory/memory_share.cc | 2 - passes/opt/opt_clean.cc | 2 - passes/opt/opt_const.cc | 2 - passes/proc/proc_dff.cc | 4 - passes/proc/proc_init.cc | 2 - passes/sat/eval.cc | 3 - passes/sat/freduce.cc | 10 +-- passes/sat/sat.cc | 5 -- 24 files changed, 15 insertions(+), 181 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index a240d2a2..d0c25079 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -70,7 +70,6 @@ struct BlifDumper const char *cstr(RTLIL::SigSpec sig) { - sig.optimize(); log_assert(sig.size() == 1); if (sig.chunks().at(0).wire == NULL) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 3b9a4337..8f36f409 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -315,7 +315,6 @@ struct EdifBackend : public Backend { } for (auto &it : net_join_db) { RTLIL::SigSpec sig = it.first; - sig.optimize(); log_assert(sig.size() == 1); if (sig.chunks().at(0).wire == NULL) { if (sig.chunks().at(0).data.bits.at(0) != RTLIL::State::S0 && sig.chunks().at(0).data.bits.at(0) != RTLIL::State::S1) diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 832922de..a4cad5ad 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -28,8 +28,6 @@ static std::string netname(std::set &conntypes_code, std::set &celltypes_code, std::set &constcells_code, RTLIL::SigSpec sig) { - sig.optimize(); - if (sig.chunks().size() != 1) error: log_error("Can't export composite or non-word-wide signal %s.\n", log_signal(sig)); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 16083508..1dcc3003 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -133,7 +133,6 @@ std::string id(std::string internal_id, bool may_rename = true) bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name) { - sig.optimize(); if (sig.chunks().size() != 1 || sig.chunks()[0].wire == NULL) return false; if (reg_wires.count(sig.chunks()[0].wire->name) == 0) @@ -303,7 +302,6 @@ std::string cellname(RTLIL::Cell *cell) if (sig.size() != 1 || sig.is_fully_const()) goto no_special_reg_name; - sig.optimize(); RTLIL::Wire *wire = sig.chunks()[0].wire; if (wire->name[0] != '\\') @@ -909,7 +907,6 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) continue; RTLIL::SigSpec sig = cell->connections["\\Q"]; - sig.optimize(); if (sig.chunks().size() == 1 && sig.chunks()[0].wire) for (int i = 0; i < sig.chunks()[0].width; i++) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 18ae008c..3d848e82 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); diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 934796d2..4f4bc37a 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -34,10 +34,8 @@ struct BitPatternPool width = sig.size(); if (width > 0) { std::vector pattern(width); - sig.optimize(); for (int i = 0; i < width; i++) { RTLIL::SigSpec s = sig.extract(i, 1); - s.optimize(); assert(s.chunks().size() == 1); if (s.chunks()[0].wire == NULL && s.chunks()[0].data.bits[0] <= RTLIL::State::S1) pattern[i] = s.chunks()[0].data.bits[0]; @@ -61,7 +59,6 @@ struct BitPatternPool bits_t sig2bits(RTLIL::SigSpec sig) { - sig.optimize(); assert(sig.is_fully_const()); assert(sig.chunks().size() == 1); bits_t bits = sig.chunks()[0].data.bits; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 32a6b277..7d031e17 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -768,14 +768,6 @@ void RTLIL::Module::check() void RTLIL::Module::optimize() { - for (auto &it : cells) - it.second->optimize(); - for (auto &it : processes) - it.second->optimize(); - for (auto &it : connections) { - it.first.optimize(); - it.second.optimize(); - } } void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const @@ -1297,12 +1289,6 @@ RTLIL::Memory::Memory() size = 0; } -void RTLIL::Cell::optimize() -{ - for (auto &it : connections) - it.second.optimize(); -} - void RTLIL::Cell::check() { InternalCellChecker checker(NULL, this); @@ -1548,40 +1534,6 @@ bool RTLIL::SigSpec::packed() const return bits_.empty(); } -void RTLIL::SigSpec::optimize() -{ -#if 0 - pack(); - std::vector new_chunks; - for (auto &c : chunks_) - if (new_chunks.size() == 0) { - new_chunks.push_back(c); - } else { - RTLIL::SigChunk &cc = new_chunks.back(); - if (c.wire == NULL && cc.wire == NULL) - cc.data.bits.insert(cc.data.bits.end(), c.data.bits.begin(), c.data.bits.end()); - if (c.wire == cc.wire && (c.wire == NULL || cc.offset + cc.width == c.offset)) - cc.width += c.width; - else - new_chunks.push_back(c); - } - chunks_.swap(new_chunks); - check(); -#endif -} - -RTLIL::SigSpec RTLIL::SigSpec::optimized() const -{ -#if 0 - pack(); - RTLIL::SigSpec ret = *this; - ret.optimize(); - return ret; -#else - return *this; -#endif -} - void RTLIL::SigSpec::sort() { unpack(); @@ -1825,8 +1777,6 @@ void RTLIL::SigSpec::extend(int width, bool is_signed) while (width_ < width) append(padding); } - - optimize(); } void RTLIL::SigSpec::extend_u0(int width, bool is_signed) @@ -1844,7 +1794,6 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed) append(padding); } - optimize(); } void RTLIL::SigSpec::check() const @@ -1888,8 +1837,6 @@ bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const return width_ < other.width_; RTLIL::SigSpec a = *this, b = other; - a.optimize(); - b.optimize(); if (a.chunks_.size() != b.chunks_.size()) return a.chunks_.size() < b.chunks_.size(); @@ -1910,8 +1857,6 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const return false; RTLIL::SigSpec a = *this, b = other; - a.optimize(); - b.optimize(); if (a.chunks_.size() != b.chunks_.size()) return false; @@ -1973,22 +1918,18 @@ bool RTLIL::SigSpec::has_marked_bits() const bool RTLIL::SigSpec::as_bool() const { pack(); - assert(is_fully_const()); - SigSpec sig = *this; - sig.optimize(); - if (sig.width_) - return sig.chunks_[0].data.as_bool(); + assert(is_fully_const() && SIZE(chunks_) <= 1); + if (width_) + return chunks_[0].data.as_bool(); return false; } int RTLIL::SigSpec::as_int() const { pack(); - assert(is_fully_const()); - SigSpec sig = *this; - sig.optimize(); - if (sig.width_) - return sig.chunks_[0].data.as_int(); + assert(is_fully_const() && SIZE(chunks_) <= 1); + if (width_) + return chunks_[0].data.as_int(); return 0; } @@ -2010,11 +1951,9 @@ std::string RTLIL::SigSpec::as_string() const RTLIL::Const RTLIL::SigSpec::as_const() const { pack(); - assert(is_fully_const()); - SigSpec sig = *this; - sig.optimize(); - if (sig.width_) - return sig.chunks_[0].data; + assert(is_fully_const() && SIZE(chunks_) <= 1); + if (width_) + return chunks_[0].data; return RTLIL::Const(); } @@ -2200,18 +2139,6 @@ RTLIL::CaseRule::~CaseRule() delete *it; } -void RTLIL::CaseRule::optimize() -{ - for (auto it : switches) - it->optimize(); - for (auto &it : compare) - it.optimize(); - for (auto &it : actions) { - it.first.optimize(); - it.second.optimize(); - } -} - RTLIL::CaseRule *RTLIL::CaseRule::clone() const { RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule; @@ -2228,13 +2155,6 @@ RTLIL::SwitchRule::~SwitchRule() delete *it; } -void RTLIL::SwitchRule::optimize() -{ - signal.optimize(); - for (auto it : cases) - it->optimize(); -} - RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const { RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule; @@ -2246,15 +2166,6 @@ RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const } -void RTLIL::SyncRule::optimize() -{ - signal.optimize(); - for (auto &it : actions) { - it.first.optimize(); - it.second.optimize(); - } -} - RTLIL::SyncRule *RTLIL::SyncRule::clone() const { RTLIL::SyncRule *new_syncrule = new RTLIL::SyncRule; @@ -2270,13 +2181,6 @@ RTLIL::Process::~Process() delete *it; } -void RTLIL::Process::optimize() -{ - root_case.optimize(); - for (auto it : syncs) - it->optimize(); -} - RTLIL::Process *RTLIL::Process::clone() const { RTLIL::Process *new_proc = new RTLIL::Process; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6c0a7b66..a13164c3 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -450,7 +450,6 @@ struct RTLIL::Cell { std::map connections; std::map parameters; RTLIL_ATTRIBUTE_MEMBERS - void optimize(); void check(); template void rewrite_sigspecs(T functor); @@ -544,9 +543,6 @@ public: inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; } inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; } - void optimize(); - RTLIL::SigSpec optimized() const; - void sort(); void sort_and_unify(); @@ -624,7 +620,6 @@ struct RTLIL::SwitchRule { RTLIL_ATTRIBUTE_MEMBERS std::vector cases; ~SwitchRule(); - void optimize(); template void rewrite_sigspecs(T functor); RTLIL::SwitchRule *clone() const; @@ -634,7 +629,6 @@ struct RTLIL::SyncRule { RTLIL::SyncType type; RTLIL::SigSpec signal; std::vector actions; - void optimize(); template void rewrite_sigspecs(T functor); RTLIL::SyncRule *clone() const; @@ -646,7 +640,6 @@ struct RTLIL::Process { RTLIL::CaseRule root_case; std::vector syncs; ~Process(); - void optimize(); template void rewrite_sigspecs(T functor); RTLIL::Process *clone() const; diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 47fa0f82..04977b36 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -212,9 +212,6 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) goto continue_without_read; } - input_sig.optimize(); - output_sig.optimize(); - RTLIL::Cell *cell = new RTLIL::Cell; cell->name = NEW_ID; cell->type = "$lut"; diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 63d5bb9a..6c4bb16c 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -144,7 +144,6 @@ struct SetundefPass : public Pass { RTLIL::SigSpec bits; for (int i = 0; i < c.width; i++) bits.append(worker.next_bit()); - bits.optimize(); module->connections.push_back(RTLIL::SigSig(c, bits)); } } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 37fe4404..6b37b7bb 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -171,8 +171,6 @@ struct ShowWorker std::string gen_signode_simple(RTLIL::SigSpec sig, bool range_check = true) { - sig.optimize(); - if (sig.chunks().size() == 0) { fprintf(f, "v%d [ label=\"\" ];\n", single_idx_count); return stringf("v%d", single_idx_count++); @@ -199,7 +197,6 @@ struct ShowWorker if (net.empty()) { std::string label_string; - sig.optimize(); int pos = sig.size()-1; int idx = single_idx_count++; for (int i = int(sig.chunks().size())-1; i >= 0; i--) { diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index aed9c076..68e8951f 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -82,7 +82,6 @@ struct SpliceWorker module->add(cell); } - new_sig.optimize(); sliced_signals_cache[sig] = new_sig; return new_sig; @@ -143,7 +142,6 @@ struct SpliceWorker module->add(cell); } - new_sig.optimize(); spliced_signals_cache[sig] = new_sig; log(" Created spliced signal: %s -> %s\n", log_signal(sig), log_signal(new_sig)); diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index c40ff2c4..c65b6a5f 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -141,7 +141,7 @@ struct SplitnetsPass : public Pass { if (!ct.cell_output(c.second->type, p.first)) continue; - RTLIL::SigSpec sig = p.second.optimized(); + RTLIL::SigSpec sig = p.second; for (auto &chunk : sig.chunks()) { if (chunk.wire == NULL) continue; diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 9dda2ba8..cee26762 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -42,13 +42,10 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapparameters["\\SIZE"] = RTLIL::Const(memory->size); mem->parameters["\\ABITS"] = RTLIL::Const(addr_bits); - sig_wr_clk_enable.optimize(); - sig_wr_clk_polarity.optimize(); - assert(sig_wr_clk.size() == wr_ports); assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const()); assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const()); @@ -158,10 +155,6 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->connections["\\WR_DATA"] = sig_wr_data; mem->connections["\\WR_EN"] = sig_wr_en; - sig_rd_clk_enable.optimize(); - sig_rd_clk_polarity.optimize(); - sig_rd_transparent.optimize(); - assert(sig_rd_clk.size() == rd_ports); assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); assert(sig_rd_clk_polarity.size() == rd_ports && sig_rd_clk_polarity.is_fully_const()); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index b1f1e22b..56915776 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -69,7 +69,6 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI replaced_this_bit:; } - sig.optimize(); return true; } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 38eff996..dd2a32ca 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -439,8 +439,6 @@ struct MemoryShareWorker merged_en.replace(k, cell_en.extract(k, 1)); merged_data.replace(k, cell_data.extract(k, 1)); } - merged_en.optimize(); - merged_data.optimize(); } // Connect the new EN and DATA signals and remove the old write port. diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 0be36606..ba0aadc6 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -241,8 +241,6 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool new_conn.second.append_bit(s2[i]); } if (new_conn.first.size() > 0) { - new_conn.first.optimize(); - new_conn.second.optimize(); used_signals.add(new_conn.first); used_signals.add(new_conn.second); module->connections.push_back(new_conn); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index ff139854..800fbf10 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -481,8 +481,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a.size() < a.size() || new_b.size() < b.size()) { - new_a.optimize(); - new_b.optimize(); cell->connections["\\A"] = new_a; cell->connections["\\B"] = new_b; cell->parameters["\\A_WIDTH"] = new_a.size(); diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 8e5fbe8f..a8aba903 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -352,10 +352,6 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) ce.assign_map.apply(rstval); ce.assign_map.apply(sig); - insig.optimize(); - rstval.optimize(); - sig.optimize(); - if (rstval == sig) { rstval = RTLIL::SigSpec(RTLIL::State::Sz, sig.size()); sync_level = NULL; diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index ba1fb5ab..4c9b6bcd 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -28,7 +28,6 @@ static void proc_get_const(RTLIL::SigSpec &sig, RTLIL::CaseRule &rule) assert(rule.compare.size() == 0); while (1) { - sig.optimize(); RTLIL::SigSpec tmp = sig; for (auto &it : rule.actions) tmp.replace(it.first, it.second); @@ -53,7 +52,6 @@ static void proc_init(RTLIL::Module *mod, RTLIL::Process *proc) RTLIL::SigSpec lhs = action.first; RTLIL::SigSpec rhs = action.second; - lhs.optimize(); proc_get_const(rhs, proc->root_case); if (!rhs.is_fully_const()) diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 9b8c3536..6949b76d 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -53,8 +53,6 @@ struct BruteForceEquivChecker return; } - inputs.optimize(); - ConstEval ce1(mod1), ce2(mod2); ce1.set(mod1_inputs, inputs.as_const()); ce2.set(mod2_inputs, inputs.as_const()); @@ -482,7 +480,6 @@ struct EvalPass : public Pass { RTLIL::SigSpec signal, value, undef; if (!RTLIL::SigSpec::parse_sel(signal, design, module, it)) log_cmd_error("Failed to parse show expression `%s'.\n", it.c_str()); - signal.optimize(); value = signal; if (set_undef) { while (!ce.eval(value, undef)) { diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 1e47e7de..ba01bc32 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -349,7 +349,7 @@ struct PerformReduction std::vector bucket_sigbits; for (int idx : bucket) bucket_sigbits.push_back(out_bits[idx]); - log("%s Trying to shatter bucket with %d signals: %s\n", indt, int(bucket.size()), log_signal(RTLIL::SigSpec(bucket_sigbits).optimized())); + log("%s Trying to shatter bucket with %d signals: %s\n", indt, int(bucket.size()), log_signal(bucket_sigbits)); } std::vector sat_set_list, sat_clr_list; @@ -494,7 +494,7 @@ struct PerformReduction std::vector r_sigbits; for (int idx : r) r_sigbits.push_back(out_bits[idx]); - log(" Found group of %d equivialent signals: %s\n", int(r.size()), log_signal(RTLIL::SigSpec(r_sigbits).optimized())); + log(" Found group of %d equivialent signals: %s\n", int(r.size()), log_signal(r_sigbits)); } std::vector undef_slaves; @@ -640,7 +640,7 @@ struct FreduceWorker found_selected_wire: log(" Finding reduced input cone for signal batch %s%c\n", - log_signal(RTLIL::SigSpec(std::vector(batch.begin(), batch.end())).optimized()), verbose_level ? ':' : '.'); + log_signal(batch), verbose_level ? ':' : '.'); FindReducedInputs infinder(sigmap, drivers); for (auto &bit : batch) { @@ -663,12 +663,12 @@ struct FreduceWorker continue; if (bucket.first.size() == 0) { - log(" Finding const values for bucket %s%c\n", log_signal(RTLIL::SigSpec(bucket.second).optimized()), verbose_level ? ':' : '.'); + log(" Finding const values for bucket %s%c\n", log_signal(bucket.second), verbose_level ? ':' : '.'); PerformReduction worker(sigmap, drivers, inv_pairs, bucket.second, bucket.first.size()); for (size_t idx = 0; idx < bucket.second.size(); idx++) worker.analyze_const(equiv, idx); } else { - log(" Trying to shatter bucket %s%c\n", log_signal(RTLIL::SigSpec(bucket.second).optimized()), verbose_level ? ':' : '.'); + log(" Trying to shatter bucket %s%c\n", log_signal(bucket.second), verbose_level ? ':' : '.'); PerformReduction worker(sigmap, drivers, inv_pairs, bucket.second, bucket.first.size()); worker.analyze(equiv, 100 * bucket_count / (buckets.size() + 1)); } diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 34becaee..4b6b1b71 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -114,10 +114,6 @@ struct SatHelper } } - lhs.optimize(); - rhs.optimize(); - removed_bits.optimize(); - if (removed_bits.size()) log("Warning: ignoring initial value on non-register: %s\n", log_signal(removed_bits)); @@ -152,7 +148,6 @@ struct SatHelper if (!satgen.initial_state.check_all(big_lhs)) { RTLIL::SigSpec rem = satgen.initial_state.remove(big_lhs); - rem.optimize(); log_cmd_error("Found -set-init bits that are not part of the initial_state: %s\n", log_signal(rem)); } From 20a7965f61a43b8c367b1042081a57b5a4005b33 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:45:27 +0200 Subject: [PATCH 382/750] Various small fixes (from gcc compiler warnings) --- frontends/ast/simplify.cc | 2 +- passes/fsm/fsmdata.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index f819b250..d86bfb3f 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++) diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index d0be71c5..ae9569ed 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -143,25 +143,25 @@ struct FsmData log(" Input signals:\n"); RTLIL::SigSpec sig_in = cell->connections["\\CTRL_IN"]; for (int i = 0; i < SIZE(sig_in); i++) - log(" %3zd: %s\n", i, log_signal(sig_in[i])); + log(" %3d: %s\n", i, log_signal(sig_in[i])); log("\n"); log(" Output signals:\n"); RTLIL::SigSpec sig_out = cell->connections["\\CTRL_OUT"]; for (int i = 0; i < SIZE(sig_out); i++) - log(" %3zd: %s\n", i, log_signal(sig_out[i])); + log(" %3d: %s\n", i, log_signal(sig_out[i])); log("\n"); log(" State encoding:\n"); for (int i = 0; i < SIZE(state_table); i++) - log(" %3zd: %10s%s\n", i, log_signal(state_table[i], false), + log(" %3d: %10s%s\n", i, log_signal(state_table[i], false), int(i) == reset_state ? " " : ""); log("\n"); log(" Transition Table (state_in, ctrl_in, state_out, ctrl_out):\n"); for (int i = 0; i < SIZE(transition_table); i++) { transition_t &tr = transition_table[i]; - log(" %5zd: %5d %s -> %5d %s\n", i, tr.state_in, log_signal(tr.ctrl_in), tr.state_out, log_signal(tr.ctrl_out)); + log(" %5d: %5d %s -> %5d %s\n", i, tr.state_in, log_signal(tr.ctrl_in), tr.state_out, log_signal(tr.ctrl_out)); } log("\n"); From 2a41afb7b2415f824ea1f60337050c9f41c0e33f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:34:14 +0200 Subject: [PATCH 383/750] Added RTLIL::SigSpec::repeat() --- kernel/rtlil.cc | 8 ++++++++ kernel/rtlil.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7d031e17..d2f37cec 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1796,6 +1796,14 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed) } +RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const +{ + RTLIL::SigSpec sig; + for (int i = 0; i < num; i++) + sig.append(*this); + return sig; +} + void RTLIL::SigSpec::check() const { if (packed()) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a13164c3..95de5f8c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -565,6 +565,8 @@ public: void extend(int width, bool is_signed = false); void extend_u0(int width, bool is_signed = false); + RTLIL::SigSpec repeat(int num) const; + bool operator <(const RTLIL::SigSpec &other) const; bool operator ==(const RTLIL::SigSpec &other) const; inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); } From 375aa71dfe53217ef4dd6273b96f53061b5c8e8c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:35:01 +0200 Subject: [PATCH 384/750] 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 diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt new file mode 100644 index 00000000..49debe0f --- /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 7411e943..c973988b 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())); From 95ac484548d4a4550568de09343964150806042d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:38:18 +0200 Subject: [PATCH 385/750] Fixed release build --- kernel/rtlil.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d2f37cec..7d630b35 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1291,8 +1291,10 @@ RTLIL::Memory::Memory() void RTLIL::Cell::check() { +#ifndef NDEBUG InternalCellChecker checker(NULL, this); checker.check(); +#endif } RTLIL::SigChunk::SigChunk() From f368d792fbe6a4430dbf710b11e89cbf58439542 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:42:44 +0200 Subject: [PATCH 386/750] Disabled RTLIL::SigSpec::check() in release builds --- kernel/rtlil.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7d630b35..b0958bd0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1808,6 +1808,7 @@ RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const void RTLIL::SigSpec::check() const { +#ifndef NDEBUG if (packed()) { int w = 0; @@ -1836,6 +1837,7 @@ void RTLIL::SigSpec::check() const assert(width_ == SIZE(bits_)); assert(chunks_.empty()); } +#endif } bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const From 82fa3560372bd89ad0985644a76cdd14f6701ec2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 23:58:03 +0200 Subject: [PATCH 387/750] Added hashing to RTLIL::SigSpec relational and equal operators --- kernel/rtlil.cc | 81 +++++++++++++++++++++++++++++++++++++++---------- kernel/rtlil.h | 9 ++++-- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b0958bd0..87c9cd04 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1411,12 +1411,14 @@ bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const RTLIL::SigSpec::SigSpec() { width_ = 0; + hash_ = 0; } RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) { chunks_.push_back(RTLIL::SigChunk(value)); width_ = chunks_.back().width; + hash_ = 0; check(); } @@ -1424,6 +1426,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) { chunks_.push_back(chunk); width_ = chunks_.back().width; + hash_ = 0; check(); } @@ -1431,6 +1434,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) { chunks_.push_back(RTLIL::SigChunk(wire)); width_ = chunks_.back().width; + hash_ = 0; check(); } @@ -1438,6 +1442,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width) { chunks_.push_back(RTLIL::SigChunk(wire, offset, width)); width_ = chunks_.back().width; + hash_ = 0; check(); } @@ -1445,6 +1450,7 @@ RTLIL::SigSpec::SigSpec(const std::string &str) { chunks_.push_back(RTLIL::SigChunk(str)); width_ = chunks_.back().width; + hash_ = 0; check(); } @@ -1452,6 +1458,7 @@ RTLIL::SigSpec::SigSpec(int val, int width) { chunks_.push_back(RTLIL::SigChunk(val, width)); width_ = width; + hash_ = 0; check(); } @@ -1459,6 +1466,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) { chunks_.push_back(RTLIL::SigChunk(bit, width)); width_ = width; + hash_ = 0; check(); } @@ -1470,12 +1478,14 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) for (int i = 0; i < width; i++) chunks_.push_back(bit); width_ = width; + hash_ = 0; check(); } RTLIL::SigSpec::SigSpec(std::vector chunks) { width_ = 0; + hash_ = 0; for (auto &c : chunks) append(c); check(); @@ -1484,6 +1494,7 @@ RTLIL::SigSpec::SigSpec(std::vector chunks) RTLIL::SigSpec::SigSpec(std::vector bits) { width_ = 0; + hash_ = 0; for (auto &bit : bits) append_bit(bit); check(); @@ -1492,6 +1503,7 @@ RTLIL::SigSpec::SigSpec(std::vector bits) RTLIL::SigSpec::SigSpec(std::set bits) { width_ = 0; + hash_ = 0; for (auto &bit : bits) append_bit(bit); check(); @@ -1529,11 +1541,34 @@ void RTLIL::SigSpec::unpack() const that->bits_.push_back(RTLIL::SigBit(c, i)); that->chunks_.clear(); + that->hash_ = 0; } -bool RTLIL::SigSpec::packed() const +#define DJB2(_hash, _value) do { (_hash) = (((_hash) << 5) + (_hash)) + (_value); } while (0) + +void RTLIL::SigSpec::hash() const { - return bits_.empty(); + RTLIL::SigSpec *that = (RTLIL::SigSpec*)this; + + if (that->hash_ != 0) + return; + + that->pack(); + that->hash_ = 5381; + + for (auto &c : that->chunks_) + if (c.wire == NULL) { + for (auto &v : c.data.bits) + DJB2(that->hash_, v); + } else { + for (auto &v : c.wire->name) + DJB2(that->hash_, v); + DJB2(that->hash_, c.offset); + DJB2(that->hash_, c.width); + } + + if (that->hash_ == 0) + that->hash_ = 1; } void RTLIL::SigSpec::sort() @@ -1842,39 +1877,53 @@ void RTLIL::SigSpec::check() const bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const { - pack(); - other.pack(); + if (this == &other) + return false; if (width_ != other.width_) return width_ < other.width_; - RTLIL::SigSpec a = *this, b = other; + pack(); + other.pack(); - if (a.chunks_.size() != b.chunks_.size()) - return a.chunks_.size() < b.chunks_.size(); + if (chunks_.size() != other.chunks_.size()) + return chunks_.size() < other.chunks_.size(); - for (size_t i = 0; i < a.chunks_.size(); i++) - if (a.chunks_[i] != b.chunks_[i]) - return a.chunks_[i] < b.chunks_[i]; + hash(); + other.hash(); + + if (hash_ != other.hash_) + return hash_ < other.hash_; + + for (size_t i = 0; i < chunks_.size(); i++) + if (chunks_[i] != other.chunks_[i]) + return chunks_[i] < other.chunks_[i]; return false; } bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const { - pack(); - other.pack(); + if (this == &other) + return true; if (width_ != other.width_) return false; - RTLIL::SigSpec a = *this, b = other; + pack(); + other.pack(); - if (a.chunks_.size() != b.chunks_.size()) + if (chunks_.size() != chunks_.size()) return false; - for (size_t i = 0; i < a.chunks_.size(); i++) - if (a.chunks_[i] != b.chunks_[i]) + hash(); + other.hash(); + + if (hash_ != other.hash_) + return false; + + for (size_t i = 0; i < chunks_.size(); i++) + if (chunks_[i] != other.chunks_[i]) return false; return true; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 95de5f8c..c25f7185 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -505,13 +505,18 @@ struct RTLIL::SigSpecIterator { struct RTLIL::SigSpec { private: + int width_; + unsigned long hash_; std::vector chunks_; // LSB at index 0 std::vector bits_; // LSB at index 0 - int width_; void pack() const; void unpack() const; - bool packed() const; + void hash() const; + + inline bool packed() const { + return bits_.empty(); + } inline void inline_unpack() const { if (!chunks_.empty()) From fa71ae89acf319696975a79472272aa30975af7f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 02:11:12 +0200 Subject: [PATCH 388/750] Added "make vloghtb" --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 6f9daa04..94b8ad4a 100644 --- a/Makefile +++ b/Makefile @@ -167,6 +167,9 @@ test: $(TARGETS) $(EXTRA_TARGETS) cd tests/memories && bash run-test.sh cd tests/sat && bash run-test.sh +vloghtb: $(TARGETS) $(EXTRA_TARGETS) + cd tests/vloghtb && bash run-test.sh + install: $(TARGETS) $(EXTRA_TARGETS) $(INSTALL_SUDO) mkdir -p $(DESTDIR)/bin $(INSTALL_SUDO) install $(TARGETS) $(DESTDIR)/bin/ From 2267db58341ccd5beed74da61e8830faa004af69 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 02:12:24 +0200 Subject: [PATCH 389/750] Added "make config-gcc-4.7" --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index 94b8ad4a..10bd9407 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ CONFIG := clang-debug # CONFIG := gcc-debug +# CONFIG := gcc-4.7 # CONFIG := release # features (the more the better) @@ -64,6 +65,11 @@ CXX = gcc CXXFLAGS += -std=gnu++0x -Os endif +ifeq ($(CONFIG),gcc-4.7) +CXX = gcc-4.7 +CXXFLAGS += -std=gnu++0x -march=native -O3 +endif + ifeq ($(CONFIG),release) CXX = gcc CXXFLAGS += -std=gnu++0x -march=native -O3 -DNDEBUG @@ -208,6 +214,9 @@ config-clang-debug: clean config-gcc-debug: clean echo 'CONFIG := gcc-debug' > Makefile.conf +config-gcc-4.7: clean + echo 'CONFIG := gcc-4.7' > Makefile.conf + config-release: clean echo 'CONFIG := release' > Makefile.conf From b31762d158f4c9fb406cd787361254330f4ec03e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 02:13:37 +0200 Subject: [PATCH 390/750] Added RELEASE_CHECKLIST --- RELEASE_CHECKLIST | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 RELEASE_CHECKLIST diff --git a/RELEASE_CHECKLIST b/RELEASE_CHECKLIST new file mode 100644 index 00000000..bb12932d --- /dev/null +++ b/RELEASE_CHECKLIST @@ -0,0 +1,87 @@ + +Update the CHANGELOG file: + + cd ~yosys + gitk & + vi CHANGELOG + + +Run all tests with "make config-{clang-debug,gcc-debug,gcc-4.7,release}": + + cd ~yosys + make clean + make test vloghtb + make install + + cd ~yosys-bigsim + make clean + make full + + cd ~vloghammer + make purge + make gen_issues gen_samples + make SYN_LIST="yosys" SIM_LIST="icarus yosim verilator" FULL=1 world + chromium-browser report.html + + +Then with any config setting: + + cd ~yosys + make manual + - sanity check the figures in the appnotes and presentation + - if there are any odd things -> investigate + - make cosmetic changes to the .tex files if necessary + + +Finally if a current verific library is available: + + cd ~yosys + cat frontends/verific/build_amd64.txt + - follow instructions + + cd frontends/verific + ../../yosys test_navre.ys + + +Release candiate: + + - create branch yosys-x.y.z-rc and push to github + - contact the usual suspects per mail and ask them to test + - post on the reddit and ask people to test + - commit KISS fixes to the -rc branch if necessary + + +Release: + + - set YOSYS_VER to x.y.z in Makefile + - update version string in CHANGELOG + git commit -am "Yosys x.y.z" + + - push tag to github + - post changelog on github + - post short release note on reddit + - delete -rc branch from github + + +Updating the website: + + cd ~yosys + make manual + make install + + - update pdf files on the website + + cd ~yosys-web + make update_cmd + make update_show + git commit -am update + make push + + +In master branch: + + git merge {release-tag} + - set version to x.y.z+ in Makefile + - add section "Yosys x.y.z .. x.y.z+" to CHANGELOG + git commit --amend -am "Yosys x.y.z+" + From 6b1018314c130ffa12df2e8c73f1c0cd5853b6f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 03:48:38 +0200 Subject: [PATCH 391/750] Added cover() API --- kernel/log.cc | 2 ++ kernel/log.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/kernel/log.cc b/kernel/log.cc index 949bf432..26414d49 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -29,6 +29,8 @@ #include #include +CoverAgent *CoverAgent::first_cover_agent = NULL; + std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; diff --git a/kernel/log.h b/kernel/log.h index 00265dbe..51780806 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -63,6 +63,39 @@ void log_cell(RTLIL::Cell *cell, std::string indent = ""); #define log_assert(_assert_expr_) do { if (_assert_expr_) break; log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) #define log_ping() log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#ifndef NDEBUG +# define cover(_id) do { \ + static CoverAgent _cover_agent(__FILE__, __LINE__, __FUNCTION__, _id); \ + _cover_agent.ticks++; \ + } while (0) +#else +# define cover(_id) do { } while (0) +#endif + +struct CoverAgent +{ + static struct CoverAgent *first_cover_agent; + struct CoverAgent *next_cover_agent; + + const char *file; + int line; + const char *func; + const char *id; + int ticks; + + CoverAgent(const char *file, int line, const char *func, const char *id) : + file(file), line(line), func(func), id(id), ticks(0) + { + next_cover_agent = first_cover_agent; + first_cover_agent = this; + }; +}; + + +// ------------------------------------------------------------ +// everything below this line are utilities for troubleshooting +// ------------------------------------------------------------ + // simple timer for performance measurements // toggle the '#if 1' to get a baseline for the perormance penalty added by the measurement struct PerformanceTimer From 9cf12570ba639ca23e1d611a27160fb46b3c46d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 03:49:32 +0200 Subject: [PATCH 392/750] Added support for YOSYS_COVER_DIR env variable --- kernel/driver.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kernel/driver.cc b/kernel/driver.cc index e365e67c..4992686b 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -749,6 +749,32 @@ int main(int argc, char **argv) delete yosys_design; yosys_design = NULL; +#ifndef NDEBUG + if (getenv("YOSYS_COVER_DIR")) + { + char filename_buffer[4096]; + snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", getenv("YOSYS_COVER_DIR"), getpid()); + FILE *f = fdopen(mkstemps(filename_buffer, 4), "w"); + + if (f == NULL) + log_error("Can't create coverage file `%s'.\n", filename_buffer); + + log("\n", filename_buffer); + + std::map> coverage_data; + for (CoverAgent *p = CoverAgent::first_cover_agent; p; p = p->next_cover_agent) { + if (coverage_data.count(p->id)) + log("WARNING: found duplicate coverage id \"%s\".\n", p->id); + coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); + coverage_data[p->id].second += p->ticks; + } + + for (auto &it : coverage_data) + fprintf(f, "%-40s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); + fclose(f); + } +#endif + log("\nREADY.\n"); log_pop(); From 1b0d5fc22d1a1e590cb8f2252956ef1b0a38dda0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 03:50:28 +0200 Subject: [PATCH 393/750] Added cover() calls to RTLIL::SigSpec methods --- kernel/rtlil.cc | 98 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 5 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 87c9cd04..4a0ac60f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1516,6 +1516,7 @@ void RTLIL::SigSpec::pack() const if (that->bits_.empty()) return; + cover("kernel.rtlil.sigspec.pack"); log_assert(that->chunks_.empty()); std::vector old_bits; @@ -1533,6 +1534,7 @@ void RTLIL::SigSpec::unpack() const if (that->chunks_.empty()) return; + cover("kernel.rtlil.sigspec.unpack"); log_assert(that->bits_.empty()); that->bits_.reserve(that->width_); @@ -1553,9 +1555,10 @@ void RTLIL::SigSpec::hash() const if (that->hash_ != 0) return; + cover("kernel.rtlil.sigspec.hash"); that->pack(); - that->hash_ = 5381; + that->hash_ = 5381; for (auto &c : that->chunks_) if (c.wire == NULL) { for (auto &v : c.data.bits) @@ -1574,11 +1577,13 @@ void RTLIL::SigSpec::hash() const void RTLIL::SigSpec::sort() { unpack(); + cover("kernel.rtlil.sigspec.sort"); std::sort(bits_.begin(), bits_.end()); } void RTLIL::SigSpec::sort_and_unify() { + cover("kernel.rtlil.sigspec.sort_and_unify"); *this = this->to_sigbit_set(); } @@ -1589,6 +1594,11 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { + if (other) + cover("kernel.rtlil.sigspec.replace_other"); + else + cover("kernel.rtlil.sigspec.replace"); + unpack(); pattern.unpack(); with.unpack(); @@ -1624,6 +1634,11 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) { + if (other) + cover("kernel.rtlil.sigspec.remove_other"); + else + cover("kernel.rtlil.sigspec.remove"); + unpack(); if (other != NULL) { @@ -1655,6 +1670,11 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const { + if (other) + cover("kernel.rtlil.sigspec.extract_other"); + else + cover("kernel.rtlil.sigspec.extract"); + pack(); pattern.pack(); @@ -1684,6 +1704,8 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) { + cover("kernel.rtlil.sigspec.replace"); + unpack(); with.unpack(); @@ -1699,6 +1721,8 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) void RTLIL::SigSpec::remove_const() { + cover("kernel.rtlil.sigspec.remove_const"); + unpack(); std::vector new_bits; @@ -1716,6 +1740,8 @@ void RTLIL::SigSpec::remove_const() void RTLIL::SigSpec::remove(int offset, int length) { + cover("kernel.rtlil.sigspec.remove_pos"); + unpack(); assert(offset >= 0); @@ -1731,6 +1757,7 @@ void RTLIL::SigSpec::remove(int offset, int length) RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const { unpack(); + cover("kernel.rtlil.sigspec.extract_pos"); return std::vector(bits_.begin() + offset, bits_.begin() + offset + length); } @@ -1744,6 +1771,8 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) return; } + cover("kernel.rtlil.sigspec.append"); + if (packed() != signal.packed()) { pack(); signal.pack(); @@ -1776,6 +1805,8 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) { if (packed()) { + cover("kernel.rtlil.sigspec.append_bit.packed"); + if (chunks_.size() == 0) chunks_.push_back(bit); else @@ -1792,7 +1823,10 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) chunks_.push_back(bit); } else + { + cover("kernel.rtlil.sigspec.append_bit.unpacked"); bits_.push_back(bit); + } width_++; @@ -1801,6 +1835,8 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) void RTLIL::SigSpec::extend(int width, bool is_signed) { + cover("kernel.rtlil.sigspec.extend"); + pack(); if (width_ > width) @@ -1818,6 +1854,8 @@ void RTLIL::SigSpec::extend(int width, bool is_signed) void RTLIL::SigSpec::extend_u0(int width, bool is_signed) { + cover("kernel.rtlil.sigspec.extend_0"); + pack(); if (width_ > width) @@ -1835,6 +1873,8 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed) RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const { + cover("kernel.rtlil.sigspec.repeat"); + RTLIL::SigSpec sig; for (int i = 0; i < num; i++) sig.append(*this); @@ -1846,6 +1886,8 @@ void RTLIL::SigSpec::check() const #ifndef NDEBUG if (packed()) { + cover("kernel.rtlil.sigspec.check.packed"); + int w = 0; for (size_t i = 0; i < chunks_.size(); i++) { const RTLIL::SigChunk chunk = chunks_[i]; @@ -1869,6 +1911,8 @@ void RTLIL::SigSpec::check() const } else { + cover("kernel.rtlil.sigspec.check.unpacked"); + assert(width_ == SIZE(bits_)); assert(chunks_.empty()); } @@ -1877,6 +1921,8 @@ void RTLIL::SigSpec::check() const bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const { + cover("kernel.rtlil.sigspec.comp_lt"); + if (this == &other) return false; @@ -1896,14 +1942,18 @@ bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const return hash_ < other.hash_; for (size_t i = 0; i < chunks_.size(); i++) - if (chunks_[i] != other.chunks_[i]) + if (chunks_[i] != other.chunks_[i]) { + cover("kernel.rtlil.sigspec.comp_lt.hash_collision"); return chunks_[i] < other.chunks_[i]; + } return false; } bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const { + cover("kernel.rtlil.sigspec.comp_eq"); + if (this == &other) return true; @@ -1923,14 +1973,18 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const return false; for (size_t i = 0; i < chunks_.size(); i++) - if (chunks_[i] != other.chunks_[i]) + if (chunks_[i] != other.chunks_[i]) { + cover("kernel.rtlil.sigspec.comp_eq.hash_collision"); return false; + } return true; } bool RTLIL::SigSpec::is_fully_const() const { + cover("kernel.rtlil.sigspec.is_fully_const"); + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) if (it->width > 0 && it->wire != NULL) @@ -1940,6 +1994,8 @@ bool RTLIL::SigSpec::is_fully_const() const bool RTLIL::SigSpec::is_fully_def() const { + cover("kernel.rtlil.sigspec.is_fully_def"); + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) @@ -1953,6 +2009,8 @@ bool RTLIL::SigSpec::is_fully_def() const bool RTLIL::SigSpec::is_fully_undef() const { + cover("kernel.rtlil.sigspec.is_fully_undef"); + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) @@ -1966,6 +2024,8 @@ bool RTLIL::SigSpec::is_fully_undef() const bool RTLIL::SigSpec::has_marked_bits() const { + cover("kernel.rtlil.sigspec.has_marked_bits"); + pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) if (it->width > 0 && it->wire == NULL) { @@ -1978,6 +2038,8 @@ bool RTLIL::SigSpec::has_marked_bits() const bool RTLIL::SigSpec::as_bool() const { + cover("kernel.rtlil.sigspec.as_bool"); + pack(); assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) @@ -1987,6 +2049,8 @@ bool RTLIL::SigSpec::as_bool() const int RTLIL::SigSpec::as_int() const { + cover("kernel.rtlil.sigspec.as_int"); + pack(); assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) @@ -1996,6 +2060,8 @@ int RTLIL::SigSpec::as_int() const std::string RTLIL::SigSpec::as_string() const { + cover("kernel.rtlil.sigspec.as_string"); + pack(); std::string str; for (size_t i = chunks_.size(); i > 0; i--) { @@ -2011,6 +2077,8 @@ std::string RTLIL::SigSpec::as_string() const RTLIL::Const RTLIL::SigSpec::as_const() const { + cover("kernel.rtlil.sigspec.as_const"); + pack(); assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) @@ -2020,6 +2088,8 @@ RTLIL::Const RTLIL::SigSpec::as_const() const bool RTLIL::SigSpec::match(std::string pattern) const { + cover("kernel.rtlil.sigspec.match"); + pack(); std::string str = as_string(); assert(pattern.size() == str.size()); @@ -2041,6 +2111,8 @@ bool RTLIL::SigSpec::match(std::string pattern) const std::set RTLIL::SigSpec::to_sigbit_set() const { + cover("kernel.rtlil.sigspec.to_sigbit_set"); + pack(); std::set sigbits; for (auto &c : chunks_) @@ -2051,12 +2123,16 @@ std::set RTLIL::SigSpec::to_sigbit_set() const std::vector RTLIL::SigSpec::to_sigbit_vector() const { + cover("kernel.rtlil.sigspec.to_sigbit_vector"); + unpack(); return bits_; } RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const { + cover("kernel.rtlil.sigspec.to_single_sigbit"); + pack(); log_assert(width_ == 1); for (auto &c : chunks_) @@ -2082,6 +2158,8 @@ static int sigspec_parse_get_dummy_line_num() bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str) { + cover("kernel.rtlil.sigspec.parse"); + std::vector tokens; sigspec_parse_split(tokens, str, ','); @@ -2095,6 +2173,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri continue; if ('0' <= netname[0] && netname[0] <= '9') { + cover("kernel.rtlil.sigspec.parse.const"); AST::get_line_num = sigspec_parse_get_dummy_line_num; AST::AstNode *ast = VERILOG_FRONTEND::const2ast(netname); if (ast == NULL) @@ -2107,6 +2186,8 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri if (module == NULL) return false; + cover("kernel.rtlil.sigspec.parse.net"); + if (netname[0] != '$' && netname[0] != '\\') netname = "\\" + netname; @@ -2134,9 +2215,11 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri if (!indices.empty()) { std::vector index_tokens; sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':'); - if (index_tokens.size() == 1) + if (index_tokens.size() == 1) { + cover("kernel.rtlil.sigspec.parse.bit_sel"); sig.append(RTLIL::SigSpec(wire, atoi(index_tokens.at(0).c_str()))); - else { + } else { + cover("kernel.rtlil.sigspec.parse.part_sel"); int a = atoi(index_tokens.at(0).c_str()); int b = atoi(index_tokens.at(1).c_str()); if (a > b) { @@ -2157,6 +2240,8 @@ bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL if (str.empty() || str[0] != '@') return parse(sig, module, str); + cover("kernel.rtlil.sigspec.parse.sel"); + str = RTLIL::escape_id(str.substr(1)); if (design->selection_vars.count(str) == 0) return false; @@ -2173,11 +2258,13 @@ bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str) { if (str == "0") { + cover("kernel.rtlil.sigspec.parse.rhs_zeros"); sig = RTLIL::SigSpec(RTLIL::State::S0, lhs.width_); return true; } if (str == "~0") { + cover("kernel.rtlil.sigspec.parse.rhs_ones"); sig = RTLIL::SigSpec(RTLIL::State::S1, lhs.width_); return true; } @@ -2187,6 +2274,7 @@ bool RTLIL::SigSpec::parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, R long long int val = strtoll(p, &endptr, 10); if (endptr && endptr != p && *endptr == 0) { sig = RTLIL::SigSpec(val, lhs.width_); + cover("kernel.rtlil.sigspec.parse.rhs_dec"); return true; } } From 798f71362975c625f4e24b0c981b15b5684ab33d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 04:16:32 +0200 Subject: [PATCH 394/750] Added support for YOSYS_COVER_FILE env variable --- kernel/driver.cc | 13 ++++++++++--- kernel/rtlil.cc | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 4992686b..9749ff30 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -750,11 +750,18 @@ int main(int argc, char **argv) yosys_design = NULL; #ifndef NDEBUG - if (getenv("YOSYS_COVER_DIR")) + if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) { char filename_buffer[4096]; - snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", getenv("YOSYS_COVER_DIR"), getpid()); - FILE *f = fdopen(mkstemps(filename_buffer, 4), "w"); + FILE *f; + + if (getenv("YOSYS_COVER_DIR")) { + snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", getenv("YOSYS_COVER_DIR"), getpid()); + f = fdopen(mkstemps(filename_buffer, 4), "w"); + } else { + snprintf(filename_buffer, 4096, "%s", getenv("YOSYS_COVER_FILE")); + f = fopen(filename_buffer, "w"); + } if (f == NULL) log_error("Can't create coverage file `%s'.\n", filename_buffer); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 4a0ac60f..ca8e9b6d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1947,6 +1947,7 @@ bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const return chunks_[i] < other.chunks_[i]; } + cover("kernel.rtlil.sigspec.comp_lt.equal"); return false; } @@ -1978,6 +1979,7 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const return false; } + cover("kernel.rtlil.sigspec.comp_eq.equal"); return true; } From 3a2c5357771df05f80bff55e8ab3e467308c57d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 04:24:47 +0200 Subject: [PATCH 395/750] Renamed RELEASE_CHECKLIST -> CHECKLIST --- RELEASE_CHECKLIST => CHECKLIST | 5 +++++ 1 file changed, 5 insertions(+) rename RELEASE_CHECKLIST => CHECKLIST (95%) diff --git a/RELEASE_CHECKLIST b/CHECKLIST similarity index 95% rename from RELEASE_CHECKLIST rename to CHECKLIST index bb12932d..c621b715 100644 --- a/RELEASE_CHECKLIST +++ b/CHECKLIST @@ -1,4 +1,9 @@ + +Checklist for creating Yosys releases +===================================== + + Update the CHANGELOG file: cd ~yosys From 22ede43b3f5016784b2e22c0ea95b7f718d7598e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 04:46:36 +0200 Subject: [PATCH 396/750] Small changes regarding cover() and check() in SigSpec --- kernel/rtlil.cc | 15 +++++---------- kernel/rtlil.h | 4 ++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ca8e9b6d..5194b5f7 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1594,10 +1594,7 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { - if (other) - cover("kernel.rtlil.sigspec.replace_other"); - else - cover("kernel.rtlil.sigspec.replace"); + cover("kernel.rtlil.sigspec.replace"); unpack(); pattern.unpack(); @@ -1797,8 +1794,7 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) bits_.insert(bits_.end(), signal.bits_.begin(), signal.bits_.end()); width_ += signal.width_; - - check(); + // check(); } void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) @@ -1829,8 +1825,7 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) } width_++; - - check(); + // check(); } void RTLIL::SigSpec::extend(int width, bool is_signed) @@ -1881,9 +1876,9 @@ RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const return sig; } +#ifndef NDEBUG void RTLIL::SigSpec::check() const { -#ifndef NDEBUG if (packed()) { cover("kernel.rtlil.sigspec.check.packed"); @@ -1916,8 +1911,8 @@ void RTLIL::SigSpec::check() const assert(width_ == SIZE(bits_)); assert(chunks_.empty()); } -#endif } +#endif bool RTLIL::SigSpec::operator <(const RTLIL::SigSpec &other) const { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c25f7185..68eee46e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -599,7 +599,11 @@ public: operator std::vector() const { return chunks(); } operator std::vector() const { return bits(); } +#ifndef NDEBUG void check() const; +#else + inline void check() const { } +#endif }; inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { From 7679000673f7a5c07037dfd3373162cbbcdb0624 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 15:05:05 +0200 Subject: [PATCH 397/750] Now using a dedicated ELF section for all coverage counters --- kernel/driver.cc | 6 +++--- kernel/log.cc | 2 -- kernel/log.h | 39 ++++++++++++++++++--------------------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 9749ff30..64165737 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -760,7 +760,7 @@ int main(int argc, char **argv) f = fdopen(mkstemps(filename_buffer, 4), "w"); } else { snprintf(filename_buffer, 4096, "%s", getenv("YOSYS_COVER_FILE")); - f = fopen(filename_buffer, "w"); + f = fopen(filename_buffer, "a+"); } if (f == NULL) @@ -769,11 +769,11 @@ int main(int argc, char **argv) log("\n", filename_buffer); std::map> coverage_data; - for (CoverAgent *p = CoverAgent::first_cover_agent; p; p = p->next_cover_agent) { + for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { if (coverage_data.count(p->id)) log("WARNING: found duplicate coverage id \"%s\".\n", p->id); coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); - coverage_data[p->id].second += p->ticks; + coverage_data[p->id].second += p->counter; } for (auto &it : coverage_data) diff --git a/kernel/log.cc b/kernel/log.cc index 26414d49..949bf432 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -29,8 +29,6 @@ #include #include -CoverAgent *CoverAgent::first_cover_agent = NULL; - std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; diff --git a/kernel/log.h b/kernel/log.h index 51780806..80417590 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -63,34 +63,31 @@ void log_cell(RTLIL::Cell *cell, std::string indent = ""); #define log_assert(_assert_expr_) do { if (_assert_expr_) break; log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) #define log_ping() log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) + +// --------------------------------------------------- +// This is the magic behind the code coverage counters +// --------------------------------------------------- + +struct CoverData { + const char *file, *func, *id; + int line, counter; +} __attribute__ ((packed)); + +// this two symbols are created by the linker for the "yosys_cover_list" ELF section +#ifndef NDEBUG +extern "C" struct CoverData __start_yosys_cover_list[]; +extern "C" struct CoverData __stop_yosys_cover_list[]; +#endif + #ifndef NDEBUG # define cover(_id) do { \ - static CoverAgent _cover_agent(__FILE__, __LINE__, __FUNCTION__, _id); \ - _cover_agent.ticks++; \ + static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1))) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ + __d.counter++; \ } while (0) #else # define cover(_id) do { } while (0) #endif -struct CoverAgent -{ - static struct CoverAgent *first_cover_agent; - struct CoverAgent *next_cover_agent; - - const char *file; - int line; - const char *func; - const char *id; - int ticks; - - CoverAgent(const char *file, int line, const char *func, const char *id) : - file(file), line(line), func(func), id(id), ticks(0) - { - next_cover_agent = first_cover_agent; - first_cover_agent = this; - }; -}; - // ------------------------------------------------------------ // everything below this line are utilities for troubleshooting From e589289df7662f076d12f7237321b429401952e2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 15:05:41 +0200 Subject: [PATCH 398/750] Some improvements in SigSpec packing/unpacking and checking --- kernel/rtlil.cc | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 5194b5f7..8e509f36 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1516,15 +1516,32 @@ void RTLIL::SigSpec::pack() const if (that->bits_.empty()) return; - cover("kernel.rtlil.sigspec.pack"); + cover("kernel.rtlil.sigspec.convert.pack"); log_assert(that->chunks_.empty()); std::vector old_bits; old_bits.swap(that->bits_); - that->width_ = 0; + RTLIL::SigChunk *last_const = NULL; + RTLIL::SigChunk *last_wire = NULL; + int last_wire_end = 0; + for (auto &bit : old_bits) - that->append_bit(bit); + if (bit.wire == NULL && last_const) { + last_const->data.bits.push_back(bit.data); + last_const->width++; + } else + if (bit.wire && last_wire && last_wire->wire == bit.wire && last_wire_end == bit.offset) { + last_wire->width++; + last_wire_end++; + } else { + that->chunks_.push_back(bit); + last_const = bit.wire ? NULL : &that->chunks_.back(); + last_wire = bit.wire ? &that->chunks_.back() : NULL; + last_wire_end = bit.offset + 1; + } + + check(); } void RTLIL::SigSpec::unpack() const @@ -1534,7 +1551,7 @@ void RTLIL::SigSpec::unpack() const if (that->chunks_.empty()) return; - cover("kernel.rtlil.sigspec.unpack"); + cover("kernel.rtlil.sigspec.convert.unpack"); log_assert(that->bits_.empty()); that->bits_.reserve(that->width_); @@ -1701,7 +1718,7 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) { - cover("kernel.rtlil.sigspec.replace"); + cover("kernel.rtlil.sigspec.replace_pos"); unpack(); with.unpack(); @@ -1794,7 +1811,7 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) bits_.insert(bits_.end(), signal.bits_.begin(), signal.bits_.end()); width_ += signal.width_; - // check(); + check(); } void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) @@ -1825,7 +1842,7 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) } width_++; - // check(); + check(); } void RTLIL::SigSpec::extend(int width, bool is_signed) @@ -1879,7 +1896,11 @@ RTLIL::SigSpec RTLIL::SigSpec::repeat(int num) const #ifndef NDEBUG void RTLIL::SigSpec::check() const { - if (packed()) + if (width_ > 64) + { + cover("kernel.rtlil.sigspec.check.skip"); + } + else if (packed()) { cover("kernel.rtlil.sigspec.check.packed"); From 2f54345cff3aea768bb89754654127a3b0ee58e9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 15:06:45 +0200 Subject: [PATCH 399/750] Added "cover" command --- Makefile | 2 +- kernel/driver.cc | 11 +--- kernel/log.h | 41 +++++++++++--- kernel/register.cc | 28 ++++++---- kernel/register.h | 9 +-- passes/cmds/Makefile.inc | 1 + passes/cmds/cover.cc | 115 +++++++++++++++++++++++++++++++++++++++ passes/cmds/tee.cc | 2 +- 8 files changed, 175 insertions(+), 34 deletions(-) create mode 100644 passes/cmds/cover.cc diff --git a/Makefile b/Makefile index 10bd9407..272161ef 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ TARGETS = yosys yosys-config all: top-all -CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -D_YOSYS_ -fPIC -I${DESTDIR}/include +CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -DYOSYS_SRC='"$(shell pwd)"' -D_YOSYS_ -fPIC -I${DESTDIR}/include LDFLAGS = -L${DESTDIR}/lib LDLIBS = -lstdc++ -lreadline -lm -ldl QMAKE = qmake-qt4 diff --git a/kernel/driver.cc b/kernel/driver.cc index 64165737..a4556fb1 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -768,16 +768,9 @@ int main(int argc, char **argv) log("\n", filename_buffer); - std::map> coverage_data; - for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { - if (coverage_data.count(p->id)) - log("WARNING: found duplicate coverage id \"%s\".\n", p->id); - coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); - coverage_data[p->id].second += p->counter; - } + for (auto &it : get_coverage_data()) + fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); - for (auto &it : coverage_data) - fprintf(f, "%-40s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); fclose(f); } #endif diff --git a/kernel/log.h b/kernel/log.h index 80417590..0e8d0827 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -21,7 +21,10 @@ #define LOG_H #include "kernel/rtlil.h" +#include "kernel/register.h" + #include +#include #include #include #include @@ -68,22 +71,46 @@ void log_cell(RTLIL::Cell *cell, std::string indent = ""); // This is the magic behind the code coverage counters // --------------------------------------------------- +#ifndef NDEBUG + +#define cover(_id) do { \ + static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1))) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ + __d.counter++; \ +} while (0) + struct CoverData { const char *file, *func, *id; int line, counter; } __attribute__ ((packed)); // this two symbols are created by the linker for the "yosys_cover_list" ELF section -#ifndef NDEBUG extern "C" struct CoverData __start_yosys_cover_list[]; extern "C" struct CoverData __stop_yosys_cover_list[]; -#endif -#ifndef NDEBUG -# define cover(_id) do { \ - static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1))) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ - __d.counter++; \ - } while (0) +static inline std::map> get_coverage_data() +{ + std::map> coverage_data; + + for (auto &it : REGISTER_INTERN::pass_register) { + std::string key = stringf("passes.%s", it.first.c_str()); + coverage_data[key].first = stringf("%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); + coverage_data[key].second += it.second->call_counter; + } + + for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { + if (coverage_data.count(p->id)) + log("WARNING: found duplicate coverage id \"%s\".\n", p->id); + coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); + coverage_data[p->id].second += p->counter; + } + + for (auto &it : coverage_data) + if (!it.second.first.compare(0, strlen(YOSYS_SRC "/"), YOSYS_SRC "/")) + it.second.first = it.second.first.substr(strlen(YOSYS_SRC "/")); + + return coverage_data; +} + #else # define cover(_id) do { } while (0) #endif diff --git a/kernel/register.cc b/kernel/register.cc index 84051948..e7ad7ef0 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -32,9 +32,7 @@ using namespace REGISTER_INTERN; namespace REGISTER_INTERN { bool echo_mode = false; - int raw_register_count = 0; - bool raw_register_done = false; - Pass *raw_register_array[MAX_REG_COUNT]; + Pass *first_queued_pass; std::map frontend_register; std::map pass_register; @@ -45,9 +43,9 @@ std::vector Frontend::next_args; Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_help(short_help) { - assert(!raw_register_done); - assert(raw_register_count < MAX_REG_COUNT); - raw_register_array[raw_register_count++] = this; + next_queued_pass = first_queued_pass; + first_queued_pass = this; + call_counter = 0; } void Pass::run_register() @@ -58,11 +56,10 @@ void Pass::run_register() void Pass::init_register() { - if (raw_register_done) - done_register(); - while (raw_register_count > 0) - raw_register_array[--raw_register_count]->run_register(); - raw_register_done = true; + while (first_queued_pass) { + first_queued_pass->run_register(); + first_queued_pass = first_queued_pass->next_queued_pass; + } } void Pass::done_register() @@ -70,7 +67,7 @@ void Pass::done_register() frontend_register.clear(); pass_register.clear(); backend_register.clear(); - raw_register_done = false; + assert(first_queued_pass == NULL); } Pass::~Pass() @@ -191,6 +188,7 @@ void Pass::call(RTLIL::Design *design, std::vector args) log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str()); size_t orig_sel_stack_pos = design->selection_stack.size(); + pass_register[args[0]]->call_counter++; pass_register[args[0]]->execute(args, design); while (design->selection_stack.size() > orig_sel_stack_pos) design->selection_stack.pop_back(); @@ -271,6 +269,7 @@ void Frontend::execute(std::vector args, RTLIL::Design *design) do { FILE *f = NULL; next_args.clear(); + call_counter++; execute(f, std::string(), args, design); args = next_args; fclose(f); @@ -334,9 +333,11 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam log_cmd_error("No such frontend: %s\n", args[0].c_str()); if (f != NULL) { + frontend_register[args[0]]->call_counter++; frontend_register[args[0]]->execute(f, filename, args, design); } else if (filename == "-") { FILE *f_stdin = stdin; // workaround for OpenBSD 'stdin' implementation + frontend_register[args[0]]->call_counter++; frontend_register[args[0]]->execute(f_stdin, "", args, design); } else { if (!filename.empty()) @@ -367,6 +368,7 @@ Backend::~Backend() void Backend::execute(std::vector args, RTLIL::Design *design) { FILE *f = NULL; + call_counter++; execute(f, std::string(), args, design); if (f != stdout) fclose(f); @@ -428,9 +430,11 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, size_t orig_sel_stack_pos = design->selection_stack.size(); if (f != NULL) { + backend_register[args[0]]->call_counter++; backend_register[args[0]]->execute(f, filename, args, design); } else if (filename == "-") { FILE *f_stdout = stdout; // workaround for OpenBSD 'stdout' implementation + backend_register[args[0]]->call_counter++; backend_register[args[0]]->execute(f_stdout, "", args, design); } else { if (!filename.empty()) diff --git a/kernel/register.h b/kernel/register.h index b07c4617..fd073cbe 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -47,9 +47,11 @@ extern std::vector pushed_designs; struct Pass { std::string pass_name, short_help; + int call_counter; + Pass(std::string name, std::string short_help = "** document me **"); - virtual void run_register(); virtual ~Pass(); + virtual void help(); virtual void execute(std::vector args, RTLIL::Design *design) = 0; @@ -66,6 +68,8 @@ struct Pass static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command); static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vector args); + Pass *next_queued_pass; + virtual void run_register(); static void init_register(); static void done_register(); }; @@ -105,9 +109,6 @@ struct Backend : Pass extern void handle_extra_select_args(Pass *pass, std::vector args, size_t argidx, size_t args_size, RTLIL::Design *design); namespace REGISTER_INTERN { - extern int raw_register_count; - extern bool raw_register_done; - extern Pass *raw_register_array[]; extern std::map pass_register; extern std::map frontend_register; extern std::map backend_register; diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 3a4b2da7..6ae4495a 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -17,4 +17,5 @@ OBJS += passes/cmds/scc.o OBJS += passes/cmds/log.o OBJS += passes/cmds/tee.o OBJS += passes/cmds/connwrappers.o +OBJS += passes/cmds/cover.o diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc new file mode 100644 index 00000000..ebbdc7c4 --- /dev/null +++ b/passes/cmds/cover.cc @@ -0,0 +1,115 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 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/rtlil.h" +#include "kernel/log.h" + +struct CoverPass : public Pass { + CoverPass() : Pass("cover", "print code coverage counters") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" cover [-q] [-o logfile|-a logfile]\n"); + log("\n"); + log("Print the code coverage counters collected using the cover() macro in the Yosys\n"); + log("C++ code. This is useful to figure out what parts of Yosys are utilized by a\n"); + log("test bench.\n"); + log("\n"); + log(" -q\n"); + log(" Do not print output to the normal destination (console and/or log file)\n"); + log("\n"); + log(" -o logfile\n"); + log(" Write output to this file, truncate if exists.\n"); + log("\n"); + log(" -a logfile\n"); + log(" Write output to this file, append if exists.\n"); + log("\n"); + log("\n"); + log("It is also possible to instruct Yosys to print the coverage counters to a file\n"); + log("using environment variables.\n"); + log("\n"); + log(" YOSYS_COVER_DIR=\"{dir-name}\" yosys {args}n"); + log("\n"); + log(" This will create a file (with an auto-generated name) in this\n"); + log(" directory and wire the coverage counters to it.\n"); + log("\n"); + log(" YOSYS_COVER_FILE=\"{file-name}\" yosys {args}n"); + log("\n"); + log(" This will append the coverage counters to the specified file.\n"); + log("\n"); + log("\n"); + log("Hint: Use the following AWK command to consolidate Yosys coverage files:\n"); + log("\n"); + log(" gawk '{ p[$3] = $1; c[$3] += $2; } END { for (i in p)\n"); + log(" printf \"%%-60s %%10d %%s\\n\", p[i], c[i], i; }' {files} | sort -k3\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + std::vector out_files; + bool do_log = true; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-q") { + do_log = false; + continue; + } + if ((args[argidx] == "-o" || args[argidx] == "-a") && argidx+1 < args.size()) { + const char *open_mode = args[argidx] == "-o" ? "w" : "a+"; + FILE *f = fopen(args[++argidx].c_str(), open_mode); + if (f == NULL) { + for (auto f : out_files) + fclose(f); + log_cmd_error("Can't create file %s.\n", args[argidx].c_str()); + } + out_files.push_back(f); + continue; + } + break; + } + extra_args(args, argidx, design); + + if (do_log) { + log_header("Printing code coverage counters.\n"); + log("\n"); + } + +#ifndef NDEBUG + for (auto &it : get_coverage_data()) { + for (auto f : out_files) + fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); + if (do_log) + log("%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); + } +#else + for (auto f : out_files) + fclose(f); + + log_cmd_error("Coverage counters are only available in debug builds of Yosys."); +#endif + + for (auto f : out_files) + fclose(f); + } +} CoverPass; + diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index dd959195..e2f69e59 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -56,7 +56,7 @@ struct TeePass : public Pass { continue; } if ((args[argidx] == "-o" || args[argidx] == "-a") && argidx+1 < args.size()) { - const char *open_mode = args[argidx] == "-o" ? "wt" : "at"; + const char *open_mode = args[argidx] == "-o" ? "w" : "a+"; FILE *f = fopen(args[++argidx].c_str(), open_mode); if (f == NULL) { for (auto cf : files_to_close) From b17d6531c833f9064c5888c694aa24e8a395b72a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:15:01 +0200 Subject: [PATCH 400/750] Added "make PRETTY=1" --- Makefile | 42 ++++++++++++++++++++++++---------- frontends/ilang/Makefile.inc | 6 ++--- frontends/verilog/Makefile.inc | 6 ++--- passes/techmap/Makefile.inc | 12 +++++----- techlibs/common/Makefile.inc | 20 ++++++++-------- techlibs/xilinx/Makefile.inc | 4 ++-- 6 files changed, 54 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 272161ef..d57d02b2 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,11 @@ YOSYS_VER := 0.3.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o +PRETTY = 0 +P = +Q = +S = + # set 'ABCREV = default' to use abc/ as it is # # Note: If you do ABC development, make sure that 'abc' in this directory @@ -102,6 +107,12 @@ CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABL LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif +ifeq ($(PRETTY), 1) +P = @echo "Building $@"; +Q = @ +S = -s +endif + OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o OBJS += kernel/compatibility.o @@ -127,41 +138,48 @@ include techlibs/*/Makefile.inc top-all: $(TARGETS) $(EXTRA_TARGETS) yosys: $(OBJS) - $(CXX) -o yosys $(LDFLAGS) $(OBJS) $(LDLIBS) + $(P) $(CXX) -o yosys $(LDFLAGS) $(OBJS) $(LDLIBS) + +%.o: %.cc + $(P) $(CXX) -o $@ -c $(CXXFLAGS) $< + +%.o: %.cpp + $(P) $(CXX) -o $@ -c $(CXXFLAGS) $< kernel/version_$(GIT_REV).cc: Makefile - rm -f kernel/version_*.o kernel/version_*.d kernel/version_*.cc - echo "extern const char *yosys_version_str; const char *yosys_version_str=\"Yosys $(YOSYS_VER) (git sha1 $(GIT_REV))\";" > kernel/version_$(GIT_REV).cc + $(P) rm -f kernel/version_*.o kernel/version_*.d kernel/version_*.cc + $(Q) echo "extern const char *yosys_version_str; const char *yosys_version_str=\"Yosys $(YOSYS_VER) (git sha1 $(GIT_REV))\";" > kernel/version_$(GIT_REV).cc yosys-config: yosys-config.in - $(SED) -e 's,@CXX@,$(CXX),;' -e 's,@CXXFLAGS@,$(CXXFLAGS),;' -e 's,@LDFLAGS@,$(LDFLAGS),;' -e 's,@LDLIBS@,$(LDLIBS),;' \ + $(P) $(SED) -e 's,@CXX@,$(CXX),;' -e 's,@CXXFLAGS@,$(CXXFLAGS),;' -e 's,@LDFLAGS@,$(LDFLAGS),;' -e 's,@LDLIBS@,$(LDLIBS),;' \ -e 's,@BINDIR@,$(DESTDIR)/bin,;' -e 's,@DATDIR@,$(DESTDIR)/share/yosys,;' < yosys-config.in > yosys-config - chmod +x yosys-config + $(Q) chmod +x yosys-config yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp - cd libs/svgviewer && $(QMAKE) && make - cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer + $(P) cd libs/svgviewer && $(QMAKE) && $(MAKE) $(S) + $(Q) cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer abc/abc-$(ABCREV): + $(P) ifneq ($(ABCREV),default) - if ( cd abc && hg identify; ) | grep -q +; then \ + $(Q) if ( cd abc && hg identify; ) | grep -q +; then \ echo 'REEBE: NOP pbagnvaf ybpny zbqvsvpngvbaf! Frg NOPERI=qrsnhyg va Lbflf Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi - if test "`cd abc && hg identify | cut -f1 -d' '`" != "$(ABCREV)"; then \ + $(Q) if test "`cd abc && hg identify | cut -f1 -d' '`" != "$(ABCREV)"; then \ test $(ABCPULL) -ne 0 || { echo 'REEBE: NOP abg hc gb qngr naq NOPCHYY frg gb 0 va Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; exit 1; }; \ test -d abc || hg clone https://bitbucket.org/alanmi/abc abc; \ cd abc && hg pull && hg update -r $(ABCREV); \ fi endif - rm -f abc/abc-[0-9a-f]* - cd abc && $(MAKE) PROG="abc-$(ABCREV)" MSG_PREFIX="YOSYS-ABC: " + $(Q) rm -f abc/abc-[0-9a-f]* + $(Q) cd abc && $(MAKE) $(S) PROG="abc-$(ABCREV)" MSG_PREFIX="YOSYS-ABC: " ifeq ($(ABCREV),default) .PHONY: abc/abc-$(ABCREV) endif yosys-abc: abc/abc-$(ABCREV) - cp abc/abc-$(ABCREV) yosys-abc + $(P) cp abc/abc-$(ABCREV) yosys-abc test: $(TARGETS) $(EXTRA_TARGETS) cd tests/simple && bash run-test.sh diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc index f81c8de9..e832cfed 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 5586b4cc..49eb320e 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 diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 85d580ce..c901da1c 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -10,11 +10,11 @@ OBJS += passes/techmap/extract.o GENFILES += passes/techmap/stdcells.inc passes/techmap/stdcells.inc: techlibs/common/stdcells.v - echo "// autogenerated from $<" > $@.new - echo "static char stdcells_code[] = {" >> $@.new - od -v -td1 -An $< | $(SED) -e 's/[0-9][0-9]*/&,/g' >> $@.new - echo "0};" >> $@.new - mv $@.new $@ + $(P) echo "// autogenerated from $<" > $@.new + $(Q) echo "static char stdcells_code[] = {" >> $@.new + $(Q) od -v -td1 -An $< | $(SED) -e 's/[0-9][0-9]*/&,/g' >> $@.new + $(Q) echo "0};" >> $@.new + $(Q) mv $@.new $@ passes/techmap/techmap.o: passes/techmap/stdcells.inc @@ -22,5 +22,5 @@ TARGETS += yosys-filterlib GENFILES += passes/techmap/filterlib.o yosys-filterlib: passes/techmap/filterlib.o - $(CXX) -o yosys-filterlib $(LDFLAGS) $^ $(LDLIBS) + $(P) $(CXX) -o yosys-filterlib $(LDFLAGS) $^ $(LDLIBS) diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index c68b13f6..a76d1a07 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -2,24 +2,24 @@ EXTRA_TARGETS += techlibs/common/blackbox.v techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib.v techlibs/common/simcells.v - cat techlibs/common/simlib.v techlibs/common/simcells.v | $(SED) -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new - mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v + $(P) cat techlibs/common/simlib.v techlibs/common/simcells.v | $(SED) -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new + $(Q) mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v EXTRA_TARGETS += share/simlib.v share/simcells.v share/blackbox.v share/pmux2mux.v share/simlib.v: techlibs/common/simlib.v - mkdir -p share - cp techlibs/common/simlib.v share/simlib.v + $(P) mkdir -p share + $(Q) cp techlibs/common/simlib.v share/simlib.v share/simcells.v: techlibs/common/simcells.v - mkdir -p share - cp techlibs/common/simcells.v share/simcells.v + $(P) mkdir -p share + $(Q) cp techlibs/common/simcells.v share/simcells.v share/blackbox.v: techlibs/common/blackbox.v - mkdir -p share - cp techlibs/common/blackbox.v share/blackbox.v + $(P) mkdir -p share + $(Q) cp techlibs/common/blackbox.v share/blackbox.v share/pmux2mux.v: techlibs/common/pmux2mux.v - mkdir -p share - cp techlibs/common/pmux2mux.v share/pmux2mux.v + $(P) mkdir -p share + $(Q) cp techlibs/common/pmux2mux.v share/pmux2mux.v diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc index f88390f7..cd19f10e 100644 --- a/techlibs/xilinx/Makefile.inc +++ b/techlibs/xilinx/Makefile.inc @@ -4,6 +4,6 @@ OBJS += techlibs/xilinx/synth_xilinx.o EXTRA_TARGETS += share/xilinx/cells.v share/xilinx/cells.v: techlibs/xilinx/cells.v - mkdir -p share/xilinx - cp techlibs/xilinx/cells.v share/xilinx/cells.v + $(P) mkdir -p share/xilinx + $(Q) cp techlibs/xilinx/cells.v share/xilinx/cells.v From 38afbe62ef61bd9b1aa92575cad7ff1785ce5e0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:53:11 +0200 Subject: [PATCH 401/750] Added percentage display to "make PRETTY=1" --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d57d02b2..a962c7e3 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,9 @@ LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif ifeq ($(PRETTY), 1) -P = @echo "Building $@"; +I = 0 +P = @echo "$(eval I=$(shell bash -c 'i=0; for x in $(OBJS) yosys; do ((i++)); [ "$$x" = "$@" -a $I -lt $$i ] && echo $$i && exit; done; echo $I'))[$(shell \ + gawk "BEGIN { N=`echo $(OBJS) yosys | wc -w`; printf \"%3d\", 100*$I/N; exit; }")%] Building $@"; Q = @ S = -s endif From 34ea9e3f098925a7e107f2da265ff27b6b9985be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:55:55 +0200 Subject: [PATCH 402/750] Now "make PRETTY=1" is the default setting --- Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index a962c7e3..e061b9c7 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ GENFILES = EXTRA_TARGETS = TARGETS = yosys yosys-config +PRETTY = 1 + all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -DYOSYS_SRC='"$(shell pwd)"' -D_YOSYS_ -fPIC -I${DESTDIR}/include @@ -44,11 +46,6 @@ YOSYS_VER := 0.3.0+ GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o -PRETTY = 0 -P = -Q = -S = - # set 'ABCREV = default' to use abc/ as it is # # Note: If you do ABC development, make sure that 'abc' in this directory @@ -113,6 +110,11 @@ P = @echo "$(eval I=$(shell bash -c 'i=0; for x in $(OBJS) yosys; do ((i++)); [ gawk "BEGIN { N=`echo $(OBJS) yosys | wc -w`; printf \"%3d\", 100*$I/N; exit; }")%] Building $@"; Q = @ S = -s +else +I = +P = +Q = +S = endif OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o From 45b4154b3799178a432d1f14dcaf51787b86f35d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 19:03:57 +0200 Subject: [PATCH 403/750] Added "make SMALL=1" --- Makefile | 26 ++++++++++++++++++++++++++ passes/techmap/Makefile.inc | 5 ++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e061b9c7..e4e0287e 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ EXTRA_TARGETS = TARGETS = yosys yosys-config PRETTY = 1 +SMALL = 0 all: top-all @@ -124,6 +125,9 @@ OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/ OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o OBJS += libs/sha1/sha1.o + +ifneq ($(SMALL),1) + OBJS += libs/subcircuit/subcircuit.o OBJS += libs/ezsat/ezsat.o @@ -139,6 +143,28 @@ include passes/*/Makefile.inc include backends/*/Makefile.inc include techlibs/*/Makefile.inc +else + +include frontends/verilog/Makefile.inc +include frontends/ilang/Makefile.inc +include frontends/ast/Makefile.inc + +OBJS += passes/hierarchy/hierarchy.o +OBJS += passes/cmds/select.o +OBJS += passes/cmds/show.o +OBJS += passes/cmds/stat.o +OBJS += passes/cmds/cover.o + +include passes/proc/Makefile.inc +include passes/opt/Makefile.inc +include passes/techmap/Makefile.inc +include passes/abc/Makefile.inc + +include backends/verilog/Makefile.inc +include backends/ilang/Makefile.inc + +endif + top-all: $(TARGETS) $(EXTRA_TARGETS) yosys: $(OBJS) diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index c901da1c..e54c018a 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -2,10 +2,13 @@ OBJS += passes/techmap/techmap.o OBJS += passes/techmap/simplemap.o OBJS += passes/techmap/dfflibmap.o +OBJS += passes/techmap/libparse.o + +ifneq ($(SMALL),1) OBJS += passes/techmap/iopadmap.o OBJS += passes/techmap/hilomap.o -OBJS += passes/techmap/libparse.o OBJS += passes/techmap/extract.o +endif GENFILES += passes/techmap/stdcells.inc From 10d2402e2f3cd49bd8c4e0cddb01c90c5615bb05 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 19:36:20 +0200 Subject: [PATCH 404/750] Added cover_list() API --- kernel/log.cc | 3 +++ kernel/log.h | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 949bf432..63a0a84d 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -29,6 +29,9 @@ #include #include +// declared extern in log.h +std::map> extra_coverage_data; + std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; diff --git a/kernel/log.h b/kernel/log.h index 0e8d0827..18ea528a 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -30,6 +30,10 @@ #include #include +#define S__LINE__sub2(x) #x +#define S__LINE__sub1(x) S__LINE__sub2(x) +#define S__LINE__ S__LINE__sub1(__LINE__) + extern std::vector log_files; extern FILE *log_errfile; extern bool log_time; @@ -87,6 +91,19 @@ struct CoverData { extern "C" struct CoverData __start_yosys_cover_list[]; extern "C" struct CoverData __stop_yosys_cover_list[]; +extern std::map> extra_coverage_data; + +static inline void cover_extra(std::string parent, std::string id, bool increment = true) { + if (extra_coverage_data.count(id) == 0) { + for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) + if (p->id == parent) + extra_coverage_data[id].first = stringf("%s:%d:%s", p->file, p->line, p->func); + log_assert(extra_coverage_data.count(id)); + } + if (increment) + extra_coverage_data[id].second++; +} + static inline std::map> get_coverage_data() { std::map> coverage_data; @@ -97,6 +114,13 @@ static inline std::map> get_coverage_da coverage_data[key].second += it.second->call_counter; } + for (auto &it : extra_coverage_data) { + if (coverage_data.count(it.first)) + log("WARNING: found duplicate coverage id \"%s\".\n", it.first.c_str()); + coverage_data[it.first].first = it.second.first; + coverage_data[it.first].second += it.second.second; + } + for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { if (coverage_data.count(p->id)) log("WARNING: found duplicate coverage id \"%s\".\n", p->id); @@ -111,8 +135,25 @@ static inline std::map> get_coverage_da return coverage_data; } +#define cover_list(_id, ...) do { cover(_id); \ + std::string r = cover_list_worker(_id, __VA_ARGS__); \ + log_assert(r.empty()); \ +} while (0) + +static inline std::string cover_list_worker(std::string, std::string last) { + return last; +} + +template +std::string cover_list_worker(std::string prefix, std::string first, T... rest) { + std::string selected = cover_list_worker(prefix, rest...); + cover_extra(prefix, prefix + "." + first, first == selected); + return first == selected ? "" : selected; +} + #else -# define cover(_id) do { } while (0) +# define cover(...) do { } while (0) +# define cover_list(...) do { } while (0) #endif @@ -196,7 +237,7 @@ static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } template static inline void log_dump_val_worker(T *ptr) { log("%p", ptr); } -template +template void log_dump_args_worker(const char *p, T first, Args ... args) { int next_p_state = 0; From 9962384d3ed26ea0707f1ed8ebef91593d1a42a4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 19:36:43 +0200 Subject: [PATCH 405/750] Added cover() calls to opt_const --- passes/opt/opt_const.cc | 54 ++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 800fbf10..e2bf7004 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -183,6 +183,8 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com log("\n"); } + cover_list("opt.opt_const.fine.group", "$not", "$pos", "$bu0", "$and", "$or", "$xor", "$xnor", cell->type); + module->remove(cell); OPT_DID_SOMETHING = true; did_something = true; @@ -209,7 +211,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (auto cell : cells) { -#define ACTION_DO(_p_, _s_) do { replace_cell(module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) +#define ACTION_DO(_p_, _s_) do { cover("opt.opt_const.action_" S__LINE__); replace_cell(module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO_Y(_v_) ACTION_DO("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) if (do_fine) @@ -236,6 +238,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a != RTLIL::State::Sm && RTLIL::SigSpec(new_a) != sig_a) { + cover("opt.opt_const.fine.$reduce_and"); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); cell->connections.at("\\A") = sig_a = new_a; @@ -262,6 +265,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a != RTLIL::State::Sm && RTLIL::SigSpec(new_a) != sig_a) { + cover_list("opt.opt_const.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); cell->connections.at("\\A") = sig_a = new_a; @@ -288,6 +292,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_b != RTLIL::State::Sm && RTLIL::SigSpec(new_b) != sig_b) { + cover_list("opt.opt_const.fine.B", "$logic_and", "$logic_or", cell->type); log("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); cell->connections.at("\\B") = sig_b = new_b; @@ -299,11 +304,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (cell->type == "$logic_or" && (assign_map(cell->connections.at("\\A")) == RTLIL::State::S1 || assign_map(cell->connections.at("\\B")) == RTLIL::State::S1)) { + cover("opt.opt_const.one_high"); replace_cell(module, cell, "one high", "\\Y", RTLIL::State::S1); goto next_cell; } if (cell->type == "$logic_and" && (assign_map(cell->connections.at("\\A")) == RTLIL::State::S0 || assign_map(cell->connections.at("\\B")) == RTLIL::State::S0)) { + cover("opt.opt_const.one_low"); replace_cell(module, cell, "one low", "\\Y", RTLIL::State::S0); goto next_cell; } @@ -330,6 +337,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (0) { found_the_x_bit: + cover_list("opt.opt_const.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$lt", "$le", "$ge", "$gt", + "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); @@ -341,11 +350,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].size() == 1 && invert_map.count(assign_map(cell->connections["\\A"])) != 0) { + cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections["\\A"]))); goto next_cell; } if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->connections["\\S"])) != 0) { + cover_list("opt.opt_const.invert.muxsel", "$_MUX_", "$mux", cell->type); RTLIL::SigSpec tmp = cell->connections["\\A"]; cell->connections["\\A"] = cell->connections["\\B"]; cell->connections["\\B"] = tmp; @@ -428,6 +439,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (input.match(" 1")) ACTION_DO("\\Y", input.extract(1, 1)); if (input.match("01 ")) ACTION_DO("\\Y", input.extract(0, 1)); if (input.match("10 ")) { + cover("opt.opt_const.mux_to_inv"); cell->type = "$_INV_"; cell->connections["\\A"] = input.extract(0, 1); cell->connections.erase("\\B"); @@ -462,9 +474,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo assert(SIZE(a) == SIZE(b)); for (int i = 0; i < SIZE(a); i++) { if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) { + cover_list("opt.opt_const.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type); RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S0 : RTLIL::State::S1); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); - replace_cell(module, cell, "empty", "\\Y", new_y); + replace_cell(module, cell, "isneq", "\\Y", new_y); goto next_cell; } if (a[i] == b[i]) @@ -474,6 +487,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a.size() == 0) { + cover_list("opt.opt_const.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type); RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S1 : RTLIL::State::S0); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(module, cell, "empty", "\\Y", new_y); @@ -481,6 +495,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a.size() < a.size() || new_b.size() < b.size()) { + cover_list("opt.opt_const.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type); cell->connections["\\A"] = new_a; cell->connections["\\B"] = new_b; cell->parameters["\\A_WIDTH"] = new_a.size(); @@ -495,10 +510,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); if (a.is_fully_const()) { - RTLIL::SigSpec tmp; - tmp = a, a = b, b = tmp; - cell->connections["\\A"] = a; - cell->connections["\\B"] = b; + cover_list("opt.opt_const.eqneq.swapconst", "$eq", "$ne", cell->type); + std::swap(cell->connections["\\A"], cell->connections["\\B"]); } if (b.is_fully_const()) { @@ -506,6 +519,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec input = b; ACTION_DO("\\Y", cell->connections["\\A"]); } else { + cover_list("opt.opt_const.eqneq.isnot", "$eq", "$ne", cell->type); cell->type = "$not"; cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); @@ -563,6 +577,11 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (identity_wrt_a || identity_wrt_b) { + if (identity_wrt_a) + cover_list("opt.opt_const.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$mul", "$div", cell->type); + if (identity_wrt_b) + cover_list("opt.opt_const.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$mul", "$div", cell->type); + log("Replacing %s cell `%s' in module `%s' with identity for port %c.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); @@ -586,12 +605,14 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections["\\A"] == RTLIL::SigSpec(0, 1) && cell->connections["\\B"] == RTLIL::SigSpec(1, 1)) { + cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); replace_cell(module, cell, "mux_bool", "\\Y", cell->connections["\\S"]); goto next_cell; } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections["\\A"] == RTLIL::SigSpec(1, 1) && cell->connections["\\B"] == RTLIL::SigSpec(0, 1)) { + cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type); cell->connections["\\A"] = cell->connections["\\S"]; cell->connections.erase("\\B"); cell->connections.erase("\\S"); @@ -609,6 +630,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections["\\A"] == RTLIL::SigSpec(0, 1)) { + cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type); cell->connections["\\A"] = cell->connections["\\S"]; cell->connections.erase("\\S"); if (cell->type == "$mux") { @@ -627,6 +649,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections["\\B"] == RTLIL::SigSpec(1, 1)) { + cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type); cell->connections["\\B"] = cell->connections["\\S"]; cell->connections.erase("\\S"); if (cell->type == "$mux") { @@ -649,7 +672,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo int width = cell->connections.at("\\A").size(); if ((cell->connections.at("\\A").is_fully_undef() && cell->connections.at("\\B").is_fully_undef()) || cell->connections.at("\\S").is_fully_undef()) { - replace_cell(module, cell, "mux undef", "\\Y", cell->connections.at("\\A")); + cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); + replace_cell(module, cell, "mux_undef", "\\Y", cell->connections.at("\\A")); goto next_cell; } for (int i = 0; i < cell->connections.at("\\S").size(); i++) { @@ -667,14 +691,17 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo new_s = new_s.extract(0, new_s.size()-1); } if (new_s.size() == 0) { - replace_cell(module, cell, "mux undef", "\\Y", new_a); + cover_list("opt.opt_const.mux_empty", "$mux", "$pmux", cell->type); + replace_cell(module, cell, "mux_empty", "\\Y", new_a); goto next_cell; } if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { - replace_cell(module, cell, "mux undef", "\\Y", new_s); + cover_list("opt.opt_const.mux_sel01", "$mux", "$pmux", cell->type); + replace_cell(module, cell, "mux_sel01", "\\Y", new_s); goto next_cell; } if (cell->connections.at("\\S").size() != new_s.size()) { + cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type); cell->connections.at("\\A") = new_a; cell->connections.at("\\B") = new_b; cell->connections.at("\\S") = new_s; @@ -699,6 +726,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), dummy_arg, \ cell->parameters["\\A_SIGNED"].as_bool(), false, \ cell->parameters["\\Y_WIDTH"].as_int())); \ + cover("opt.opt_const.const.$" #_t); \ replace_cell(module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ goto next_cell; \ } \ @@ -713,6 +741,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->parameters["\\A_SIGNED"].as_bool(), \ cell->parameters["\\B_SIGNED"].as_bool(), \ cell->parameters["\\Y_WIDTH"].as_int())); \ + cover("opt.opt_const.const.$" #_t); \ replace_cell(module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), "\\Y", y); \ goto next_cell; \ } \ @@ -787,6 +816,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (a_val == 0) { + cover("opt.opt_const.mul_shift.zero"); + log("Replacing multiply-by-zero cell `%s' in module `%s' with zero-driver.\n", cell->name.c_str(), module->name.c_str()); @@ -801,6 +832,11 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (int i = 1; i < (a_signed ? sig_a.size()-1 : sig_a.size()); i++) if (a_val == (1 << i)) { + if (swapped_ab) + cover("opt.opt_const.mul_shift.swapped"); + else + cover("opt.opt_const.mul_shift.unswapped"); + log("Replacing multiply-by-%d cell `%s' in module `%s' with shift-by-%d.\n", a_val, cell->name.c_str(), module->name.c_str(), i); From 7a608437c65e9646ed229055d61b310e7d93e37e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 20:57:21 +0200 Subject: [PATCH 406/750] Updated ABC to hg id "b1e63d18768d" --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e4e0287e..3919b3f1 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 7600ffb9340c +ABCREV = b1e63d18768d ABCPULL = 1 -include Makefile.conf From 6aa792c864444324a1b140c2b63bd860f0cc3914 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 22:47:57 +0200 Subject: [PATCH 407/750] Replaced more old SigChunk programming patterns --- backends/autotest/autotest.cc | 5 ++-- backends/blif/blif.cc | 14 +++++------- backends/edif/edif.cc | 15 +++++------- backends/ilang/ilang_backend.cc | 2 +- backends/intersynth/intersynth.cc | 16 +++++-------- backends/spice/spice.cc | 16 ++++++------- frontends/ast/genrtlil.cc | 14 ++++++------ kernel/bitpattern.h | 10 +++----- kernel/consteval.h | 6 ++--- kernel/rtlil.cc | 17 ++++++++++++++ kernel/rtlil.h | 4 +++- passes/abc/abc.cc | 38 +++++++++++++++---------------- passes/cmds/show.cc | 4 ++-- passes/memory/memory_collect.cc | 10 ++++---- passes/opt/opt_clean.cc | 13 ++++------- passes/proc/proc_dff.cc | 2 +- passes/proc/proc_init.cc | 19 ++++++++-------- 17 files changed, 101 insertions(+), 104 deletions(-) diff --git a/backends/autotest/autotest.cc b/backends/autotest/autotest.cc index 028d1f37..db49880a 100644 --- a/backends/autotest/autotest.cc +++ b/backends/autotest/autotest.cc @@ -119,10 +119,9 @@ static void autotest(FILE *f, RTLIL::Design *design) if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1) continue; RTLIL::SigSpec &signal = (*it4)->signal; - for (size_t i = 0; i < signal.chunks().size(); i++) { - if (signal.chunks()[i].wire == wire) + for (auto &c : signal.chunks()) + if (c.wire == wire) is_clksignal = true; - } } if (is_clksignal && wire->attributes.count("\\gentb_constant") == 0) { signal_clk[idy("sig", mod->name, wire->name)] = wire->width; diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index d0c25079..fc090cfe 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -68,20 +68,18 @@ struct BlifDumper return cstr_buf.back().c_str(); } - const char *cstr(RTLIL::SigSpec sig) + const char *cstr(RTLIL::SigBit sig) { - log_assert(sig.size() == 1); + if (sig.wire == NULL) + return sig == RTLIL::State::S1 ? "$true" : "$false"; - if (sig.chunks().at(0).wire == NULL) - return sig.chunks().at(0).data.bits.at(0) == RTLIL::State::S1 ? "$true" : "$false"; - - std::string str = RTLIL::unescape_id(sig.chunks().at(0).wire->name); + std::string str = RTLIL::unescape_id(sig.wire->name); for (size_t i = 0; i < str.size(); i++) if (str[i] == '#' || str[i] == '=') str[i] = '?'; - if (sig.chunks().at(0).wire->width != 1) - str += stringf("[%d]", sig.chunks().at(0).offset); + if (sig.wire->width != 1) + str += stringf("[%d]", sig.offset); cstr_buf.push_back(str); return cstr_buf.back().c_str(); diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 8f36f409..a3ae9649 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -314,12 +314,9 @@ struct EdifBackend : public Backend { } } for (auto &it : net_join_db) { - RTLIL::SigSpec sig = it.first; - log_assert(sig.size() == 1); - if (sig.chunks().at(0).wire == NULL) { - if (sig.chunks().at(0).data.bits.at(0) != RTLIL::State::S0 && sig.chunks().at(0).data.bits.at(0) != RTLIL::State::S1) - continue; - } + RTLIL::SigBit sig = it.first; + if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1) + continue; std::string netname = log_signal(sig); for (size_t i = 0; i < netname.size(); i++) if (netname[i] == ' ' || netname[i] == '\\') @@ -327,10 +324,10 @@ struct EdifBackend : public Backend { fprintf(f, " (net %s (joined\n", EDIF_DEF(netname)); for (auto &ref : it.second) fprintf(f, " %s\n", ref.c_str()); - if (sig.chunks().at(0).wire == NULL) { - if (sig.chunks().at(0).data.bits.at(0) == RTLIL::State::S0) + if (sig.wire == NULL) { + if (sig == RTLIL::State::S0) fprintf(f, " (portRef G (instanceRef GND))\n"); - if (sig.chunks().at(0).data.bits.at(0) == RTLIL::State::S1) + if (sig == RTLIL::State::S1) fprintf(f, " (portRef P (instanceRef VCC))\n"); } fprintf(f, " ))\n"); diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index a312b02c..e3093e37 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -103,7 +103,7 @@ void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool au void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint) { if (sig.chunks().size() == 1) { - dump_sigchunk(f, sig.chunks()[0], autoint); + dump_sigchunk(f, sig.chunks().front(), autoint); } else { fprintf(f, "{ "); for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) { diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index a4cad5ad..b2e472bf 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -28,23 +28,19 @@ static std::string netname(std::set &conntypes_code, std::set &celltypes_code, std::set &constcells_code, RTLIL::SigSpec sig) { - if (sig.chunks().size() != 1) -error: + if (!sig.is_fully_const() && !sig.is_wire()) log_error("Can't export composite or non-word-wide signal %s.\n", log_signal(sig)); conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size())); - if (sig.chunks()[0].wire == NULL) { + if (sig.is_fully_const()) { celltypes_code.insert(stringf("celltype CONST_%d b%d *CONST cfg:%d VALUE\n", sig.size(), sig.size(), sig.size())); - constcells_code.insert(stringf("node CONST_%d_0x%x CONST_%d CONST CONST_%d_0x%x VALUE 0x%x\n", sig.size(), sig.chunks()[0].data.as_int(), - sig.size(), sig.size(), sig.chunks()[0].data.as_int(), sig.chunks()[0].data.as_int())); - return stringf("CONST_%d_0x%x", sig.size(), sig.chunks()[0].data.as_int()); + constcells_code.insert(stringf("node CONST_%d_0x%x CONST_%d CONST CONST_%d_0x%x VALUE 0x%x\n", + sig.size(), sig.as_int(), sig.size(), sig.size(), sig.as_int(), sig.as_int())); + return stringf("CONST_%d_0x%x", sig.size(), sig.as_int()); } - if (sig.chunks()[0].offset != 0 || sig.size() != sig.chunks()[0].wire->width) - goto error; - - return RTLIL::unescape_id(sig.chunks()[0].wire->name); + return RTLIL::unescape_id(sig.as_wire()->name); } struct IntersynthBackend : public Backend { diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 8e894caf..e548df36 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -25,18 +25,17 @@ #include #include -static void print_spice_net(FILE *f, RTLIL::SigSpec s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) +static void print_spice_net(FILE *f, RTLIL::SigBit s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) { - log_assert(s.chunks().size() == 1 && s.chunks()[0].width == 1); - if (s.chunks()[0].wire) { - if (s.chunks()[0].wire->width > 1) - fprintf(f, " %s[%d]", RTLIL::id2cstr(s.chunks()[0].wire->name), s.chunks()[0].offset); + if (s.wire) { + if (s.wire->width > 1) + fprintf(f, " %s[%d]", RTLIL::id2cstr(s.wire->name), s.offset); else - fprintf(f, " %s", RTLIL::id2cstr(s.chunks()[0].wire->name)); + fprintf(f, " %s", RTLIL::id2cstr(s.wire->name)); } else { - if (s.chunks()[0].data.bits.at(0) == RTLIL::State::S0) + if (s == RTLIL::State::S0) fprintf(f, " %s", neg.c_str()); - else if (s.chunks()[0].data.bits.at(0) == RTLIL::State::S1) + else if (s == RTLIL::State::S1) fprintf(f, " %s", pos.c_str()); else fprintf(f, " %s%d", ncpf.c_str(), nc_counter++); @@ -92,7 +91,6 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de for (auto &sig : port_sigs) { for (int i = 0; i < sig.size(); i++) { RTLIL::SigSpec s = sig.extract(big_endian ? sig.size() - 1 - i : i, 1); - log_assert(s.chunks().size() == 1 && s.chunks()[0].width == 1); print_spice_net(f, s, neg, pos, ncpf, nc_counter); } } diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3d848e82..e74f36ab 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(); diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 4f4bc37a..05b2bbc2 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -35,10 +35,8 @@ struct BitPatternPool if (width > 0) { std::vector pattern(width); for (int i = 0; i < width; i++) { - RTLIL::SigSpec s = sig.extract(i, 1); - assert(s.chunks().size() == 1); - if (s.chunks()[0].wire == NULL && s.chunks()[0].data.bits[0] <= RTLIL::State::S1) - pattern[i] = s.chunks()[0].data.bits[0]; + if (sig[i].wire == NULL && sig[i].data <= RTLIL::State::S1) + pattern[i] = sig[i].data; else pattern[i] = RTLIL::State::Sa; } @@ -59,9 +57,7 @@ struct BitPatternPool bits_t sig2bits(RTLIL::SigSpec sig) { - assert(sig.is_fully_const()); - assert(sig.chunks().size() == 1); - bits_t bits = sig.chunks()[0].data.bits; + bits_t bits = sig.as_const().bits; for (auto &b : bits) if (b > RTLIL::State::S1) b = RTLIL::State::Sa; diff --git a/kernel/consteval.h b/kernel/consteval.h index 3a8ef44a..7b1b798c 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -207,9 +207,9 @@ struct ConstEval if (sig.is_fully_const()) return true; - for (size_t i = 0; i < sig.chunks().size(); i++) - if (sig.chunks()[i].wire != NULL) - undef.append(sig.chunks()[i]); + for (auto &c : sig.chunks()) + if (c.wire != NULL) + undef.append(c); return false; } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8e509f36..f741e2a3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1999,6 +1999,14 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const return true; } +bool RTLIL::SigSpec::is_wire() const +{ + cover("kernel.rtlil.sigspec.is_wire"); + + pack(); + return SIZE(chunks_) == 1 && chunks_[0].wire && chunks_[0].wire->width == width_; +} + bool RTLIL::SigSpec::is_fully_const() const { cover("kernel.rtlil.sigspec.is_fully_const"); @@ -2104,6 +2112,15 @@ RTLIL::Const RTLIL::SigSpec::as_const() const return RTLIL::Const(); } +RTLIL::Wire *RTLIL::SigSpec::as_wire() const +{ + cover("kernel.rtlil.sigspec.as_wire"); + + pack(); + assert(is_wire()); + return chunks_[0].wire; +} + bool RTLIL::SigSpec::match(std::string pattern) const { cover("kernel.rtlil.sigspec.match"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 68eee46e..a4b7e849 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -576,6 +576,7 @@ public: bool operator ==(const RTLIL::SigSpec &other) const; inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); } + bool is_wire() const; bool is_fully_const() const; bool is_fully_def() const; bool is_fully_undef() const; @@ -585,6 +586,7 @@ public: int as_int() const; std::string as_string() const; RTLIL::Const as_const() const; + RTLIL::Wire *as_wire() const; bool match(std::string pattern) const; @@ -612,7 +614,7 @@ inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { assert(sig.size() == 1 && sig.chunks().size() == 1); - *this = SigBit(sig.chunks()[0]); + *this = SigBit(sig.chunks().front()); } struct RTLIL::CaseRule { diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index ba27a3fc..d25f88c0 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -709,15 +709,15 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); module->connections.push_back(conn); continue; } if (c->type == "\\BUF") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); - conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); module->connections.push_back(conn); continue; } @@ -725,8 +725,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_INV_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; @@ -735,9 +735,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_" + c->type.substr(1) + "_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].chunks()[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); + cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].as_wire()->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; @@ -746,10 +746,10 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = "$_MUX_"; cell->name = remap_name(c->name); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].chunks()[0].wire->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].chunks()[0].wire->name)]); - cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].chunks()[0].wire->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].chunks()[0].wire->name)]); + cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); + cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].as_wire()->name)]); + cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].as_wire()->name)]); + cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); module->cells[cell->name] = cell; design->select(module, cell); continue; @@ -759,8 +759,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; cell->name = remap_name(c->name); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].chunks()[0].wire->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].chunks()[0].wire->name)]); + cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].as_wire()->name)]); + cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].as_wire()->name)]); cell->connections["\\C"] = clk_sig; module->cells[cell->name] = cell; design->select(module, cell); @@ -777,7 +777,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\_const0_" || c->type == "\\_const1_") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections.begin()->second.chunks()[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections.begin()->second.as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1); module->connections.push_back(conn); continue; @@ -787,8 +787,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Cell *cell = new RTLIL::Cell; cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; cell->name = remap_name(c->name); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].chunks()[0].wire->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].chunks()[0].wire->name)]); + cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].as_wire()->name)]); + cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].as_wire()->name)]); cell->connections["\\C"] = clk_sig; module->cells[cell->name] = cell; design->select(module, cell); @@ -815,9 +815,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std for (auto conn : mapped_mod->connections) { if (!conn.first.is_fully_const()) - conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.chunks()[0].wire->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.as_wire()->name)]); if (!conn.second.is_fully_const()) - conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.chunks()[0].wire->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.as_wire()->name)]); module->connections.push_back(conn); } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 6b37b7bb..0a1d584c 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -177,7 +177,7 @@ struct ShowWorker } if (sig.chunks().size() == 1) { - const RTLIL::SigChunk &c = sig.chunks()[0]; + const RTLIL::SigChunk &c = sig.chunks().front(); if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) { if (!range_check || c.wire->width == c.width) return stringf("n%d", id2num(c.wire->name)); @@ -200,7 +200,7 @@ struct ShowWorker int pos = sig.size()-1; int idx = single_idx_count++; for (int i = int(sig.chunks().size())-1; i >= 0; i--) { - const RTLIL::SigChunk &c = sig.chunks()[i]; + const RTLIL::SigChunk &c = sig.chunks().at(i); net = gen_signode_simple(c, false); assert(!net.empty()); if (driver) { diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index fec0b407..3ceb5da3 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -147,8 +147,8 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) assert(sig_wr_en.size() == wr_ports * memory->width); mem->parameters["\\WR_PORTS"] = RTLIL::Const(wr_ports); - mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.chunks()[0].data : RTLIL::Const(0, 0); - mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.chunks()[0].data : RTLIL::Const(0, 0); + mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : RTLIL::Const(0, 0); + mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : RTLIL::Const(0, 0); mem->connections["\\WR_CLK"] = sig_wr_clk; mem->connections["\\WR_ADDR"] = sig_wr_addr; @@ -162,9 +162,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) assert(sig_rd_data.size() == rd_ports * memory->width); mem->parameters["\\RD_PORTS"] = RTLIL::Const(rd_ports); - mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.chunks()[0].data : RTLIL::Const(0, 0); - mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.chunks()[0].data : RTLIL::Const(0, 0); - mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.chunks()[0].data : RTLIL::Const(0, 0); + mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : RTLIL::Const(0, 0); + mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : RTLIL::Const(0, 0); + mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : RTLIL::Const(0, 0); mem->connections["\\RD_CLK"] = sig_rd_clk; mem->connections["\\RD_ADDR"] = sig_rd_addr; diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index ba0aadc6..02efabf7 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -104,15 +104,10 @@ static int count_nontrivial_wire_attrs(RTLIL::Wire *w) return count; } -static bool compare_signals(RTLIL::SigSpec &s1, RTLIL::SigSpec &s2, SigPool ®s, SigPool &conns, std::set &direct_wires) +static bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, SigPool &conns, std::set &direct_wires) { - assert(s1.size() == 1); - assert(s2.size() == 1); - assert(s1.chunks().size() == 1); - assert(s2.chunks().size() == 1); - - RTLIL::Wire *w1 = s1.chunks()[0].wire; - RTLIL::Wire *w2 = s2.chunks()[0].wire; + RTLIL::Wire *w1 = s1.wire; + RTLIL::Wire *w2 = s2.wire; if (w1 == NULL || w2 == NULL) return w2 == NULL; @@ -189,7 +184,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it : module->wires) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) { - RTLIL::SigSpec s1 = RTLIL::SigSpec(wire, i), s2 = assign_map(s1); + RTLIL::SigBit s1 = RTLIL::SigBit(wire, i), s2 = assign_map(s1); if (!compare_signals(s1, s2, register_signals, connected_signals, direct_wires)) assign_map.add(s1); } diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index a8aba903..5982fd8e 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -382,7 +382,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) sync_edge->signal, sync_level->signal, proc); } else - gen_dff(mod, insig, rstval.chunks()[0].data, sig, + gen_dff(mod, insig, rstval.as_const(), sig, sync_edge->type == RTLIL::SyncType::STp, sync_level && sync_level->type == RTLIL::SyncType::ST1, sync_edge->signal, sync_level ? &sync_level->signal : NULL, proc); diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index 4c9b6bcd..5976c216 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -58,16 +58,15 @@ static void proc_init(RTLIL::Module *mod, RTLIL::Process *proc) log_cmd_error("Failed to get a constant init value for %s: %s\n", log_signal(lhs), log_signal(rhs)); int offset = 0; - for (size_t i = 0; i < lhs.chunks().size(); i++) { - if (lhs.chunks()[i].wire == NULL) - continue; - RTLIL::Wire *wire = lhs.chunks()[i].wire; - RTLIL::SigSpec value = rhs.extract(offset, lhs.chunks()[i].width); - if (value.size() != wire->width) - log_cmd_error("Init value is not for the entire wire: %s = %s\n", log_signal(lhs.chunks()[i]), log_signal(value)); - log(" Setting init value: %s = %s\n", log_signal(wire), log_signal(value)); - wire->attributes["\\init"] = value.as_const(); - offset += wire->width; + for (auto &lhs_c : lhs.chunks()) { + if (lhs_c.wire != NULL) { + RTLIL::SigSpec value = rhs.extract(offset, lhs_c.width); + if (value.size() != lhs_c.wire->width) + log_cmd_error("Init value is not for the entire wire: %s = %s\n", log_signal(lhs_c), log_signal(value)); + log(" Setting init value: %s = %s\n", log_signal(lhs_c.wire), log_signal(value)); + lhs_c.wire->attributes["\\init"] = value.as_const(); + } + offset += lhs_c.width; } } } From 01dbf12ac9227f7aac92b1fa7af056ad2a1f24e3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:12:14 +0200 Subject: [PATCH 408/750] Further improved "make" prettiness --- Makefile | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 3919b3f1..c96cdeab 100644 --- a/Makefile +++ b/Makefile @@ -106,13 +106,15 @@ LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) endif ifeq ($(PRETTY), 1) -I = 0 -P = @echo "$(eval I=$(shell bash -c 'i=0; for x in $(OBJS) yosys; do ((i++)); [ "$$x" = "$@" -a $I -lt $$i ] && echo $$i && exit; done; echo $I'))[$(shell \ - gawk "BEGIN { N=`echo $(OBJS) yosys | wc -w`; printf \"%3d\", 100*$I/N; exit; }")%] Building $@"; +P_STATUS = 0 +P_OFFSET = 0 +P_UPDATE = $(eval P_STATUS=$(shell echo $(OBJS) yosys | gawk 'BEGIN { RS = " "; I = $(P_STATUS)+0; } $$1 == "$@" && NR > I { I = NR; } END { print I; }')) +P_SHOW = [$(shell gawk "BEGIN { N=$(words $(OBJS) yosys); printf \"%3d\", $(P_OFFSET)+90*$(P_STATUS)/N; exit; }")%] +P = @echo "$(if $(findstring $@,$(TARGETS) $(EXTRA_TARGETS)),$(eval P_OFFSET = 10))$(call P_UPDATE)$(call P_SHOW) Building $@"; Q = @ S = -s else -I = +P_SHOW = -> P = Q = S = @@ -166,6 +168,9 @@ include backends/ilang/Makefile.inc endif top-all: $(TARGETS) $(EXTRA_TARGETS) + @echo "" + @echo " It's a Yosys." + @echo "" yosys: $(OBJS) $(P) $(CXX) -o yosys $(LDFLAGS) $(OBJS) $(LDLIBS) @@ -202,7 +207,7 @@ ifneq ($(ABCREV),default) fi endif $(Q) rm -f abc/abc-[0-9a-f]* - $(Q) cd abc && $(MAKE) $(S) PROG="abc-$(ABCREV)" MSG_PREFIX="YOSYS-ABC: " + $(Q) cd abc && $(MAKE) $(S) PROG="abc-$(ABCREV)" MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " ifeq ($(ABCREV),default) .PHONY: abc/abc-$(ABCREV) From cd699254377b08729342026056f97d9d6bc1e2f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:17:06 +0200 Subject: [PATCH 409/750] Added "make clean-abc" --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index c96cdeab..29c6113f 100644 --- a/Makefile +++ b/Makefile @@ -248,6 +248,10 @@ clean: rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d test ! -f libs/svgviewer/Makefile || make -C libs/svgviewer distclean +clean-abc: + make -C abc clean + rm -f yosys-abc abc/abc-[0-9a-f]* + mrproper: clean git clean -xdf From 7f1789ad1bb978132e8e09fee54ded81b370fcb3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:17:35 +0200 Subject: [PATCH 410/750] Fixed typo in cover id --- kernel/rtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f741e2a3..6bb395ec 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1866,7 +1866,7 @@ void RTLIL::SigSpec::extend(int width, bool is_signed) void RTLIL::SigSpec::extend_u0(int width, bool is_signed) { - cover("kernel.rtlil.sigspec.extend_0"); + cover("kernel.rtlil.sigspec.extend_u0"); pack(); From e4a0ab9bedcf357551c0faf548317e0998d5a4d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:18:16 +0200 Subject: [PATCH 411/750] Added more stuff to the checklist --- CHECKLIST | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CHECKLIST b/CHECKLIST index c621b715..7fcdd8e9 100644 --- a/CHECKLIST +++ b/CHECKLIST @@ -29,7 +29,7 @@ Run all tests with "make config-{clang-debug,gcc-debug,gcc-4.7,release}": chromium-browser report.html -Then with any config setting: +Then with default config setting: cd ~yosys make manual @@ -38,6 +38,18 @@ Then with any config setting: - make cosmetic changes to the .tex files if necessary +Also with default config setting: + + cd ~yosys/techlibs/cmos + bash testbench.sh + + cd ~yosys/techlibs/xilinx/example_sim_counter + bash run_sim.sh + + cd ~yosys/techlibs/xilinx/example_mojo_counter + bash example.sh + + Finally if a current verific library is available: cd ~yosys From 6789e3002aadb78623b9205492d14bbafb3e39eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:31:16 +0200 Subject: [PATCH 412/750] Removed Minisat dependency on zlib --- libs/ezsat/ezminisat.cc | 1 + ...patch => 00_PATCH_mkLit_default_arg.patch} | 0 libs/minisat/00_PATCH_remove_zlib.patch | 38 +++++++++++++++++++ libs/minisat/{UPDATE.sh => 00_UPDATE.sh} | 3 +- libs/minisat/ParseUtils.h | 14 +------ 5 files changed, 43 insertions(+), 13 deletions(-) rename libs/minisat/{PATCH_mkLit_default_arg.patch => 00_PATCH_mkLit_default_arg.patch} (100%) create mode 100644 libs/minisat/00_PATCH_remove_zlib.patch rename libs/minisat/{UPDATE.sh => 00_UPDATE.sh} (86%) diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 3f43f3ec..dc4e5d28 100644 --- a/libs/ezsat/ezminisat.cc +++ b/libs/ezsat/ezminisat.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include "../minisat/Solver.h" #include "../minisat/SimpSolver.h" diff --git a/libs/minisat/PATCH_mkLit_default_arg.patch b/libs/minisat/00_PATCH_mkLit_default_arg.patch similarity index 100% rename from libs/minisat/PATCH_mkLit_default_arg.patch rename to libs/minisat/00_PATCH_mkLit_default_arg.patch diff --git a/libs/minisat/00_PATCH_remove_zlib.patch b/libs/minisat/00_PATCH_remove_zlib.patch new file mode 100644 index 00000000..61a36f7e --- /dev/null +++ b/libs/minisat/00_PATCH_remove_zlib.patch @@ -0,0 +1,38 @@ +--- ParseUtils.h ++++ ParseUtils.h +@@ -24,8 +24,6 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA + #include + #include + +-#include +- + #include "XAlloc.h" + + namespace Minisat { +@@ -36,24 +34,16 @@ namespace Minisat { + + + class StreamBuffer { +- gzFile in; + unsigned char* buf; + int pos; + int size; + + enum { buffer_size = 64*1024 }; + +- void assureLookahead() { +- if (pos >= size) { +- pos = 0; +- size = gzread(in, buf, buffer_size); } } ++ virtual void assureLookahead() = 0; + + public: +- explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0){ +- buf = (unsigned char*)xrealloc(NULL, buffer_size); +- assureLookahead(); +- } +- ~StreamBuffer() { free(buf); } ++ virtual ~StreamBuffer() { } + + int operator * () const { return (pos >= size) ? EOF : buf[pos]; } + void operator ++ () { pos++; assureLookahead(); } diff --git a/libs/minisat/UPDATE.sh b/libs/minisat/00_UPDATE.sh similarity index 86% rename from libs/minisat/UPDATE.sh rename to libs/minisat/00_UPDATE.sh index fa72ba21..96a34ec9 100644 --- a/libs/minisat/UPDATE.sh +++ b/libs/minisat/00_UPDATE.sh @@ -12,5 +12,6 @@ sed -i -e 's/PRI[iu]64/ & /' Options.h Solver.cc sed -i -e '1 i #define __STDC_LIMIT_MACROS' *.cc sed -i -e '1 i #define __STDC_FORMAT_MACROS' *.cc -patch -p0 < PATCH_mkLit_default_arg.patch +patch -p0 < 00_PATCH_mkLit_default_arg.patch +patch -p0 < 00_PATCH_remove_zlib.patch diff --git a/libs/minisat/ParseUtils.h b/libs/minisat/ParseUtils.h index 1c9e7bf7..04911c70 100644 --- a/libs/minisat/ParseUtils.h +++ b/libs/minisat/ParseUtils.h @@ -24,8 +24,6 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include #include -#include - #include "XAlloc.h" namespace Minisat { @@ -36,24 +34,16 @@ namespace Minisat { class StreamBuffer { - gzFile in; unsigned char* buf; int pos; int size; enum { buffer_size = 64*1024 }; - void assureLookahead() { - if (pos >= size) { - pos = 0; - size = gzread(in, buf, buffer_size); } } + virtual void assureLookahead() = 0; public: - explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0){ - buf = (unsigned char*)xrealloc(NULL, buffer_size); - assureLookahead(); - } - ~StreamBuffer() { free(buf); } + virtual ~StreamBuffer() { } int operator * () const { return (pos >= size) ? EOF : buf[pos]; } void operator ++ () { pos++; assureLookahead(); } From 91bf0c90c86f5f857f440bec012b085d9f218ef0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:04:40 +0200 Subject: [PATCH 413/750] Improvements in "cover" command --- passes/cmds/cover.cc | 48 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index ebbdc7c4..0a96c0b2 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -17,6 +17,10 @@ * */ +#include +#include +#include + #include "kernel/register.h" #include "kernel/rtlil.h" #include "kernel/log.h" @@ -27,7 +31,7 @@ struct CoverPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" cover [-q] [-o logfile|-a logfile]\n"); + log(" cover [options] [pattern]\n"); log("\n"); log("Print the code coverage counters collected using the cover() macro in the Yosys\n"); log("C++ code. This is useful to figure out what parts of Yosys are utilized by a\n"); @@ -36,22 +40,28 @@ struct CoverPass : public Pass { log(" -q\n"); log(" Do not print output to the normal destination (console and/or log file)\n"); log("\n"); - log(" -o logfile\n"); + log(" -o file\n"); log(" Write output to this file, truncate if exists.\n"); log("\n"); - log(" -a logfile\n"); + log(" -a file\n"); log(" Write output to this file, append if exists.\n"); log("\n"); + log(" -d dir\n"); + log(" Write output to a newly created file in the specified directory.\n"); log("\n"); - log("It is also possible to instruct Yosys to print the coverage counters to a file\n"); - log("using environment variables.\n"); + log("When one or more pattern (shell wildcards) are specified, then only counters\n"); + log("matching at least one pattern are printed.\n"); log("\n"); - log(" YOSYS_COVER_DIR=\"{dir-name}\" yosys {args}n"); + log("\n"); + log("It is also possible to instruct Yosys to print the coverage counters on program\n"); + log("exit to a file using environment variables:\n"); + log("\n"); + log(" YOSYS_COVER_DIR=\"{dir-name}\" yosys {args}\n"); log("\n"); log(" This will create a file (with an auto-generated name) in this\n"); - log(" directory and wire the coverage counters to it.\n"); + log(" directory and write the coverage counters to it.\n"); log("\n"); - log(" YOSYS_COVER_FILE=\"{file-name}\" yosys {args}n"); + log(" YOSYS_COVER_FILE=\"{file-name}\" yosys {args}\n"); log("\n"); log(" This will append the coverage counters to the specified file.\n"); log("\n"); @@ -65,6 +75,7 @@ struct CoverPass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { std::vector out_files; + std::vector patterns; bool do_log = true; size_t argidx; @@ -74,9 +85,15 @@ struct CoverPass : public Pass { do_log = false; continue; } - if ((args[argidx] == "-o" || args[argidx] == "-a") && argidx+1 < args.size()) { - const char *open_mode = args[argidx] == "-o" ? "w" : "a+"; - FILE *f = fopen(args[++argidx].c_str(), open_mode); + if ((args[argidx] == "-o" || args[argidx] == "-a" || args[argidx] == "-d") && argidx+1 < args.size()) { + const char *open_mode = args[argidx] == "-a" ? "a+" : "w"; + std::string filename = args[++argidx]; + if (args[argidx-1] == "-d") { + char filename_buffer[4096]; + snprintf(filename_buffer, 4096, "%s/yosys_cover_%d_XXXXXX.txt", filename.c_str(), getpid()); + filename = mkstemps(filename_buffer, 4); + } + FILE *f = fopen(filename.c_str(), open_mode); if (f == NULL) { for (auto f : out_files) fclose(f); @@ -87,6 +104,8 @@ struct CoverPass : public Pass { } break; } + while (argidx < args.size() && args[argidx].substr(0, 1) != "-") + patterns.push_back(args[argidx++]); extra_args(args, argidx, design); if (do_log) { @@ -96,6 +115,13 @@ struct CoverPass : public Pass { #ifndef NDEBUG for (auto &it : get_coverage_data()) { + if (!patterns.empty()) { + for (auto &p : patterns) + if (!fnmatch(p.c_str(), it.first.c_str(), 0)) + goto pattern_match; + continue; + } + pattern_match: for (auto f : out_files) fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); if (do_log) From 1488bc0c4f80b32cabd096232830b7fdfc400bbf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:16:03 +0200 Subject: [PATCH 414/750] Updated verific build/test instructions --- frontends/verific/build_amd64.txt | 22 ++++++++++------------ frontends/verific/test_navre.ys | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 49debe0f..2f325e51 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. - -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 . +libreadline-dev:amd64 or lib32readline6-dev, depending on the +exact version of debian/ubuntu you are working with. -3.) Run 'make' and 'make install' as usual. +3.) Build and test + +make -j8 +./yosys frontends/verific/test_navre.ys diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys index 6f63761a..a56b725a 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 From a8706b73a2c14c6b34e4fb7136866c0bc959acbb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:16:23 +0200 Subject: [PATCH 415/750] Added more stuff to checklist --- CHECKLIST | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHECKLIST b/CHECKLIST index 7fcdd8e9..35de389b 100644 --- a/CHECKLIST +++ b/CHECKLIST @@ -31,6 +31,10 @@ Run all tests with "make config-{clang-debug,gcc-debug,gcc-4.7,release}": Then with default config setting: + cd ~yosys + ./yosys -p 'proc; show' tests/simple/fiedler-cooley.v + ./yosys -p 'proc; opt; show' tests/simple/fiedler-cooley.v + cd ~yosys make manual - sanity check the figures in the appnotes and presentation From c4e4f79a2a2fd5530fa2677245f9361c7b04df70 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:22:37 +0200 Subject: [PATCH 416/750] Disabled cover() for non-linux builds --- kernel/driver.cc | 2 +- kernel/log.h | 3 ++- passes/cmds/cover.cc | 7 +++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index a4556fb1..3c185e44 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -749,7 +749,7 @@ int main(int argc, char **argv) delete yosys_design; yosys_design = NULL; -#ifndef NDEBUG +#ifdef COVER_ACTIVE if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) { char filename_buffer[4096]; diff --git a/kernel/log.h b/kernel/log.h index 18ea528a..1658800d 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -75,7 +75,8 @@ void log_cell(RTLIL::Cell *cell, std::string indent = ""); // This is the magic behind the code coverage counters // --------------------------------------------------- -#ifndef NDEBUG +#if defined(__linux__) && !defined(NDEBUG) +#define COVER_ACTIVE #define cover(_id) do { \ static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1))) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ diff --git a/passes/cmds/cover.cc b/passes/cmds/cover.cc index 0a96c0b2..ac72ba53 100644 --- a/passes/cmds/cover.cc +++ b/passes/cmds/cover.cc @@ -71,6 +71,9 @@ struct CoverPass : public Pass { log(" gawk '{ p[$3] = $1; c[$3] += $2; } END { for (i in p)\n"); log(" printf \"%%-60s %%10d %%s\\n\", p[i], c[i], i; }' {files} | sort -k3\n"); log("\n"); + log("\n"); + log("Coverage counters are only available in debug builds of Yosys for Linux.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { @@ -113,7 +116,7 @@ struct CoverPass : public Pass { log("\n"); } -#ifndef NDEBUG +#ifdef COVER_ACTIVE for (auto &it : get_coverage_data()) { if (!patterns.empty()) { for (auto &p : patterns) @@ -131,7 +134,7 @@ struct CoverPass : public Pass { for (auto f : out_files) fclose(f); - log_cmd_error("Coverage counters are only available in debug builds of Yosys."); + log_cmd_error("Coverage counters are only available in debug builds of Yosys for Linux.\n"); #endif for (auto f : out_files) From 0520bfea892291a131134411d587034fcd36bf1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:49:51 +0200 Subject: [PATCH 417/750] Fixed memory corruption in "opt_reduce" pass --- passes/opt/opt_reduce.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 913855f4..0cc16ee6 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -312,12 +312,14 @@ struct OptReduceWorker // merge identical inputs on $mux and $pmux cells - for (auto &cell_it : module->cells) - { - RTLIL::Cell *cell = cell_it.second; - if ((cell->type != "$mux" && cell->type != "$pmux" && cell->type != "$safe_pmux") || !design->selected(module, cell)) - continue; + std::vector cells; + for (auto &it : module->cells) + if ((it.second->type == "$mux" || it.second->type == "$pmux" || it.second->type == "$safe_pmux") && design->selected(module, it.second)) + cells.push_back(it.second); + + for (auto cell : cells) + { // this optimization is to aggressive for most coarse-grain applications. // but we always want it for multiplexers driving write enable ports. if (do_fine || mem_wren_sigs.check_any(assign_map(cell->connections.at("\\Y")))) From 50f22ff30c921c90f686879455117c7c2c9f96d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 13:01:45 +0200 Subject: [PATCH 418/750] Renamed some of the test cases in tests/simple to avoid name collisions --- tests/simple/arraycells.v | 2 +- tests/simple/fsm.v | 2 +- tests/simple/generate.v | 6 +++--- tests/simple/i2c_master_tests.v | 4 ++-- tests/simple/macros.v | 2 +- tests/simple/mem2reg.v | 6 +++--- tests/simple/memory.v | 18 +++++++++--------- tests/simple/operators.v | 2 +- tests/simple/paramods.v | 6 +++--- tests/simple/partsel.v | 2 +- tests/simple/repwhile.v | 2 +- tests/simple/signedexpr.v | 2 +- tests/simple/task_func.v | 2 +- tests/simple/undef_eqx_nex.v | 2 +- .../{usb_phy_tetsts.v => usb_phy_tests.v} | 2 +- 15 files changed, 30 insertions(+), 30 deletions(-) rename tests/simple/{usb_phy_tetsts.v => usb_phy_tests.v} (92%) diff --git a/tests/simple/arraycells.v b/tests/simple/arraycells.v index ad509800..704ca3fd 100644 --- a/tests/simple/arraycells.v +++ b/tests/simple/arraycells.v @@ -1,5 +1,5 @@ -module test001(a, b, c, y); +module array_test001(a, b, c, y); input a; input [31:0] b, c; input [31:0] y; diff --git a/tests/simple/fsm.v b/tests/simple/fsm.v index 79ca041d..2dba14bb 100644 --- a/tests/simple/fsm.v +++ b/tests/simple/fsm.v @@ -1,7 +1,7 @@ // `define ASYNC_RESET -module test(clk, reset, button_a, button_b, red_a, green_a, red_b, green_b); +module fsm_test(clk, reset, button_a, button_b, red_a, green_a, red_b, green_b); input clk, reset, button_a, button_b; output reg red_a, green_a, red_b, green_b; diff --git a/tests/simple/generate.v b/tests/simple/generate.v index 39e573a7..24eb4462 100644 --- a/tests/simple/generate.v +++ b/tests/simple/generate.v @@ -1,5 +1,5 @@ -module test1(clk, a, b, y); +module gen_test1(clk, a, b, y); input clk; input [7:0] a, b; @@ -40,7 +40,7 @@ endmodule // ------------------------------------------ -module test2(clk, a, b, y); +module gen_test2(clk, a, b, y); input clk; input [7:0] a, b; @@ -67,7 +67,7 @@ endmodule // ------------------------------------------ -module test3(a, b, sel, y, z); +module gen_test3(a, b, sel, y, z); input [3:0] a, b; input sel; diff --git a/tests/simple/i2c_master_tests.v b/tests/simple/i2c_master_tests.v index f8f56408..3aa59663 100644 --- a/tests/simple/i2c_master_tests.v +++ b/tests/simple/i2c_master_tests.v @@ -3,7 +3,7 @@ // this core that triggered bugs in early versions of yosys. // from i2c_master_bit_ctrl -module test01(clk, rst, nReset, al); +module i2c_test01(clk, rst, nReset, al); input clk, rst, nReset; output reg al; @@ -26,7 +26,7 @@ module test01(clk, rst, nReset, al); endmodule // from i2c_master_bit_ctrl -module test02(clk, slave_wait, clk_cnt, cmd, cmd_stop, cnt); +module i2c_test02(clk, slave_wait, clk_cnt, cmd, cmd_stop, cnt); input clk, slave_wait, clk_cnt; input cmd; diff --git a/tests/simple/macros.v b/tests/simple/macros.v index a3e8d70f..7b4d616e 100644 --- a/tests/simple/macros.v +++ b/tests/simple/macros.v @@ -237,7 +237,7 @@ end endmodule `define SIZE 4 // comment supported in this part -module test ( din_a, dout_a ); +module test_comment_in_macro ( din_a, dout_a ); input [`SIZE-1:0] din_a; output [`SIZE-1:0] dout_a; assign dout_a = din_a | `SIZE'ha; diff --git a/tests/simple/mem2reg.v b/tests/simple/mem2reg.v index 3630b57c..bed5528d 100644 --- a/tests/simple/mem2reg.v +++ b/tests/simple/mem2reg.v @@ -1,5 +1,5 @@ -module test1(in_addr, in_data, out_addr, out_data); +module mem2reg_test1(in_addr, in_data, out_addr, out_data); input [1:0] in_addr, out_addr; input [3:0] in_data; @@ -19,7 +19,7 @@ endmodule // ------------------------------------------------------ -module test2(clk, mode, addr, data); +module mem2reg_test2(clk, mode, addr, data); input clk, mode; input [2:0] addr; @@ -46,7 +46,7 @@ endmodule // ------------------------------------------------------ // http://www.reddit.com/r/yosys/comments/28d9lx/problem_with_concatenation_of_two_dimensional/ -module test3( input clk, input [8:0] din_a, output reg [7:0] dout_a, output [7:0] dout_b); +module mem2reg_test3( input clk, input [8:0] din_a, output reg [7:0] dout_a, output [7:0] dout_b); reg [7:0] dint_c [0:7]; always @(posedge clk) begin diff --git a/tests/simple/memory.v b/tests/simple/memory.v index ae63e8a1..9fed1bf3 100644 --- a/tests/simple/memory.v +++ b/tests/simple/memory.v @@ -1,5 +1,5 @@ -module test00(clk, setA, setB, y); +module memtest00(clk, setA, setB, y); input clk, setA, setB; output y; @@ -16,7 +16,7 @@ endmodule // ---------------------------------------------------------- -module test01(clk, wr_en, wr_addr, wr_value, rd_addr, rd_value); +module memtest01(clk, wr_en, wr_addr, wr_value, rd_addr, rd_value); input clk, wr_en; input [3:0] wr_addr, rd_addr; @@ -36,7 +36,7 @@ endmodule // ---------------------------------------------------------- -module test02(clk, setA, setB, addr, bit, y1, y2, y3, y4); +module memtest02(clk, setA, setB, addr, bit, y1, y2, y3, y4); input clk, setA, setB; input [1:0] addr; @@ -77,7 +77,7 @@ endmodule // ---------------------------------------------------------- -module test03(clk, wr_addr, wr_data, wr_enable, rd_addr, rd_data); +module memtest03(clk, wr_addr, wr_data, wr_enable, rd_addr, rd_data); input clk, wr_enable; input [3:0] wr_addr, wr_data, rd_addr; @@ -95,7 +95,7 @@ endmodule // ---------------------------------------------------------- -module test04(clk, wr_addr, wr_data, wr_enable, rd_addr, rd_data); +module memtest04(clk, wr_addr, wr_data, wr_enable, rd_addr, rd_data); input clk, wr_enable; input [3:0] wr_addr, wr_data, rd_addr; @@ -116,7 +116,7 @@ endmodule // ---------------------------------------------------------- -module test05(clk, addr, wdata, rdata, wen); +module memtest05(clk, addr, wdata, rdata, wen); input clk; input [1:0] addr; @@ -137,7 +137,7 @@ endmodule // ---------------------------------------------------------- -module test06_sync(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); +module memtest06_sync(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); (* gentb_constant=0 *) wire rst; reg [7:0] test [0:7]; integer i; @@ -156,7 +156,7 @@ module test06_sync(input clk, input rst, input [2:0] idx, input [7:0] din, outpu assign dout = test[idx]; endmodule -module test06_async(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); +module memtest06_async(input clk, input rst, input [2:0] idx, input [7:0] din, output [7:0] dout); (* gentb_constant=0 *) wire rst; reg [7:0] test [0:7]; integer i; @@ -177,7 +177,7 @@ endmodule // ---------------------------------------------------------- -module test07(clk, addr, woffset, wdata, rdata); +module memtest07(clk, addr, woffset, wdata, rdata); input clk; input [1:0] addr; diff --git a/tests/simple/operators.v b/tests/simple/operators.v index 7439101c..2f0fdb82 100644 --- a/tests/simple/operators.v +++ b/tests/simple/operators.v @@ -1,4 +1,4 @@ -module test(clk, mode, u1, s1, u2, s2, y); +module optest(clk, mode, u1, s1, u2, s2, y); input clk; input [6:0] mode; diff --git a/tests/simple/paramods.v b/tests/simple/paramods.v index 8d0134a6..23cb276f 100644 --- a/tests/simple/paramods.v +++ b/tests/simple/paramods.v @@ -1,5 +1,5 @@ -module test1(a, b, x, y); +module pm_test1(a, b, x, y); input [7:0] a, b; output [7:0] x, y; @@ -11,7 +11,7 @@ endmodule // ----------------------------------- -module test2(a, b, x, y); +module pm_test2(a, b, x, y); input [7:0] a, b; output [7:0] x, y; @@ -23,7 +23,7 @@ endmodule // ----------------------------------- -module test3(a, b, x, y); +module pm_test3(a, b, x, y); input [7:0] a, b; output [7:0] x, y; diff --git a/tests/simple/partsel.v b/tests/simple/partsel.v index acfc1ca5..9b1a9985 100644 --- a/tests/simple/partsel.v +++ b/tests/simple/partsel.v @@ -1,4 +1,4 @@ -module test001(input [2:0] idx, input [31:0] data, output [3:0] slice_up, slice_down); +module partsel_test001(input [2:0] idx, input [31:0] data, output [3:0] slice_up, slice_down); wire [5:0] offset = idx << 2; assign slice_up = data[offset +: 4]; assign slice_down = data[offset + 3 -: 4]; diff --git a/tests/simple/repwhile.v b/tests/simple/repwhile.v index cde37c56..5d0c75fa 100644 --- a/tests/simple/repwhile.v +++ b/tests/simple/repwhile.v @@ -1,4 +1,4 @@ -module test001(input [5:0] a, output [7:0] y, output [31:0] x); +module repwhile_test001(input [5:0] a, output [7:0] y, output [31:0] x); function [7:0] mylog2; input [31:0] value; diff --git a/tests/simple/signedexpr.v b/tests/simple/signedexpr.v index 3eb5e93d..8bba4a4b 100644 --- a/tests/simple/signedexpr.v +++ b/tests/simple/signedexpr.v @@ -1,4 +1,4 @@ -module test01(a, b, xu, xs, yu, ys, zu, zs); +module signed_test01(a, b, xu, xs, yu, ys, zu, zs); input signed [1:0] a; input signed [2:0] b; diff --git a/tests/simple/task_func.v b/tests/simple/task_func.v index 3a09cbc3..8dbc90c5 100644 --- a/tests/simple/task_func.v +++ b/tests/simple/task_func.v @@ -1,5 +1,5 @@ -module test01(clk, a, b, c, x, y, z, w); +module task_func_test01(clk, a, b, c, x, y, z, w); input clk; input [7:0] a, b, c; diff --git a/tests/simple/undef_eqx_nex.v b/tests/simple/undef_eqx_nex.v index 63912a2f..b0178677 100644 --- a/tests/simple/undef_eqx_nex.v +++ b/tests/simple/undef_eqx_nex.v @@ -1,4 +1,4 @@ -module test(y); +module undef_eqx_nex(y); output [7:0] y; assign y[0] = 0/0; assign y[1] = 0/1; diff --git a/tests/simple/usb_phy_tetsts.v b/tests/simple/usb_phy_tests.v similarity index 92% rename from tests/simple/usb_phy_tetsts.v rename to tests/simple/usb_phy_tests.v index 2375183d..bc45e71a 100644 --- a/tests/simple/usb_phy_tetsts.v +++ b/tests/simple/usb_phy_tests.v @@ -1,6 +1,6 @@ // from usb_rx_phy -module test01(clk, rst, rx_en, fs_ce); +module usb_phy_test01(clk, rst, rx_en, fs_ce); input clk, rst; input rx_en; From 309d64d46a7ca7390ccb27b06ecb78228c8b54f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 13:07:31 +0200 Subject: [PATCH 419/750] Fixed two memory leaks in ast simplify --- frontends/ast/simplify.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d86bfb3f..6302260a 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) From 1834af5e5382de67860f5714746566123c4d6b53 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 13:15:46 +0200 Subject: [PATCH 420/750] Added "make vgtest" --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 29c6113f..6dde27a9 100644 --- a/Makefile +++ b/Makefile @@ -226,6 +226,11 @@ test: $(TARGETS) $(EXTRA_TARGETS) cd tests/memories && bash run-test.sh cd tests/sat && bash run-test.sh +VALGRIND ?= valgrind --error-exitcode=1 --leak-check=full --show-reachable=yes --errors-for-leak-kinds=all + +vgtest: $(TARGETS) $(EXTRA_TARGETS) + $(VALGRIND) ./yosys -p 'setattr -mod -unset top; hierarchy; proc; opt; memory -nomap; opt -fine; techmap; opt' $$( ls tests/simple/*.v | grep -v repwhile.v ) + vloghtb: $(TARGETS) $(EXTRA_TARGETS) cd tests/vloghtb && bash run-test.sh From c762050e7fc2c733210f8cd2b147e6084af0afe1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 14:23:10 +0200 Subject: [PATCH 421/750] Added RTLIL::SigSpec is_chunk()/as_chunk() API --- kernel/rtlil.cc | 17 +++++++++++++++++ kernel/rtlil.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 6bb395ec..83524d79 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2007,6 +2007,14 @@ bool RTLIL::SigSpec::is_wire() const return SIZE(chunks_) == 1 && chunks_[0].wire && chunks_[0].wire->width == width_; } +bool RTLIL::SigSpec::is_chunk() const +{ + cover("kernel.rtlil.sigspec.is_chunk"); + + pack(); + return SIZE(chunks_) == 1; +} + bool RTLIL::SigSpec::is_fully_const() const { cover("kernel.rtlil.sigspec.is_fully_const"); @@ -2121,6 +2129,15 @@ RTLIL::Wire *RTLIL::SigSpec::as_wire() const return chunks_[0].wire; } +RTLIL::SigChunk RTLIL::SigSpec::as_chunk() const +{ + cover("kernel.rtlil.sigspec.as_chunk"); + + pack(); + assert(is_chunk()); + return chunks_[0]; +} + bool RTLIL::SigSpec::match(std::string pattern) const { cover("kernel.rtlil.sigspec.match"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a4b7e849..59db099f 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -577,6 +577,8 @@ public: inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); } bool is_wire() const; + bool is_chunk() const; + bool is_fully_const() const; bool is_fully_def() const; bool is_fully_undef() const; @@ -587,6 +589,7 @@ public: std::string as_string() const; RTLIL::Const as_const() const; RTLIL::Wire *as_wire() const; + RTLIL::SigChunk as_chunk() const; bool match(std::string pattern) const; From 5826670009e1018734de49aaf1554cb8a43d09d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 14:23:31 +0200 Subject: [PATCH 422/750] Various RTLIL::SigSpec related code cleanups --- backends/btor/btor.cc | 42 ++++++++++++------------ backends/ilang/ilang_backend.cc | 4 +-- backends/verilog/verilog_backend.cc | 50 +++++++++++++++++------------ passes/cmds/show.cc | 6 ++-- 4 files changed, 55 insertions(+), 47 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 9139749c..096c6029 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -207,15 +207,15 @@ struct BtorDumper int start_bit=0; for(unsigned j=0; jchunks().size(); ++j) { - start_bit+=cell_output->chunks()[j].width; - if(cell_output->chunks()[j].wire->name == wire->name) + start_bit+=cell_output->chunks().at(j).width; + if(cell_output->chunks().at(j).wire->name == wire->name) { prev_wire_line = wire_line; wire_line = ++line_num; - str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks()[j].width, - cell_line, start_bit-1, start_bit-cell_output->chunks()[j].width); + str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks().at(j).width, + cell_line, start_bit-1, start_bit-cell_output->chunks().at(j).width); fprintf(f, "%s\n", str.c_str()); - wire_width += cell_output->chunks()[j].width; + wire_width += cell_output->chunks().at(j).width; if(prev_wire_line!=0) { ++line_num; @@ -320,21 +320,21 @@ struct BtorDumper auto it = sig_ref.find(s); if(it == std::end(sig_ref)) { - if (s.chunks().size() == 1) + if (s.is_chunk()) { - l = dump_sigchunk(&s.chunks()[0]); + l = dump_sigchunk(&s.chunks().front()); } else { int l1, l2, w1, w2; - l1 = dump_sigchunk(&s.chunks()[0]); + l1 = dump_sigchunk(&s.chunks().front()); log_assert(l1>0); - w1 = s.chunks()[0].width; + w1 = s.chunks().front().width; for (unsigned i=1; i < s.chunks().size(); ++i) { - l2 = dump_sigchunk(&s.chunks()[i]); + l2 = dump_sigchunk(&s.chunks().at(i)); log_assert(l2>0); - w2 = s.chunks()[i].width; + w2 = s.chunks().at(i).width; ++line_num; str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); fprintf(f, "%s\n", str.c_str()); @@ -651,9 +651,9 @@ struct BtorDumper unsigned start_bit = 0; for(unsigned i=0; ichunks().size(); ++i) { - output_width = cell_output->chunks()[i].width; - log_assert( output_width == cell_output->chunks()[i].wire->width);//full reg is given the next value - int reg = dump_wire(cell_output->chunks()[i].wire);//register + output_width = cell_output->chunks().at(i).width; + log_assert( output_width == cell_output->chunks().at(i).wire->width);//full reg is given the next value + int reg = dump_wire(cell_output->chunks().at(i).wire);//register int slice = value; if(cell_output->chunks().size()>1) { @@ -845,9 +845,9 @@ struct BtorDumper { for(unsigned i=0; ichunks().size(); ++i) { - RTLIL::Wire *w = output_sig->chunks()[i].wire; + RTLIL::Wire *w = output_sig->chunks().at(i).wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks()[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks().at(i))); } } else if(cell->type == "$memwr") @@ -856,12 +856,12 @@ struct BtorDumper } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - RTLIL::IdString wire_id = output_sig->chunks()[0].wire->name; + RTLIL::IdString wire_id = output_sig->chunks().front().wire->name; for(unsigned i=0; ichunks().size(); ++i) { - RTLIL::Wire *w = output_sig->chunks()[i].wire; + RTLIL::Wire *w = output_sig->chunks().at(i).wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks()[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks().at(i))); basic_wires[wire_id] = true; } } @@ -869,9 +869,9 @@ struct BtorDumper { for(unsigned i=0; ichunks().size(); ++i) { - RTLIL::Wire *w = output_sig->chunks()[i].wire; + RTLIL::Wire *w = output_sig->chunks().at(i).wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks()[i])); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks().at(i))); } } } diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index e3093e37..3c8e805b 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -102,8 +102,8 @@ void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool au void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint) { - if (sig.chunks().size() == 1) { - dump_sigchunk(f, sig.chunks().front(), autoint); + if (sig.is_chunk()) { + dump_sigchunk(f, sig.as_chunk(), autoint); } else { fprintf(f, "{ "); for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) { diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 1dcc3003..a22035ed 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -133,18 +133,23 @@ std::string id(std::string internal_id, bool may_rename = true) bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name) { - if (sig.chunks().size() != 1 || sig.chunks()[0].wire == NULL) + if (!sig.is_chunk() || sig.as_chunk().wire == NULL) return false; - if (reg_wires.count(sig.chunks()[0].wire->name) == 0) + + RTLIL::SigChunk chunk = sig.as_chunk(); + + if (reg_wires.count(chunk.wire->name) == 0) return false; - reg_name = id(sig.chunks()[0].wire->name); - if (sig.size() != sig.chunks()[0].wire->width) { + + reg_name = id(chunk.wire->name); + if (sig.size() != chunk.wire->width) { if (sig.size() == 1) - reg_name += stringf("[%d]", sig.chunks()[0].wire->start_offset + sig.chunks()[0].offset); + reg_name += stringf("[%d]", chunk.wire->start_offset + chunk.offset); else - reg_name += stringf("[%d:%d]", sig.chunks()[0].wire->start_offset + sig.chunks()[0].offset + sig.chunks()[0].width - 1, - sig.chunks()[0].wire->start_offset + sig.chunks()[0].offset); + reg_name += stringf("[%d:%d]", chunk.wire->start_offset + chunk.offset + chunk.width - 1, + chunk.wire->start_offset + chunk.offset); } + return true; } @@ -220,8 +225,8 @@ void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool no_decimal = fals void dump_sigspec(FILE *f, RTLIL::SigSpec &sig) { - if (sig.chunks().size() == 1) { - dump_sigchunk(f, sig.chunks()[0]); + if (sig.is_chunk()) { + dump_sigchunk(f, sig.as_chunk()); } else { fprintf(f, "{ "); for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) { @@ -299,10 +304,10 @@ std::string cellname(RTLIL::Cell *cell) if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections.count("\\Q") > 0) { RTLIL::SigSpec sig = cell->connections["\\Q"]; - if (sig.size() != 1 || sig.is_fully_const()) + if (SIZE(sig) != 1 || sig.is_fully_const()) goto no_special_reg_name; - RTLIL::Wire *wire = sig.chunks()[0].wire; + RTLIL::Wire *wire = sig[0].wire; if (wire->name[0] != '\\') goto no_special_reg_name; @@ -316,7 +321,7 @@ std::string cellname(RTLIL::Cell *cell) cell_name = cell_name + "_reg"; if (wire->width != 1) - cell_name += stringf("[%d]", wire->start_offset + sig.chunks()[0].offset); + cell_name += stringf("[%d]", wire->start_offset + sig[0].offset); if (active_module && active_module->count_id(cell_name) > 0) goto no_special_reg_name; @@ -809,9 +814,9 @@ void case_body_find_regs(RTLIL::CaseRule *cs) case_body_find_regs(*it2); for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) { - for (size_t i = 0; i < it->first.chunks().size(); i++) - if (it->first.chunks()[i].wire) - reg_wires.insert(it->first.chunks()[i].wire->name); + for (auto &c : it->first.chunks()) + if (c.wire != NULL) + reg_wires.insert(c.wire->name); } } @@ -821,9 +826,9 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r case_body_find_regs(&proc->root_case); for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++) for (auto it2 = (*it)->actions.begin(); it2 != (*it)->actions.end(); it2++) { - for (size_t i = 0; i < it2->first.chunks().size(); i++) - if (it2->first.chunks()[i].wire) - reg_wires.insert(it2->first.chunks()[i].wire->name); + for (auto &c : it2->first.chunks()) + if (c.wire != NULL) + reg_wires.insert(c.wire->name); } return; } @@ -908,9 +913,12 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) RTLIL::SigSpec sig = cell->connections["\\Q"]; - if (sig.chunks().size() == 1 && sig.chunks()[0].wire) - for (int i = 0; i < sig.chunks()[0].width; i++) - reg_bits.insert(std::pair(sig.chunks()[0].wire, sig.chunks()[0].offset+i)); + if (sig.is_chunk()) { + RTLIL::SigChunk chunk = sig.as_chunk(); + if (chunk.wire != NULL) + for (int i = 0; i < chunk.width; i++) + reg_bits.insert(std::pair(chunk.wire, chunk.offset+i)); + } } for (auto &it : module->wires) { diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 0a1d584c..8ff06899 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -171,13 +171,13 @@ struct ShowWorker std::string gen_signode_simple(RTLIL::SigSpec sig, bool range_check = true) { - if (sig.chunks().size() == 0) { + if (SIZE(sig) == 0) { fprintf(f, "v%d [ label=\"\" ];\n", single_idx_count); return stringf("v%d", single_idx_count++); } - if (sig.chunks().size() == 1) { - const RTLIL::SigChunk &c = sig.chunks().front(); + if (sig.is_chunk()) { + const RTLIL::SigChunk &c = sig.as_chunk(); if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) { if (!range_check || c.wire->width == c.width) return stringf("n%d", id2num(c.wire->name)); From 2bec47a4045d23d46e7d300cbf80b2dce1a549a9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 15:05:18 +0200 Subject: [PATCH 423/750] 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 ++++++------------------------ kernel/rtlil.cc | 37 +++++++++++++++- kernel/rtlil.h | 21 ++++++++- passes/abc/abc.cc | 42 +++++------------- passes/abc/blifparse.cc | 24 +++-------- passes/cmds/delete.cc | 9 ++-- passes/cmds/splice.cc | 10 +---- passes/fsm/fsm_expand.cc | 6 +-- passes/fsm/fsm_extract.cc | 5 +-- passes/fsm/fsm_map.cc | 68 +++++++---------------------- passes/hierarchy/submod.cc | 14 +++--- passes/memory/memory_collect.cc | 18 +++----- passes/memory/memory_map.cc | 42 ++++-------------- passes/memory/memory_share.cc | 6 +-- passes/memory/memory_unpack.cc | 13 ++---- passes/opt/opt_clean.cc | 3 +- passes/opt/opt_const.cc | 3 +- passes/opt/opt_muxtree.cc | 6 +-- passes/opt/opt_reduce.cc | 13 ++---- passes/opt/opt_rmdff.cc | 3 +- passes/opt/opt_share.cc | 3 +- passes/proc/proc_dff.cc | 65 ++++++---------------------- passes/proc/proc_mux.cc | 17 ++------ passes/sat/expose.cc | 21 +++------ passes/sat/freduce.cc | 5 +-- passes/sat/miter.cc | 51 +++++----------------- passes/sat/share.cc | 8 +--- passes/techmap/dfflibmap.cc | 35 +++++++-------- passes/techmap/extract.cc | 13 ++---- passes/techmap/hilomap.cc | 10 +---- passes/techmap/iopadmap.cc | 10 +---- passes/techmap/simplemap.cc | 76 +++++++-------------------------- passes/techmap/techmap.cc | 37 +++++++++------- 35 files changed, 259 insertions(+), 582 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index e74f36ab..c121a869 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 3fe5199f..82826a35 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 3fe227be..74524792 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 { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 83524d79..17e4a273 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -782,8 +782,14 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const for (auto &it : memories) new_mod->memories[it.first] = new RTLIL::Memory(*it.second); - for (auto &it : cells) - new_mod->cells[it.first] = new RTLIL::Cell(*it.second); + for (auto &it : cells) { + new_mod->cells[it.first] = new RTLIL::Cell; + new_mod->cells[it.first]->name = it.second->name; + new_mod->cells[it.first]->type = it.second->type; + new_mod->cells[it.first]->connections = it.second->connections; + new_mod->cells[it.first]->parameters = it.second->parameters; + new_mod->cells[it.first]->attributes = it.second->attributes; + } for (auto &it : processes) new_mod->processes[it.first] = it.second->clone(); @@ -834,6 +840,33 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) delete cell; } +void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) +{ + assert(wires[wire->name] == wire); + wires.erase(wire->name); + wire->name = new_name; + add(wire); +} + +void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name) +{ + assert(cells[cell->name] == cell); + cells.erase(cell->name); + cell->name = new_name; + add(cell); +} + +void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name) +{ + assert(count_id(old_name) != 0); + if (wires.count(old_name)) + rename(wires.at(old_name), new_name); + else if (cells.count(old_name)) + rename(cells.at(old_name), new_name); + else + log_abort(); +} + static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) { if (a->port_id && !b->port_id) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 59db099f..e1e4a54b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -271,7 +271,8 @@ struct RTLIL::Design { return attributes.at(id).as_bool(); \ } -struct RTLIL::Module { +struct RTLIL::Module +{ RTLIL::IdString name; std::set avail_parameters; std::map wires; @@ -295,6 +296,10 @@ struct RTLIL::Module { void add(RTLIL::Cell *cell); void remove(RTLIL::Cell *cell); + void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); + void rename(RTLIL::Cell *cell, RTLIL::IdString new_name); + void rename(RTLIL::IdString old_name, RTLIL::IdString new_name); + RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); @@ -444,7 +449,19 @@ struct RTLIL::Memory { Memory(); }; -struct RTLIL::Cell { +struct RTLIL::Cell +{ +protected: + // Use module->addCell() and module->remove() to create or destroy modules. + friend struct RTLIL::Module; + Cell() { }; + ~Cell() { }; + +public: + // do not copy simply cells + Cell(RTLIL::Cell &other) = delete; + void operator=(RTLIL::Cell &other) = delete; + RTLIL::IdString name; RTLIL::IdString type; std::map connections; diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index d25f88c0..980e69aa 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -127,8 +127,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) map_signal(sig_q, 'f', map_signal(sig_d)); - module->cells.erase(cell->name); - delete cell; + module->remove(cell); return; } @@ -142,8 +141,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) map_signal(sig_y, 'n', map_signal(sig_a)); - module->cells.erase(cell->name); - delete cell; + module->remove(cell); return; } @@ -169,8 +167,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) else log_abort(); - module->cells.erase(cell->name); - delete cell; + module->remove(cell); return; } @@ -192,8 +189,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) map_signal(sig_y, 'm', mapped_a, mapped_b, mapped_s); - module->cells.erase(cell->name); - delete cell; + module->remove(cell); return; } } @@ -722,47 +718,35 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std continue; } if (c->type == "\\INV") { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->type = "$_INV_"; - cell->name = remap_name(c->name); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_INV_"); cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); - module->cells[cell->name] = cell; design->select(module, cell); continue; } if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR") { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->type = "$_" + c->type.substr(1) + "_"; - cell->name = remap_name(c->name); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].as_wire()->name)]); cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); - module->cells[cell->name] = cell; design->select(module, cell); continue; } if (c->type == "\\MUX") { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->type = "$_MUX_"; - cell->name = remap_name(c->name); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_"); cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].as_wire()->name)]); cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].as_wire()->name)]); cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); - module->cells[cell->name] = cell; design->select(module, cell); continue; } if (c->type == "\\DFF") { log_assert(clk_sig.size() == 1); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; - cell->name = remap_name(c->name); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].as_wire()->name)]); cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].as_wire()->name)]); cell->connections["\\C"] = clk_sig; - module->cells[cell->name] = cell; design->select(module, cell); continue; } @@ -784,20 +768,15 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } if (c->type == "\\_dff_") { log_assert(clk_sig.size() == 1); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->type = clk_polarity ? "$_DFF_P_" : "$_DFF_N_"; - cell->name = remap_name(c->name); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].as_wire()->name)]); cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].as_wire()->name)]); cell->connections["\\C"] = clk_sig; - module->cells[cell->name] = cell; design->select(module, cell); continue; } - RTLIL::Cell *cell = new RTLIL::Cell; - cell->type = c->type; + RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); cell->parameters = c->parameters; - cell->name = remap_name(c->name); for (auto &conn : c->connections) { RTLIL::SigSpec newsig; for (auto &c : conn.second.chunks()) { @@ -808,7 +787,6 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } cell->connections[conn.first] = newsig; } - module->cells[cell->name] = cell; design->select(module, cell); } } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 04977b36..e7feb187 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -127,36 +127,27 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) module->add(wire); } - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = dff_name; + RTLIL::Cell *cell = module->addCell(NEW_ID, dff_name); cell->connections["\\D"] = module->wires.at(RTLIL::escape_id(d)); cell->connections["\\Q"] = module->wires.at(RTLIL::escape_id(q)); - module->add(cell); continue; } if (!strcmp(cmd, ".gate")) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - module->add(cell); - char *p = strtok(NULL, " \t\r\n"); if (p == NULL) goto error; - cell->type = RTLIL::escape_id(p); + + RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(p)); while ((p = strtok(NULL, " \t\r\n")) != NULL) { char *q = strchr(p, '='); if (q == NULL || !q[0] || !q[1]) goto error; *(q++) = 0; - if (module->wires.count(RTLIL::escape_id(q)) == 0) { - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(q); - module->add(wire); - } + if (module->wires.count(RTLIL::escape_id(q)) == 0) + module->addWire(RTLIL::escape_id(q)); cell->connections[RTLIL::escape_id(p)] = module->wires.at(RTLIL::escape_id(q)); } continue; @@ -212,16 +203,13 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) goto continue_without_read; } - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$lut"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$lut"); cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size()); cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size()); cell->connections["\\I"] = input_sig; cell->connections["\\O"] = output_sig; lutptr = &cell->parameters.at("\\LUT"); lut_default_state = RTLIL::State::Sx; - module->add(cell); continue; } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 7fe95b0a..79b7c3c3 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -107,7 +107,7 @@ struct DeletePass : public Pass { } std::set delete_wires; - std::set delete_cells; + std::set delete_cells; std::set delete_procs; std::set delete_mems; @@ -121,10 +121,10 @@ struct DeletePass : public Pass { for (auto &it : module->cells) { if (design->selected(module, it.second)) - delete_cells.insert(it.first); + delete_cells.insert(it.second); if ((it.second->type == "$memrd" || it.second->type == "$memwr") && delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0) - delete_cells.insert(it.first); + delete_cells.insert(it.second); } for (auto &it : module->processes) @@ -147,8 +147,7 @@ struct DeletePass : public Pass { } for (auto &it : delete_cells) { - delete module->cells.at(it); - module->cells.erase(it); + module->remove(it); } for (auto &it : delete_procs) { diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 68e8951f..a470aed0 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -70,16 +70,13 @@ struct SpliceWorker RTLIL::SigSpec new_sig = sig; if (sig_a.size() != sig.size()) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$slice"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$slice"); cell->parameters["\\OFFSET"] = offset; cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig.size(); cell->connections["\\A"] = sig_a; cell->connections["\\Y"] = module->addWire(NEW_ID, sig.size()); new_sig = cell->connections["\\Y"]; - module->add(cell); } sliced_signals_cache[sig] = new_sig; @@ -130,16 +127,13 @@ struct SpliceWorker RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front()); for (size_t i = 1; i < chunks.size(); i++) { RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$concat"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat"); cell->parameters["\\A_WIDTH"] = new_sig.size(); cell->parameters["\\B_WIDTH"] = sig2.size(); cell->connections["\\A"] = new_sig; cell->connections["\\B"] = sig2; cell->connections["\\Y"] = module->addWire(NEW_ID, new_sig.size() + sig2.size()); new_sig = cell->connections["\\Y"]; - module->add(cell); } spliced_signals_cache[sig] = new_sig; diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 0dd328db..f3b6c998 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -226,10 +226,8 @@ struct FsmExpand merge_cell_into_fsm(c); } - for (auto c : merged_set) { - module->cells.erase(c->name); - delete c; - } + for (auto c : merged_set) + module->remove(c); if (merged_set.size() > 0 && !already_optimized) FsmData::optimize_fsm(fsm_cell, module); diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index dfd025a5..1b5ea1bc 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -270,9 +270,7 @@ static void extract_fsm(RTLIL::Wire *wire) // create fsm cell - RTLIL::Cell *fsm_cell = new RTLIL::Cell; - fsm_cell->name = stringf("$fsm$%s$%d", wire->name.c_str(), RTLIL::autoidx++); - fsm_cell->type = "$fsm"; + RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), RTLIL::autoidx++), "$fsm"); fsm_cell->connections["\\CLK"] = clk; fsm_cell->connections["\\ARST"] = arst; fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); @@ -282,7 +280,6 @@ static void extract_fsm(RTLIL::Wire *wire) fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name); fsm_cell->attributes = wire->attributes; fsm_data.copy_to_cell(fsm_cell); - module->cells[fsm_cell->name] = fsm_cell; // rename original state wire diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index cee26762..78248eb6 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -54,13 +54,10 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 0) { - RTLIL::Wire *eq_wire = new RTLIL::Wire; - eq_wire->name = NEW_ID; - module->add(eq_wire); + RTLIL::Wire *eq_wire = module->addWire(NEW_ID); + and_sig.append(RTLIL::SigSpec(eq_wire)); - RTLIL::Cell *eq_cell = new RTLIL::Cell; - eq_cell->name = NEW_ID; - eq_cell->type = "$eq"; + RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq"); eq_cell->connections["\\A"] = eq_sig_a; eq_cell->connections["\\B"] = eq_sig_b; eq_cell->connections["\\Y"] = RTLIL::SigSpec(eq_wire); @@ -69,9 +66,6 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapparameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size()); eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - module->add(eq_cell); - - and_sig.append(RTLIL::SigSpec(eq_wire)); } if (or_sig.size() < num_states-int(fullstate_cache.size())) @@ -82,21 +76,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapname = NEW_ID; - module->add(or_wire); + RTLIL::Wire *or_wire = module->addWire(NEW_ID); + and_sig.append(RTLIL::SigSpec(or_wire)); - RTLIL::Cell *or_cell = new RTLIL::Cell; - or_cell->name = NEW_ID; - or_cell->type = "$reduce_or"; + RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or"); or_cell->connections["\\A"] = or_sig; or_cell->connections["\\Y"] = RTLIL::SigSpec(or_wire); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - module->add(or_cell); - - and_sig.append(RTLIL::SigSpec(or_wire)); } } @@ -104,13 +92,10 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapname = NEW_ID; - module->add(and_wire); + RTLIL::Wire *and_wire = module->addWire(NEW_ID); + cases_vector.append(RTLIL::SigSpec(and_wire)); - RTLIL::Cell *and_cell = new RTLIL::Cell; - and_cell->name = NEW_ID; - and_cell->type = "$and"; + RTLIL::Cell *and_cell = module->addCell(NEW_ID, "$and"); and_cell->connections["\\A"] = and_sig.extract(0, 1); and_cell->connections["\\B"] = and_sig.extract(1, 1); and_cell->connections["\\Y"] = RTLIL::SigSpec(and_wire); @@ -119,9 +104,6 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapparameters["\\A_WIDTH"] = RTLIL::Const(1); and_cell->parameters["\\B_WIDTH"] = RTLIL::Const(1); and_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - module->add(and_cell); - - cases_vector.append(RTLIL::SigSpec(and_wire)); break; } case 1: @@ -136,15 +118,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 1) { - RTLIL::Cell *or_cell = new RTLIL::Cell; - or_cell->name = NEW_ID; - or_cell->type = "$reduce_or"; + RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or"); or_cell->connections["\\A"] = cases_vector; or_cell->connections["\\Y"] = output; or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - module->add(or_cell); } else if (cases_vector.size() == 1) { module->connections.push_back(RTLIL::SigSig(output, cases_vector)); } else { @@ -171,13 +150,9 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) state_wire->width = fsm_data.state_bits; module->add(state_wire); - RTLIL::Wire *next_state_wire = new RTLIL::Wire; - next_state_wire->name = NEW_ID; - next_state_wire->width = fsm_data.state_bits; - module->add(next_state_wire); + RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits); - RTLIL::Cell *state_dff = new RTLIL::Cell; - state_dff->name = NEW_ID; + RTLIL::Cell *state_dff = module->addCell(NEW_ID, ""); if (fsm_cell->connections["\\ARST"].is_fully_const()) { state_dff->type = "$dff"; } else { @@ -194,16 +169,12 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) state_dff->connections["\\CLK"] = fsm_cell->connections["\\CLK"]; state_dff->connections["\\D"] = RTLIL::SigSpec(next_state_wire); state_dff->connections["\\Q"] = RTLIL::SigSpec(state_wire); - module->add(state_dff); // decode state register bool encoding_is_onehot = true; - RTLIL::Wire *state_onehot = new RTLIL::Wire; - state_onehot->name = NEW_ID; - state_onehot->width = fsm_data.state_table.size(); - module->add(state_onehot); + RTLIL::Wire *state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size()); for (size_t i = 0; i < fsm_data.state_table.size(); i++) { @@ -224,9 +195,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) { encoding_is_onehot = false; - RTLIL::Cell *eq_cell = new RTLIL::Cell; - eq_cell->name = NEW_ID; - eq_cell->type = "$eq"; + RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq"); eq_cell->connections["\\A"] = sig_a; eq_cell->connections["\\B"] = sig_b; eq_cell->connections["\\Y"] = RTLIL::SigSpec(state_onehot, i); @@ -235,7 +204,6 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size()); eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - module->add(eq_cell); } } @@ -296,16 +264,13 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) } } - RTLIL::Cell *mux_cell = new RTLIL::Cell; - mux_cell->name = NEW_ID; - mux_cell->type = "$safe_pmux"; + RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux"); mux_cell->connections["\\A"] = sig_a; mux_cell->connections["\\B"] = sig_b; mux_cell->connections["\\S"] = sig_s; mux_cell->connections["\\Y"] = RTLIL::SigSpec(next_state_wire); mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); - module->add(mux_cell); } // Generate ctrl_out signal @@ -335,8 +300,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) // Remove FSM cell - module->cells.erase(fsm_cell->name); - delete fsm_cell; + module->remove(fsm_cell); } struct FsmMapPass : public Pass { diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 25730188..204f899a 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -162,7 +162,10 @@ struct SubmodWorker } for (RTLIL::Cell *cell : submod.cells) { - RTLIL::Cell *new_cell = new RTLIL::Cell(*cell); + RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell->type); + new_cell->connections = cell->connections; + new_cell->parameters = cell->parameters; + new_cell->attributes = cell->attributes; for (auto &conn : new_cell->connections) for (auto &bit : conn.second) if (bit.wire != NULL) { @@ -170,15 +173,11 @@ struct SubmodWorker bit.wire = wire_flags[bit.wire].new_wire; } log(" cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str()); - new_mod->cells[new_cell->name] = new_cell; - module->cells.erase(cell->name); - delete cell; + module->remove(cell); } submod.cells.clear(); - RTLIL::Cell *new_cell = new RTLIL::Cell; - new_cell->name = submod.full_name; - new_cell->type = submod.full_name; + RTLIL::Cell *new_cell = module->addCell(submod.full_name, submod.full_name); for (auto &it : wire_flags) { RTLIL::Wire *old_wire = it.first; @@ -186,7 +185,6 @@ struct SubmodWorker if (new_wire->port_id > 0) new_cell->connections[new_wire->name] = RTLIL::SigSpec(old_wire); } - module->cells[new_cell->name] = new_cell; } SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, std::string opt_name = std::string()) : design(design), module(module), opt_name(opt_name) diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 3ceb5da3..116b704e 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -58,7 +58,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) RTLIL::SigSpec sig_rd_addr; RTLIL::SigSpec sig_rd_data; - std::vector del_cell_ids; + std::vector del_cells; std::vector memcells; for (auto &cell_it : module->cells) { @@ -74,7 +74,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) if (cell->type == "$memwr" && cell->parameters["\\MEMID"].decode_string() == memory->name) { wr_ports++; - del_cell_ids.push_back(cell->name); + del_cells.push_back(cell); RTLIL::SigSpec clk = cell->connections["\\CLK"]; RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); @@ -101,7 +101,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) if (cell->type == "$memrd" && cell->parameters["\\MEMID"].decode_string() == memory->name) { rd_ports++; - del_cell_ids.push_back(cell->name); + del_cells.push_back(cell); RTLIL::SigSpec clk = cell->connections["\\CLK"]; RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); @@ -129,10 +129,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) std::stringstream sstr; sstr << "$mem$" << memory->name << "$" << (RTLIL::autoidx++); - RTLIL::Cell *mem = new RTLIL::Cell; - mem->name = sstr.str(); - mem->type = "$mem"; - + RTLIL::Cell *mem = module->addCell(sstr.str(), "$mem"); mem->parameters["\\MEMID"] = RTLIL::Const(memory->name); mem->parameters["\\WIDTH"] = RTLIL::Const(memory->width); mem->parameters["\\OFFSET"] = RTLIL::Const(memory->start_offset); @@ -170,11 +167,8 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->connections["\\RD_ADDR"] = sig_rd_addr; mem->connections["\\RD_DATA"] = sig_rd_data; - for (auto &id : del_cell_ids) { - delete module->cells[id]; - module->cells.erase(id); - } - module->cells[mem->name] = mem; + for (auto c : del_cells) + module->remove(c); } static void handle_module(RTLIL::Design *design, RTLIL::Module *module) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index e605e6e5..b5f0520a 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -57,8 +57,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) // delete unused memory cell if (cell->parameters["\\RD_PORTS"].as_int() == 0 && cell->parameters["\\WR_PORTS"].as_int() == 0) { - module->cells.erase(cell->name); - delete cell; + module->remove(cell); return; } @@ -117,9 +116,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) } else { - RTLIL::Cell *c = new RTLIL::Cell; - c->name = genid(cell->name, "", i); - c->type = "$dff"; + RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), "$dff"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; if (clocks_pol.bits.size() > 0) { c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]); @@ -128,7 +125,6 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1); c->connections["\\CLK"] = RTLIL::SigSpec(RTLIL::State::S0); } - module->cells[c->name] = c; RTLIL::Wire *w_in = new RTLIL::Wire; w_in->name = genid(cell->name, "", i, "$d"); @@ -164,14 +160,11 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) { if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1) { - RTLIL::Cell *c = new RTLIL::Cell; - c->name = genid(cell->name, "$rdreg", i); - c->type = "$dff"; + RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = RTLIL::Const(mem_abits); c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); c->connections["\\CLK"] = cell->connections["\\RD_CLK"].extract(i, 1); c->connections["\\D"] = rd_addr; - module->cells[c->name] = c; count_dff++; RTLIL::Wire *w = new RTLIL::Wire; @@ -184,14 +177,11 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) } else { - RTLIL::Cell *c = new RTLIL::Cell; - c->name = genid(cell->name, "$rdreg", i); - c->type = "$dff"; + RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); c->connections["\\CLK"] = cell->connections["\\RD_CLK"].extract(i, 1); c->connections["\\Q"] = rd_signals.back(); - module->cells[c->name] = c; count_dff++; RTLIL::Wire *w = new RTLIL::Wire; @@ -211,13 +201,10 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) for (size_t k = 0; k < rd_signals.size(); k++) { - RTLIL::Cell *c = new RTLIL::Cell; - c->name = genid(cell->name, "$rdmux", i, "", j, "", k); - c->type = "$mux"; + RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; c->connections["\\Y"] = rd_signals[k]; c->connections["\\S"] = rd_addr.extract(mem_abits-j-1, 1); - module->cells[c->name] = c; count_mux++; RTLIL::Wire *w = new RTLIL::Wire; @@ -258,9 +245,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec wr_data = cell->connections["\\WR_DATA"].extract(j*mem_width, mem_width); RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(j*mem_width, mem_width); - RTLIL::Cell *c = new RTLIL::Cell; - c->name = genid(cell->name, "$wreq", i, "", j); - c->type = "$eq"; + RTLIL::Cell *c = module->addCell(genid(cell->name, "$wreq", i, "", j), "$eq"); c->parameters["\\A_SIGNED"] = RTLIL::Const(0); c->parameters["\\B_SIGNED"] = RTLIL::Const(0); c->parameters["\\A_WIDTH"] = cell->parameters["\\ABITS"]; @@ -268,7 +253,6 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); c->connections["\\A"] = RTLIL::SigSpec(i, mem_abits); c->connections["\\B"] = wr_addr; - module->cells[c->name] = c; count_wrmux++; RTLIL::Wire *w_seladdr = new RTLIL::Wire; @@ -293,9 +277,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) if (wr_bit != RTLIL::SigSpec(1, 1)) { - c = new RTLIL::Cell; - c->name = genid(cell->name, "$wren", i, "", j, "", wr_offset); - c->type = "$and"; + c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); c->parameters["\\A_SIGNED"] = RTLIL::Const(0); c->parameters["\\B_SIGNED"] = RTLIL::Const(0); c->parameters["\\A_WIDTH"] = RTLIL::Const(1); @@ -303,7 +285,6 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); c->connections["\\A"] = w; c->connections["\\B"] = wr_bit; - module->cells[c->name] = c; w = new RTLIL::Wire; w->name = genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"); @@ -311,14 +292,11 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->connections["\\Y"] = RTLIL::SigSpec(w); } - c = new RTLIL::Cell; - c->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset); - c->type = "$mux"; + c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); c->parameters["\\WIDTH"] = wr_width; c->connections["\\A"] = sig.extract(wr_offset, wr_width); c->connections["\\B"] = wr_data.extract(wr_offset, wr_width); c->connections["\\S"] = RTLIL::SigSpec(w); - module->cells[c->name] = c; w = new RTLIL::Wire; w->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"); @@ -336,9 +314,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) log(" write interface: %d blocks of $eq, $and and $mux cells.\n", count_wrmux); - module->cells.erase(cell->name); - delete cell; - return; + module->remove(cell); } static void handle_module(RTLIL::Design *design, RTLIL::Module *module) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index dd2a32ca..63f6b14f 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -446,8 +446,7 @@ struct MemoryShareWorker cell->connections.at("\\EN") = merged_en; cell->connections.at("\\DATA") = merged_data; - module->cells.erase(wr_ports[last_i]->name); - delete wr_ports[last_i]; + module->remove(wr_ports[last_i]); wr_ports[last_i] = NULL; log(" Active bits: "); @@ -617,8 +616,7 @@ struct MemoryShareWorker module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); wr_ports[i]->connections.at("\\EN") = en; - module->cells.erase(wr_ports[i-1]->name); - delete wr_ports[i-1]; + module->remove(wr_ports[i-1]); wr_ports[i-1] = NULL; } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index bbd01583..97cda144 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -47,9 +47,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) for (int i = 0; i < num_rd_ports; i++) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$memrd"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$memrd"); cell->parameters["\\MEMID"] = mem_name; cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS"); cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH"); @@ -59,14 +57,11 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->connections["\\CLK"] = memory->connections.at("\\RD_CLK").extract(i, 1); cell->connections["\\ADDR"] = memory->connections.at("\\RD_ADDR").extract(i*abits, abits); cell->connections["\\DATA"] = memory->connections.at("\\RD_DATA").extract(i*mem->width, mem->width); - module->add(cell); } for (int i = 0; i < num_wr_ports; i++) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$memwr"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$memwr"); cell->parameters["\\MEMID"] = mem_name; cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS"); cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH"); @@ -77,11 +72,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->connections["\\EN"] = memory->connections.at("\\WR_EN").extract(i*mem->width, mem->width); cell->connections["\\ADDR"] = memory->connections.at("\\WR_ADDR").extract(i*abits, abits); cell->connections["\\DATA"] = memory->connections.at("\\WR_DATA").extract(i*mem->width, mem->width); - module->add(cell); } - module->cells.erase(memory->name); - delete memory; + module->remove(memory); } static void handle_module(RTLIL::Design *design, RTLIL::Module *module) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 02efabf7..00fa6031 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -90,9 +90,8 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) if (verbose) log(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str()); OPT_DID_SOMETHING = true; - module->cells.erase(cell->name); + module->remove(cell); count_rm_cells++; - delete cell; } } diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index e2bf7004..e1b6c598 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -81,8 +81,7 @@ static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string i module->name.c_str(), log_signal(Y), log_signal(out_val)); // ILANG_BACKEND::dump_cell(stderr, "--> ", cell); module->connections.push_back(RTLIL::SigSig(Y, out_val)); - module->cells.erase(cell->name); - delete cell; + module->remove(cell); OPT_DID_SOMETHING = true; did_something = true; } diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index dfcd5512..750a9d41 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -190,8 +190,7 @@ struct OptMuxtreeWorker continue; if (live_ports.size() == 0) { - module->cells.erase(mi.cell->name); - delete mi.cell; + module->remove(mi.cell); continue; } @@ -207,8 +206,7 @@ struct OptMuxtreeWorker { RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.size(), sig_a.size()); module->connections.push_back(RTLIL::SigSig(sig_y, sig_in)); - module->cells.erase(mi.cell->name); - delete mi.cell; + module->remove(mi.cell); } else { diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 0cc16ee6..073af308 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -124,19 +124,13 @@ struct OptReduceWorker if (this_s.size() > 1) { - RTLIL::Wire *reduce_or_wire = new RTLIL::Wire; - reduce_or_wire->name = NEW_ID; - module->wires[reduce_or_wire->name] = reduce_or_wire; - - RTLIL::Cell *reduce_or_cell = new RTLIL::Cell; - reduce_or_cell->name = NEW_ID; - reduce_or_cell->type = "$reduce_or"; + RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, "$reduce_or"); reduce_or_cell->connections["\\A"] = this_s; reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size()); reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - module->cells[reduce_or_cell->name] = reduce_or_cell; + RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); this_s = RTLIL::SigSpec(reduce_or_wire); reduce_or_cell->connections["\\Y"] = this_s; } @@ -157,8 +151,7 @@ struct OptReduceWorker { module->connections.push_back(RTLIL::SigSig(cell->connections["\\Y"], cell->connections["\\A"])); assign_map.add(cell->connections["\\Y"], cell->connections["\\A"]); - module->cells.erase(cell->name); - delete cell; + module->remove(cell); } else { diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 4215a7b5..6a35cb61 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -143,8 +143,7 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) delete_dff: log("Removing %s (%s) from module %s.\n", dff->name.c_str(), dff->type.c_str(), mod->name.c_str()); OPT_DID_SOMETHING = true; - mod->cells.erase(dff->name); - delete dff; + mod->remove(dff); return true; } diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 819a0e46..e3e9511f 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -271,10 +271,9 @@ struct OptShareWorker } } log(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); - module->cells.erase(cell->name); + module->remove(cell); OPT_DID_SOMETHING = true; total_count++; - delete cell; } else { sharemap[cell] = cell; } diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 5982fd8e..876adb0d 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -73,79 +73,59 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S log_abort(); if (sync_low_signals.size() > 1) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$reduce_or"; + RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or"); cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; cell->connections["\\Y"] = sync_low_signals = mod->addWire(NEW_ID); - mod->add(cell); } if (sync_low_signals.size() > 0) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$not"; + RTLIL::Cell *cell = mod->addCell(NEW_ID, "$not"); cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_low_signals; cell->connections["\\Y"] = mod->addWire(NEW_ID); sync_high_signals.append(cell->connections["\\Y"]); - mod->add(cell); } if (sync_high_signals.size() > 1) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$reduce_or"; + RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or"); cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); cell->connections["\\A"] = sync_high_signals; cell->connections["\\Y"] = sync_high_signals = mod->addWire(NEW_ID); - mod->add(cell); } - RTLIL::Cell *inv_cell = new RTLIL::Cell; - inv_cell->name = NEW_ID; - inv_cell->type = "$not"; + RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, "$not"); inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size()); inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size()); inv_cell->connections["\\A"] = sync_value; inv_cell->connections["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.size()); - mod->add(inv_cell); - RTLIL::Cell *mux_set_cell = new RTLIL::Cell; - mux_set_cell->name = NEW_ID; - mux_set_cell->type = "$mux"; + RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, "$mux"); mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); mux_set_cell->connections["\\A"] = sig_sr_set; mux_set_cell->connections["\\B"] = sync_value; mux_set_cell->connections["\\S"] = sync_high_signals; mux_set_cell->connections["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.size()); - mod->add(mux_set_cell); - RTLIL::Cell *mux_clr_cell = new RTLIL::Cell; - mux_clr_cell->name = NEW_ID; - mux_clr_cell->type = "$mux"; + RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, "$mux"); mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); mux_clr_cell->connections["\\A"] = sig_sr_clr; mux_clr_cell->connections["\\B"] = sync_value_inv; mux_clr_cell->connections["\\S"] = sync_high_signals; mux_clr_cell->connections["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()); - mod->add(mux_clr_cell); } std::stringstream sstr; sstr << "$procdff$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = sstr.str(); - cell->type = "$dffsr"; + RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); @@ -156,7 +136,6 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->connections["\\CLK"] = clk; cell->connections["\\SET"] = sig_sr_set; cell->connections["\\CLR"] = sig_sr_clr; - mod->add(cell); log(" created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); @@ -172,39 +151,28 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size()); RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.size()); - RTLIL::Cell *inv_set = new RTLIL::Cell; - inv_set->name = NEW_ID; - inv_set->type = "$not"; + RTLIL::Cell *inv_set = mod->addCell(NEW_ID, "$not"); inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size()); inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size()); inv_set->connections["\\A"] = sig_set; inv_set->connections["\\Y"] = sig_set_inv; - mod->add(inv_set); - RTLIL::Cell *mux_sr_set = new RTLIL::Cell; - mux_sr_set->name = NEW_ID; - mux_sr_set->type = "$mux"; + RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux"); mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); mux_sr_set->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); mux_sr_set->connections[set_polarity ? "\\B" : "\\A"] = sig_set; mux_sr_set->connections["\\Y"] = sig_sr_set; mux_sr_set->connections["\\S"] = set; - mod->add(mux_sr_set); - RTLIL::Cell *mux_sr_clr = new RTLIL::Cell; - mux_sr_clr->name = NEW_ID; - mux_sr_clr->type = "$mux"; + RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux"); mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); mux_sr_clr->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); mux_sr_clr->connections[set_polarity ? "\\B" : "\\A"] = sig_set_inv; mux_sr_clr->connections["\\Y"] = sig_sr_clr; mux_sr_clr->connections["\\S"] = set; - mod->add(mux_sr_clr); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = sstr.str(); - cell->type = "$dffsr"; + RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); @@ -215,7 +183,6 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec cell->connections["\\CLK"] = clk; cell->connections["\\SET"] = sig_sr_set; cell->connections["\\CLR"] = sig_sr_clr; - mod->add(cell); log(" created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative", set_polarity ? "positive" : "negative"); @@ -227,11 +194,8 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ std::stringstream sstr; sstr << "$procdff$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = sstr.str(); - cell->type = arst ? "$adff" : "$dff"; + RTLIL::Cell *cell = mod->addCell(sstr.str(), arst ? "$adff" : "$dff"); cell->attributes = proc->attributes; - mod->cells[cell->name] = cell; cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); if (arst) { @@ -326,9 +290,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) } assert(inputs.size() == compare.size()); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$ne"; + RTLIL::Cell *cell = mod->addCell(NEW_ID, "$ne"); cell->parameters["\\A_SIGNED"] = RTLIL::Const(false, 1); cell->parameters["\\B_SIGNED"] = RTLIL::Const(false, 1); cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size()); @@ -337,7 +299,6 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) cell->connections["\\A"] = inputs; cell->connections["\\B"] = compare; cell->connections["\\Y"] = sync_level->signal; - mod->add(cell); many_async_rules.clear(); } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 804c51fd..5bb1ab94 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -86,13 +86,8 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, else { // create compare cell - RTLIL::Cell *eq_cell = new RTLIL::Cell; - std::stringstream sstr2; - sstr2 << sstr.str() << "_CMP" << cmp_wire->width; - eq_cell->name = sstr2.str(); - eq_cell->type = "$eq"; + RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), "$eq"); eq_cell->attributes = sw->attributes; - mod->cells[eq_cell->name] = eq_cell; eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0); @@ -120,11 +115,8 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, mod->wires[ctrl_wire->name] = ctrl_wire; // reduce cmp vector to one logic signal - RTLIL::Cell *any_cell = new RTLIL::Cell; - any_cell->name = sstr.str() + "_ANY"; - any_cell->type = "$reduce_or"; + RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", "$reduce_or"); any_cell->attributes = sw->attributes; - mod->cells[any_cell->name] = any_cell; any_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width); @@ -161,11 +153,8 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, mod->wires[result_wire->name] = result_wire; // create the multiplexer itself - RTLIL::Cell *mux_cell = new RTLIL::Cell; - mux_cell->name = sstr.str(); - mux_cell->type = "$mux"; + RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), "$mux"); mux_cell->attributes = sw->attributes; - mod->cells[mux_cell->name] = mux_cell; mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size()); mux_cell->connections["\\A"] = else_signal; diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index c9363f4b..29ce899e 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -554,15 +554,12 @@ struct ExposePass : public Pass { if (info.clk_polarity) { module->connections.push_back(RTLIL::SigSig(wire_c, info.sig_clk)); } else { - RTLIL::Cell *c = new RTLIL::Cell; - c->name = NEW_ID; - c->type = "$not"; + RTLIL::Cell *c = module->addCell(NEW_ID, "$not"); c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; c->connections["\\A"] = info.sig_clk; c->connections["\\Y"] = wire_c; - module->add(c); } if (info.sig_arst != RTLIL::State::Sm) @@ -575,15 +572,12 @@ struct ExposePass : public Pass { if (info.arst_polarity) { module->connections.push_back(RTLIL::SigSig(wire_r, info.sig_arst)); } else { - RTLIL::Cell *c = new RTLIL::Cell; - c->name = NEW_ID; - c->type = "$not"; + RTLIL::Cell *c = module->addCell(NEW_ID, "$not"); c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; c->connections["\\A"] = info.sig_arst; c->connections["\\Y"] = wire_r; - module->add(c); } RTLIL::Wire *wire_v = new RTLIL::Wire; @@ -598,7 +592,7 @@ struct ExposePass : public Pass { if (flag_evert) { - std::vector delete_cells; + std::vector delete_cells; for (auto &it : module->cells) { @@ -665,13 +659,12 @@ struct ExposePass : public Pass { } } - delete_cells.push_back(cell->name); + delete_cells.push_back(cell); } - for (auto &it : delete_cells) { - log("Removing cell: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it), RTLIL::id2cstr(module->cells.at(it)->type)); - delete module->cells.at(it); - module->cells.erase(it); + for (auto cell : delete_cells) { + log("Removing cell: %s/%s (%s)\n", log_id(module), log_id(cell), log_id(cell->type)); + module->remove(cell); } } diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index ba01bc32..79dec3b5 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -718,12 +718,9 @@ struct FreduceWorker { inv_sig = module->addWire(NEW_ID); - RTLIL::Cell *inv_cell = new RTLIL::Cell; - inv_cell->name = NEW_ID; - inv_cell->type = "$_INV_"; + RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_INV_"); inv_cell->connections["\\A"] = grp[0].bit; inv_cell->connections["\\Y"] = inv_sig; - module->add(inv_cell); } module->connections.push_back(RTLIL::SigSig(grp[i].bit, inv_sig)); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 12384e2c..aff66424 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -115,15 +115,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, miter_module->name = miter_name; design->modules[miter_name] = miter_module; - RTLIL::Cell *gold_cell = new RTLIL::Cell; - gold_cell->name = "\\gold"; - gold_cell->type = gold_name; - miter_module->add(gold_cell); - - RTLIL::Cell *gate_cell = new RTLIL::Cell; - gate_cell->name = "\\gate"; - gate_cell->type = gate_name; - miter_module->add(gate_cell); + RTLIL::Cell *gold_cell = miter_module->addCell("\\gold", gold_name); + RTLIL::Cell *gate_cell = miter_module->addCell("\\gate", gate_name); RTLIL::SigSpec all_conditions; @@ -166,9 +159,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, { RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w2_gold->width); for (int i = 0; i < w2_gold->width; i++) { - RTLIL::Cell *eqx_cell = new RTLIL::Cell; - eqx_cell->name = NEW_ID; - eqx_cell->type = "$eqx"; + RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx"); eqx_cell->parameters["\\A_WIDTH"] = 1; eqx_cell->parameters["\\B_WIDTH"] = 1; eqx_cell->parameters["\\Y_WIDTH"] = 1; @@ -177,15 +168,12 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eqx_cell->connections["\\A"] = RTLIL::SigSpec(w2_gold, i); eqx_cell->connections["\\B"] = RTLIL::State::Sx; eqx_cell->connections["\\Y"] = gold_x.extract(i, 1); - miter_module->add(eqx_cell); } RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width); RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w2_gate->width); - RTLIL::Cell *or_gold_cell = new RTLIL::Cell; - or_gold_cell->name = NEW_ID; - or_gold_cell->type = "$or"; + RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or"); or_gold_cell->parameters["\\A_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\B_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width; @@ -194,11 +182,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gold_cell->connections["\\A"] = w2_gold; or_gold_cell->connections["\\B"] = gold_x; or_gold_cell->connections["\\Y"] = gold_masked; - miter_module->add(or_gold_cell); - RTLIL::Cell *or_gate_cell = new RTLIL::Cell; - or_gate_cell->name = NEW_ID; - or_gate_cell->type = "$or"; + RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or"); or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\B_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width; @@ -207,11 +192,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gate_cell->connections["\\A"] = w2_gate; or_gate_cell->connections["\\B"] = gold_x; or_gate_cell->connections["\\Y"] = gate_masked; - miter_module->add(or_gate_cell); - RTLIL::Cell *eq_cell = new RTLIL::Cell; - eq_cell->name = NEW_ID; - eq_cell->type = "$eqx"; + RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; eq_cell->parameters["\\B_WIDTH"] = w2_gate->width; eq_cell->parameters["\\Y_WIDTH"] = 1; @@ -221,13 +203,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->connections["\\B"] = gate_masked; eq_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); this_condition = eq_cell->connections["\\Y"]; - miter_module->add(eq_cell); } else { - RTLIL::Cell *eq_cell = new RTLIL::Cell; - eq_cell->name = NEW_ID; - eq_cell->type = "$eqx"; + RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; eq_cell->parameters["\\B_WIDTH"] = w2_gate->width; eq_cell->parameters["\\Y_WIDTH"] = 1; @@ -237,7 +216,6 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->connections["\\B"] = w2_gate; eq_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); this_condition = eq_cell->connections["\\Y"]; - miter_module->add(eq_cell); } if (flag_make_outcmp) @@ -254,25 +232,19 @@ static void create_miter_equiv(struct Pass *that, std::vector args, } if (all_conditions.size() != 1) { - RTLIL::Cell *reduce_cell = new RTLIL::Cell; - reduce_cell->name = NEW_ID; - reduce_cell->type = "$reduce_and"; + RTLIL::Cell *reduce_cell = miter_module->addCell(NEW_ID, "$reduce_and"); reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size(); reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; reduce_cell->connections["\\A"] = all_conditions; reduce_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); all_conditions = reduce_cell->connections["\\Y"]; - miter_module->add(reduce_cell); } if (flag_make_assert) { - RTLIL::Cell *assert_cell = new RTLIL::Cell; - assert_cell->name = NEW_ID; - assert_cell->type = "$assert"; + RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); assert_cell->connections["\\A"] = all_conditions; assert_cell->connections["\\EN"] = RTLIL::SigSpec(1, 1); - miter_module->add(assert_cell); } RTLIL::Wire *w_trigger = new RTLIL::Wire; @@ -280,16 +252,13 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w_trigger->port_output = true; miter_module->add(w_trigger); - RTLIL::Cell *not_cell = new RTLIL::Cell; - not_cell->name = NEW_ID; - not_cell->type = "$not"; + RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, "$not"); not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); not_cell->parameters["\\Y_WIDTH"] = w_trigger->width; not_cell->parameters["\\A_SIGNED"] = 0; not_cell->connections["\\A"] = all_conditions; not_cell->connections["\\Y"] = w_trigger; - miter_module->add(not_cell); miter_module->fixup_ports(); diff --git a/passes/sat/share.cc b/passes/sat/share.cc index ede2fa88..7e24e1f0 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -282,15 +282,12 @@ struct ShareWorker RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); - RTLIL::Cell *supercell = new RTLIL::Cell; - supercell->name = NEW_ID; - supercell->type = c1->type; + RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); supercell->parameters["\\A_SIGNED"] = a_signed; supercell->parameters["\\A_WIDTH"] = a_width; supercell->parameters["\\Y_WIDTH"] = y_width; supercell->connections["\\A"] = a; supercell->connections["\\Y"] = y; - module->add(supercell); RTLIL::SigSpec new_y1(y, 0, y1.size()); RTLIL::SigSpec new_y2(y, 0, y2.size()); @@ -846,8 +843,7 @@ struct ShareWorker log("Removing %d cells in module %s:\n", SIZE(cells_to_remove), log_id(module)); for (auto c : cells_to_remove) { log(" Removing cell %s (%s).\n", log_id(c), log_id(c->type)); - module->cells.erase(c->name); - delete c; + module->remove(c); } } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 4bf73358..c047e418 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -394,28 +394,24 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } std::map stats; - for (auto cell : cell_list) { - cell_mapping &cm = cell_mappings[cell->type]; - RTLIL::Cell *new_cell = new RTLIL::Cell; - new_cell->name = cell->name; - new_cell->type = "\\" + cm.cell_name; + for (auto cell : cell_list) + { + auto cell_type = cell->type; + auto cell_name = cell->name; + auto cell_connections = cell->connections; + module->remove(cell); + + cell_mapping &cm = cell_mappings[cell_type]; + RTLIL::Cell *new_cell = module->addCell(cell_name, "\\" + cm.cell_name); + for (auto &port : cm.ports) { RTLIL::SigSpec sig; if ('A' <= port.second && port.second <= 'Z') { - sig = cell->connections[std::string("\\") + port.second]; + sig = cell_connections[std::string("\\") + port.second]; } else if ('a' <= port.second && port.second <= 'z') { - sig = cell->connections[std::string("\\") + char(port.second - ('a' - 'A'))]; - RTLIL::Cell *inv_cell = new RTLIL::Cell; - RTLIL::Wire *inv_wire = new RTLIL::Wire; - inv_cell->name = stringf("$dfflibmap$inv$%d", RTLIL::autoidx); - inv_wire->name = stringf("$dfflibmap$sig$%d", RTLIL::autoidx++); - inv_cell->type = "$_INV_"; - inv_cell->connections[port.second == 'q' ? "\\Y" : "\\A"] = sig; - sig = RTLIL::SigSpec(inv_wire); - inv_cell->connections[port.second == 'q' ? "\\A" : "\\Y"] = sig; - module->cells[inv_cell->name] = inv_cell; - module->wires[inv_wire->name] = inv_wire; + sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))]; + sig = module->InvGate(NEW_ID, sig); } else if (port.second == '0' || port.second == '1') { sig = RTLIL::SigSpec(port.second == '0' ? 0 : 1, 1); @@ -424,9 +420,8 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) log_abort(); new_cell->connections["\\" + port.first] = sig; } - stats[stringf(" mapped %%d %s cells to %s cells.\n", cell->type.c_str(), new_cell->type.c_str())]++; - module->cells[cell->name] = new_cell; - delete cell; + + stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type.c_str(), new_cell->type.c_str())]++; } for (auto &stat: stats) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 4c3aec31..e52c8fe5 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -297,10 +297,7 @@ namespace SigSet> sig2port; // create new cell - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = stringf("$extract$%s$%d", needle->name.c_str(), RTLIL::autoidx++); - cell->type = needle->name; - haystack->add(cell); + RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), RTLIL::autoidx++), needle->name); // create cell ports for (auto &it : needle->wires) { @@ -333,8 +330,7 @@ namespace } } - haystack->cells.erase(haystack_cell->name); - delete haystack_cell; + haystack->remove(haystack_cell); } return cell; @@ -741,9 +737,7 @@ struct ExtractPass : public Pass { } for (auto cell : cells) { - RTLIL::Cell *newCell = new RTLIL::Cell; - newCell->name = cell->name; - newCell->type = cell->type; + RTLIL::Cell *newCell = newMod->addCell(cell->name, cell->type); newCell->parameters = cell->parameters; for (auto &conn : cell->connections) { std::vector chunks = sigmap(conn.second); @@ -752,7 +746,6 @@ struct ExtractPass : public Pass { chunk.wire = newMod->wires.at(chunk.wire->name); newCell->connections[conn.first] = chunks; } - newMod->add(newCell); } } diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index 51b8802c..e4153670 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -34,22 +34,16 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (bit == RTLIL::State::S1 && !hicell_celltype.empty()) { if (!singleton_mode || last_hi == RTLIL::State::Sm) { last_hi = module->addWire(NEW_ID); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = RTLIL::escape_id(hicell_celltype); + RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype)); cell->connections[RTLIL::escape_id(hicell_portname)] = last_hi; - module->add(cell); } bit = last_hi; } if (bit == RTLIL::State::S0 && !locell_celltype.empty()) { if (!singleton_mode || last_lo == RTLIL::State::Sm) { last_lo = module->addWire(NEW_ID); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = RTLIL::escape_id(locell_celltype); + RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype)); cell->connections[RTLIL::escape_id(locell_portname)] = last_lo; - module->add(cell); } bit = last_lo; } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 09147383..7b2484d8 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -176,9 +176,7 @@ struct IopadmapPass : public Pass { { for (int i = 0; i < wire->width; i++) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = RTLIL::escape_id(celltype); + RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, i); if (!portname2.empty()) cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, i); @@ -187,14 +185,11 @@ struct IopadmapPass : public Pass { if (!nameparam.empty()) cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(stringf("%s[%d]", RTLIL::id2cstr(wire->name), i)); cell->attributes["\\keep"] = RTLIL::Const(1); - module->add(cell); } } else { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = RTLIL::escape_id(celltype); + RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); if (!portname2.empty()) cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); @@ -203,7 +198,6 @@ struct IopadmapPass : public Pass { if (!nameparam.empty()) cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(RTLIL::id2cstr(wire->name)); cell->attributes["\\keep"] = RTLIL::Const(1); - module->add(cell); } wire->port_id = 0; diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 034677d3..8489e7fd 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -35,12 +35,9 @@ static void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); for (int i = 0; i < SIZE(sig_y); i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = "$_INV_"; + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); gate->connections["\\A"] = sig_a[i]; gate->connections["\\Y"] = sig_y[i]; - module->add(gate); } } @@ -78,12 +75,9 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_t = module->addWire(NEW_ID, SIZE(sig_y)); for (int i = 0; i < SIZE(sig_y); i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = "$_INV_"; + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); gate->connections["\\A"] = sig_t[i]; gate->connections["\\Y"] = sig_y[i]; - module->add(gate); } sig_y = sig_t; @@ -97,13 +91,10 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) log_assert(!gate_type.empty()); for (int i = 0; i < SIZE(sig_y); i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = gate_type; + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->connections["\\A"] = sig_a[i]; gate->connections["\\B"] = sig_b[i]; gate->connections["\\Y"] = sig_y[i]; - module->add(gate); } } @@ -150,14 +141,11 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) continue; } - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = gate_type; + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->connections["\\A"] = sig_a[i]; gate->connections["\\B"] = sig_a[i+1]; gate->connections["\\Y"] = sig_t[i/2]; last_output = &gate->connections["\\Y"]; - module->add(gate); } sig_a = sig_t; @@ -165,13 +153,10 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$reduce_xnor") { RTLIL::SigSpec sig_t = module->addWire(NEW_ID); - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = "$_INV_"; + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); gate->connections["\\A"] = sig_a; gate->connections["\\Y"] = sig_t; last_output = &gate->connections["\\Y"]; - module->add(gate); sig_a = sig_t; } @@ -195,13 +180,10 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) continue; } - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = "$_OR_"; + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_"); gate->connections["\\A"] = sig[i]; gate->connections["\\B"] = sig[i+1]; gate->connections["\\Y"] = sig_t[i/2]; - module->add(gate); } sig = sig_t; @@ -226,12 +208,9 @@ static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) sig_y = sig_y.extract(0, 1); } - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = "$_INV_"; + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); gate->connections["\\A"] = sig_a; gate->connections["\\Y"] = sig_y; - module->add(gate); } static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) @@ -257,13 +236,10 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$logic_or") gate_type = "$_OR_"; log_assert(!gate_type.empty()); - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = gate_type; + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->connections["\\A"] = sig_a; gate->connections["\\B"] = sig_b; gate->connections["\\Y"] = sig_y; - module->add(gate); } static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) @@ -273,14 +249,11 @@ static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); for (int i = 0; i < SIZE(sig_y); i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = "$_MUX_"; + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_"); gate->connections["\\A"] = sig_a[i]; gate->connections["\\B"] = sig_b[i]; gate->connections["\\S"] = cell->connections.at("\\S"); gate->connections["\\Y"] = sig_y[i]; - module->add(gate); } } @@ -313,13 +286,10 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol); for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = gate_type; + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->connections["\\S"] = sig_s[i]; gate->connections["\\R"] = sig_r[i]; gate->connections["\\Q"] = sig_q[i]; - module->add(gate); } } @@ -335,13 +305,10 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) std::string gate_type = stringf("$_DFF_%c_", clk_pol); for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = gate_type; + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->connections["\\C"] = sig_clk; gate->connections["\\D"] = sig_d[i]; gate->connections["\\Q"] = sig_q[i]; - module->add(gate); } } @@ -361,15 +328,12 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) std::string gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol); for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = gate_type; + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->connections["\\C"] = sig_clk; gate->connections["\\S"] = sig_s[i]; gate->connections["\\R"] = sig_r[i]; gate->connections["\\D"] = sig_d[i]; gate->connections["\\Q"] = sig_q[i]; - module->add(gate); } } @@ -392,14 +356,11 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) std::string gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol); for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0; + RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); gate->connections["\\C"] = sig_clk; gate->connections["\\R"] = sig_rst; gate->connections["\\D"] = sig_d[i]; gate->connections["\\Q"] = sig_q[i]; - module->add(gate); } } @@ -415,13 +376,10 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) std::string gate_type = stringf("$_DLATCH_%c_", en_pol); for (int i = 0; i < width; i++) { - RTLIL::Cell *gate = new RTLIL::Cell; - gate->name = NEW_ID; - gate->type = gate_type; + RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); gate->connections["\\E"] = sig_en; gate->connections["\\D"] = sig_d[i]; gate->connections["\\Q"] = sig_q[i]; - module->add(gate); } } @@ -490,10 +448,8 @@ struct SimplemapPass : public Pass { mappers.at(cell_it.second->type)(mod_it.second, cell_it.second); delete_cells.push_back(cell_it.second); } - for (auto &it : delete_cells) { - mod_it.second->cells.erase(it->name); - delete it; - } + for (auto c : delete_cells) + mod_it.second->remove(c); } } } SimplemapPass; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 8d7b21e0..e8385844 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -114,15 +114,12 @@ struct TechmapWorker log_error("Technology map yielded processes -> this is not supported.\n"); } - // erase from namespace first for _TECHMAP_REPLACE_ to work - module->cells.erase(cell->name); std::string orig_cell_name; - if (!flatten_mode) for (auto &it : tpl->cells) if (it.first == "\\_TECHMAP_REPLACE_") { orig_cell_name = cell->name; - cell->name = stringf("$techmap%d", RTLIL::autoidx++) + cell->name; + module->rename(cell, stringf("$techmap%d", RTLIL::autoidx++) + cell->name); break; } @@ -183,20 +180,29 @@ struct TechmapWorker } } - for (auto &it : tpl->cells) { - RTLIL::Cell *c = new RTLIL::Cell(*it.second); - if (!flatten_mode && c->type.substr(0, 2) == "\\$") - c->type = c->type.substr(1); - if (!flatten_mode && c->name == "\\_TECHMAP_REPLACE_") - c->name = orig_cell_name; + for (auto &it : tpl->cells) + { + RTLIL::IdString c_name = it.second->name; + RTLIL::IdString c_type = it.second->type; + + if (!flatten_mode && c_type.substr(0, 2) == "\\$") + c_type = c_type.substr(1); + + if (!flatten_mode && c_name == "\\_TECHMAP_REPLACE_") + c_name = orig_cell_name; else - apply_prefix(cell->name, c->name); + apply_prefix(cell->name, c_name); + + RTLIL::Cell *c = module->addCell(c_name, c_type); + c->connections = it.second->connections; + c->parameters = it.second->parameters; + c->attributes = it.second->attributes; + design->select(module, c); + for (auto &it2 : c->connections) { apply_prefix(cell->name, it2.second, module); port_signal_map.apply(it2.second); } - module->add(c); - design->select(module, c); } for (auto &it : tpl->connections) { @@ -208,7 +214,7 @@ struct TechmapWorker module->connections.push_back(c); } - delete cell; + module->remove(cell); } bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, @@ -254,8 +260,7 @@ struct TechmapWorker if (simplemap_mappers.count(cell->type) == 0) log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); simplemap_mappers.at(cell->type)(module, cell); - module->cells.erase(cell->name); - delete cell; + module->remove(cell); cell = NULL; did_something = true; break; From 4755e14e7b9ba57ea21bec4c0d0b3ac6080307e4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 00:38:44 +0200 Subject: [PATCH 424/750] Added copy-constructor-like module->addCell(name, other) method --- kernel/rtlil.cc | 19 +++++++++++-------- kernel/rtlil.h | 1 + passes/hierarchy/submod.cc | 5 +---- passes/techmap/techmap.cc | 12 ++++-------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 17e4a273..1a6e386f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -782,14 +782,8 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const for (auto &it : memories) new_mod->memories[it.first] = new RTLIL::Memory(*it.second); - for (auto &it : cells) { - new_mod->cells[it.first] = new RTLIL::Cell; - new_mod->cells[it.first]->name = it.second->name; - new_mod->cells[it.first]->type = it.second->type; - new_mod->cells[it.first]->connections = it.second->connections; - new_mod->cells[it.first]->parameters = it.second->parameters; - new_mod->cells[it.first]->attributes = it.second->attributes; - } + for (auto &it : cells) + new_mod->addCell(it.first, it.second); for (auto &it : processes) new_mod->processes[it.first] = it.second->clone(); @@ -912,6 +906,15 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) return cell; } +RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *other) +{ + RTLIL::Cell *cell = addCell(name, other->type); + cell->connections = other->connections; + cell->parameters = other->parameters; + cell->attributes = other->attributes; + return cell; +} + #define DEF_METHOD(_func, _y_size, _type) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \ RTLIL::Cell *cell = new RTLIL::Cell; \ diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e1e4a54b..fbd6e719 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -302,6 +302,7 @@ struct RTLIL::Module RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); + RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); // The add* methods create a cell and return the created cell. All signals must exist in advance. diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 204f899a..be580ca0 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -162,10 +162,7 @@ struct SubmodWorker } for (RTLIL::Cell *cell : submod.cells) { - RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell->type); - new_cell->connections = cell->connections; - new_cell->parameters = cell->parameters; - new_cell->attributes = cell->attributes; + RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell); for (auto &conn : new_cell->connections) for (auto &bit : conn.second) if (bit.wire != NULL) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index e8385844..94cb1e8d 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -183,22 +183,18 @@ struct TechmapWorker for (auto &it : tpl->cells) { RTLIL::IdString c_name = it.second->name; - RTLIL::IdString c_type = it.second->type; - - if (!flatten_mode && c_type.substr(0, 2) == "\\$") - c_type = c_type.substr(1); if (!flatten_mode && c_name == "\\_TECHMAP_REPLACE_") c_name = orig_cell_name; else apply_prefix(cell->name, c_name); - RTLIL::Cell *c = module->addCell(c_name, c_type); - c->connections = it.second->connections; - c->parameters = it.second->parameters; - c->attributes = it.second->attributes; + RTLIL::Cell *c = module->addCell(c_name, it.second); design->select(module, c); + if (!flatten_mode && c->type.substr(0, 2) == "\\$") + c->type = c->type.substr(1); + for (auto &it2 : c->connections) { apply_prefix(cell->name, it2.second, module); port_signal_map.apply(it2.second); From f8a68b8f55ed61c6046e11b60587c840f0ba1879 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:23:43 +0200 Subject: [PATCH 425/750] Added "Checklist for adding internal cell types" --- CHECKLIST => CHECKLISTS | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) rename CHECKLIST => CHECKLISTS (72%) diff --git a/CHECKLIST b/CHECKLISTS similarity index 72% rename from CHECKLIST rename to CHECKLISTS index 35de389b..3f824fc2 100644 --- a/CHECKLIST +++ b/CHECKLISTS @@ -1,7 +1,16 @@ +This file contains checklists for various tasks. + -Checklist for creating Yosys releases -===================================== +Table of contents +================= + +1. Checklist for creating Yosys releases +2. Checklist for adding internal cell types + + +1. Checklist for creating Yosys releases +======================================== Update the CHANGELOG file: @@ -106,3 +115,18 @@ In master branch: - add section "Yosys x.y.z .. x.y.z+" to CHANGELOG git commit --amend -am "Yosys x.y.z+" + +2. Checklist for adding internal cell types +=========================================== + +Things to do right away: + + - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) + - Add to InternalCellChecker::check() in kernel/rtlil.cc + +Things to do after finalizing the cell interface: + + - Add support to kernel/satgen.h for the new cell type + - Add to manual/CHAPTER_CellLib.tex (or just add a fixme to the bottom) + - Maybe add support to the verilog backend for dumping such cells as expression + From 665759fceee4a0db3e776b7912e976eea2ff29a3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:55:58 +0200 Subject: [PATCH 426/750] Cosmetic fixes for "make abc" --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 6dde27a9..da4d7fac 100644 --- a/Makefile +++ b/Makefile @@ -197,11 +197,12 @@ yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp abc/abc-$(ABCREV): $(P) ifneq ($(ABCREV),default) - $(Q) if ( cd abc && hg identify; ) | grep -q +; then \ + $(Q) if ( cd abc 2> /dev/null && hg identify; ) | grep -q +; then \ echo 'REEBE: NOP pbagnvaf ybpny zbqvsvpngvbaf! Frg NOPERI=qrsnhyg va Lbflf Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi - $(Q) if test "`cd abc && hg identify | cut -f1 -d' '`" != "$(ABCREV)"; then \ + $(Q) if test "`cd abc 2> /dev/null && hg identify | cut -f1 -d' '`" != "$(ABCREV)"; then \ test $(ABCPULL) -ne 0 || { echo 'REEBE: NOP abg hc gb qngr naq NOPCHYY frg gb 0 va Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; exit 1; }; \ + echo "Pulling ABC from bitbucket.org:"; \ test -d abc || hg clone https://bitbucket.org/alanmi/abc abc; \ cd abc && hg pull && hg update -r $(ABCREV); \ fi From cc4f10883bcc5f0a3c1b4f0937e60be3c6a1b121 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:58:03 +0200 Subject: [PATCH 427/750] Renamed RTLIL::{Module,Cell}::connections to connections_ --- backends/blif/blif.cc | 24 ++-- backends/btor/btor.cc | 68 +++++----- backends/edif/edif.cc | 4 +- backends/ilang/ilang_backend.cc | 4 +- backends/intersynth/intersynth.cc | 2 +- backends/spice/spice.cc | 8 +- backends/verilog/verilog_backend.cc | 86 ++++++------ frontends/ast/genrtlil.cc | 48 +++---- frontends/ilang/parser.y | 6 +- frontends/liberty/liberty.cc | 124 ++++++++--------- kernel/consteval.h | 18 +-- kernel/modwalker.h | 4 +- kernel/rtlil.cc | 171 +++++++++++------------ kernel/rtlil.h | 36 +++-- kernel/satgen.h | 170 +++++++++++------------ kernel/sigtools.h | 2 +- manual/CHAPTER_Prog/stubnets.cc | 2 +- passes/abc/abc.cc | 84 ++++++------ passes/abc/blifparse.cc | 12 +- passes/cmds/add.cc | 4 +- passes/cmds/connect.cc | 10 +- passes/cmds/connwrappers.cc | 4 +- passes/cmds/scatter.cc | 6 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 4 +- passes/cmds/setundef.cc | 4 +- passes/cmds/show.cc | 10 +- passes/cmds/splice.cc | 20 +-- passes/cmds/splitnets.cc | 2 +- passes/fsm/fsm_detect.cc | 18 +-- passes/fsm/fsm_expand.cc | 56 ++++---- passes/fsm/fsm_extract.cc | 38 +++--- passes/fsm/fsm_map.cc | 56 ++++---- passes/fsm/fsm_opt.cc | 16 +-- passes/fsm/fsmdata.h | 4 +- passes/hierarchy/hierarchy.cc | 10 +- passes/hierarchy/submod.cc | 12 +- passes/memory/memory_collect.cc | 28 ++-- passes/memory/memory_dff.cc | 38 +++--- passes/memory/memory_map.cc | 74 +++++----- passes/memory/memory_share.cc | 102 +++++++------- passes/memory/memory_unpack.cc | 14 +- passes/opt/opt_clean.cc | 16 +-- passes/opt/opt_const.cc | 202 ++++++++++++++-------------- passes/opt/opt_muxtree.cc | 26 ++-- passes/opt/opt_reduce.cc | 78 +++++------ passes/opt/opt_rmdff.cc | 52 +++---- passes/opt/opt_share.cc | 16 +-- passes/proc/proc_arst.cc | 44 +++--- passes/proc/proc_dff.cc | 90 ++++++------- passes/proc/proc_mux.cc | 30 ++--- passes/sat/expose.cc | 72 +++++----- passes/sat/freduce.cc | 14 +- passes/sat/miter.cc | 58 ++++---- passes/sat/sat.cc | 4 +- passes/sat/share.cc | 84 ++++++------ passes/techmap/dfflibmap.cc | 4 +- passes/techmap/extract.cc | 24 ++-- passes/techmap/hilomap.cc | 4 +- passes/techmap/iopadmap.cc | 8 +- passes/techmap/simplemap.cc | 198 +++++++++++++-------------- passes/techmap/techmap.cc | 18 +-- 62 files changed, 1234 insertions(+), 1213 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index fc090cfe..8d80eccd 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -146,56 +146,56 @@ struct BlifDumper if (!config->icells_mode && cell->type == "$_INV_") { fprintf(f, ".names %s %s\n0 1\n", - cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\Y"))); + cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_AND_") { fprintf(f, ".names %s %s %s\n11 1\n", - cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y"))); + cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), cstr(cell->connections_.at("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_OR_") { fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n", - cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y"))); + cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), cstr(cell->connections_.at("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_XOR_") { fprintf(f, ".names %s %s %s\n10 1\n01 1\n", - cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), cstr(cell->connections.at("\\Y"))); + cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), cstr(cell->connections_.at("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_MUX_") { fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n", - cstr(cell->connections.at("\\A")), cstr(cell->connections.at("\\B")), - cstr(cell->connections.at("\\S")), cstr(cell->connections.at("\\Y"))); + cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), + cstr(cell->connections_.at("\\S")), cstr(cell->connections_.at("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_N_") { fprintf(f, ".latch %s %s fe %s\n", - cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C"))); + cstr(cell->connections_.at("\\D")), cstr(cell->connections_.at("\\Q")), cstr(cell->connections_.at("\\C"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_P_") { fprintf(f, ".latch %s %s re %s\n", - cstr(cell->connections.at("\\D")), cstr(cell->connections.at("\\Q")), cstr(cell->connections.at("\\C"))); + cstr(cell->connections_.at("\\D")), cstr(cell->connections_.at("\\Q")), cstr(cell->connections_.at("\\C"))); continue; } if (!config->icells_mode && cell->type == "$lut") { fprintf(f, ".names"); - auto &inputs = cell->connections.at("\\I"); + auto &inputs = cell->connections_.at("\\I"); auto width = cell->parameters.at("\\WIDTH").as_int(); log_assert(inputs.size() == width); for (int i = 0; i < inputs.size(); i++) { fprintf(f, " %s", cstr(inputs.extract(i, 1))); } - auto &output = cell->connections.at("\\O"); + auto &output = cell->connections_.at("\\O"); log_assert(output.size() == 1); fprintf(f, " %s", cstr(output)); fprintf(f, "\n"); @@ -211,7 +211,7 @@ struct BlifDumper } fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type)); - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) for (int i = 0; i < conn.second.size(); i++) { if (conn.second.size() == 1) fprintf(f, " %s", cstr(conn.first)); @@ -240,7 +240,7 @@ struct BlifDumper } } - for (auto &conn : module->connections) + for (auto &conn : module->connections_) for (int i = 0; i < conn.first.size(); i++) if (config->conn_mode) fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 096c6029..46edec9c 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -387,8 +387,8 @@ struct BtorDumper if(cell->type == "$assert") { log("writing assert cell - %s\n", cstr(cell->type)); - const RTLIL::SigSpec* expr = &cell->connections.at(RTLIL::IdString("\\A")); - const RTLIL::SigSpec* en = &cell->connections.at(RTLIL::IdString("\\EN")); + const RTLIL::SigSpec* expr = &cell->connections_.at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* en = &cell->connections_.at(RTLIL::IdString("\\EN")); log_assert(expr->size() == 1); log_assert(en->size() == 1); int expr_line = dump_sigspec(expr, 1); @@ -420,7 +420,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); w = w>output_width ? w:output_width; //padding of w - int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), w); int cell_line = l; if(cell->type != "$pos") { @@ -444,7 +444,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), w); if(cell->type == "$logic_not" && w > 1) { ++line_num; @@ -481,8 +481,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -515,8 +515,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -550,8 +550,8 @@ struct BtorDumper l1_width = pow(2, ceil(log(l1_width)/log(2))); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); //assert(l2_width <= ceil(log(l1_width)/log(2)) ); - int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); + int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); int cell_output = ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), l1_width, l1, l2); fprintf(f, "%s\n", str.c_str()); @@ -559,7 +559,7 @@ struct BtorDumper if(l2_width > ceil(log(l1_width)/log(2))) { int extra_width = l2_width - ceil(log(l1_width)/log(2)); - l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width); + l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), l2_width); ++line_num; str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width); fprintf(f, "%s\n", str.c_str()); @@ -592,8 +592,8 @@ struct BtorDumper log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); + int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), output_width); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); if(l1_width >1) @@ -628,9 +628,9 @@ struct BtorDumper { log("writing mux cell\n"); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); - int s = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\S")), 1); + int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), output_width); + int s = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\S")), 1); ++line_num; str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell @@ -644,10 +644,10 @@ struct BtorDumper log("writing cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); log(" - width is %d\n", output_width); - int cond = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1); + int cond = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - const RTLIL::SigSpec* cell_output = &cell->connections.at(RTLIL::IdString("\\Q")); - int value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\D")), output_width); + const RTLIL::SigSpec* cell_output = &cell->connections_.at(RTLIL::IdString("\\Q")); + int value = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\D")), output_width); unsigned start_bit = 0; for(unsigned i=0; ichunks().size(); ++i) { @@ -665,9 +665,9 @@ struct BtorDumper } if(cell->type == "$dffsr") { - int sync_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLR")), 1); + int sync_reset = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\CLR")), 1); bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); - int sync_reset_value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\SET")), + int sync_reset_value = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\SET")), output_width); bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); ++line_num; @@ -685,7 +685,7 @@ struct BtorDumper int next = line_num; if(cell->type == "$adff") { - int async_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ARST")), 1); + int async_reset = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\ARST")), 1); bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), output_width, 0); @@ -710,7 +710,7 @@ struct BtorDumper str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); ++line_num; str = stringf("%d read %d %d %d", line_num, data_width, mem, address); @@ -722,13 +722,13 @@ struct BtorDumper log("writing memwr cell\n"); if (cell->parameters.at("\\CLK_ENABLE").as_bool() == false) log_error("The btor backen does not support $memwr cells without built-in registers. Run memory_dff (but with -wr_only).\n"); - int clk = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1); + int clk = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - int enable = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\EN")), 1); + int enable = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\EN")), 1); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int data = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\DATA")), data_width); + int data = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\DATA")), data_width); str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); ++line_num; @@ -757,11 +757,11 @@ struct BtorDumper else if(cell->type == "$slice") { log("writing slice cell\n"); - const RTLIL::SigSpec* input = &cell->connections.at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input = &cell->connections_.at(RTLIL::IdString("\\A")); int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input->size() == input_width); int input_line = dump_sigspec(input, input_width); - const RTLIL::SigSpec* output = &cell->connections.at(RTLIL::IdString("\\Y")); + const RTLIL::SigSpec* output = &cell->connections_.at(RTLIL::IdString("\\Y")); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output->size() == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); @@ -773,11 +773,11 @@ struct BtorDumper else if(cell->type == "$concat") { log("writing concat cell\n"); - const RTLIL::SigSpec* input_a = &cell->connections.at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input_a = &cell->connections_.at(RTLIL::IdString("\\A")); int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input_a->size() == input_a_width); int input_a_line = dump_sigspec(input_a, input_a_width); - const RTLIL::SigSpec* input_b = &cell->connections.at(RTLIL::IdString("\\B")); + const RTLIL::SigSpec* input_b = &cell->connections_.at(RTLIL::IdString("\\B")); int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); log_assert(input_b->size() == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); @@ -801,7 +801,7 @@ struct BtorDumper RTLIL::SigSpec *output_sig = nullptr; if (cell->type == "$memrd") { - output_sig = &cell->connections.at(RTLIL::IdString("\\DATA")); + output_sig = &cell->connections_.at(RTLIL::IdString("\\DATA")); } else if(cell->type == "$memwr" || cell->type == "$assert") { @@ -809,11 +809,11 @@ struct BtorDumper } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - output_sig = &cell->connections.at(RTLIL::IdString("\\Q")); + output_sig = &cell->connections_.at(RTLIL::IdString("\\Q")); } else { - output_sig = &cell->connections.at(RTLIL::IdString("\\Y")); + output_sig = &cell->connections_.at(RTLIL::IdString("\\Y")); } return output_sig; } diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index a3ae9649..13ab4dc6 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -148,7 +148,7 @@ struct EdifBackend : public Backend { RTLIL::Cell *cell = cell_it.second; if (!design->modules.count(cell->type) || design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) { lib_cell_ports[cell->type]; - for (auto p : cell->connections) { + for (auto p : cell->connections_) { if (p.second.size() > 1) log_error("Found multi-bit port %s on library cell %s.%s (%s): not supported in EDIF backend!\n", RTLIL::id2cstr(p.first), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); @@ -304,7 +304,7 @@ struct EdifBackend : public Backend { fprintf(f, "\n (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str()); } fprintf(f, ")\n"); - for (auto &p : cell->connections) { + for (auto &p : cell->connections_) { RTLIL::SigSpec sig = sigmap(p.second); for (int i = 0; i < SIZE(sig); i++) if (sig.size() == 1) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index 3c8e805b..0e329fc9 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -163,7 +163,7 @@ void ILANG_BACKEND::dump_cell(FILE *f, std::string indent, const RTLIL::Cell *ce dump_const(f, it->second); fprintf(f, "\n"); } - for (auto it = cell->connections.begin(); it != cell->connections.end(); it++) { + for (auto it = cell->connections_.begin(); it != cell->connections_.end(); it++) { fprintf(f, "%s connect %s ", indent.c_str(), it->first.c_str()); dump_sigspec(f, it->second); fprintf(f, "\n"); @@ -309,7 +309,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module } bool first_conn_line = true; - for (auto it = module->connections.begin(); it != module->connections.end(); it++) { + for (auto it = module->connections_.begin(); it != module->connections_.end(); it++) { bool show_conn = !only_selected; if (only_selected) { RTLIL::SigSpec sigs = it->first; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index b2e472bf..8231f1d8 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -169,7 +169,7 @@ struct IntersynthBackend : public Backend { celltype_code = stringf("celltype %s", RTLIL::id2cstr(cell->type)); node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); - for (auto &port : cell->connections) { + for (auto &port : cell->connections_) { RTLIL::SigSpec sig = sigmap(port.second); if (sig.size() != 0) { conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size())); diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index e548df36..a3784f11 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -58,7 +58,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de { log("Warning: no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n", RTLIL::id2cstr(cell->type), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name)); - for (auto &conn : cell->connections) { + for (auto &conn : cell->connections_) { RTLIL::SigSpec sig = sigmap(conn.second); port_sigs.push_back(sig); } @@ -80,8 +80,8 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de for (RTLIL::Wire *wire : ports) { log_assert(wire != NULL); RTLIL::SigSpec sig(RTLIL::State::Sz, wire->width); - if (cell->connections.count(wire->name) > 0) { - sig = sigmap(cell->connections.at(wire->name)); + if (cell->connections_.count(wire->name) > 0) { + sig = sigmap(cell->connections_.at(wire->name)); sig.extend(wire->width, false); } port_sigs.push_back(sig); @@ -98,7 +98,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de fprintf(f, " %s\n", RTLIL::id2cstr(cell->type)); } - for (auto &conn : module->connections) + for (auto &conn : module->connections_) for (int i = 0; i < conn.first.size(); i++) { fprintf(f, "V%d", conn_counter++); print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a22035ed..d3b5d52d 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -293,17 +293,17 @@ void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_ { if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) { fprintf(f, "$signed("); - dump_sigspec(f, cell->connections["\\" + port]); + dump_sigspec(f, cell->connections_["\\" + port]); fprintf(f, ")"); } else - dump_sigspec(f, cell->connections["\\" + port]); + dump_sigspec(f, cell->connections_["\\" + port]); } std::string cellname(RTLIL::Cell *cell) { - if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections.count("\\Q") > 0) + if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections_.count("\\Q") > 0) { - RTLIL::SigSpec sig = cell->connections["\\Q"]; + RTLIL::SigSpec sig = cell->connections_["\\Q"]; if (SIZE(sig) != 1 || sig.is_fully_const()) goto no_special_reg_name; @@ -338,7 +338,7 @@ no_special_reg_name: void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = %s ", op.c_str()); dump_attributes(f, "", cell->attributes, ' '); dump_cell_expr_port(f, cell, "A", true); @@ -348,7 +348,7 @@ void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::s void dump_cell_expr_binop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = "); dump_cell_expr_port(f, cell, "A", true); fprintf(f, " %s ", op.c_str()); @@ -361,7 +361,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) { if (cell->type == "$_INV_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = "); fprintf(f, "~"); dump_attributes(f, "", cell->attributes, ' '); @@ -372,7 +372,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = "); dump_cell_expr_port(f, cell, "A", false); fprintf(f, " "); @@ -391,7 +391,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$_MUX_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = "); dump_cell_expr_port(f, cell, "S", false); fprintf(f, " ? "); @@ -406,23 +406,23 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type.substr(0, 6) == "$_DFF_") { std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->connections["\\Q"], reg_name); + bool out_is_reg_wire = is_reg_wire(cell->connections_["\\Q"], reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); fprintf(f, "%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections["\\C"]); + dump_sigspec(f, cell->connections_["\\C"]); if (cell->type[7] != '_') { fprintf(f, " or %sedge ", cell->type[7] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections["\\R"]); + dump_sigspec(f, cell->connections_["\\R"]); } fprintf(f, ")\n"); if (cell->type[7] != '_') { fprintf(f, "%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!"); - dump_sigspec(f, cell->connections["\\R"]); + dump_sigspec(f, cell->connections_["\\R"]); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); fprintf(f, "%s" " else\n", indent.c_str()); @@ -434,7 +434,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Q"]); + dump_sigspec(f, cell->connections_["\\Q"]); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -446,27 +446,27 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10]; std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->connections["\\Q"], reg_name); + bool out_is_reg_wire = is_reg_wire(cell->connections_["\\Q"], reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections["\\C"]); + dump_sigspec(f, cell->connections_["\\C"]); fprintf(f, " or %sedge ", pol_s == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections["\\S"]); + dump_sigspec(f, cell->connections_["\\S"]); fprintf(f, " or %sedge ", pol_r == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections["\\R"]); + dump_sigspec(f, cell->connections_["\\R"]); fprintf(f, ")\n"); fprintf(f, "%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!"); - dump_sigspec(f, cell->connections["\\R"]); + dump_sigspec(f, cell->connections_["\\R"]); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str()); fprintf(f, "%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!"); - dump_sigspec(f, cell->connections["\\S"]); + dump_sigspec(f, cell->connections_["\\S"]); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str()); @@ -477,7 +477,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Q"]); + dump_sigspec(f, cell->connections_["\\Q"]); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -535,7 +535,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$pmux_safe") { int width = cell->parameters["\\WIDTH"].as_int(); - int s_width = cell->connections["\\S"].size(); + int s_width = cell->connections_["\\S"].size(); std::string func_name = cellname(cell); fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); @@ -567,13 +567,13 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, "%s" "endfunction\n", indent.c_str()); fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = %s(", func_name.c_str()); - dump_sigspec(f, cell->connections["\\A"]); + dump_sigspec(f, cell->connections_["\\A"]); fprintf(f, ", "); - dump_sigspec(f, cell->connections["\\B"]); + dump_sigspec(f, cell->connections_["\\B"]); fprintf(f, ", "); - dump_sigspec(f, cell->connections["\\S"]); + dump_sigspec(f, cell->connections_["\\S"]); fprintf(f, ");\n"); return true; } @@ -581,9 +581,9 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$slice") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = "); - dump_sigspec(f, cell->connections["\\A"]); + dump_sigspec(f, cell->connections_["\\A"]); fprintf(f, " >> %d;\n", cell->parameters.at("\\OFFSET").as_int()); return true; } @@ -591,14 +591,14 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$bu0") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); if (cell->parameters["\\A_SIGNED"].as_bool()) { fprintf(f, " = $signed("); - dump_sigspec(f, cell->connections["\\A"]); + dump_sigspec(f, cell->connections_["\\A"]); fprintf(f, ");\n"); } else { fprintf(f, " = { 1'b0, "); - dump_sigspec(f, cell->connections["\\A"]); + dump_sigspec(f, cell->connections_["\\A"]); fprintf(f, " };\n"); } return true; @@ -607,11 +607,11 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$concat") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Y"]); + dump_sigspec(f, cell->connections_["\\Y"]); fprintf(f, " = { "); - dump_sigspec(f, cell->connections["\\B"]); + dump_sigspec(f, cell->connections_["\\B"]); fprintf(f, " , "); - dump_sigspec(f, cell->connections["\\A"]); + dump_sigspec(f, cell->connections_["\\A"]); fprintf(f, " };\n"); return true; } @@ -621,17 +621,17 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) RTLIL::SigSpec sig_clk, sig_arst, val_arst; bool pol_clk, pol_arst = false; - sig_clk = cell->connections["\\CLK"]; + sig_clk = cell->connections_["\\CLK"]; pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool(); if (cell->type == "$adff") { - sig_arst = cell->connections["\\ARST"]; + sig_arst = cell->connections_["\\ARST"]; pol_arst = cell->parameters["\\ARST_POLARITY"].as_bool(); val_arst = RTLIL::SigSpec(cell->parameters["\\ARST_VALUE"]); } std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->connections["\\Q"], reg_name); + bool out_is_reg_wire = is_reg_wire(cell->connections_["\\Q"], reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str()); @@ -660,7 +660,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections["\\Q"]); + dump_sigspec(f, cell->connections_["\\Q"]); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -707,7 +707,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) for (int i = 1; true; i++) { char str[16]; snprintf(str, 16, "$%d", i); - for (auto it = cell->connections.begin(); it != cell->connections.end(); it++) { + for (auto it = cell->connections_.begin(); it != cell->connections_.end(); it++) { if (it->first != str) continue; if (!first_arg) @@ -721,7 +721,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) break; found_numbered_port:; } - for (auto it = cell->connections.begin(); it != cell->connections.end(); it++) { + for (auto it = cell->connections_.begin(); it != cell->connections_.end(); it++) { if (numbered_ports.count(it->first)) continue; if (!first_arg) @@ -908,10 +908,10 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - if (!reg_ct.cell_known(cell->type) || cell->connections.count("\\Q") == 0) + if (!reg_ct.cell_known(cell->type) || cell->connections_.count("\\Q") == 0) continue; - RTLIL::SigSpec sig = cell->connections["\\Q"]; + RTLIL::SigSpec sig = cell->connections_["\\Q"]; if (sig.is_chunk()) { RTLIL::SigChunk chunk = sig.as_chunk(); @@ -961,7 +961,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto it = module->processes.begin(); it != module->processes.end(); it++) dump_process(f, indent + " ", it->second); - for (auto it = module->connections.begin(); it != module->connections.end(); it++) + for (auto it = module->connections_.begin(); it != module->connections_.end(); it++) dump_conn(f, indent + " ", it->first, it->second); fprintf(f, "%s" "endmodule\n", indent.c_str()); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c121a869..c70b79a5 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 82826a35..bb42c5ec 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 74524792..ec96fbdd 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)); } } diff --git a/kernel/consteval.h b/kernel/consteval.h index 7b1b798c..5469fa80 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -43,7 +43,7 @@ struct ConstEval for (auto &it : module->cells) { if (!ct.cell_known(it.second->type)) continue; - for (auto &it2 : it.second->connections) + for (auto &it2 : it.second->connections_) if (ct.cell_output(it.second->type, it2.first)) sig2driver.insert(assign_map(it2.second), it.second); } @@ -87,22 +87,22 @@ struct ConstEval { RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; - assert(cell->connections.count("\\Y") > 0); - sig_y = values_map(assign_map(cell->connections["\\Y"])); + assert(cell->connections_.count("\\Y") > 0); + sig_y = values_map(assign_map(cell->connections_["\\Y"])); if (sig_y.is_fully_const()) return true; - if (cell->connections.count("\\S") > 0) { - sig_s = cell->connections["\\S"]; + if (cell->connections_.count("\\S") > 0) { + sig_s = cell->connections_["\\S"]; if (!eval(sig_s, undef, cell)) return false; } - if (cell->connections.count("\\A") > 0) - sig_a = cell->connections["\\A"]; + if (cell->connections_.count("\\A") > 0) + sig_a = cell->connections_["\\A"]; - if (cell->connections.count("\\B") > 0) - sig_b = cell->connections["\\B"]; + if (cell->connections_.count("\\B") > 0) + sig_b = cell->connections_["\\B"]; if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") { diff --git a/kernel/modwalker.h b/kernel/modwalker.h index 6c3da5dd..efd97379 100644 --- a/kernel/modwalker.h +++ b/kernel/modwalker.h @@ -88,12 +88,12 @@ struct ModWalker void add_cell(RTLIL::Cell *cell) { if (ct.cell_known(cell->type)) { - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) add_cell_port(cell, conn.first, sigmap(conn.second), ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first)); } else { - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) add_cell_port(cell, conn.first, sigmap(conn.second), true, true); } } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1a6e386f..4d0aadbb 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -348,9 +348,9 @@ namespace { void port(const char *name, int width) { - if (cell->connections.count(name) == 0) + if (cell->connections_.count(name) == 0) error(__LINE__); - if (cell->connections.at(name).size() != width) + if (cell->connections_.at(name).size() != width) error(__LINE__); expected_ports.insert(name); } @@ -360,7 +360,7 @@ namespace { for (auto ¶ : cell->parameters) if (expected_params.count(para.first) == 0) error(__LINE__); - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) if (expected_ports.count(conn.first) == 0) error(__LINE__); @@ -379,13 +379,13 @@ namespace { for (const char *p = ports; *p; p++) { char portname[3] = { '\\', *p, 0 }; - if (cell->connections.count(portname) == 0) + if (cell->connections_.count(portname) == 0) error(__LINE__); - if (cell->connections.at(portname).size() != 1) + if (cell->connections_.at(portname).size() != 1) error(__LINE__); } - for (auto &conn : cell->connections) { + for (auto &conn : cell->connections_) { if (conn.first.size() != 2 || conn.first.at(0) != '\\') error(__LINE__); if (strchr(ports, conn.first.at(1)) == NULL) @@ -734,7 +734,7 @@ void RTLIL::Module::check() assert(it.first == it.second->name); assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$')); - for (auto &it2 : it.second->connections) { + for (auto &it2 : it.second->connections_) { assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); it2.second.check(); } @@ -754,7 +754,7 @@ void RTLIL::Module::check() // FIXME: More checks here.. } - for (auto &it : connections) { + for (auto &it : connections_) { assert(it.first.size() == it.second.size()); it.first.check(); it.second.check(); @@ -773,7 +773,7 @@ void RTLIL::Module::optimize() void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const { new_mod->name = name; - new_mod->connections = connections; + new_mod->connections_ = connections_; new_mod->attributes = attributes; for (auto &it : wires) @@ -873,6 +873,11 @@ static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) return a->port_id < b->port_id; } +void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs) +{ + connections_.push_back(RTLIL::SigSig(lhs, rhs)); +} + void RTLIL::Module::fixup_ports() { std::vector all_ports; @@ -909,7 +914,7 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *other) { RTLIL::Cell *cell = addCell(name, other->type); - cell->connections = other->connections; + cell->connections_ = other->connections_; cell->parameters = other->parameters; cell->attributes = other->attributes; return cell; @@ -923,8 +928,8 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\A_WIDTH"] = sig_a.size(); \ cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->connections["\\A"] = sig_a; \ - cell->connections["\\Y"] = sig_y; \ + cell->connections_["\\A"] = sig_a; \ + cell->connections_["\\Y"] = sig_y; \ add(cell); \ return cell; \ } \ @@ -955,9 +960,9 @@ DEF_METHOD(LogicNot, 1, "$logic_not") cell->parameters["\\A_WIDTH"] = sig_a.size(); \ cell->parameters["\\B_WIDTH"] = sig_b.size(); \ cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->connections["\\A"] = sig_a; \ - cell->connections["\\B"] = sig_b; \ - cell->connections["\\Y"] = sig_y; \ + cell->connections_["\\A"] = sig_a; \ + cell->connections_["\\B"] = sig_b; \ + cell->connections_["\\Y"] = sig_y; \ add(cell); \ return cell; \ } \ @@ -999,10 +1004,10 @@ DEF_METHOD(LogicOr, 1, "$logic_or") cell->parameters["\\WIDTH"] = sig_a.size(); \ cell->parameters["\\WIDTH"] = sig_b.size(); \ if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ - cell->connections["\\A"] = sig_a; \ - cell->connections["\\B"] = sig_b; \ - cell->connections["\\S"] = sig_s; \ - cell->connections["\\Y"] = sig_y; \ + cell->connections_["\\A"] = sig_a; \ + cell->connections_["\\B"] = sig_b; \ + cell->connections_["\\S"] = sig_s; \ + cell->connections_["\\Y"] = sig_y; \ add(cell); \ return cell; \ } \ @@ -1021,8 +1026,8 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections["\\" #_P1] = sig1; \ - cell->connections["\\" #_P2] = sig2; \ + cell->connections_["\\" #_P1] = sig1; \ + cell->connections_["\\" #_P2] = sig2; \ add(cell); \ return cell; \ } \ @@ -1036,9 +1041,9 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections["\\" #_P1] = sig1; \ - cell->connections["\\" #_P2] = sig2; \ - cell->connections["\\" #_P3] = sig3; \ + cell->connections_["\\" #_P1] = sig1; \ + cell->connections_["\\" #_P2] = sig2; \ + cell->connections_["\\" #_P3] = sig3; \ add(cell); \ return cell; \ } \ @@ -1052,10 +1057,10 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections["\\" #_P1] = sig1; \ - cell->connections["\\" #_P2] = sig2; \ - cell->connections["\\" #_P3] = sig3; \ - cell->connections["\\" #_P4] = sig4; \ + cell->connections_["\\" #_P1] = sig1; \ + cell->connections_["\\" #_P2] = sig2; \ + cell->connections_["\\" #_P3] = sig3; \ + cell->connections_["\\" #_P4] = sig4; \ add(cell); \ return cell; \ } \ @@ -1083,9 +1088,9 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\B_WIDTH"] = sig_b.size(); cell->parameters["\\Y_WIDTH"] = sig_y.size(); - cell->connections["\\A"] = sig_a; - cell->connections["\\B"] = sig_b; - cell->connections["\\Y"] = sig_y; + cell->connections_["\\A"] = sig_a; + cell->connections_["\\B"] = sig_b; + cell->connections_["\\Y"] = sig_y; add(cell); return cell; } @@ -1098,8 +1103,8 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig_y.size(); cell->parameters["\\OFFSET"] = offset; - cell->connections["\\A"] = sig_a; - cell->connections["\\Y"] = sig_y; + cell->connections_["\\A"] = sig_a; + cell->connections_["\\Y"] = sig_y; add(cell); return cell; } @@ -1111,9 +1116,9 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a cell->type = "$concat"; cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\B_WIDTH"] = sig_b.size(); - cell->connections["\\A"] = sig_a; - cell->connections["\\B"] = sig_b; - cell->connections["\\Y"] = sig_y; + cell->connections_["\\A"] = sig_a; + cell->connections_["\\B"] = sig_b; + cell->connections_["\\Y"] = sig_y; add(cell); return cell; } @@ -1125,8 +1130,8 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, R cell->type = "$lut"; cell->parameters["\\LUT"] = lut; cell->parameters["\\WIDTH"] = sig_i.size(); - cell->connections["\\I"] = sig_i; - cell->connections["\\O"] = sig_o; + cell->connections_["\\I"] = sig_i; + cell->connections_["\\O"] = sig_o; add(cell); return cell; } @@ -1136,8 +1141,8 @@ RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = "$assert"; - cell->connections["\\A"] = sig_a; - cell->connections["\\EN"] = sig_en; + cell->connections_["\\A"] = sig_a; + cell->connections_["\\EN"] = sig_en; add(cell); return cell; } @@ -1150,9 +1155,9 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections["\\SET"] = sig_set; - cell->connections["\\CLR"] = sig_clr; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\SET"] = sig_set; + cell->connections_["\\CLR"] = sig_clr; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1164,9 +1169,9 @@ RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, cell->type = "$dff"; cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections["\\CLK"] = sig_clk; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\CLK"] = sig_clk; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1181,11 +1186,11 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections["\\CLK"] = sig_clk; - cell->connections["\\SET"] = sig_set; - cell->connections["\\CLR"] = sig_clr; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\CLK"] = sig_clk; + cell->connections_["\\SET"] = sig_set; + cell->connections_["\\CLR"] = sig_clr; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1200,10 +1205,10 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk cell->parameters["\\ARST_POLARITY"] = arst_polarity; cell->parameters["\\ARST_VALUE"] = arst_value; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections["\\CLK"] = sig_clk; - cell->connections["\\ARST"] = sig_arst; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\CLK"] = sig_clk; + cell->connections_["\\ARST"] = sig_arst; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1215,9 +1220,9 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e cell->type = "$dlatch"; cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections["\\EN"] = sig_en; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\EN"] = sig_en; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1232,11 +1237,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections["\\EN"] = sig_en; - cell->connections["\\SET"] = sig_set; - cell->connections["\\CLR"] = sig_clr; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\EN"] = sig_en; + cell->connections_["\\SET"] = sig_set; + cell->connections_["\\CLR"] = sig_clr; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1246,9 +1251,9 @@ RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_ RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); - cell->connections["\\C"] = sig_clk; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\C"] = sig_clk; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1259,11 +1264,11 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec si RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); - cell->connections["\\C"] = sig_clk; - cell->connections["\\S"] = sig_set; - cell->connections["\\R"] = sig_clr; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\C"] = sig_clk; + cell->connections_["\\S"] = sig_set; + cell->connections_["\\R"] = sig_clr; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1274,10 +1279,10 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'); - cell->connections["\\C"] = sig_clk; - cell->connections["\\R"] = sig_arst; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\C"] = sig_clk; + cell->connections_["\\R"] = sig_arst; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1287,9 +1292,9 @@ RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec s RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'); - cell->connections["\\E"] = sig_en; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\E"] = sig_en; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } @@ -1300,11 +1305,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); - cell->connections["\\E"] = sig_en; - cell->connections["\\S"] = sig_set; - cell->connections["\\R"] = sig_clr; - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; + cell->connections_["\\E"] = sig_en; + cell->connections_["\\S"] = sig_set; + cell->connections_["\\R"] = sig_clr; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; add(cell); return cell; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index fbd6e719..96bda753 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -279,13 +279,16 @@ struct RTLIL::Module std::map memories; std::map cells; std::map processes; - std::vector connections; + std::vector connections_; RTLIL_ATTRIBUTE_MEMBERS + virtual ~Module(); virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); virtual size_t count_id(RTLIL::IdString id); virtual void check(); virtual void optimize(); + + void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); void fixup_ports(); template void rewrite_sigspecs(T functor); @@ -435,37 +438,50 @@ struct RTLIL::Module RTLIL::SigSpec MuxGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); }; -struct RTLIL::Wire { +struct RTLIL::Wire +{ +//protected: + // use module->addWire() and module->remove() to create or destroy wires + friend struct RTLIL::Module; + Wire(); + ~Wire() { }; + +public: + // do not simply copy wires + //Wire(RTLIL::Wire &other) = delete; + //void operator=(RTLIL::Wire &other) = delete; + RTLIL::IdString name; int width, start_offset, port_id; bool port_input, port_output; RTLIL_ATTRIBUTE_MEMBERS - Wire(); }; -struct RTLIL::Memory { +struct RTLIL::Memory +{ + Memory(); + RTLIL::IdString name; int width, start_offset, size; RTLIL_ATTRIBUTE_MEMBERS - Memory(); }; struct RTLIL::Cell { protected: - // Use module->addCell() and module->remove() to create or destroy modules. + // use module->addCell() and module->remove() to create or destroy cells friend struct RTLIL::Module; Cell() { }; ~Cell() { }; public: - // do not copy simply cells + // do not simply copy cells Cell(RTLIL::Cell &other) = delete; void operator=(RTLIL::Cell &other) = delete; RTLIL::IdString name; RTLIL::IdString type; - std::map connections; + std::map connections_; std::map parameters; RTLIL_ATTRIBUTE_MEMBERS void check(); @@ -686,7 +702,7 @@ void RTLIL::Module::rewrite_sigspecs(T functor) it.second->rewrite_sigspecs(functor); for (auto &it : processes) it.second->rewrite_sigspecs(functor); - for (auto &it : connections) { + for (auto &it : connections_) { functor(it.first); functor(it.second); } @@ -694,7 +710,7 @@ void RTLIL::Module::rewrite_sigspecs(T functor) template void RTLIL::Cell::rewrite_sigspecs(T functor) { - for (auto &it : connections) + for (auto &it : connections_) functor(it.second); } diff --git a/kernel/satgen.h b/kernel/satgen.h index ea04cb40..ec4480c3 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -182,9 +182,9 @@ struct SatGen if (model_undef && (cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || is_arith_compare)) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); if (is_arith_compare) extendSignalWidth(undef_a, undef_b, cell, true); else @@ -195,7 +195,7 @@ struct SatGen int undef_y_bit = ez->OR(undef_any_a, undef_any_b); if (cell->type == "$div" || cell->type == "$mod") { - std::vector b = importSigSpec(cell->connections.at("\\B"), timestep); + std::vector b = importSigSpec(cell->connections_.at("\\B"), timestep); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); } @@ -215,9 +215,9 @@ struct SatGen cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$sub") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -237,9 +237,9 @@ struct SatGen if (model_undef && !arith_undef_handled) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, undef_y, cell, false); if (cell->type == "$and" || cell->type == "$_AND_") { @@ -265,7 +265,7 @@ struct SatGen } else if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -273,16 +273,16 @@ struct SatGen if (cell->type == "$_INV_" || cell->type == "$not") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_not(a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, true); ez->assume(ez->vec_eq(undef_a, undef_y)); undefGating(y, yy, undef_y); @@ -292,20 +292,20 @@ struct SatGen if (cell->type == "$_MUX_" || cell->type == "$mux") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections.at("\\B"), timestep); - std::vector s = importDefSigSpec(cell->connections.at("\\S"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector s = importDefSigSpec(cell->connections_.at("\\S"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->connections.at("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_s = importUndefSigSpec(cell->connections_.at("\\S"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); std::vector unequal_ab = ez->vec_not(ez->vec_iff(a, b)); std::vector undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); @@ -318,10 +318,10 @@ struct SatGen if (cell->type == "$pmux" || cell->type == "$safe_pmux") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections.at("\\B"), timestep); - std::vector s = importDefSigSpec(cell->connections.at("\\S"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector s = importDefSigSpec(cell->connections_.at("\\S"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -336,10 +336,10 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->connections.at("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_s = importUndefSigSpec(cell->connections_.at("\\S"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); int maybe_one_hot = ez->FALSE; int maybe_many_hot = ez->FALSE; @@ -387,8 +387,8 @@ struct SatGen if (cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -402,8 +402,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, cell->type != "$bu0"); if (cell->type == "$pos" || cell->type == "$bu0") { @@ -422,8 +422,8 @@ struct SatGen if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$reduce_bool" || cell->type == "$logic_not") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -442,8 +442,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); int aX = ez->expression(ezSAT::OpOr, undef_a); if (cell->type == "$reduce_and") { @@ -469,12 +469,12 @@ struct SatGen if (cell->type == "$logic_and" || cell->type == "$logic_or") { - std::vector vec_a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector vec_b = importDefSigSpec(cell->connections.at("\\B"), timestep); + std::vector vec_a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector vec_b = importDefSigSpec(cell->connections_.at("\\B"), timestep); int a = ez->expression(ez->OpOr, vec_a); int b = ez->expression(ez->OpOr, vec_b); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -487,9 +487,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a))); int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); @@ -516,16 +516,16 @@ struct SatGen if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") { bool is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidth(a, b, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); a = ez->vec_or(a, undef_a); b = ez->vec_or(b, undef_b); @@ -548,9 +548,9 @@ struct SatGen if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); if (cell->type == "$eqx") @@ -565,9 +565,9 @@ struct SatGen } else if (model_undef && (cell->type == "$eq" || cell->type == "$ne")) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); @@ -589,7 +589,7 @@ struct SatGen else { if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); undefGating(y, yy, undef_y); } log_assert(!model_undef || arith_undef_handled); @@ -599,9 +599,9 @@ struct SatGen if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); char shift_left = cell->type == "$shl" || cell->type == "$sshl"; bool sign_extend = cell->type == "$sshr" && cell->parameters["\\A_SIGNED"].as_bool(); @@ -627,9 +627,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); while (undef_y.size() < undef_a.size()) undef_y.push_back(ez->literal()); @@ -657,9 +657,9 @@ struct SatGen if (cell->type == "$mul") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -676,7 +676,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -684,9 +684,9 @@ struct SatGen if (cell->type == "$div" || cell->type == "$mod") { - std::vector a = importDefSigSpec(cell->connections.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); + std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -740,11 +740,11 @@ struct SatGen only_first_one.at(0) = ez->TRUE; div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); } else { - div_zero_result.insert(div_zero_result.end(), cell->connections.at("\\A").size(), ez->TRUE); + div_zero_result.insert(div_zero_result.end(), cell->connections_.at("\\A").size(), ez->TRUE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->FALSE); } } else { - int copy_a_bits = std::min(cell->connections.at("\\A").size(), cell->connections.at("\\B").size()); + int copy_a_bits = std::min(cell->connections_.at("\\A").size(), cell->connections_.at("\\B").size()); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); @@ -756,7 +756,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->connections.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -764,17 +764,17 @@ struct SatGen if (cell->type == "$slice") { - RTLIL::SigSpec a = cell->connections.at("\\A"); - RTLIL::SigSpec y = cell->connections.at("\\Y"); + RTLIL::SigSpec a = cell->connections_.at("\\A"); + RTLIL::SigSpec y = cell->connections_.at("\\Y"); ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.size()), y, timestep)); return true; } if (cell->type == "$concat") { - RTLIL::SigSpec a = cell->connections.at("\\A"); - RTLIL::SigSpec b = cell->connections.at("\\B"); - RTLIL::SigSpec y = cell->connections.at("\\Y"); + RTLIL::SigSpec a = cell->connections_.at("\\A"); + RTLIL::SigSpec b = cell->connections_.at("\\B"); + RTLIL::SigSpec y = cell->connections_.at("\\Y"); RTLIL::SigSpec ab = a; ab.append(b); @@ -787,20 +787,20 @@ struct SatGen { if (timestep == 1) { - initial_state.add((*sigmap)(cell->connections.at("\\Q"))); + initial_state.add((*sigmap)(cell->connections_.at("\\Q"))); } else { - std::vector d = importDefSigSpec(cell->connections.at("\\D"), timestep-1); - std::vector q = importDefSigSpec(cell->connections.at("\\Q"), timestep); + std::vector d = importDefSigSpec(cell->connections_.at("\\D"), timestep-1); + std::vector q = importDefSigSpec(cell->connections_.at("\\Q"), timestep); std::vector qq = model_undef ? ez->vec_var(q.size()) : q; ez->assume(ez->vec_eq(d, qq)); if (model_undef) { - std::vector undef_d = importUndefSigSpec(cell->connections.at("\\D"), timestep-1); - std::vector undef_q = importUndefSigSpec(cell->connections.at("\\Q"), timestep); + std::vector undef_d = importUndefSigSpec(cell->connections_.at("\\D"), timestep-1); + std::vector undef_q = importUndefSigSpec(cell->connections_.at("\\Q"), timestep); ez->assume(ez->vec_eq(undef_d, undef_q)); undefGating(q, qq, undef_q); @@ -812,8 +812,8 @@ struct SatGen if (cell->type == "$assert") { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - asserts_a[pf].append((*sigmap)(cell->connections.at("\\A"))); - asserts_en[pf].append((*sigmap)(cell->connections.at("\\EN"))); + asserts_a[pf].append((*sigmap)(cell->connections_.at("\\A"))); + asserts_en[pf].append((*sigmap)(cell->connections_.at("\\EN"))); return true; } diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 1a84194e..ea95e06e 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -269,7 +269,7 @@ struct SigMap void set(RTLIL::Module *module) { clear(); - for (auto &it : module->connections) + for (auto &it : module->connections_) add(it.first, it.second); } diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index 3f8d553a..f6c1528e 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -30,7 +30,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // For all ports on all cells for (auto &cell_iter : module->cells) - for (auto &conn : cell_iter.second->connections) + for (auto &conn : cell_iter.second->connections_) { // Get the signals on the port // (use sigmap to get a uniqe signal name) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 980e69aa..80828e15 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -111,11 +111,11 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) { if (clk_polarity != (cell->type == "$_DFF_P_")) return; - if (clk_sig != assign_map(cell->connections["\\C"])) + if (clk_sig != assign_map(cell->connections_["\\C"])) return; - RTLIL::SigSpec sig_d = cell->connections["\\D"]; - RTLIL::SigSpec sig_q = cell->connections["\\Q"]; + RTLIL::SigSpec sig_d = cell->connections_["\\D"]; + RTLIL::SigSpec sig_q = cell->connections_["\\Q"]; if (keepff) for (auto &c : sig_q.chunks()) @@ -133,8 +133,8 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_INV_") { - RTLIL::SigSpec sig_a = cell->connections["\\A"]; - RTLIL::SigSpec sig_y = cell->connections["\\Y"]; + RTLIL::SigSpec sig_a = cell->connections_["\\A"]; + RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; assign_map.apply(sig_a); assign_map.apply(sig_y); @@ -147,9 +147,9 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { - RTLIL::SigSpec sig_a = cell->connections["\\A"]; - RTLIL::SigSpec sig_b = cell->connections["\\B"]; - RTLIL::SigSpec sig_y = cell->connections["\\Y"]; + RTLIL::SigSpec sig_a = cell->connections_["\\A"]; + RTLIL::SigSpec sig_b = cell->connections_["\\B"]; + RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -173,10 +173,10 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_MUX_") { - RTLIL::SigSpec sig_a = cell->connections["\\A"]; - RTLIL::SigSpec sig_b = cell->connections["\\B"]; - RTLIL::SigSpec sig_s = cell->connections["\\S"]; - RTLIL::SigSpec sig_y = cell->connections["\\Y"]; + RTLIL::SigSpec sig_a = cell->connections_["\\A"]; + RTLIL::SigSpec sig_b = cell->connections_["\\B"]; + RTLIL::SigSpec sig_s = cell->connections_["\\S"]; + RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -347,7 +347,7 @@ static void handle_loops() } edges[id1].swap(edges[id3]); - module->connections.push_back(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); + module->connections_.push_back(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count); } } @@ -470,7 +470,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std if (cell->type != "$_DFF_N_" && cell->type != "$_DFF_P_") continue; - std::pair key(cell->type == "$_DFF_P_", assign_map(cell->connections.at("\\C"))); + std::pair key(cell->type == "$_DFF_P_", assign_map(cell->connections_.at("\\C"))); if (++dff_counters[key] > best_dff_counter) { best_dff_counter = dff_counters[key]; clk_polarity = key.first; @@ -503,7 +503,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } for (auto &cell_it : module->cells) - for (auto &port_it : cell_it.second->connections) + for (auto &port_it : cell_it.second->connections_) mark_port(port_it.second); handle_loops(); @@ -705,48 +705,48 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); - module->connections.push_back(conn); + module->connections_.push_back(conn); continue; } if (c->type == "\\BUF") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); - conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); - module->connections.push_back(conn); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); + module->connections_.push_back(conn); continue; } if (c->type == "\\INV") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_INV_"); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); + cell->connections_["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); + cell->connections_["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); design->select(module, cell); continue; } if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].as_wire()->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); + cell->connections_["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); + cell->connections_["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\B"].as_wire()->name)]); + cell->connections_["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); design->select(module, cell); continue; } if (c->type == "\\MUX") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_"); - cell->connections["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\A"].as_wire()->name)]); - cell->connections["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\B"].as_wire()->name)]); - cell->connections["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\S"].as_wire()->name)]); - cell->connections["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Y"].as_wire()->name)]); + cell->connections_["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); + cell->connections_["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\B"].as_wire()->name)]); + cell->connections_["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\S"].as_wire()->name)]); + cell->connections_["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); design->select(module, cell); continue; } if (c->type == "\\DFF") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].as_wire()->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].as_wire()->name)]); - cell->connections["\\C"] = clk_sig; + cell->connections_["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\D"].as_wire()->name)]); + cell->connections_["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Q"].as_wire()->name)]); + cell->connections_["\\C"] = clk_sig; design->select(module, cell); continue; } @@ -761,23 +761,23 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\_const0_" || c->type == "\\_const1_") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections.begin()->second.as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections_.begin()->second.as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1); - module->connections.push_back(conn); + module->connections_.push_back(conn); continue; } if (c->type == "\\_dff_") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->connections["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\D"].as_wire()->name)]); - cell->connections["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections["\\Q"].as_wire()->name)]); - cell->connections["\\C"] = clk_sig; + cell->connections_["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\D"].as_wire()->name)]); + cell->connections_["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Q"].as_wire()->name)]); + cell->connections_["\\C"] = clk_sig; design->select(module, cell); continue; } RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); cell->parameters = c->parameters; - for (auto &conn : c->connections) { + for (auto &conn : c->connections_) { RTLIL::SigSpec newsig; for (auto &c : conn.second.chunks()) { if (c.width == 0) @@ -785,18 +785,18 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std assert(c.width == 1); newsig.append(module->wires[remap_name(c.wire->name)]); } - cell->connections[conn.first] = newsig; + cell->connections_[conn.first] = newsig; } design->select(module, cell); } } - for (auto conn : mapped_mod->connections) { + for (auto conn : mapped_mod->connections_) { if (!conn.first.is_fully_const()) conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.as_wire()->name)]); if (!conn.second.is_fully_const()) conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.as_wire()->name)]); - module->connections.push_back(conn); + module->connections_.push_back(conn); } for (auto &it : cell_stats) @@ -816,7 +816,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std conn.second = si.bit; in_wires++; } - module->connections.push_back(conn); + module->connections_.push_back(conn); } log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); log("ABC RESULTS: input signals: %8d\n", in_wires); diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index e7feb187..122f7845 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -128,8 +128,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) } RTLIL::Cell *cell = module->addCell(NEW_ID, dff_name); - cell->connections["\\D"] = module->wires.at(RTLIL::escape_id(d)); - cell->connections["\\Q"] = module->wires.at(RTLIL::escape_id(q)); + cell->connections_["\\D"] = module->wires.at(RTLIL::escape_id(d)); + cell->connections_["\\Q"] = module->wires.at(RTLIL::escape_id(q)); continue; } @@ -148,7 +148,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) *(q++) = 0; if (module->wires.count(RTLIL::escape_id(q)) == 0) module->addWire(RTLIL::escape_id(q)); - cell->connections[RTLIL::escape_id(p)] = module->wires.at(RTLIL::escape_id(q)); + cell->connections_[RTLIL::escape_id(p)] = module->wires.at(RTLIL::escape_id(q)); } continue; } @@ -199,15 +199,15 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) finished_parsing_constval: if (state == RTLIL::State::Sa) state = RTLIL::State::S1; - module->connections.push_back(RTLIL::SigSig(output_sig, state)); + module->connections_.push_back(RTLIL::SigSig(output_sig, state)); goto continue_without_read; } RTLIL::Cell *cell = module->addCell(NEW_ID, "$lut"); cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size()); cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size()); - cell->connections["\\I"] = input_sig; - cell->connections["\\O"] = output_sig; + cell->connections_["\\I"] = input_sig; + cell->connections_["\\O"] = output_sig; lutptr = &cell->parameters.at("\\LUT"); lut_default_state = RTLIL::State::Sx; continue; diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index acee4c46..ce8ecc32 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -75,10 +75,10 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n continue; if (mod->get_bool_attribute("\\blackbox")) continue; - if (it.second->connections.count(name) > 0) + if (it.second->connections_.count(name) > 0) continue; - it.second->connections[name] = wire; + it.second->connections_[name] = wire; log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str()); } } diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index dcd5fc96..ea05026f 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -30,11 +30,11 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size()); for (auto &it : module->cells) - for (auto &port : it.second->connections) + for (auto &port : it.second->connections_) if (ct.cell_output(it.second->type, port.first)) sigmap(port.second).replace(sig, dummy_wire, &port.second); - for (auto &conn : module->connections) + for (auto &conn : module->connections_) sigmap(conn.first).replace(sig, dummy_wire, &conn.first); } @@ -123,7 +123,7 @@ struct ConnectPass : public Pass { SigMap sigmap; if (!flag_nomap) - for (auto &it : module->connections) { + for (auto &it : module->connections_) { std::vector lhs = it.first.to_sigbit_vector(); std::vector rhs = it.first.to_sigbit_vector(); for (size_t i = 0; i < lhs.size(); i++) @@ -148,7 +148,7 @@ struct ConnectPass : public Pass { if (!flag_nounset) unset_drivers(design, module, sigmap, sig_lhs); - module->connections.push_back(RTLIL::SigSig(sig_lhs, sig_rhs)); + module->connections_.push_back(RTLIL::SigSig(sig_lhs, sig_rhs)); } else if (!unset_expr.empty()) @@ -176,7 +176,7 @@ struct ConnectPass : public Pass { if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cells.at(RTLIL::escape_id(port_cell))->connections[RTLIL::escape_id(port_port)] = sigmap(sig); + module->cells.at(RTLIL::escape_id(port_cell))->connections_[RTLIL::escape_id(port_port)] = sigmap(sig); } else log_cmd_error("Expected -set, -unset, or -port.\n"); diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 6cb2a892..87ed3d85 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -74,7 +74,7 @@ struct ConnwrappersWorker if (!decl_celltypes.count(cell->type)) continue; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) { std::pair key(cell->type, conn.first); @@ -109,7 +109,7 @@ struct ConnwrappersWorker if (!design->selected(module, cell)) continue; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) { std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); RTLIL::SigSpec old_sig; diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index d5976dcb..0028f7ea 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -49,7 +49,7 @@ struct ScatterPass : public Pass { continue; for (auto &c : mod_it.second->cells) - for (auto &p : c.second->connections) + for (auto &p : c.second->connections_) { RTLIL::Wire *wire = new RTLIL::Wire; wire->name = NEW_ID; @@ -58,10 +58,10 @@ struct ScatterPass : public Pass { if (ct.cell_output(c.second->type, p.first)) { RTLIL::SigSig sigsig(p.second, wire); - mod_it.second->connections.push_back(sigsig); + mod_it.second->connections_.push_back(sigsig); } else { RTLIL::SigSig sigsig(wire, p.second); - mod_it.second->connections.push_back(sigsig); + mod_it.second->connections_.push_back(sigsig); } p.second = wire; diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 49e79bd4..40a2e48c 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -132,7 +132,7 @@ struct SccWorker RTLIL::SigSpec inputSignals, outputSignals; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) { bool isInput = true, isOutput = true; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 123483a3..5d991d03 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -380,7 +380,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0) selected_wires.insert(it.second); - for (auto &conn : mod->connections) + for (auto &conn : mod->connections_) { std::vector conn_lhs = conn.first.to_sigbit_vector(); std::vector conn_rhs = conn.second.to_sigbit_vector(); @@ -396,7 +396,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v } for (auto &cell : mod->cells) - for (auto &conn : cell.second->connections) + for (auto &conn : cell.second->connections_) { char last_mode = '-'; for (auto &rule : rules) { diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 6c4bb16c..e1005a27 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -135,7 +135,7 @@ struct SetundefPass : public Pass { CellTypes ct(design); for (auto &it : module->cells) - for (auto &conn : it.second->connections) + for (auto &conn : it.second->connections_) if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) undriven_signals.del(sigmap(conn.second)); @@ -144,7 +144,7 @@ struct SetundefPass : public Pass { RTLIL::SigSpec bits; for (int i = 0; i < c.width; i++) bits.append(worker.next_bit()); - module->connections.push_back(RTLIL::SigSig(c, bits)); + module->connections_.push_back(RTLIL::SigSig(c, bits)); } } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 8ff06899..29b83a9a 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -344,7 +344,7 @@ struct ShowWorker std::vector in_ports, out_ports; - for (auto &conn : it.second->connections) { + for (auto &conn : it.second->connections_) { if (!ct.cell_output(it.second->type, conn.first)) in_ports.push_back(conn.first); else @@ -368,7 +368,7 @@ struct ShowWorker label_string += "}}"; std::string code; - for (auto &conn : it.second->connections) { + for (auto &conn : it.second->connections_) { code += gen_portbox(stringf("c%d:p%d", id2num(it.first), id2num(conn.first)), conn.second, ct.cell_output(it.second->type, conn.first)); } @@ -421,7 +421,7 @@ struct ShowWorker fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name), proc_src.c_str()); } - for (auto &conn : module->connections) + for (auto &conn : module->connections_) { bool found_lhs_wire = false; for (auto &c : conn.first.chunks()) { @@ -516,7 +516,7 @@ struct ShowWorker log("Skipping blackbox module %s.\n", id2cstr(module->name)); continue; } else - if (module->cells.empty() && module->connections.empty() && module->processes.empty()) { + if (module->cells.empty() && module->connections_.empty() && module->processes.empty()) { log("Skipping empty module %s.\n", id2cstr(module->name)); continue; } else @@ -695,7 +695,7 @@ struct ShowPass : public Pass { for (auto &mod_it : design->modules) { if (mod_it.second->get_bool_attribute("\\blackbox")) continue; - if (mod_it.second->cells.empty() && mod_it.second->connections.empty()) + if (mod_it.second->cells.empty() && mod_it.second->connections_.empty()) continue; if (design->selected_module(mod_it.first)) modcount++; diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index a470aed0..c8b3d0b0 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -74,9 +74,9 @@ struct SpliceWorker cell->parameters["\\OFFSET"] = offset; cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig.size(); - cell->connections["\\A"] = sig_a; - cell->connections["\\Y"] = module->addWire(NEW_ID, sig.size()); - new_sig = cell->connections["\\Y"]; + cell->connections_["\\A"] = sig_a; + cell->connections_["\\Y"] = module->addWire(NEW_ID, sig.size()); + new_sig = cell->connections_["\\Y"]; } sliced_signals_cache[sig] = new_sig; @@ -130,10 +130,10 @@ struct SpliceWorker RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat"); cell->parameters["\\A_WIDTH"] = new_sig.size(); cell->parameters["\\B_WIDTH"] = sig2.size(); - cell->connections["\\A"] = new_sig; - cell->connections["\\B"] = sig2; - cell->connections["\\Y"] = module->addWire(NEW_ID, new_sig.size() + sig2.size()); - new_sig = cell->connections["\\Y"]; + cell->connections_["\\A"] = new_sig; + cell->connections_["\\B"] = sig2; + cell->connections_["\\Y"] = module->addWire(NEW_ID, new_sig.size() + sig2.size()); + new_sig = cell->connections_["\\Y"]; } spliced_signals_cache[sig] = new_sig; @@ -159,7 +159,7 @@ struct SpliceWorker } for (auto &it : module->cells) - for (auto &conn : it.second->connections) + for (auto &conn : it.second->connections_) if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) { RTLIL::SigSpec sig = sigmap(conn.second); driven_chunks.insert(sig); @@ -182,7 +182,7 @@ struct SpliceWorker for (auto &it : module->cells) { if (!sel_by_wire && !design->selected(module, it.second)) continue; - for (auto &conn : it.second->connections) + for (auto &conn : it.second->connections_) if (ct.cell_input(it.second->type, conn.first)) { if (ports.size() > 0 && !ports.count(conn.first)) continue; @@ -232,7 +232,7 @@ struct SpliceWorker it.first->port_output = false; module->add(it.first); module->add(new_port); - module->connections.push_back(RTLIL::SigSig(new_port, it.second)); + module->connections_.push_back(RTLIL::SigSig(new_port, it.second)); } } }; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index c65b6a5f..497d0a2a 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -134,7 +134,7 @@ struct SplitnetsPass : public Pass { std::map> split_wires_at; for (auto &c : module->cells) - for (auto &p : c.second->connections) + for (auto &p : c.second->connections_) { if (!ct.cell_known(c.second->type)) continue; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 2ba4c72b..e5967659 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -52,8 +52,8 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig for (auto &cellport : cellport_list) { if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux" && cellport.first->type != "$safe_pmux") || cellport.second != "\\Y") return false; - RTLIL::SigSpec sig_a = assign_map(cellport.first->connections["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cellport.first->connections["\\B"]); + RTLIL::SigSpec sig_a = assign_map(cellport.first->connections_["\\A"]); + RTLIL::SigSpec sig_b = assign_map(cellport.first->connections_["\\B"]); if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) return false; for (int i = 0; i < sig_b.size(); i += sig_a.size()) @@ -80,14 +80,14 @@ static bool check_state_users(RTLIL::SigSpec sig) continue; if (cellport.second != "\\A" && cellport.second != "\\B") return false; - if (cell->connections.count("\\A") == 0 || cell->connections.count("\\B") == 0 || cell->connections.count("\\Y") == 0) + if (cell->connections_.count("\\A") == 0 || cell->connections_.count("\\B") == 0 || cell->connections_.count("\\Y") == 0) return false; - for (auto &port_it : cell->connections) + for (auto &port_it : cell->connections_) if (port_it.first != "\\A" && port_it.first != "\\B" && port_it.first != "\\Y") return false; - if (assign_map(cell->connections["\\A"]) == sig && cell->connections["\\B"].is_fully_const()) + if (assign_map(cell->connections_["\\A"]) == sig && cell->connections_["\\B"].is_fully_const()) continue; - if (assign_map(cell->connections["\\B"]) == sig && cell->connections["\\A"].is_fully_const()) + if (assign_map(cell->connections_["\\B"]) == sig && cell->connections_["\\A"].is_fully_const()) continue; return false; } @@ -109,8 +109,8 @@ static void detect_fsm(RTLIL::Wire *wire) continue; muxtree_cells.clear(); SigPool recursion_monitor; - RTLIL::SigSpec sig_q = assign_map(cellport.first->connections["\\Q"]); - RTLIL::SigSpec sig_d = assign_map(cellport.first->connections["\\D"]); + RTLIL::SigSpec sig_q = assign_map(cellport.first->connections_["\\Q"]); + RTLIL::SigSpec sig_d = assign_map(cellport.first->connections_["\\D"]); if (sig_q == RTLIL::SigSpec(wire) && check_state_mux_tree(sig_q, sig_d, recursion_monitor) && check_state_users(sig_q)) { log("Found FSM state register %s in module %s.\n", wire->name.c_str(), module->name.c_str()); wire->attributes["\\fsm_encoding"] = RTLIL::Const("auto"); @@ -160,7 +160,7 @@ struct FsmDetectPass : public Pass { sig2user.clear(); sig_at_port.clear(); for (auto &cell_it : module->cells) - for (auto &conn_it : cell_it.second->connections) { + for (auto &conn_it : cell_it.second->connections_) { if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index f3b6c998..431f086d 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -43,34 +43,34 @@ struct FsmExpand bool is_cell_merge_candidate(RTLIL::Cell *cell) { if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") - if (cell->connections.at("\\A").size() < 2) + if (cell->connections_.at("\\A").size() < 2) return true; RTLIL::SigSpec new_signals; - if (cell->connections.count("\\A") > 0) - new_signals.append(assign_map(cell->connections["\\A"])); - if (cell->connections.count("\\B") > 0) - new_signals.append(assign_map(cell->connections["\\B"])); - if (cell->connections.count("\\S") > 0) - new_signals.append(assign_map(cell->connections["\\S"])); - if (cell->connections.count("\\Y") > 0) - new_signals.append(assign_map(cell->connections["\\Y"])); + if (cell->connections_.count("\\A") > 0) + new_signals.append(assign_map(cell->connections_["\\A"])); + if (cell->connections_.count("\\B") > 0) + new_signals.append(assign_map(cell->connections_["\\B"])); + if (cell->connections_.count("\\S") > 0) + new_signals.append(assign_map(cell->connections_["\\S"])); + if (cell->connections_.count("\\Y") > 0) + new_signals.append(assign_map(cell->connections_["\\Y"])); new_signals.sort_and_unify(); new_signals.remove_const(); - new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_IN"])); - new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_OUT"])); + new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_IN"])); + new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_OUT"])); if (new_signals.size() > 3) return false; - if (cell->connections.count("\\Y") > 0) { - new_signals.append(assign_map(cell->connections["\\Y"])); + if (cell->connections_.count("\\Y") > 0) { + new_signals.append(assign_map(cell->connections_["\\Y"])); new_signals.sort_and_unify(); new_signals.remove_const(); - new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_IN"])); - new_signals.remove(assign_map(fsm_cell->connections["\\CTRL_OUT"])); + new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_IN"])); + new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_OUT"])); } if (new_signals.size() > 2) @@ -83,10 +83,10 @@ struct FsmExpand { std::vector cell_list; - for (auto c : sig2driver.find(assign_map(fsm_cell->connections["\\CTRL_IN"]))) + for (auto c : sig2driver.find(assign_map(fsm_cell->connections_["\\CTRL_IN"]))) cell_list.push_back(c); - for (auto c : sig2user.find(assign_map(fsm_cell->connections["\\CTRL_OUT"]))) + for (auto c : sig2user.find(assign_map(fsm_cell->connections_["\\CTRL_OUT"]))) cell_list.push_back(c); current_set.clear(); @@ -94,7 +94,7 @@ struct FsmExpand { if (merged_set.count(c) > 0 || current_set.count(c) > 0 || no_candidate_set.count(c) > 0) continue; - for (auto &p : c->connections) { + for (auto &p : c->connections_) { if (p.first != "\\A" && p.first != "\\B" && p.first != "\\S" && p.first != "\\Y") goto next_cell; } @@ -135,7 +135,7 @@ struct FsmExpand RTLIL::SigSpec input_sig, output_sig; - for (auto &p : cell->connections) + for (auto &p : cell->connections_) if (ct.cell_output(cell->type, p.first)) output_sig.append(assign_map(p.second)); else @@ -148,12 +148,12 @@ struct FsmExpand for (int i = 0; i < (1 << input_sig.size()); i++) { RTLIL::Const in_val(i, input_sig.size()); RTLIL::SigSpec A, B, S; - if (cell->connections.count("\\A") > 0) - A = assign_map(cell->connections["\\A"]); - if (cell->connections.count("\\B") > 0) - B = assign_map(cell->connections["\\B"]); - if (cell->connections.count("\\S") > 0) - S = assign_map(cell->connections["\\S"]); + if (cell->connections_.count("\\A") > 0) + A = assign_map(cell->connections_["\\A"]); + if (cell->connections_.count("\\B") > 0) + B = assign_map(cell->connections_["\\B"]); + if (cell->connections_.count("\\S") > 0) + S = assign_map(cell->connections_["\\S"]); A.replace(input_sig, RTLIL::SigSpec(in_val)); B.replace(input_sig, RTLIL::SigSpec(in_val)); S.replace(input_sig, RTLIL::SigSpec(in_val)); @@ -167,10 +167,10 @@ struct FsmExpand fsm_data.copy_from_cell(fsm_cell); fsm_data.num_inputs += input_sig.size(); - fsm_cell->connections["\\CTRL_IN"].append(input_sig); + fsm_cell->connections_["\\CTRL_IN"].append(input_sig); fsm_data.num_outputs += output_sig.size(); - fsm_cell->connections["\\CTRL_OUT"].append(output_sig); + fsm_cell->connections_["\\CTRL_OUT"].append(output_sig); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { @@ -204,7 +204,7 @@ struct FsmExpand for (auto &cell_it : module->cells) { RTLIL::Cell *c = cell_it.second; if (ct.cell_known(c->type) && design->selected(mod, c)) - for (auto &p : c->connections) { + for (auto &p : c->connections_) { if (ct.cell_output(c->type, p.first)) sig2driver.insert(assign_map(p.second), c); else diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 1b5ea1bc..b0e1c903 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -58,9 +58,9 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); return false; } - RTLIL::SigSpec sig_a = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections["\\B"]); - RTLIL::SigSpec sig_s = assign_map(cell->connections["\\S"]); + RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec sig_s = assign_map(cell->connections_["\\S"]); if (reset_state && RTLIL::SigSpec(*reset_state).is_fully_undef()) do { if (sig_a.is_fully_def()) @@ -183,12 +183,12 @@ static void extract_fsm(RTLIL::Wire *wire) if ((cell->type != "$dff" && cell->type != "$adff") || cellport.second != "\\Q") continue; log(" found %s cell for state register: %s\n", cell->type.c_str(), cell->name.c_str()); - RTLIL::SigSpec sig_q = assign_map(cell->connections["\\Q"]); - RTLIL::SigSpec sig_d = assign_map(cell->connections["\\D"]); - clk = cell->connections["\\CLK"]; + RTLIL::SigSpec sig_q = assign_map(cell->connections_["\\Q"]); + RTLIL::SigSpec sig_d = assign_map(cell->connections_["\\D"]); + clk = cell->connections_["\\CLK"]; clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); if (cell->type == "$adff") { - arst = cell->connections["\\ARST"]; + arst = cell->connections_["\\ARST"]; arst_polarity = cell->parameters["\\ARST_POLARITY"].as_bool(); reset_state = cell->parameters["\\ARST_VALUE"]; } @@ -224,9 +224,9 @@ static void extract_fsm(RTLIL::Wire *wire) sig2trigger.find(dff_out, cellport_list); for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells.at(cellport.first); - RTLIL::SigSpec sig_a = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections["\\B"]); - RTLIL::SigSpec sig_y = assign_map(cell->connections["\\Y"]); + RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec sig_y = assign_map(cell->connections_["\\Y"]); if (cellport.second == "\\A" && !sig_b.is_fully_const()) continue; if (cellport.second == "\\B" && !sig_a.is_fully_const()) @@ -271,12 +271,12 @@ static void extract_fsm(RTLIL::Wire *wire) // create fsm cell RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), RTLIL::autoidx++), "$fsm"); - fsm_cell->connections["\\CLK"] = clk; - fsm_cell->connections["\\ARST"] = arst; + fsm_cell->connections_["\\CLK"] = clk; + fsm_cell->connections_["\\ARST"] = arst; fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); fsm_cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity ? 1 : 0, 1); - fsm_cell->connections["\\CTRL_IN"] = ctrl_in; - fsm_cell->connections["\\CTRL_OUT"] = ctrl_out; + fsm_cell->connections_["\\CTRL_IN"] = ctrl_in; + fsm_cell->connections_["\\CTRL_OUT"] = ctrl_out; fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name); fsm_cell->attributes = wire->attributes; fsm_data.copy_to_cell(fsm_cell); @@ -294,13 +294,13 @@ static void extract_fsm(RTLIL::Wire *wire) sig2driver.find(ctrl_out, cellport_list); for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells.at(cellport.first); - RTLIL::SigSpec port_sig = assign_map(cell->connections[cellport.second]); + RTLIL::SigSpec port_sig = assign_map(cell->connections_[cellport.second]); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = new RTLIL::Wire; unconn_wire->name = stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++); unconn_wire->width = unconn_sig.size(); module->wires[unconn_wire->name] = unconn_wire; - port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections[cellport.second]); + port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); } } @@ -344,14 +344,14 @@ struct FsmExtractPass : public Pass { sig2driver.clear(); sig2trigger.clear(); for (auto &cell_it : module->cells) - for (auto &conn_it : cell_it.second->connections) { + for (auto &conn_it : cell_it.second->connections_) { if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); sig2driver.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); } - if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->connections.count("\\Y") > 0 && - cell_it.second->connections["\\Y"].size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { + if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->connections_.count("\\Y") > 0 && + cell_it.second->connections_["\\Y"].size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); sig2trigger.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 78248eb6..cf482d6d 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -58,9 +58,9 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$eq"); - eq_cell->connections["\\A"] = eq_sig_a; - eq_cell->connections["\\B"] = eq_sig_b; - eq_cell->connections["\\Y"] = RTLIL::SigSpec(eq_wire); + eq_cell->connections_["\\A"] = eq_sig_a; + eq_cell->connections_["\\B"] = eq_sig_b; + eq_cell->connections_["\\Y"] = RTLIL::SigSpec(eq_wire); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size()); @@ -80,8 +80,8 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$reduce_or"); - or_cell->connections["\\A"] = or_sig; - or_cell->connections["\\Y"] = RTLIL::SigSpec(or_wire); + or_cell->connections_["\\A"] = or_sig; + or_cell->connections_["\\Y"] = RTLIL::SigSpec(or_wire); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); @@ -96,9 +96,9 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$and"); - and_cell->connections["\\A"] = and_sig.extract(0, 1); - and_cell->connections["\\B"] = and_sig.extract(1, 1); - and_cell->connections["\\Y"] = RTLIL::SigSpec(and_wire); + and_cell->connections_["\\A"] = and_sig.extract(0, 1); + and_cell->connections_["\\B"] = and_sig.extract(1, 1); + and_cell->connections_["\\Y"] = RTLIL::SigSpec(and_wire); and_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); and_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); and_cell->parameters["\\A_WIDTH"] = RTLIL::Const(1); @@ -119,15 +119,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 1) { RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or"); - or_cell->connections["\\A"] = cases_vector; - or_cell->connections["\\Y"] = output; + or_cell->connections_["\\A"] = cases_vector; + or_cell->connections_["\\Y"] = output; or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); } else if (cases_vector.size() == 1) { - module->connections.push_back(RTLIL::SigSig(output, cases_vector)); + module->connections_.push_back(RTLIL::SigSig(output, cases_vector)); } else { - module->connections.push_back(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); + module->connections_.push_back(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); } } @@ -138,8 +138,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) FsmData fsm_data; fsm_data.copy_from_cell(fsm_cell); - RTLIL::SigSpec ctrl_in = fsm_cell->connections["\\CTRL_IN"]; - RTLIL::SigSpec ctrl_out = fsm_cell->connections["\\CTRL_OUT"]; + RTLIL::SigSpec ctrl_in = fsm_cell->connections_["\\CTRL_IN"]; + RTLIL::SigSpec ctrl_out = fsm_cell->connections_["\\CTRL_OUT"]; // create state register @@ -153,7 +153,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits); RTLIL::Cell *state_dff = module->addCell(NEW_ID, ""); - if (fsm_cell->connections["\\ARST"].is_fully_const()) { + if (fsm_cell->connections_["\\ARST"].is_fully_const()) { state_dff->type = "$dff"; } else { state_dff->type = "$adff"; @@ -162,13 +162,13 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) for (auto &bit : state_dff->parameters["\\ARST_VALUE"].bits) if (bit != RTLIL::State::S1) bit = RTLIL::State::S0; - state_dff->connections["\\ARST"] = fsm_cell->connections["\\ARST"]; + state_dff->connections_["\\ARST"] = fsm_cell->connections_["\\ARST"]; } state_dff->parameters["\\WIDTH"] = RTLIL::Const(fsm_data.state_bits); state_dff->parameters["\\CLK_POLARITY"] = fsm_cell->parameters["\\CLK_POLARITY"]; - state_dff->connections["\\CLK"] = fsm_cell->connections["\\CLK"]; - state_dff->connections["\\D"] = RTLIL::SigSpec(next_state_wire); - state_dff->connections["\\Q"] = RTLIL::SigSpec(state_wire); + state_dff->connections_["\\CLK"] = fsm_cell->connections_["\\CLK"]; + state_dff->connections_["\\D"] = RTLIL::SigSpec(next_state_wire); + state_dff->connections_["\\Q"] = RTLIL::SigSpec(state_wire); // decode state register @@ -189,16 +189,16 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) if (sig_b == RTLIL::SigSpec(RTLIL::State::S1)) { - module->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec(state_onehot, i), sig_a)); + module->connections_.push_back(RTLIL::SigSig(RTLIL::SigSpec(state_onehot, i), sig_a)); } else { encoding_is_onehot = false; RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq"); - eq_cell->connections["\\A"] = sig_a; - eq_cell->connections["\\B"] = sig_b; - eq_cell->connections["\\Y"] = RTLIL::SigSpec(state_onehot, i); + eq_cell->connections_["\\A"] = sig_a; + eq_cell->connections_["\\B"] = sig_b; + eq_cell->connections_["\\Y"] = RTLIL::SigSpec(state_onehot, i); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size()); @@ -245,7 +245,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, i)); } log_assert(!next_state_sig.has_marked_bits()); - module->connections.push_back(RTLIL::SigSig(next_state_wire, next_state_sig)); + module->connections_.push_back(RTLIL::SigSig(next_state_wire, next_state_sig)); } else { @@ -265,10 +265,10 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) } RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux"); - mux_cell->connections["\\A"] = sig_a; - mux_cell->connections["\\B"] = sig_b; - mux_cell->connections["\\S"] = sig_s; - mux_cell->connections["\\Y"] = RTLIL::SigSpec(next_state_wire); + mux_cell->connections_["\\A"] = sig_a; + mux_cell->connections_["\\B"] = sig_b; + mux_cell->connections_["\\S"] = sig_s; + mux_cell->connections_["\\Y"] = RTLIL::SigSpec(next_state_wire); mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); } diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index efa61245..3fde534d 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -52,7 +52,7 @@ struct FsmOpt void opt_const_and_unused_inputs() { - RTLIL::SigSpec ctrl_in = cell->connections["\\CTRL_IN"]; + RTLIL::SigSpec ctrl_in = cell->connections_["\\CTRL_IN"]; std::vector ctrl_in_used(ctrl_in.size()); std::vector new_transition_table; @@ -73,13 +73,13 @@ struct FsmOpt for (int i = int(ctrl_in_used.size())-1; i >= 0; i--) { if (!ctrl_in_used[i]) { - log(" Removing unused input signal %s.\n", log_signal(cell->connections["\\CTRL_IN"].extract(i, 1))); + log(" Removing unused input signal %s.\n", log_signal(cell->connections_["\\CTRL_IN"].extract(i, 1))); for (auto &tr : new_transition_table) { RTLIL::SigSpec tmp(tr.ctrl_in); tmp.remove(i, 1); tr.ctrl_in = tmp.as_const(); } - cell->connections["\\CTRL_IN"].remove(i, 1); + cell->connections_["\\CTRL_IN"].remove(i, 1); fsm_data.num_inputs--; } } @@ -91,10 +91,10 @@ struct FsmOpt void opt_unused_outputs() { for (int i = 0; i < fsm_data.num_outputs; i++) { - RTLIL::SigSpec sig = cell->connections["\\CTRL_OUT"].extract(i, 1); + RTLIL::SigSpec sig = cell->connections_["\\CTRL_OUT"].extract(i, 1); if (signal_is_unused(sig)) { log(" Removing unused output signal %s.\n", log_signal(sig)); - cell->connections["\\CTRL_OUT"].remove(i, 1); + cell->connections_["\\CTRL_OUT"].remove(i, 1); for (auto &tr : fsm_data.transition_table) { RTLIL::SigSpec tmp(tr.ctrl_out); tmp.remove(i, 1); @@ -108,7 +108,7 @@ struct FsmOpt void opt_alias_inputs() { - RTLIL::SigSpec &ctrl_in = cell->connections["\\CTRL_IN"]; + RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"]; for (int i = 0; i < ctrl_in.size(); i++) for (int j = i+1; j < ctrl_in.size(); j++) @@ -145,8 +145,8 @@ struct FsmOpt void opt_feedback_inputs() { - RTLIL::SigSpec &ctrl_in = cell->connections["\\CTRL_IN"]; - RTLIL::SigSpec &ctrl_out = cell->connections["\\CTRL_OUT"]; + RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"]; + RTLIL::SigSpec &ctrl_out = cell->connections_["\\CTRL_OUT"]; for (int j = 0; j < ctrl_out.size(); j++) for (int i = 0; i < ctrl_in.size(); i++) diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index ae9569ed..a336d23f 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -141,13 +141,13 @@ struct FsmData log("\n"); log(" Input signals:\n"); - RTLIL::SigSpec sig_in = cell->connections["\\CTRL_IN"]; + RTLIL::SigSpec sig_in = cell->connections_["\\CTRL_IN"]; for (int i = 0; i < SIZE(sig_in); i++) log(" %3d: %s\n", i, log_signal(sig_in[i])); log("\n"); log(" Output signals:\n"); - RTLIL::SigSpec sig_out = cell->connections["\\CTRL_OUT"]; + RTLIL::SigSpec sig_out = cell->connections_["\\CTRL_OUT"]; for (int i = 0; i < SIZE(sig_out); i++) log(" %3d: %s\n", i, log_signal(sig_out[i])); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 90f377e0..4306c29e 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -58,7 +58,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell for (auto i1 : design->modules) for (auto i2 : i1.second->cells) if (i2.second->type == celltype) { - for (auto &conn : i2.second->connections) { + for (auto &conn : i2.second->connections_) { if (conn.first[0] != '$') portnames.insert(conn.first); portwidths[conn.first] = std::max(portwidths[conn.first], conn.second.size()); @@ -219,7 +219,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla RTLIL::Module *mod = design->modules[cell->type]; - for (auto &conn : cell->connections) { + for (auto &conn : cell->connections_) { int conn_size = conn.second.size(); std::string portname = conn.first; if (portname.substr(0, 1) == "$") { @@ -486,7 +486,7 @@ struct HierarchyPass : public Pass { RTLIL::Cell *cell = cell_it.second; if (design->modules.count(cell->type) == 0) continue; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { pos_mods.insert(design->modules.at(cell->type)); pos_work.push_back(std::pair(mod_it.second, cell)); @@ -507,7 +507,7 @@ struct HierarchyPass : public Pass { log("Mapping positional arguments of cell %s.%s (%s).\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); std::map new_connections; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { int id = atoi(conn.first.c_str()+1); std::pair key(design->modules.at(cell->type), id); @@ -519,7 +519,7 @@ struct HierarchyPass : public Pass { new_connections[pos_map.at(key)] = conn.second; } else new_connections[conn.first] = conn.second; - cell->connections = new_connections; + cell->connections_ = new_connections; } } diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index be580ca0..df5fd8e3 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -79,11 +79,11 @@ struct SubmodWorker wire_flags.clear(); for (RTLIL::Cell *cell : submod.cells) { if (ct.cell_known(cell->type)) { - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) flag_signal(conn.second, true, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first), false, false); } else { log("WARNING: Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str()); - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) flag_signal(conn.second, true, true, true, false, false); } } @@ -92,11 +92,11 @@ struct SubmodWorker if (submod.cells.count(cell) > 0) continue; if (ct.cell_known(cell->type)) { - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) flag_signal(conn.second, false, false, false, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first)); } else { flag_found_something = false; - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) flag_signal(conn.second, false, false, false, true, true); if (flag_found_something) log("WARNING: Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str()); @@ -163,7 +163,7 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell); - for (auto &conn : new_cell->connections) + for (auto &conn : new_cell->connections_) for (auto &bit : conn.second) if (bit.wire != NULL) { assert(wire_flags.count(bit.wire) > 0); @@ -180,7 +180,7 @@ struct SubmodWorker RTLIL::Wire *old_wire = it.first; RTLIL::Wire *new_wire = it.second.new_wire; if (new_wire->port_id > 0) - new_cell->connections[new_wire->name] = RTLIL::SigSpec(old_wire); + new_cell->connections_[new_wire->name] = RTLIL::SigSpec(old_wire); } } diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 116b704e..b4242f25 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -76,12 +76,12 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) wr_ports++; del_cells.push_back(cell); - RTLIL::SigSpec clk = cell->connections["\\CLK"]; + RTLIL::SigSpec clk = cell->connections_["\\CLK"]; RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); - RTLIL::SigSpec addr = cell->connections["\\ADDR"]; - RTLIL::SigSpec data = cell->connections["\\DATA"]; - RTLIL::SigSpec en = cell->connections["\\EN"]; + RTLIL::SigSpec addr = cell->connections_["\\ADDR"]; + RTLIL::SigSpec data = cell->connections_["\\DATA"]; + RTLIL::SigSpec en = cell->connections_["\\EN"]; clk.extend(1, false); clk_enable.extend(1, false); @@ -103,12 +103,12 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) rd_ports++; del_cells.push_back(cell); - RTLIL::SigSpec clk = cell->connections["\\CLK"]; + RTLIL::SigSpec clk = cell->connections_["\\CLK"]; RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); RTLIL::SigSpec transparent = RTLIL::SigSpec(cell->parameters["\\TRANSPARENT"]); - RTLIL::SigSpec addr = cell->connections["\\ADDR"]; - RTLIL::SigSpec data = cell->connections["\\DATA"]; + RTLIL::SigSpec addr = cell->connections_["\\ADDR"]; + RTLIL::SigSpec data = cell->connections_["\\DATA"]; clk.extend(1, false); clk_enable.extend(1, false); @@ -147,10 +147,10 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : RTLIL::Const(0, 0); mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : RTLIL::Const(0, 0); - mem->connections["\\WR_CLK"] = sig_wr_clk; - mem->connections["\\WR_ADDR"] = sig_wr_addr; - mem->connections["\\WR_DATA"] = sig_wr_data; - mem->connections["\\WR_EN"] = sig_wr_en; + mem->connections_["\\WR_CLK"] = sig_wr_clk; + mem->connections_["\\WR_ADDR"] = sig_wr_addr; + mem->connections_["\\WR_DATA"] = sig_wr_data; + mem->connections_["\\WR_EN"] = sig_wr_en; assert(sig_rd_clk.size() == rd_ports); assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); @@ -163,9 +163,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : RTLIL::Const(0, 0); mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : RTLIL::Const(0, 0); - mem->connections["\\RD_CLK"] = sig_rd_clk; - mem->connections["\\RD_ADDR"] = sig_rd_addr; - mem->connections["\\RD_DATA"] = sig_rd_data; + mem->connections_["\\RD_CLK"] = sig_rd_clk; + mem->connections_["\\RD_ADDR"] = sig_rd_addr; + mem->connections_["\\RD_DATA"] = sig_rd_data; for (auto c : del_cells) module->remove(c); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 56915776..63f7d052 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -25,7 +25,7 @@ static void normalize_sig(RTLIL::Module *module, RTLIL::SigSpec &sig) { - for (auto &conn : module->connections) + for (auto &conn : module->connections_) sig.replace(conn.first, conn.second); } @@ -46,21 +46,21 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI continue; if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - if (cell->connections["\\CLK"] != clk) + if (cell->connections_["\\CLK"] != clk) continue; if (cell->parameters["\\CLK_POLARITY"].as_bool() != clk_polarity) continue; } - RTLIL::SigSpec q_norm = cell->connections[after ? "\\D" : "\\Q"]; + RTLIL::SigSpec q_norm = cell->connections_[after ? "\\D" : "\\Q"]; normalize_sig(module, q_norm); - RTLIL::SigSpec d = q_norm.extract(bit, &cell->connections[after ? "\\Q" : "\\D"]); + RTLIL::SigSpec d = q_norm.extract(bit, &cell->connections_[after ? "\\Q" : "\\D"]); if (d.size() != 1) continue; bit = d; - clk = cell->connections["\\CLK"]; + clk = cell->connections_["\\CLK"]; clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); goto replaced_this_bit; } @@ -79,29 +79,29 @@ static void handle_wr_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec clk = RTLIL::SigSpec(RTLIL::State::Sx); bool clk_polarity = 0; - RTLIL::SigSpec sig_addr = cell->connections["\\ADDR"]; + RTLIL::SigSpec sig_addr = cell->connections_["\\ADDR"]; if (!find_sig_before_dff(module, sig_addr, clk, clk_polarity)) { log("no (compatible) $dff for address input found.\n"); return; } - RTLIL::SigSpec sig_data = cell->connections["\\DATA"]; + RTLIL::SigSpec sig_data = cell->connections_["\\DATA"]; if (!find_sig_before_dff(module, sig_data, clk, clk_polarity)) { log("no (compatible) $dff for data input found.\n"); return; } - RTLIL::SigSpec sig_en = cell->connections["\\EN"]; + RTLIL::SigSpec sig_en = cell->connections_["\\EN"]; if (!find_sig_before_dff(module, sig_en, clk, clk_polarity)) { log("no (compatible) $dff for enable input found.\n"); return; } if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - cell->connections["\\CLK"] = clk; - cell->connections["\\ADDR"] = sig_addr; - cell->connections["\\DATA"] = sig_data; - cell->connections["\\EN"] = sig_en; + cell->connections_["\\CLK"] = clk; + cell->connections_["\\ADDR"] = sig_addr; + cell->connections_["\\DATA"] = sig_data; + cell->connections_["\\EN"] = sig_en; cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); log("merged $dff to cell.\n"); @@ -128,7 +128,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$dff") - cell->connections["\\Q"].replace(sig, newsig); + cell->connections_["\\Q"].replace(sig, newsig); } } @@ -139,13 +139,13 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) bool clk_polarity = 0; RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_data = cell->connections["\\DATA"]; + RTLIL::SigSpec sig_data = cell->connections_["\\DATA"]; if (find_sig_before_dff(module, sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) { disconnect_dff(module, sig_data); - cell->connections["\\CLK"] = clk_data; - cell->connections["\\DATA"] = sig_data; + cell->connections_["\\CLK"] = clk_data; + cell->connections_["\\DATA"] = sig_data; cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0); @@ -154,12 +154,12 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_addr = cell->connections["\\ADDR"]; + RTLIL::SigSpec sig_addr = cell->connections_["\\ADDR"]; if (find_sig_before_dff(module, sig_addr, clk_addr, clk_polarity) && clk_addr != RTLIL::SigSpec(RTLIL::State::Sx)) { - cell->connections["\\CLK"] = clk_addr; - cell->connections["\\ADDR"] = sig_addr; + cell->connections_["\\CLK"] = clk_addr; + cell->connections_["\\ADDR"] = sig_addr; cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); cell->parameters["\\TRANSPARENT"] = RTLIL::Const(1); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index b5f0520a..a626b5af 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -62,20 +62,20 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) } // all write ports must share the same clock - RTLIL::SigSpec clocks = cell->connections["\\WR_CLK"]; + RTLIL::SigSpec clocks = cell->connections_["\\WR_CLK"]; RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"]; RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"]; RTLIL::SigSpec refclock; RTLIL::State refclock_pol = RTLIL::State::Sx; for (int i = 0; i < clocks.size(); i++) { - RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(i * mem_width, mem_width); + RTLIL::SigSpec wr_en = cell->connections_["\\WR_EN"].extract(i * mem_width, mem_width); if (wr_en.is_fully_const() && !wr_en.as_bool()) { static_ports.insert(i); continue; } if (clocks_en.bits[i] != RTLIL::State::S1) { - RTLIL::SigSpec wr_addr = cell->connections["\\WR_ADDR"].extract(i*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->connections["\\WR_DATA"].extract(i*mem_width, mem_width); + RTLIL::SigSpec wr_addr = cell->connections_["\\WR_ADDR"].extract(i*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->connections_["\\WR_DATA"].extract(i*mem_width, mem_width); if (wr_addr.is_fully_const()) { // FIXME: Actually we should check for wr_en.is_fully_const() also and // create a $adff cell with this ports wr_en input as reset pin when wr_en @@ -120,10 +120,10 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; if (clocks_pol.bits.size() > 0) { c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]); - c->connections["\\CLK"] = clocks.extract(0, 1); + c->connections_["\\CLK"] = clocks.extract(0, 1); } else { c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1); - c->connections["\\CLK"] = RTLIL::SigSpec(RTLIL::State::S0); + c->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::S0); } RTLIL::Wire *w_in = new RTLIL::Wire; @@ -131,7 +131,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) w_in->width = mem_width; module->wires[w_in->name] = w_in; data_reg_in.push_back(RTLIL::SigSpec(w_in)); - c->connections["\\D"] = data_reg_in.back(); + c->connections_["\\D"] = data_reg_in.back(); RTLIL::Wire *w_out = new RTLIL::Wire; w_out->name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); @@ -141,7 +141,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) w_out->start_offset = mem_offset; module->wires[w_out->name] = w_out; data_reg_out.push_back(RTLIL::SigSpec(w_out)); - c->connections["\\Q"] = data_reg_out.back(); + c->connections_["\\Q"] = data_reg_out.back(); } } @@ -151,10 +151,10 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++) { - RTLIL::SigSpec rd_addr = cell->connections["\\RD_ADDR"].extract(i*mem_abits, mem_abits); + RTLIL::SigSpec rd_addr = cell->connections_["\\RD_ADDR"].extract(i*mem_abits, mem_abits); std::vector rd_signals; - rd_signals.push_back(cell->connections["\\RD_DATA"].extract(i*mem_width, mem_width)); + rd_signals.push_back(cell->connections_["\\RD_DATA"].extract(i*mem_width, mem_width)); if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1) { @@ -163,8 +163,8 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = RTLIL::Const(mem_abits); c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->connections["\\CLK"] = cell->connections["\\RD_CLK"].extract(i, 1); - c->connections["\\D"] = rd_addr; + c->connections_["\\CLK"] = cell->connections_["\\RD_CLK"].extract(i, 1); + c->connections_["\\D"] = rd_addr; count_dff++; RTLIL::Wire *w = new RTLIL::Wire; @@ -172,7 +172,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) w->width = mem_abits; module->wires[w->name] = w; - c->connections["\\Q"] = RTLIL::SigSpec(w); + c->connections_["\\Q"] = RTLIL::SigSpec(w); rd_addr = RTLIL::SigSpec(w); } else @@ -180,8 +180,8 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->connections["\\CLK"] = cell->connections["\\RD_CLK"].extract(i, 1); - c->connections["\\Q"] = rd_signals.back(); + c->connections_["\\CLK"] = cell->connections_["\\RD_CLK"].extract(i, 1); + c->connections_["\\Q"] = rd_signals.back(); count_dff++; RTLIL::Wire *w = new RTLIL::Wire; @@ -191,7 +191,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) rd_signals.clear(); rd_signals.push_back(RTLIL::SigSpec(w)); - c->connections["\\D"] = rd_signals.back(); + c->connections_["\\D"] = rd_signals.back(); } } @@ -203,31 +203,31 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) { RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; - c->connections["\\Y"] = rd_signals[k]; - c->connections["\\S"] = rd_addr.extract(mem_abits-j-1, 1); + c->connections_["\\Y"] = rd_signals[k]; + c->connections_["\\S"] = rd_addr.extract(mem_abits-j-1, 1); count_mux++; RTLIL::Wire *w = new RTLIL::Wire; w->name = genid(cell->name, "$rdmux", i, "", j, "", k, "$a"); w->width = mem_width; module->wires[w->name] = w; - c->connections["\\A"] = RTLIL::SigSpec(w); + c->connections_["\\A"] = RTLIL::SigSpec(w); w = new RTLIL::Wire; w->name = genid(cell->name, "$rdmux", i, "", j, "", k, "$b"); w->width = mem_width; module->wires[w->name] = w; - c->connections["\\B"] = RTLIL::SigSpec(w); + c->connections_["\\B"] = RTLIL::SigSpec(w); - next_rd_signals.push_back(c->connections["\\A"]); - next_rd_signals.push_back(c->connections["\\B"]); + next_rd_signals.push_back(c->connections_["\\A"]); + next_rd_signals.push_back(c->connections_["\\B"]); } next_rd_signals.swap(rd_signals); } for (int j = 0; j < mem_size; j++) - module->connections.push_back(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); + module->connections_.push_back(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); } log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); @@ -241,9 +241,9 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++) { - RTLIL::SigSpec wr_addr = cell->connections["\\WR_ADDR"].extract(j*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->connections["\\WR_DATA"].extract(j*mem_width, mem_width); - RTLIL::SigSpec wr_en = cell->connections["\\WR_EN"].extract(j*mem_width, mem_width); + RTLIL::SigSpec wr_addr = cell->connections_["\\WR_ADDR"].extract(j*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->connections_["\\WR_DATA"].extract(j*mem_width, mem_width); + RTLIL::SigSpec wr_en = cell->connections_["\\WR_EN"].extract(j*mem_width, mem_width); RTLIL::Cell *c = module->addCell(genid(cell->name, "$wreq", i, "", j), "$eq"); c->parameters["\\A_SIGNED"] = RTLIL::Const(0); @@ -251,14 +251,14 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\A_WIDTH"] = cell->parameters["\\ABITS"]; c->parameters["\\B_WIDTH"] = cell->parameters["\\ABITS"]; c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->connections["\\A"] = RTLIL::SigSpec(i, mem_abits); - c->connections["\\B"] = wr_addr; + c->connections_["\\A"] = RTLIL::SigSpec(i, mem_abits); + c->connections_["\\B"] = wr_addr; count_wrmux++; RTLIL::Wire *w_seladdr = new RTLIL::Wire; w_seladdr->name = genid(cell->name, "$wreq", i, "", j, "$y"); module->wires[w_seladdr->name] = w_seladdr; - c->connections["\\Y"] = w_seladdr; + c->connections_["\\Y"] = w_seladdr; int wr_offset = 0; while (wr_offset < wr_en.size()) @@ -283,33 +283,33 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\A_WIDTH"] = RTLIL::Const(1); c->parameters["\\B_WIDTH"] = RTLIL::Const(1); c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->connections["\\A"] = w; - c->connections["\\B"] = wr_bit; + c->connections_["\\A"] = w; + c->connections_["\\B"] = wr_bit; w = new RTLIL::Wire; w->name = genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"); module->wires[w->name] = w; - c->connections["\\Y"] = RTLIL::SigSpec(w); + c->connections_["\\Y"] = RTLIL::SigSpec(w); } c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); c->parameters["\\WIDTH"] = wr_width; - c->connections["\\A"] = sig.extract(wr_offset, wr_width); - c->connections["\\B"] = wr_data.extract(wr_offset, wr_width); - c->connections["\\S"] = RTLIL::SigSpec(w); + c->connections_["\\A"] = sig.extract(wr_offset, wr_width); + c->connections_["\\B"] = wr_data.extract(wr_offset, wr_width); + c->connections_["\\S"] = RTLIL::SigSpec(w); w = new RTLIL::Wire; w->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"); w->width = wr_width; module->wires[w->name] = w; - c->connections["\\Y"] = w; + c->connections_["\\Y"] = w; sig.replace(wr_offset, w); wr_offset += wr_width; } } - module->connections.push_back(RTLIL::SigSig(data_reg_in[i], sig)); + module->connections_.push_back(RTLIL::SigSig(data_reg_in[i], sig)); } log(" write interface: %d blocks of $eq, $and and $mux cells.\n", count_wrmux); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 63f6b14f..919e24a4 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -64,16 +64,16 @@ struct MemoryShareWorker RTLIL::Cell *cell = sig_to_mux.at(sig).first; int bit_idx = sig_to_mux.at(sig).second; - std::vector sig_a = sigmap(cell->connections.at("\\A")); - std::vector sig_b = sigmap(cell->connections.at("\\B")); - std::vector sig_s = sigmap(cell->connections.at("\\S")); - std::vector sig_y = sigmap(cell->connections.at("\\Y")); + std::vector sig_a = sigmap(cell->connections_.at("\\A")); + std::vector sig_b = sigmap(cell->connections_.at("\\B")); + std::vector sig_s = sigmap(cell->connections_.at("\\S")); + std::vector sig_y = sigmap(cell->connections_.at("\\Y")); log_assert(sig_y.at(bit_idx) == sig); for (int i = 0; i < int(sig_s.size()); i++) if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) - cell->connections.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->connections_.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); return false; } @@ -87,7 +87,7 @@ struct MemoryShareWorker new_state[sig_s[i]] = true; if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) - cell->connections.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->connections_.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); } std::map new_state = state; @@ -95,7 +95,7 @@ struct MemoryShareWorker new_state[sig_s[i]] = false; if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) - cell->connections.at("\\A").replace(bit_idx, RTLIL::State::Sx); + cell->connections_.at("\\A").replace(bit_idx, RTLIL::State::Sx); return false; } @@ -141,10 +141,10 @@ struct MemoryShareWorker if (cell->type == "$mux" || cell->type == "$pmux") { - std::vector sig_a = sigmap(cell->connections.at("\\A")); - std::vector sig_b = sigmap(cell->connections.at("\\B")); - std::vector sig_s = sigmap(cell->connections.at("\\S")); - std::vector sig_y = sigmap(cell->connections.at("\\Y")); + std::vector sig_a = sigmap(cell->connections_.at("\\A")); + std::vector sig_b = sigmap(cell->connections_.at("\\B")); + std::vector sig_s = sigmap(cell->connections_.at("\\S")); + std::vector sig_y = sigmap(cell->connections_.at("\\Y")); non_feedback_nets.insert(sig_s.begin(), sig_s.end()); @@ -161,7 +161,7 @@ struct MemoryShareWorker cell->parameters.at("\\MEMID").decode_string() == memid) ignore_data_port = true; - for (auto conn : cell_it.second->connections) + for (auto conn : cell_it.second->connections_) { if (ignore_data_port && conn.first == "\\DATA") continue; @@ -191,8 +191,8 @@ struct MemoryShareWorker if (cell->parameters.at("\\CLK_ENABLE").as_bool()) continue; - RTLIL::SigSpec sig_addr = sigmap(cell->connections.at("\\ADDR")); - std::vector sig_data = sigmap(cell->connections.at("\\DATA")); + RTLIL::SigSpec sig_addr = sigmap(cell->connections_.at("\\ADDR")); + std::vector sig_data = sigmap(cell->connections_.at("\\DATA")); for (int i = 0; i < int(sig_data.size()); i++) if (non_feedback_nets.count(sig_data[i])) @@ -212,14 +212,14 @@ struct MemoryShareWorker for (auto cell : wr_ports) { - RTLIL::SigSpec sig_addr = sigmap_xmux(cell->connections.at("\\ADDR")); + RTLIL::SigSpec sig_addr = sigmap_xmux(cell->connections_.at("\\ADDR")); if (!async_rd_bits.count(sig_addr)) continue; log(" Analyzing write port %s.\n", log_id(cell)); - std::vector cell_data = cell->connections.at("\\DATA"); - std::vector cell_en = cell->connections.at("\\EN"); + std::vector cell_data = cell->connections_.at("\\DATA"); + std::vector cell_en = cell->connections_.at("\\EN"); int created_conditions = 0; for (int i = 0; i < int(cell_data.size()); i++) @@ -239,7 +239,7 @@ struct MemoryShareWorker if (created_conditions) { log(" Added enable logic for %d different cases.\n", created_conditions); - cell->connections.at("\\EN") = cell_en; + cell->connections_.at("\\EN") = cell_en; } } } @@ -357,15 +357,15 @@ struct MemoryShareWorker for (int i = 0; i < int(wr_ports.size()); i++) { RTLIL::Cell *cell = wr_ports.at(i); - RTLIL::SigSpec addr = sigmap_xmux(cell->connections.at("\\ADDR")); + RTLIL::SigSpec addr = sigmap_xmux(cell->connections_.at("\\ADDR")); if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->connections.at("\\CLK")) != cache_clk || + (cache_clk_enable && (sigmap(cell->connections_.at("\\CLK")) != cache_clk || cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) { cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); - cache_clk = sigmap(cell->connections.at("\\CLK")); + cache_clk = sigmap(cell->connections_.at("\\CLK")); last_port_by_addr.clear(); if (cache_clk_enable) @@ -377,7 +377,7 @@ struct MemoryShareWorker log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr)); log(" Active bits: "); - std::vector en_bits = sigmap(cell->connections.at("\\EN")); + std::vector en_bits = sigmap(cell->connections_.at("\\EN")); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) { active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0; @@ -399,13 +399,13 @@ struct MemoryShareWorker // Force this ports addr input to addr directly (skip don't care muxes) - cell->connections.at("\\ADDR") = addr; + cell->connections_.at("\\ADDR") = addr; // If any of the ports between `last_i' and `i' write to the same address, this // will have priority over whatever `last_i` wrote. So we need to revisit those // ports and mask the EN bits accordingly. - RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->connections.at("\\EN")); + RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->connections_.at("\\EN")); for (int j = last_i+1; j < i; j++) { @@ -420,20 +420,20 @@ struct MemoryShareWorker found_overlapping_bits_i_j: log(" Creating collosion-detect logic for port %d.\n", j); RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID); - module->addEq(NEW_ID, addr, wr_ports[j]->connections.at("\\ADDR"), is_same_addr); - merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->connections.at("\\EN"))); + module->addEq(NEW_ID, addr, wr_ports[j]->connections_.at("\\ADDR"), is_same_addr); + merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->connections_.at("\\EN"))); } } // Then we need to merge the (masked) EN and the DATA signals. - RTLIL::SigSpec merged_data = wr_ports[last_i]->connections.at("\\DATA"); + RTLIL::SigSpec merged_data = wr_ports[last_i]->connections_.at("\\DATA"); if (found_overlapping_bits) { log(" Creating logic for merging DATA and EN ports.\n"); - merge_en_data(merged_en, merged_data, sigmap(cell->connections.at("\\EN")), sigmap(cell->connections.at("\\DATA"))); + merge_en_data(merged_en, merged_data, sigmap(cell->connections_.at("\\EN")), sigmap(cell->connections_.at("\\DATA"))); } else { - RTLIL::SigSpec cell_en = sigmap(cell->connections.at("\\EN")); - RTLIL::SigSpec cell_data = sigmap(cell->connections.at("\\DATA")); + RTLIL::SigSpec cell_en = sigmap(cell->connections_.at("\\EN")); + RTLIL::SigSpec cell_data = sigmap(cell->connections_.at("\\DATA")); for (int k = 0; k < int(en_bits.size()); k++) if (!active_bits_on_port[last_i][k]) { merged_en.replace(k, cell_en.extract(k, 1)); @@ -443,14 +443,14 @@ struct MemoryShareWorker // Connect the new EN and DATA signals and remove the old write port. - cell->connections.at("\\EN") = merged_en; - cell->connections.at("\\DATA") = merged_data; + cell->connections_.at("\\EN") = merged_en; + cell->connections_.at("\\DATA") = merged_data; module->remove(wr_ports[last_i]); wr_ports[last_i] = NULL; log(" Active bits: "); - std::vector en_bits = sigmap(cell->connections.at("\\EN")); + std::vector en_bits = sigmap(cell->connections_.at("\\EN")); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) log("%c", active_bits_on_port[i][k] ? '1' : '0'); @@ -489,7 +489,7 @@ struct MemoryShareWorker std::set considered_port_pairs; for (int i = 0; i < int(wr_ports.size()); i++) { - std::vector bits = modwalker.sigmap(wr_ports[i]->connections.at("\\EN")); + std::vector bits = modwalker.sigmap(wr_ports[i]->connections_.at("\\EN")); for (auto bit : bits) if (bit == RTLIL::State::S1) goto port_is_always_active; @@ -509,12 +509,12 @@ struct MemoryShareWorker RTLIL::Cell *cell = wr_ports.at(i); if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->connections.at("\\CLK")) != cache_clk || + (cache_clk_enable && (sigmap(cell->connections_.at("\\CLK")) != cache_clk || cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) { cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); - cache_clk = sigmap(cell->connections.at("\\CLK")); + cache_clk = sigmap(cell->connections_.at("\\CLK")); } else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i)) considered_port_pairs.insert(i); @@ -542,7 +542,7 @@ struct MemoryShareWorker for (int i = 0; i < int(wr_ports.size()); i++) if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1)) { - RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->connections.at("\\EN")); + RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->connections_.at("\\EN")); port_to_sat_variable[i] = ez.expression(ez.OpOr, satgen.importSigSpec(sig)); std::vector bits = sig; @@ -585,18 +585,18 @@ struct MemoryShareWorker log(" Merging port %d into port %d.\n", i-1, i); port_to_sat_variable.at(i) = ez.OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i)); - RTLIL::SigSpec last_addr = wr_ports[i-1]->connections.at("\\ADDR"); - RTLIL::SigSpec last_data = wr_ports[i-1]->connections.at("\\DATA"); - std::vector last_en = modwalker.sigmap(wr_ports[i-1]->connections.at("\\EN")); + RTLIL::SigSpec last_addr = wr_ports[i-1]->connections_.at("\\ADDR"); + RTLIL::SigSpec last_data = wr_ports[i-1]->connections_.at("\\DATA"); + std::vector last_en = modwalker.sigmap(wr_ports[i-1]->connections_.at("\\EN")); - RTLIL::SigSpec this_addr = wr_ports[i]->connections.at("\\ADDR"); - RTLIL::SigSpec this_data = wr_ports[i]->connections.at("\\DATA"); - std::vector this_en = modwalker.sigmap(wr_ports[i]->connections.at("\\EN")); + RTLIL::SigSpec this_addr = wr_ports[i]->connections_.at("\\ADDR"); + RTLIL::SigSpec this_data = wr_ports[i]->connections_.at("\\DATA"); + std::vector this_en = modwalker.sigmap(wr_ports[i]->connections_.at("\\EN")); RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); - wr_ports[i]->connections.at("\\ADDR") = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); - wr_ports[i]->connections.at("\\DATA") = module->Mux(NEW_ID, last_data, this_data, this_en_active); + wr_ports[i]->connections_.at("\\ADDR") = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); + wr_ports[i]->connections_.at("\\DATA") = module->Mux(NEW_ID, last_data, this_data, this_en_active); std::map, int> groups_en; RTLIL::SigSpec grouped_last_en, grouped_this_en, en; @@ -614,7 +614,7 @@ struct MemoryShareWorker } module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); - wr_ports[i]->connections.at("\\EN") = en; + wr_ports[i]->connections_.at("\\EN") = en; module->remove(wr_ports[i-1]); wr_ports[i-1] = NULL; @@ -653,18 +653,18 @@ struct MemoryShareWorker if (cell->type == "$mux") { - RTLIL::SigSpec sig_a = sigmap_xmux(cell->connections.at("\\A")); - RTLIL::SigSpec sig_b = sigmap_xmux(cell->connections.at("\\B")); + RTLIL::SigSpec sig_a = sigmap_xmux(cell->connections_.at("\\A")); + RTLIL::SigSpec sig_b = sigmap_xmux(cell->connections_.at("\\B")); if (sig_a.is_fully_undef()) - sigmap_xmux.add(cell->connections.at("\\Y"), sig_b); + sigmap_xmux.add(cell->connections_.at("\\Y"), sig_b); else if (sig_b.is_fully_undef()) - sigmap_xmux.add(cell->connections.at("\\Y"), sig_a); + sigmap_xmux.add(cell->connections_.at("\\Y"), sig_a); } if (cell->type == "$mux" || cell->type == "$pmux") { - std::vector sig_y = sigmap(cell->connections.at("\\Y")); + std::vector sig_y = sigmap(cell->connections_.at("\\Y")); for (int i = 0; i < int(sig_y.size()); i++) sig_to_mux[sig_y[i]] = std::pair(cell, i); } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 97cda144..9c457ad5 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -54,9 +54,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_ENABLE")).extract(i, 1).as_const(); cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const(); cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const(); - cell->connections["\\CLK"] = memory->connections.at("\\RD_CLK").extract(i, 1); - cell->connections["\\ADDR"] = memory->connections.at("\\RD_ADDR").extract(i*abits, abits); - cell->connections["\\DATA"] = memory->connections.at("\\RD_DATA").extract(i*mem->width, mem->width); + cell->connections_["\\CLK"] = memory->connections_.at("\\RD_CLK").extract(i, 1); + cell->connections_["\\ADDR"] = memory->connections_.at("\\RD_ADDR").extract(i*abits, abits); + cell->connections_["\\DATA"] = memory->connections_.at("\\RD_DATA").extract(i*mem->width, mem->width); } for (int i = 0; i < num_wr_ports; i++) @@ -68,10 +68,10 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_ENABLE")).extract(i, 1).as_const(); cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const(); cell->parameters["\\PRIORITY"] = i; - cell->connections["\\CLK"] = memory->connections.at("\\WR_CLK").extract(i, 1); - cell->connections["\\EN"] = memory->connections.at("\\WR_EN").extract(i*mem->width, mem->width); - cell->connections["\\ADDR"] = memory->connections.at("\\WR_ADDR").extract(i*abits, abits); - cell->connections["\\DATA"] = memory->connections.at("\\WR_DATA").extract(i*mem->width, mem->width); + cell->connections_["\\CLK"] = memory->connections_.at("\\WR_CLK").extract(i, 1); + cell->connections_["\\EN"] = memory->connections_.at("\\WR_EN").extract(i*mem->width, mem->width); + cell->connections_["\\ADDR"] = memory->connections_.at("\\WR_ADDR").extract(i*abits, abits); + cell->connections_["\\DATA"] = memory->connections_.at("\\WR_DATA").extract(i*mem->width, mem->width); } module->remove(memory); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 00fa6031..30ab8814 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -40,7 +40,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) SigSet wire2driver; for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - for (auto &it2 : cell->connections) { + for (auto &it2 : cell->connections_) { if (!ct.cell_input(cell->type, it2.first)) { RTLIL::SigSpec sig = it2.second; assign_map.apply(sig); @@ -70,7 +70,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) for (auto cell : queue) unused.erase(cell); for (auto cell : queue) { - for (auto &it : cell->connections) { + for (auto &it : cell->connections_) { if (!ct.cell_output(cell->type, it.first)) { std::set cell_list; RTLIL::SigSpec sig = it.second; @@ -158,10 +158,10 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; if (ct_reg.cell_known(cell->type)) - for (auto &it2 : cell->connections) + for (auto &it2 : cell->connections_) if (ct_reg.cell_output(cell->type, it2.first)) register_signals.add(it2.second); - for (auto &it2 : cell->connections) + for (auto &it2 : cell->connections_) connected_signals.add(it2.second); } @@ -171,7 +171,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; if (ct_all.cell_known(cell->type)) - for (auto &it2 : cell->connections) + for (auto &it2 : cell->connections_) if (ct_all.cell_output(cell->type, it2.first)) direct_sigs.insert(assign_map(it2.second)); } @@ -189,13 +189,13 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } } - module->connections.clear(); + module->connections_.clear(); SigPool used_signals; SigPool used_signals_nodrivers; for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - for (auto &it2 : cell->connections) { + for (auto &it2 : cell->connections_) { assign_map.apply(it2.second); used_signals.add(it2.second); if (!ct.cell_output(cell->type, it2.first)) @@ -237,7 +237,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (new_conn.first.size() > 0) { used_signals.add(new_conn.first); used_signals.add(new_conn.second); - module->connections.push_back(new_conn); + module->connections_.push_back(new_conn); } } } else { diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index e1b6c598..2a5ec8be 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -38,7 +38,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) SigPool all_signals; for (auto &it : module->cells) - for (auto &conn : it.second->connections) { + for (auto &conn : it.second->connections_) { if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) driven_signals.add(sigmap(conn.second)); if (!ct.cell_known(it.second->type) || ct.cell_input(it.second->type, conn.first)) @@ -66,21 +66,21 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) continue; log("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c)); - module->connections.push_back(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width))); + module->connections_.push_back(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width))); OPT_DID_SOMETHING = true; } } static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { - RTLIL::SigSpec Y = cell->connections[out_port]; + RTLIL::SigSpec Y = cell->connections_[out_port]; out_val.extend_u0(Y.size(), false); log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", cell->type.c_str(), cell->name.c_str(), info.c_str(), module->name.c_str(), log_signal(Y), log_signal(out_val)); // ILANG_BACKEND::dump_cell(stderr, "--> ", cell); - module->connections.push_back(RTLIL::SigSig(Y, out_val)); + module->connections_.push_back(RTLIL::SigSig(Y, out_val)); module->remove(cell); OPT_DID_SOMETHING = true; did_something = true; @@ -88,14 +88,14 @@ static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string i static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, bool extend_u0, SigMap &sigmap) { - std::string b_name = cell->connections.count("\\B") ? "\\B" : "\\A"; + std::string b_name = cell->connections_.count("\\B") ? "\\B" : "\\A"; bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool(); bool b_signed = cell->parameters.at(b_name + "_SIGNED").as_bool(); - RTLIL::SigSpec sig_a = sigmap(cell->connections.at("\\A")); - RTLIL::SigSpec sig_b = sigmap(cell->connections.at(b_name)); - RTLIL::SigSpec sig_y = sigmap(cell->connections.at("\\Y")); + RTLIL::SigSpec sig_a = sigmap(cell->connections_.at("\\A")); + RTLIL::SigSpec sig_b = sigmap(cell->connections_.at(b_name)); + RTLIL::SigSpec sig_y = sigmap(cell->connections_.at("\\Y")); if (extend_u0) { sig_a.extend_u0(sig_y.size(), a_signed); @@ -160,21 +160,21 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); - c->connections["\\A"] = new_a; + c->connections_["\\A"] = new_a; c->parameters["\\A_WIDTH"] = new_a.size(); c->parameters["\\A_SIGNED"] = false; if (b_name == "\\B") { - c->connections["\\B"] = new_b; + c->connections_["\\B"] = new_b; c->parameters["\\B_WIDTH"] = new_b.size(); c->parameters["\\B_SIGNED"] = false; } - c->connections["\\Y"] = new_y; + c->connections_["\\Y"] = new_y; c->parameters["\\Y_WIDTH"] = new_y->width; c->check(); - module->connections.push_back(new_conn); + module->connections_.push_back(new_conn); log(" New cell `%s': A=%s", log_id(c), log_signal(new_a)); if (b_name == "\\B") @@ -203,8 +203,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (auto &cell_it : module->cells) if (design->selected(module, cell_it.second)) { if ((cell_it.second->type == "$_INV_" || cell_it.second->type == "$not" || cell_it.second->type == "$logic_not") && - cell_it.second->connections["\\A"].size() == 1 && cell_it.second->connections["\\Y"].size() == 1) - invert_map[assign_map(cell_it.second->connections["\\Y"])] = assign_map(cell_it.second->connections["\\A"]); + cell_it.second->connections_["\\A"].size() == 1 && cell_it.second->connections_["\\Y"].size() == 1) + invert_map[assign_map(cell_it.second->connections_["\\Y"])] = assign_map(cell_it.second->connections_["\\A"]); cells.push_back(cell_it.second); } @@ -222,7 +222,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$reduce_and") { - RTLIL::SigSpec sig_a = assign_map(cell->connections.at("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->connections_.at("\\A")); RTLIL::State new_a = RTLIL::State::S1; for (auto &bit : sig_a.to_sigbit_vector()) @@ -240,7 +240,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover("opt.opt_const.fine.$reduce_and"); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->connections.at("\\A") = sig_a = new_a; + cell->connections_.at("\\A") = sig_a = new_a; cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -249,7 +249,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") { - RTLIL::SigSpec sig_a = assign_map(cell->connections.at("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->connections_.at("\\A")); RTLIL::State new_a = RTLIL::State::S0; for (auto &bit : sig_a.to_sigbit_vector()) @@ -267,7 +267,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->connections.at("\\A") = sig_a = new_a; + cell->connections_.at("\\A") = sig_a = new_a; cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -276,7 +276,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$logic_and" || cell->type == "$logic_or") { - RTLIL::SigSpec sig_b = assign_map(cell->connections.at("\\B")); + RTLIL::SigSpec sig_b = assign_map(cell->connections_.at("\\B")); RTLIL::State new_b = RTLIL::State::S0; for (auto &bit : sig_b.to_sigbit_vector()) @@ -294,7 +294,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.B", "$logic_and", "$logic_or", cell->type); log("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); - cell->connections.at("\\B") = sig_b = new_b; + cell->connections_.at("\\B") = sig_b = new_b; cell->parameters.at("\\B_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -302,13 +302,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } } - if (cell->type == "$logic_or" && (assign_map(cell->connections.at("\\A")) == RTLIL::State::S1 || assign_map(cell->connections.at("\\B")) == RTLIL::State::S1)) { + if (cell->type == "$logic_or" && (assign_map(cell->connections_.at("\\A")) == RTLIL::State::S1 || assign_map(cell->connections_.at("\\B")) == RTLIL::State::S1)) { cover("opt.opt_const.one_high"); replace_cell(module, cell, "one high", "\\Y", RTLIL::State::S1); goto next_cell; } - if (cell->type == "$logic_and" && (assign_map(cell->connections.at("\\A")) == RTLIL::State::S0 || assign_map(cell->connections.at("\\B")) == RTLIL::State::S0)) { + if (cell->type == "$logic_and" && (assign_map(cell->connections_.at("\\A")) == RTLIL::State::S0 || assign_map(cell->connections_.at("\\B")) == RTLIL::State::S0)) { cover("opt.opt_const.one_low"); replace_cell(module, cell, "one low", "\\Y", RTLIL::State::S0); goto next_cell; @@ -320,8 +320,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || cell->type == "$pow") { - RTLIL::SigSpec sig_a = assign_map(cell->connections.at("\\A")); - RTLIL::SigSpec sig_b = cell->connections.count("\\B") ? assign_map(cell->connections.at("\\B")) : RTLIL::SigSpec(); + RTLIL::SigSpec sig_a = assign_map(cell->connections_.at("\\A")); + RTLIL::SigSpec sig_b = cell->connections_.count("\\B") ? assign_map(cell->connections_.at("\\B")) : RTLIL::SigSpec(); if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") sig_a = RTLIL::SigSpec(); @@ -342,31 +342,31 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); else - replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections.at("\\Y").size())); + replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections_.at("\\Y").size())); goto next_cell; } } - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections["\\Y"].size() == 1 && - invert_map.count(assign_map(cell->connections["\\A"])) != 0) { + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections_["\\Y"].size() == 1 && + invert_map.count(assign_map(cell->connections_["\\A"])) != 0) { cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); - replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections["\\A"]))); + replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections_["\\A"]))); goto next_cell; } - if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->connections["\\S"])) != 0) { + if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->connections_["\\S"])) != 0) { cover_list("opt.opt_const.invert.muxsel", "$_MUX_", "$mux", cell->type); - RTLIL::SigSpec tmp = cell->connections["\\A"]; - cell->connections["\\A"] = cell->connections["\\B"]; - cell->connections["\\B"] = tmp; - cell->connections["\\S"] = invert_map.at(assign_map(cell->connections["\\S"])); + RTLIL::SigSpec tmp = cell->connections_["\\A"]; + cell->connections_["\\A"] = cell->connections_["\\B"]; + cell->connections_["\\B"] = tmp; + cell->connections_["\\S"] = invert_map.at(assign_map(cell->connections_["\\S"])); OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } if (cell->type == "$_INV_") { - RTLIL::SigSpec input = cell->connections["\\A"]; + RTLIL::SigSpec input = cell->connections_["\\A"]; assign_map.apply(input); if (input.match("1")) ACTION_DO_Y(0); if (input.match("0")) ACTION_DO_Y(1); @@ -375,8 +375,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_AND_") { RTLIL::SigSpec input; - input.append(cell->connections["\\B"]); - input.append(cell->connections["\\A"]); + input.append(cell->connections_["\\B"]); + input.append(cell->connections_["\\A"]); assign_map.apply(input); if (input.match(" 0")) ACTION_DO_Y(0); if (input.match("0 ")) ACTION_DO_Y(0); @@ -394,8 +394,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_OR_") { RTLIL::SigSpec input; - input.append(cell->connections["\\B"]); - input.append(cell->connections["\\A"]); + input.append(cell->connections_["\\B"]); + input.append(cell->connections_["\\A"]); assign_map.apply(input); if (input.match(" 1")) ACTION_DO_Y(1); if (input.match("1 ")) ACTION_DO_Y(1); @@ -413,8 +413,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_XOR_") { RTLIL::SigSpec input; - input.append(cell->connections["\\B"]); - input.append(cell->connections["\\A"]); + input.append(cell->connections_["\\B"]); + input.append(cell->connections_["\\A"]); assign_map.apply(input); if (input.match("00")) ACTION_DO_Y(0); if (input.match("01")) ACTION_DO_Y(1); @@ -428,9 +428,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_MUX_") { RTLIL::SigSpec input; - input.append(cell->connections["\\S"]); - input.append(cell->connections["\\B"]); - input.append(cell->connections["\\A"]); + input.append(cell->connections_["\\S"]); + input.append(cell->connections_["\\B"]); + input.append(cell->connections_["\\A"]); assign_map.apply(input); if (input.extract(2, 1) == input.extract(1, 1)) ACTION_DO("\\Y", input.extract(2, 1)); @@ -440,9 +440,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (input.match("10 ")) { cover("opt.opt_const.mux_to_inv"); cell->type = "$_INV_"; - cell->connections["\\A"] = input.extract(0, 1); - cell->connections.erase("\\B"); - cell->connections.erase("\\S"); + cell->connections_["\\A"] = input.extract(0, 1); + cell->connections_.erase("\\B"); + cell->connections_.erase("\\S"); goto next_cell; } if (input.match("11 ")) ACTION_DO_Y(1); @@ -459,8 +459,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex") { - RTLIL::SigSpec a = cell->connections["\\A"]; - RTLIL::SigSpec b = cell->connections["\\B"]; + RTLIL::SigSpec a = cell->connections_["\\A"]; + RTLIL::SigSpec b = cell->connections_["\\B"]; if (cell->parameters["\\A_WIDTH"].as_int() != cell->parameters["\\B_WIDTH"].as_int()) { int width = std::max(cell->parameters["\\A_WIDTH"].as_int(), cell->parameters["\\B_WIDTH"].as_int()); @@ -495,8 +495,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (new_a.size() < a.size() || new_b.size() < b.size()) { cover_list("opt.opt_const.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type); - cell->connections["\\A"] = new_a; - cell->connections["\\B"] = new_b; + cell->connections_["\\A"] = new_a; + cell->connections_["\\B"] = new_b; cell->parameters["\\A_WIDTH"] = new_a.size(); cell->parameters["\\B_WIDTH"] = new_b.size(); } @@ -505,24 +505,24 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->type == "$eq" || cell->type == "$ne") && cell->parameters["\\Y_WIDTH"].as_int() == 1 && cell->parameters["\\A_WIDTH"].as_int() == 1 && cell->parameters["\\B_WIDTH"].as_int() == 1) { - RTLIL::SigSpec a = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + RTLIL::SigSpec a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); if (a.is_fully_const()) { cover_list("opt.opt_const.eqneq.swapconst", "$eq", "$ne", cell->type); - std::swap(cell->connections["\\A"], cell->connections["\\B"]); + std::swap(cell->connections_["\\A"], cell->connections_["\\B"]); } if (b.is_fully_const()) { if (b.as_bool() == (cell->type == "$eq")) { RTLIL::SigSpec input = b; - ACTION_DO("\\Y", cell->connections["\\A"]); + ACTION_DO("\\Y", cell->connections_["\\A"]); } else { cover_list("opt.opt_const.eqneq.isnot", "$eq", "$ne", cell->type); cell->type = "$not"; cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); - cell->connections.erase("\\B"); + cell->connections_.erase("\\B"); } goto next_cell; } @@ -536,8 +536,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$or" || cell->type == "$xor") { - RTLIL::SigSpec a = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + RTLIL::SigSpec a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); if (cell->type != "$sub" && a.is_fully_const() && a.as_bool() == false) identity_wrt_b = true; @@ -548,7 +548,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { - RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); if (b.is_fully_const() && b.as_bool() == false) identity_wrt_a = true, identity_bu0 = true; @@ -556,8 +556,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$mul") { - RTLIL::SigSpec a = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + RTLIL::SigSpec a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); if (a.is_fully_const() && a.size() <= 32 && a.as_int() == 1) identity_wrt_b = true; @@ -568,7 +568,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$div") { - RTLIL::SigSpec b = assign_map(cell->connections["\\B"]); + RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) identity_wrt_a = true; @@ -585,13 +585,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); if (!identity_wrt_a) { - cell->connections.at("\\A") = cell->connections.at("\\B"); + cell->connections_.at("\\A") = cell->connections_.at("\\B"); cell->parameters.at("\\A_WIDTH") = cell->parameters.at("\\B_WIDTH"); cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); } cell->type = identity_bu0 ? "$bu0" : "$pos"; - cell->connections.erase("\\B"); + cell->connections_.erase("\\B"); cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); cell->check(); @@ -603,18 +603,18 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->connections["\\A"] == RTLIL::SigSpec(0, 1) && cell->connections["\\B"] == RTLIL::SigSpec(1, 1)) { + cell->connections_["\\A"] == RTLIL::SigSpec(0, 1) && cell->connections_["\\B"] == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); - replace_cell(module, cell, "mux_bool", "\\Y", cell->connections["\\S"]); + replace_cell(module, cell, "mux_bool", "\\Y", cell->connections_["\\S"]); goto next_cell; } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->connections["\\A"] == RTLIL::SigSpec(1, 1) && cell->connections["\\B"] == RTLIL::SigSpec(0, 1)) { + cell->connections_["\\A"] == RTLIL::SigSpec(1, 1) && cell->connections_["\\B"] == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type); - cell->connections["\\A"] = cell->connections["\\S"]; - cell->connections.erase("\\B"); - cell->connections.erase("\\S"); + cell->connections_["\\A"] = cell->connections_["\\S"]; + cell->connections_.erase("\\B"); + cell->connections_.erase("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\Y_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -628,10 +628,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections["\\A"] == RTLIL::SigSpec(0, 1)) { + if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections_["\\A"] == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type); - cell->connections["\\A"] = cell->connections["\\S"]; - cell->connections.erase("\\S"); + cell->connections_["\\A"] = cell->connections_["\\S"]; + cell->connections_.erase("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -647,10 +647,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections["\\B"] == RTLIL::SigSpec(1, 1)) { + if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections_["\\B"] == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type); - cell->connections["\\B"] = cell->connections["\\S"]; - cell->connections.erase("\\S"); + cell->connections_["\\B"] = cell->connections_["\\S"]; + cell->connections_.erase("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -668,22 +668,22 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->connections.at("\\A").size(); - if ((cell->connections.at("\\A").is_fully_undef() && cell->connections.at("\\B").is_fully_undef()) || - cell->connections.at("\\S").is_fully_undef()) { + int width = cell->connections_.at("\\A").size(); + if ((cell->connections_.at("\\A").is_fully_undef() && cell->connections_.at("\\B").is_fully_undef()) || + cell->connections_.at("\\S").is_fully_undef()) { cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); - replace_cell(module, cell, "mux_undef", "\\Y", cell->connections.at("\\A")); + replace_cell(module, cell, "mux_undef", "\\Y", cell->connections_.at("\\A")); goto next_cell; } - for (int i = 0; i < cell->connections.at("\\S").size(); i++) { - RTLIL::SigSpec old_b = cell->connections.at("\\B").extract(i*width, width); - RTLIL::SigSpec old_s = cell->connections.at("\\S").extract(i, 1); + for (int i = 0; i < cell->connections_.at("\\S").size(); i++) { + RTLIL::SigSpec old_b = cell->connections_.at("\\B").extract(i*width, width); + RTLIL::SigSpec old_s = cell->connections_.at("\\S").extract(i, 1); if (old_b.is_fully_undef() || old_s.is_fully_undef()) continue; new_b.append(old_b); new_s.append(old_s); } - new_a = cell->connections.at("\\A"); + new_a = cell->connections_.at("\\A"); if (new_a.is_fully_undef() && new_s.size() > 0) { new_a = new_b.extract((new_s.size()-1)*width, width); new_b = new_b.extract(0, (new_s.size()-1)*width); @@ -699,11 +699,11 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo replace_cell(module, cell, "mux_sel01", "\\Y", new_s); goto next_cell; } - if (cell->connections.at("\\S").size() != new_s.size()) { + if (cell->connections_.at("\\S").size() != new_s.size()) { cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type); - cell->connections.at("\\A") = new_a; - cell->connections.at("\\B") = new_b; - cell->connections.at("\\S") = new_s; + cell->connections_.at("\\A") = new_a; + cell->connections_.at("\\B") = new_b; + cell->connections_.at("\\S") = new_s; if (new_s.size() > 1) { cell->type = "$pmux"; cell->parameters["\\S_WIDTH"] = new_s.size(); @@ -718,7 +718,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo #define FOLD_1ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->connections["\\A"]; \ + RTLIL::SigSpec a = cell->connections_["\\A"]; \ assign_map.apply(a); \ if (a.is_fully_const()) { \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ @@ -732,8 +732,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } #define FOLD_2ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->connections["\\A"]; \ - RTLIL::SigSpec b = cell->connections["\\B"]; \ + RTLIL::SigSpec a = cell->connections_["\\A"]; \ + RTLIL::SigSpec b = cell->connections_["\\B"]; \ assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \ @@ -787,13 +787,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo // be very conservative with optimizing $mux cells as we do not want to break mux trees if (cell->type == "$mux") { - RTLIL::SigSpec input = assign_map(cell->connections["\\S"]); - RTLIL::SigSpec inA = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec inB = assign_map(cell->connections["\\B"]); + RTLIL::SigSpec input = assign_map(cell->connections_["\\S"]); + RTLIL::SigSpec inA = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec inB = assign_map(cell->connections_["\\B"]); if (input.is_fully_const()) - ACTION_DO("\\Y", input.as_bool() ? cell->connections["\\B"] : cell->connections["\\A"]); + ACTION_DO("\\Y", input.as_bool() ? cell->connections_["\\B"] : cell->connections_["\\A"]); else if (inA == inB) - ACTION_DO("\\Y", cell->connections["\\A"]); + ACTION_DO("\\Y", cell->connections_["\\A"]); } if (!keepdc && cell->type == "$mul") @@ -802,9 +802,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo bool b_signed = cell->parameters["\\B_SIGNED"].as_bool(); bool swapped_ab = false; - RTLIL::SigSpec sig_a = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections["\\B"]); - RTLIL::SigSpec sig_y = assign_map(cell->connections["\\Y"]); + RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec sig_y = assign_map(cell->connections_["\\Y"]); if (sig_b.is_fully_const() && sig_b.size() <= 32) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; @@ -820,7 +820,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo log("Replacing multiply-by-zero cell `%s' in module `%s' with zero-driver.\n", cell->name.c_str(), module->name.c_str()); - module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); module->remove(cell); OPT_DID_SOMETHING = true; @@ -840,7 +840,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo a_val, cell->name.c_str(), module->name.c_str(), i); if (!swapped_ab) { - cell->connections["\\A"] = cell->connections["\\B"]; + cell->connections_["\\A"] = cell->connections_["\\B"]; cell->parameters["\\A_WIDTH"] = cell->parameters["\\B_WIDTH"]; cell->parameters["\\A_SIGNED"] = cell->parameters["\\B_SIGNED"]; } @@ -853,7 +853,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$shl"; cell->parameters["\\B_WIDTH"] = SIZE(new_b); cell->parameters["\\B_SIGNED"] = false; - cell->connections["\\B"] = new_b; + cell->connections_["\\B"] = new_b; cell->check(); OPT_DID_SOMETHING = true; diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 750a9d41..33e66e07 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -88,10 +88,10 @@ struct OptMuxtreeWorker RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") { - RTLIL::SigSpec sig_a = cell->connections["\\A"]; - RTLIL::SigSpec sig_b = cell->connections["\\B"]; - RTLIL::SigSpec sig_s = cell->connections["\\S"]; - RTLIL::SigSpec sig_y = cell->connections["\\Y"]; + RTLIL::SigSpec sig_a = cell->connections_["\\A"]; + RTLIL::SigSpec sig_b = cell->connections_["\\B"]; + RTLIL::SigSpec sig_s = cell->connections_["\\S"]; + RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; muxinfo_t muxinfo; muxinfo.cell = cell; @@ -130,7 +130,7 @@ struct OptMuxtreeWorker } else { - for (auto &it : cell->connections) { + for (auto &it : cell->connections_) { for (int idx : sig2bits(it.second)) bit2info[idx].seen_non_mux = true; } @@ -194,10 +194,10 @@ struct OptMuxtreeWorker continue; } - RTLIL::SigSpec sig_a = mi.cell->connections["\\A"]; - RTLIL::SigSpec sig_b = mi.cell->connections["\\B"]; - RTLIL::SigSpec sig_s = mi.cell->connections["\\S"]; - RTLIL::SigSpec sig_y = mi.cell->connections["\\Y"]; + RTLIL::SigSpec sig_a = mi.cell->connections_["\\A"]; + RTLIL::SigSpec sig_b = mi.cell->connections_["\\B"]; + RTLIL::SigSpec sig_s = mi.cell->connections_["\\S"]; + RTLIL::SigSpec sig_y = mi.cell->connections_["\\Y"]; RTLIL::SigSpec sig_ports = sig_b; sig_ports.append(sig_a); @@ -205,7 +205,7 @@ struct OptMuxtreeWorker if (live_ports.size() == 1) { RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.size(), sig_a.size()); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_in)); + module->connections_.push_back(RTLIL::SigSig(sig_y, sig_in)); module->remove(mi.cell); } else @@ -222,9 +222,9 @@ struct OptMuxtreeWorker } } - mi.cell->connections["\\A"] = new_sig_a; - mi.cell->connections["\\B"] = new_sig_b; - mi.cell->connections["\\S"] = new_sig_s; + mi.cell->connections_["\\A"] = new_sig_a; + mi.cell->connections_["\\B"] = new_sig_b; + mi.cell->connections_["\\S"] = new_sig_s; if (new_sig_s.size() == 1) { mi.cell->type = "$mux"; mi.cell->parameters.erase("\\S_WIDTH"); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 073af308..7a7f02f6 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -43,7 +43,7 @@ struct OptReduceWorker return; cells.erase(cell); - RTLIL::SigSpec sig_a = assign_map(cell->connections["\\A"]); + RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); std::set new_sig_a_bits; for (auto &bit : sig_a.to_sigbit_set()) @@ -73,8 +73,8 @@ struct OptReduceWorker for (auto child_cell : drivers.find(bit)) { if (child_cell->type == cell->type) { opt_reduce(cells, drivers, child_cell); - if (child_cell->connections["\\Y"][0] == bit) { - std::set child_sig_a_bits = assign_map(child_cell->connections["\\A"]).to_sigbit_set(); + if (child_cell->connections_["\\Y"][0] == bit) { + std::set child_sig_a_bits = assign_map(child_cell->connections_["\\A"]).to_sigbit_set(); new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); } else new_sig_a_bits.insert(RTLIL::State::S0); @@ -87,23 +87,23 @@ struct OptReduceWorker RTLIL::SigSpec new_sig_a(new_sig_a_bits); - if (new_sig_a != sig_a || sig_a.size() != cell->connections["\\A"].size()) { + if (new_sig_a != sig_a || sig_a.size() != cell->connections_["\\A"].size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; OPT_DID_SOMETHING = true; total_count++; } - cell->connections["\\A"] = new_sig_a; + cell->connections_["\\A"] = new_sig_a; cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.size()); return; } void opt_mux(RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = assign_map(cell->connections["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections["\\B"]); - RTLIL::SigSpec sig_s = assign_map(cell->connections["\\S"]); + RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec sig_s = assign_map(cell->connections_["\\S"]); RTLIL::SigSpec new_sig_b, new_sig_s; std::set handled_sig; @@ -125,14 +125,14 @@ struct OptReduceWorker if (this_s.size() > 1) { RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, "$reduce_or"); - reduce_or_cell->connections["\\A"] = this_s; + reduce_or_cell->connections_["\\A"] = this_s; reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size()); reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); this_s = RTLIL::SigSpec(reduce_or_wire); - reduce_or_cell->connections["\\Y"] = this_s; + reduce_or_cell->connections_["\\Y"] = this_s; } new_sig_b.append(this_b); @@ -149,14 +149,14 @@ struct OptReduceWorker if (new_sig_s.size() == 0) { - module->connections.push_back(RTLIL::SigSig(cell->connections["\\Y"], cell->connections["\\A"])); - assign_map.add(cell->connections["\\Y"], cell->connections["\\A"]); + module->connections_.push_back(RTLIL::SigSig(cell->connections_["\\Y"], cell->connections_["\\A"])); + assign_map.add(cell->connections_["\\Y"], cell->connections_["\\A"]); module->remove(cell); } else { - cell->connections["\\B"] = new_sig_b; - cell->connections["\\S"] = new_sig_s; + cell->connections_["\\B"] = new_sig_b; + cell->connections_["\\S"] = new_sig_s; if (new_sig_s.size() > 1) { cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); } else { @@ -168,9 +168,9 @@ struct OptReduceWorker void opt_mux_bits(RTLIL::Cell *cell) { - std::vector sig_a = assign_map(cell->connections["\\A"]).to_sigbit_vector(); - std::vector sig_b = assign_map(cell->connections["\\B"]).to_sigbit_vector(); - std::vector sig_y = assign_map(cell->connections["\\Y"]).to_sigbit_vector(); + std::vector sig_a = assign_map(cell->connections_["\\A"]).to_sigbit_vector(); + std::vector sig_b = assign_map(cell->connections_["\\B"]).to_sigbit_vector(); + std::vector sig_y = assign_map(cell->connections_["\\Y"]).to_sigbit_vector(); std::vector new_sig_y; RTLIL::SigSig old_sig_conn; @@ -211,26 +211,26 @@ struct OptReduceWorker if (new_sig_y.size() != sig_y.size()) { log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); - log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections["\\A"]), - log_signal(cell->connections["\\B"]), log_signal(cell->connections["\\Y"])); + log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections_["\\A"]), + log_signal(cell->connections_["\\B"]), log_signal(cell->connections_["\\Y"])); - cell->connections["\\A"] = RTLIL::SigSpec(); + cell->connections_["\\A"] = RTLIL::SigSpec(); for (auto &in_tuple : consolidated_in_tuples) - cell->connections["\\A"].append(in_tuple.at(0)); + cell->connections_["\\A"].append(in_tuple.at(0)); - cell->connections["\\B"] = RTLIL::SigSpec(); - for (int i = 1; i <= cell->connections["\\S"].size(); i++) + cell->connections_["\\B"] = RTLIL::SigSpec(); + for (int i = 1; i <= cell->connections_["\\S"].size(); i++) for (auto &in_tuple : consolidated_in_tuples) - cell->connections["\\B"].append(in_tuple.at(i)); + cell->connections_["\\B"].append(in_tuple.at(i)); cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); - cell->connections["\\Y"] = new_sig_y; + cell->connections_["\\Y"] = new_sig_y; - log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections["\\A"]), - log_signal(cell->connections["\\B"]), log_signal(cell->connections["\\Y"])); + log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections_["\\A"]), + log_signal(cell->connections_["\\B"]), log_signal(cell->connections_["\\Y"])); log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); - module->connections.push_back(old_sig_conn); + module->connections_.push_back(old_sig_conn); module->check(); did_something = true; @@ -251,14 +251,14 @@ struct OptReduceWorker for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mem") - mem_wren_sigs.add(assign_map(cell->connections["\\WR_EN"])); + mem_wren_sigs.add(assign_map(cell->connections_["\\WR_EN"])); if (cell->type == "$memwr") - mem_wren_sigs.add(assign_map(cell->connections["\\EN"])); + mem_wren_sigs.add(assign_map(cell->connections_["\\EN"])); } for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->connections["\\Q"]))) - mem_wren_sigs.add(assign_map(cell->connections["\\D"])); + if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->connections_["\\Q"]))) + mem_wren_sigs.add(assign_map(cell->connections_["\\D"])); } bool keep_expanding_mem_wren_sigs = true; @@ -266,12 +266,12 @@ struct OptReduceWorker keep_expanding_mem_wren_sigs = false; for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->connections["\\Y"]))) { - if (!mem_wren_sigs.check_all(assign_map(cell->connections["\\A"])) || - !mem_wren_sigs.check_all(assign_map(cell->connections["\\B"]))) + if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->connections_["\\Y"]))) { + if (!mem_wren_sigs.check_all(assign_map(cell->connections_["\\A"])) || + !mem_wren_sigs.check_all(assign_map(cell->connections_["\\B"]))) keep_expanding_mem_wren_sigs = true; - mem_wren_sigs.add(assign_map(cell->connections["\\A"])); - mem_wren_sigs.add(assign_map(cell->connections["\\B"])); + mem_wren_sigs.add(assign_map(cell->connections_["\\A"])); + mem_wren_sigs.add(assign_map(cell->connections_["\\B"])); } } } @@ -293,7 +293,7 @@ struct OptReduceWorker RTLIL::Cell *cell = cell_it.second; if (cell->type != type || !design->selected(module, cell)) continue; - drivers.insert(assign_map(cell->connections["\\Y"]), cell); + drivers.insert(assign_map(cell->connections_["\\Y"]), cell); cells.insert(cell); } @@ -315,7 +315,7 @@ struct OptReduceWorker { // this optimization is to aggressive for most coarse-grain applications. // but we always want it for multiplexers driving write enable ports. - if (do_fine || mem_wren_sigs.check_any(assign_map(cell->connections.at("\\Y")))) + if (do_fine || mem_wren_sigs.check_any(assign_map(cell->connections_.at("\\Y")))) opt_mux_bits(cell); opt_mux(cell); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 6a35cb61..4ece182f 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -33,34 +33,34 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) RTLIL::Const val_cp, val_rp, val_rv; if (dff->type == "$_DFF_N_" || dff->type == "$_DFF_P_") { - sig_d = dff->connections["\\D"]; - sig_q = dff->connections["\\Q"]; - sig_c = dff->connections["\\C"]; + sig_d = dff->connections_["\\D"]; + sig_q = dff->connections_["\\Q"]; + sig_c = dff->connections_["\\C"]; val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1); } else if (dff->type.substr(0,6) == "$_DFF_" && dff->type.substr(9) == "_" && (dff->type[6] == 'N' || dff->type[6] == 'P') && (dff->type[7] == 'N' || dff->type[7] == 'P') && (dff->type[8] == '0' || dff->type[8] == '1')) { - sig_d = dff->connections["\\D"]; - sig_q = dff->connections["\\Q"]; - sig_c = dff->connections["\\C"]; - sig_r = dff->connections["\\R"]; + sig_d = dff->connections_["\\D"]; + sig_q = dff->connections_["\\Q"]; + sig_c = dff->connections_["\\C"]; + sig_r = dff->connections_["\\R"]; val_cp = RTLIL::Const(dff->type[6] == 'P', 1); val_rp = RTLIL::Const(dff->type[7] == 'P', 1); val_rv = RTLIL::Const(dff->type[8] == '1', 1); } else if (dff->type == "$dff") { - sig_d = dff->connections["\\D"]; - sig_q = dff->connections["\\Q"]; - sig_c = dff->connections["\\CLK"]; + sig_d = dff->connections_["\\D"]; + sig_q = dff->connections_["\\Q"]; + sig_c = dff->connections_["\\CLK"]; val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); } else if (dff->type == "$adff") { - sig_d = dff->connections["\\D"]; - sig_q = dff->connections["\\Q"]; - sig_c = dff->connections["\\CLK"]; - sig_r = dff->connections["\\ARST"]; + sig_d = dff->connections_["\\D"]; + sig_q = dff->connections_["\\Q"]; + sig_c = dff->connections_["\\CLK"]; + sig_r = dff->connections_["\\ARST"]; val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); val_rp = RTLIL::Const(dff->parameters["\\ARST_POLARITY"].as_bool(), 1); val_rv = dff->parameters["\\ARST_VALUE"]; @@ -85,16 +85,16 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) std::set muxes; mux_drivers.find(sig_d, muxes); for (auto mux : muxes) { - RTLIL::SigSpec sig_a = assign_map(mux->connections.at("\\A")); - RTLIL::SigSpec sig_b = assign_map(mux->connections.at("\\B")); + RTLIL::SigSpec sig_a = assign_map(mux->connections_.at("\\A")); + RTLIL::SigSpec sig_b = assign_map(mux->connections_.at("\\B")); if (sig_a == sig_q && sig_b.is_fully_const()) { RTLIL::SigSig conn(sig_q, sig_b); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); goto delete_dff; } if (sig_b == sig_q && sig_a.is_fully_const()) { RTLIL::SigSig conn(sig_q, sig_a); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); goto delete_dff; } } @@ -104,36 +104,36 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) if (val_rv.bits.size() == 0) val_rv = val_init; RTLIL::SigSig conn(sig_q, val_rv); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); goto delete_dff; } if (sig_d.is_fully_undef() && sig_r.size() && !has_init) { RTLIL::SigSig conn(sig_q, val_rv); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); goto delete_dff; } if (sig_d.is_fully_undef() && !sig_r.size() && has_init) { RTLIL::SigSig conn(sig_q, val_init); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); goto delete_dff; } if (sig_d.is_fully_const() && !sig_r.size() && !has_init) { RTLIL::SigSig conn(sig_q, sig_d); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); goto delete_dff; } if (sig_d == sig_q && !(sig_r.size() && has_init)) { if (sig_r.size()) { RTLIL::SigSig conn(sig_q, val_rv); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); } if (has_init) { RTLIL::SigSig conn(sig_q, val_init); - mod->connections.push_back(conn); + mod->connections_.push_back(conn); } goto delete_dff; } @@ -181,8 +181,8 @@ struct OptRmdffPass : public Pass { std::vector dff_list; for (auto &it : mod_it.second->cells) { if (it.second->type == "$mux" || it.second->type == "$pmux") { - if (it.second->connections.at("\\A").size() == it.second->connections.at("\\B").size()) - mux_drivers.insert(assign_map(it.second->connections.at("\\Y")), it.second); + if (it.second->connections_.at("\\A").size() == it.second->connections_.at("\\B").size()) + mux_drivers.insert(assign_map(it.second->connections_.at("\\Y")), it.second); continue; } if (!design->selected(mod_it.second, it.second)) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index e3e9511f..b3a37209 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -66,7 +66,7 @@ struct OptShareWorker for (auto &it : cell->parameters) hash_string += "P " + it.first + "=" + it.second.as_string() + "\n"; - const std::map *conn = &cell->connections; + const std::map *conn = &cell->connections_; std::map alt_conn; if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$mul" || @@ -135,8 +135,8 @@ struct OptShareWorker return true; } - std::map conn1 = cell1->connections; - std::map conn2 = cell2->connections; + std::map conn1 = cell1->connections_; + std::map conn2 = cell2->connections_; for (auto &it : conn1) { if (ct.cell_output(cell1->type, it.first)) @@ -180,8 +180,8 @@ struct OptShareWorker } if (cell1->type.substr(0, 1) == "$" && conn1.count("\\Q") != 0) { - std::vector q1 = dff_init_map(cell1->connections.at("\\Q")).to_sigbit_vector(); - std::vector q2 = dff_init_map(cell2->connections.at("\\Q")).to_sigbit_vector(); + std::vector q1 = dff_init_map(cell1->connections_.at("\\Q")).to_sigbit_vector(); + std::vector q2 = dff_init_map(cell2->connections_.at("\\Q")).to_sigbit_vector(); for (size_t i = 0; i < q1.size(); i++) if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { lt = q1.at(i) < q2.at(i); @@ -261,12 +261,12 @@ struct OptShareWorker if (sharemap.count(cell) > 0) { did_something = true; log(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str()); - for (auto &it : cell->connections) { + for (auto &it : cell->connections_) { if (ct.cell_output(cell->type, it.first)) { - RTLIL::SigSpec other_sig = sharemap[cell]->connections[it.first]; + RTLIL::SigSpec other_sig = sharemap[cell]->connections_[it.first]; log(" Redirecting output %s: %s = %s\n", it.first.c_str(), log_signal(it.second), log_signal(other_sig)); - module->connections.push_back(RTLIL::SigSig(it.second, other_sig)); + module->connections_.push_back(RTLIL::SigSig(it.second, other_sig)); assign_map.add(it.second, other_sig); } } diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 145abfa4..ce313360 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -35,40 +35,40 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp for (auto &cell_it : mod->cells) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$reduce_or" && cell->connections["\\Y"] == signal) - return check_signal(mod, cell->connections["\\A"], ref, polarity); - if (cell->type == "$reduce_bool" && cell->connections["\\Y"] == signal) - return check_signal(mod, cell->connections["\\A"], ref, polarity); - if (cell->type == "$logic_not" && cell->connections["\\Y"] == signal) { + if (cell->type == "$reduce_or" && cell->connections_["\\Y"] == signal) + return check_signal(mod, cell->connections_["\\A"], ref, polarity); + if (cell->type == "$reduce_bool" && cell->connections_["\\Y"] == signal) + return check_signal(mod, cell->connections_["\\A"], ref, polarity); + if (cell->type == "$logic_not" && cell->connections_["\\Y"] == signal) { polarity = !polarity; - return check_signal(mod, cell->connections["\\A"], ref, polarity); + return check_signal(mod, cell->connections_["\\A"], ref, polarity); } - if (cell->type == "$not" && cell->connections["\\Y"] == signal) { + if (cell->type == "$not" && cell->connections_["\\Y"] == signal) { polarity = !polarity; - return check_signal(mod, cell->connections["\\A"], ref, polarity); + return check_signal(mod, cell->connections_["\\A"], ref, polarity); } - if ((cell->type == "$eq" || cell->type == "$eqx") && cell->connections["\\Y"] == signal) { - if (cell->connections["\\A"].is_fully_const()) { - if (!cell->connections["\\A"].as_bool()) + if ((cell->type == "$eq" || cell->type == "$eqx") && cell->connections_["\\Y"] == signal) { + if (cell->connections_["\\A"].is_fully_const()) { + if (!cell->connections_["\\A"].as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections["\\B"], ref, polarity); + return check_signal(mod, cell->connections_["\\B"], ref, polarity); } - if (cell->connections["\\B"].is_fully_const()) { - if (!cell->connections["\\B"].as_bool()) + if (cell->connections_["\\B"].is_fully_const()) { + if (!cell->connections_["\\B"].as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections["\\A"], ref, polarity); + return check_signal(mod, cell->connections_["\\A"], ref, polarity); } } - if ((cell->type == "$ne" || cell->type == "$nex") && cell->connections["\\Y"] == signal) { - if (cell->connections["\\A"].is_fully_const()) { - if (cell->connections["\\A"].as_bool()) + if ((cell->type == "$ne" || cell->type == "$nex") && cell->connections_["\\Y"] == signal) { + if (cell->connections_["\\A"].is_fully_const()) { + if (cell->connections_["\\A"].as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections["\\B"], ref, polarity); + return check_signal(mod, cell->connections_["\\B"], ref, polarity); } - if (cell->connections["\\B"].is_fully_const()) { - if (cell->connections["\\B"].as_bool()) + if (cell->connections_["\\B"].is_fully_const()) { + if (cell->connections_["\\B"].as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections["\\A"], ref, polarity); + return check_signal(mod, cell->connections_["\\A"], ref, polarity); } } } diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 876adb0d..9d2c897e 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -77,8 +77,8 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections["\\A"] = sync_low_signals; - cell->connections["\\Y"] = sync_low_signals = mod->addWire(NEW_ID); + cell->connections_["\\A"] = sync_low_signals; + cell->connections_["\\Y"] = sync_low_signals = mod->addWire(NEW_ID); } if (sync_low_signals.size() > 0) { @@ -86,9 +86,9 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections["\\A"] = sync_low_signals; - cell->connections["\\Y"] = mod->addWire(NEW_ID); - sync_high_signals.append(cell->connections["\\Y"]); + cell->connections_["\\A"] = sync_low_signals; + cell->connections_["\\Y"] = mod->addWire(NEW_ID); + sync_high_signals.append(cell->connections_["\\Y"]); } if (sync_high_signals.size() > 1) { @@ -96,30 +96,30 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections["\\A"] = sync_high_signals; - cell->connections["\\Y"] = sync_high_signals = mod->addWire(NEW_ID); + cell->connections_["\\A"] = sync_high_signals; + cell->connections_["\\Y"] = sync_high_signals = mod->addWire(NEW_ID); } RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, "$not"); inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size()); inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size()); - inv_cell->connections["\\A"] = sync_value; - inv_cell->connections["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.size()); + inv_cell->connections_["\\A"] = sync_value; + inv_cell->connections_["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.size()); RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, "$mux"); mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); - mux_set_cell->connections["\\A"] = sig_sr_set; - mux_set_cell->connections["\\B"] = sync_value; - mux_set_cell->connections["\\S"] = sync_high_signals; - mux_set_cell->connections["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.size()); + mux_set_cell->connections_["\\A"] = sig_sr_set; + mux_set_cell->connections_["\\B"] = sync_value; + mux_set_cell->connections_["\\S"] = sync_high_signals; + mux_set_cell->connections_["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.size()); RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, "$mux"); mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); - mux_clr_cell->connections["\\A"] = sig_sr_clr; - mux_clr_cell->connections["\\B"] = sync_value_inv; - mux_clr_cell->connections["\\S"] = sync_high_signals; - mux_clr_cell->connections["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()); + mux_clr_cell->connections_["\\A"] = sig_sr_clr; + mux_clr_cell->connections_["\\B"] = sync_value_inv; + mux_clr_cell->connections_["\\S"] = sync_high_signals; + mux_clr_cell->connections_["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()); } std::stringstream sstr; @@ -131,11 +131,11 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); - cell->connections["\\D"] = sig_d; - cell->connections["\\Q"] = sig_q; - cell->connections["\\CLK"] = clk; - cell->connections["\\SET"] = sig_sr_set; - cell->connections["\\CLR"] = sig_sr_clr; + cell->connections_["\\D"] = sig_d; + cell->connections_["\\Q"] = sig_q; + cell->connections_["\\CLK"] = clk; + cell->connections_["\\SET"] = sig_sr_set; + cell->connections_["\\CLR"] = sig_sr_clr; log(" created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); @@ -155,22 +155,22 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size()); inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size()); - inv_set->connections["\\A"] = sig_set; - inv_set->connections["\\Y"] = sig_set_inv; + inv_set->connections_["\\A"] = sig_set; + inv_set->connections_["\\Y"] = sig_set_inv; RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux"); mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_set->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); - mux_sr_set->connections[set_polarity ? "\\B" : "\\A"] = sig_set; - mux_sr_set->connections["\\Y"] = sig_sr_set; - mux_sr_set->connections["\\S"] = set; + mux_sr_set->connections_[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); + mux_sr_set->connections_[set_polarity ? "\\B" : "\\A"] = sig_set; + mux_sr_set->connections_["\\Y"] = sig_sr_set; + mux_sr_set->connections_["\\S"] = set; RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux"); mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_clr->connections[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); - mux_sr_clr->connections[set_polarity ? "\\B" : "\\A"] = sig_set_inv; - mux_sr_clr->connections["\\Y"] = sig_sr_clr; - mux_sr_clr->connections["\\S"] = set; + mux_sr_clr->connections_[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); + mux_sr_clr->connections_[set_polarity ? "\\B" : "\\A"] = sig_set_inv; + mux_sr_clr->connections_["\\Y"] = sig_sr_clr; + mux_sr_clr->connections_["\\S"] = set; RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; @@ -178,11 +178,11 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); - cell->connections["\\D"] = sig_in; - cell->connections["\\Q"] = sig_out; - cell->connections["\\CLK"] = clk; - cell->connections["\\SET"] = sig_sr_set; - cell->connections["\\CLR"] = sig_sr_clr; + cell->connections_["\\D"] = sig_in; + cell->connections_["\\Q"] = sig_out; + cell->connections_["\\CLK"] = clk; + cell->connections_["\\SET"] = sig_sr_set; + cell->connections_["\\CLR"] = sig_sr_clr; log(" created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative", set_polarity ? "positive" : "negative"); @@ -204,11 +204,11 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ } cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); - cell->connections["\\D"] = sig_in; - cell->connections["\\Q"] = sig_out; + cell->connections_["\\D"] = sig_in; + cell->connections_["\\Q"] = sig_out; if (arst) - cell->connections["\\ARST"] = *arst; - cell->connections["\\CLK"] = clk; + cell->connections_["\\ARST"] = *arst; + cell->connections_["\\CLK"] = clk; log(" created %s cell `%s' with %s edge clock", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); if (arst) @@ -296,9 +296,9 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections["\\A"] = inputs; - cell->connections["\\B"] = compare; - cell->connections["\\Y"] = sync_level->signal; + cell->connections_["\\A"] = inputs; + cell->connections_["\\B"] = compare; + cell->connections_["\\Y"] = sync_level->signal; many_async_rules.clear(); } @@ -322,7 +322,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) if (sync_edge || sync_level || many_async_rules.size() > 0) log_error("Mixed always event with edge and/or level sensitive events!\n"); log(" created direct connection (no actual register cell created).\n"); - mod->connections.push_back(RTLIL::SigSig(sig, insig)); + mod->connections_.push_back(RTLIL::SigSig(sig, insig)); continue; } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 5bb1ab94..2cde749a 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -81,7 +81,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, if (sig.size() == 1 && comp == RTLIL::SigSpec(1,1)) { - mod->connections.push_back(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, cmp_wire->width++), sig)); + mod->connections_.push_back(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, cmp_wire->width++), sig)); } else { @@ -96,9 +96,9 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - eq_cell->connections["\\A"] = sig; - eq_cell->connections["\\B"] = comp; - eq_cell->connections["\\Y"] = RTLIL::SigSpec(cmp_wire, cmp_wire->width++); + eq_cell->connections_["\\A"] = sig; + eq_cell->connections_["\\B"] = comp; + eq_cell->connections_["\\Y"] = RTLIL::SigSpec(cmp_wire, cmp_wire->width++); } } @@ -122,8 +122,8 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width); any_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - any_cell->connections["\\A"] = cmp_wire; - any_cell->connections["\\Y"] = RTLIL::SigSpec(ctrl_wire); + any_cell->connections_["\\A"] = cmp_wire; + any_cell->connections_["\\Y"] = RTLIL::SigSpec(ctrl_wire); } return RTLIL::SigSpec(ctrl_wire); @@ -157,10 +157,10 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, mux_cell->attributes = sw->attributes; mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size()); - mux_cell->connections["\\A"] = else_signal; - mux_cell->connections["\\B"] = when_signal; - mux_cell->connections["\\S"] = ctrl_sig; - mux_cell->connections["\\Y"] = RTLIL::SigSpec(result_wire); + mux_cell->connections_["\\A"] = else_signal; + mux_cell->connections_["\\B"] = when_signal; + mux_cell->connections_["\\S"] = ctrl_sig; + mux_cell->connections_["\\Y"] = RTLIL::SigSpec(result_wire); last_mux_cell = mux_cell; return RTLIL::SigSpec(result_wire); @@ -169,14 +169,14 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw) { assert(last_mux_cell != NULL); - assert(when_signal.size() == last_mux_cell->connections["\\A"].size()); + assert(when_signal.size() == last_mux_cell->connections_["\\A"].size()); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); assert(ctrl_sig.size() == 1); last_mux_cell->type = "$pmux"; - last_mux_cell->connections["\\S"].append(ctrl_sig); - last_mux_cell->connections["\\B"].append(when_signal); - last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->connections["\\S"].size(); + last_mux_cell->connections_["\\S"].append(ctrl_sig); + last_mux_cell->connections_["\\B"].append(when_signal); + last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->connections_["\\S"].size(); } static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs, const RTLIL::SigSpec &sig, const RTLIL::SigSpec &defval) @@ -256,7 +256,7 @@ static void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc) log(" creating decoder for signal `%s'.\n", log_signal(sig)); RTLIL::SigSpec value = signal_to_mux_tree(mod, &proc->root_case, sig, RTLIL::SigSpec(RTLIL::State::Sx, sig.size())); - mod->connections.push_back(RTLIL::SigSig(sig, value)); + mod->connections_.push_back(RTLIL::SigSig(sig, value)); } } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 29ce899e..22b724d5 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -83,8 +83,8 @@ static void find_dff_wires(std::set &dff_wires, RTLIL::Module *modu SigPool dffsignals; for (auto &it : module->cells) { - if (ct.cell_known(it.second->type) && it.second->connections.count("\\Q")) - dffsignals.add(sigmap(it.second->connections.at("\\Q"))); + if (ct.cell_known(it.second->type) && it.second->connections_.count("\\Q")) + dffsignals.add(sigmap(it.second->connections_.at("\\Q"))); } for (auto &it : module->wires) { @@ -113,10 +113,10 @@ static void create_dff_dq_map(std::map &map, RTLIL: info.cell = it.second; if (info.cell->type == "$dff") { - info.bit_clk = sigmap(info.cell->connections.at("\\CLK")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->connections_.at("\\CLK")).to_single_sigbit(); info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool(); - std::vector sig_d = sigmap(info.cell->connections.at("\\D")).to_sigbit_vector(); - std::vector sig_q = sigmap(info.cell->connections.at("\\Q")).to_sigbit_vector(); + std::vector sig_d = sigmap(info.cell->connections_.at("\\D")).to_sigbit_vector(); + std::vector sig_q = sigmap(info.cell->connections_.at("\\Q")).to_sigbit_vector(); for (size_t i = 0; i < sig_d.size(); i++) { info.bit_d = sig_d.at(i); bit_info[sig_q.at(i)] = info; @@ -125,12 +125,12 @@ static void create_dff_dq_map(std::map &map, RTLIL: } if (info.cell->type == "$adff") { - info.bit_clk = sigmap(info.cell->connections.at("\\CLK")).to_single_sigbit(); - info.bit_arst = sigmap(info.cell->connections.at("\\ARST")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->connections_.at("\\CLK")).to_single_sigbit(); + info.bit_arst = sigmap(info.cell->connections_.at("\\ARST")).to_single_sigbit(); info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool(); info.arst_polarity = info.cell->parameters.at("\\ARST_POLARITY").as_bool(); - std::vector sig_d = sigmap(info.cell->connections.at("\\D")).to_sigbit_vector(); - std::vector sig_q = sigmap(info.cell->connections.at("\\Q")).to_sigbit_vector(); + std::vector sig_d = sigmap(info.cell->connections_.at("\\D")).to_sigbit_vector(); + std::vector sig_q = sigmap(info.cell->connections_.at("\\Q")).to_sigbit_vector(); std::vector arst_value = info.cell->parameters.at("\\ARST_VALUE").bits; for (size_t i = 0; i < sig_d.size(); i++) { info.bit_d = sig_d.at(i); @@ -141,21 +141,21 @@ static void create_dff_dq_map(std::map &map, RTLIL: } if (info.cell->type == "$_DFF_N_" || info.cell->type == "$_DFF_P_") { - info.bit_clk = sigmap(info.cell->connections.at("\\C")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->connections_.at("\\C")).to_single_sigbit(); info.clk_polarity = info.cell->type == "$_DFF_P_"; - info.bit_d = sigmap(info.cell->connections.at("\\D")).to_single_sigbit(); - bit_info[sigmap(info.cell->connections.at("\\Q")).to_single_sigbit()] = info; + info.bit_d = sigmap(info.cell->connections_.at("\\D")).to_single_sigbit(); + bit_info[sigmap(info.cell->connections_.at("\\Q")).to_single_sigbit()] = info; continue; } if (info.cell->type.size() == 10 && info.cell->type.substr(0, 6) == "$_DFF_") { - info.bit_clk = sigmap(info.cell->connections.at("\\C")).to_single_sigbit(); - info.bit_arst = sigmap(info.cell->connections.at("\\R")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->connections_.at("\\C")).to_single_sigbit(); + info.bit_arst = sigmap(info.cell->connections_.at("\\R")).to_single_sigbit(); info.clk_polarity = info.cell->type[6] == 'P'; info.arst_polarity = info.cell->type[7] == 'P'; info.arst_value = info.cell->type[0] == '1' ? RTLIL::State::S1 : RTLIL::State::S0; - info.bit_d = sigmap(info.cell->connections.at("\\D")).to_single_sigbit(); - bit_info[sigmap(info.cell->connections.at("\\Q")).to_single_sigbit()] = info; + info.bit_d = sigmap(info.cell->connections_.at("\\D")).to_single_sigbit(); + bit_info[sigmap(info.cell->connections_.at("\\Q")).to_single_sigbit()] = info; continue; } } @@ -485,12 +485,12 @@ struct ExposePass : public Pass { for (auto &it : module->cells) { if (!ct.cell_known(it.second->type)) continue; - for (auto &conn : it.second->connections) + for (auto &conn : it.second->connections_) if (ct.cell_input(it.second->type, conn.first)) conn.second = out_to_in_map(sigmap(conn.second)); } - for (auto &conn : module->connections) + for (auto &conn : module->connections_) conn.second = out_to_in_map(sigmap(conn.second)); } @@ -514,11 +514,11 @@ struct ExposePass : public Pass { for (auto &cell_name : info.cells) { RTLIL::Cell *cell = module->cells.at(cell_name); - std::vector cell_q_bits = sigmap(cell->connections.at("\\Q")).to_sigbit_vector(); + std::vector cell_q_bits = sigmap(cell->connections_.at("\\Q")).to_sigbit_vector(); for (auto &bit : cell_q_bits) if (wire_bits_set.count(bit)) bit = RTLIL::SigBit(wire_dummy_q, wire_dummy_q->width++); - cell->connections.at("\\Q") = cell_q_bits; + cell->connections_.at("\\Q") = cell_q_bits; } RTLIL::Wire *wire_q = new RTLIL::Wire; @@ -536,7 +536,7 @@ struct ExposePass : public Pass { connect_q.second.append(RTLIL::SigBit(wire_q, i)); set_q_bits.insert(wire_bits_vec[i]); } - module->connections.push_back(connect_q); + module->connections_.push_back(connect_q); RTLIL::Wire *wire_d = new RTLIL::Wire; wire_d->name = wire->name + sep + "d"; @@ -544,7 +544,7 @@ struct ExposePass : public Pass { wire_d->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_d->name)); add_new_wire(module, wire_d); - module->connections.push_back(RTLIL::SigSig(wire_d, info.sig_d)); + module->connections_.push_back(RTLIL::SigSig(wire_d, info.sig_d)); RTLIL::Wire *wire_c = new RTLIL::Wire; wire_c->name = wire->name + sep + "c"; @@ -552,14 +552,14 @@ struct ExposePass : public Pass { log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_c->name)); add_new_wire(module, wire_c); if (info.clk_polarity) { - module->connections.push_back(RTLIL::SigSig(wire_c, info.sig_clk)); + module->connections_.push_back(RTLIL::SigSig(wire_c, info.sig_clk)); } else { RTLIL::Cell *c = module->addCell(NEW_ID, "$not"); c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; - c->connections["\\A"] = info.sig_clk; - c->connections["\\Y"] = wire_c; + c->connections_["\\A"] = info.sig_clk; + c->connections_["\\Y"] = wire_c; } if (info.sig_arst != RTLIL::State::Sm) @@ -570,14 +570,14 @@ struct ExposePass : public Pass { log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_r->name)); add_new_wire(module, wire_r); if (info.arst_polarity) { - module->connections.push_back(RTLIL::SigSig(wire_r, info.sig_arst)); + module->connections_.push_back(RTLIL::SigSig(wire_r, info.sig_arst)); } else { RTLIL::Cell *c = module->addCell(NEW_ID, "$not"); c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; - c->connections["\\A"] = info.sig_arst; - c->connections["\\Y"] = wire_r; + c->connections_["\\A"] = info.sig_arst; + c->connections_["\\Y"] = wire_r; } RTLIL::Wire *wire_v = new RTLIL::Wire; @@ -586,7 +586,7 @@ struct ExposePass : public Pass { wire_v->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_v->name)); add_new_wire(module, wire_v); - module->connections.push_back(RTLIL::SigSig(wire_v, info.arst_value)); + module->connections_.push_back(RTLIL::SigSig(wire_v, info.arst_value)); } } @@ -628,18 +628,18 @@ struct ExposePass : public Pass { log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); RTLIL::SigSpec sig; - if (cell->connections.count(p->name) != 0) - sig = cell->connections.at(p->name); + if (cell->connections_.count(p->name) != 0) + sig = cell->connections_.at(p->name); sig.extend(w->width); if (w->port_input) - module->connections.push_back(RTLIL::SigSig(sig, w)); + module->connections_.push_back(RTLIL::SigSig(sig, w)); else - module->connections.push_back(RTLIL::SigSig(w, sig)); + module->connections_.push_back(RTLIL::SigSig(w, sig)); } } else { - for (auto &it : cell->connections) + for (auto &it : cell->connections_) { RTLIL::Wire *w = new RTLIL::Wire; w->name = cell->name + sep + RTLIL::unescape_id(it.first); @@ -653,9 +653,9 @@ struct ExposePass : public Pass { log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); if (w->port_input) - module->connections.push_back(RTLIL::SigSig(it.second, w)); + module->connections_.push_back(RTLIL::SigSig(it.second, w)); else - module->connections.push_back(RTLIL::SigSig(w, it.second)); + module->connections_.push_back(RTLIL::SigSig(w, it.second)); } } diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 79dec3b5..517e6713 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -610,7 +610,7 @@ struct FreduceWorker for (auto &it : module->cells) { if (ct.cell_known(it.second->type)) { std::set inputs, outputs; - for (auto &port : it.second->connections) { + for (auto &port : it.second->connections_) { std::vector bits = sigmap(port.second).to_sigbit_vector(); if (ct.cell_output(it.second->type, port.first)) outputs.insert(bits.begin(), bits.end()); @@ -624,7 +624,7 @@ struct FreduceWorker bits_full_total += outputs.size(); } if (inv_mode && it.second->type == "$_INV_") - inv_pairs.insert(std::pair(sigmap(it.second->connections.at("\\A")), sigmap(it.second->connections.at("\\Y")))); + inv_pairs.insert(std::pair(sigmap(it.second->connections_.at("\\A")), sigmap(it.second->connections_.at("\\Y")))); } int bits_count = 0; @@ -708,7 +708,7 @@ struct FreduceWorker RTLIL::Cell *drv = drivers.at(grp[i].bit).first; RTLIL::Wire *dummy_wire = module->addWire(NEW_ID); - for (auto &port : drv->connections) + for (auto &port : drv->connections_) if (ct.cell_output(drv->type, port.first)) sigmap(port.second).replace(grp[i].bit, dummy_wire, &port.second); @@ -719,14 +719,14 @@ struct FreduceWorker inv_sig = module->addWire(NEW_ID); RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_INV_"); - inv_cell->connections["\\A"] = grp[0].bit; - inv_cell->connections["\\Y"] = inv_sig; + inv_cell->connections_["\\A"] = grp[0].bit; + inv_cell->connections_["\\Y"] = inv_sig; } - module->connections.push_back(RTLIL::SigSig(grp[i].bit, inv_sig)); + module->connections_.push_back(RTLIL::SigSig(grp[i].bit, inv_sig)); } else - module->connections.push_back(RTLIL::SigSig(grp[i].bit, grp[0].bit)); + module->connections_.push_back(RTLIL::SigSig(grp[i].bit, grp[0].bit)); rewired_sigbits++; } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index aff66424..9e151cdf 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -132,8 +132,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w2->width = w1->width; miter_module->add(w2); - gold_cell->connections[w1->name] = w2; - gate_cell->connections[w1->name] = w2; + gold_cell->connections_[w1->name] = w2; + gate_cell->connections_[w1->name] = w2; } if (w1->port_output) @@ -150,8 +150,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w2_gate->width = w1->width; miter_module->add(w2_gate); - gold_cell->connections[w1->name] = w2_gold; - gate_cell->connections[w1->name] = w2_gate; + gold_cell->connections_[w1->name] = w2_gold; + gate_cell->connections_[w1->name] = w2_gate; RTLIL::SigSpec this_condition; @@ -165,9 +165,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eqx_cell->parameters["\\Y_WIDTH"] = 1; eqx_cell->parameters["\\A_SIGNED"] = 0; eqx_cell->parameters["\\B_SIGNED"] = 0; - eqx_cell->connections["\\A"] = RTLIL::SigSpec(w2_gold, i); - eqx_cell->connections["\\B"] = RTLIL::State::Sx; - eqx_cell->connections["\\Y"] = gold_x.extract(i, 1); + eqx_cell->connections_["\\A"] = RTLIL::SigSpec(w2_gold, i); + eqx_cell->connections_["\\B"] = RTLIL::State::Sx; + eqx_cell->connections_["\\Y"] = gold_x.extract(i, 1); } RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width); @@ -179,9 +179,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\A_SIGNED"] = 0; or_gold_cell->parameters["\\B_SIGNED"] = 0; - or_gold_cell->connections["\\A"] = w2_gold; - or_gold_cell->connections["\\B"] = gold_x; - or_gold_cell->connections["\\Y"] = gold_masked; + or_gold_cell->connections_["\\A"] = w2_gold; + or_gold_cell->connections_["\\B"] = gold_x; + or_gold_cell->connections_["\\Y"] = gold_masked; RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or"); or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width; @@ -189,9 +189,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\A_SIGNED"] = 0; or_gate_cell->parameters["\\B_SIGNED"] = 0; - or_gate_cell->connections["\\A"] = w2_gate; - or_gate_cell->connections["\\B"] = gold_x; - or_gate_cell->connections["\\Y"] = gate_masked; + or_gate_cell->connections_["\\A"] = w2_gate; + or_gate_cell->connections_["\\B"] = gold_x; + or_gate_cell->connections_["\\Y"] = gate_masked; RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; @@ -199,10 +199,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->connections["\\A"] = gold_masked; - eq_cell->connections["\\B"] = gate_masked; - eq_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); - this_condition = eq_cell->connections["\\Y"]; + eq_cell->connections_["\\A"] = gold_masked; + eq_cell->connections_["\\B"] = gate_masked; + eq_cell->connections_["\\Y"] = miter_module->addWire(NEW_ID); + this_condition = eq_cell->connections_["\\Y"]; } else { @@ -212,10 +212,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->connections["\\A"] = w2_gold; - eq_cell->connections["\\B"] = w2_gate; - eq_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); - this_condition = eq_cell->connections["\\Y"]; + eq_cell->connections_["\\A"] = w2_gold; + eq_cell->connections_["\\B"] = w2_gate; + eq_cell->connections_["\\Y"] = miter_module->addWire(NEW_ID); + this_condition = eq_cell->connections_["\\Y"]; } if (flag_make_outcmp) @@ -224,7 +224,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w_cmp->name = "\\cmp_" + RTLIL::unescape_id(w1->name); w_cmp->port_output = true; miter_module->add(w_cmp); - miter_module->connections.push_back(RTLIL::SigSig(w_cmp, this_condition)); + miter_module->connections_.push_back(RTLIL::SigSig(w_cmp, this_condition)); } all_conditions.append(this_condition); @@ -236,15 +236,15 @@ static void create_miter_equiv(struct Pass *that, std::vector args, reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size(); reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; - reduce_cell->connections["\\A"] = all_conditions; - reduce_cell->connections["\\Y"] = miter_module->addWire(NEW_ID); - all_conditions = reduce_cell->connections["\\Y"]; + reduce_cell->connections_["\\A"] = all_conditions; + reduce_cell->connections_["\\Y"] = miter_module->addWire(NEW_ID); + all_conditions = reduce_cell->connections_["\\Y"]; } if (flag_make_assert) { RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); - assert_cell->connections["\\A"] = all_conditions; - assert_cell->connections["\\EN"] = RTLIL::SigSpec(1, 1); + assert_cell->connections_["\\A"] = all_conditions; + assert_cell->connections_["\\EN"] = RTLIL::SigSpec(1, 1); } RTLIL::Wire *w_trigger = new RTLIL::Wire; @@ -257,8 +257,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); not_cell->parameters["\\Y_WIDTH"] = w_trigger->width; not_cell->parameters["\\A_SIGNED"] = 0; - not_cell->connections["\\A"] = all_conditions; - not_cell->connections["\\Y"] = w_trigger; + not_cell->connections_["\\A"] = all_conditions; + not_cell->connections_["\\Y"] = w_trigger; miter_module->fixup_ports(); diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 4b6b1b71..cc041391 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -321,7 +321,7 @@ struct SatHelper if (design->selected(module, c.second)) { // log("Import cell: %s\n", RTLIL::id2cstr(c.first)); if (satgen.importCell(c.second, timestep)) { - for (auto &p : c.second->connections) + for (auto &p : c.second->connections_) if (ct.cell_output(c.second->type, p.first)) show_drivers.insert(sigmap(p.second), c.second); import_cell_counter++; @@ -505,7 +505,7 @@ struct SatHelper final_signals.add(sig); } else { for (auto &d : drivers) - for (auto &p : d->connections) { + for (auto &p : d->connections_) { if (d->type == "$dff" && p.first == "\\CLK") continue; if (d->type.substr(0, 6) == "$_DFF_" && p.first == "\\C") diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 7e24e1f0..01acf50d 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -77,7 +77,7 @@ struct ShareWorker for (auto &pbit : portbits) { if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { - std::set bits = modwalker.sigmap(pbit.cell->connections.at("\\S")).to_sigbit_set(); + std::set bits = modwalker.sigmap(pbit.cell->connections_.at("\\S")).to_sigbit_set(); terminal_bits.insert(bits.begin(), bits.end()); queue_bits.insert(bits.begin(), bits.end()); visited_cells.insert(pbit.cell); @@ -256,9 +256,9 @@ struct ShareWorker if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->connections.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->connections_.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - unsigned_cell->connections.at("\\A").append_bit(RTLIL::State::S0); + unsigned_cell->connections_.at("\\A").append_bit(RTLIL::State::S0); } unsigned_cell->parameters.at("\\A_SIGNED") = true; unsigned_cell->check(); @@ -267,17 +267,17 @@ struct ShareWorker bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); - RTLIL::SigSpec a1 = c1->connections.at("\\A"); - RTLIL::SigSpec y1 = c1->connections.at("\\Y"); + RTLIL::SigSpec a1 = c1->connections_.at("\\A"); + RTLIL::SigSpec y1 = c1->connections_.at("\\Y"); - RTLIL::SigSpec a2 = c2->connections.at("\\A"); - RTLIL::SigSpec y2 = c2->connections.at("\\Y"); + RTLIL::SigSpec a2 = c2->connections_.at("\\A"); + RTLIL::SigSpec y2 = c2->connections_.at("\\Y"); int a_width = std::max(a1.size(), a2.size()); int y_width = std::max(y1.size(), y2.size()); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); @@ -286,14 +286,14 @@ struct ShareWorker supercell->parameters["\\A_SIGNED"] = a_signed; supercell->parameters["\\A_WIDTH"] = a_width; supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->connections["\\A"] = a; - supercell->connections["\\Y"] = y; + supercell->connections_["\\A"] = a; + supercell->connections_["\\Y"] = y; RTLIL::SigSpec new_y1(y, 0, y1.size()); RTLIL::SigSpec new_y2(y, 0, y2.size()); - module->connections.push_back(RTLIL::SigSig(y1, new_y1)); - module->connections.push_back(RTLIL::SigSig(y2, new_y2)); + module->connections_.push_back(RTLIL::SigSig(y1, new_y1)); + module->connections_.push_back(RTLIL::SigSig(y2, new_y2)); return supercell; } @@ -312,7 +312,7 @@ struct ShareWorker if (score_flipped < score_unflipped) { - std::swap(c2->connections.at("\\A"), c2->connections.at("\\B")); + std::swap(c2->connections_.at("\\A"), c2->connections_.at("\\B")); std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); modified_src_cells = true; @@ -323,9 +323,9 @@ struct ShareWorker { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->connections.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->connections_.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - unsigned_cell->connections.at("\\A").append_bit(RTLIL::State::S0); + unsigned_cell->connections_.at("\\A").append_bit(RTLIL::State::S0); } unsigned_cell->parameters.at("\\A_SIGNED") = true; modified_src_cells = true; @@ -334,9 +334,9 @@ struct ShareWorker if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->connections.at("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->connections_.at("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; - unsigned_cell->connections.at("\\B").append_bit(RTLIL::State::S0); + unsigned_cell->connections_.at("\\B").append_bit(RTLIL::State::S0); } unsigned_cell->parameters.at("\\B_SIGNED") = true; modified_src_cells = true; @@ -356,13 +356,13 @@ struct ShareWorker if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") b_signed = false; - RTLIL::SigSpec a1 = c1->connections.at("\\A"); - RTLIL::SigSpec b1 = c1->connections.at("\\B"); - RTLIL::SigSpec y1 = c1->connections.at("\\Y"); + RTLIL::SigSpec a1 = c1->connections_.at("\\A"); + RTLIL::SigSpec b1 = c1->connections_.at("\\B"); + RTLIL::SigSpec y1 = c1->connections_.at("\\Y"); - RTLIL::SigSpec a2 = c2->connections.at("\\A"); - RTLIL::SigSpec b2 = c2->connections.at("\\B"); - RTLIL::SigSpec y2 = c2->connections.at("\\Y"); + RTLIL::SigSpec a2 = c2->connections_.at("\\A"); + RTLIL::SigSpec b2 = c2->connections_.at("\\B"); + RTLIL::SigSpec y2 = c2->connections_.at("\\Y"); int a_width = std::max(a1.size(), a2.size()); int b_width = std::max(b1.size(), b2.size()); @@ -372,20 +372,20 @@ struct ShareWorker { a_width = std::max(y_width, a_width); - if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->connections.at("\\Y"); - if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->connections.at("\\Y"); + if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->connections_.at("\\Y"); + if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->connections_.at("\\Y"); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections_.at("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections_.at("\\Y"); } else { - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); } - if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); - if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections.at("\\Y"); + if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections_.at("\\Y"); + if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections_.at("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); @@ -397,16 +397,16 @@ struct ShareWorker supercell->parameters["\\A_WIDTH"] = a_width; supercell->parameters["\\B_WIDTH"] = b_width; supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->connections["\\A"] = a; - supercell->connections["\\B"] = b; - supercell->connections["\\Y"] = y; + supercell->connections_["\\A"] = a; + supercell->connections_["\\B"] = b; + supercell->connections_["\\Y"] = y; supercell->check(); RTLIL::SigSpec new_y1(y, 0, y1.size()); RTLIL::SigSpec new_y2(y, 0, y2.size()); - module->connections.push_back(RTLIL::SigSig(y1, new_y1)); - module->connections.push_back(RTLIL::SigSig(y2, new_y2)); + module->connections_.push_back(RTLIL::SigSig(y1, new_y1)); + module->connections_.push_back(RTLIL::SigSig(y2, new_y2)); return supercell; } @@ -438,7 +438,7 @@ struct ShareWorker for (auto &bit : pbits) { if ((bit.cell->type == "$mux" || bit.cell->type == "$pmux") && bit.port == "\\S") - forbidden_controls_cache[cell].insert(bit.cell->connections.at("\\S").extract(bit.offset, 1)); + forbidden_controls_cache[cell].insert(bit.cell->connections_.at("\\S").extract(bit.offset, 1)); consumer_cells.insert(bit.cell); } @@ -532,9 +532,9 @@ struct ShareWorker std::set used_in_b_parts; int width = c->parameters.at("\\WIDTH").as_int(); - std::vector sig_a = modwalker.sigmap(c->connections.at("\\A")); - std::vector sig_b = modwalker.sigmap(c->connections.at("\\B")); - std::vector sig_s = modwalker.sigmap(c->connections.at("\\S")); + std::vector sig_a = modwalker.sigmap(c->connections_.at("\\A")); + std::vector sig_b = modwalker.sigmap(c->connections_.at("\\B")); + std::vector sig_s = modwalker.sigmap(c->connections_.at("\\S")); for (auto &bit : sig_a) if (cell_out_bits.count(bit)) @@ -572,7 +572,7 @@ struct ShareWorker if (activation_patterns_cache[cell].empty()) { log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; - module->connections.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); + module->connections_.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); cells_to_remove.insert(cell); } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index c047e418..ac0064f7 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -398,7 +398,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) { auto cell_type = cell->type; auto cell_name = cell->name; - auto cell_connections = cell->connections; + auto cell_connections = cell->connections_; module->remove(cell); cell_mapping &cm = cell_mappings[cell_type]; @@ -418,7 +418,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } else if (port.second != 0) log_abort(); - new_cell->connections["\\" + port.first] = sig; + new_cell->connections_["\\" + port.first] = sig; } stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type.c_str(), new_cell->type.c_str())]++; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index e52c8fe5..5dfcd63d 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -125,10 +125,10 @@ namespace RTLIL::Wire *lastHaystackWire = NULL; std::map emptyAttr; - for (auto &conn : needleCell->connections) + for (auto &conn : needleCell->connections_) { RTLIL::SigSpec needleSig = conn.second; - RTLIL::SigSpec haystackSig = haystackCell->connections.at(portMapping.at(conn.first)); + RTLIL::SigSpec haystackSig = haystackCell->connections_.at(portMapping.at(conn.first)); for (int i = 0; i < std::min(needleSig.size(), haystackSig.size()); i++) { RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire; @@ -186,7 +186,7 @@ namespace { RTLIL::Cell *cell = cell_it.second; if (!sel || sel->selected(mod, cell)) - for (auto &conn : cell->connections) { + for (auto &conn : cell->connections_) { RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); for (auto &bit : conn_sig) @@ -207,7 +207,7 @@ namespace type = type.substr(1); graph.createNode(cell->name, type, (void*)cell); - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) { graph.createPort(cell->name, conn.first, conn.second.size()); @@ -257,7 +257,7 @@ namespace { RTLIL::Cell *cell = cell_it.second; if (sel && !sel->selected(mod, cell)) - for (auto &conn : cell->connections) + for (auto &conn : cell->connections_) { RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); @@ -305,7 +305,7 @@ namespace if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair(wire->name, i)); - cell->connections[wire->name] = RTLIL::SigSpec(RTLIL::State::Sz, wire->width); + cell->connections_[wire->name] = RTLIL::SigSpec(RTLIL::State::Sz, wire->width); } } @@ -319,13 +319,13 @@ namespace if (needle_cell == NULL) continue; - for (auto &conn : needle_cell->connections) { + for (auto &conn : needle_cell->connections_) { RTLIL::SigSpec sig = sigmap(conn.second); if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { for (int i = 0; i < sig.size(); i++) for (auto &port : sig2port.find(sig[i])) { - RTLIL::SigSpec bitsig = haystack_cell->connections.at(mapping.portMapping[conn.first]).extract(i, 1); - cell->connections.at(port.first).replace(port.second, bitsig); + RTLIL::SigSpec bitsig = haystack_cell->connections_.at(mapping.portMapping[conn.first]).extract(i, 1); + cell->connections_.at(port.first).replace(port.second, bitsig); } } } @@ -714,7 +714,7 @@ struct ExtractPass : public Pass { cells.insert((RTLIL::Cell*)node.userData); for (auto cell : cells) - for (auto &conn : cell->connections) { + for (auto &conn : cell->connections_) { RTLIL::SigSpec sig = sigmap(conn.second); for (auto &chunk : sig.chunks()) if (chunk.wire != NULL) @@ -739,12 +739,12 @@ struct ExtractPass : public Pass { for (auto cell : cells) { RTLIL::Cell *newCell = newMod->addCell(cell->name, cell->type); newCell->parameters = cell->parameters; - for (auto &conn : cell->connections) { + for (auto &conn : cell->connections_) { std::vector chunks = sigmap(conn.second); for (auto &chunk : chunks) if (chunk.wire != NULL) chunk.wire = newMod->wires.at(chunk.wire->name); - newCell->connections[conn.first] = chunks; + newCell->connections_[conn.first] = chunks; } } } diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index e4153670..286ad8ac 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -35,7 +35,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_hi == RTLIL::State::Sm) { last_hi = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype)); - cell->connections[RTLIL::escape_id(hicell_portname)] = last_hi; + cell->connections_[RTLIL::escape_id(hicell_portname)] = last_hi; } bit = last_hi; } @@ -43,7 +43,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_lo == RTLIL::State::Sm) { last_lo = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype)); - cell->connections[RTLIL::escape_id(locell_portname)] = last_lo; + cell->connections_[RTLIL::escape_id(locell_portname)] = last_lo; } bit = last_lo; } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 7b2484d8..ba9bf51d 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -177,9 +177,9 @@ struct IopadmapPass : public Pass { for (int i = 0; i < wire->width; i++) { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, i); + cell->connections_[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, i); if (!portname2.empty()) - cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, i); + cell->connections_[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, i); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) @@ -190,9 +190,9 @@ struct IopadmapPass : public Pass { else { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->connections[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); + cell->connections_[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); if (!portname2.empty()) - cell->connections[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); + cell->connections_[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 8489e7fd..df7592ce 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -29,43 +29,43 @@ extern void simplemap_get_mappers(std::mapconnections.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections["\\A"] = sig_a[i]; - gate->connections["\\Y"] = sig_y[i]; + gate->connections_["\\A"] = sig_a[i]; + gate->connections_["\\Y"] = sig_y[i]; } } static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_a)); + module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a)); } static void simplemap_bu0(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_a)); + module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a)); } static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - RTLIL::SigSpec sig_b = cell->connections.at("\\B"); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_b = cell->connections_.at("\\B"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); sig_b.extend_u0(SIZE(sig_y), cell->parameters.at("\\B_SIGNED").as_bool()); @@ -76,8 +76,8 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections["\\A"] = sig_t[i]; - gate->connections["\\Y"] = sig_y[i]; + gate->connections_["\\A"] = sig_t[i]; + gate->connections_["\\Y"] = sig_y[i]; } sig_y = sig_t; @@ -92,31 +92,31 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections["\\A"] = sig_a[i]; - gate->connections["\\B"] = sig_b[i]; - gate->connections["\\Y"] = sig_y[i]; + gate->connections_["\\A"] = sig_a[i]; + gate->connections_["\\B"] = sig_b[i]; + gate->connections_["\\Y"] = sig_y[i]; } } static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); if (sig_y.size() == 0) return; if (sig_a.size() == 0) { - if (cell->type == "$reduce_and") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == "$reduce_or") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == "$reduce_xor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == "$reduce_xnor") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == "$reduce_bool") module->connections.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_and") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == "$reduce_or") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_xor") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_xnor") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == "$reduce_bool") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); return; } if (sig_y.size() > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); + module->connections_.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } @@ -142,10 +142,10 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections["\\A"] = sig_a[i]; - gate->connections["\\B"] = sig_a[i+1]; - gate->connections["\\Y"] = sig_t[i/2]; - last_output = &gate->connections["\\Y"]; + gate->connections_["\\A"] = sig_a[i]; + gate->connections_["\\B"] = sig_a[i+1]; + gate->connections_["\\Y"] = sig_t[i/2]; + last_output = &gate->connections_["\\Y"]; } sig_a = sig_t; @@ -154,14 +154,14 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$reduce_xnor") { RTLIL::SigSpec sig_t = module->addWire(NEW_ID); RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections["\\A"] = sig_a; - gate->connections["\\Y"] = sig_t; - last_output = &gate->connections["\\Y"]; + gate->connections_["\\A"] = sig_a; + gate->connections_["\\Y"] = sig_t; + last_output = &gate->connections_["\\Y"]; sig_a = sig_t; } if (last_output == NULL) { - module->connections.push_back(RTLIL::SigSig(sig_y, sig_a)); + module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a)); } else { *last_output = sig_y; } @@ -181,9 +181,9 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) } RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_"); - gate->connections["\\A"] = sig[i]; - gate->connections["\\B"] = sig[i+1]; - gate->connections["\\Y"] = sig_t[i/2]; + gate->connections_["\\A"] = sig[i]; + gate->connections_["\\B"] = sig[i+1]; + gate->connections_["\\Y"] = sig_t[i/2]; } sig = sig_t; @@ -195,39 +195,39 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); logic_reduce(module, sig_a); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); if (sig_y.size() == 0) return; if (sig_y.size() > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); + module->connections_.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections["\\A"] = sig_a; - gate->connections["\\Y"] = sig_y; + gate->connections_["\\A"] = sig_a; + gate->connections_["\\Y"] = sig_y; } static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); logic_reduce(module, sig_a); - RTLIL::SigSpec sig_b = cell->connections.at("\\B"); + RTLIL::SigSpec sig_b = cell->connections_.at("\\B"); logic_reduce(module, sig_b); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); if (sig_y.size() == 0) return; if (sig_y.size() > 1) { - module->connections.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); + module->connections_.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } @@ -237,40 +237,40 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) log_assert(!gate_type.empty()); RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections["\\A"] = sig_a; - gate->connections["\\B"] = sig_b; - gate->connections["\\Y"] = sig_y; + gate->connections_["\\A"] = sig_a; + gate->connections_["\\B"] = sig_b; + gate->connections_["\\Y"] = sig_y; } static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - RTLIL::SigSpec sig_b = cell->connections.at("\\B"); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_b = cell->connections_.at("\\B"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_"); - gate->connections["\\A"] = sig_a[i]; - gate->connections["\\B"] = sig_b[i]; - gate->connections["\\S"] = cell->connections.at("\\S"); - gate->connections["\\Y"] = sig_y[i]; + gate->connections_["\\A"] = sig_a[i]; + gate->connections_["\\B"] = sig_b[i]; + gate->connections_["\\S"] = cell->connections_.at("\\S"); + gate->connections_["\\Y"] = sig_y[i]; } } static void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) { int offset = cell->parameters.at("\\OFFSET").as_int(); - RTLIL::SigSpec sig_a = cell->connections.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); + RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); } static void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_ab = cell->connections.at("\\A"); - sig_ab.append(cell->connections.at("\\B")); - RTLIL::SigSpec sig_y = cell->connections.at("\\Y"); - module->connections.push_back(RTLIL::SigSig(sig_y, sig_ab)); + RTLIL::SigSpec sig_ab = cell->connections_.at("\\A"); + sig_ab.append(cell->connections_.at("\\B")); + RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + module->connections_.push_back(RTLIL::SigSig(sig_y, sig_ab)); } static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) @@ -279,17 +279,17 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_s = cell->connections.at("\\SET"); - RTLIL::SigSpec sig_r = cell->connections.at("\\CLR"); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); + RTLIL::SigSpec sig_s = cell->connections_.at("\\SET"); + RTLIL::SigSpec sig_r = cell->connections_.at("\\CLR"); + RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections["\\S"] = sig_s[i]; - gate->connections["\\R"] = sig_r[i]; - gate->connections["\\Q"] = sig_q[i]; + gate->connections_["\\S"] = sig_s[i]; + gate->connections_["\\R"] = sig_r[i]; + gate->connections_["\\Q"] = sig_q[i]; } } @@ -298,17 +298,17 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) int width = cell->parameters.at("\\WIDTH").as_int(); char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->connections.at("\\CLK"); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); + RTLIL::SigSpec sig_clk = cell->connections_.at("\\CLK"); + RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); + RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); std::string gate_type = stringf("$_DFF_%c_", clk_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections["\\C"] = sig_clk; - gate->connections["\\D"] = sig_d[i]; - gate->connections["\\Q"] = sig_q[i]; + gate->connections_["\\C"] = sig_clk; + gate->connections_["\\D"] = sig_d[i]; + gate->connections_["\\Q"] = sig_q[i]; } } @@ -319,21 +319,21 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->connections.at("\\CLK"); - RTLIL::SigSpec sig_s = cell->connections.at("\\SET"); - RTLIL::SigSpec sig_r = cell->connections.at("\\CLR"); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); + RTLIL::SigSpec sig_clk = cell->connections_.at("\\CLK"); + RTLIL::SigSpec sig_s = cell->connections_.at("\\SET"); + RTLIL::SigSpec sig_r = cell->connections_.at("\\CLR"); + RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); + RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); std::string gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections["\\C"] = sig_clk; - gate->connections["\\S"] = sig_s[i]; - gate->connections["\\R"] = sig_r[i]; - gate->connections["\\D"] = sig_d[i]; - gate->connections["\\Q"] = sig_q[i]; + gate->connections_["\\C"] = sig_clk; + gate->connections_["\\S"] = sig_s[i]; + gate->connections_["\\R"] = sig_r[i]; + gate->connections_["\\D"] = sig_d[i]; + gate->connections_["\\Q"] = sig_q[i]; } } @@ -347,20 +347,20 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) while (int(rst_val.size()) < width) rst_val.push_back(RTLIL::State::S0); - RTLIL::SigSpec sig_clk = cell->connections.at("\\CLK"); - RTLIL::SigSpec sig_rst = cell->connections.at("\\ARST"); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); + RTLIL::SigSpec sig_clk = cell->connections_.at("\\CLK"); + RTLIL::SigSpec sig_rst = cell->connections_.at("\\ARST"); + RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); + RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); std::string gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); std::string gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); - gate->connections["\\C"] = sig_clk; - gate->connections["\\R"] = sig_rst; - gate->connections["\\D"] = sig_d[i]; - gate->connections["\\Q"] = sig_q[i]; + gate->connections_["\\C"] = sig_clk; + gate->connections_["\\R"] = sig_rst; + gate->connections_["\\D"] = sig_d[i]; + gate->connections_["\\Q"] = sig_q[i]; } } @@ -369,17 +369,17 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) int width = cell->parameters.at("\\WIDTH").as_int(); char en_pol = cell->parameters.at("\\EN_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_en = cell->connections.at("\\EN"); - RTLIL::SigSpec sig_d = cell->connections.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections.at("\\Q"); + RTLIL::SigSpec sig_en = cell->connections_.at("\\EN"); + RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); + RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); std::string gate_type = stringf("$_DLATCH_%c_", en_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections["\\E"] = sig_en; - gate->connections["\\D"] = sig_d[i]; - gate->connections["\\Q"] = sig_q[i]; + gate->connections_["\\E"] = sig_en; + gate->connections_["\\D"] = sig_d[i]; + gate->connections_["\\Q"] = sig_q[i]; } } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 94cb1e8d..ab95c003 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -141,7 +141,7 @@ struct TechmapWorker SigMap port_signal_map; - for (auto &it : cell->connections) { + for (auto &it : cell->connections_) { RTLIL::IdString portname = it.first; if (positional_ports.count(portname) > 0) portname = positional_ports.at(portname); @@ -169,7 +169,7 @@ struct TechmapWorker if (flatten_mode) { // more conservative approach: // connect internal and external wires - module->connections.push_back(c); + module->connections_.push_back(c); } else { // approach that yields nicer outputs: // replace internal wires that are connected to external wires @@ -195,19 +195,19 @@ struct TechmapWorker if (!flatten_mode && c->type.substr(0, 2) == "\\$") c->type = c->type.substr(1); - for (auto &it2 : c->connections) { + for (auto &it2 : c->connections_) { apply_prefix(cell->name, it2.second, module); port_signal_map.apply(it2.second); } } - for (auto &it : tpl->connections) { + for (auto &it : tpl->connections_) { RTLIL::SigSig c = it; apply_prefix(cell->name, c.first, module); apply_prefix(cell->name, c.second, module); port_signal_map.apply(c.first); port_signal_map.apply(c.second); - module->connections.push_back(c); + module->connections_.push_back(c); } module->remove(cell); @@ -262,7 +262,7 @@ struct TechmapWorker break; } - for (auto conn : cell->connections) { + for (auto conn : cell->connections_) { if (conn.first.substr(0, 1) == "$") continue; if (tpl->wires.count(conn.first) > 0 && tpl->wires.at(conn.first)->port_id > 0) @@ -280,7 +280,7 @@ struct TechmapWorker if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0) parameters["\\_TECHMAP_CELLTYPE_"] = RTLIL::unescape_id(cell->type); - for (auto conn : cell->connections) { + for (auto conn : cell->connections_) { if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) { std::vector v = sigmap(conn.second).to_sigbit_vector(); for (auto &bit : v) @@ -303,7 +303,7 @@ struct TechmapWorker unique_bit_id[RTLIL::State::Sx] = unique_bit_id_counter++; unique_bit_id[RTLIL::State::Sz] = unique_bit_id_counter++; - for (auto conn : cell->connections) + for (auto conn : cell->connections_) if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) { for (auto &bit : sigmap(conn.second).to_sigbit_vector()) if (unique_bit_id.count(bit) == 0) @@ -317,7 +317,7 @@ struct TechmapWorker if (tpl->avail_parameters.count("\\_TECHMAP_BITS_CONNMAP_")) parameters["\\_TECHMAP_BITS_CONNMAP_"] = bits; - for (auto conn : cell->connections) + for (auto conn : cell->connections_) if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) { RTLIL::Const value; for (auto &bit : sigmap(conn.second).to_sigbit_vector()) { From e75e495c2bddb62634c6d50f90e09e0ff358faa5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 12:22:58 +0200 Subject: [PATCH 428/750] Added new RTLIL::Cell port access methods --- kernel/rtlil.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 8 +++++++ 2 files changed, 71 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 4d0aadbb..27063aea 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1330,6 +1330,26 @@ RTLIL::Memory::Memory() size = 0; } +void RTLIL::Cell::unset(RTLIL::IdString portname) +{ + connections_.erase(portname); +} + +void RTLIL::Cell::set(RTLIL::IdString portname, RTLIL::SigSpec signal) +{ + connections_[portname] = signal; +} + +RTLIL::SigSpec RTLIL::Cell::get(RTLIL::IdString portname) const +{ + return connections_.at(portname); +} + +const std::map &RTLIL::Cell::connections() +{ + return connections_; +} + void RTLIL::Cell::check() { #ifndef NDEBUG @@ -1338,6 +1358,49 @@ void RTLIL::Cell::check() #endif } +void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) +{ + if (type[0] != '$' || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || + type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:") + return; + + if (type == "$mux" || type == "$pmux" || type == "$safe_pmux") + { + parameters["\\WIDTH"] = SIZE(connections_["\\Y"]); + if (type == "$pmux" || type == "$safe_pmux") + parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]); + check(); + return; + } + + bool signedness_ab = type != "$slice" && type != "$concat"; + + if (connections_.count("\\A")) { + if (signedness_ab) { + if (set_a_signed) + parameters["\\A_SIGNED"] = true; + else if (parameters.count("\\A_SIGNED") == 0) + parameters["\\A_SIGNED"] = false; + } + parameters["\\A_WIDTH"] = SIZE(connections_["\\A"]); + } + + if (connections_.count("\\B")) { + if (signedness_ab) { + if (set_b_signed) + parameters["\\B_SIGNED"] = true; + else if (parameters.count("\\B_SIGNED") == 0) + parameters["\\B_SIGNED"] = false; + } + parameters["\\B_WIDTH"] = SIZE(connections_["\\B"]); + } + + if (connections_.count("\\Y")) + parameters["\\Y_WIDTH"] = SIZE(connections_["\\Y"]); + + check(); +} + RTLIL::SigChunk::SigChunk() { wire = NULL; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 96bda753..0b92405e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -484,7 +484,15 @@ public: std::map connections_; std::map parameters; RTLIL_ATTRIBUTE_MEMBERS + + // access cell ports + void unset(RTLIL::IdString portname); + void set(RTLIL::IdString portname, RTLIL::SigSpec signal); + RTLIL::SigSpec get(RTLIL::IdString portname) const; + const std::map &connections(); + void check(); + void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); template void rewrite_sigspecs(T functor); }; From 3719281ed44aa9d8b2ac11eb936b750c4642be38 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 13:59:30 +0200 Subject: [PATCH 429/750] Automatically pack SigSpec on copy/assign --- kernel/rtlil.cc | 75 ++++++++++++++++++++++++++++++++++++++----------- kernel/rtlil.h | 3 ++ 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 27063aea..2378e95c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1518,6 +1518,48 @@ RTLIL::SigSpec::SigSpec() hash_ = 0; } +RTLIL::SigSpec::SigSpec(const RTLIL::SigSpec &other) +{ + *this = other; +} + +const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other) +{ + cover("kernel.rtlil.sigspec.assign"); + + width_ = other.width_; + hash_ = other.hash_; + chunks_ = other.chunks_; + bits_.clear(); + + if (!other.bits_.empty()) + { + RTLIL::SigChunk *last = NULL; + int last_end_offset = 0; + + for (auto &bit : other.bits_) { + if (last && bit.wire == last->wire) { + if (bit.wire == NULL) { + last->data.bits.push_back(bit.data); + last->width++; + continue; + } else if (last_end_offset == bit.offset) { + last_end_offset++; + last->width++; + continue; + } + } + chunks_.push_back(bit); + last = &chunks_.back(); + last_end_offset = bit.offset + 1; + } + + check(); + } + + return *this; +} + RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) { chunks_.push_back(RTLIL::SigChunk(value)); @@ -1626,24 +1668,25 @@ void RTLIL::SigSpec::pack() const std::vector old_bits; old_bits.swap(that->bits_); - RTLIL::SigChunk *last_const = NULL; - RTLIL::SigChunk *last_wire = NULL; - int last_wire_end = 0; + RTLIL::SigChunk *last = NULL; + int last_end_offset = 0; - for (auto &bit : old_bits) - if (bit.wire == NULL && last_const) { - last_const->data.bits.push_back(bit.data); - last_const->width++; - } else - if (bit.wire && last_wire && last_wire->wire == bit.wire && last_wire_end == bit.offset) { - last_wire->width++; - last_wire_end++; - } else { - that->chunks_.push_back(bit); - last_const = bit.wire ? NULL : &that->chunks_.back(); - last_wire = bit.wire ? &that->chunks_.back() : NULL; - last_wire_end = bit.offset + 1; + for (auto &bit : old_bits) { + if (last && bit.wire == last->wire) { + if (bit.wire == NULL) { + last->data.bits.push_back(bit.data); + last->width++; + continue; + } else if (last_end_offset == bit.offset) { + last_end_offset++; + last->width++; + continue; + } } + that->chunks_.push_back(bit); + last = &that->chunks_.back(); + last_end_offset = bit.offset + 1; + } check(); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0b92405e..a2320873 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -567,6 +567,9 @@ private: public: SigSpec(); + SigSpec(const RTLIL::SigSpec &other); + const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other); + SigSpec(const RTLIL::Const &value); SigSpec(const RTLIL::SigChunk &chunk); SigSpec(RTLIL::Wire *wire); From b90f443338460f1f906fc8e342130ab428e343ad Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:08:20 +0200 Subject: [PATCH 430/750] Added "passed" message to make test targets --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index da4d7fac..b87a7474 100644 --- a/Makefile +++ b/Makefile @@ -226,14 +226,23 @@ test: $(TARGETS) $(EXTRA_TARGETS) cd tests/techmap && bash run-test.sh cd tests/memories && bash run-test.sh cd tests/sat && bash run-test.sh + @echo "" + @echo " Passed \"make test\"." + @echo "" VALGRIND ?= valgrind --error-exitcode=1 --leak-check=full --show-reachable=yes --errors-for-leak-kinds=all vgtest: $(TARGETS) $(EXTRA_TARGETS) $(VALGRIND) ./yosys -p 'setattr -mod -unset top; hierarchy; proc; opt; memory -nomap; opt -fine; techmap; opt' $$( ls tests/simple/*.v | grep -v repwhile.v ) + @echo "" + @echo " Passed \"make vgtest\"." + @echo "" vloghtb: $(TARGETS) $(EXTRA_TARGETS) cd tests/vloghtb && bash run-test.sh + @echo "" + @echo " Passed \"make vloghtb\"." + @echo "" install: $(TARGETS) $(EXTRA_TARGETS) $(INSTALL_SUDO) mkdir -p $(DESTDIR)/bin From 027819c7e8ba3b1f9c7eb4864fa221a4f3b01092 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:08:43 +0200 Subject: [PATCH 431/750] Use "wget -N" in tests/vloghtb/run-test.sh --- tests/vloghtb/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh index 3b8a3e9e..b1b205a2 100755 --- a/tests/vloghtb/run-test.sh +++ b/tests/vloghtb/run-test.sh @@ -2,8 +2,8 @@ set -ex -rm -rf Makefile refdat rtl scripts spec vloghammer_tb.tar.bz2 -wget http://www.clifford.at/yosys/nogit/vloghammer_tb.tar.bz2 +rm -rf Makefile refdat rtl scripts spec +wget -N http://www.clifford.at/yosys/nogit/vloghammer_tb.tar.bz2 tar --strip=1 -xjf vloghammer_tb.tar.bz2 make clean From b03aec6e3212a387e3d255583476d472d16663f1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:31:47 +0200 Subject: [PATCH 432/750] Added RTLIL::Module::connect(const RTLIL::SigSig&) --- kernel/rtlil.cc | 5 +++++ kernel/rtlil.h | 1 + 2 files changed, 6 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2378e95c..ce4ecea6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -873,6 +873,11 @@ static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) return a->port_id < b->port_id; } +void RTLIL::Module::connect(const RTLIL::SigSig &conn) +{ + connections_.push_back(conn); +} + void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs) { connections_.push_back(RTLIL::SigSig(lhs, rhs)); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a2320873..4f91b720 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -288,6 +288,7 @@ struct RTLIL::Module virtual void check(); virtual void optimize(); + void connect(const RTLIL::SigSig &conn); void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); void fixup_ports(); From 7ac9dc7f6eab40b3853583848933c4a8a94df9c9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:38:33 +0200 Subject: [PATCH 433/750] Added RTLIL::Module::connections() --- kernel/rtlil.cc | 5 +++++ kernel/rtlil.h | 1 + 2 files changed, 6 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ce4ecea6..1638682c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -883,6 +883,11 @@ void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs connections_.push_back(RTLIL::SigSig(lhs, rhs)); } +const std::vector &RTLIL::Module::connections() +{ + return connections_; +} + void RTLIL::Module::fixup_ports() { std::vector all_ports; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 4f91b720..1775975d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -290,6 +290,7 @@ struct RTLIL::Module void connect(const RTLIL::SigSig &conn); void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); + const std::vector &connections(); void fixup_ports(); template void rewrite_sigspecs(T functor); From cd6574ecf652901573cbc6b89e1a59dd383ec496 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 15:57:27 +0200 Subject: [PATCH 434/750] Added some missing "const" in rtlil.h --- kernel/rtlil.cc | 10 +++++----- kernel/rtlil.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1638682c..73f5d71f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -883,7 +883,7 @@ void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs connections_.push_back(RTLIL::SigSig(lhs, rhs)); } -const std::vector &RTLIL::Module::connections() +const std::vector &RTLIL::Module::connections() const { return connections_; } @@ -1350,12 +1350,12 @@ void RTLIL::Cell::set(RTLIL::IdString portname, RTLIL::SigSpec signal) connections_[portname] = signal; } -RTLIL::SigSpec RTLIL::Cell::get(RTLIL::IdString portname) const +const RTLIL::SigSpec &RTLIL::Cell::get(RTLIL::IdString portname) const { return connections_.at(portname); } -const std::map &RTLIL::Cell::connections() +const std::map &RTLIL::Cell::connections() const { return connections_; } @@ -1839,7 +1839,7 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe check(); } -RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const +RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other) const { if (other) cover("kernel.rtlil.sigspec.extract_other"); @@ -1859,7 +1859,7 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *o RTLIL::SigSpec ret; if (other) { - std::vector bits_other = other ? other->to_sigbit_vector() : bits_match; + std::vector bits_other = other->to_sigbit_vector(); for (int i = 0; i < width_; i++) if (bits_match[i].wire && pat.count(bits_match[i])) ret.append_bit(bits_other[i]); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1775975d..25d0a830 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -290,7 +290,7 @@ struct RTLIL::Module void connect(const RTLIL::SigSig &conn); void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); - const std::vector &connections(); + const std::vector &connections() const; void fixup_ports(); template void rewrite_sigspecs(T functor); @@ -490,8 +490,8 @@ public: // access cell ports void unset(RTLIL::IdString portname); void set(RTLIL::IdString portname, RTLIL::SigSpec signal); - RTLIL::SigSpec get(RTLIL::IdString portname) const; - const std::map &connections(); + const RTLIL::SigSpec &get(RTLIL::IdString portname) const; + const std::map &connections() const; void check(); void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); @@ -608,7 +608,7 @@ public: void remove(int offset, int length = 1); void remove_const(); - RTLIL::SigSpec extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(int offset, int length = 1) const; void append(const RTLIL::SigSpec &signal); From b7dda723022ad00c6c0089be888eab319953faa8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:32:50 +0200 Subject: [PATCH 435/750] 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;' --- backends/blif/blif.cc | 24 ++-- backends/btor/btor.cc | 68 +++++----- backends/edif/edif.cc | 4 +- backends/ilang/ilang_backend.cc | 4 +- backends/intersynth/intersynth.cc | 2 +- backends/spice/spice.cc | 8 +- backends/verilog/verilog_backend.cc | 86 ++++++------ frontends/ast/genrtlil.cc | 48 +++---- frontends/ilang/parser.y | 4 +- frontends/liberty/liberty.cc | 124 ++++++++--------- kernel/consteval.h | 18 +-- kernel/modwalker.h | 4 +- kernel/rtlil.cc | 164 +++++++++++----------- kernel/satgen.h | 170 +++++++++++------------ kernel/sigtools.h | 2 +- manual/CHAPTER_Prog/stubnets.cc | 2 +- passes/abc/abc.cc | 84 ++++++------ passes/abc/blifparse.cc | 12 +- passes/cmds/add.cc | 4 +- passes/cmds/connect.cc | 10 +- passes/cmds/connwrappers.cc | 4 +- passes/cmds/scatter.cc | 6 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 4 +- passes/cmds/setundef.cc | 4 +- passes/cmds/show.cc | 10 +- passes/cmds/splice.cc | 20 +-- passes/cmds/splitnets.cc | 2 +- passes/fsm/fsm_detect.cc | 18 +-- passes/fsm/fsm_expand.cc | 56 ++++---- passes/fsm/fsm_extract.cc | 38 +++--- passes/fsm/fsm_map.cc | 56 ++++---- passes/fsm/fsm_opt.cc | 16 +-- passes/fsm/fsmdata.h | 4 +- passes/hierarchy/hierarchy.cc | 10 +- passes/hierarchy/submod.cc | 12 +- passes/memory/memory_collect.cc | 28 ++-- passes/memory/memory_dff.cc | 38 +++--- passes/memory/memory_map.cc | 74 +++++----- passes/memory/memory_share.cc | 102 +++++++------- passes/memory/memory_unpack.cc | 14 +- passes/opt/opt_clean.cc | 16 +-- passes/opt/opt_const.cc | 202 ++++++++++++++-------------- passes/opt/opt_muxtree.cc | 26 ++-- passes/opt/opt_reduce.cc | 78 +++++------ passes/opt/opt_rmdff.cc | 52 +++---- passes/opt/opt_share.cc | 16 +-- passes/proc/proc_arst.cc | 44 +++--- passes/proc/proc_dff.cc | 90 ++++++------- passes/proc/proc_mux.cc | 30 ++--- passes/sat/expose.cc | 72 +++++----- passes/sat/freduce.cc | 14 +- passes/sat/miter.cc | 58 ++++---- passes/sat/sat.cc | 4 +- passes/sat/share.cc | 84 ++++++------ passes/techmap/dfflibmap.cc | 4 +- passes/techmap/extract.cc | 24 ++-- passes/techmap/hilomap.cc | 4 +- passes/techmap/iopadmap.cc | 8 +- passes/techmap/simplemap.cc | 198 +++++++++++++-------------- passes/techmap/techmap.cc | 18 +-- 61 files changed, 1201 insertions(+), 1201 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 8d80eccd..cb40834b 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -146,56 +146,56 @@ struct BlifDumper if (!config->icells_mode && cell->type == "$_INV_") { fprintf(f, ".names %s %s\n0 1\n", - cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\Y"))); + cstr(cell->get("\\A")), cstr(cell->get("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_AND_") { fprintf(f, ".names %s %s %s\n11 1\n", - cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), cstr(cell->connections_.at("\\Y"))); + cstr(cell->get("\\A")), cstr(cell->get("\\B")), cstr(cell->get("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_OR_") { fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n", - cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), cstr(cell->connections_.at("\\Y"))); + cstr(cell->get("\\A")), cstr(cell->get("\\B")), cstr(cell->get("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_XOR_") { fprintf(f, ".names %s %s %s\n10 1\n01 1\n", - cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), cstr(cell->connections_.at("\\Y"))); + cstr(cell->get("\\A")), cstr(cell->get("\\B")), cstr(cell->get("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_MUX_") { fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n", - cstr(cell->connections_.at("\\A")), cstr(cell->connections_.at("\\B")), - cstr(cell->connections_.at("\\S")), cstr(cell->connections_.at("\\Y"))); + cstr(cell->get("\\A")), cstr(cell->get("\\B")), + cstr(cell->get("\\S")), cstr(cell->get("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_N_") { fprintf(f, ".latch %s %s fe %s\n", - cstr(cell->connections_.at("\\D")), cstr(cell->connections_.at("\\Q")), cstr(cell->connections_.at("\\C"))); + cstr(cell->get("\\D")), cstr(cell->get("\\Q")), cstr(cell->get("\\C"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_P_") { fprintf(f, ".latch %s %s re %s\n", - cstr(cell->connections_.at("\\D")), cstr(cell->connections_.at("\\Q")), cstr(cell->connections_.at("\\C"))); + cstr(cell->get("\\D")), cstr(cell->get("\\Q")), cstr(cell->get("\\C"))); continue; } if (!config->icells_mode && cell->type == "$lut") { fprintf(f, ".names"); - auto &inputs = cell->connections_.at("\\I"); + auto &inputs = cell->get("\\I"); auto width = cell->parameters.at("\\WIDTH").as_int(); log_assert(inputs.size() == width); for (int i = 0; i < inputs.size(); i++) { fprintf(f, " %s", cstr(inputs.extract(i, 1))); } - auto &output = cell->connections_.at("\\O"); + auto &output = cell->get("\\O"); log_assert(output.size() == 1); fprintf(f, " %s", cstr(output)); fprintf(f, "\n"); @@ -211,7 +211,7 @@ struct BlifDumper } fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type)); - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) for (int i = 0; i < conn.second.size(); i++) { if (conn.second.size() == 1) fprintf(f, " %s", cstr(conn.first)); @@ -240,7 +240,7 @@ struct BlifDumper } } - for (auto &conn : module->connections_) + for (auto &conn : module->connections()) for (int i = 0; i < conn.first.size(); i++) if (config->conn_mode) fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 46edec9c..0316f7ab 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -387,8 +387,8 @@ struct BtorDumper if(cell->type == "$assert") { log("writing assert cell - %s\n", cstr(cell->type)); - const RTLIL::SigSpec* expr = &cell->connections_.at(RTLIL::IdString("\\A")); - const RTLIL::SigSpec* en = &cell->connections_.at(RTLIL::IdString("\\EN")); + const RTLIL::SigSpec* expr = &cell->connections().at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* en = &cell->connections().at(RTLIL::IdString("\\EN")); log_assert(expr->size() == 1); log_assert(en->size() == 1); int expr_line = dump_sigspec(expr, 1); @@ -420,7 +420,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); w = w>output_width ? w:output_width; //padding of w - int l = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), w); int cell_line = l; if(cell->type != "$pos") { @@ -444,7 +444,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), w); if(cell->type == "$logic_not" && w > 1) { ++line_num; @@ -481,8 +481,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -515,8 +515,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -550,8 +550,8 @@ struct BtorDumper l1_width = pow(2, ceil(log(l1_width)/log(2))); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); //assert(l2_width <= ceil(log(l1_width)/log(2)) ); - int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); + int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); int cell_output = ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), l1_width, l1, l2); fprintf(f, "%s\n", str.c_str()); @@ -559,7 +559,7 @@ struct BtorDumper if(l2_width > ceil(log(l1_width)/log(2))) { int extra_width = l2_width - ceil(log(l1_width)/log(2)); - l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), l2_width); + l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), l2_width); ++line_num; str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width); fprintf(f, "%s\n", str.c_str()); @@ -592,8 +592,8 @@ struct BtorDumper log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), output_width); + int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), output_width); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); if(l1_width >1) @@ -628,9 +628,9 @@ struct BtorDumper { log("writing mux cell\n"); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int l1 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\B")), output_width); - int s = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\S")), 1); + int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), output_width); + int s = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\S")), 1); ++line_num; str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell @@ -644,10 +644,10 @@ struct BtorDumper log("writing cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); log(" - width is %d\n", output_width); - int cond = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\CLK")), 1); + int cond = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - const RTLIL::SigSpec* cell_output = &cell->connections_.at(RTLIL::IdString("\\Q")); - int value = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\D")), output_width); + const RTLIL::SigSpec* cell_output = &cell->connections().at(RTLIL::IdString("\\Q")); + int value = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\D")), output_width); unsigned start_bit = 0; for(unsigned i=0; ichunks().size(); ++i) { @@ -665,9 +665,9 @@ struct BtorDumper } if(cell->type == "$dffsr") { - int sync_reset = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\CLR")), 1); + int sync_reset = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\CLR")), 1); bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); - int sync_reset_value = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\SET")), + int sync_reset_value = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\SET")), output_width); bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); ++line_num; @@ -685,7 +685,7 @@ struct BtorDumper int next = line_num; if(cell->type == "$adff") { - int async_reset = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\ARST")), 1); + int async_reset = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\ARST")), 1); bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), output_width, 0); @@ -710,7 +710,7 @@ struct BtorDumper str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); ++line_num; str = stringf("%d read %d %d %d", line_num, data_width, mem, address); @@ -722,13 +722,13 @@ struct BtorDumper log("writing memwr cell\n"); if (cell->parameters.at("\\CLK_ENABLE").as_bool() == false) log_error("The btor backen does not support $memwr cells without built-in registers. Run memory_dff (but with -wr_only).\n"); - int clk = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\CLK")), 1); + int clk = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - int enable = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\EN")), 1); + int enable = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\EN")), 1); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int data = dump_sigspec(&cell->connections_.at(RTLIL::IdString("\\DATA")), data_width); + int data = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\DATA")), data_width); str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); ++line_num; @@ -757,11 +757,11 @@ struct BtorDumper else if(cell->type == "$slice") { log("writing slice cell\n"); - const RTLIL::SigSpec* input = &cell->connections_.at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input = &cell->connections().at(RTLIL::IdString("\\A")); int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input->size() == input_width); int input_line = dump_sigspec(input, input_width); - const RTLIL::SigSpec* output = &cell->connections_.at(RTLIL::IdString("\\Y")); + const RTLIL::SigSpec* output = &cell->connections().at(RTLIL::IdString("\\Y")); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output->size() == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); @@ -773,11 +773,11 @@ struct BtorDumper else if(cell->type == "$concat") { log("writing concat cell\n"); - const RTLIL::SigSpec* input_a = &cell->connections_.at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input_a = &cell->connections().at(RTLIL::IdString("\\A")); int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input_a->size() == input_a_width); int input_a_line = dump_sigspec(input_a, input_a_width); - const RTLIL::SigSpec* input_b = &cell->connections_.at(RTLIL::IdString("\\B")); + const RTLIL::SigSpec* input_b = &cell->connections().at(RTLIL::IdString("\\B")); int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); log_assert(input_b->size() == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); @@ -801,7 +801,7 @@ struct BtorDumper RTLIL::SigSpec *output_sig = nullptr; if (cell->type == "$memrd") { - output_sig = &cell->connections_.at(RTLIL::IdString("\\DATA")); + output_sig = &cell->connections().at(RTLIL::IdString("\\DATA")); } else if(cell->type == "$memwr" || cell->type == "$assert") { @@ -809,11 +809,11 @@ struct BtorDumper } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - output_sig = &cell->connections_.at(RTLIL::IdString("\\Q")); + output_sig = &cell->connections().at(RTLIL::IdString("\\Q")); } else { - output_sig = &cell->connections_.at(RTLIL::IdString("\\Y")); + output_sig = &cell->connections().at(RTLIL::IdString("\\Y")); } return output_sig; } diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 13ab4dc6..fc2f4a7e 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -148,7 +148,7 @@ struct EdifBackend : public Backend { RTLIL::Cell *cell = cell_it.second; if (!design->modules.count(cell->type) || design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) { lib_cell_ports[cell->type]; - for (auto p : cell->connections_) { + for (auto p : cell->connections()) { if (p.second.size() > 1) log_error("Found multi-bit port %s on library cell %s.%s (%s): not supported in EDIF backend!\n", RTLIL::id2cstr(p.first), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); @@ -304,7 +304,7 @@ struct EdifBackend : public Backend { fprintf(f, "\n (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str()); } fprintf(f, ")\n"); - for (auto &p : cell->connections_) { + for (auto &p : cell->connections()) { RTLIL::SigSpec sig = sigmap(p.second); for (int i = 0; i < SIZE(sig); i++) if (sig.size() == 1) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index 0e329fc9..6678f19d 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -163,7 +163,7 @@ void ILANG_BACKEND::dump_cell(FILE *f, std::string indent, const RTLIL::Cell *ce dump_const(f, it->second); fprintf(f, "\n"); } - for (auto it = cell->connections_.begin(); it != cell->connections_.end(); it++) { + for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) { fprintf(f, "%s connect %s ", indent.c_str(), it->first.c_str()); dump_sigspec(f, it->second); fprintf(f, "\n"); @@ -309,7 +309,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module } bool first_conn_line = true; - for (auto it = module->connections_.begin(); it != module->connections_.end(); it++) { + for (auto it = module->connections().begin(); it != module->connections().end(); it++) { bool show_conn = !only_selected; if (only_selected) { RTLIL::SigSpec sigs = it->first; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 8231f1d8..8c08747c 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -169,7 +169,7 @@ struct IntersynthBackend : public Backend { celltype_code = stringf("celltype %s", RTLIL::id2cstr(cell->type)); node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); - for (auto &port : cell->connections_) { + for (auto &port : cell->connections()) { RTLIL::SigSpec sig = sigmap(port.second); if (sig.size() != 0) { conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size())); diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index a3784f11..4bc8710e 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -58,7 +58,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de { log("Warning: no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n", RTLIL::id2cstr(cell->type), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name)); - for (auto &conn : cell->connections_) { + for (auto &conn : cell->connections()) { RTLIL::SigSpec sig = sigmap(conn.second); port_sigs.push_back(sig); } @@ -80,8 +80,8 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de for (RTLIL::Wire *wire : ports) { log_assert(wire != NULL); RTLIL::SigSpec sig(RTLIL::State::Sz, wire->width); - if (cell->connections_.count(wire->name) > 0) { - sig = sigmap(cell->connections_.at(wire->name)); + if (cell->connections().count(wire->name) > 0) { + sig = sigmap(cell->connections().at(wire->name)); sig.extend(wire->width, false); } port_sigs.push_back(sig); @@ -98,7 +98,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de fprintf(f, " %s\n", RTLIL::id2cstr(cell->type)); } - for (auto &conn : module->connections_) + for (auto &conn : module->connections()) for (int i = 0; i < conn.first.size(); i++) { fprintf(f, "V%d", conn_counter++); print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index d3b5d52d..aa2f88fa 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -293,17 +293,17 @@ void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_ { if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) { fprintf(f, "$signed("); - dump_sigspec(f, cell->connections_["\\" + port]); + dump_sigspec(f, cell->connections()["\\" + port]); fprintf(f, ")"); } else - dump_sigspec(f, cell->connections_["\\" + port]); + dump_sigspec(f, cell->connections()["\\" + port]); } std::string cellname(RTLIL::Cell *cell) { - if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections_.count("\\Q") > 0) + if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections().count("\\Q") > 0) { - RTLIL::SigSpec sig = cell->connections_["\\Q"]; + RTLIL::SigSpec sig = cell->get("\\Q"); if (SIZE(sig) != 1 || sig.is_fully_const()) goto no_special_reg_name; @@ -338,7 +338,7 @@ no_special_reg_name: void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = %s ", op.c_str()); dump_attributes(f, "", cell->attributes, ' '); dump_cell_expr_port(f, cell, "A", true); @@ -348,7 +348,7 @@ void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::s void dump_cell_expr_binop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = "); dump_cell_expr_port(f, cell, "A", true); fprintf(f, " %s ", op.c_str()); @@ -361,7 +361,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) { if (cell->type == "$_INV_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = "); fprintf(f, "~"); dump_attributes(f, "", cell->attributes, ' '); @@ -372,7 +372,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = "); dump_cell_expr_port(f, cell, "A", false); fprintf(f, " "); @@ -391,7 +391,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$_MUX_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = "); dump_cell_expr_port(f, cell, "S", false); fprintf(f, " ? "); @@ -406,23 +406,23 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type.substr(0, 6) == "$_DFF_") { std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->connections_["\\Q"], reg_name); + bool out_is_reg_wire = is_reg_wire(cell->get("\\Q"), reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); fprintf(f, "%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections_["\\C"]); + dump_sigspec(f, cell->get("\\C")); if (cell->type[7] != '_') { fprintf(f, " or %sedge ", cell->type[7] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections_["\\R"]); + dump_sigspec(f, cell->get("\\R")); } fprintf(f, ")\n"); if (cell->type[7] != '_') { fprintf(f, "%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!"); - dump_sigspec(f, cell->connections_["\\R"]); + dump_sigspec(f, cell->get("\\R")); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); fprintf(f, "%s" " else\n", indent.c_str()); @@ -434,7 +434,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Q"]); + dump_sigspec(f, cell->get("\\Q")); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -446,27 +446,27 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10]; std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->connections_["\\Q"], reg_name); + bool out_is_reg_wire = is_reg_wire(cell->get("\\Q"), reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections_["\\C"]); + dump_sigspec(f, cell->get("\\C")); fprintf(f, " or %sedge ", pol_s == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections_["\\S"]); + dump_sigspec(f, cell->get("\\S")); fprintf(f, " or %sedge ", pol_r == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->connections_["\\R"]); + dump_sigspec(f, cell->get("\\R")); fprintf(f, ")\n"); fprintf(f, "%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!"); - dump_sigspec(f, cell->connections_["\\R"]); + dump_sigspec(f, cell->get("\\R")); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str()); fprintf(f, "%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!"); - dump_sigspec(f, cell->connections_["\\S"]); + dump_sigspec(f, cell->get("\\S")); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str()); @@ -477,7 +477,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Q"]); + dump_sigspec(f, cell->get("\\Q")); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -535,7 +535,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$pmux_safe") { int width = cell->parameters["\\WIDTH"].as_int(); - int s_width = cell->connections_["\\S"].size(); + int s_width = cell->get("\\S").size(); std::string func_name = cellname(cell); fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); @@ -567,13 +567,13 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, "%s" "endfunction\n", indent.c_str()); fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = %s(", func_name.c_str()); - dump_sigspec(f, cell->connections_["\\A"]); + dump_sigspec(f, cell->get("\\A")); fprintf(f, ", "); - dump_sigspec(f, cell->connections_["\\B"]); + dump_sigspec(f, cell->get("\\B")); fprintf(f, ", "); - dump_sigspec(f, cell->connections_["\\S"]); + dump_sigspec(f, cell->get("\\S")); fprintf(f, ");\n"); return true; } @@ -581,9 +581,9 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$slice") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = "); - dump_sigspec(f, cell->connections_["\\A"]); + dump_sigspec(f, cell->get("\\A")); fprintf(f, " >> %d;\n", cell->parameters.at("\\OFFSET").as_int()); return true; } @@ -591,14 +591,14 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$bu0") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); if (cell->parameters["\\A_SIGNED"].as_bool()) { fprintf(f, " = $signed("); - dump_sigspec(f, cell->connections_["\\A"]); + dump_sigspec(f, cell->get("\\A")); fprintf(f, ");\n"); } else { fprintf(f, " = { 1'b0, "); - dump_sigspec(f, cell->connections_["\\A"]); + dump_sigspec(f, cell->get("\\A")); fprintf(f, " };\n"); } return true; @@ -607,11 +607,11 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$concat") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Y"]); + dump_sigspec(f, cell->get("\\Y")); fprintf(f, " = { "); - dump_sigspec(f, cell->connections_["\\B"]); + dump_sigspec(f, cell->get("\\B")); fprintf(f, " , "); - dump_sigspec(f, cell->connections_["\\A"]); + dump_sigspec(f, cell->get("\\A")); fprintf(f, " };\n"); return true; } @@ -621,17 +621,17 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) RTLIL::SigSpec sig_clk, sig_arst, val_arst; bool pol_clk, pol_arst = false; - sig_clk = cell->connections_["\\CLK"]; + sig_clk = cell->get("\\CLK"); pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool(); if (cell->type == "$adff") { - sig_arst = cell->connections_["\\ARST"]; + sig_arst = cell->get("\\ARST"); pol_arst = cell->parameters["\\ARST_POLARITY"].as_bool(); val_arst = RTLIL::SigSpec(cell->parameters["\\ARST_VALUE"]); } std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->connections_["\\Q"], reg_name); + bool out_is_reg_wire = is_reg_wire(cell->get("\\Q"), reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str()); @@ -660,7 +660,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->connections_["\\Q"]); + dump_sigspec(f, cell->get("\\Q")); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -707,7 +707,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) for (int i = 1; true; i++) { char str[16]; snprintf(str, 16, "$%d", i); - for (auto it = cell->connections_.begin(); it != cell->connections_.end(); it++) { + for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) { if (it->first != str) continue; if (!first_arg) @@ -721,7 +721,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) break; found_numbered_port:; } - for (auto it = cell->connections_.begin(); it != cell->connections_.end(); it++) { + for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) { if (numbered_ports.count(it->first)) continue; if (!first_arg) @@ -908,10 +908,10 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - if (!reg_ct.cell_known(cell->type) || cell->connections_.count("\\Q") == 0) + if (!reg_ct.cell_known(cell->type) || cell->connections().count("\\Q") == 0) continue; - RTLIL::SigSpec sig = cell->connections_["\\Q"]; + RTLIL::SigSpec sig = cell->get("\\Q"); if (sig.is_chunk()) { RTLIL::SigChunk chunk = sig.as_chunk(); @@ -961,7 +961,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto it = module->processes.begin(); it != module->processes.end(); it++) dump_process(f, indent + " ", it->second); - for (auto it = module->connections_.begin(); it != module->connections_.end(); it++) + for (auto it = module->connections().begin(); it != module->connections().end(); it++) dump_conn(f, indent + " ", it->first, it->second); fprintf(f, "%s" "endmodule\n", indent.c_str()); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c70b79a5..861df3fd 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 bb42c5ec..a7ce4bc7 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 ec96fbdd..d7068d46 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)); } } diff --git a/kernel/consteval.h b/kernel/consteval.h index 5469fa80..4050d2dc 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -43,7 +43,7 @@ struct ConstEval for (auto &it : module->cells) { if (!ct.cell_known(it.second->type)) continue; - for (auto &it2 : it.second->connections_) + for (auto &it2 : it.second->connections()) if (ct.cell_output(it.second->type, it2.first)) sig2driver.insert(assign_map(it2.second), it.second); } @@ -87,22 +87,22 @@ struct ConstEval { RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; - assert(cell->connections_.count("\\Y") > 0); - sig_y = values_map(assign_map(cell->connections_["\\Y"])); + assert(cell->connections().count("\\Y") > 0); + sig_y = values_map(assign_map(cell->get("\\Y"))); if (sig_y.is_fully_const()) return true; - if (cell->connections_.count("\\S") > 0) { - sig_s = cell->connections_["\\S"]; + if (cell->connections().count("\\S") > 0) { + sig_s = cell->get("\\S"); if (!eval(sig_s, undef, cell)) return false; } - if (cell->connections_.count("\\A") > 0) - sig_a = cell->connections_["\\A"]; + if (cell->connections().count("\\A") > 0) + sig_a = cell->get("\\A"); - if (cell->connections_.count("\\B") > 0) - sig_b = cell->connections_["\\B"]; + if (cell->connections().count("\\B") > 0) + sig_b = cell->get("\\B"); if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") { diff --git a/kernel/modwalker.h b/kernel/modwalker.h index efd97379..a3983a2c 100644 --- a/kernel/modwalker.h +++ b/kernel/modwalker.h @@ -88,12 +88,12 @@ struct ModWalker void add_cell(RTLIL::Cell *cell) { if (ct.cell_known(cell->type)) { - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) add_cell_port(cell, conn.first, sigmap(conn.second), ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first)); } else { - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) add_cell_port(cell, conn.first, sigmap(conn.second), true, true); } } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 73f5d71f..9781fa32 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -348,9 +348,9 @@ namespace { void port(const char *name, int width) { - if (cell->connections_.count(name) == 0) + if (cell->connections().count(name) == 0) error(__LINE__); - if (cell->connections_.at(name).size() != width) + if (cell->connections().at(name).size() != width) error(__LINE__); expected_ports.insert(name); } @@ -360,7 +360,7 @@ namespace { for (auto ¶ : cell->parameters) if (expected_params.count(para.first) == 0) error(__LINE__); - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) if (expected_ports.count(conn.first) == 0) error(__LINE__); @@ -379,13 +379,13 @@ namespace { for (const char *p = ports; *p; p++) { char portname[3] = { '\\', *p, 0 }; - if (cell->connections_.count(portname) == 0) + if (cell->connections().count(portname) == 0) error(__LINE__); - if (cell->connections_.at(portname).size() != 1) + if (cell->connections().at(portname).size() != 1) error(__LINE__); } - for (auto &conn : cell->connections_) { + for (auto &conn : cell->connections()) { if (conn.first.size() != 2 || conn.first.at(0) != '\\') error(__LINE__); if (strchr(ports, conn.first.at(1)) == NULL) @@ -734,7 +734,7 @@ void RTLIL::Module::check() assert(it.first == it.second->name); assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$')); - for (auto &it2 : it.second->connections_) { + for (auto &it2 : it.second->connections()) { assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); it2.second.check(); } @@ -773,7 +773,7 @@ void RTLIL::Module::optimize() void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const { new_mod->name = name; - new_mod->connections_ = connections_; + new_mod->connections() = connections_; new_mod->attributes = attributes; for (auto &it : wires) @@ -924,7 +924,7 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *other) { RTLIL::Cell *cell = addCell(name, other->type); - cell->connections_ = other->connections_; + cell->connections() = other->connections(); cell->parameters = other->parameters; cell->attributes = other->attributes; return cell; @@ -938,8 +938,8 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\A_WIDTH"] = sig_a.size(); \ cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->connections_["\\A"] = sig_a; \ - cell->connections_["\\Y"] = sig_y; \ + cell->set("\\A", sig_a); \ + cell->set("\\Y", sig_y); \ add(cell); \ return cell; \ } \ @@ -970,9 +970,9 @@ DEF_METHOD(LogicNot, 1, "$logic_not") cell->parameters["\\A_WIDTH"] = sig_a.size(); \ cell->parameters["\\B_WIDTH"] = sig_b.size(); \ cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->connections_["\\A"] = sig_a; \ - cell->connections_["\\B"] = sig_b; \ - cell->connections_["\\Y"] = sig_y; \ + cell->set("\\A", sig_a); \ + cell->set("\\B", sig_b); \ + cell->set("\\Y", sig_y); \ add(cell); \ return cell; \ } \ @@ -1014,10 +1014,10 @@ DEF_METHOD(LogicOr, 1, "$logic_or") cell->parameters["\\WIDTH"] = sig_a.size(); \ cell->parameters["\\WIDTH"] = sig_b.size(); \ if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ - cell->connections_["\\A"] = sig_a; \ - cell->connections_["\\B"] = sig_b; \ - cell->connections_["\\S"] = sig_s; \ - cell->connections_["\\Y"] = sig_y; \ + cell->set("\\A", sig_a); \ + cell->set("\\B", sig_b); \ + cell->set("\\S", sig_s); \ + cell->set("\\Y", sig_y); \ add(cell); \ return cell; \ } \ @@ -1036,8 +1036,8 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections_["\\" #_P1] = sig1; \ - cell->connections_["\\" #_P2] = sig2; \ + cell->connections()["\\" #_P1] = sig1; \ + cell->connections()["\\" #_P2] = sig2; \ add(cell); \ return cell; \ } \ @@ -1051,9 +1051,9 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections_["\\" #_P1] = sig1; \ - cell->connections_["\\" #_P2] = sig2; \ - cell->connections_["\\" #_P3] = sig3; \ + cell->connections()["\\" #_P1] = sig1; \ + cell->connections()["\\" #_P2] = sig2; \ + cell->connections()["\\" #_P3] = sig3; \ add(cell); \ return cell; \ } \ @@ -1067,10 +1067,10 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections_["\\" #_P1] = sig1; \ - cell->connections_["\\" #_P2] = sig2; \ - cell->connections_["\\" #_P3] = sig3; \ - cell->connections_["\\" #_P4] = sig4; \ + cell->connections()["\\" #_P1] = sig1; \ + cell->connections()["\\" #_P2] = sig2; \ + cell->connections()["\\" #_P3] = sig3; \ + cell->connections()["\\" #_P4] = sig4; \ add(cell); \ return cell; \ } \ @@ -1098,9 +1098,9 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\B_WIDTH"] = sig_b.size(); cell->parameters["\\Y_WIDTH"] = sig_y.size(); - cell->connections_["\\A"] = sig_a; - cell->connections_["\\B"] = sig_b; - cell->connections_["\\Y"] = sig_y; + cell->set("\\A", sig_a); + cell->set("\\B", sig_b); + cell->set("\\Y", sig_y); add(cell); return cell; } @@ -1113,8 +1113,8 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig_y.size(); cell->parameters["\\OFFSET"] = offset; - cell->connections_["\\A"] = sig_a; - cell->connections_["\\Y"] = sig_y; + cell->set("\\A", sig_a); + cell->set("\\Y", sig_y); add(cell); return cell; } @@ -1126,9 +1126,9 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a cell->type = "$concat"; cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\B_WIDTH"] = sig_b.size(); - cell->connections_["\\A"] = sig_a; - cell->connections_["\\B"] = sig_b; - cell->connections_["\\Y"] = sig_y; + cell->set("\\A", sig_a); + cell->set("\\B", sig_b); + cell->set("\\Y", sig_y); add(cell); return cell; } @@ -1140,8 +1140,8 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, R cell->type = "$lut"; cell->parameters["\\LUT"] = lut; cell->parameters["\\WIDTH"] = sig_i.size(); - cell->connections_["\\I"] = sig_i; - cell->connections_["\\O"] = sig_o; + cell->set("\\I", sig_i); + cell->set("\\O", sig_o); add(cell); return cell; } @@ -1151,8 +1151,8 @@ RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = "$assert"; - cell->connections_["\\A"] = sig_a; - cell->connections_["\\EN"] = sig_en; + cell->set("\\A", sig_a); + cell->set("\\EN", sig_en); add(cell); return cell; } @@ -1165,9 +1165,9 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections_["\\SET"] = sig_set; - cell->connections_["\\CLR"] = sig_clr; - cell->connections_["\\Q"] = sig_q; + cell->set("\\SET", sig_set); + cell->set("\\CLR", sig_clr); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1179,9 +1179,9 @@ RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, cell->type = "$dff"; cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections_["\\CLK"] = sig_clk; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\CLK", sig_clk); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1196,11 +1196,11 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections_["\\CLK"] = sig_clk; - cell->connections_["\\SET"] = sig_set; - cell->connections_["\\CLR"] = sig_clr; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\CLK", sig_clk); + cell->set("\\SET", sig_set); + cell->set("\\CLR", sig_clr); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1215,10 +1215,10 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk cell->parameters["\\ARST_POLARITY"] = arst_polarity; cell->parameters["\\ARST_VALUE"] = arst_value; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections_["\\CLK"] = sig_clk; - cell->connections_["\\ARST"] = sig_arst; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\CLK", sig_clk); + cell->set("\\ARST", sig_arst); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1230,9 +1230,9 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e cell->type = "$dlatch"; cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections_["\\EN"] = sig_en; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\EN", sig_en); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1247,11 +1247,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->connections_["\\EN"] = sig_en; - cell->connections_["\\SET"] = sig_set; - cell->connections_["\\CLR"] = sig_clr; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\EN", sig_en); + cell->set("\\SET", sig_set); + cell->set("\\CLR", sig_clr); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1261,9 +1261,9 @@ RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_ RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); - cell->connections_["\\C"] = sig_clk; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\C", sig_clk); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1274,11 +1274,11 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec si RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); - cell->connections_["\\C"] = sig_clk; - cell->connections_["\\S"] = sig_set; - cell->connections_["\\R"] = sig_clr; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\C", sig_clk); + cell->set("\\S", sig_set); + cell->set("\\R", sig_clr); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1289,10 +1289,10 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'); - cell->connections_["\\C"] = sig_clk; - cell->connections_["\\R"] = sig_arst; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\C", sig_clk); + cell->set("\\R", sig_arst); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1302,9 +1302,9 @@ RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec s RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'); - cell->connections_["\\E"] = sig_en; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\E", sig_en); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } @@ -1315,11 +1315,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::Cell *cell = new RTLIL::Cell; cell->name = name; cell->type = stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); - cell->connections_["\\E"] = sig_en; - cell->connections_["\\S"] = sig_set; - cell->connections_["\\R"] = sig_clr; - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; + cell->set("\\E", sig_en); + cell->set("\\S", sig_set); + cell->set("\\R", sig_clr); + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); add(cell); return cell; } diff --git a/kernel/satgen.h b/kernel/satgen.h index ec4480c3..6a288a8d 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -182,9 +182,9 @@ struct SatGen if (model_undef && (cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || is_arith_compare)) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); if (is_arith_compare) extendSignalWidth(undef_a, undef_b, cell, true); else @@ -195,7 +195,7 @@ struct SatGen int undef_y_bit = ez->OR(undef_any_a, undef_any_b); if (cell->type == "$div" || cell->type == "$mod") { - std::vector b = importSigSpec(cell->connections_.at("\\B"), timestep); + std::vector b = importSigSpec(cell->get("\\B"), timestep); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); } @@ -215,9 +215,9 @@ struct SatGen cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$sub") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -237,9 +237,9 @@ struct SatGen if (model_undef && !arith_undef_handled) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, undef_y, cell, false); if (cell->type == "$and" || cell->type == "$_AND_") { @@ -265,7 +265,7 @@ struct SatGen } else if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -273,16 +273,16 @@ struct SatGen if (cell->type == "$_INV_" || cell->type == "$not") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_not(a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, true); ez->assume(ez->vec_eq(undef_a, undef_y)); undefGating(y, yy, undef_y); @@ -292,20 +292,20 @@ struct SatGen if (cell->type == "$_MUX_" || cell->type == "$mux") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector s = importDefSigSpec(cell->connections_.at("\\S"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector s = importDefSigSpec(cell->get("\\S"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->connections_.at("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_s = importUndefSigSpec(cell->get("\\S"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); std::vector unequal_ab = ez->vec_not(ez->vec_iff(a, b)); std::vector undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); @@ -318,10 +318,10 @@ struct SatGen if (cell->type == "$pmux" || cell->type == "$safe_pmux") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector s = importDefSigSpec(cell->connections_.at("\\S"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector s = importDefSigSpec(cell->get("\\S"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -336,10 +336,10 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->connections_.at("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_s = importUndefSigSpec(cell->get("\\S"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); int maybe_one_hot = ez->FALSE; int maybe_many_hot = ez->FALSE; @@ -387,8 +387,8 @@ struct SatGen if (cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -402,8 +402,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, cell->type != "$bu0"); if (cell->type == "$pos" || cell->type == "$bu0") { @@ -422,8 +422,8 @@ struct SatGen if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$reduce_bool" || cell->type == "$logic_not") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -442,8 +442,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); int aX = ez->expression(ezSAT::OpOr, undef_a); if (cell->type == "$reduce_and") { @@ -469,12 +469,12 @@ struct SatGen if (cell->type == "$logic_and" || cell->type == "$logic_or") { - std::vector vec_a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector vec_b = importDefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector vec_a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector vec_b = importDefSigSpec(cell->get("\\B"), timestep); int a = ez->expression(ez->OpOr, vec_a); int b = ez->expression(ez->OpOr, vec_b); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -487,9 +487,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a))); int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); @@ -516,16 +516,16 @@ struct SatGen if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") { bool is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); extendSignalWidth(a, b, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); a = ez->vec_or(a, undef_a); b = ez->vec_or(b, undef_b); @@ -548,9 +548,9 @@ struct SatGen if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); if (cell->type == "$eqx") @@ -565,9 +565,9 @@ struct SatGen } else if (model_undef && (cell->type == "$eq" || cell->type == "$ne")) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); @@ -589,7 +589,7 @@ struct SatGen else { if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); undefGating(y, yy, undef_y); } log_assert(!model_undef || arith_undef_handled); @@ -599,9 +599,9 @@ struct SatGen if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); char shift_left = cell->type == "$shl" || cell->type == "$sshl"; bool sign_extend = cell->type == "$sshr" && cell->parameters["\\A_SIGNED"].as_bool(); @@ -627,9 +627,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); while (undef_y.size() < undef_a.size()) undef_y.push_back(ez->literal()); @@ -657,9 +657,9 @@ struct SatGen if (cell->type == "$mul") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -676,7 +676,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -684,9 +684,9 @@ struct SatGen if (cell->type == "$div" || cell->type == "$mod") { - std::vector a = importDefSigSpec(cell->connections_.at("\\A"), timestep); - std::vector b = importDefSigSpec(cell->connections_.at("\\B"), timestep); - std::vector y = importDefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->get("\\A"), timestep); + std::vector b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -740,11 +740,11 @@ struct SatGen only_first_one.at(0) = ez->TRUE; div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); } else { - div_zero_result.insert(div_zero_result.end(), cell->connections_.at("\\A").size(), ez->TRUE); + div_zero_result.insert(div_zero_result.end(), cell->get("\\A").size(), ez->TRUE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->FALSE); } } else { - int copy_a_bits = std::min(cell->connections_.at("\\A").size(), cell->connections_.at("\\B").size()); + int copy_a_bits = std::min(cell->get("\\A").size(), cell->get("\\B").size()); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); @@ -756,7 +756,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->connections_.at("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -764,17 +764,17 @@ struct SatGen if (cell->type == "$slice") { - RTLIL::SigSpec a = cell->connections_.at("\\A"); - RTLIL::SigSpec y = cell->connections_.at("\\Y"); + RTLIL::SigSpec a = cell->get("\\A"); + RTLIL::SigSpec y = cell->get("\\Y"); ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.size()), y, timestep)); return true; } if (cell->type == "$concat") { - RTLIL::SigSpec a = cell->connections_.at("\\A"); - RTLIL::SigSpec b = cell->connections_.at("\\B"); - RTLIL::SigSpec y = cell->connections_.at("\\Y"); + RTLIL::SigSpec a = cell->get("\\A"); + RTLIL::SigSpec b = cell->get("\\B"); + RTLIL::SigSpec y = cell->get("\\Y"); RTLIL::SigSpec ab = a; ab.append(b); @@ -787,20 +787,20 @@ struct SatGen { if (timestep == 1) { - initial_state.add((*sigmap)(cell->connections_.at("\\Q"))); + initial_state.add((*sigmap)(cell->get("\\Q"))); } else { - std::vector d = importDefSigSpec(cell->connections_.at("\\D"), timestep-1); - std::vector q = importDefSigSpec(cell->connections_.at("\\Q"), timestep); + std::vector d = importDefSigSpec(cell->get("\\D"), timestep-1); + std::vector q = importDefSigSpec(cell->get("\\Q"), timestep); std::vector qq = model_undef ? ez->vec_var(q.size()) : q; ez->assume(ez->vec_eq(d, qq)); if (model_undef) { - std::vector undef_d = importUndefSigSpec(cell->connections_.at("\\D"), timestep-1); - std::vector undef_q = importUndefSigSpec(cell->connections_.at("\\Q"), timestep); + std::vector undef_d = importUndefSigSpec(cell->get("\\D"), timestep-1); + std::vector undef_q = importUndefSigSpec(cell->get("\\Q"), timestep); ez->assume(ez->vec_eq(undef_d, undef_q)); undefGating(q, qq, undef_q); @@ -812,8 +812,8 @@ struct SatGen if (cell->type == "$assert") { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - asserts_a[pf].append((*sigmap)(cell->connections_.at("\\A"))); - asserts_en[pf].append((*sigmap)(cell->connections_.at("\\EN"))); + asserts_a[pf].append((*sigmap)(cell->get("\\A"))); + asserts_en[pf].append((*sigmap)(cell->get("\\EN"))); return true; } diff --git a/kernel/sigtools.h b/kernel/sigtools.h index ea95e06e..7035db73 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -269,7 +269,7 @@ struct SigMap void set(RTLIL::Module *module) { clear(); - for (auto &it : module->connections_) + for (auto &it : module->connections()) add(it.first, it.second); } diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index f6c1528e..f67ffe1e 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -30,7 +30,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re // For all ports on all cells for (auto &cell_iter : module->cells) - for (auto &conn : cell_iter.second->connections_) + for (auto &conn : cell_iter.second->connections()) { // Get the signals on the port // (use sigmap to get a uniqe signal name) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 80828e15..c53c4450 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -111,11 +111,11 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) { if (clk_polarity != (cell->type == "$_DFF_P_")) return; - if (clk_sig != assign_map(cell->connections_["\\C"])) + if (clk_sig != assign_map(cell->get("\\C"))) return; - RTLIL::SigSpec sig_d = cell->connections_["\\D"]; - RTLIL::SigSpec sig_q = cell->connections_["\\Q"]; + RTLIL::SigSpec sig_d = cell->get("\\D"); + RTLIL::SigSpec sig_q = cell->get("\\Q"); if (keepff) for (auto &c : sig_q.chunks()) @@ -133,8 +133,8 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_INV_") { - RTLIL::SigSpec sig_a = cell->connections_["\\A"]; - RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); assign_map.apply(sig_a); assign_map.apply(sig_y); @@ -147,9 +147,9 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { - RTLIL::SigSpec sig_a = cell->connections_["\\A"]; - RTLIL::SigSpec sig_b = cell->connections_["\\B"]; - RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_b = cell->get("\\B"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -173,10 +173,10 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_MUX_") { - RTLIL::SigSpec sig_a = cell->connections_["\\A"]; - RTLIL::SigSpec sig_b = cell->connections_["\\B"]; - RTLIL::SigSpec sig_s = cell->connections_["\\S"]; - RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_b = cell->get("\\B"); + RTLIL::SigSpec sig_s = cell->get("\\S"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -347,7 +347,7 @@ static void handle_loops() } edges[id1].swap(edges[id3]); - module->connections_.push_back(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); + module->connect(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit)); dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count); } } @@ -470,7 +470,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std if (cell->type != "$_DFF_N_" && cell->type != "$_DFF_P_") continue; - std::pair key(cell->type == "$_DFF_P_", assign_map(cell->connections_.at("\\C"))); + std::pair key(cell->type == "$_DFF_P_", assign_map(cell->get("\\C"))); if (++dff_counters[key] > best_dff_counter) { best_dff_counter = dff_counters[key]; clk_polarity = key.first; @@ -503,7 +503,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } for (auto &cell_it : module->cells) - for (auto &port_it : cell_it.second->connections_) + for (auto &port_it : cell_it.second->connections()) mark_port(port_it.second); handle_loops(); @@ -705,48 +705,48 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); - module->connections_.push_back(conn); + module->connect(conn); continue; } if (c->type == "\\BUF") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); - conn.second = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); - module->connections_.push_back(conn); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)]); + module->connect(conn); continue; } if (c->type == "\\INV") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_INV_"); - cell->connections_["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); - cell->connections_["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); + cell->set("\\A", RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)])); + cell->set("\\Y", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); - cell->connections_["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); - cell->connections_["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\B"].as_wire()->name)]); - cell->connections_["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); + cell->set("\\A", RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)])); + cell->set("\\B", RTLIL::SigSpec(module->wires[remap_name(c->get("\\B").as_wire()->name)])); + cell->set("\\Y", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\MUX") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_"); - cell->connections_["\\A"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\A"].as_wire()->name)]); - cell->connections_["\\B"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\B"].as_wire()->name)]); - cell->connections_["\\S"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\S"].as_wire()->name)]); - cell->connections_["\\Y"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Y"].as_wire()->name)]); + cell->set("\\A", RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)])); + cell->set("\\B", RTLIL::SigSpec(module->wires[remap_name(c->get("\\B").as_wire()->name)])); + cell->set("\\S", RTLIL::SigSpec(module->wires[remap_name(c->get("\\S").as_wire()->name)])); + cell->set("\\Y", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\DFF") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->connections_["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\D"].as_wire()->name)]); - cell->connections_["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Q"].as_wire()->name)]); - cell->connections_["\\C"] = clk_sig; + cell->set("\\D", RTLIL::SigSpec(module->wires[remap_name(c->get("\\D").as_wire()->name)])); + cell->set("\\Q", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Q").as_wire()->name)])); + cell->set("\\C", clk_sig); design->select(module, cell); continue; } @@ -761,23 +761,23 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\_const0_" || c->type == "\\_const1_") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections_.begin()->second.as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections().begin()->second.as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1); - module->connections_.push_back(conn); + module->connect(conn); continue; } if (c->type == "\\_dff_") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->connections_["\\D"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\D"].as_wire()->name)]); - cell->connections_["\\Q"] = RTLIL::SigSpec(module->wires[remap_name(c->connections_["\\Q"].as_wire()->name)]); - cell->connections_["\\C"] = clk_sig; + cell->set("\\D", RTLIL::SigSpec(module->wires[remap_name(c->get("\\D").as_wire()->name)])); + cell->set("\\Q", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Q").as_wire()->name)])); + cell->set("\\C", clk_sig); design->select(module, cell); continue; } RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); cell->parameters = c->parameters; - for (auto &conn : c->connections_) { + for (auto &conn : c->connections()) { RTLIL::SigSpec newsig; for (auto &c : conn.second.chunks()) { if (c.width == 0) @@ -785,18 +785,18 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std assert(c.width == 1); newsig.append(module->wires[remap_name(c.wire->name)]); } - cell->connections_[conn.first] = newsig; + cell->connections()[conn.first] = newsig; } design->select(module, cell); } } - for (auto conn : mapped_mod->connections_) { + for (auto conn : mapped_mod->connections()) { if (!conn.first.is_fully_const()) conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.as_wire()->name)]); if (!conn.second.is_fully_const()) conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.as_wire()->name)]); - module->connections_.push_back(conn); + module->connect(conn); } for (auto &it : cell_stats) @@ -816,7 +816,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std conn.second = si.bit; in_wires++; } - module->connections_.push_back(conn); + module->connect(conn); } log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); log("ABC RESULTS: input signals: %8d\n", in_wires); diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 122f7845..e5bfb98b 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -128,8 +128,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) } RTLIL::Cell *cell = module->addCell(NEW_ID, dff_name); - cell->connections_["\\D"] = module->wires.at(RTLIL::escape_id(d)); - cell->connections_["\\Q"] = module->wires.at(RTLIL::escape_id(q)); + cell->set("\\D", module->wires.at(RTLIL::escape_id(d))); + cell->set("\\Q", module->wires.at(RTLIL::escape_id(q))); continue; } @@ -148,7 +148,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) *(q++) = 0; if (module->wires.count(RTLIL::escape_id(q)) == 0) module->addWire(RTLIL::escape_id(q)); - cell->connections_[RTLIL::escape_id(p)] = module->wires.at(RTLIL::escape_id(q)); + cell->connections()[RTLIL::escape_id(p)] = module->wires.at(RTLIL::escape_id(q)); } continue; } @@ -199,15 +199,15 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) finished_parsing_constval: if (state == RTLIL::State::Sa) state = RTLIL::State::S1; - module->connections_.push_back(RTLIL::SigSig(output_sig, state)); + module->connect(RTLIL::SigSig(output_sig, state)); goto continue_without_read; } RTLIL::Cell *cell = module->addCell(NEW_ID, "$lut"); cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size()); cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size()); - cell->connections_["\\I"] = input_sig; - cell->connections_["\\O"] = output_sig; + cell->set("\\I", input_sig); + cell->set("\\O", output_sig); lutptr = &cell->parameters.at("\\LUT"); lut_default_state = RTLIL::State::Sx; continue; diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index ce8ecc32..9004bf75 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -75,10 +75,10 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n continue; if (mod->get_bool_attribute("\\blackbox")) continue; - if (it.second->connections_.count(name) > 0) + if (it.second->connections().count(name) > 0) continue; - it.second->connections_[name] = wire; + it.second->connections()[name] = wire; log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str()); } } diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index ea05026f..ffe7a5ef 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -30,11 +30,11 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size()); for (auto &it : module->cells) - for (auto &port : it.second->connections_) + for (auto &port : it.second->connections()) if (ct.cell_output(it.second->type, port.first)) sigmap(port.second).replace(sig, dummy_wire, &port.second); - for (auto &conn : module->connections_) + for (auto &conn : module->connections()) sigmap(conn.first).replace(sig, dummy_wire, &conn.first); } @@ -123,7 +123,7 @@ struct ConnectPass : public Pass { SigMap sigmap; if (!flag_nomap) - for (auto &it : module->connections_) { + for (auto &it : module->connections()) { std::vector lhs = it.first.to_sigbit_vector(); std::vector rhs = it.first.to_sigbit_vector(); for (size_t i = 0; i < lhs.size(); i++) @@ -148,7 +148,7 @@ struct ConnectPass : public Pass { if (!flag_nounset) unset_drivers(design, module, sigmap, sig_lhs); - module->connections_.push_back(RTLIL::SigSig(sig_lhs, sig_rhs)); + module->connect(RTLIL::SigSig(sig_lhs, sig_rhs)); } else if (!unset_expr.empty()) @@ -176,7 +176,7 @@ struct ConnectPass : public Pass { if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cells.at(RTLIL::escape_id(port_cell))->connections_[RTLIL::escape_id(port_port)] = sigmap(sig); + module->cells.at(RTLIL::escape_id(port_cell))->connections()[RTLIL::escape_id(port_port)] = sigmap(sig); } else log_cmd_error("Expected -set, -unset, or -port.\n"); diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 87ed3d85..d7560ab1 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -74,7 +74,7 @@ struct ConnwrappersWorker if (!decl_celltypes.count(cell->type)) continue; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) { std::pair key(cell->type, conn.first); @@ -109,7 +109,7 @@ struct ConnwrappersWorker if (!design->selected(module, cell)) continue; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) { std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); RTLIL::SigSpec old_sig; diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index 0028f7ea..1a780466 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -49,7 +49,7 @@ struct ScatterPass : public Pass { continue; for (auto &c : mod_it.second->cells) - for (auto &p : c.second->connections_) + for (auto &p : c.second->connections()) { RTLIL::Wire *wire = new RTLIL::Wire; wire->name = NEW_ID; @@ -58,10 +58,10 @@ struct ScatterPass : public Pass { if (ct.cell_output(c.second->type, p.first)) { RTLIL::SigSig sigsig(p.second, wire); - mod_it.second->connections_.push_back(sigsig); + mod_it.second->connect(sigsig); } else { RTLIL::SigSig sigsig(wire, p.second); - mod_it.second->connections_.push_back(sigsig); + mod_it.second->connect(sigsig); } p.second = wire; diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 40a2e48c..3380a935 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -132,7 +132,7 @@ struct SccWorker RTLIL::SigSpec inputSignals, outputSignals; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) { bool isInput = true, isOutput = true; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 5d991d03..e0f1a6d6 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -380,7 +380,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0) selected_wires.insert(it.second); - for (auto &conn : mod->connections_) + for (auto &conn : mod->connections()) { std::vector conn_lhs = conn.first.to_sigbit_vector(); std::vector conn_rhs = conn.second.to_sigbit_vector(); @@ -396,7 +396,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v } for (auto &cell : mod->cells) - for (auto &conn : cell.second->connections_) + for (auto &conn : cell.second->connections()) { char last_mode = '-'; for (auto &rule : rules) { diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index e1005a27..e2610610 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -135,7 +135,7 @@ struct SetundefPass : public Pass { CellTypes ct(design); for (auto &it : module->cells) - for (auto &conn : it.second->connections_) + for (auto &conn : it.second->connections()) if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) undriven_signals.del(sigmap(conn.second)); @@ -144,7 +144,7 @@ struct SetundefPass : public Pass { RTLIL::SigSpec bits; for (int i = 0; i < c.width; i++) bits.append(worker.next_bit()); - module->connections_.push_back(RTLIL::SigSig(c, bits)); + module->connect(RTLIL::SigSig(c, bits)); } } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 29b83a9a..441268ee 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -344,7 +344,7 @@ struct ShowWorker std::vector in_ports, out_ports; - for (auto &conn : it.second->connections_) { + for (auto &conn : it.second->connections()) { if (!ct.cell_output(it.second->type, conn.first)) in_ports.push_back(conn.first); else @@ -368,7 +368,7 @@ struct ShowWorker label_string += "}}"; std::string code; - for (auto &conn : it.second->connections_) { + for (auto &conn : it.second->connections()) { code += gen_portbox(stringf("c%d:p%d", id2num(it.first), id2num(conn.first)), conn.second, ct.cell_output(it.second->type, conn.first)); } @@ -421,7 +421,7 @@ struct ShowWorker fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name), proc_src.c_str()); } - for (auto &conn : module->connections_) + for (auto &conn : module->connections()) { bool found_lhs_wire = false; for (auto &c : conn.first.chunks()) { @@ -516,7 +516,7 @@ struct ShowWorker log("Skipping blackbox module %s.\n", id2cstr(module->name)); continue; } else - if (module->cells.empty() && module->connections_.empty() && module->processes.empty()) { + if (module->cells.empty() && module->connections().empty() && module->processes.empty()) { log("Skipping empty module %s.\n", id2cstr(module->name)); continue; } else @@ -695,7 +695,7 @@ struct ShowPass : public Pass { for (auto &mod_it : design->modules) { if (mod_it.second->get_bool_attribute("\\blackbox")) continue; - if (mod_it.second->cells.empty() && mod_it.second->connections_.empty()) + if (mod_it.second->cells.empty() && mod_it.second->connections().empty()) continue; if (design->selected_module(mod_it.first)) modcount++; diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index c8b3d0b0..94f8365b 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -74,9 +74,9 @@ struct SpliceWorker cell->parameters["\\OFFSET"] = offset; cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig.size(); - cell->connections_["\\A"] = sig_a; - cell->connections_["\\Y"] = module->addWire(NEW_ID, sig.size()); - new_sig = cell->connections_["\\Y"]; + cell->set("\\A", sig_a); + cell->set("\\Y", module->addWire(NEW_ID, sig.size())); + new_sig = cell->get("\\Y"); } sliced_signals_cache[sig] = new_sig; @@ -130,10 +130,10 @@ struct SpliceWorker RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat"); cell->parameters["\\A_WIDTH"] = new_sig.size(); cell->parameters["\\B_WIDTH"] = sig2.size(); - cell->connections_["\\A"] = new_sig; - cell->connections_["\\B"] = sig2; - cell->connections_["\\Y"] = module->addWire(NEW_ID, new_sig.size() + sig2.size()); - new_sig = cell->connections_["\\Y"]; + cell->set("\\A", new_sig); + cell->set("\\B", sig2); + cell->set("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size())); + new_sig = cell->get("\\Y"); } spliced_signals_cache[sig] = new_sig; @@ -159,7 +159,7 @@ struct SpliceWorker } for (auto &it : module->cells) - for (auto &conn : it.second->connections_) + for (auto &conn : it.second->connections()) if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) { RTLIL::SigSpec sig = sigmap(conn.second); driven_chunks.insert(sig); @@ -182,7 +182,7 @@ struct SpliceWorker for (auto &it : module->cells) { if (!sel_by_wire && !design->selected(module, it.second)) continue; - for (auto &conn : it.second->connections_) + for (auto &conn : it.second->connections()) if (ct.cell_input(it.second->type, conn.first)) { if (ports.size() > 0 && !ports.count(conn.first)) continue; @@ -232,7 +232,7 @@ struct SpliceWorker it.first->port_output = false; module->add(it.first); module->add(new_port); - module->connections_.push_back(RTLIL::SigSig(new_port, it.second)); + module->connect(RTLIL::SigSig(new_port, it.second)); } } }; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 497d0a2a..28575e7b 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -134,7 +134,7 @@ struct SplitnetsPass : public Pass { std::map> split_wires_at; for (auto &c : module->cells) - for (auto &p : c.second->connections_) + for (auto &p : c.second->connections()) { if (!ct.cell_known(c.second->type)) continue; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index e5967659..be851afa 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -52,8 +52,8 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig for (auto &cellport : cellport_list) { if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux" && cellport.first->type != "$safe_pmux") || cellport.second != "\\Y") return false; - RTLIL::SigSpec sig_a = assign_map(cellport.first->connections_["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cellport.first->connections_["\\B"]); + RTLIL::SigSpec sig_a = assign_map(cellport.first->get("\\A")); + RTLIL::SigSpec sig_b = assign_map(cellport.first->get("\\B")); if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) return false; for (int i = 0; i < sig_b.size(); i += sig_a.size()) @@ -80,14 +80,14 @@ static bool check_state_users(RTLIL::SigSpec sig) continue; if (cellport.second != "\\A" && cellport.second != "\\B") return false; - if (cell->connections_.count("\\A") == 0 || cell->connections_.count("\\B") == 0 || cell->connections_.count("\\Y") == 0) + if (cell->connections().count("\\A") == 0 || cell->connections().count("\\B") == 0 || cell->connections().count("\\Y") == 0) return false; - for (auto &port_it : cell->connections_) + for (auto &port_it : cell->connections()) if (port_it.first != "\\A" && port_it.first != "\\B" && port_it.first != "\\Y") return false; - if (assign_map(cell->connections_["\\A"]) == sig && cell->connections_["\\B"].is_fully_const()) + if (assign_map(cell->get("\\A")) == sig && cell->get("\\B").is_fully_const()) continue; - if (assign_map(cell->connections_["\\B"]) == sig && cell->connections_["\\A"].is_fully_const()) + if (assign_map(cell->get("\\B")) == sig && cell->get("\\A").is_fully_const()) continue; return false; } @@ -109,8 +109,8 @@ static void detect_fsm(RTLIL::Wire *wire) continue; muxtree_cells.clear(); SigPool recursion_monitor; - RTLIL::SigSpec sig_q = assign_map(cellport.first->connections_["\\Q"]); - RTLIL::SigSpec sig_d = assign_map(cellport.first->connections_["\\D"]); + RTLIL::SigSpec sig_q = assign_map(cellport.first->get("\\Q")); + RTLIL::SigSpec sig_d = assign_map(cellport.first->get("\\D")); if (sig_q == RTLIL::SigSpec(wire) && check_state_mux_tree(sig_q, sig_d, recursion_monitor) && check_state_users(sig_q)) { log("Found FSM state register %s in module %s.\n", wire->name.c_str(), module->name.c_str()); wire->attributes["\\fsm_encoding"] = RTLIL::Const("auto"); @@ -160,7 +160,7 @@ struct FsmDetectPass : public Pass { sig2user.clear(); sig_at_port.clear(); for (auto &cell_it : module->cells) - for (auto &conn_it : cell_it.second->connections_) { + for (auto &conn_it : cell_it.second->connections()) { if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 431f086d..126c4866 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -43,34 +43,34 @@ struct FsmExpand bool is_cell_merge_candidate(RTLIL::Cell *cell) { if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") - if (cell->connections_.at("\\A").size() < 2) + if (cell->get("\\A").size() < 2) return true; RTLIL::SigSpec new_signals; - if (cell->connections_.count("\\A") > 0) - new_signals.append(assign_map(cell->connections_["\\A"])); - if (cell->connections_.count("\\B") > 0) - new_signals.append(assign_map(cell->connections_["\\B"])); - if (cell->connections_.count("\\S") > 0) - new_signals.append(assign_map(cell->connections_["\\S"])); - if (cell->connections_.count("\\Y") > 0) - new_signals.append(assign_map(cell->connections_["\\Y"])); + if (cell->connections().count("\\A") > 0) + new_signals.append(assign_map(cell->get("\\A"))); + if (cell->connections().count("\\B") > 0) + new_signals.append(assign_map(cell->get("\\B"))); + if (cell->connections().count("\\S") > 0) + new_signals.append(assign_map(cell->get("\\S"))); + if (cell->connections().count("\\Y") > 0) + new_signals.append(assign_map(cell->get("\\Y"))); new_signals.sort_and_unify(); new_signals.remove_const(); - new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_IN"])); - new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_OUT"])); + new_signals.remove(assign_map(fsm_cell->get("\\CTRL_IN"))); + new_signals.remove(assign_map(fsm_cell->get("\\CTRL_OUT"))); if (new_signals.size() > 3) return false; - if (cell->connections_.count("\\Y") > 0) { - new_signals.append(assign_map(cell->connections_["\\Y"])); + if (cell->connections().count("\\Y") > 0) { + new_signals.append(assign_map(cell->get("\\Y"))); new_signals.sort_and_unify(); new_signals.remove_const(); - new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_IN"])); - new_signals.remove(assign_map(fsm_cell->connections_["\\CTRL_OUT"])); + new_signals.remove(assign_map(fsm_cell->get("\\CTRL_IN"))); + new_signals.remove(assign_map(fsm_cell->get("\\CTRL_OUT"))); } if (new_signals.size() > 2) @@ -83,10 +83,10 @@ struct FsmExpand { std::vector cell_list; - for (auto c : sig2driver.find(assign_map(fsm_cell->connections_["\\CTRL_IN"]))) + for (auto c : sig2driver.find(assign_map(fsm_cell->get("\\CTRL_IN")))) cell_list.push_back(c); - for (auto c : sig2user.find(assign_map(fsm_cell->connections_["\\CTRL_OUT"]))) + for (auto c : sig2user.find(assign_map(fsm_cell->get("\\CTRL_OUT")))) cell_list.push_back(c); current_set.clear(); @@ -94,7 +94,7 @@ struct FsmExpand { if (merged_set.count(c) > 0 || current_set.count(c) > 0 || no_candidate_set.count(c) > 0) continue; - for (auto &p : c->connections_) { + for (auto &p : c->connections()) { if (p.first != "\\A" && p.first != "\\B" && p.first != "\\S" && p.first != "\\Y") goto next_cell; } @@ -135,7 +135,7 @@ struct FsmExpand RTLIL::SigSpec input_sig, output_sig; - for (auto &p : cell->connections_) + for (auto &p : cell->connections()) if (ct.cell_output(cell->type, p.first)) output_sig.append(assign_map(p.second)); else @@ -148,12 +148,12 @@ struct FsmExpand for (int i = 0; i < (1 << input_sig.size()); i++) { RTLIL::Const in_val(i, input_sig.size()); RTLIL::SigSpec A, B, S; - if (cell->connections_.count("\\A") > 0) - A = assign_map(cell->connections_["\\A"]); - if (cell->connections_.count("\\B") > 0) - B = assign_map(cell->connections_["\\B"]); - if (cell->connections_.count("\\S") > 0) - S = assign_map(cell->connections_["\\S"]); + if (cell->connections().count("\\A") > 0) + A = assign_map(cell->get("\\A")); + if (cell->connections().count("\\B") > 0) + B = assign_map(cell->get("\\B")); + if (cell->connections().count("\\S") > 0) + S = assign_map(cell->get("\\S")); A.replace(input_sig, RTLIL::SigSpec(in_val)); B.replace(input_sig, RTLIL::SigSpec(in_val)); S.replace(input_sig, RTLIL::SigSpec(in_val)); @@ -167,10 +167,10 @@ struct FsmExpand fsm_data.copy_from_cell(fsm_cell); fsm_data.num_inputs += input_sig.size(); - fsm_cell->connections_["\\CTRL_IN"].append(input_sig); + fsm_cell->get("\\CTRL_IN").append(input_sig); fsm_data.num_outputs += output_sig.size(); - fsm_cell->connections_["\\CTRL_OUT"].append(output_sig); + fsm_cell->get("\\CTRL_OUT").append(output_sig); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { @@ -204,7 +204,7 @@ struct FsmExpand for (auto &cell_it : module->cells) { RTLIL::Cell *c = cell_it.second; if (ct.cell_known(c->type) && design->selected(mod, c)) - for (auto &p : c->connections_) { + for (auto &p : c->connections()) { if (ct.cell_output(c->type, p.first)) sig2driver.insert(assign_map(p.second), c); else diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index b0e1c903..3ded8aca 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -58,9 +58,9 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); return false; } - RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); - RTLIL::SigSpec sig_s = assign_map(cell->connections_["\\S"]); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); + RTLIL::SigSpec sig_s = assign_map(cell->get("\\S")); if (reset_state && RTLIL::SigSpec(*reset_state).is_fully_undef()) do { if (sig_a.is_fully_def()) @@ -183,12 +183,12 @@ static void extract_fsm(RTLIL::Wire *wire) if ((cell->type != "$dff" && cell->type != "$adff") || cellport.second != "\\Q") continue; log(" found %s cell for state register: %s\n", cell->type.c_str(), cell->name.c_str()); - RTLIL::SigSpec sig_q = assign_map(cell->connections_["\\Q"]); - RTLIL::SigSpec sig_d = assign_map(cell->connections_["\\D"]); - clk = cell->connections_["\\CLK"]; + RTLIL::SigSpec sig_q = assign_map(cell->get("\\Q")); + RTLIL::SigSpec sig_d = assign_map(cell->get("\\D")); + clk = cell->get("\\CLK"); clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); if (cell->type == "$adff") { - arst = cell->connections_["\\ARST"]; + arst = cell->get("\\ARST"); arst_polarity = cell->parameters["\\ARST_POLARITY"].as_bool(); reset_state = cell->parameters["\\ARST_VALUE"]; } @@ -224,9 +224,9 @@ static void extract_fsm(RTLIL::Wire *wire) sig2trigger.find(dff_out, cellport_list); for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells.at(cellport.first); - RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); - RTLIL::SigSpec sig_y = assign_map(cell->connections_["\\Y"]); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); + RTLIL::SigSpec sig_y = assign_map(cell->get("\\Y")); if (cellport.second == "\\A" && !sig_b.is_fully_const()) continue; if (cellport.second == "\\B" && !sig_a.is_fully_const()) @@ -271,12 +271,12 @@ static void extract_fsm(RTLIL::Wire *wire) // create fsm cell RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), RTLIL::autoidx++), "$fsm"); - fsm_cell->connections_["\\CLK"] = clk; - fsm_cell->connections_["\\ARST"] = arst; + fsm_cell->set("\\CLK", clk); + fsm_cell->set("\\ARST", arst); fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); fsm_cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity ? 1 : 0, 1); - fsm_cell->connections_["\\CTRL_IN"] = ctrl_in; - fsm_cell->connections_["\\CTRL_OUT"] = ctrl_out; + fsm_cell->set("\\CTRL_IN", ctrl_in); + fsm_cell->set("\\CTRL_OUT", ctrl_out); fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name); fsm_cell->attributes = wire->attributes; fsm_data.copy_to_cell(fsm_cell); @@ -294,13 +294,13 @@ static void extract_fsm(RTLIL::Wire *wire) sig2driver.find(ctrl_out, cellport_list); for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells.at(cellport.first); - RTLIL::SigSpec port_sig = assign_map(cell->connections_[cellport.second]); + RTLIL::SigSpec port_sig = assign_map(cell->connections()[cellport.second]); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = new RTLIL::Wire; unconn_wire->name = stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++); unconn_wire->width = unconn_sig.size(); module->wires[unconn_wire->name] = unconn_wire; - port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); + port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections()[cellport.second]); } } @@ -344,14 +344,14 @@ struct FsmExtractPass : public Pass { sig2driver.clear(); sig2trigger.clear(); for (auto &cell_it : module->cells) - for (auto &conn_it : cell_it.second->connections_) { + for (auto &conn_it : cell_it.second->connections()) { if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); sig2driver.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); } - if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->connections_.count("\\Y") > 0 && - cell_it.second->connections_["\\Y"].size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { + if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->connections().count("\\Y") > 0 && + cell_it.second->get("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); sig2trigger.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index cf482d6d..a22441b4 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -58,9 +58,9 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$eq"); - eq_cell->connections_["\\A"] = eq_sig_a; - eq_cell->connections_["\\B"] = eq_sig_b; - eq_cell->connections_["\\Y"] = RTLIL::SigSpec(eq_wire); + eq_cell->set("\\A", eq_sig_a); + eq_cell->set("\\B", eq_sig_b); + eq_cell->set("\\Y", RTLIL::SigSpec(eq_wire)); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size()); @@ -80,8 +80,8 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$reduce_or"); - or_cell->connections_["\\A"] = or_sig; - or_cell->connections_["\\Y"] = RTLIL::SigSpec(or_wire); + or_cell->set("\\A", or_sig); + or_cell->set("\\Y", RTLIL::SigSpec(or_wire)); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); @@ -96,9 +96,9 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$and"); - and_cell->connections_["\\A"] = and_sig.extract(0, 1); - and_cell->connections_["\\B"] = and_sig.extract(1, 1); - and_cell->connections_["\\Y"] = RTLIL::SigSpec(and_wire); + and_cell->set("\\A", and_sig.extract(0, 1)); + and_cell->set("\\B", and_sig.extract(1, 1)); + and_cell->set("\\Y", RTLIL::SigSpec(and_wire)); and_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); and_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); and_cell->parameters["\\A_WIDTH"] = RTLIL::Const(1); @@ -119,15 +119,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 1) { RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or"); - or_cell->connections_["\\A"] = cases_vector; - or_cell->connections_["\\Y"] = output; + or_cell->set("\\A", cases_vector); + or_cell->set("\\Y", output); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); } else if (cases_vector.size() == 1) { - module->connections_.push_back(RTLIL::SigSig(output, cases_vector)); + module->connect(RTLIL::SigSig(output, cases_vector)); } else { - module->connections_.push_back(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); + module->connect(RTLIL::SigSig(output, RTLIL::SigSpec(0, 1))); } } @@ -138,8 +138,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) FsmData fsm_data; fsm_data.copy_from_cell(fsm_cell); - RTLIL::SigSpec ctrl_in = fsm_cell->connections_["\\CTRL_IN"]; - RTLIL::SigSpec ctrl_out = fsm_cell->connections_["\\CTRL_OUT"]; + RTLIL::SigSpec ctrl_in = fsm_cell->get("\\CTRL_IN"); + RTLIL::SigSpec ctrl_out = fsm_cell->get("\\CTRL_OUT"); // create state register @@ -153,7 +153,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits); RTLIL::Cell *state_dff = module->addCell(NEW_ID, ""); - if (fsm_cell->connections_["\\ARST"].is_fully_const()) { + if (fsm_cell->get("\\ARST").is_fully_const()) { state_dff->type = "$dff"; } else { state_dff->type = "$adff"; @@ -162,13 +162,13 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) for (auto &bit : state_dff->parameters["\\ARST_VALUE"].bits) if (bit != RTLIL::State::S1) bit = RTLIL::State::S0; - state_dff->connections_["\\ARST"] = fsm_cell->connections_["\\ARST"]; + state_dff->set("\\ARST", fsm_cell->get("\\ARST")); } state_dff->parameters["\\WIDTH"] = RTLIL::Const(fsm_data.state_bits); state_dff->parameters["\\CLK_POLARITY"] = fsm_cell->parameters["\\CLK_POLARITY"]; - state_dff->connections_["\\CLK"] = fsm_cell->connections_["\\CLK"]; - state_dff->connections_["\\D"] = RTLIL::SigSpec(next_state_wire); - state_dff->connections_["\\Q"] = RTLIL::SigSpec(state_wire); + state_dff->set("\\CLK", fsm_cell->get("\\CLK")); + state_dff->set("\\D", RTLIL::SigSpec(next_state_wire)); + state_dff->set("\\Q", RTLIL::SigSpec(state_wire)); // decode state register @@ -189,16 +189,16 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) if (sig_b == RTLIL::SigSpec(RTLIL::State::S1)) { - module->connections_.push_back(RTLIL::SigSig(RTLIL::SigSpec(state_onehot, i), sig_a)); + module->connect(RTLIL::SigSig(RTLIL::SigSpec(state_onehot, i), sig_a)); } else { encoding_is_onehot = false; RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq"); - eq_cell->connections_["\\A"] = sig_a; - eq_cell->connections_["\\B"] = sig_b; - eq_cell->connections_["\\Y"] = RTLIL::SigSpec(state_onehot, i); + eq_cell->set("\\A", sig_a); + eq_cell->set("\\B", sig_b); + eq_cell->set("\\Y", RTLIL::SigSpec(state_onehot, i)); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size()); @@ -245,7 +245,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, i)); } log_assert(!next_state_sig.has_marked_bits()); - module->connections_.push_back(RTLIL::SigSig(next_state_wire, next_state_sig)); + module->connect(RTLIL::SigSig(next_state_wire, next_state_sig)); } else { @@ -265,10 +265,10 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) } RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux"); - mux_cell->connections_["\\A"] = sig_a; - mux_cell->connections_["\\B"] = sig_b; - mux_cell->connections_["\\S"] = sig_s; - mux_cell->connections_["\\Y"] = RTLIL::SigSpec(next_state_wire); + mux_cell->set("\\A", sig_a); + mux_cell->set("\\B", sig_b); + mux_cell->set("\\S", sig_s); + mux_cell->set("\\Y", RTLIL::SigSpec(next_state_wire)); mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); } diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 3fde534d..e82b5363 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -52,7 +52,7 @@ struct FsmOpt void opt_const_and_unused_inputs() { - RTLIL::SigSpec ctrl_in = cell->connections_["\\CTRL_IN"]; + RTLIL::SigSpec ctrl_in = cell->get("\\CTRL_IN"); std::vector ctrl_in_used(ctrl_in.size()); std::vector new_transition_table; @@ -73,13 +73,13 @@ struct FsmOpt for (int i = int(ctrl_in_used.size())-1; i >= 0; i--) { if (!ctrl_in_used[i]) { - log(" Removing unused input signal %s.\n", log_signal(cell->connections_["\\CTRL_IN"].extract(i, 1))); + log(" Removing unused input signal %s.\n", log_signal(cell->get("\\CTRL_IN").extract(i, 1))); for (auto &tr : new_transition_table) { RTLIL::SigSpec tmp(tr.ctrl_in); tmp.remove(i, 1); tr.ctrl_in = tmp.as_const(); } - cell->connections_["\\CTRL_IN"].remove(i, 1); + cell->get("\\CTRL_IN").remove(i, 1); fsm_data.num_inputs--; } } @@ -91,10 +91,10 @@ struct FsmOpt void opt_unused_outputs() { for (int i = 0; i < fsm_data.num_outputs; i++) { - RTLIL::SigSpec sig = cell->connections_["\\CTRL_OUT"].extract(i, 1); + RTLIL::SigSpec sig = cell->get("\\CTRL_OUT").extract(i, 1); if (signal_is_unused(sig)) { log(" Removing unused output signal %s.\n", log_signal(sig)); - cell->connections_["\\CTRL_OUT"].remove(i, 1); + cell->get("\\CTRL_OUT").remove(i, 1); for (auto &tr : fsm_data.transition_table) { RTLIL::SigSpec tmp(tr.ctrl_out); tmp.remove(i, 1); @@ -108,7 +108,7 @@ struct FsmOpt void opt_alias_inputs() { - RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"]; + RTLIL::SigSpec &ctrl_in = cell->get("\\CTRL_IN"); for (int i = 0; i < ctrl_in.size(); i++) for (int j = i+1; j < ctrl_in.size(); j++) @@ -145,8 +145,8 @@ struct FsmOpt void opt_feedback_inputs() { - RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"]; - RTLIL::SigSpec &ctrl_out = cell->connections_["\\CTRL_OUT"]; + RTLIL::SigSpec &ctrl_in = cell->get("\\CTRL_IN"); + RTLIL::SigSpec &ctrl_out = cell->get("\\CTRL_OUT"); for (int j = 0; j < ctrl_out.size(); j++) for (int i = 0; i < ctrl_in.size(); i++) diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index a336d23f..8f0e5d62 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -141,13 +141,13 @@ struct FsmData log("\n"); log(" Input signals:\n"); - RTLIL::SigSpec sig_in = cell->connections_["\\CTRL_IN"]; + RTLIL::SigSpec sig_in = cell->get("\\CTRL_IN"); for (int i = 0; i < SIZE(sig_in); i++) log(" %3d: %s\n", i, log_signal(sig_in[i])); log("\n"); log(" Output signals:\n"); - RTLIL::SigSpec sig_out = cell->connections_["\\CTRL_OUT"]; + RTLIL::SigSpec sig_out = cell->get("\\CTRL_OUT"); for (int i = 0; i < SIZE(sig_out); i++) log(" %3d: %s\n", i, log_signal(sig_out[i])); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 4306c29e..5937373f 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -58,7 +58,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell for (auto i1 : design->modules) for (auto i2 : i1.second->cells) if (i2.second->type == celltype) { - for (auto &conn : i2.second->connections_) { + for (auto &conn : i2.second->connections()) { if (conn.first[0] != '$') portnames.insert(conn.first); portwidths[conn.first] = std::max(portwidths[conn.first], conn.second.size()); @@ -219,7 +219,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla RTLIL::Module *mod = design->modules[cell->type]; - for (auto &conn : cell->connections_) { + for (auto &conn : cell->connections()) { int conn_size = conn.second.size(); std::string portname = conn.first; if (portname.substr(0, 1) == "$") { @@ -486,7 +486,7 @@ struct HierarchyPass : public Pass { RTLIL::Cell *cell = cell_it.second; if (design->modules.count(cell->type) == 0) continue; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { pos_mods.insert(design->modules.at(cell->type)); pos_work.push_back(std::pair(mod_it.second, cell)); @@ -507,7 +507,7 @@ struct HierarchyPass : public Pass { log("Mapping positional arguments of cell %s.%s (%s).\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); std::map new_connections; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { int id = atoi(conn.first.c_str()+1); std::pair key(design->modules.at(cell->type), id); @@ -519,7 +519,7 @@ struct HierarchyPass : public Pass { new_connections[pos_map.at(key)] = conn.second; } else new_connections[conn.first] = conn.second; - cell->connections_ = new_connections; + cell->connections() = new_connections; } } diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index df5fd8e3..d72ebb12 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -79,11 +79,11 @@ struct SubmodWorker wire_flags.clear(); for (RTLIL::Cell *cell : submod.cells) { if (ct.cell_known(cell->type)) { - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) flag_signal(conn.second, true, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first), false, false); } else { log("WARNING: Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str()); - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) flag_signal(conn.second, true, true, true, false, false); } } @@ -92,11 +92,11 @@ struct SubmodWorker if (submod.cells.count(cell) > 0) continue; if (ct.cell_known(cell->type)) { - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) flag_signal(conn.second, false, false, false, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first)); } else { flag_found_something = false; - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) flag_signal(conn.second, false, false, false, true, true); if (flag_found_something) log("WARNING: Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str()); @@ -163,7 +163,7 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell); - for (auto &conn : new_cell->connections_) + for (auto &conn : new_cell->connections()) for (auto &bit : conn.second) if (bit.wire != NULL) { assert(wire_flags.count(bit.wire) > 0); @@ -180,7 +180,7 @@ struct SubmodWorker RTLIL::Wire *old_wire = it.first; RTLIL::Wire *new_wire = it.second.new_wire; if (new_wire->port_id > 0) - new_cell->connections_[new_wire->name] = RTLIL::SigSpec(old_wire); + new_cell->connections()[new_wire->name] = RTLIL::SigSpec(old_wire); } } diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index b4242f25..a8caf883 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -76,12 +76,12 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) wr_ports++; del_cells.push_back(cell); - RTLIL::SigSpec clk = cell->connections_["\\CLK"]; + RTLIL::SigSpec clk = cell->get("\\CLK"); RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); - RTLIL::SigSpec addr = cell->connections_["\\ADDR"]; - RTLIL::SigSpec data = cell->connections_["\\DATA"]; - RTLIL::SigSpec en = cell->connections_["\\EN"]; + RTLIL::SigSpec addr = cell->get("\\ADDR"); + RTLIL::SigSpec data = cell->get("\\DATA"); + RTLIL::SigSpec en = cell->get("\\EN"); clk.extend(1, false); clk_enable.extend(1, false); @@ -103,12 +103,12 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) rd_ports++; del_cells.push_back(cell); - RTLIL::SigSpec clk = cell->connections_["\\CLK"]; + RTLIL::SigSpec clk = cell->get("\\CLK"); RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); RTLIL::SigSpec transparent = RTLIL::SigSpec(cell->parameters["\\TRANSPARENT"]); - RTLIL::SigSpec addr = cell->connections_["\\ADDR"]; - RTLIL::SigSpec data = cell->connections_["\\DATA"]; + RTLIL::SigSpec addr = cell->get("\\ADDR"); + RTLIL::SigSpec data = cell->get("\\DATA"); clk.extend(1, false); clk_enable.extend(1, false); @@ -147,10 +147,10 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : RTLIL::Const(0, 0); mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : RTLIL::Const(0, 0); - mem->connections_["\\WR_CLK"] = sig_wr_clk; - mem->connections_["\\WR_ADDR"] = sig_wr_addr; - mem->connections_["\\WR_DATA"] = sig_wr_data; - mem->connections_["\\WR_EN"] = sig_wr_en; + mem->set("\\WR_CLK", sig_wr_clk); + mem->set("\\WR_ADDR", sig_wr_addr); + mem->set("\\WR_DATA", sig_wr_data); + mem->set("\\WR_EN", sig_wr_en); assert(sig_rd_clk.size() == rd_ports); assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); @@ -163,9 +163,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : RTLIL::Const(0, 0); mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : RTLIL::Const(0, 0); - mem->connections_["\\RD_CLK"] = sig_rd_clk; - mem->connections_["\\RD_ADDR"] = sig_rd_addr; - mem->connections_["\\RD_DATA"] = sig_rd_data; + mem->set("\\RD_CLK", sig_rd_clk); + mem->set("\\RD_ADDR", sig_rd_addr); + mem->set("\\RD_DATA", sig_rd_data); for (auto c : del_cells) module->remove(c); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 63f7d052..0513aa3d 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -25,7 +25,7 @@ static void normalize_sig(RTLIL::Module *module, RTLIL::SigSpec &sig) { - for (auto &conn : module->connections_) + for (auto &conn : module->connections()) sig.replace(conn.first, conn.second); } @@ -46,21 +46,21 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI continue; if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - if (cell->connections_["\\CLK"] != clk) + if (cell->get("\\CLK") != clk) continue; if (cell->parameters["\\CLK_POLARITY"].as_bool() != clk_polarity) continue; } - RTLIL::SigSpec q_norm = cell->connections_[after ? "\\D" : "\\Q"]; + RTLIL::SigSpec q_norm = cell->connections()[after ? "\\D" : "\\Q"]; normalize_sig(module, q_norm); - RTLIL::SigSpec d = q_norm.extract(bit, &cell->connections_[after ? "\\Q" : "\\D"]); + RTLIL::SigSpec d = q_norm.extract(bit, &cell->connections()[after ? "\\Q" : "\\D"]); if (d.size() != 1) continue; bit = d; - clk = cell->connections_["\\CLK"]; + clk = cell->get("\\CLK"); clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); goto replaced_this_bit; } @@ -79,29 +79,29 @@ static void handle_wr_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec clk = RTLIL::SigSpec(RTLIL::State::Sx); bool clk_polarity = 0; - RTLIL::SigSpec sig_addr = cell->connections_["\\ADDR"]; + RTLIL::SigSpec sig_addr = cell->get("\\ADDR"); if (!find_sig_before_dff(module, sig_addr, clk, clk_polarity)) { log("no (compatible) $dff for address input found.\n"); return; } - RTLIL::SigSpec sig_data = cell->connections_["\\DATA"]; + RTLIL::SigSpec sig_data = cell->get("\\DATA"); if (!find_sig_before_dff(module, sig_data, clk, clk_polarity)) { log("no (compatible) $dff for data input found.\n"); return; } - RTLIL::SigSpec sig_en = cell->connections_["\\EN"]; + RTLIL::SigSpec sig_en = cell->get("\\EN"); if (!find_sig_before_dff(module, sig_en, clk, clk_polarity)) { log("no (compatible) $dff for enable input found.\n"); return; } if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - cell->connections_["\\CLK"] = clk; - cell->connections_["\\ADDR"] = sig_addr; - cell->connections_["\\DATA"] = sig_data; - cell->connections_["\\EN"] = sig_en; + cell->set("\\CLK", clk); + cell->set("\\ADDR", sig_addr); + cell->set("\\DATA", sig_data); + cell->set("\\EN", sig_en); cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); log("merged $dff to cell.\n"); @@ -128,7 +128,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$dff") - cell->connections_["\\Q"].replace(sig, newsig); + cell->get("\\Q").replace(sig, newsig); } } @@ -139,13 +139,13 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) bool clk_polarity = 0; RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_data = cell->connections_["\\DATA"]; + RTLIL::SigSpec sig_data = cell->get("\\DATA"); if (find_sig_before_dff(module, sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) { disconnect_dff(module, sig_data); - cell->connections_["\\CLK"] = clk_data; - cell->connections_["\\DATA"] = sig_data; + cell->set("\\CLK", clk_data); + cell->set("\\DATA", sig_data); cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0); @@ -154,12 +154,12 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_addr = cell->connections_["\\ADDR"]; + RTLIL::SigSpec sig_addr = cell->get("\\ADDR"); if (find_sig_before_dff(module, sig_addr, clk_addr, clk_polarity) && clk_addr != RTLIL::SigSpec(RTLIL::State::Sx)) { - cell->connections_["\\CLK"] = clk_addr; - cell->connections_["\\ADDR"] = sig_addr; + cell->set("\\CLK", clk_addr); + cell->set("\\ADDR", sig_addr); cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); cell->parameters["\\TRANSPARENT"] = RTLIL::Const(1); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index a626b5af..5b180db6 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -62,20 +62,20 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) } // all write ports must share the same clock - RTLIL::SigSpec clocks = cell->connections_["\\WR_CLK"]; + RTLIL::SigSpec clocks = cell->get("\\WR_CLK"); RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"]; RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"]; RTLIL::SigSpec refclock; RTLIL::State refclock_pol = RTLIL::State::Sx; for (int i = 0; i < clocks.size(); i++) { - RTLIL::SigSpec wr_en = cell->connections_["\\WR_EN"].extract(i * mem_width, mem_width); + RTLIL::SigSpec wr_en = cell->get("\\WR_EN").extract(i * mem_width, mem_width); if (wr_en.is_fully_const() && !wr_en.as_bool()) { static_ports.insert(i); continue; } if (clocks_en.bits[i] != RTLIL::State::S1) { - RTLIL::SigSpec wr_addr = cell->connections_["\\WR_ADDR"].extract(i*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->connections_["\\WR_DATA"].extract(i*mem_width, mem_width); + RTLIL::SigSpec wr_addr = cell->get("\\WR_ADDR").extract(i*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->get("\\WR_DATA").extract(i*mem_width, mem_width); if (wr_addr.is_fully_const()) { // FIXME: Actually we should check for wr_en.is_fully_const() also and // create a $adff cell with this ports wr_en input as reset pin when wr_en @@ -120,10 +120,10 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; if (clocks_pol.bits.size() > 0) { c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]); - c->connections_["\\CLK"] = clocks.extract(0, 1); + c->set("\\CLK", clocks.extract(0, 1)); } else { c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1); - c->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::S0); + c->set("\\CLK", RTLIL::SigSpec(RTLIL::State::S0)); } RTLIL::Wire *w_in = new RTLIL::Wire; @@ -131,7 +131,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) w_in->width = mem_width; module->wires[w_in->name] = w_in; data_reg_in.push_back(RTLIL::SigSpec(w_in)); - c->connections_["\\D"] = data_reg_in.back(); + c->set("\\D", data_reg_in.back()); RTLIL::Wire *w_out = new RTLIL::Wire; w_out->name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); @@ -141,7 +141,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) w_out->start_offset = mem_offset; module->wires[w_out->name] = w_out; data_reg_out.push_back(RTLIL::SigSpec(w_out)); - c->connections_["\\Q"] = data_reg_out.back(); + c->set("\\Q", data_reg_out.back()); } } @@ -151,10 +151,10 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++) { - RTLIL::SigSpec rd_addr = cell->connections_["\\RD_ADDR"].extract(i*mem_abits, mem_abits); + RTLIL::SigSpec rd_addr = cell->get("\\RD_ADDR").extract(i*mem_abits, mem_abits); std::vector rd_signals; - rd_signals.push_back(cell->connections_["\\RD_DATA"].extract(i*mem_width, mem_width)); + rd_signals.push_back(cell->get("\\RD_DATA").extract(i*mem_width, mem_width)); if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1) { @@ -163,8 +163,8 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = RTLIL::Const(mem_abits); c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->connections_["\\CLK"] = cell->connections_["\\RD_CLK"].extract(i, 1); - c->connections_["\\D"] = rd_addr; + c->set("\\CLK", cell->get("\\RD_CLK").extract(i, 1)); + c->set("\\D", rd_addr); count_dff++; RTLIL::Wire *w = new RTLIL::Wire; @@ -172,7 +172,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) w->width = mem_abits; module->wires[w->name] = w; - c->connections_["\\Q"] = RTLIL::SigSpec(w); + c->set("\\Q", RTLIL::SigSpec(w)); rd_addr = RTLIL::SigSpec(w); } else @@ -180,8 +180,8 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->connections_["\\CLK"] = cell->connections_["\\RD_CLK"].extract(i, 1); - c->connections_["\\Q"] = rd_signals.back(); + c->set("\\CLK", cell->get("\\RD_CLK").extract(i, 1)); + c->set("\\Q", rd_signals.back()); count_dff++; RTLIL::Wire *w = new RTLIL::Wire; @@ -191,7 +191,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) rd_signals.clear(); rd_signals.push_back(RTLIL::SigSpec(w)); - c->connections_["\\D"] = rd_signals.back(); + c->set("\\D", rd_signals.back()); } } @@ -203,31 +203,31 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) { RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; - c->connections_["\\Y"] = rd_signals[k]; - c->connections_["\\S"] = rd_addr.extract(mem_abits-j-1, 1); + c->set("\\Y", rd_signals[k]); + c->set("\\S", rd_addr.extract(mem_abits-j-1, 1)); count_mux++; RTLIL::Wire *w = new RTLIL::Wire; w->name = genid(cell->name, "$rdmux", i, "", j, "", k, "$a"); w->width = mem_width; module->wires[w->name] = w; - c->connections_["\\A"] = RTLIL::SigSpec(w); + c->set("\\A", RTLIL::SigSpec(w)); w = new RTLIL::Wire; w->name = genid(cell->name, "$rdmux", i, "", j, "", k, "$b"); w->width = mem_width; module->wires[w->name] = w; - c->connections_["\\B"] = RTLIL::SigSpec(w); + c->set("\\B", RTLIL::SigSpec(w)); - next_rd_signals.push_back(c->connections_["\\A"]); - next_rd_signals.push_back(c->connections_["\\B"]); + next_rd_signals.push_back(c->get("\\A")); + next_rd_signals.push_back(c->get("\\B")); } next_rd_signals.swap(rd_signals); } for (int j = 0; j < mem_size; j++) - module->connections_.push_back(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); + module->connect(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); } log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); @@ -241,9 +241,9 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++) { - RTLIL::SigSpec wr_addr = cell->connections_["\\WR_ADDR"].extract(j*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->connections_["\\WR_DATA"].extract(j*mem_width, mem_width); - RTLIL::SigSpec wr_en = cell->connections_["\\WR_EN"].extract(j*mem_width, mem_width); + RTLIL::SigSpec wr_addr = cell->get("\\WR_ADDR").extract(j*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->get("\\WR_DATA").extract(j*mem_width, mem_width); + RTLIL::SigSpec wr_en = cell->get("\\WR_EN").extract(j*mem_width, mem_width); RTLIL::Cell *c = module->addCell(genid(cell->name, "$wreq", i, "", j), "$eq"); c->parameters["\\A_SIGNED"] = RTLIL::Const(0); @@ -251,14 +251,14 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\A_WIDTH"] = cell->parameters["\\ABITS"]; c->parameters["\\B_WIDTH"] = cell->parameters["\\ABITS"]; c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->connections_["\\A"] = RTLIL::SigSpec(i, mem_abits); - c->connections_["\\B"] = wr_addr; + c->set("\\A", RTLIL::SigSpec(i, mem_abits)); + c->set("\\B", wr_addr); count_wrmux++; RTLIL::Wire *w_seladdr = new RTLIL::Wire; w_seladdr->name = genid(cell->name, "$wreq", i, "", j, "$y"); module->wires[w_seladdr->name] = w_seladdr; - c->connections_["\\Y"] = w_seladdr; + c->set("\\Y", w_seladdr); int wr_offset = 0; while (wr_offset < wr_en.size()) @@ -283,33 +283,33 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\A_WIDTH"] = RTLIL::Const(1); c->parameters["\\B_WIDTH"] = RTLIL::Const(1); c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->connections_["\\A"] = w; - c->connections_["\\B"] = wr_bit; + c->set("\\A", w); + c->set("\\B", wr_bit); w = new RTLIL::Wire; w->name = genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"); module->wires[w->name] = w; - c->connections_["\\Y"] = RTLIL::SigSpec(w); + c->set("\\Y", RTLIL::SigSpec(w)); } c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); c->parameters["\\WIDTH"] = wr_width; - c->connections_["\\A"] = sig.extract(wr_offset, wr_width); - c->connections_["\\B"] = wr_data.extract(wr_offset, wr_width); - c->connections_["\\S"] = RTLIL::SigSpec(w); + c->set("\\A", sig.extract(wr_offset, wr_width)); + c->set("\\B", wr_data.extract(wr_offset, wr_width)); + c->set("\\S", RTLIL::SigSpec(w)); w = new RTLIL::Wire; w->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"); w->width = wr_width; module->wires[w->name] = w; - c->connections_["\\Y"] = w; + c->set("\\Y", w); sig.replace(wr_offset, w); wr_offset += wr_width; } } - module->connections_.push_back(RTLIL::SigSig(data_reg_in[i], sig)); + module->connect(RTLIL::SigSig(data_reg_in[i], sig)); } log(" write interface: %d blocks of $eq, $and and $mux cells.\n", count_wrmux); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 919e24a4..8b4eb0d0 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -64,16 +64,16 @@ struct MemoryShareWorker RTLIL::Cell *cell = sig_to_mux.at(sig).first; int bit_idx = sig_to_mux.at(sig).second; - std::vector sig_a = sigmap(cell->connections_.at("\\A")); - std::vector sig_b = sigmap(cell->connections_.at("\\B")); - std::vector sig_s = sigmap(cell->connections_.at("\\S")); - std::vector sig_y = sigmap(cell->connections_.at("\\Y")); + std::vector sig_a = sigmap(cell->get("\\A")); + std::vector sig_b = sigmap(cell->get("\\B")); + std::vector sig_s = sigmap(cell->get("\\S")); + std::vector sig_y = sigmap(cell->get("\\Y")); log_assert(sig_y.at(bit_idx) == sig); for (int i = 0; i < int(sig_s.size()); i++) if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) - cell->connections_.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->get("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); return false; } @@ -87,7 +87,7 @@ struct MemoryShareWorker new_state[sig_s[i]] = true; if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) - cell->connections_.at("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->get("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); } std::map new_state = state; @@ -95,7 +95,7 @@ struct MemoryShareWorker new_state[sig_s[i]] = false; if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) - cell->connections_.at("\\A").replace(bit_idx, RTLIL::State::Sx); + cell->get("\\A").replace(bit_idx, RTLIL::State::Sx); return false; } @@ -141,10 +141,10 @@ struct MemoryShareWorker if (cell->type == "$mux" || cell->type == "$pmux") { - std::vector sig_a = sigmap(cell->connections_.at("\\A")); - std::vector sig_b = sigmap(cell->connections_.at("\\B")); - std::vector sig_s = sigmap(cell->connections_.at("\\S")); - std::vector sig_y = sigmap(cell->connections_.at("\\Y")); + std::vector sig_a = sigmap(cell->get("\\A")); + std::vector sig_b = sigmap(cell->get("\\B")); + std::vector sig_s = sigmap(cell->get("\\S")); + std::vector sig_y = sigmap(cell->get("\\Y")); non_feedback_nets.insert(sig_s.begin(), sig_s.end()); @@ -161,7 +161,7 @@ struct MemoryShareWorker cell->parameters.at("\\MEMID").decode_string() == memid) ignore_data_port = true; - for (auto conn : cell_it.second->connections_) + for (auto conn : cell_it.second->connections()) { if (ignore_data_port && conn.first == "\\DATA") continue; @@ -191,8 +191,8 @@ struct MemoryShareWorker if (cell->parameters.at("\\CLK_ENABLE").as_bool()) continue; - RTLIL::SigSpec sig_addr = sigmap(cell->connections_.at("\\ADDR")); - std::vector sig_data = sigmap(cell->connections_.at("\\DATA")); + RTLIL::SigSpec sig_addr = sigmap(cell->get("\\ADDR")); + std::vector sig_data = sigmap(cell->get("\\DATA")); for (int i = 0; i < int(sig_data.size()); i++) if (non_feedback_nets.count(sig_data[i])) @@ -212,14 +212,14 @@ struct MemoryShareWorker for (auto cell : wr_ports) { - RTLIL::SigSpec sig_addr = sigmap_xmux(cell->connections_.at("\\ADDR")); + RTLIL::SigSpec sig_addr = sigmap_xmux(cell->get("\\ADDR")); if (!async_rd_bits.count(sig_addr)) continue; log(" Analyzing write port %s.\n", log_id(cell)); - std::vector cell_data = cell->connections_.at("\\DATA"); - std::vector cell_en = cell->connections_.at("\\EN"); + std::vector cell_data = cell->get("\\DATA"); + std::vector cell_en = cell->get("\\EN"); int created_conditions = 0; for (int i = 0; i < int(cell_data.size()); i++) @@ -239,7 +239,7 @@ struct MemoryShareWorker if (created_conditions) { log(" Added enable logic for %d different cases.\n", created_conditions); - cell->connections_.at("\\EN") = cell_en; + cell->get("\\EN") = cell_en; } } } @@ -357,15 +357,15 @@ struct MemoryShareWorker for (int i = 0; i < int(wr_ports.size()); i++) { RTLIL::Cell *cell = wr_ports.at(i); - RTLIL::SigSpec addr = sigmap_xmux(cell->connections_.at("\\ADDR")); + RTLIL::SigSpec addr = sigmap_xmux(cell->get("\\ADDR")); if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->connections_.at("\\CLK")) != cache_clk || + (cache_clk_enable && (sigmap(cell->get("\\CLK")) != cache_clk || cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) { cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); - cache_clk = sigmap(cell->connections_.at("\\CLK")); + cache_clk = sigmap(cell->get("\\CLK")); last_port_by_addr.clear(); if (cache_clk_enable) @@ -377,7 +377,7 @@ struct MemoryShareWorker log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr)); log(" Active bits: "); - std::vector en_bits = sigmap(cell->connections_.at("\\EN")); + std::vector en_bits = sigmap(cell->get("\\EN")); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) { active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0; @@ -399,13 +399,13 @@ struct MemoryShareWorker // Force this ports addr input to addr directly (skip don't care muxes) - cell->connections_.at("\\ADDR") = addr; + cell->get("\\ADDR") = addr; // If any of the ports between `last_i' and `i' write to the same address, this // will have priority over whatever `last_i` wrote. So we need to revisit those // ports and mask the EN bits accordingly. - RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->connections_.at("\\EN")); + RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->get("\\EN")); for (int j = last_i+1; j < i; j++) { @@ -420,20 +420,20 @@ struct MemoryShareWorker found_overlapping_bits_i_j: log(" Creating collosion-detect logic for port %d.\n", j); RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID); - module->addEq(NEW_ID, addr, wr_ports[j]->connections_.at("\\ADDR"), is_same_addr); - merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->connections_.at("\\EN"))); + module->addEq(NEW_ID, addr, wr_ports[j]->get("\\ADDR"), is_same_addr); + merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->get("\\EN"))); } } // Then we need to merge the (masked) EN and the DATA signals. - RTLIL::SigSpec merged_data = wr_ports[last_i]->connections_.at("\\DATA"); + RTLIL::SigSpec merged_data = wr_ports[last_i]->get("\\DATA"); if (found_overlapping_bits) { log(" Creating logic for merging DATA and EN ports.\n"); - merge_en_data(merged_en, merged_data, sigmap(cell->connections_.at("\\EN")), sigmap(cell->connections_.at("\\DATA"))); + merge_en_data(merged_en, merged_data, sigmap(cell->get("\\EN")), sigmap(cell->get("\\DATA"))); } else { - RTLIL::SigSpec cell_en = sigmap(cell->connections_.at("\\EN")); - RTLIL::SigSpec cell_data = sigmap(cell->connections_.at("\\DATA")); + RTLIL::SigSpec cell_en = sigmap(cell->get("\\EN")); + RTLIL::SigSpec cell_data = sigmap(cell->get("\\DATA")); for (int k = 0; k < int(en_bits.size()); k++) if (!active_bits_on_port[last_i][k]) { merged_en.replace(k, cell_en.extract(k, 1)); @@ -443,14 +443,14 @@ struct MemoryShareWorker // Connect the new EN and DATA signals and remove the old write port. - cell->connections_.at("\\EN") = merged_en; - cell->connections_.at("\\DATA") = merged_data; + cell->get("\\EN") = merged_en; + cell->get("\\DATA") = merged_data; module->remove(wr_ports[last_i]); wr_ports[last_i] = NULL; log(" Active bits: "); - std::vector en_bits = sigmap(cell->connections_.at("\\EN")); + std::vector en_bits = sigmap(cell->get("\\EN")); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) log("%c", active_bits_on_port[i][k] ? '1' : '0'); @@ -489,7 +489,7 @@ struct MemoryShareWorker std::set considered_port_pairs; for (int i = 0; i < int(wr_ports.size()); i++) { - std::vector bits = modwalker.sigmap(wr_ports[i]->connections_.at("\\EN")); + std::vector bits = modwalker.sigmap(wr_ports[i]->get("\\EN")); for (auto bit : bits) if (bit == RTLIL::State::S1) goto port_is_always_active; @@ -509,12 +509,12 @@ struct MemoryShareWorker RTLIL::Cell *cell = wr_ports.at(i); if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->connections_.at("\\CLK")) != cache_clk || + (cache_clk_enable && (sigmap(cell->get("\\CLK")) != cache_clk || cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) { cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); - cache_clk = sigmap(cell->connections_.at("\\CLK")); + cache_clk = sigmap(cell->get("\\CLK")); } else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i)) considered_port_pairs.insert(i); @@ -542,7 +542,7 @@ struct MemoryShareWorker for (int i = 0; i < int(wr_ports.size()); i++) if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1)) { - RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->connections_.at("\\EN")); + RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->get("\\EN")); port_to_sat_variable[i] = ez.expression(ez.OpOr, satgen.importSigSpec(sig)); std::vector bits = sig; @@ -585,18 +585,18 @@ struct MemoryShareWorker log(" Merging port %d into port %d.\n", i-1, i); port_to_sat_variable.at(i) = ez.OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i)); - RTLIL::SigSpec last_addr = wr_ports[i-1]->connections_.at("\\ADDR"); - RTLIL::SigSpec last_data = wr_ports[i-1]->connections_.at("\\DATA"); - std::vector last_en = modwalker.sigmap(wr_ports[i-1]->connections_.at("\\EN")); + RTLIL::SigSpec last_addr = wr_ports[i-1]->get("\\ADDR"); + RTLIL::SigSpec last_data = wr_ports[i-1]->get("\\DATA"); + std::vector last_en = modwalker.sigmap(wr_ports[i-1]->get("\\EN")); - RTLIL::SigSpec this_addr = wr_ports[i]->connections_.at("\\ADDR"); - RTLIL::SigSpec this_data = wr_ports[i]->connections_.at("\\DATA"); - std::vector this_en = modwalker.sigmap(wr_ports[i]->connections_.at("\\EN")); + RTLIL::SigSpec this_addr = wr_ports[i]->get("\\ADDR"); + RTLIL::SigSpec this_data = wr_ports[i]->get("\\DATA"); + std::vector this_en = modwalker.sigmap(wr_ports[i]->get("\\EN")); RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); - wr_ports[i]->connections_.at("\\ADDR") = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); - wr_ports[i]->connections_.at("\\DATA") = module->Mux(NEW_ID, last_data, this_data, this_en_active); + wr_ports[i]->get("\\ADDR") = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); + wr_ports[i]->get("\\DATA") = module->Mux(NEW_ID, last_data, this_data, this_en_active); std::map, int> groups_en; RTLIL::SigSpec grouped_last_en, grouped_this_en, en; @@ -614,7 +614,7 @@ struct MemoryShareWorker } module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); - wr_ports[i]->connections_.at("\\EN") = en; + wr_ports[i]->get("\\EN") = en; module->remove(wr_ports[i-1]); wr_ports[i-1] = NULL; @@ -653,18 +653,18 @@ struct MemoryShareWorker if (cell->type == "$mux") { - RTLIL::SigSpec sig_a = sigmap_xmux(cell->connections_.at("\\A")); - RTLIL::SigSpec sig_b = sigmap_xmux(cell->connections_.at("\\B")); + RTLIL::SigSpec sig_a = sigmap_xmux(cell->get("\\A")); + RTLIL::SigSpec sig_b = sigmap_xmux(cell->get("\\B")); if (sig_a.is_fully_undef()) - sigmap_xmux.add(cell->connections_.at("\\Y"), sig_b); + sigmap_xmux.add(cell->get("\\Y"), sig_b); else if (sig_b.is_fully_undef()) - sigmap_xmux.add(cell->connections_.at("\\Y"), sig_a); + sigmap_xmux.add(cell->get("\\Y"), sig_a); } if (cell->type == "$mux" || cell->type == "$pmux") { - std::vector sig_y = sigmap(cell->connections_.at("\\Y")); + std::vector sig_y = sigmap(cell->get("\\Y")); for (int i = 0; i < int(sig_y.size()); i++) sig_to_mux[sig_y[i]] = std::pair(cell, i); } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 9c457ad5..f0835076 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -54,9 +54,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_ENABLE")).extract(i, 1).as_const(); cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const(); cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const(); - cell->connections_["\\CLK"] = memory->connections_.at("\\RD_CLK").extract(i, 1); - cell->connections_["\\ADDR"] = memory->connections_.at("\\RD_ADDR").extract(i*abits, abits); - cell->connections_["\\DATA"] = memory->connections_.at("\\RD_DATA").extract(i*mem->width, mem->width); + cell->set("\\CLK", memory->get("\\RD_CLK").extract(i, 1)); + cell->set("\\ADDR", memory->get("\\RD_ADDR").extract(i*abits, abits)); + cell->set("\\DATA", memory->get("\\RD_DATA").extract(i*mem->width, mem->width)); } for (int i = 0; i < num_wr_ports; i++) @@ -68,10 +68,10 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_ENABLE")).extract(i, 1).as_const(); cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const(); cell->parameters["\\PRIORITY"] = i; - cell->connections_["\\CLK"] = memory->connections_.at("\\WR_CLK").extract(i, 1); - cell->connections_["\\EN"] = memory->connections_.at("\\WR_EN").extract(i*mem->width, mem->width); - cell->connections_["\\ADDR"] = memory->connections_.at("\\WR_ADDR").extract(i*abits, abits); - cell->connections_["\\DATA"] = memory->connections_.at("\\WR_DATA").extract(i*mem->width, mem->width); + cell->set("\\CLK", memory->get("\\WR_CLK").extract(i, 1)); + cell->set("\\EN", memory->get("\\WR_EN").extract(i*mem->width, mem->width)); + cell->set("\\ADDR", memory->get("\\WR_ADDR").extract(i*abits, abits)); + cell->set("\\DATA", memory->get("\\WR_DATA").extract(i*mem->width, mem->width)); } module->remove(memory); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 30ab8814..fa5d8f18 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -40,7 +40,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) SigSet wire2driver; for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - for (auto &it2 : cell->connections_) { + for (auto &it2 : cell->connections()) { if (!ct.cell_input(cell->type, it2.first)) { RTLIL::SigSpec sig = it2.second; assign_map.apply(sig); @@ -70,7 +70,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) for (auto cell : queue) unused.erase(cell); for (auto cell : queue) { - for (auto &it : cell->connections_) { + for (auto &it : cell->connections()) { if (!ct.cell_output(cell->type, it.first)) { std::set cell_list; RTLIL::SigSpec sig = it.second; @@ -158,10 +158,10 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; if (ct_reg.cell_known(cell->type)) - for (auto &it2 : cell->connections_) + for (auto &it2 : cell->connections()) if (ct_reg.cell_output(cell->type, it2.first)) register_signals.add(it2.second); - for (auto &it2 : cell->connections_) + for (auto &it2 : cell->connections()) connected_signals.add(it2.second); } @@ -171,7 +171,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; if (ct_all.cell_known(cell->type)) - for (auto &it2 : cell->connections_) + for (auto &it2 : cell->connections()) if (ct_all.cell_output(cell->type, it2.first)) direct_sigs.insert(assign_map(it2.second)); } @@ -189,13 +189,13 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } } - module->connections_.clear(); + module->connections().clear(); SigPool used_signals; SigPool used_signals_nodrivers; for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - for (auto &it2 : cell->connections_) { + for (auto &it2 : cell->connections()) { assign_map.apply(it2.second); used_signals.add(it2.second); if (!ct.cell_output(cell->type, it2.first)) @@ -237,7 +237,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (new_conn.first.size() > 0) { used_signals.add(new_conn.first); used_signals.add(new_conn.second); - module->connections_.push_back(new_conn); + module->connect(new_conn); } } } else { diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 2a5ec8be..7f420ec3 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -38,7 +38,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) SigPool all_signals; for (auto &it : module->cells) - for (auto &conn : it.second->connections_) { + for (auto &conn : it.second->connections()) { if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) driven_signals.add(sigmap(conn.second)); if (!ct.cell_known(it.second->type) || ct.cell_input(it.second->type, conn.first)) @@ -66,21 +66,21 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) continue; log("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c)); - module->connections_.push_back(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width))); + module->connect(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width))); OPT_DID_SOMETHING = true; } } static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { - RTLIL::SigSpec Y = cell->connections_[out_port]; + RTLIL::SigSpec Y = cell->connections()[out_port]; out_val.extend_u0(Y.size(), false); log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", cell->type.c_str(), cell->name.c_str(), info.c_str(), module->name.c_str(), log_signal(Y), log_signal(out_val)); // ILANG_BACKEND::dump_cell(stderr, "--> ", cell); - module->connections_.push_back(RTLIL::SigSig(Y, out_val)); + module->connect(RTLIL::SigSig(Y, out_val)); module->remove(cell); OPT_DID_SOMETHING = true; did_something = true; @@ -88,14 +88,14 @@ static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string i static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, bool extend_u0, SigMap &sigmap) { - std::string b_name = cell->connections_.count("\\B") ? "\\B" : "\\A"; + std::string b_name = cell->connections().count("\\B") ? "\\B" : "\\A"; bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool(); bool b_signed = cell->parameters.at(b_name + "_SIGNED").as_bool(); - RTLIL::SigSpec sig_a = sigmap(cell->connections_.at("\\A")); - RTLIL::SigSpec sig_b = sigmap(cell->connections_.at(b_name)); - RTLIL::SigSpec sig_y = sigmap(cell->connections_.at("\\Y")); + RTLIL::SigSpec sig_a = sigmap(cell->get("\\A")); + RTLIL::SigSpec sig_b = sigmap(cell->connections().at(b_name)); + RTLIL::SigSpec sig_y = sigmap(cell->get("\\Y")); if (extend_u0) { sig_a.extend_u0(sig_y.size(), a_signed); @@ -160,21 +160,21 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); - c->connections_["\\A"] = new_a; + c->set("\\A", new_a); c->parameters["\\A_WIDTH"] = new_a.size(); c->parameters["\\A_SIGNED"] = false; if (b_name == "\\B") { - c->connections_["\\B"] = new_b; + c->set("\\B", new_b); c->parameters["\\B_WIDTH"] = new_b.size(); c->parameters["\\B_SIGNED"] = false; } - c->connections_["\\Y"] = new_y; + c->set("\\Y", new_y); c->parameters["\\Y_WIDTH"] = new_y->width; c->check(); - module->connections_.push_back(new_conn); + module->connect(new_conn); log(" New cell `%s': A=%s", log_id(c), log_signal(new_a)); if (b_name == "\\B") @@ -203,8 +203,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (auto &cell_it : module->cells) if (design->selected(module, cell_it.second)) { if ((cell_it.second->type == "$_INV_" || cell_it.second->type == "$not" || cell_it.second->type == "$logic_not") && - cell_it.second->connections_["\\A"].size() == 1 && cell_it.second->connections_["\\Y"].size() == 1) - invert_map[assign_map(cell_it.second->connections_["\\Y"])] = assign_map(cell_it.second->connections_["\\A"]); + cell_it.second->get("\\A").size() == 1 && cell_it.second->get("\\Y").size() == 1) + invert_map[assign_map(cell_it.second->get("\\Y"))] = assign_map(cell_it.second->get("\\A")); cells.push_back(cell_it.second); } @@ -222,7 +222,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$reduce_and") { - RTLIL::SigSpec sig_a = assign_map(cell->connections_.at("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); RTLIL::State new_a = RTLIL::State::S1; for (auto &bit : sig_a.to_sigbit_vector()) @@ -240,7 +240,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover("opt.opt_const.fine.$reduce_and"); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->connections_.at("\\A") = sig_a = new_a; + cell->get("\\A") = sig_a = new_a; cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -249,7 +249,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") { - RTLIL::SigSpec sig_a = assign_map(cell->connections_.at("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); RTLIL::State new_a = RTLIL::State::S0; for (auto &bit : sig_a.to_sigbit_vector()) @@ -267,7 +267,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->connections_.at("\\A") = sig_a = new_a; + cell->get("\\A") = sig_a = new_a; cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -276,7 +276,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$logic_and" || cell->type == "$logic_or") { - RTLIL::SigSpec sig_b = assign_map(cell->connections_.at("\\B")); + RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); RTLIL::State new_b = RTLIL::State::S0; for (auto &bit : sig_b.to_sigbit_vector()) @@ -294,7 +294,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.B", "$logic_and", "$logic_or", cell->type); log("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); - cell->connections_.at("\\B") = sig_b = new_b; + cell->get("\\B") = sig_b = new_b; cell->parameters.at("\\B_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -302,13 +302,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } } - if (cell->type == "$logic_or" && (assign_map(cell->connections_.at("\\A")) == RTLIL::State::S1 || assign_map(cell->connections_.at("\\B")) == RTLIL::State::S1)) { + if (cell->type == "$logic_or" && (assign_map(cell->get("\\A")) == RTLIL::State::S1 || assign_map(cell->get("\\B")) == RTLIL::State::S1)) { cover("opt.opt_const.one_high"); replace_cell(module, cell, "one high", "\\Y", RTLIL::State::S1); goto next_cell; } - if (cell->type == "$logic_and" && (assign_map(cell->connections_.at("\\A")) == RTLIL::State::S0 || assign_map(cell->connections_.at("\\B")) == RTLIL::State::S0)) { + if (cell->type == "$logic_and" && (assign_map(cell->get("\\A")) == RTLIL::State::S0 || assign_map(cell->get("\\B")) == RTLIL::State::S0)) { cover("opt.opt_const.one_low"); replace_cell(module, cell, "one low", "\\Y", RTLIL::State::S0); goto next_cell; @@ -320,8 +320,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || cell->type == "$pow") { - RTLIL::SigSpec sig_a = assign_map(cell->connections_.at("\\A")); - RTLIL::SigSpec sig_b = cell->connections_.count("\\B") ? assign_map(cell->connections_.at("\\B")) : RTLIL::SigSpec(); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_b = cell->connections().count("\\B") ? assign_map(cell->get("\\B")) : RTLIL::SigSpec(); if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") sig_a = RTLIL::SigSpec(); @@ -342,31 +342,31 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); else - replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->connections_.at("\\Y").size())); + replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->get("\\Y").size())); goto next_cell; } } - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->connections_["\\Y"].size() == 1 && - invert_map.count(assign_map(cell->connections_["\\A"])) != 0) { + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->get("\\Y").size() == 1 && + invert_map.count(assign_map(cell->get("\\A"))) != 0) { cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); - replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->connections_["\\A"]))); + replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->get("\\A")))); goto next_cell; } - if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->connections_["\\S"])) != 0) { + if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->get("\\S"))) != 0) { cover_list("opt.opt_const.invert.muxsel", "$_MUX_", "$mux", cell->type); - RTLIL::SigSpec tmp = cell->connections_["\\A"]; - cell->connections_["\\A"] = cell->connections_["\\B"]; - cell->connections_["\\B"] = tmp; - cell->connections_["\\S"] = invert_map.at(assign_map(cell->connections_["\\S"])); + RTLIL::SigSpec tmp = cell->get("\\A"); + cell->set("\\A", cell->get("\\B")); + cell->set("\\B", tmp); + cell->set("\\S", invert_map.at(assign_map(cell->get("\\S")))); OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } if (cell->type == "$_INV_") { - RTLIL::SigSpec input = cell->connections_["\\A"]; + RTLIL::SigSpec input = cell->get("\\A"); assign_map.apply(input); if (input.match("1")) ACTION_DO_Y(0); if (input.match("0")) ACTION_DO_Y(1); @@ -375,8 +375,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_AND_") { RTLIL::SigSpec input; - input.append(cell->connections_["\\B"]); - input.append(cell->connections_["\\A"]); + input.append(cell->get("\\B")); + input.append(cell->get("\\A")); assign_map.apply(input); if (input.match(" 0")) ACTION_DO_Y(0); if (input.match("0 ")) ACTION_DO_Y(0); @@ -394,8 +394,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_OR_") { RTLIL::SigSpec input; - input.append(cell->connections_["\\B"]); - input.append(cell->connections_["\\A"]); + input.append(cell->get("\\B")); + input.append(cell->get("\\A")); assign_map.apply(input); if (input.match(" 1")) ACTION_DO_Y(1); if (input.match("1 ")) ACTION_DO_Y(1); @@ -413,8 +413,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_XOR_") { RTLIL::SigSpec input; - input.append(cell->connections_["\\B"]); - input.append(cell->connections_["\\A"]); + input.append(cell->get("\\B")); + input.append(cell->get("\\A")); assign_map.apply(input); if (input.match("00")) ACTION_DO_Y(0); if (input.match("01")) ACTION_DO_Y(1); @@ -428,9 +428,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_MUX_") { RTLIL::SigSpec input; - input.append(cell->connections_["\\S"]); - input.append(cell->connections_["\\B"]); - input.append(cell->connections_["\\A"]); + input.append(cell->get("\\S")); + input.append(cell->get("\\B")); + input.append(cell->get("\\A")); assign_map.apply(input); if (input.extract(2, 1) == input.extract(1, 1)) ACTION_DO("\\Y", input.extract(2, 1)); @@ -440,9 +440,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (input.match("10 ")) { cover("opt.opt_const.mux_to_inv"); cell->type = "$_INV_"; - cell->connections_["\\A"] = input.extract(0, 1); - cell->connections_.erase("\\B"); - cell->connections_.erase("\\S"); + cell->set("\\A", input.extract(0, 1)); + cell->connections().erase("\\B"); + cell->connections().erase("\\S"); goto next_cell; } if (input.match("11 ")) ACTION_DO_Y(1); @@ -459,8 +459,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex") { - RTLIL::SigSpec a = cell->connections_["\\A"]; - RTLIL::SigSpec b = cell->connections_["\\B"]; + RTLIL::SigSpec a = cell->get("\\A"); + RTLIL::SigSpec b = cell->get("\\B"); if (cell->parameters["\\A_WIDTH"].as_int() != cell->parameters["\\B_WIDTH"].as_int()) { int width = std::max(cell->parameters["\\A_WIDTH"].as_int(), cell->parameters["\\B_WIDTH"].as_int()); @@ -495,8 +495,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (new_a.size() < a.size() || new_b.size() < b.size()) { cover_list("opt.opt_const.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type); - cell->connections_["\\A"] = new_a; - cell->connections_["\\B"] = new_b; + cell->set("\\A", new_a); + cell->set("\\B", new_b); cell->parameters["\\A_WIDTH"] = new_a.size(); cell->parameters["\\B_WIDTH"] = new_b.size(); } @@ -505,24 +505,24 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->type == "$eq" || cell->type == "$ne") && cell->parameters["\\Y_WIDTH"].as_int() == 1 && cell->parameters["\\A_WIDTH"].as_int() == 1 && cell->parameters["\\B_WIDTH"].as_int() == 1) { - RTLIL::SigSpec a = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec a = assign_map(cell->get("\\A")); + RTLIL::SigSpec b = assign_map(cell->get("\\B")); if (a.is_fully_const()) { cover_list("opt.opt_const.eqneq.swapconst", "$eq", "$ne", cell->type); - std::swap(cell->connections_["\\A"], cell->connections_["\\B"]); + std::swap(cell->get("\\A"), cell->get("\\B")); } if (b.is_fully_const()) { if (b.as_bool() == (cell->type == "$eq")) { RTLIL::SigSpec input = b; - ACTION_DO("\\Y", cell->connections_["\\A"]); + ACTION_DO("\\Y", cell->get("\\A")); } else { cover_list("opt.opt_const.eqneq.isnot", "$eq", "$ne", cell->type); cell->type = "$not"; cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); - cell->connections_.erase("\\B"); + cell->connections().erase("\\B"); } goto next_cell; } @@ -536,8 +536,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$or" || cell->type == "$xor") { - RTLIL::SigSpec a = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec a = assign_map(cell->get("\\A")); + RTLIL::SigSpec b = assign_map(cell->get("\\B")); if (cell->type != "$sub" && a.is_fully_const() && a.as_bool() == false) identity_wrt_b = true; @@ -548,7 +548,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { - RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec b = assign_map(cell->get("\\B")); if (b.is_fully_const() && b.as_bool() == false) identity_wrt_a = true, identity_bu0 = true; @@ -556,8 +556,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$mul") { - RTLIL::SigSpec a = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec a = assign_map(cell->get("\\A")); + RTLIL::SigSpec b = assign_map(cell->get("\\B")); if (a.is_fully_const() && a.size() <= 32 && a.as_int() == 1) identity_wrt_b = true; @@ -568,7 +568,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$div") { - RTLIL::SigSpec b = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec b = assign_map(cell->get("\\B")); if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) identity_wrt_a = true; @@ -585,13 +585,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); if (!identity_wrt_a) { - cell->connections_.at("\\A") = cell->connections_.at("\\B"); + cell->get("\\A") = cell->get("\\B"); cell->parameters.at("\\A_WIDTH") = cell->parameters.at("\\B_WIDTH"); cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); } cell->type = identity_bu0 ? "$bu0" : "$pos"; - cell->connections_.erase("\\B"); + cell->connections().erase("\\B"); cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); cell->check(); @@ -603,18 +603,18 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->connections_["\\A"] == RTLIL::SigSpec(0, 1) && cell->connections_["\\B"] == RTLIL::SigSpec(1, 1)) { + cell->get("\\A") == RTLIL::SigSpec(0, 1) && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); - replace_cell(module, cell, "mux_bool", "\\Y", cell->connections_["\\S"]); + replace_cell(module, cell, "mux_bool", "\\Y", cell->get("\\S")); goto next_cell; } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->connections_["\\A"] == RTLIL::SigSpec(1, 1) && cell->connections_["\\B"] == RTLIL::SigSpec(0, 1)) { + cell->get("\\A") == RTLIL::SigSpec(1, 1) && cell->get("\\B") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type); - cell->connections_["\\A"] = cell->connections_["\\S"]; - cell->connections_.erase("\\B"); - cell->connections_.erase("\\S"); + cell->set("\\A", cell->get("\\S")); + cell->connections().erase("\\B"); + cell->connections().erase("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\Y_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -628,10 +628,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections_["\\A"] == RTLIL::SigSpec(0, 1)) { + if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->get("\\A") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type); - cell->connections_["\\A"] = cell->connections_["\\S"]; - cell->connections_.erase("\\S"); + cell->set("\\A", cell->get("\\S")); + cell->connections().erase("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -647,10 +647,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->connections_["\\B"] == RTLIL::SigSpec(1, 1)) { + if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type); - cell->connections_["\\B"] = cell->connections_["\\S"]; - cell->connections_.erase("\\S"); + cell->set("\\B", cell->get("\\S")); + cell->connections().erase("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -668,22 +668,22 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->connections_.at("\\A").size(); - if ((cell->connections_.at("\\A").is_fully_undef() && cell->connections_.at("\\B").is_fully_undef()) || - cell->connections_.at("\\S").is_fully_undef()) { + int width = cell->get("\\A").size(); + if ((cell->get("\\A").is_fully_undef() && cell->get("\\B").is_fully_undef()) || + cell->get("\\S").is_fully_undef()) { cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); - replace_cell(module, cell, "mux_undef", "\\Y", cell->connections_.at("\\A")); + replace_cell(module, cell, "mux_undef", "\\Y", cell->get("\\A")); goto next_cell; } - for (int i = 0; i < cell->connections_.at("\\S").size(); i++) { - RTLIL::SigSpec old_b = cell->connections_.at("\\B").extract(i*width, width); - RTLIL::SigSpec old_s = cell->connections_.at("\\S").extract(i, 1); + for (int i = 0; i < cell->get("\\S").size(); i++) { + RTLIL::SigSpec old_b = cell->get("\\B").extract(i*width, width); + RTLIL::SigSpec old_s = cell->get("\\S").extract(i, 1); if (old_b.is_fully_undef() || old_s.is_fully_undef()) continue; new_b.append(old_b); new_s.append(old_s); } - new_a = cell->connections_.at("\\A"); + new_a = cell->get("\\A"); if (new_a.is_fully_undef() && new_s.size() > 0) { new_a = new_b.extract((new_s.size()-1)*width, width); new_b = new_b.extract(0, (new_s.size()-1)*width); @@ -699,11 +699,11 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo replace_cell(module, cell, "mux_sel01", "\\Y", new_s); goto next_cell; } - if (cell->connections_.at("\\S").size() != new_s.size()) { + if (cell->get("\\S").size() != new_s.size()) { cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type); - cell->connections_.at("\\A") = new_a; - cell->connections_.at("\\B") = new_b; - cell->connections_.at("\\S") = new_s; + cell->get("\\A") = new_a; + cell->get("\\B") = new_b; + cell->get("\\S") = new_s; if (new_s.size() > 1) { cell->type = "$pmux"; cell->parameters["\\S_WIDTH"] = new_s.size(); @@ -718,7 +718,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo #define FOLD_1ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->connections_["\\A"]; \ + RTLIL::SigSpec a = cell->get("\\A"); \ assign_map.apply(a); \ if (a.is_fully_const()) { \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ @@ -732,8 +732,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } #define FOLD_2ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->connections_["\\A"]; \ - RTLIL::SigSpec b = cell->connections_["\\B"]; \ + RTLIL::SigSpec a = cell->get("\\A"); \ + RTLIL::SigSpec b = cell->get("\\B"); \ assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \ @@ -787,13 +787,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo // be very conservative with optimizing $mux cells as we do not want to break mux trees if (cell->type == "$mux") { - RTLIL::SigSpec input = assign_map(cell->connections_["\\S"]); - RTLIL::SigSpec inA = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec inB = assign_map(cell->connections_["\\B"]); + RTLIL::SigSpec input = assign_map(cell->get("\\S")); + RTLIL::SigSpec inA = assign_map(cell->get("\\A")); + RTLIL::SigSpec inB = assign_map(cell->get("\\B")); if (input.is_fully_const()) - ACTION_DO("\\Y", input.as_bool() ? cell->connections_["\\B"] : cell->connections_["\\A"]); + ACTION_DO("\\Y", input.as_bool() ? cell->get("\\B") : cell->get("\\A")); else if (inA == inB) - ACTION_DO("\\Y", cell->connections_["\\A"]); + ACTION_DO("\\Y", cell->get("\\A")); } if (!keepdc && cell->type == "$mul") @@ -802,9 +802,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo bool b_signed = cell->parameters["\\B_SIGNED"].as_bool(); bool swapped_ab = false; - RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); - RTLIL::SigSpec sig_y = assign_map(cell->connections_["\\Y"]); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); + RTLIL::SigSpec sig_y = assign_map(cell->get("\\Y")); if (sig_b.is_fully_const() && sig_b.size() <= 32) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; @@ -820,7 +820,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo log("Replacing multiply-by-zero cell `%s' in module `%s' with zero-driver.\n", cell->name.c_str(), module->name.c_str()); - module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); module->remove(cell); OPT_DID_SOMETHING = true; @@ -840,7 +840,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo a_val, cell->name.c_str(), module->name.c_str(), i); if (!swapped_ab) { - cell->connections_["\\A"] = cell->connections_["\\B"]; + cell->set("\\A", cell->get("\\B")); cell->parameters["\\A_WIDTH"] = cell->parameters["\\B_WIDTH"]; cell->parameters["\\A_SIGNED"] = cell->parameters["\\B_SIGNED"]; } @@ -853,7 +853,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$shl"; cell->parameters["\\B_WIDTH"] = SIZE(new_b); cell->parameters["\\B_SIGNED"] = false; - cell->connections_["\\B"] = new_b; + cell->set("\\B", new_b); cell->check(); OPT_DID_SOMETHING = true; diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 33e66e07..8487152f 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -88,10 +88,10 @@ struct OptMuxtreeWorker RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") { - RTLIL::SigSpec sig_a = cell->connections_["\\A"]; - RTLIL::SigSpec sig_b = cell->connections_["\\B"]; - RTLIL::SigSpec sig_s = cell->connections_["\\S"]; - RTLIL::SigSpec sig_y = cell->connections_["\\Y"]; + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_b = cell->get("\\B"); + RTLIL::SigSpec sig_s = cell->get("\\S"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); muxinfo_t muxinfo; muxinfo.cell = cell; @@ -130,7 +130,7 @@ struct OptMuxtreeWorker } else { - for (auto &it : cell->connections_) { + for (auto &it : cell->connections()) { for (int idx : sig2bits(it.second)) bit2info[idx].seen_non_mux = true; } @@ -194,10 +194,10 @@ struct OptMuxtreeWorker continue; } - RTLIL::SigSpec sig_a = mi.cell->connections_["\\A"]; - RTLIL::SigSpec sig_b = mi.cell->connections_["\\B"]; - RTLIL::SigSpec sig_s = mi.cell->connections_["\\S"]; - RTLIL::SigSpec sig_y = mi.cell->connections_["\\Y"]; + RTLIL::SigSpec sig_a = mi.cell->get("\\A"); + RTLIL::SigSpec sig_b = mi.cell->get("\\B"); + RTLIL::SigSpec sig_s = mi.cell->get("\\S"); + RTLIL::SigSpec sig_y = mi.cell->get("\\Y"); RTLIL::SigSpec sig_ports = sig_b; sig_ports.append(sig_a); @@ -205,7 +205,7 @@ struct OptMuxtreeWorker if (live_ports.size() == 1) { RTLIL::SigSpec sig_in = sig_ports.extract(live_ports[0]*sig_a.size(), sig_a.size()); - module->connections_.push_back(RTLIL::SigSig(sig_y, sig_in)); + module->connect(RTLIL::SigSig(sig_y, sig_in)); module->remove(mi.cell); } else @@ -222,9 +222,9 @@ struct OptMuxtreeWorker } } - mi.cell->connections_["\\A"] = new_sig_a; - mi.cell->connections_["\\B"] = new_sig_b; - mi.cell->connections_["\\S"] = new_sig_s; + mi.cell->set("\\A", new_sig_a); + mi.cell->set("\\B", new_sig_b); + mi.cell->set("\\S", new_sig_s); if (new_sig_s.size() == 1) { mi.cell->type = "$mux"; mi.cell->parameters.erase("\\S_WIDTH"); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 7a7f02f6..8c281b34 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -43,7 +43,7 @@ struct OptReduceWorker return; cells.erase(cell); - RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); std::set new_sig_a_bits; for (auto &bit : sig_a.to_sigbit_set()) @@ -73,8 +73,8 @@ struct OptReduceWorker for (auto child_cell : drivers.find(bit)) { if (child_cell->type == cell->type) { opt_reduce(cells, drivers, child_cell); - if (child_cell->connections_["\\Y"][0] == bit) { - std::set child_sig_a_bits = assign_map(child_cell->connections_["\\A"]).to_sigbit_set(); + if (child_cell->get("\\Y")[0] == bit) { + std::set child_sig_a_bits = assign_map(child_cell->get("\\A")).to_sigbit_set(); new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); } else new_sig_a_bits.insert(RTLIL::State::S0); @@ -87,23 +87,23 @@ struct OptReduceWorker RTLIL::SigSpec new_sig_a(new_sig_a_bits); - if (new_sig_a != sig_a || sig_a.size() != cell->connections_["\\A"].size()) { + if (new_sig_a != sig_a || sig_a.size() != cell->get("\\A").size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; OPT_DID_SOMETHING = true; total_count++; } - cell->connections_["\\A"] = new_sig_a; + cell->set("\\A", new_sig_a); cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.size()); return; } void opt_mux(RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = assign_map(cell->connections_["\\A"]); - RTLIL::SigSpec sig_b = assign_map(cell->connections_["\\B"]); - RTLIL::SigSpec sig_s = assign_map(cell->connections_["\\S"]); + RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); + RTLIL::SigSpec sig_s = assign_map(cell->get("\\S")); RTLIL::SigSpec new_sig_b, new_sig_s; std::set handled_sig; @@ -125,14 +125,14 @@ struct OptReduceWorker if (this_s.size() > 1) { RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, "$reduce_or"); - reduce_or_cell->connections_["\\A"] = this_s; + reduce_or_cell->set("\\A", this_s); reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size()); reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); this_s = RTLIL::SigSpec(reduce_or_wire); - reduce_or_cell->connections_["\\Y"] = this_s; + reduce_or_cell->set("\\Y", this_s); } new_sig_b.append(this_b); @@ -149,14 +149,14 @@ struct OptReduceWorker if (new_sig_s.size() == 0) { - module->connections_.push_back(RTLIL::SigSig(cell->connections_["\\Y"], cell->connections_["\\A"])); - assign_map.add(cell->connections_["\\Y"], cell->connections_["\\A"]); + module->connect(RTLIL::SigSig(cell->get("\\Y"), cell->get("\\A"))); + assign_map.add(cell->get("\\Y"), cell->get("\\A")); module->remove(cell); } else { - cell->connections_["\\B"] = new_sig_b; - cell->connections_["\\S"] = new_sig_s; + cell->set("\\B", new_sig_b); + cell->set("\\S", new_sig_s); if (new_sig_s.size() > 1) { cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); } else { @@ -168,9 +168,9 @@ struct OptReduceWorker void opt_mux_bits(RTLIL::Cell *cell) { - std::vector sig_a = assign_map(cell->connections_["\\A"]).to_sigbit_vector(); - std::vector sig_b = assign_map(cell->connections_["\\B"]).to_sigbit_vector(); - std::vector sig_y = assign_map(cell->connections_["\\Y"]).to_sigbit_vector(); + std::vector sig_a = assign_map(cell->get("\\A")).to_sigbit_vector(); + std::vector sig_b = assign_map(cell->get("\\B")).to_sigbit_vector(); + std::vector sig_y = assign_map(cell->get("\\Y")).to_sigbit_vector(); std::vector new_sig_y; RTLIL::SigSig old_sig_conn; @@ -211,26 +211,26 @@ struct OptReduceWorker if (new_sig_y.size() != sig_y.size()) { log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); - log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections_["\\A"]), - log_signal(cell->connections_["\\B"]), log_signal(cell->connections_["\\Y"])); + log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->get("\\A")), + log_signal(cell->get("\\B")), log_signal(cell->get("\\Y"))); - cell->connections_["\\A"] = RTLIL::SigSpec(); + cell->set("\\A", RTLIL::SigSpec()); for (auto &in_tuple : consolidated_in_tuples) - cell->connections_["\\A"].append(in_tuple.at(0)); + cell->get("\\A").append(in_tuple.at(0)); - cell->connections_["\\B"] = RTLIL::SigSpec(); - for (int i = 1; i <= cell->connections_["\\S"].size(); i++) + cell->set("\\B", RTLIL::SigSpec()); + for (int i = 1; i <= cell->get("\\S").size(); i++) for (auto &in_tuple : consolidated_in_tuples) - cell->connections_["\\B"].append(in_tuple.at(i)); + cell->get("\\B").append(in_tuple.at(i)); cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); - cell->connections_["\\Y"] = new_sig_y; + cell->set("\\Y", new_sig_y); - log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->connections_["\\A"]), - log_signal(cell->connections_["\\B"]), log_signal(cell->connections_["\\Y"])); + log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->get("\\A")), + log_signal(cell->get("\\B")), log_signal(cell->get("\\Y"))); log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); - module->connections_.push_back(old_sig_conn); + module->connect(old_sig_conn); module->check(); did_something = true; @@ -251,14 +251,14 @@ struct OptReduceWorker for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mem") - mem_wren_sigs.add(assign_map(cell->connections_["\\WR_EN"])); + mem_wren_sigs.add(assign_map(cell->get("\\WR_EN"))); if (cell->type == "$memwr") - mem_wren_sigs.add(assign_map(cell->connections_["\\EN"])); + mem_wren_sigs.add(assign_map(cell->get("\\EN"))); } for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->connections_["\\Q"]))) - mem_wren_sigs.add(assign_map(cell->connections_["\\D"])); + if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->get("\\Q")))) + mem_wren_sigs.add(assign_map(cell->get("\\D"))); } bool keep_expanding_mem_wren_sigs = true; @@ -266,12 +266,12 @@ struct OptReduceWorker keep_expanding_mem_wren_sigs = false; for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->connections_["\\Y"]))) { - if (!mem_wren_sigs.check_all(assign_map(cell->connections_["\\A"])) || - !mem_wren_sigs.check_all(assign_map(cell->connections_["\\B"]))) + if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->get("\\Y")))) { + if (!mem_wren_sigs.check_all(assign_map(cell->get("\\A"))) || + !mem_wren_sigs.check_all(assign_map(cell->get("\\B")))) keep_expanding_mem_wren_sigs = true; - mem_wren_sigs.add(assign_map(cell->connections_["\\A"])); - mem_wren_sigs.add(assign_map(cell->connections_["\\B"])); + mem_wren_sigs.add(assign_map(cell->get("\\A"))); + mem_wren_sigs.add(assign_map(cell->get("\\B"))); } } } @@ -293,7 +293,7 @@ struct OptReduceWorker RTLIL::Cell *cell = cell_it.second; if (cell->type != type || !design->selected(module, cell)) continue; - drivers.insert(assign_map(cell->connections_["\\Y"]), cell); + drivers.insert(assign_map(cell->get("\\Y")), cell); cells.insert(cell); } @@ -315,7 +315,7 @@ struct OptReduceWorker { // this optimization is to aggressive for most coarse-grain applications. // but we always want it for multiplexers driving write enable ports. - if (do_fine || mem_wren_sigs.check_any(assign_map(cell->connections_.at("\\Y")))) + if (do_fine || mem_wren_sigs.check_any(assign_map(cell->get("\\Y")))) opt_mux_bits(cell); opt_mux(cell); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 4ece182f..8c09f541 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -33,34 +33,34 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) RTLIL::Const val_cp, val_rp, val_rv; if (dff->type == "$_DFF_N_" || dff->type == "$_DFF_P_") { - sig_d = dff->connections_["\\D"]; - sig_q = dff->connections_["\\Q"]; - sig_c = dff->connections_["\\C"]; + sig_d = dff->get("\\D"); + sig_q = dff->get("\\Q"); + sig_c = dff->get("\\C"); val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1); } else if (dff->type.substr(0,6) == "$_DFF_" && dff->type.substr(9) == "_" && (dff->type[6] == 'N' || dff->type[6] == 'P') && (dff->type[7] == 'N' || dff->type[7] == 'P') && (dff->type[8] == '0' || dff->type[8] == '1')) { - sig_d = dff->connections_["\\D"]; - sig_q = dff->connections_["\\Q"]; - sig_c = dff->connections_["\\C"]; - sig_r = dff->connections_["\\R"]; + sig_d = dff->get("\\D"); + sig_q = dff->get("\\Q"); + sig_c = dff->get("\\C"); + sig_r = dff->get("\\R"); val_cp = RTLIL::Const(dff->type[6] == 'P', 1); val_rp = RTLIL::Const(dff->type[7] == 'P', 1); val_rv = RTLIL::Const(dff->type[8] == '1', 1); } else if (dff->type == "$dff") { - sig_d = dff->connections_["\\D"]; - sig_q = dff->connections_["\\Q"]; - sig_c = dff->connections_["\\CLK"]; + sig_d = dff->get("\\D"); + sig_q = dff->get("\\Q"); + sig_c = dff->get("\\CLK"); val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); } else if (dff->type == "$adff") { - sig_d = dff->connections_["\\D"]; - sig_q = dff->connections_["\\Q"]; - sig_c = dff->connections_["\\CLK"]; - sig_r = dff->connections_["\\ARST"]; + sig_d = dff->get("\\D"); + sig_q = dff->get("\\Q"); + sig_c = dff->get("\\CLK"); + sig_r = dff->get("\\ARST"); val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); val_rp = RTLIL::Const(dff->parameters["\\ARST_POLARITY"].as_bool(), 1); val_rv = dff->parameters["\\ARST_VALUE"]; @@ -85,16 +85,16 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) std::set muxes; mux_drivers.find(sig_d, muxes); for (auto mux : muxes) { - RTLIL::SigSpec sig_a = assign_map(mux->connections_.at("\\A")); - RTLIL::SigSpec sig_b = assign_map(mux->connections_.at("\\B")); + RTLIL::SigSpec sig_a = assign_map(mux->get("\\A")); + RTLIL::SigSpec sig_b = assign_map(mux->get("\\B")); if (sig_a == sig_q && sig_b.is_fully_const()) { RTLIL::SigSig conn(sig_q, sig_b); - mod->connections_.push_back(conn); + mod->connect(conn); goto delete_dff; } if (sig_b == sig_q && sig_a.is_fully_const()) { RTLIL::SigSig conn(sig_q, sig_a); - mod->connections_.push_back(conn); + mod->connect(conn); goto delete_dff; } } @@ -104,36 +104,36 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) if (val_rv.bits.size() == 0) val_rv = val_init; RTLIL::SigSig conn(sig_q, val_rv); - mod->connections_.push_back(conn); + mod->connect(conn); goto delete_dff; } if (sig_d.is_fully_undef() && sig_r.size() && !has_init) { RTLIL::SigSig conn(sig_q, val_rv); - mod->connections_.push_back(conn); + mod->connect(conn); goto delete_dff; } if (sig_d.is_fully_undef() && !sig_r.size() && has_init) { RTLIL::SigSig conn(sig_q, val_init); - mod->connections_.push_back(conn); + mod->connect(conn); goto delete_dff; } if (sig_d.is_fully_const() && !sig_r.size() && !has_init) { RTLIL::SigSig conn(sig_q, sig_d); - mod->connections_.push_back(conn); + mod->connect(conn); goto delete_dff; } if (sig_d == sig_q && !(sig_r.size() && has_init)) { if (sig_r.size()) { RTLIL::SigSig conn(sig_q, val_rv); - mod->connections_.push_back(conn); + mod->connect(conn); } if (has_init) { RTLIL::SigSig conn(sig_q, val_init); - mod->connections_.push_back(conn); + mod->connect(conn); } goto delete_dff; } @@ -181,8 +181,8 @@ struct OptRmdffPass : public Pass { std::vector dff_list; for (auto &it : mod_it.second->cells) { if (it.second->type == "$mux" || it.second->type == "$pmux") { - if (it.second->connections_.at("\\A").size() == it.second->connections_.at("\\B").size()) - mux_drivers.insert(assign_map(it.second->connections_.at("\\Y")), it.second); + if (it.second->get("\\A").size() == it.second->get("\\B").size()) + mux_drivers.insert(assign_map(it.second->get("\\Y")), it.second); continue; } if (!design->selected(mod_it.second, it.second)) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index b3a37209..8412f929 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -66,7 +66,7 @@ struct OptShareWorker for (auto &it : cell->parameters) hash_string += "P " + it.first + "=" + it.second.as_string() + "\n"; - const std::map *conn = &cell->connections_; + const std::map *conn = &cell->connections(); std::map alt_conn; if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$mul" || @@ -135,8 +135,8 @@ struct OptShareWorker return true; } - std::map conn1 = cell1->connections_; - std::map conn2 = cell2->connections_; + std::map conn1 = cell1->connections(); + std::map conn2 = cell2->connections(); for (auto &it : conn1) { if (ct.cell_output(cell1->type, it.first)) @@ -180,8 +180,8 @@ struct OptShareWorker } if (cell1->type.substr(0, 1) == "$" && conn1.count("\\Q") != 0) { - std::vector q1 = dff_init_map(cell1->connections_.at("\\Q")).to_sigbit_vector(); - std::vector q2 = dff_init_map(cell2->connections_.at("\\Q")).to_sigbit_vector(); + std::vector q1 = dff_init_map(cell1->get("\\Q")).to_sigbit_vector(); + std::vector q2 = dff_init_map(cell2->get("\\Q")).to_sigbit_vector(); for (size_t i = 0; i < q1.size(); i++) if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { lt = q1.at(i) < q2.at(i); @@ -261,12 +261,12 @@ struct OptShareWorker if (sharemap.count(cell) > 0) { did_something = true; log(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str()); - for (auto &it : cell->connections_) { + for (auto &it : cell->connections()) { if (ct.cell_output(cell->type, it.first)) { - RTLIL::SigSpec other_sig = sharemap[cell]->connections_[it.first]; + RTLIL::SigSpec other_sig = sharemap[cell]->connections()[it.first]; log(" Redirecting output %s: %s = %s\n", it.first.c_str(), log_signal(it.second), log_signal(other_sig)); - module->connections_.push_back(RTLIL::SigSig(it.second, other_sig)); + module->connect(RTLIL::SigSig(it.second, other_sig)); assign_map.add(it.second, other_sig); } } diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index ce313360..114f2567 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -35,40 +35,40 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp for (auto &cell_it : mod->cells) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$reduce_or" && cell->connections_["\\Y"] == signal) - return check_signal(mod, cell->connections_["\\A"], ref, polarity); - if (cell->type == "$reduce_bool" && cell->connections_["\\Y"] == signal) - return check_signal(mod, cell->connections_["\\A"], ref, polarity); - if (cell->type == "$logic_not" && cell->connections_["\\Y"] == signal) { + if (cell->type == "$reduce_or" && cell->get("\\Y") == signal) + return check_signal(mod, cell->get("\\A"), ref, polarity); + if (cell->type == "$reduce_bool" && cell->get("\\Y") == signal) + return check_signal(mod, cell->get("\\A"), ref, polarity); + if (cell->type == "$logic_not" && cell->get("\\Y") == signal) { polarity = !polarity; - return check_signal(mod, cell->connections_["\\A"], ref, polarity); + return check_signal(mod, cell->get("\\A"), ref, polarity); } - if (cell->type == "$not" && cell->connections_["\\Y"] == signal) { + if (cell->type == "$not" && cell->get("\\Y") == signal) { polarity = !polarity; - return check_signal(mod, cell->connections_["\\A"], ref, polarity); + return check_signal(mod, cell->get("\\A"), ref, polarity); } - if ((cell->type == "$eq" || cell->type == "$eqx") && cell->connections_["\\Y"] == signal) { - if (cell->connections_["\\A"].is_fully_const()) { - if (!cell->connections_["\\A"].as_bool()) + if ((cell->type == "$eq" || cell->type == "$eqx") && cell->get("\\Y") == signal) { + if (cell->get("\\A").is_fully_const()) { + if (!cell->get("\\A").as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections_["\\B"], ref, polarity); + return check_signal(mod, cell->get("\\B"), ref, polarity); } - if (cell->connections_["\\B"].is_fully_const()) { - if (!cell->connections_["\\B"].as_bool()) + if (cell->get("\\B").is_fully_const()) { + if (!cell->get("\\B").as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections_["\\A"], ref, polarity); + return check_signal(mod, cell->get("\\A"), ref, polarity); } } - if ((cell->type == "$ne" || cell->type == "$nex") && cell->connections_["\\Y"] == signal) { - if (cell->connections_["\\A"].is_fully_const()) { - if (cell->connections_["\\A"].as_bool()) + if ((cell->type == "$ne" || cell->type == "$nex") && cell->get("\\Y") == signal) { + if (cell->get("\\A").is_fully_const()) { + if (cell->get("\\A").as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections_["\\B"], ref, polarity); + return check_signal(mod, cell->get("\\B"), ref, polarity); } - if (cell->connections_["\\B"].is_fully_const()) { - if (cell->connections_["\\B"].as_bool()) + if (cell->get("\\B").is_fully_const()) { + if (cell->get("\\B").as_bool()) polarity = !polarity; - return check_signal(mod, cell->connections_["\\A"], ref, polarity); + return check_signal(mod, cell->get("\\A"), ref, polarity); } } } diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 9d2c897e..2e2d4701 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -77,8 +77,8 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections_["\\A"] = sync_low_signals; - cell->connections_["\\Y"] = sync_low_signals = mod->addWire(NEW_ID); + cell->set("\\A", sync_low_signals); + cell->set("\\Y", sync_low_signals = mod->addWire(NEW_ID)); } if (sync_low_signals.size() > 0) { @@ -86,9 +86,9 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections_["\\A"] = sync_low_signals; - cell->connections_["\\Y"] = mod->addWire(NEW_ID); - sync_high_signals.append(cell->connections_["\\Y"]); + cell->set("\\A", sync_low_signals); + cell->set("\\Y", mod->addWire(NEW_ID)); + sync_high_signals.append(cell->get("\\Y")); } if (sync_high_signals.size() > 1) { @@ -96,30 +96,30 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections_["\\A"] = sync_high_signals; - cell->connections_["\\Y"] = sync_high_signals = mod->addWire(NEW_ID); + cell->set("\\A", sync_high_signals); + cell->set("\\Y", sync_high_signals = mod->addWire(NEW_ID)); } RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, "$not"); inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size()); inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size()); - inv_cell->connections_["\\A"] = sync_value; - inv_cell->connections_["\\Y"] = sync_value_inv = mod->addWire(NEW_ID, sig_d.size()); + inv_cell->set("\\A", sync_value); + inv_cell->set("\\Y", sync_value_inv = mod->addWire(NEW_ID, sig_d.size())); RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, "$mux"); mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); - mux_set_cell->connections_["\\A"] = sig_sr_set; - mux_set_cell->connections_["\\B"] = sync_value; - mux_set_cell->connections_["\\S"] = sync_high_signals; - mux_set_cell->connections_["\\Y"] = sig_sr_set = mod->addWire(NEW_ID, sig_d.size()); + mux_set_cell->set("\\A", sig_sr_set); + mux_set_cell->set("\\B", sync_value); + mux_set_cell->set("\\S", sync_high_signals); + mux_set_cell->set("\\Y", sig_sr_set = mod->addWire(NEW_ID, sig_d.size())); RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, "$mux"); mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); - mux_clr_cell->connections_["\\A"] = sig_sr_clr; - mux_clr_cell->connections_["\\B"] = sync_value_inv; - mux_clr_cell->connections_["\\S"] = sync_high_signals; - mux_clr_cell->connections_["\\Y"] = sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()); + mux_clr_cell->set("\\A", sig_sr_clr); + mux_clr_cell->set("\\B", sync_value_inv); + mux_clr_cell->set("\\S", sync_high_signals); + mux_clr_cell->set("\\Y", sig_sr_clr = mod->addWire(NEW_ID, sig_d.size())); } std::stringstream sstr; @@ -131,11 +131,11 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); - cell->connections_["\\D"] = sig_d; - cell->connections_["\\Q"] = sig_q; - cell->connections_["\\CLK"] = clk; - cell->connections_["\\SET"] = sig_sr_set; - cell->connections_["\\CLR"] = sig_sr_clr; + cell->set("\\D", sig_d); + cell->set("\\Q", sig_q); + cell->set("\\CLK", clk); + cell->set("\\SET", sig_sr_set); + cell->set("\\CLR", sig_sr_clr); log(" created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); @@ -155,22 +155,22 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size()); inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size()); - inv_set->connections_["\\A"] = sig_set; - inv_set->connections_["\\Y"] = sig_set_inv; + inv_set->set("\\A", sig_set); + inv_set->set("\\Y", sig_set_inv); RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux"); mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_set->connections_[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); - mux_sr_set->connections_[set_polarity ? "\\B" : "\\A"] = sig_set; - mux_sr_set->connections_["\\Y"] = sig_sr_set; - mux_sr_set->connections_["\\S"] = set; + mux_sr_set->connections()[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); + mux_sr_set->connections()[set_polarity ? "\\B" : "\\A"] = sig_set; + mux_sr_set->set("\\Y", sig_sr_set); + mux_sr_set->set("\\S", set); RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux"); mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_clr->connections_[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); - mux_sr_clr->connections_[set_polarity ? "\\B" : "\\A"] = sig_set_inv; - mux_sr_clr->connections_["\\Y"] = sig_sr_clr; - mux_sr_clr->connections_["\\S"] = set; + mux_sr_clr->connections()[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); + mux_sr_clr->connections()[set_polarity ? "\\B" : "\\A"] = sig_set_inv; + mux_sr_clr->set("\\Y", sig_sr_clr); + mux_sr_clr->set("\\S", set); RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; @@ -178,11 +178,11 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); - cell->connections_["\\D"] = sig_in; - cell->connections_["\\Q"] = sig_out; - cell->connections_["\\CLK"] = clk; - cell->connections_["\\SET"] = sig_sr_set; - cell->connections_["\\CLR"] = sig_sr_clr; + cell->set("\\D", sig_in); + cell->set("\\Q", sig_out); + cell->set("\\CLK", clk); + cell->set("\\SET", sig_sr_set); + cell->set("\\CLR", sig_sr_clr); log(" created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative", set_polarity ? "positive" : "negative"); @@ -204,11 +204,11 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ } cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); - cell->connections_["\\D"] = sig_in; - cell->connections_["\\Q"] = sig_out; + cell->set("\\D", sig_in); + cell->set("\\Q", sig_out); if (arst) - cell->connections_["\\ARST"] = *arst; - cell->connections_["\\CLK"] = clk; + cell->set("\\ARST", *arst); + cell->set("\\CLK", clk); log(" created %s cell `%s' with %s edge clock", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); if (arst) @@ -296,9 +296,9 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->connections_["\\A"] = inputs; - cell->connections_["\\B"] = compare; - cell->connections_["\\Y"] = sync_level->signal; + cell->set("\\A", inputs); + cell->set("\\B", compare); + cell->set("\\Y", sync_level->signal); many_async_rules.clear(); } @@ -322,7 +322,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) if (sync_edge || sync_level || many_async_rules.size() > 0) log_error("Mixed always event with edge and/or level sensitive events!\n"); log(" created direct connection (no actual register cell created).\n"); - mod->connections_.push_back(RTLIL::SigSig(sig, insig)); + mod->connect(RTLIL::SigSig(sig, insig)); continue; } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 2cde749a..2ff755ae 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -81,7 +81,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, if (sig.size() == 1 && comp == RTLIL::SigSpec(1,1)) { - mod->connections_.push_back(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, cmp_wire->width++), sig)); + mod->connect(RTLIL::SigSig(RTLIL::SigSpec(cmp_wire, cmp_wire->width++), sig)); } else { @@ -96,9 +96,9 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - eq_cell->connections_["\\A"] = sig; - eq_cell->connections_["\\B"] = comp; - eq_cell->connections_["\\Y"] = RTLIL::SigSpec(cmp_wire, cmp_wire->width++); + eq_cell->set("\\A", sig); + eq_cell->set("\\B", comp); + eq_cell->set("\\Y", RTLIL::SigSpec(cmp_wire, cmp_wire->width++)); } } @@ -122,8 +122,8 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width); any_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - any_cell->connections_["\\A"] = cmp_wire; - any_cell->connections_["\\Y"] = RTLIL::SigSpec(ctrl_wire); + any_cell->set("\\A", cmp_wire); + any_cell->set("\\Y", RTLIL::SigSpec(ctrl_wire)); } return RTLIL::SigSpec(ctrl_wire); @@ -157,10 +157,10 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, mux_cell->attributes = sw->attributes; mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size()); - mux_cell->connections_["\\A"] = else_signal; - mux_cell->connections_["\\B"] = when_signal; - mux_cell->connections_["\\S"] = ctrl_sig; - mux_cell->connections_["\\Y"] = RTLIL::SigSpec(result_wire); + mux_cell->set("\\A", else_signal); + mux_cell->set("\\B", when_signal); + mux_cell->set("\\S", ctrl_sig); + mux_cell->set("\\Y", RTLIL::SigSpec(result_wire)); last_mux_cell = mux_cell; return RTLIL::SigSpec(result_wire); @@ -169,14 +169,14 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw) { assert(last_mux_cell != NULL); - assert(when_signal.size() == last_mux_cell->connections_["\\A"].size()); + assert(when_signal.size() == last_mux_cell->get("\\A").size()); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); assert(ctrl_sig.size() == 1); last_mux_cell->type = "$pmux"; - last_mux_cell->connections_["\\S"].append(ctrl_sig); - last_mux_cell->connections_["\\B"].append(when_signal); - last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->connections_["\\S"].size(); + last_mux_cell->get("\\S").append(ctrl_sig); + last_mux_cell->get("\\B").append(when_signal); + last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->get("\\S").size(); } static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs, const RTLIL::SigSpec &sig, const RTLIL::SigSpec &defval) @@ -256,7 +256,7 @@ static void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc) log(" creating decoder for signal `%s'.\n", log_signal(sig)); RTLIL::SigSpec value = signal_to_mux_tree(mod, &proc->root_case, sig, RTLIL::SigSpec(RTLIL::State::Sx, sig.size())); - mod->connections_.push_back(RTLIL::SigSig(sig, value)); + mod->connect(RTLIL::SigSig(sig, value)); } } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 22b724d5..58dcf915 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -83,8 +83,8 @@ static void find_dff_wires(std::set &dff_wires, RTLIL::Module *modu SigPool dffsignals; for (auto &it : module->cells) { - if (ct.cell_known(it.second->type) && it.second->connections_.count("\\Q")) - dffsignals.add(sigmap(it.second->connections_.at("\\Q"))); + if (ct.cell_known(it.second->type) && it.second->connections().count("\\Q")) + dffsignals.add(sigmap(it.second->get("\\Q"))); } for (auto &it : module->wires) { @@ -113,10 +113,10 @@ static void create_dff_dq_map(std::map &map, RTLIL: info.cell = it.second; if (info.cell->type == "$dff") { - info.bit_clk = sigmap(info.cell->connections_.at("\\CLK")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->get("\\CLK")).to_single_sigbit(); info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool(); - std::vector sig_d = sigmap(info.cell->connections_.at("\\D")).to_sigbit_vector(); - std::vector sig_q = sigmap(info.cell->connections_.at("\\Q")).to_sigbit_vector(); + std::vector sig_d = sigmap(info.cell->get("\\D")).to_sigbit_vector(); + std::vector sig_q = sigmap(info.cell->get("\\Q")).to_sigbit_vector(); for (size_t i = 0; i < sig_d.size(); i++) { info.bit_d = sig_d.at(i); bit_info[sig_q.at(i)] = info; @@ -125,12 +125,12 @@ static void create_dff_dq_map(std::map &map, RTLIL: } if (info.cell->type == "$adff") { - info.bit_clk = sigmap(info.cell->connections_.at("\\CLK")).to_single_sigbit(); - info.bit_arst = sigmap(info.cell->connections_.at("\\ARST")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->get("\\CLK")).to_single_sigbit(); + info.bit_arst = sigmap(info.cell->get("\\ARST")).to_single_sigbit(); info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool(); info.arst_polarity = info.cell->parameters.at("\\ARST_POLARITY").as_bool(); - std::vector sig_d = sigmap(info.cell->connections_.at("\\D")).to_sigbit_vector(); - std::vector sig_q = sigmap(info.cell->connections_.at("\\Q")).to_sigbit_vector(); + std::vector sig_d = sigmap(info.cell->get("\\D")).to_sigbit_vector(); + std::vector sig_q = sigmap(info.cell->get("\\Q")).to_sigbit_vector(); std::vector arst_value = info.cell->parameters.at("\\ARST_VALUE").bits; for (size_t i = 0; i < sig_d.size(); i++) { info.bit_d = sig_d.at(i); @@ -141,21 +141,21 @@ static void create_dff_dq_map(std::map &map, RTLIL: } if (info.cell->type == "$_DFF_N_" || info.cell->type == "$_DFF_P_") { - info.bit_clk = sigmap(info.cell->connections_.at("\\C")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->get("\\C")).to_single_sigbit(); info.clk_polarity = info.cell->type == "$_DFF_P_"; - info.bit_d = sigmap(info.cell->connections_.at("\\D")).to_single_sigbit(); - bit_info[sigmap(info.cell->connections_.at("\\Q")).to_single_sigbit()] = info; + info.bit_d = sigmap(info.cell->get("\\D")).to_single_sigbit(); + bit_info[sigmap(info.cell->get("\\Q")).to_single_sigbit()] = info; continue; } if (info.cell->type.size() == 10 && info.cell->type.substr(0, 6) == "$_DFF_") { - info.bit_clk = sigmap(info.cell->connections_.at("\\C")).to_single_sigbit(); - info.bit_arst = sigmap(info.cell->connections_.at("\\R")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->get("\\C")).to_single_sigbit(); + info.bit_arst = sigmap(info.cell->get("\\R")).to_single_sigbit(); info.clk_polarity = info.cell->type[6] == 'P'; info.arst_polarity = info.cell->type[7] == 'P'; info.arst_value = info.cell->type[0] == '1' ? RTLIL::State::S1 : RTLIL::State::S0; - info.bit_d = sigmap(info.cell->connections_.at("\\D")).to_single_sigbit(); - bit_info[sigmap(info.cell->connections_.at("\\Q")).to_single_sigbit()] = info; + info.bit_d = sigmap(info.cell->get("\\D")).to_single_sigbit(); + bit_info[sigmap(info.cell->get("\\Q")).to_single_sigbit()] = info; continue; } } @@ -485,12 +485,12 @@ struct ExposePass : public Pass { for (auto &it : module->cells) { if (!ct.cell_known(it.second->type)) continue; - for (auto &conn : it.second->connections_) + for (auto &conn : it.second->connections()) if (ct.cell_input(it.second->type, conn.first)) conn.second = out_to_in_map(sigmap(conn.second)); } - for (auto &conn : module->connections_) + for (auto &conn : module->connections()) conn.second = out_to_in_map(sigmap(conn.second)); } @@ -514,11 +514,11 @@ struct ExposePass : public Pass { for (auto &cell_name : info.cells) { RTLIL::Cell *cell = module->cells.at(cell_name); - std::vector cell_q_bits = sigmap(cell->connections_.at("\\Q")).to_sigbit_vector(); + std::vector cell_q_bits = sigmap(cell->get("\\Q")).to_sigbit_vector(); for (auto &bit : cell_q_bits) if (wire_bits_set.count(bit)) bit = RTLIL::SigBit(wire_dummy_q, wire_dummy_q->width++); - cell->connections_.at("\\Q") = cell_q_bits; + cell->get("\\Q") = cell_q_bits; } RTLIL::Wire *wire_q = new RTLIL::Wire; @@ -536,7 +536,7 @@ struct ExposePass : public Pass { connect_q.second.append(RTLIL::SigBit(wire_q, i)); set_q_bits.insert(wire_bits_vec[i]); } - module->connections_.push_back(connect_q); + module->connect(connect_q); RTLIL::Wire *wire_d = new RTLIL::Wire; wire_d->name = wire->name + sep + "d"; @@ -544,7 +544,7 @@ struct ExposePass : public Pass { wire_d->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_d->name)); add_new_wire(module, wire_d); - module->connections_.push_back(RTLIL::SigSig(wire_d, info.sig_d)); + module->connect(RTLIL::SigSig(wire_d, info.sig_d)); RTLIL::Wire *wire_c = new RTLIL::Wire; wire_c->name = wire->name + sep + "c"; @@ -552,14 +552,14 @@ struct ExposePass : public Pass { log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_c->name)); add_new_wire(module, wire_c); if (info.clk_polarity) { - module->connections_.push_back(RTLIL::SigSig(wire_c, info.sig_clk)); + module->connect(RTLIL::SigSig(wire_c, info.sig_clk)); } else { RTLIL::Cell *c = module->addCell(NEW_ID, "$not"); c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; - c->connections_["\\A"] = info.sig_clk; - c->connections_["\\Y"] = wire_c; + c->set("\\A", info.sig_clk); + c->set("\\Y", wire_c); } if (info.sig_arst != RTLIL::State::Sm) @@ -570,14 +570,14 @@ struct ExposePass : public Pass { log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_r->name)); add_new_wire(module, wire_r); if (info.arst_polarity) { - module->connections_.push_back(RTLIL::SigSig(wire_r, info.sig_arst)); + module->connect(RTLIL::SigSig(wire_r, info.sig_arst)); } else { RTLIL::Cell *c = module->addCell(NEW_ID, "$not"); c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; - c->connections_["\\A"] = info.sig_arst; - c->connections_["\\Y"] = wire_r; + c->set("\\A", info.sig_arst); + c->set("\\Y", wire_r); } RTLIL::Wire *wire_v = new RTLIL::Wire; @@ -586,7 +586,7 @@ struct ExposePass : public Pass { wire_v->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_v->name)); add_new_wire(module, wire_v); - module->connections_.push_back(RTLIL::SigSig(wire_v, info.arst_value)); + module->connect(RTLIL::SigSig(wire_v, info.arst_value)); } } @@ -628,18 +628,18 @@ struct ExposePass : public Pass { log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); RTLIL::SigSpec sig; - if (cell->connections_.count(p->name) != 0) - sig = cell->connections_.at(p->name); + if (cell->connections().count(p->name) != 0) + sig = cell->connections().at(p->name); sig.extend(w->width); if (w->port_input) - module->connections_.push_back(RTLIL::SigSig(sig, w)); + module->connect(RTLIL::SigSig(sig, w)); else - module->connections_.push_back(RTLIL::SigSig(w, sig)); + module->connect(RTLIL::SigSig(w, sig)); } } else { - for (auto &it : cell->connections_) + for (auto &it : cell->connections()) { RTLIL::Wire *w = new RTLIL::Wire; w->name = cell->name + sep + RTLIL::unescape_id(it.first); @@ -653,9 +653,9 @@ struct ExposePass : public Pass { log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); if (w->port_input) - module->connections_.push_back(RTLIL::SigSig(it.second, w)); + module->connect(RTLIL::SigSig(it.second, w)); else - module->connections_.push_back(RTLIL::SigSig(w, it.second)); + module->connect(RTLIL::SigSig(w, it.second)); } } diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 517e6713..da934585 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -610,7 +610,7 @@ struct FreduceWorker for (auto &it : module->cells) { if (ct.cell_known(it.second->type)) { std::set inputs, outputs; - for (auto &port : it.second->connections_) { + for (auto &port : it.second->connections()) { std::vector bits = sigmap(port.second).to_sigbit_vector(); if (ct.cell_output(it.second->type, port.first)) outputs.insert(bits.begin(), bits.end()); @@ -624,7 +624,7 @@ struct FreduceWorker bits_full_total += outputs.size(); } if (inv_mode && it.second->type == "$_INV_") - inv_pairs.insert(std::pair(sigmap(it.second->connections_.at("\\A")), sigmap(it.second->connections_.at("\\Y")))); + inv_pairs.insert(std::pair(sigmap(it.second->get("\\A")), sigmap(it.second->get("\\Y")))); } int bits_count = 0; @@ -708,7 +708,7 @@ struct FreduceWorker RTLIL::Cell *drv = drivers.at(grp[i].bit).first; RTLIL::Wire *dummy_wire = module->addWire(NEW_ID); - for (auto &port : drv->connections_) + for (auto &port : drv->connections()) if (ct.cell_output(drv->type, port.first)) sigmap(port.second).replace(grp[i].bit, dummy_wire, &port.second); @@ -719,14 +719,14 @@ struct FreduceWorker inv_sig = module->addWire(NEW_ID); RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_INV_"); - inv_cell->connections_["\\A"] = grp[0].bit; - inv_cell->connections_["\\Y"] = inv_sig; + inv_cell->set("\\A", grp[0].bit); + inv_cell->set("\\Y", inv_sig); } - module->connections_.push_back(RTLIL::SigSig(grp[i].bit, inv_sig)); + module->connect(RTLIL::SigSig(grp[i].bit, inv_sig)); } else - module->connections_.push_back(RTLIL::SigSig(grp[i].bit, grp[0].bit)); + module->connect(RTLIL::SigSig(grp[i].bit, grp[0].bit)); rewired_sigbits++; } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 9e151cdf..34355122 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -132,8 +132,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w2->width = w1->width; miter_module->add(w2); - gold_cell->connections_[w1->name] = w2; - gate_cell->connections_[w1->name] = w2; + gold_cell->connections()[w1->name] = w2; + gate_cell->connections()[w1->name] = w2; } if (w1->port_output) @@ -150,8 +150,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w2_gate->width = w1->width; miter_module->add(w2_gate); - gold_cell->connections_[w1->name] = w2_gold; - gate_cell->connections_[w1->name] = w2_gate; + gold_cell->connections()[w1->name] = w2_gold; + gate_cell->connections()[w1->name] = w2_gate; RTLIL::SigSpec this_condition; @@ -165,9 +165,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eqx_cell->parameters["\\Y_WIDTH"] = 1; eqx_cell->parameters["\\A_SIGNED"] = 0; eqx_cell->parameters["\\B_SIGNED"] = 0; - eqx_cell->connections_["\\A"] = RTLIL::SigSpec(w2_gold, i); - eqx_cell->connections_["\\B"] = RTLIL::State::Sx; - eqx_cell->connections_["\\Y"] = gold_x.extract(i, 1); + eqx_cell->set("\\A", RTLIL::SigSpec(w2_gold, i)); + eqx_cell->set("\\B", RTLIL::State::Sx); + eqx_cell->set("\\Y", gold_x.extract(i, 1)); } RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width); @@ -179,9 +179,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\A_SIGNED"] = 0; or_gold_cell->parameters["\\B_SIGNED"] = 0; - or_gold_cell->connections_["\\A"] = w2_gold; - or_gold_cell->connections_["\\B"] = gold_x; - or_gold_cell->connections_["\\Y"] = gold_masked; + or_gold_cell->set("\\A", w2_gold); + or_gold_cell->set("\\B", gold_x); + or_gold_cell->set("\\Y", gold_masked); RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or"); or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width; @@ -189,9 +189,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\A_SIGNED"] = 0; or_gate_cell->parameters["\\B_SIGNED"] = 0; - or_gate_cell->connections_["\\A"] = w2_gate; - or_gate_cell->connections_["\\B"] = gold_x; - or_gate_cell->connections_["\\Y"] = gate_masked; + or_gate_cell->set("\\A", w2_gate); + or_gate_cell->set("\\B", gold_x); + or_gate_cell->set("\\Y", gate_masked); RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; @@ -199,10 +199,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->connections_["\\A"] = gold_masked; - eq_cell->connections_["\\B"] = gate_masked; - eq_cell->connections_["\\Y"] = miter_module->addWire(NEW_ID); - this_condition = eq_cell->connections_["\\Y"]; + eq_cell->set("\\A", gold_masked); + eq_cell->set("\\B", gate_masked); + eq_cell->set("\\Y", miter_module->addWire(NEW_ID)); + this_condition = eq_cell->get("\\Y"); } else { @@ -212,10 +212,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->connections_["\\A"] = w2_gold; - eq_cell->connections_["\\B"] = w2_gate; - eq_cell->connections_["\\Y"] = miter_module->addWire(NEW_ID); - this_condition = eq_cell->connections_["\\Y"]; + eq_cell->set("\\A", w2_gold); + eq_cell->set("\\B", w2_gate); + eq_cell->set("\\Y", miter_module->addWire(NEW_ID)); + this_condition = eq_cell->get("\\Y"); } if (flag_make_outcmp) @@ -224,7 +224,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w_cmp->name = "\\cmp_" + RTLIL::unescape_id(w1->name); w_cmp->port_output = true; miter_module->add(w_cmp); - miter_module->connections_.push_back(RTLIL::SigSig(w_cmp, this_condition)); + miter_module->connect(RTLIL::SigSig(w_cmp, this_condition)); } all_conditions.append(this_condition); @@ -236,15 +236,15 @@ static void create_miter_equiv(struct Pass *that, std::vector args, reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size(); reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; - reduce_cell->connections_["\\A"] = all_conditions; - reduce_cell->connections_["\\Y"] = miter_module->addWire(NEW_ID); - all_conditions = reduce_cell->connections_["\\Y"]; + reduce_cell->set("\\A", all_conditions); + reduce_cell->set("\\Y", miter_module->addWire(NEW_ID)); + all_conditions = reduce_cell->get("\\Y"); } if (flag_make_assert) { RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); - assert_cell->connections_["\\A"] = all_conditions; - assert_cell->connections_["\\EN"] = RTLIL::SigSpec(1, 1); + assert_cell->set("\\A", all_conditions); + assert_cell->set("\\EN", RTLIL::SigSpec(1, 1)); } RTLIL::Wire *w_trigger = new RTLIL::Wire; @@ -257,8 +257,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); not_cell->parameters["\\Y_WIDTH"] = w_trigger->width; not_cell->parameters["\\A_SIGNED"] = 0; - not_cell->connections_["\\A"] = all_conditions; - not_cell->connections_["\\Y"] = w_trigger; + not_cell->set("\\A", all_conditions); + not_cell->set("\\Y", w_trigger); miter_module->fixup_ports(); diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index cc041391..71eba2f7 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -321,7 +321,7 @@ struct SatHelper if (design->selected(module, c.second)) { // log("Import cell: %s\n", RTLIL::id2cstr(c.first)); if (satgen.importCell(c.second, timestep)) { - for (auto &p : c.second->connections_) + for (auto &p : c.second->connections()) if (ct.cell_output(c.second->type, p.first)) show_drivers.insert(sigmap(p.second), c.second); import_cell_counter++; @@ -505,7 +505,7 @@ struct SatHelper final_signals.add(sig); } else { for (auto &d : drivers) - for (auto &p : d->connections_) { + for (auto &p : d->connections()) { if (d->type == "$dff" && p.first == "\\CLK") continue; if (d->type.substr(0, 6) == "$_DFF_" && p.first == "\\C") diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 01acf50d..13ef695e 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -77,7 +77,7 @@ struct ShareWorker for (auto &pbit : portbits) { if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { - std::set bits = modwalker.sigmap(pbit.cell->connections_.at("\\S")).to_sigbit_set(); + std::set bits = modwalker.sigmap(pbit.cell->get("\\S")).to_sigbit_set(); terminal_bits.insert(bits.begin(), bits.end()); queue_bits.insert(bits.begin(), bits.end()); visited_cells.insert(pbit.cell); @@ -256,9 +256,9 @@ struct ShareWorker if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->connections_.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->get("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - unsigned_cell->connections_.at("\\A").append_bit(RTLIL::State::S0); + unsigned_cell->get("\\A").append_bit(RTLIL::State::S0); } unsigned_cell->parameters.at("\\A_SIGNED") = true; unsigned_cell->check(); @@ -267,17 +267,17 @@ struct ShareWorker bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); - RTLIL::SigSpec a1 = c1->connections_.at("\\A"); - RTLIL::SigSpec y1 = c1->connections_.at("\\Y"); + RTLIL::SigSpec a1 = c1->get("\\A"); + RTLIL::SigSpec y1 = c1->get("\\Y"); - RTLIL::SigSpec a2 = c2->connections_.at("\\A"); - RTLIL::SigSpec y2 = c2->connections_.at("\\Y"); + RTLIL::SigSpec a2 = c2->get("\\A"); + RTLIL::SigSpec y2 = c2->get("\\Y"); int a_width = std::max(a1.size(), a2.size()); int y_width = std::max(y1.size(), y2.size()); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); @@ -286,14 +286,14 @@ struct ShareWorker supercell->parameters["\\A_SIGNED"] = a_signed; supercell->parameters["\\A_WIDTH"] = a_width; supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->connections_["\\A"] = a; - supercell->connections_["\\Y"] = y; + supercell->set("\\A", a); + supercell->set("\\Y", y); RTLIL::SigSpec new_y1(y, 0, y1.size()); RTLIL::SigSpec new_y2(y, 0, y2.size()); - module->connections_.push_back(RTLIL::SigSig(y1, new_y1)); - module->connections_.push_back(RTLIL::SigSig(y2, new_y2)); + module->connect(RTLIL::SigSig(y1, new_y1)); + module->connect(RTLIL::SigSig(y2, new_y2)); return supercell; } @@ -312,7 +312,7 @@ struct ShareWorker if (score_flipped < score_unflipped) { - std::swap(c2->connections_.at("\\A"), c2->connections_.at("\\B")); + std::swap(c2->get("\\A"), c2->get("\\B")); std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); modified_src_cells = true; @@ -323,9 +323,9 @@ struct ShareWorker { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->connections_.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->get("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - unsigned_cell->connections_.at("\\A").append_bit(RTLIL::State::S0); + unsigned_cell->get("\\A").append_bit(RTLIL::State::S0); } unsigned_cell->parameters.at("\\A_SIGNED") = true; modified_src_cells = true; @@ -334,9 +334,9 @@ struct ShareWorker if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->connections_.at("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->get("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; - unsigned_cell->connections_.at("\\B").append_bit(RTLIL::State::S0); + unsigned_cell->get("\\B").append_bit(RTLIL::State::S0); } unsigned_cell->parameters.at("\\B_SIGNED") = true; modified_src_cells = true; @@ -356,13 +356,13 @@ struct ShareWorker if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") b_signed = false; - RTLIL::SigSpec a1 = c1->connections_.at("\\A"); - RTLIL::SigSpec b1 = c1->connections_.at("\\B"); - RTLIL::SigSpec y1 = c1->connections_.at("\\Y"); + RTLIL::SigSpec a1 = c1->get("\\A"); + RTLIL::SigSpec b1 = c1->get("\\B"); + RTLIL::SigSpec y1 = c1->get("\\Y"); - RTLIL::SigSpec a2 = c2->connections_.at("\\A"); - RTLIL::SigSpec b2 = c2->connections_.at("\\B"); - RTLIL::SigSpec y2 = c2->connections_.at("\\Y"); + RTLIL::SigSpec a2 = c2->get("\\A"); + RTLIL::SigSpec b2 = c2->get("\\B"); + RTLIL::SigSpec y2 = c2->get("\\Y"); int a_width = std::max(a1.size(), a2.size()); int b_width = std::max(b1.size(), b2.size()); @@ -372,20 +372,20 @@ struct ShareWorker { a_width = std::max(y_width, a_width); - if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->connections_.at("\\Y"); - if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->connections_.at("\\Y"); + if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->get("\\Y"); + if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->get("\\Y"); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->connections_.at("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->connections_.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->get("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->get("\\Y"); } else { - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->connections_.at("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); } - if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->connections_.at("\\Y"); - if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->connections_.at("\\Y"); + if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->get("\\Y"); + if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->get("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); @@ -397,16 +397,16 @@ struct ShareWorker supercell->parameters["\\A_WIDTH"] = a_width; supercell->parameters["\\B_WIDTH"] = b_width; supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->connections_["\\A"] = a; - supercell->connections_["\\B"] = b; - supercell->connections_["\\Y"] = y; + supercell->set("\\A", a); + supercell->set("\\B", b); + supercell->set("\\Y", y); supercell->check(); RTLIL::SigSpec new_y1(y, 0, y1.size()); RTLIL::SigSpec new_y2(y, 0, y2.size()); - module->connections_.push_back(RTLIL::SigSig(y1, new_y1)); - module->connections_.push_back(RTLIL::SigSig(y2, new_y2)); + module->connect(RTLIL::SigSig(y1, new_y1)); + module->connect(RTLIL::SigSig(y2, new_y2)); return supercell; } @@ -438,7 +438,7 @@ struct ShareWorker for (auto &bit : pbits) { if ((bit.cell->type == "$mux" || bit.cell->type == "$pmux") && bit.port == "\\S") - forbidden_controls_cache[cell].insert(bit.cell->connections_.at("\\S").extract(bit.offset, 1)); + forbidden_controls_cache[cell].insert(bit.cell->get("\\S").extract(bit.offset, 1)); consumer_cells.insert(bit.cell); } @@ -532,9 +532,9 @@ struct ShareWorker std::set used_in_b_parts; int width = c->parameters.at("\\WIDTH").as_int(); - std::vector sig_a = modwalker.sigmap(c->connections_.at("\\A")); - std::vector sig_b = modwalker.sigmap(c->connections_.at("\\B")); - std::vector sig_s = modwalker.sigmap(c->connections_.at("\\S")); + std::vector sig_a = modwalker.sigmap(c->get("\\A")); + std::vector sig_b = modwalker.sigmap(c->get("\\B")); + std::vector sig_s = modwalker.sigmap(c->get("\\S")); for (auto &bit : sig_a) if (cell_out_bits.count(bit)) @@ -572,7 +572,7 @@ struct ShareWorker if (activation_patterns_cache[cell].empty()) { log("%sFound cell that is never activated: %s\n", indent, log_id(cell)); RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; - module->connections_.push_back(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); + module->connect(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); cells_to_remove.insert(cell); } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index ac0064f7..1dce39f6 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -398,7 +398,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) { auto cell_type = cell->type; auto cell_name = cell->name; - auto cell_connections = cell->connections_; + auto cell_connections = cell->connections(); module->remove(cell); cell_mapping &cm = cell_mappings[cell_type]; @@ -418,7 +418,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } else if (port.second != 0) log_abort(); - new_cell->connections_["\\" + port.first] = sig; + new_cell->connections()["\\" + port.first] = sig; } stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type.c_str(), new_cell->type.c_str())]++; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 5dfcd63d..0d8f6ab0 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -125,10 +125,10 @@ namespace RTLIL::Wire *lastHaystackWire = NULL; std::map emptyAttr; - for (auto &conn : needleCell->connections_) + for (auto &conn : needleCell->connections()) { RTLIL::SigSpec needleSig = conn.second; - RTLIL::SigSpec haystackSig = haystackCell->connections_.at(portMapping.at(conn.first)); + RTLIL::SigSpec haystackSig = haystackCell->connections().at(portMapping.at(conn.first)); for (int i = 0; i < std::min(needleSig.size(), haystackSig.size()); i++) { RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire; @@ -186,7 +186,7 @@ namespace { RTLIL::Cell *cell = cell_it.second; if (!sel || sel->selected(mod, cell)) - for (auto &conn : cell->connections_) { + for (auto &conn : cell->connections()) { RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); for (auto &bit : conn_sig) @@ -207,7 +207,7 @@ namespace type = type.substr(1); graph.createNode(cell->name, type, (void*)cell); - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) { graph.createPort(cell->name, conn.first, conn.second.size()); @@ -257,7 +257,7 @@ namespace { RTLIL::Cell *cell = cell_it.second; if (sel && !sel->selected(mod, cell)) - for (auto &conn : cell->connections_) + for (auto &conn : cell->connections()) { RTLIL::SigSpec conn_sig = conn.second; sigmap.apply(conn_sig); @@ -305,7 +305,7 @@ namespace if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair(wire->name, i)); - cell->connections_[wire->name] = RTLIL::SigSpec(RTLIL::State::Sz, wire->width); + cell->connections()[wire->name] = RTLIL::SigSpec(RTLIL::State::Sz, wire->width); } } @@ -319,13 +319,13 @@ namespace if (needle_cell == NULL) continue; - for (auto &conn : needle_cell->connections_) { + for (auto &conn : needle_cell->connections()) { RTLIL::SigSpec sig = sigmap(conn.second); if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { for (int i = 0; i < sig.size(); i++) for (auto &port : sig2port.find(sig[i])) { - RTLIL::SigSpec bitsig = haystack_cell->connections_.at(mapping.portMapping[conn.first]).extract(i, 1); - cell->connections_.at(port.first).replace(port.second, bitsig); + RTLIL::SigSpec bitsig = haystack_cell->connections().at(mapping.portMapping[conn.first]).extract(i, 1); + cell->connections().at(port.first).replace(port.second, bitsig); } } } @@ -714,7 +714,7 @@ struct ExtractPass : public Pass { cells.insert((RTLIL::Cell*)node.userData); for (auto cell : cells) - for (auto &conn : cell->connections_) { + for (auto &conn : cell->connections()) { RTLIL::SigSpec sig = sigmap(conn.second); for (auto &chunk : sig.chunks()) if (chunk.wire != NULL) @@ -739,12 +739,12 @@ struct ExtractPass : public Pass { for (auto cell : cells) { RTLIL::Cell *newCell = newMod->addCell(cell->name, cell->type); newCell->parameters = cell->parameters; - for (auto &conn : cell->connections_) { + for (auto &conn : cell->connections()) { std::vector chunks = sigmap(conn.second); for (auto &chunk : chunks) if (chunk.wire != NULL) chunk.wire = newMod->wires.at(chunk.wire->name); - newCell->connections_[conn.first] = chunks; + newCell->connections()[conn.first] = chunks; } } } diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index 286ad8ac..2e5dd7dc 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -35,7 +35,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_hi == RTLIL::State::Sm) { last_hi = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype)); - cell->connections_[RTLIL::escape_id(hicell_portname)] = last_hi; + cell->connections()[RTLIL::escape_id(hicell_portname)] = last_hi; } bit = last_hi; } @@ -43,7 +43,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_lo == RTLIL::State::Sm) { last_lo = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype)); - cell->connections_[RTLIL::escape_id(locell_portname)] = last_lo; + cell->connections()[RTLIL::escape_id(locell_portname)] = last_lo; } bit = last_lo; } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index ba9bf51d..199fd602 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -177,9 +177,9 @@ struct IopadmapPass : public Pass { for (int i = 0; i < wire->width; i++) { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->connections_[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, i); + cell->connections()[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, i); if (!portname2.empty()) - cell->connections_[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, i); + cell->connections()[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, i); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) @@ -190,9 +190,9 @@ struct IopadmapPass : public Pass { else { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->connections_[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); + cell->connections()[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); if (!portname2.empty()) - cell->connections_[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); + cell->connections()[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index df7592ce..f8851400 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -29,43 +29,43 @@ extern void simplemap_get_mappers(std::mapconnections_.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections_["\\A"] = sig_a[i]; - gate->connections_["\\Y"] = sig_y[i]; + gate->set("\\A", sig_a[i]); + gate->set("\\Y", sig_y[i]); } } static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); - module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a)); + module->connect(RTLIL::SigSig(sig_y, sig_a)); } static void simplemap_bu0(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); - module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a)); + module->connect(RTLIL::SigSig(sig_y, sig_a)); } static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); - RTLIL::SigSpec sig_b = cell->connections_.at("\\B"); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_b = cell->get("\\B"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); sig_b.extend_u0(SIZE(sig_y), cell->parameters.at("\\B_SIGNED").as_bool()); @@ -76,8 +76,8 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections_["\\A"] = sig_t[i]; - gate->connections_["\\Y"] = sig_y[i]; + gate->set("\\A", sig_t[i]); + gate->set("\\Y", sig_y[i]); } sig_y = sig_t; @@ -92,31 +92,31 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections_["\\A"] = sig_a[i]; - gate->connections_["\\B"] = sig_b[i]; - gate->connections_["\\Y"] = sig_y[i]; + gate->set("\\A", sig_a[i]); + gate->set("\\B", sig_b[i]); + gate->set("\\Y", sig_y[i]); } } static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); if (sig_y.size() == 0) return; if (sig_a.size() == 0) { - if (cell->type == "$reduce_and") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == "$reduce_or") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == "$reduce_xor") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == "$reduce_xnor") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == "$reduce_bool") module->connections_.push_back(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_and") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == "$reduce_or") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_xor") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type == "$reduce_xnor") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type == "$reduce_bool") module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); return; } if (sig_y.size() > 1) { - module->connections_.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); + module->connect(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } @@ -142,10 +142,10 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections_["\\A"] = sig_a[i]; - gate->connections_["\\B"] = sig_a[i+1]; - gate->connections_["\\Y"] = sig_t[i/2]; - last_output = &gate->connections_["\\Y"]; + gate->set("\\A", sig_a[i]); + gate->set("\\B", sig_a[i+1]); + gate->set("\\Y", sig_t[i/2]); + last_output = &gate->get("\\Y"); } sig_a = sig_t; @@ -154,14 +154,14 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$reduce_xnor") { RTLIL::SigSpec sig_t = module->addWire(NEW_ID); RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections_["\\A"] = sig_a; - gate->connections_["\\Y"] = sig_t; - last_output = &gate->connections_["\\Y"]; + gate->set("\\A", sig_a); + gate->set("\\Y", sig_t); + last_output = &gate->get("\\Y"); sig_a = sig_t; } if (last_output == NULL) { - module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a)); + module->connect(RTLIL::SigSig(sig_y, sig_a)); } else { *last_output = sig_y; } @@ -181,9 +181,9 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) } RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_"); - gate->connections_["\\A"] = sig[i]; - gate->connections_["\\B"] = sig[i+1]; - gate->connections_["\\Y"] = sig_t[i/2]; + gate->set("\\A", sig[i]); + gate->set("\\B", sig[i+1]); + gate->set("\\Y", sig_t[i/2]); } sig = sig_t; @@ -195,39 +195,39 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_a = cell->get("\\A"); logic_reduce(module, sig_a); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); if (sig_y.size() == 0) return; if (sig_y.size() > 1) { - module->connections_.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); + module->connect(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->connections_["\\A"] = sig_a; - gate->connections_["\\Y"] = sig_y; + gate->set("\\A", sig_a); + gate->set("\\Y", sig_y); } static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); + RTLIL::SigSpec sig_a = cell->get("\\A"); logic_reduce(module, sig_a); - RTLIL::SigSpec sig_b = cell->connections_.at("\\B"); + RTLIL::SigSpec sig_b = cell->get("\\B"); logic_reduce(module, sig_b); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); if (sig_y.size() == 0) return; if (sig_y.size() > 1) { - module->connections_.push_back(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); + module->connect(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1))); sig_y = sig_y.extract(0, 1); } @@ -237,40 +237,40 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) log_assert(!gate_type.empty()); RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections_["\\A"] = sig_a; - gate->connections_["\\B"] = sig_b; - gate->connections_["\\Y"] = sig_y; + gate->set("\\A", sig_a); + gate->set("\\B", sig_b); + gate->set("\\Y", sig_y); } static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); - RTLIL::SigSpec sig_b = cell->connections_.at("\\B"); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_b = cell->get("\\B"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_"); - gate->connections_["\\A"] = sig_a[i]; - gate->connections_["\\B"] = sig_b[i]; - gate->connections_["\\S"] = cell->connections_.at("\\S"); - gate->connections_["\\Y"] = sig_y[i]; + gate->set("\\A", sig_a[i]); + gate->set("\\B", sig_b[i]); + gate->set("\\S", cell->get("\\S")); + gate->set("\\Y", sig_y[i]); } } static void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) { int offset = cell->parameters.at("\\OFFSET").as_int(); - RTLIL::SigSpec sig_a = cell->connections_.at("\\A"); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); - module->connections_.push_back(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); + RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_y = cell->get("\\Y"); + module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); } static void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_ab = cell->connections_.at("\\A"); - sig_ab.append(cell->connections_.at("\\B")); - RTLIL::SigSpec sig_y = cell->connections_.at("\\Y"); - module->connections_.push_back(RTLIL::SigSig(sig_y, sig_ab)); + RTLIL::SigSpec sig_ab = cell->get("\\A"); + sig_ab.append(cell->get("\\B")); + RTLIL::SigSpec sig_y = cell->get("\\Y"); + module->connect(RTLIL::SigSig(sig_y, sig_ab)); } static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) @@ -279,17 +279,17 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_s = cell->connections_.at("\\SET"); - RTLIL::SigSpec sig_r = cell->connections_.at("\\CLR"); - RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); + RTLIL::SigSpec sig_s = cell->get("\\SET"); + RTLIL::SigSpec sig_r = cell->get("\\CLR"); + RTLIL::SigSpec sig_q = cell->get("\\Q"); std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections_["\\S"] = sig_s[i]; - gate->connections_["\\R"] = sig_r[i]; - gate->connections_["\\Q"] = sig_q[i]; + gate->set("\\S", sig_s[i]); + gate->set("\\R", sig_r[i]); + gate->set("\\Q", sig_q[i]); } } @@ -298,17 +298,17 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) int width = cell->parameters.at("\\WIDTH").as_int(); char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->connections_.at("\\CLK"); - RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); + RTLIL::SigSpec sig_clk = cell->get("\\CLK"); + RTLIL::SigSpec sig_d = cell->get("\\D"); + RTLIL::SigSpec sig_q = cell->get("\\Q"); std::string gate_type = stringf("$_DFF_%c_", clk_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections_["\\C"] = sig_clk; - gate->connections_["\\D"] = sig_d[i]; - gate->connections_["\\Q"] = sig_q[i]; + gate->set("\\C", sig_clk); + gate->set("\\D", sig_d[i]); + gate->set("\\Q", sig_q[i]); } } @@ -319,21 +319,21 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->connections_.at("\\CLK"); - RTLIL::SigSpec sig_s = cell->connections_.at("\\SET"); - RTLIL::SigSpec sig_r = cell->connections_.at("\\CLR"); - RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); + RTLIL::SigSpec sig_clk = cell->get("\\CLK"); + RTLIL::SigSpec sig_s = cell->get("\\SET"); + RTLIL::SigSpec sig_r = cell->get("\\CLR"); + RTLIL::SigSpec sig_d = cell->get("\\D"); + RTLIL::SigSpec sig_q = cell->get("\\Q"); std::string gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections_["\\C"] = sig_clk; - gate->connections_["\\S"] = sig_s[i]; - gate->connections_["\\R"] = sig_r[i]; - gate->connections_["\\D"] = sig_d[i]; - gate->connections_["\\Q"] = sig_q[i]; + gate->set("\\C", sig_clk); + gate->set("\\S", sig_s[i]); + gate->set("\\R", sig_r[i]); + gate->set("\\D", sig_d[i]); + gate->set("\\Q", sig_q[i]); } } @@ -347,20 +347,20 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) while (int(rst_val.size()) < width) rst_val.push_back(RTLIL::State::S0); - RTLIL::SigSpec sig_clk = cell->connections_.at("\\CLK"); - RTLIL::SigSpec sig_rst = cell->connections_.at("\\ARST"); - RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); + RTLIL::SigSpec sig_clk = cell->get("\\CLK"); + RTLIL::SigSpec sig_rst = cell->get("\\ARST"); + RTLIL::SigSpec sig_d = cell->get("\\D"); + RTLIL::SigSpec sig_q = cell->get("\\Q"); std::string gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); std::string gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); - gate->connections_["\\C"] = sig_clk; - gate->connections_["\\R"] = sig_rst; - gate->connections_["\\D"] = sig_d[i]; - gate->connections_["\\Q"] = sig_q[i]; + gate->set("\\C", sig_clk); + gate->set("\\R", sig_rst); + gate->set("\\D", sig_d[i]); + gate->set("\\Q", sig_q[i]); } } @@ -369,17 +369,17 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) int width = cell->parameters.at("\\WIDTH").as_int(); char en_pol = cell->parameters.at("\\EN_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_en = cell->connections_.at("\\EN"); - RTLIL::SigSpec sig_d = cell->connections_.at("\\D"); - RTLIL::SigSpec sig_q = cell->connections_.at("\\Q"); + RTLIL::SigSpec sig_en = cell->get("\\EN"); + RTLIL::SigSpec sig_d = cell->get("\\D"); + RTLIL::SigSpec sig_q = cell->get("\\Q"); std::string gate_type = stringf("$_DLATCH_%c_", en_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->connections_["\\E"] = sig_en; - gate->connections_["\\D"] = sig_d[i]; - gate->connections_["\\Q"] = sig_q[i]; + gate->set("\\E", sig_en); + gate->set("\\D", sig_d[i]); + gate->set("\\Q", sig_q[i]); } } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index ab95c003..4c8f9250 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -141,7 +141,7 @@ struct TechmapWorker SigMap port_signal_map; - for (auto &it : cell->connections_) { + for (auto &it : cell->connections()) { RTLIL::IdString portname = it.first; if (positional_ports.count(portname) > 0) portname = positional_ports.at(portname); @@ -169,7 +169,7 @@ struct TechmapWorker if (flatten_mode) { // more conservative approach: // connect internal and external wires - module->connections_.push_back(c); + module->connect(c); } else { // approach that yields nicer outputs: // replace internal wires that are connected to external wires @@ -195,19 +195,19 @@ struct TechmapWorker if (!flatten_mode && c->type.substr(0, 2) == "\\$") c->type = c->type.substr(1); - for (auto &it2 : c->connections_) { + for (auto &it2 : c->connections()) { apply_prefix(cell->name, it2.second, module); port_signal_map.apply(it2.second); } } - for (auto &it : tpl->connections_) { + for (auto &it : tpl->connections()) { RTLIL::SigSig c = it; apply_prefix(cell->name, c.first, module); apply_prefix(cell->name, c.second, module); port_signal_map.apply(c.first); port_signal_map.apply(c.second); - module->connections_.push_back(c); + module->connect(c); } module->remove(cell); @@ -262,7 +262,7 @@ struct TechmapWorker break; } - for (auto conn : cell->connections_) { + for (auto conn : cell->connections()) { if (conn.first.substr(0, 1) == "$") continue; if (tpl->wires.count(conn.first) > 0 && tpl->wires.at(conn.first)->port_id > 0) @@ -280,7 +280,7 @@ struct TechmapWorker if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0) parameters["\\_TECHMAP_CELLTYPE_"] = RTLIL::unescape_id(cell->type); - for (auto conn : cell->connections_) { + for (auto conn : cell->connections()) { if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) { std::vector v = sigmap(conn.second).to_sigbit_vector(); for (auto &bit : v) @@ -303,7 +303,7 @@ struct TechmapWorker unique_bit_id[RTLIL::State::Sx] = unique_bit_id_counter++; unique_bit_id[RTLIL::State::Sz] = unique_bit_id_counter++; - for (auto conn : cell->connections_) + for (auto conn : cell->connections()) if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) { for (auto &bit : sigmap(conn.second).to_sigbit_vector()) if (unique_bit_id.count(bit) == 0) @@ -317,7 +317,7 @@ struct TechmapWorker if (tpl->avail_parameters.count("\\_TECHMAP_BITS_CONNMAP_")) parameters["\\_TECHMAP_BITS_CONNMAP_"] = bits; - for (auto conn : cell->connections_) + for (auto conn : cell->connections()) if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) { RTLIL::Const value; for (auto &bit : sigmap(conn.second).to_sigbit_vector()) { From f8fdc47d3361c1a3445a9357ca26cfe75907d6b0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 15:57:57 +0200 Subject: [PATCH 436/750] Manual fixes for new cell connections API --- backends/btor/btor.cc | 8 +++---- backends/verilog/verilog_backend.cc | 8 +++---- frontends/ast/genrtlil.cc | 4 ++-- frontends/ilang/parser.y | 2 +- kernel/rtlil.cc | 22 +++++++++--------- passes/abc/abc.cc | 2 +- passes/abc/blifparse.cc | 2 +- passes/cmds/add.cc | 2 +- passes/cmds/connect.cc | 6 ++--- passes/cmds/connwrappers.cc | 2 +- passes/cmds/scatter.cc | 2 +- passes/cmds/show.cc | 6 ++--- passes/cmds/splice.cc | 2 +- passes/fsm/fsm_expand.cc | 8 +++++-- passes/fsm/fsm_extract.cc | 4 ++-- passes/fsm/fsm_opt.cc | 14 +++++++---- passes/hierarchy/hierarchy.cc | 4 ++-- passes/hierarchy/submod.cc | 6 ++--- passes/memory/memory_dff.cc | 11 +++++---- passes/memory/memory_share.cc | 35 +++++++++++++++++----------- passes/opt/opt_clean.cc | 4 ++-- passes/opt/opt_const.cc | 36 +++++++++++++++-------------- passes/opt/opt_reduce.cc | 14 +++++++---- passes/opt/opt_share.cc | 2 +- passes/proc/proc_dff.cc | 8 +++---- passes/proc/proc_mux.cc | 11 +++++++-- passes/sat/expose.cc | 6 ++--- passes/sat/freduce.cc | 2 +- passes/sat/miter.cc | 8 +++---- passes/sat/share.cc | 17 ++++++++++---- passes/techmap/dfflibmap.cc | 2 +- passes/techmap/extract.cc | 8 ++++--- passes/techmap/hilomap.cc | 4 ++-- passes/techmap/iopadmap.cc | 8 +++---- passes/techmap/simplemap.cc | 10 ++++---- passes/techmap/techmap.cc | 2 +- 36 files changed, 169 insertions(+), 123 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 0316f7ab..bbfbc0f9 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -193,7 +193,7 @@ struct BtorDumper break; log(" -- found cell %s\n", cstr(cell_id)); RTLIL::Cell* cell = module->cells.at(cell_id); - RTLIL::SigSpec* cell_output = get_cell_output(cell); + const RTLIL::SigSpec* cell_output = get_cell_output(cell); int cell_line = dump_cell(cell); if(dep_set.size()==1 && wire->width == cell_output->size()) @@ -796,9 +796,9 @@ struct BtorDumper } } - RTLIL::SigSpec* get_cell_output(RTLIL::Cell* cell) + const RTLIL::SigSpec* get_cell_output(RTLIL::Cell* cell) { - RTLIL::SigSpec *output_sig = nullptr; + const RTLIL::SigSpec *output_sig = nullptr; if (cell->type == "$memrd") { output_sig = &cell->connections().at(RTLIL::IdString("\\DATA")); @@ -835,7 +835,7 @@ struct BtorDumper for (auto it = module->cells.begin(); it != module->cells.end(); ++it) { RTLIL::Cell *cell = it->second; - RTLIL::SigSpec* output_sig = get_cell_output(cell); + const RTLIL::SigSpec* output_sig = get_cell_output(cell); if(output_sig==nullptr) continue; RTLIL::SigSpec s = sigmap(*output_sig); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index aa2f88fa..6bef90e3 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -223,7 +223,7 @@ void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool no_decimal = fals } } -void dump_sigspec(FILE *f, RTLIL::SigSpec &sig) +void dump_sigspec(FILE *f, const RTLIL::SigSpec &sig) { if (sig.is_chunk()) { dump_sigchunk(f, sig.as_chunk()); @@ -293,10 +293,10 @@ void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_ { if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) { fprintf(f, "$signed("); - dump_sigspec(f, cell->connections()["\\" + port]); + dump_sigspec(f, cell->get("\\" + port)); fprintf(f, ")"); } else - dump_sigspec(f, cell->connections()["\\" + port]); + dump_sigspec(f, cell->get("\\" + port)); } std::string cellname(RTLIL::Cell *cell) @@ -735,7 +735,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, "\n%s" ");\n", indent.c_str()); } -void dump_conn(FILE *f, std::string indent, RTLIL::SigSpec &left, RTLIL::SigSpec &right) +void dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { fprintf(f, "%s" "assign ", indent.c_str()); dump_sigspec(f, left); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 861df3fd..dba301f4 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 a7ce4bc7..952dd6a3 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); } | diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9781fa32..ceb2b0f5 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -773,7 +773,7 @@ void RTLIL::Module::optimize() void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const { new_mod->name = name; - new_mod->connections() = connections_; + new_mod->connections_ = connections_; new_mod->attributes = attributes; for (auto &it : wires) @@ -924,7 +924,7 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *other) { RTLIL::Cell *cell = addCell(name, other->type); - cell->connections() = other->connections(); + cell->connections_ = other->connections_; cell->parameters = other->parameters; cell->attributes = other->attributes; return cell; @@ -1036,8 +1036,8 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections()["\\" #_P1] = sig1; \ - cell->connections()["\\" #_P2] = sig2; \ + cell->set("\\" #_P1, sig1); \ + cell->set("\\" #_P2, sig2); \ add(cell); \ return cell; \ } \ @@ -1051,9 +1051,9 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections()["\\" #_P1] = sig1; \ - cell->connections()["\\" #_P2] = sig2; \ - cell->connections()["\\" #_P3] = sig3; \ + cell->set("\\" #_P1, sig1); \ + cell->set("\\" #_P2, sig2); \ + cell->set("\\" #_P3, sig3); \ add(cell); \ return cell; \ } \ @@ -1067,10 +1067,10 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) RTLIL::Cell *cell = new RTLIL::Cell; \ cell->name = name; \ cell->type = _type; \ - cell->connections()["\\" #_P1] = sig1; \ - cell->connections()["\\" #_P2] = sig2; \ - cell->connections()["\\" #_P3] = sig3; \ - cell->connections()["\\" #_P4] = sig4; \ + cell->set("\\" #_P1, sig1); \ + cell->set("\\" #_P2, sig2); \ + cell->set("\\" #_P3, sig3); \ + cell->set("\\" #_P4, sig4); \ add(cell); \ return cell; \ } \ diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index c53c4450..4d9a6c13 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -785,7 +785,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std assert(c.width == 1); newsig.append(module->wires[remap_name(c.wire->name)]); } - cell->connections()[conn.first] = newsig; + cell->set(conn.first, newsig); } design->select(module, cell); } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index e5bfb98b..45a9ac76 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -148,7 +148,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) *(q++) = 0; if (module->wires.count(RTLIL::escape_id(q)) == 0) module->addWire(RTLIL::escape_id(q)); - cell->connections()[RTLIL::escape_id(p)] = module->wires.at(RTLIL::escape_id(q)); + cell->set(RTLIL::escape_id(p), module->wires.at(RTLIL::escape_id(q))); } continue; } diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 9004bf75..1401193f 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -78,7 +78,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n if (it.second->connections().count(name) > 0) continue; - it.second->connections()[name] = wire; + it.second->set(name, wire); log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str()); } } diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index ffe7a5ef..99a28d4a 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -30,11 +30,11 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size()); for (auto &it : module->cells) - for (auto &port : it.second->connections()) + for (auto &port : it.second->connections_) if (ct.cell_output(it.second->type, port.first)) sigmap(port.second).replace(sig, dummy_wire, &port.second); - for (auto &conn : module->connections()) + for (auto &conn : module->connections_) sigmap(conn.first).replace(sig, dummy_wire, &conn.first); } @@ -176,7 +176,7 @@ struct ConnectPass : public Pass { if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cells.at(RTLIL::escape_id(port_cell))->connections()[RTLIL::escape_id(port_port)] = sigmap(sig); + module->cells.at(RTLIL::escape_id(port_cell))->set(RTLIL::escape_id(port_port), sigmap(sig)); } else log_cmd_error("Expected -set, -unset, or -port.\n"); diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index d7560ab1..9faeffaf 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -109,7 +109,7 @@ struct ConnwrappersWorker if (!design->selected(module, cell)) continue; - for (auto &conn : cell->connections()) + for (auto &conn : cell->connections_) { std::vector sigbits = sigmap(conn.second).to_sigbit_vector(); RTLIL::SigSpec old_sig; diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index 1a780466..35ce0a11 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -49,7 +49,7 @@ struct ScatterPass : public Pass { continue; for (auto &c : mod_it.second->cells) - for (auto &p : c.second->connections()) + for (auto &p : c.second->connections_) { RTLIL::Wire *wire = new RTLIL::Wire; wire->name = NEW_ID; diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 441268ee..d63d9897 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -87,17 +87,17 @@ struct ShowWorker return defaultColor; } - std::string nextColor(RTLIL::SigSig &conn, std::string defaultColor) + std::string nextColor(const RTLIL::SigSig &conn, std::string defaultColor) { return nextColor(conn.first, nextColor(conn.second, defaultColor)); } - std::string nextColor(RTLIL::SigSpec &sig) + std::string nextColor(const RTLIL::SigSpec &sig) { return nextColor(sig, nextColor()); } - std::string nextColor(RTLIL::SigSig &conn) + std::string nextColor(const RTLIL::SigSig &conn) { return nextColor(conn, nextColor()); } diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 94f8365b..8b7e0406 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -182,7 +182,7 @@ struct SpliceWorker for (auto &it : module->cells) { if (!sel_by_wire && !design->selected(module, it.second)) continue; - for (auto &conn : it.second->connections()) + for (auto &conn : it.second->connections_) if (ct.cell_input(it.second->type, conn.first)) { if (ports.size() > 0 && !ports.count(conn.first)) continue; diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 126c4866..ed80d7c3 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -167,10 +167,14 @@ struct FsmExpand fsm_data.copy_from_cell(fsm_cell); fsm_data.num_inputs += input_sig.size(); - fsm_cell->get("\\CTRL_IN").append(input_sig); + RTLIL::SigSpec new_ctrl_in = fsm_cell->get("\\CTRL_IN"); + new_ctrl_in.append(input_sig); + fsm_cell->set("\\CTRL_IN", new_ctrl_in); fsm_data.num_outputs += output_sig.size(); - fsm_cell->get("\\CTRL_OUT").append(output_sig); + RTLIL::SigSpec new_ctrl_out = fsm_cell->get("\\CTRL_OUT"); + new_ctrl_out.append(output_sig); + fsm_cell->set("\\CTRL_OUT", new_ctrl_out); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 3ded8aca..e89bba89 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -294,13 +294,13 @@ static void extract_fsm(RTLIL::Wire *wire) sig2driver.find(ctrl_out, cellport_list); for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells.at(cellport.first); - RTLIL::SigSpec port_sig = assign_map(cell->connections()[cellport.second]); + RTLIL::SigSpec port_sig = assign_map(cell->get(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = new RTLIL::Wire; unconn_wire->name = stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++); unconn_wire->width = unconn_sig.size(); module->wires[unconn_wire->name] = unconn_wire; - port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections()[cellport.second]); + port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); } } diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index e82b5363..1441378a 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -79,7 +79,9 @@ struct FsmOpt tmp.remove(i, 1); tr.ctrl_in = tmp.as_const(); } - cell->get("\\CTRL_IN").remove(i, 1); + RTLIL::SigSpec new_ctrl_in = cell->get("\\CTRL_IN"); + new_ctrl_in.remove(i, 1); + cell->set("\\CTRL_IN", new_ctrl_in); fsm_data.num_inputs--; } } @@ -94,7 +96,9 @@ struct FsmOpt RTLIL::SigSpec sig = cell->get("\\CTRL_OUT").extract(i, 1); if (signal_is_unused(sig)) { log(" Removing unused output signal %s.\n", log_signal(sig)); - cell->get("\\CTRL_OUT").remove(i, 1); + RTLIL::SigSpec new_ctrl_out = cell->get("\\CTRL_OUT"); + new_ctrl_out.remove(i, 1); + cell->set("\\CTRL_OUT", new_ctrl_out); for (auto &tr : fsm_data.transition_table) { RTLIL::SigSpec tmp(tr.ctrl_out); tmp.remove(i, 1); @@ -108,7 +112,7 @@ struct FsmOpt void opt_alias_inputs() { - RTLIL::SigSpec &ctrl_in = cell->get("\\CTRL_IN"); + RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"]; for (int i = 0; i < ctrl_in.size(); i++) for (int j = i+1; j < ctrl_in.size(); j++) @@ -145,8 +149,8 @@ struct FsmOpt void opt_feedback_inputs() { - RTLIL::SigSpec &ctrl_in = cell->get("\\CTRL_IN"); - RTLIL::SigSpec &ctrl_out = cell->get("\\CTRL_OUT"); + RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"]; + RTLIL::SigSpec &ctrl_out = cell->connections_["\\CTRL_OUT"]; for (int j = 0; j < ctrl_out.size(); j++) for (int i = 0; i < ctrl_in.size(); i++) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 5937373f..76b667b8 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -219,7 +219,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla RTLIL::Module *mod = design->modules[cell->type]; - for (auto &conn : cell->connections()) { + for (auto &conn : cell->connections_) { int conn_size = conn.second.size(); std::string portname = conn.first; if (portname.substr(0, 1) == "$") { @@ -519,7 +519,7 @@ struct HierarchyPass : public Pass { new_connections[pos_map.at(key)] = conn.second; } else new_connections[conn.first] = conn.second; - cell->connections() = new_connections; + cell->connections_ = new_connections; } } diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index d72ebb12..ef4a9f16 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -65,7 +65,7 @@ struct SubmodWorker flag_found_something = true; } - void flag_signal(RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) + void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used) { for (auto &c : sig.chunks()) if (c.wire != NULL) @@ -163,7 +163,7 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell); - for (auto &conn : new_cell->connections()) + for (auto &conn : new_cell->connections_) for (auto &bit : conn.second) if (bit.wire != NULL) { assert(wire_flags.count(bit.wire) > 0); @@ -180,7 +180,7 @@ struct SubmodWorker RTLIL::Wire *old_wire = it.first; RTLIL::Wire *new_wire = it.second.new_wire; if (new_wire->port_id > 0) - new_cell->connections()[new_wire->name] = RTLIL::SigSpec(old_wire); + new_cell->set(new_wire->name, RTLIL::SigSpec(old_wire)); } } diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 0513aa3d..999c969b 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -52,10 +52,10 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI continue; } - RTLIL::SigSpec q_norm = cell->connections()[after ? "\\D" : "\\Q"]; + RTLIL::SigSpec q_norm = cell->get(after ? "\\D" : "\\Q"); normalize_sig(module, q_norm); - RTLIL::SigSpec d = q_norm.extract(bit, &cell->connections()[after ? "\\Q" : "\\D"]); + RTLIL::SigSpec d = q_norm.extract(bit, &cell->get(after ? "\\Q" : "\\D")); if (d.size() != 1) continue; @@ -127,8 +127,11 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$dff") - cell->get("\\Q").replace(sig, newsig); + if (cell->type == "$dff") { + RTLIL::SigSpec new_q = cell->get("\\Q"); + new_q.replace(sig, newsig); + cell->set("\\Q", new_q); + } } } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 8b4eb0d0..df1a2697 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -72,8 +72,11 @@ struct MemoryShareWorker for (int i = 0; i < int(sig_s.size()); i++) if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { - if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) - cell->get("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) { + RTLIL::SigSpec new_b = cell->get("\\B"); + new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->set("\\B", new_b); + } return false; } @@ -86,16 +89,22 @@ struct MemoryShareWorker std::map new_state = state; new_state[sig_s[i]] = true; - if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) - cell->get("\\B").replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) { + RTLIL::SigSpec new_b = cell->get("\\B"); + new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); + cell->set("\\B", new_b); + } } std::map new_state = state; for (int i = 0; i < int(sig_s.size()); i++) new_state[sig_s[i]] = false; - if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) - cell->get("\\A").replace(bit_idx, RTLIL::State::Sx); + if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) { + RTLIL::SigSpec new_a = cell->get("\\A"); + new_a.replace(bit_idx, RTLIL::State::Sx); + cell->set("\\A", new_a); + } return false; } @@ -239,7 +248,7 @@ struct MemoryShareWorker if (created_conditions) { log(" Added enable logic for %d different cases.\n", created_conditions); - cell->get("\\EN") = cell_en; + cell->set("\\EN", cell_en); } } } @@ -399,7 +408,7 @@ struct MemoryShareWorker // Force this ports addr input to addr directly (skip don't care muxes) - cell->get("\\ADDR") = addr; + cell->set("\\ADDR", addr); // If any of the ports between `last_i' and `i' write to the same address, this // will have priority over whatever `last_i` wrote. So we need to revisit those @@ -443,8 +452,8 @@ struct MemoryShareWorker // Connect the new EN and DATA signals and remove the old write port. - cell->get("\\EN") = merged_en; - cell->get("\\DATA") = merged_data; + cell->set("\\EN", merged_en); + cell->set("\\DATA", merged_data); module->remove(wr_ports[last_i]); wr_ports[last_i] = NULL; @@ -595,8 +604,8 @@ struct MemoryShareWorker RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); - wr_ports[i]->get("\\ADDR") = module->Mux(NEW_ID, last_addr, this_addr, this_en_active); - wr_ports[i]->get("\\DATA") = module->Mux(NEW_ID, last_data, this_data, this_en_active); + wr_ports[i]->set("\\ADDR", module->Mux(NEW_ID, last_addr, this_addr, this_en_active)); + wr_ports[i]->set("\\DATA", module->Mux(NEW_ID, last_data, this_data, this_en_active)); std::map, int> groups_en; RTLIL::SigSpec grouped_last_en, grouped_this_en, en; @@ -614,7 +623,7 @@ struct MemoryShareWorker } module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); - wr_ports[i]->get("\\EN") = en; + wr_ports[i]->set("\\EN", en); module->remove(wr_ports[i-1]); wr_ports[i-1] = NULL; diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index fa5d8f18..e279c020 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -189,13 +189,13 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } } - module->connections().clear(); + module->connections_.clear(); SigPool used_signals; SigPool used_signals_nodrivers; for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - for (auto &it2 : cell->connections()) { + for (auto &it2 : cell->connections_) { assign_map.apply(it2.second); used_signals.add(it2.second); if (!ct.cell_output(cell->type, it2.first)) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 7f420ec3..e5288231 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -73,7 +73,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { - RTLIL::SigSpec Y = cell->connections()[out_port]; + RTLIL::SigSpec Y = cell->get(out_port); out_val.extend_u0(Y.size(), false); log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", @@ -240,7 +240,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover("opt.opt_const.fine.$reduce_and"); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->get("\\A") = sig_a = new_a; + cell->set("\\A", sig_a = new_a); cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -267,7 +267,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->get("\\A") = sig_a = new_a; + cell->set("\\A", sig_a = new_a); cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -294,7 +294,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.B", "$logic_and", "$logic_or", cell->type); log("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); - cell->get("\\B") = sig_b = new_b; + cell->set("\\B", sig_b = new_b); cell->parameters.at("\\B_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -441,8 +441,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover("opt.opt_const.mux_to_inv"); cell->type = "$_INV_"; cell->set("\\A", input.extract(0, 1)); - cell->connections().erase("\\B"); - cell->connections().erase("\\S"); + cell->unset("\\B"); + cell->unset("\\S"); goto next_cell; } if (input.match("11 ")) ACTION_DO_Y(1); @@ -510,7 +510,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (a.is_fully_const()) { cover_list("opt.opt_const.eqneq.swapconst", "$eq", "$ne", cell->type); - std::swap(cell->get("\\A"), cell->get("\\B")); + RTLIL::SigSpec tmp = cell->get("\\A"); + cell->set("\\A", cell->get("\\B")); + cell->set("\\B", tmp); } if (b.is_fully_const()) { @@ -522,7 +524,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$not"; cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); - cell->connections().erase("\\B"); + cell->unset("\\B"); } goto next_cell; } @@ -585,13 +587,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); if (!identity_wrt_a) { - cell->get("\\A") = cell->get("\\B"); + cell->set("\\A", cell->get("\\B")); cell->parameters.at("\\A_WIDTH") = cell->parameters.at("\\B_WIDTH"); cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); } cell->type = identity_bu0 ? "$bu0" : "$pos"; - cell->connections().erase("\\B"); + cell->unset("\\B"); cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); cell->check(); @@ -613,8 +615,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->get("\\A") == RTLIL::SigSpec(1, 1) && cell->get("\\B") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type); cell->set("\\A", cell->get("\\S")); - cell->connections().erase("\\B"); - cell->connections().erase("\\S"); + cell->unset("\\B"); + cell->unset("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\Y_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -631,7 +633,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->get("\\A") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type); cell->set("\\A", cell->get("\\S")); - cell->connections().erase("\\S"); + cell->unset("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -650,7 +652,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type); cell->set("\\B", cell->get("\\S")); - cell->connections().erase("\\S"); + cell->unset("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -701,9 +703,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (cell->get("\\S").size() != new_s.size()) { cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type); - cell->get("\\A") = new_a; - cell->get("\\B") = new_b; - cell->get("\\S") = new_s; + cell->set("\\A", new_a); + cell->set("\\B", new_b); + cell->set("\\S", new_s); if (new_s.size() > 1) { cell->type = "$pmux"; cell->parameters["\\S_WIDTH"] = new_s.size(); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 8c281b34..1f8648c4 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -215,13 +215,19 @@ struct OptReduceWorker log_signal(cell->get("\\B")), log_signal(cell->get("\\Y"))); cell->set("\\A", RTLIL::SigSpec()); - for (auto &in_tuple : consolidated_in_tuples) - cell->get("\\A").append(in_tuple.at(0)); + for (auto &in_tuple : consolidated_in_tuples) { + RTLIL::SigSpec new_a = cell->get("\\A"); + new_a.append(in_tuple.at(0)); + cell->set("\\A", new_a); + } cell->set("\\B", RTLIL::SigSpec()); for (int i = 1; i <= cell->get("\\S").size(); i++) - for (auto &in_tuple : consolidated_in_tuples) - cell->get("\\B").append(in_tuple.at(i)); + for (auto &in_tuple : consolidated_in_tuples) { + RTLIL::SigSpec new_b = cell->get("\\B"); + new_b.append(in_tuple.at(i)); + cell->set("\\B", new_b); + } cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); cell->set("\\Y", new_sig_y); diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 8412f929..4f733a37 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -263,7 +263,7 @@ struct OptShareWorker log(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str()); for (auto &it : cell->connections()) { if (ct.cell_output(cell->type, it.first)) { - RTLIL::SigSpec other_sig = sharemap[cell]->connections()[it.first]; + RTLIL::SigSpec other_sig = sharemap[cell]->get(it.first); log(" Redirecting output %s: %s = %s\n", it.first.c_str(), log_signal(it.second), log_signal(other_sig)); module->connect(RTLIL::SigSig(it.second, other_sig)); diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 2e2d4701..cfd2eb7a 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -160,15 +160,15 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux"); mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_set->connections()[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); - mux_sr_set->connections()[set_polarity ? "\\B" : "\\A"] = sig_set; + mux_sr_set->set(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size())); + mux_sr_set->set(set_polarity ? "\\B" : "\\A", sig_set); mux_sr_set->set("\\Y", sig_sr_set); mux_sr_set->set("\\S", set); RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux"); mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_clr->connections()[set_polarity ? "\\A" : "\\B"] = RTLIL::Const(0, sig_in.size()); - mux_sr_clr->connections()[set_polarity ? "\\B" : "\\A"] = sig_set_inv; + mux_sr_clr->set(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size())); + mux_sr_clr->set(set_polarity ? "\\B" : "\\A", sig_set_inv); mux_sr_clr->set("\\Y", sig_sr_clr); mux_sr_clr->set("\\S", set); diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 2ff755ae..30e7b748 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -174,8 +174,15 @@ static void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); assert(ctrl_sig.size() == 1); last_mux_cell->type = "$pmux"; - last_mux_cell->get("\\S").append(ctrl_sig); - last_mux_cell->get("\\B").append(when_signal); + + RTLIL::SigSpec new_s = last_mux_cell->get("\\S"); + new_s.append(ctrl_sig); + last_mux_cell->set("\\S", new_s); + + RTLIL::SigSpec new_b = last_mux_cell->get("\\B"); + new_b.append(when_signal); + last_mux_cell->set("\\B", new_b); + last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->get("\\S").size(); } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 58dcf915..a84faf79 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -485,12 +485,12 @@ struct ExposePass : public Pass { for (auto &it : module->cells) { if (!ct.cell_known(it.second->type)) continue; - for (auto &conn : it.second->connections()) + for (auto &conn : it.second->connections_) if (ct.cell_input(it.second->type, conn.first)) conn.second = out_to_in_map(sigmap(conn.second)); } - for (auto &conn : module->connections()) + for (auto &conn : module->connections_) conn.second = out_to_in_map(sigmap(conn.second)); } @@ -518,7 +518,7 @@ struct ExposePass : public Pass { for (auto &bit : cell_q_bits) if (wire_bits_set.count(bit)) bit = RTLIL::SigBit(wire_dummy_q, wire_dummy_q->width++); - cell->get("\\Q") = cell_q_bits; + cell->set("\\Q", cell_q_bits); } RTLIL::Wire *wire_q = new RTLIL::Wire; diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index da934585..d5336ca0 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -708,7 +708,7 @@ struct FreduceWorker RTLIL::Cell *drv = drivers.at(grp[i].bit).first; RTLIL::Wire *dummy_wire = module->addWire(NEW_ID); - for (auto &port : drv->connections()) + for (auto &port : drv->connections_) if (ct.cell_output(drv->type, port.first)) sigmap(port.second).replace(grp[i].bit, dummy_wire, &port.second); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 34355122..96aa10ba 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -132,8 +132,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w2->width = w1->width; miter_module->add(w2); - gold_cell->connections()[w1->name] = w2; - gate_cell->connections()[w1->name] = w2; + gold_cell->set(w1->name, w2); + gate_cell->set(w1->name, w2); } if (w1->port_output) @@ -150,8 +150,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, w2_gate->width = w1->width; miter_module->add(w2_gate); - gold_cell->connections()[w1->name] = w2_gold; - gate_cell->connections()[w1->name] = w2_gate; + gold_cell->set(w1->name, w2_gold); + gate_cell->set(w1->name, w2_gate); RTLIL::SigSpec this_condition; diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 13ef695e..0ee5af18 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -258,7 +258,9 @@ struct ShareWorker RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; if (unsigned_cell->get("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - unsigned_cell->get("\\A").append_bit(RTLIL::State::S0); + RTLIL::SigSpec new_a = unsigned_cell->get("\\A"); + new_a.append_bit(RTLIL::State::S0); + unsigned_cell->set("\\A", new_a); } unsigned_cell->parameters.at("\\A_SIGNED") = true; unsigned_cell->check(); @@ -312,7 +314,10 @@ struct ShareWorker if (score_flipped < score_unflipped) { - std::swap(c2->get("\\A"), c2->get("\\B")); + RTLIL::SigSpec tmp = c2->get("\\A"); + c2->set("\\A", c2->get("\\B")); + c2->set("\\B", tmp); + std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); modified_src_cells = true; @@ -325,7 +330,9 @@ struct ShareWorker RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; if (unsigned_cell->get("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - unsigned_cell->get("\\A").append_bit(RTLIL::State::S0); + RTLIL::SigSpec new_a = unsigned_cell->get("\\A"); + new_a.append_bit(RTLIL::State::S0); + unsigned_cell->set("\\A", new_a); } unsigned_cell->parameters.at("\\A_SIGNED") = true; modified_src_cells = true; @@ -336,7 +343,9 @@ struct ShareWorker RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; if (unsigned_cell->get("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; - unsigned_cell->get("\\B").append_bit(RTLIL::State::S0); + RTLIL::SigSpec new_b = unsigned_cell->get("\\B"); + new_b.append_bit(RTLIL::State::S0); + unsigned_cell->set("\\B", new_b); } unsigned_cell->parameters.at("\\B_SIGNED") = true; modified_src_cells = true; diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 1dce39f6..eabc56bd 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -418,7 +418,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } else if (port.second != 0) log_abort(); - new_cell->connections()["\\" + port.first] = sig; + new_cell->set("\\" + port.first, sig); } stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type.c_str(), new_cell->type.c_str())]++; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 0d8f6ab0..6439302c 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -305,7 +305,7 @@ namespace if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair(wire->name, i)); - cell->connections()[wire->name] = RTLIL::SigSpec(RTLIL::State::Sz, wire->width); + cell->set(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width)); } } @@ -325,7 +325,9 @@ namespace for (int i = 0; i < sig.size(); i++) for (auto &port : sig2port.find(sig[i])) { RTLIL::SigSpec bitsig = haystack_cell->connections().at(mapping.portMapping[conn.first]).extract(i, 1); - cell->connections().at(port.first).replace(port.second, bitsig); + RTLIL::SigSpec new_sig = cell->get(port.first); + new_sig.replace(port.second, bitsig); + cell->set(port.first, new_sig); } } } @@ -744,7 +746,7 @@ struct ExtractPass : public Pass { for (auto &chunk : chunks) if (chunk.wire != NULL) chunk.wire = newMod->wires.at(chunk.wire->name); - newCell->connections()[conn.first] = chunks; + newCell->set(conn.first, chunks); } } } diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index 2e5dd7dc..30977787 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -35,7 +35,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_hi == RTLIL::State::Sm) { last_hi = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype)); - cell->connections()[RTLIL::escape_id(hicell_portname)] = last_hi; + cell->set(RTLIL::escape_id(hicell_portname), last_hi); } bit = last_hi; } @@ -43,7 +43,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_lo == RTLIL::State::Sm) { last_lo = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype)); - cell->connections()[RTLIL::escape_id(locell_portname)] = last_lo; + cell->set(RTLIL::escape_id(locell_portname), last_lo); } bit = last_lo; } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 199fd602..114d28e2 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -177,9 +177,9 @@ struct IopadmapPass : public Pass { for (int i = 0; i < wire->width; i++) { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->connections()[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire, i); + cell->set(RTLIL::escape_id(portname), RTLIL::SigSpec(wire, i)); if (!portname2.empty()) - cell->connections()[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire, i); + cell->set(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire, i)); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) @@ -190,9 +190,9 @@ struct IopadmapPass : public Pass { else { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->connections()[RTLIL::escape_id(portname)] = RTLIL::SigSpec(wire); + cell->set(RTLIL::escape_id(portname), RTLIL::SigSpec(wire)); if (!portname2.empty()) - cell->connections()[RTLIL::escape_id(portname2)] = RTLIL::SigSpec(new_wire); + cell->set(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire)); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index f8851400..355c07c8 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -128,7 +128,7 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$reduce_bool") gate_type = "$_OR_"; log_assert(!gate_type.empty()); - RTLIL::SigSpec *last_output = NULL; + RTLIL::Cell *last_output_cell = NULL; while (sig_a.size() > 1) { @@ -145,7 +145,7 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) gate->set("\\A", sig_a[i]); gate->set("\\B", sig_a[i+1]); gate->set("\\Y", sig_t[i/2]); - last_output = &gate->get("\\Y"); + last_output_cell = gate; } sig_a = sig_t; @@ -156,14 +156,14 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); gate->set("\\A", sig_a); gate->set("\\Y", sig_t); - last_output = &gate->get("\\Y"); + last_output_cell = gate; sig_a = sig_t; } - if (last_output == NULL) { + if (last_output_cell == NULL) { module->connect(RTLIL::SigSig(sig_y, sig_a)); } else { - *last_output = sig_y; + last_output_cell->set("\\Y", sig_y); } } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 4c8f9250..9dcd6a45 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -195,7 +195,7 @@ struct TechmapWorker if (!flatten_mode && c->type.substr(0, 2) == "\\$") c->type = c->type.substr(1); - for (auto &it2 : c->connections()) { + for (auto &it2 : c->connections_) { apply_prefix(cell->name, it2.second, module); port_signal_map.apply(it2.second); } From 97a59851a6c411ccb06162d4b31725bf89262378 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 16:11:28 +0200 Subject: [PATCH 437/750] Added RTLIL::Cell::has(portname) --- backends/spice/spice.cc | 2 +- backends/verilog/verilog_backend.cc | 4 ++-- frontends/ilang/parser.y | 2 +- kernel/consteval.h | 8 ++++---- kernel/rtlil.cc | 13 +++++++++---- kernel/rtlil.h | 1 + passes/cmds/add.cc | 2 +- passes/fsm/fsm_detect.cc | 2 +- passes/fsm/fsm_expand.cc | 16 ++++++++-------- passes/fsm/fsm_extract.cc | 2 +- passes/opt/opt_const.cc | 4 ++-- passes/sat/expose.cc | 4 ++-- 12 files changed, 33 insertions(+), 27 deletions(-) diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 4bc8710e..653a9f22 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -80,7 +80,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de for (RTLIL::Wire *wire : ports) { log_assert(wire != NULL); RTLIL::SigSpec sig(RTLIL::State::Sz, wire->width); - if (cell->connections().count(wire->name) > 0) { + if (cell->has(wire->name)) { sig = sigmap(cell->connections().at(wire->name)); sig.extend(wire->width, false); } diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 6bef90e3..d9186c04 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -301,7 +301,7 @@ void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_ std::string cellname(RTLIL::Cell *cell) { - if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->connections().count("\\Q") > 0) + if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->has("\\Q")) { RTLIL::SigSpec sig = cell->get("\\Q"); if (SIZE(sig) != 1 || sig.is_fully_const()) @@ -908,7 +908,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto &it : module->cells) { RTLIL::Cell *cell = it.second; - if (!reg_ct.cell_known(cell->type) || cell->connections().count("\\Q") == 0) + if (!reg_ct.cell_known(cell->type) || !cell->has("\\Q")) continue; RTLIL::SigSpec sig = cell->get("\\Q"); diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 952dd6a3..09437a0a 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; diff --git a/kernel/consteval.h b/kernel/consteval.h index 4050d2dc..3a5c5347 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -87,21 +87,21 @@ struct ConstEval { RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; - assert(cell->connections().count("\\Y") > 0); + assert(cell->has("\\Y")); sig_y = values_map(assign_map(cell->get("\\Y"))); if (sig_y.is_fully_const()) return true; - if (cell->connections().count("\\S") > 0) { + if (cell->has("\\S")) { sig_s = cell->get("\\S"); if (!eval(sig_s, undef, cell)) return false; } - if (cell->connections().count("\\A") > 0) + if (cell->has("\\A")) sig_a = cell->get("\\A"); - if (cell->connections().count("\\B") > 0) + if (cell->has("\\B")) sig_b = cell->get("\\B"); if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ceb2b0f5..059357d2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -348,9 +348,9 @@ namespace { void port(const char *name, int width) { - if (cell->connections().count(name) == 0) + if (!cell->has(name)) error(__LINE__); - if (cell->connections().at(name).size() != width) + if (cell->get(name).size() != width) error(__LINE__); expected_ports.insert(name); } @@ -379,9 +379,9 @@ namespace { for (const char *p = ports; *p; p++) { char portname[3] = { '\\', *p, 0 }; - if (cell->connections().count(portname) == 0) + if (!cell->has(portname)) error(__LINE__); - if (cell->connections().at(portname).size() != 1) + if (cell->get(portname).size() != 1) error(__LINE__); } @@ -1340,6 +1340,11 @@ RTLIL::Memory::Memory() size = 0; } +bool RTLIL::Cell::has(RTLIL::IdString portname) +{ + return connections_.count(portname) != 0; +} + void RTLIL::Cell::unset(RTLIL::IdString portname) { connections_.erase(portname); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 25d0a830..73d3727c 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -488,6 +488,7 @@ public: RTLIL_ATTRIBUTE_MEMBERS // access cell ports + bool has(RTLIL::IdString portname); void unset(RTLIL::IdString portname); void set(RTLIL::IdString portname, RTLIL::SigSpec signal); const RTLIL::SigSpec &get(RTLIL::IdString portname) const; diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 1401193f..f94ea639 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -75,7 +75,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n continue; if (mod->get_bool_attribute("\\blackbox")) continue; - if (it.second->connections().count(name) > 0) + if (it.second->has(name)) continue; it.second->set(name, wire); diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index be851afa..55fe336f 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -80,7 +80,7 @@ static bool check_state_users(RTLIL::SigSpec sig) continue; if (cellport.second != "\\A" && cellport.second != "\\B") return false; - if (cell->connections().count("\\A") == 0 || cell->connections().count("\\B") == 0 || cell->connections().count("\\Y") == 0) + if (!cell->has("\\A") || !cell->has("\\B") || !cell->has("\\Y")) return false; for (auto &port_it : cell->connections()) if (port_it.first != "\\A" && port_it.first != "\\B" && port_it.first != "\\Y") diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index ed80d7c3..186ea2fd 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -47,13 +47,13 @@ struct FsmExpand return true; RTLIL::SigSpec new_signals; - if (cell->connections().count("\\A") > 0) + if (cell->has("\\A")) new_signals.append(assign_map(cell->get("\\A"))); - if (cell->connections().count("\\B") > 0) + if (cell->has("\\B")) new_signals.append(assign_map(cell->get("\\B"))); - if (cell->connections().count("\\S") > 0) + if (cell->has("\\S")) new_signals.append(assign_map(cell->get("\\S"))); - if (cell->connections().count("\\Y") > 0) + if (cell->has("\\Y")) new_signals.append(assign_map(cell->get("\\Y"))); new_signals.sort_and_unify(); @@ -65,7 +65,7 @@ struct FsmExpand if (new_signals.size() > 3) return false; - if (cell->connections().count("\\Y") > 0) { + if (cell->has("\\Y")) { new_signals.append(assign_map(cell->get("\\Y"))); new_signals.sort_and_unify(); new_signals.remove_const(); @@ -148,11 +148,11 @@ struct FsmExpand for (int i = 0; i < (1 << input_sig.size()); i++) { RTLIL::Const in_val(i, input_sig.size()); RTLIL::SigSpec A, B, S; - if (cell->connections().count("\\A") > 0) + if (cell->has("\\A")) A = assign_map(cell->get("\\A")); - if (cell->connections().count("\\B") > 0) + if (cell->has("\\B")) B = assign_map(cell->get("\\B")); - if (cell->connections().count("\\S") > 0) + if (cell->has("\\S")) S = assign_map(cell->get("\\S")); A.replace(input_sig, RTLIL::SigSpec(in_val)); B.replace(input_sig, RTLIL::SigSpec(in_val)); diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index e89bba89..ff3ac760 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -350,7 +350,7 @@ struct FsmExtractPass : public Pass { assign_map.apply(sig); sig2driver.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); } - if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->connections().count("\\Y") > 0 && + if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->has("\\Y") && cell_it.second->get("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index e5288231..000a9ec2 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -88,7 +88,7 @@ static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string i static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, bool extend_u0, SigMap &sigmap) { - std::string b_name = cell->connections().count("\\B") ? "\\B" : "\\A"; + std::string b_name = cell->has("\\B") ? "\\B" : "\\A"; bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool(); bool b_signed = cell->parameters.at(b_name + "_SIGNED").as_bool(); @@ -321,7 +321,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || cell->type == "$pow") { RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); - RTLIL::SigSpec sig_b = cell->connections().count("\\B") ? assign_map(cell->get("\\B")) : RTLIL::SigSpec(); + RTLIL::SigSpec sig_b = cell->has("\\B") ? assign_map(cell->get("\\B")) : RTLIL::SigSpec(); if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") sig_a = RTLIL::SigSpec(); diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index a84faf79..198f8347 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -83,7 +83,7 @@ static void find_dff_wires(std::set &dff_wires, RTLIL::Module *modu SigPool dffsignals; for (auto &it : module->cells) { - if (ct.cell_known(it.second->type) && it.second->connections().count("\\Q")) + if (ct.cell_known(it.second->type) && it.second->has("\\Q")) dffsignals.add(sigmap(it.second->get("\\Q"))); } @@ -628,7 +628,7 @@ struct ExposePass : public Pass { log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); RTLIL::SigSpec sig; - if (cell->connections().count(p->name) != 0) + if (cell->has(p->name)) sig = cell->connections().at(p->name); sig.extend(w->width); if (w->port_input) From 3f4e3ca8ad480c2e73e2072ada77078ffd95e08f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 16:14:02 +0200 Subject: [PATCH 438/750] More RTLIL::Cell API usage cleanups --- backends/btor/btor.cc | 68 +++++++++++++++++++-------------------- backends/spice/spice.cc | 2 +- passes/opt/opt_const.cc | 2 +- passes/sat/expose.cc | 2 +- passes/techmap/extract.cc | 4 +-- 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index bbfbc0f9..f731e17e 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -387,8 +387,8 @@ struct BtorDumper if(cell->type == "$assert") { log("writing assert cell - %s\n", cstr(cell->type)); - const RTLIL::SigSpec* expr = &cell->connections().at(RTLIL::IdString("\\A")); - const RTLIL::SigSpec* en = &cell->connections().at(RTLIL::IdString("\\EN")); + const RTLIL::SigSpec* expr = &cell->get(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* en = &cell->get(RTLIL::IdString("\\EN")); log_assert(expr->size() == 1); log_assert(en->size() == 1); int expr_line = dump_sigspec(expr, 1); @@ -420,7 +420,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); w = w>output_width ? w:output_width; //padding of w - int l = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), w); int cell_line = l; if(cell->type != "$pos") { @@ -444,7 +444,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), w); if(cell->type == "$logic_not" && w > 1) { ++line_num; @@ -481,8 +481,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -515,8 +515,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -550,8 +550,8 @@ struct BtorDumper l1_width = pow(2, ceil(log(l1_width)/log(2))); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); //assert(l2_width <= ceil(log(l1_width)/log(2)) ); - int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); + int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); int cell_output = ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), l1_width, l1, l2); fprintf(f, "%s\n", str.c_str()); @@ -559,7 +559,7 @@ struct BtorDumper if(l2_width > ceil(log(l1_width)/log(2))) { int extra_width = l2_width - ceil(log(l1_width)/log(2)); - l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), l2_width); + l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), l2_width); ++line_num; str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width); fprintf(f, "%s\n", str.c_str()); @@ -592,8 +592,8 @@ struct BtorDumper log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), output_width); + int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), output_width); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); if(l1_width >1) @@ -628,9 +628,9 @@ struct BtorDumper { log("writing mux cell\n"); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int l1 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\B")), output_width); - int s = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\S")), 1); + int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), output_width); + int s = dump_sigspec(&cell->get(RTLIL::IdString("\\S")), 1); ++line_num; str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell @@ -644,10 +644,10 @@ struct BtorDumper log("writing cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); log(" - width is %d\n", output_width); - int cond = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\CLK")), 1); + int cond = dump_sigspec(&cell->get(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - const RTLIL::SigSpec* cell_output = &cell->connections().at(RTLIL::IdString("\\Q")); - int value = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\D")), output_width); + const RTLIL::SigSpec* cell_output = &cell->get(RTLIL::IdString("\\Q")); + int value = dump_sigspec(&cell->get(RTLIL::IdString("\\D")), output_width); unsigned start_bit = 0; for(unsigned i=0; ichunks().size(); ++i) { @@ -665,9 +665,9 @@ struct BtorDumper } if(cell->type == "$dffsr") { - int sync_reset = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\CLR")), 1); + int sync_reset = dump_sigspec(&cell->get(RTLIL::IdString("\\CLR")), 1); bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); - int sync_reset_value = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\SET")), + int sync_reset_value = dump_sigspec(&cell->get(RTLIL::IdString("\\SET")), output_width); bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); ++line_num; @@ -685,7 +685,7 @@ struct BtorDumper int next = line_num; if(cell->type == "$adff") { - int async_reset = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\ARST")), 1); + int async_reset = dump_sigspec(&cell->get(RTLIL::IdString("\\ARST")), 1); bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), output_width, 0); @@ -710,7 +710,7 @@ struct BtorDumper str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->get(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); ++line_num; str = stringf("%d read %d %d %d", line_num, data_width, mem, address); @@ -722,13 +722,13 @@ struct BtorDumper log("writing memwr cell\n"); if (cell->parameters.at("\\CLK_ENABLE").as_bool() == false) log_error("The btor backen does not support $memwr cells without built-in registers. Run memory_dff (but with -wr_only).\n"); - int clk = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\CLK")), 1); + int clk = dump_sigspec(&cell->get(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - int enable = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\EN")), 1); + int enable = dump_sigspec(&cell->get(RTLIL::IdString("\\EN")), 1); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->get(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int data = dump_sigspec(&cell->connections().at(RTLIL::IdString("\\DATA")), data_width); + int data = dump_sigspec(&cell->get(RTLIL::IdString("\\DATA")), data_width); str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); ++line_num; @@ -757,11 +757,11 @@ struct BtorDumper else if(cell->type == "$slice") { log("writing slice cell\n"); - const RTLIL::SigSpec* input = &cell->connections().at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input = &cell->get(RTLIL::IdString("\\A")); int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input->size() == input_width); int input_line = dump_sigspec(input, input_width); - const RTLIL::SigSpec* output = &cell->connections().at(RTLIL::IdString("\\Y")); + const RTLIL::SigSpec* output = &cell->get(RTLIL::IdString("\\Y")); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output->size() == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); @@ -773,11 +773,11 @@ struct BtorDumper else if(cell->type == "$concat") { log("writing concat cell\n"); - const RTLIL::SigSpec* input_a = &cell->connections().at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input_a = &cell->get(RTLIL::IdString("\\A")); int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input_a->size() == input_a_width); int input_a_line = dump_sigspec(input_a, input_a_width); - const RTLIL::SigSpec* input_b = &cell->connections().at(RTLIL::IdString("\\B")); + const RTLIL::SigSpec* input_b = &cell->get(RTLIL::IdString("\\B")); int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); log_assert(input_b->size() == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); @@ -801,7 +801,7 @@ struct BtorDumper const RTLIL::SigSpec *output_sig = nullptr; if (cell->type == "$memrd") { - output_sig = &cell->connections().at(RTLIL::IdString("\\DATA")); + output_sig = &cell->get(RTLIL::IdString("\\DATA")); } else if(cell->type == "$memwr" || cell->type == "$assert") { @@ -809,11 +809,11 @@ struct BtorDumper } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - output_sig = &cell->connections().at(RTLIL::IdString("\\Q")); + output_sig = &cell->get(RTLIL::IdString("\\Q")); } else { - output_sig = &cell->connections().at(RTLIL::IdString("\\Y")); + output_sig = &cell->get(RTLIL::IdString("\\Y")); } return output_sig; } diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 653a9f22..07736877 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -81,7 +81,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de log_assert(wire != NULL); RTLIL::SigSpec sig(RTLIL::State::Sz, wire->width); if (cell->has(wire->name)) { - sig = sigmap(cell->connections().at(wire->name)); + sig = sigmap(cell->get(wire->name)); sig.extend(wire->width, false); } port_sigs.push_back(sig); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 000a9ec2..67218600 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -94,7 +94,7 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com bool b_signed = cell->parameters.at(b_name + "_SIGNED").as_bool(); RTLIL::SigSpec sig_a = sigmap(cell->get("\\A")); - RTLIL::SigSpec sig_b = sigmap(cell->connections().at(b_name)); + RTLIL::SigSpec sig_b = sigmap(cell->get(b_name)); RTLIL::SigSpec sig_y = sigmap(cell->get("\\Y")); if (extend_u0) { diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 198f8347..9ce3b43d 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -629,7 +629,7 @@ struct ExposePass : public Pass { RTLIL::SigSpec sig; if (cell->has(p->name)) - sig = cell->connections().at(p->name); + sig = cell->get(p->name); sig.extend(w->width); if (w->port_input) module->connect(RTLIL::SigSig(sig, w)); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 6439302c..b8c349f5 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -128,7 +128,7 @@ namespace for (auto &conn : needleCell->connections()) { RTLIL::SigSpec needleSig = conn.second; - RTLIL::SigSpec haystackSig = haystackCell->connections().at(portMapping.at(conn.first)); + RTLIL::SigSpec haystackSig = haystackCell->get(portMapping.at(conn.first)); for (int i = 0; i < std::min(needleSig.size(), haystackSig.size()); i++) { RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire; @@ -324,7 +324,7 @@ namespace if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { for (int i = 0; i < sig.size(); i++) for (auto &port : sig2port.find(sig[i])) { - RTLIL::SigSpec bitsig = haystack_cell->connections().at(mapping.portMapping[conn.first]).extract(i, 1); + RTLIL::SigSpec bitsig = haystack_cell->get(mapping.portMapping[conn.first]).extract(i, 1); RTLIL::SigSpec new_sig = cell->get(port.first); new_sig.replace(port.second, bitsig); cell->set(port.first, new_sig); From 267c61564047f8768c29040f898633d9444a5404 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 17:21:40 +0200 Subject: [PATCH 439/750] Added support for here documents --- kernel/driver.cc | 44 ++++++++++++++++++++++++++++---------------- kernel/register.cc | 31 ++++++++++++++++++++++++++++++- kernel/register.h | 6 +++++- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 3c185e44..97910aa9 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -28,6 +28,7 @@ #include #include +#include #include "kernel/rtlil.h" #include "kernel/register.h" @@ -116,25 +117,36 @@ static void run_frontend(std::string filename, std::string command, RTLIL::Desig if (f == NULL) log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); - std::string command; - while (fgetline(f, command)) { - while (!command.empty() && command[command.size()-1] == '\\') { - std::string next_line; - if (!fgetline(f, next_line)) - break; - command.resize(command.size()-1); - command += next_line; + FILE *backup_script_file = Frontend::current_script_file; + Frontend::current_script_file = f; + + try { + std::string command; + while (fgetline(f, command)) { + while (!command.empty() && command[command.size()-1] == '\\') { + std::string next_line; + if (!fgetline(f, next_line)) + break; + command.resize(command.size()-1); + command += next_line; + } + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); } - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); + + if (!command.empty()) { + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + } + catch (...) { + Frontend::current_script_file = backup_script_file; + std::rethrow_exception(std::current_exception()); } - if (!command.empty()) { - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); - } + Frontend::current_script_file = backup_script_file; if (filename != "-") fclose(f); diff --git a/kernel/register.cc b/kernel/register.cc index e7ad7ef0..59667ac9 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -276,6 +276,9 @@ void Frontend::execute(std::vector args, RTLIL::Design *design) } while (!args.empty()); } +FILE *Frontend::current_script_file = NULL; +std::string Frontend::last_here_document; + void Frontend::extra_args(FILE *&f, std::string &filename, std::vector args, size_t argidx) { bool called_with_fp = f != NULL; @@ -291,7 +294,33 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vector 0 && (buffer[buffer.size() - 1] == '\n' || buffer[buffer.size() - 1] == '\r')) + break; + } + int indent = buffer.find_first_not_of(" \t\r\n"); + if (buffer.substr(indent, eot_marker.size()) == eot_marker) + break; + last_here_document += buffer; + } + f = fmemopen((void*)last_here_document.c_str(), last_here_document.size(), "r"); + } else + f = fopen(filename.c_str(), "r"); if (f == NULL) log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); diff --git a/kernel/register.h b/kernel/register.h index fd073cbe..73875e96 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -38,7 +38,7 @@ extern const char *yosys_version_str; extern RTLIL::Design *yosys_get_design(); extern std::string proc_self_dirname(); extern std::string proc_share_dirname(); -const char *create_prompt(RTLIL::Design *design, int recursion_counter); +extern const char *create_prompt(RTLIL::Design *design, int recursion_counter); // from passes/cmds/design.cc extern std::map saved_designs; @@ -76,6 +76,10 @@ struct Pass struct Frontend : Pass { + // for reading of here documents + static FILE *current_script_file; + static std::string last_here_document; + std::string frontend_name; Frontend(std::string name, std::string short_help = "** document me **"); virtual void run_register(); From b21ebe1859df2f9bd1791de34633a85918651c13 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 17:22:18 +0200 Subject: [PATCH 440/750] Added tests/various/submod_extract.ys --- Makefile | 1 + tests/various/run-test.sh | 6 ++++++ tests/various/submod_extract.ys | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100755 tests/various/run-test.sh create mode 100644 tests/various/submod_extract.ys diff --git a/Makefile b/Makefile index b87a7474..6809ffd0 100644 --- a/Makefile +++ b/Makefile @@ -225,6 +225,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) cd tests/share && bash run-test.sh cd tests/techmap && bash run-test.sh cd tests/memories && bash run-test.sh + cd tests/various && bash run-test.sh cd tests/sat && bash run-test.sh @echo "" @echo " Passed \"make test\"." diff --git a/tests/various/run-test.sh b/tests/various/run-test.sh new file mode 100755 index 00000000..67e1beb2 --- /dev/null +++ b/tests/various/run-test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +for x in *.ys; do + echo "Running $x.." + ../../yosys -ql ${x%.ys}.log $x +done diff --git a/tests/various/submod_extract.ys b/tests/various/submod_extract.ys new file mode 100644 index 00000000..8d11c21d --- /dev/null +++ b/tests/various/submod_extract.ys @@ -0,0 +1,21 @@ +read_verilog << EOT + module test(input [7:0] a, b, c, d, output [7:0] x, y, z); + assign x = a + b, y = b + c, z = c + d; + endmodule +EOT + +copy test gold +rename test gate + +submod -name mycell gate/x %ci* +design -copy-to mymap mycell +extract -map %mymap gate + +select -assert-count 3 gold/t:* +select -assert-count 3 gold/t:$add + +select -assert-count 3 gate/t:* +select -assert-count 3 gate/t:mycell + +miter -equiv -flatten gold gate miter +sat -verify -prove trigger 0 miter From d49dec1f861ce11a87c48cc21c8edc1755802a5f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 17:43:41 +0200 Subject: [PATCH 441/750] Added tests/various/.gitignore --- tests/various/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/various/.gitignore diff --git a/tests/various/.gitignore b/tests/various/.gitignore new file mode 100644 index 00000000..397b4a76 --- /dev/null +++ b/tests/various/.gitignore @@ -0,0 +1 @@ +*.log From 946ddff9cef3ea0b4dad8664319fb13074133775 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 20:12:50 +0200 Subject: [PATCH 442/750] Changed a lot of code to the new RTLIL::Wire constructors --- frontends/ast/genrtlil.cc | 22 ++++++--------- frontends/ilang/parser.y | 5 ++-- kernel/rtlil.cc | 40 ++++++++++++++++++++++++++ kernel/rtlil.h | 3 ++ passes/abc/abc.cc | 8 ++---- passes/abc/blifparse.cc | 22 ++++----------- passes/cmds/add.cc | 5 +--- passes/cmds/delete.cc | 35 ++++------------------- passes/cmds/scatter.cc | 5 +--- passes/cmds/splitnets.cc | 52 +++++++++++++++++----------------- passes/fsm/fsm_extract.cc | 5 +--- passes/fsm/fsm_map.cc | 20 ++++--------- passes/hierarchy/hierarchy.cc | 5 +--- passes/hierarchy/submod.cc | 37 +++++++++++++----------- passes/memory/memory_dff.cc | 9 ++---- passes/memory/memory_map.cc | 53 +++++++++-------------------------- passes/opt/opt_clean.cc | 16 +++++++---- passes/proc/proc_mux.cc | 15 ++-------- passes/sat/miter.cc | 23 ++++----------- 19 files changed, 156 insertions(+), 224 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dba301f4..3bc9b06e 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 09437a0a..20490e0d 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); }; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 059357d2..930e8a71 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -827,6 +827,46 @@ void RTLIL::Module::add(RTLIL::Cell *cell) cells[cell->name] = cell; } +namespace { + struct DeleteWireWorker + { + RTLIL::Module *module; + const std::set *wires_p; + + void operator()(RTLIL::SigSpec &sig) { + std::vector chunks = sig; + for (auto &c : chunks) + if (c.wire != NULL && wires_p->count(c.wire)) { + c.wire = module->addWire(NEW_ID, c.width); + c.offset = 0; + } + sig = chunks; + } + }; +} + +#if 0 +void RTLIL::Module::remove(RTLIL::Wire *wire) +{ + std::set wires; + wires.insert(wire); + remove(wires); +} +#endif + +void RTLIL::Module::remove(const std::set &wires) +{ + DeleteWireWorker delete_wire_worker; + delete_wire_worker.module = this; + delete_wire_worker.wires_p = &wires; + rewrite_sigspecs(delete_wire_worker); + + for (auto &it : wires) { + this->wires.erase(it->name); + delete it; + } +} + void RTLIL::Module::remove(RTLIL::Cell *cell) { assert(cells.count(cell->name) != 0); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 73d3727c..f43e7b67 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -299,6 +299,9 @@ struct RTLIL::Module void add(RTLIL::Wire *wire); void add(RTLIL::Cell *cell); + + // Removing wires is expensive. If you have to remove wires, remove them all at once. + void remove(const std::set &wires); void remove(RTLIL::Cell *cell); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 4d9a6c13..41cfe88f 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -313,11 +313,9 @@ static void handle_loops() continue; } - RTLIL::Wire *wire = new RTLIL::Wire; std::stringstream sstr; sstr << "$abcloop$" << (RTLIL::autoidx++); - wire->name = sstr.str(); - module->wires[wire->name] = wire; + RTLIL::Wire *wire = module->addWire(sstr.str()); bool first_line = true; for (int id2 : edges[id1]) { @@ -691,9 +689,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std log_error("ABC output file does not contain a module `netlist'.\n"); for (auto &it : mapped_mod->wires) { RTLIL::Wire *w = it.second; - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = remap_name(w->name); - module->wires[wire->name] = wire; + RTLIL::Wire *wire = module->addWire(remap_name(w->name)); design->select(module, wire); } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 45a9ac76..e86afa1b 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -98,14 +98,12 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) if (!strcmp(cmd, ".inputs") || !strcmp(cmd, ".outputs")) { char *p; while ((p = strtok(NULL, " \t\r\n")) != NULL) { - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = stringf("\\%s", p); + RTLIL::Wire *wire = module->addWire(stringf("\\%s", p)); wire->port_id = ++port_count; if (!strcmp(cmd, ".inputs")) wire->port_input = true; else wire->port_output = true; - module->add(wire); } continue; } @@ -115,17 +113,11 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) char *d = strtok(NULL, " \t\r\n"); char *q = strtok(NULL, " \t\r\n"); - if (module->wires.count(RTLIL::escape_id(d)) == 0) { - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(d); - module->add(wire); - } + if (module->wires.count(RTLIL::escape_id(d)) == 0) + module->addWire(RTLIL::escape_id(d)); - if (module->wires.count(RTLIL::escape_id(q)) == 0) { - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(q); - module->add(wire); - } + if (module->wires.count(RTLIL::escape_id(q)) == 0) + module->addWire(RTLIL::escape_id(q)); RTLIL::Cell *cell = module->addCell(NEW_ID, dff_name); cell->set("\\D", module->wires.at(RTLIL::escape_id(d))); @@ -162,9 +154,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) if (module->wires.count(stringf("\\%s", p)) > 0) { wire = module->wires.at(stringf("\\%s", p)); } else { - wire = new RTLIL::Wire; - wire->name = stringf("\\%s", p); - module->add(wire); + wire = module->addWire(stringf("\\%s", p)); } input_sig.append(wire); } diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index f94ea639..7e9ba97e 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -47,12 +47,9 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n } else { - wire = new RTLIL::Wire; - wire->name = name; - wire->width = width; + wire = module->addWire(name, width); wire->port_input = flag_input; wire->port_output = flag_output; - module->add(wire); if (flag_input || flag_output) { wire->port_id = module->wires.size(); diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 79b7c3c3..df5a3d4b 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -21,22 +21,6 @@ #include "kernel/rtlil.h" #include "kernel/log.h" -struct DeleteWireWorker -{ - RTLIL::Module *module; - std::set *delete_wires_p; - - void operator()(RTLIL::SigSpec &sig) { - std::vector chunks = sig; - for (auto &c : chunks) - if (c.wire != NULL && delete_wires_p->count(c.wire->name)) { - c.wire = module->addWire(NEW_ID, c.width); - c.offset = 0; - } - sig = chunks; - } -}; - struct DeletePass : public Pass { DeletePass() : Pass("delete", "delete objects in the design") { } virtual void help() @@ -106,14 +90,14 @@ struct DeletePass : public Pass { continue; } - std::set delete_wires; + std::set delete_wires; std::set delete_cells; std::set delete_procs; std::set delete_mems; for (auto &it : module->wires) if (design->selected(module, it.second)) - delete_wires.insert(it.first); + delete_wires.insert(it.second); for (auto &it : module->memories) if (design->selected(module, it.second)) @@ -131,30 +115,21 @@ struct DeletePass : public Pass { if (design->selected(module, it.second)) delete_procs.insert(it.first); - DeleteWireWorker delete_wire_worker; - delete_wire_worker.module = module; - delete_wire_worker.delete_wires_p = &delete_wires; - module->rewrite_sigspecs(delete_wire_worker); - - for (auto &it : delete_wires) { - delete module->wires.at(it); - module->wires.erase(it); - } - for (auto &it : delete_mems) { delete module->memories.at(it); module->memories.erase(it); } - for (auto &it : delete_cells) { + for (auto &it : delete_cells) module->remove(it); - } for (auto &it : delete_procs) { delete module->processes.at(it); module->processes.erase(it); } + module->remove(delete_wires); + module->fixup_ports(); } diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index 35ce0a11..0b95fe02 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -51,10 +51,7 @@ struct ScatterPass : public Pass { for (auto &c : mod_it.second->cells) for (auto &p : c.second->connections_) { - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = NEW_ID; - wire->width = p.second.size(); - mod_it.second->add(wire); + RTLIL::Wire *wire = mod_it.second->addWire(NEW_ID, p.second.size()); if (ct.cell_output(c.second->type, p.first)) { RTLIL::SigSig sigsig(p.second, wire); diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 28575e7b..6bffba62 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -28,33 +28,31 @@ struct SplitnetsWorker void append_wire(RTLIL::Module *module, RTLIL::Wire *wire, int offset, int width, std::string format) { - RTLIL::Wire *new_wire = new RTLIL::Wire; + std::string new_wire_name = wire->name; + if (format.size() > 0) + new_wire_name += format.substr(0, 1); + + if (width > 1) { + new_wire_name += stringf("%d", offset+width-1); + if (format.size() > 2) + new_wire_name += format.substr(2, 1); + else + new_wire_name += ":"; + } + + new_wire_name += stringf("%d", offset); + + if (format.size() > 1) + new_wire_name += format.substr(1, 1); + + while (module->count_id(new_wire_name) > 0) + new_wire_name += "_"; + + RTLIL::Wire *new_wire = module->addWire(new_wire_name, width); new_wire->port_id = wire->port_id; new_wire->port_input = wire->port_input; new_wire->port_output = wire->port_output; - new_wire->name = wire->name; - new_wire->width = width; - - if (format.size() > 0) - new_wire->name += format.substr(0, 1); - - if (width > 1) { - new_wire->name += stringf("%d", offset+width-1); - if (format.size() > 2) - new_wire->name += format.substr(2, 1); - else - new_wire->name += ":"; - } - - new_wire->name += stringf("%d", offset); - - if (format.size() > 1) - new_wire->name += format.substr(1, 1); - - while (module->count_id(new_wire->name) > 0) - new_wire->name = new_wire->name + "_"; - module->add(new_wire); std::vector sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector(); splitmap[wire].insert(splitmap[wire].end(), sigvec.begin(), sigvec.end()); @@ -178,10 +176,10 @@ struct SplitnetsPass : public Pass { module->rewrite_sigspecs(worker); - for (auto &it : worker.splitmap) { - module->wires.erase(it.first->name); - delete it.first; - } + std::set delete_wires; + for (auto &it : worker.splitmap) + delete_wires.insert(it.first); + module->remove(delete_wires); module->fixup_ports(); } diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index ff3ac760..51a4a75e 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -296,10 +296,7 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::Cell *cell = module->cells.at(cellport.first); RTLIL::SigSpec port_sig = assign_map(cell->get(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); - RTLIL::Wire *unconn_wire = new RTLIL::Wire; - unconn_wire->name = stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++); - unconn_wire->width = unconn_sig.size(); - module->wires[unconn_wire->name] = unconn_wire; + RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++), unconn_sig.size()); port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); } } diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index a22441b4..7ab15954 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -143,13 +143,11 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) // create state register - RTLIL::Wire *state_wire = new RTLIL::Wire; - state_wire->name = fsm_cell->parameters["\\NAME"].decode_string(); - while (module->count_id(state_wire->name) > 0) - state_wire->name += "_"; - state_wire->width = fsm_data.state_bits; - module->add(state_wire); + std::string state_wire_name = fsm_cell->parameters["\\NAME"].decode_string(); + while (module->count_id(state_wire_name) > 0) + state_wire_name += "_"; + RTLIL::Wire *state_wire = module->addWire(state_wire_name, fsm_data.state_bits); RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits); RTLIL::Cell *state_dff = module->addCell(NEW_ID, ""); @@ -209,10 +207,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) // generate next_state signal - RTLIL::Wire *next_state_onehot = new RTLIL::Wire; - next_state_onehot->name = NEW_ID; - next_state_onehot->width = fsm_data.state_table.size(); - module->add(next_state_onehot); + RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size()); for (size_t i = 0; i < fsm_data.state_table.size(); i++) { @@ -275,11 +270,6 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) // Generate ctrl_out signal - RTLIL::Wire *ctrl_out_wire = new RTLIL::Wire; - ctrl_out_wire->name = NEW_ID; - ctrl_out_wire->width = fsm_data.num_outputs; - module->add(ctrl_out_wire); - for (int i = 0; i < fsm_data.num_outputs; i++) { std::map> pattern_cache; diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 76b667b8..8c09d2ea 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -118,13 +118,10 @@ static void generate(RTLIL::Design *design, const std::vector &cell design->modules[mod->name] = mod; for (auto &decl : ports) { - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = decl.portname; - wire->width = portwidths.at(decl.portname); + RTLIL::Wire *wire = mod->addWire(decl.portname, portwidths.at(decl.portname)); wire->port_id = decl.index; wire->port_input = decl.input; wire->port_output = decl.output; - mod->add(wire); } for (auto ¶ : parameters) diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index ef4a9f16..e39f96ca 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -123,31 +123,37 @@ struct SubmodWorker if (wire->port_output) flags.is_ext_used = true; - RTLIL::Wire *new_wire = new RTLIL::Wire; - new_wire->name = wire->name; - new_wire->width = wire->width; - new_wire->start_offset = wire->start_offset; - new_wire->attributes = wire->attributes; + bool new_wire_port_input = false; + bool new_wire_port_output = false; if (flags.is_int_driven && flags.is_ext_used) - new_wire->port_output = true; + new_wire_port_output = true; if (flags.is_ext_driven && flags.is_int_used) - new_wire->port_input = true; + new_wire_port_input = true; if (flags.is_int_driven && flags.is_ext_driven) - new_wire->port_input = true, new_wire->port_output = true; + new_wire_port_input = true, new_wire_port_output = true; - if (new_wire->port_input || new_wire->port_output) { - new_wire->port_id = port_counter++; - while (new_wire->name[0] == '$') { - std::string new_wire_name = stringf("\\n%d", auto_name_counter++); - if (all_wire_names.count(new_wire_name) == 0) { - all_wire_names.insert(new_wire_name); - new_wire->name = new_wire_name; + std::string new_wire_name = wire->name; + if (new_wire_port_input || new_wire_port_output) { + while (new_wire_name[0] == '$') { + std::string next_wire_name = stringf("\\n%d", auto_name_counter++); + if (all_wire_names.count(next_wire_name) == 0) { + all_wire_names.insert(next_wire_name); + new_wire_name = next_wire_name; } } } + RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name, wire->width); + new_wire->port_input = new_wire_port_input; + new_wire->port_output = new_wire_port_output; + new_wire->start_offset = wire->start_offset; + new_wire->attributes = wire->attributes; + + if (new_wire->port_input || new_wire->port_output) + new_wire->port_id = port_counter++; + if (new_wire->port_input && new_wire->port_output) log(" signal %s: inout %s\n", wire->name.c_str(), new_wire->name.c_str()); else if (new_wire->port_input) @@ -157,7 +163,6 @@ struct SubmodWorker else log(" signal %s: internal\n", wire->name.c_str()); - new_mod->wires[new_wire->name] = new_wire; flags.new_wire = new_wire; } diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 999c969b..b63b3aec 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -118,18 +118,13 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) std::stringstream sstr; sstr << "$memory_dff_disconnected$" << (RTLIL::autoidx++); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = sstr.str(); - wire->width = sig.size(); - module->wires[wire->name] = wire; - - RTLIL::SigSpec newsig(wire); + RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); for (auto &cell_it : module->cells) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$dff") { RTLIL::SigSpec new_q = cell->get("\\Q"); - new_q.replace(sig, newsig); + new_q.replace(sig, new_sig); cell->set("\\Q", new_q); } } diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 5b180db6..32c7e63a 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -126,20 +126,17 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\CLK", RTLIL::SigSpec(RTLIL::State::S0)); } - RTLIL::Wire *w_in = new RTLIL::Wire; - w_in->name = genid(cell->name, "", i, "$d"); - w_in->width = mem_width; - module->wires[w_in->name] = w_in; + RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width); data_reg_in.push_back(RTLIL::SigSpec(w_in)); c->set("\\D", data_reg_in.back()); - RTLIL::Wire *w_out = new RTLIL::Wire; - w_out->name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); - if (module->wires.count(w_out->name) > 0) - w_out->name = genid(cell->name, "", i, "$q"); - w_out->width = mem_width; + std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); + if (module->wires.count(w_out_name) > 0) + w_out_name = genid(cell->name, "", i, "$q"); + + RTLIL::Wire *w_out = module->addWire(w_out_name, mem_width); w_out->start_offset = mem_offset; - module->wires[w_out->name] = w_out; + data_reg_out.push_back(RTLIL::SigSpec(w_out)); c->set("\\Q", data_reg_out.back()); } @@ -167,10 +164,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\D", rd_addr); count_dff++; - RTLIL::Wire *w = new RTLIL::Wire; - w->name = genid(cell->name, "$rdreg", i, "$q"); - w->width = mem_abits; - module->wires[w->name] = w; + RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits); c->set("\\Q", RTLIL::SigSpec(w)); rd_addr = RTLIL::SigSpec(w); @@ -184,10 +178,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\Q", rd_signals.back()); count_dff++; - RTLIL::Wire *w = new RTLIL::Wire; - w->name = genid(cell->name, "$rdreg", i, "$d"); - w->width = mem_width; - module->wires[w->name] = w; + RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width); rd_signals.clear(); rd_signals.push_back(RTLIL::SigSpec(w)); @@ -207,17 +198,8 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\S", rd_addr.extract(mem_abits-j-1, 1)); count_mux++; - RTLIL::Wire *w = new RTLIL::Wire; - w->name = genid(cell->name, "$rdmux", i, "", j, "", k, "$a"); - w->width = mem_width; - module->wires[w->name] = w; - c->set("\\A", RTLIL::SigSpec(w)); - - w = new RTLIL::Wire; - w->name = genid(cell->name, "$rdmux", i, "", j, "", k, "$b"); - w->width = mem_width; - module->wires[w->name] = w; - c->set("\\B", RTLIL::SigSpec(w)); + c->set("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width)); + c->set("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width)); next_rd_signals.push_back(c->get("\\A")); next_rd_signals.push_back(c->get("\\B")); @@ -255,9 +237,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\B", wr_addr); count_wrmux++; - RTLIL::Wire *w_seladdr = new RTLIL::Wire; - w_seladdr->name = genid(cell->name, "$wreq", i, "", j, "$y"); - module->wires[w_seladdr->name] = w_seladdr; + RTLIL::Wire *w_seladdr = module->addWire(genid(cell->name, "$wreq", i, "", j, "$y")); c->set("\\Y", w_seladdr); int wr_offset = 0; @@ -286,9 +266,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\A", w); c->set("\\B", wr_bit); - w = new RTLIL::Wire; - w->name = genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"); - module->wires[w->name] = w; + w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y")); c->set("\\Y", RTLIL::SigSpec(w)); } @@ -298,10 +276,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\B", wr_data.extract(wr_offset, wr_width)); c->set("\\S", RTLIL::SigSpec(w)); - w = new RTLIL::Wire; - w->name = genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"); - w->width = wr_width; - module->wires[w->name] = w; + w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); c->set("\\Y", w); sig.replace(wr_offset, w); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index e279c020..63d03b20 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -218,14 +218,14 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } } - std::vector del_wires; + std::vector maybe_del_wires; for (auto &it : module->wires) { RTLIL::Wire *wire = it.second; if ((!purge_mode && check_public_name(wire->name)) || wire->port_id != 0 || wire->get_bool_attribute("\\keep")) { RTLIL::SigSpec s1 = RTLIL::SigSpec(wire), s2 = s1; assign_map.apply(s2); if (!used_signals.check_any(s2) && wire->port_id == 0 && !wire->get_bool_attribute("\\keep")) { - del_wires.push_back(wire); + maybe_del_wires.push_back(wire); } else { assert(SIZE(s1) == SIZE(s2)); RTLIL::SigSig new_conn; @@ -242,7 +242,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } } else { if (!used_signals.check_any(RTLIL::SigSpec(wire))) - del_wires.push_back(wire); + maybe_del_wires.push_back(wire); } RTLIL::SigSpec sig = assign_map(RTLIL::SigSpec(wire)); if (!used_signals_nodrivers.check_any(sig)) { @@ -265,6 +265,9 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } } + + std::set del_wires; + int del_wires_count = 0; for (auto wire : del_wires) if (!used_signals.check_any(RTLIL::SigSpec(wire))) { @@ -272,11 +275,12 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool log(" removing unused non-port wire %s.\n", wire->name.c_str()); del_wires_count++; } - module->wires.erase(wire->name); - count_rm_wires++; - delete wire; + del_wires.insert(wire); } + module->remove(del_wires); + count_rm_wires += del_wires.size();; + if (del_wires_count > 0) log(" removed %d unused temporary wires.\n", del_wires_count); } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 30e7b748..67113a68 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -60,10 +60,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, std::stringstream sstr; sstr << "$procmux$" << (RTLIL::autoidx++); - RTLIL::Wire *cmp_wire = new RTLIL::Wire; - cmp_wire->name = sstr.str() + "_CMP"; - cmp_wire->width = 0; - mod->wires[cmp_wire->name] = cmp_wire; + RTLIL::Wire *cmp_wire = mod->addWire(sstr.str() + "_CMP", 0); for (auto comp : compare) { @@ -109,10 +106,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, } else { - ctrl_wire = new RTLIL::Wire; - ctrl_wire->name = sstr.str() + "_CTRL"; - ctrl_wire->width = 1; - mod->wires[ctrl_wire->name] = ctrl_wire; + ctrl_wire = mod->addWire(sstr.str() + "_CTRL"); // reduce cmp vector to one logic signal RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", "$reduce_or"); @@ -147,10 +141,7 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, assert(ctrl_sig.size() == 1); // prepare multiplexer output signal - RTLIL::Wire *result_wire = new RTLIL::Wire; - result_wire->name = sstr.str() + "_Y"; - result_wire->width = when_signal.size(); - mod->wires[result_wire->name] = result_wire; + RTLIL::Wire *result_wire = mod->addWire(sstr.str() + "_Y", when_signal.size()); // create the multiplexer itself RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), "$mux"); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 96aa10ba..0c5989b1 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -126,11 +126,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, if (w1->port_input) { - RTLIL::Wire *w2 = new RTLIL::Wire; - w2->name = "\\in_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w2 = miter_module->addWire("\\in_" + RTLIL::unescape_id(w1->name), w1->width); w2->port_input = true; - w2->width = w1->width; - miter_module->add(w2); gold_cell->set(w1->name, w2); gate_cell->set(w1->name, w2); @@ -138,17 +135,11 @@ static void create_miter_equiv(struct Pass *that, std::vector args, if (w1->port_output) { - RTLIL::Wire *w2_gold = new RTLIL::Wire; - w2_gold->name = "\\gold_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w2_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(w1->name), w1->width); w2_gold->port_output = flag_make_outputs; - w2_gold->width = w1->width; - miter_module->add(w2_gold); - RTLIL::Wire *w2_gate = new RTLIL::Wire; - w2_gate->name = "\\gate_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w2_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(w1->name), w1->width); w2_gate->port_output = flag_make_outputs; - w2_gate->width = w1->width; - miter_module->add(w2_gate); gold_cell->set(w1->name, w2_gold); gate_cell->set(w1->name, w2_gate); @@ -220,10 +211,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, if (flag_make_outcmp) { - RTLIL::Wire *w_cmp = new RTLIL::Wire; - w_cmp->name = "\\cmp_" + RTLIL::unescape_id(w1->name); + RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(w1->name)); w_cmp->port_output = true; - miter_module->add(w_cmp); miter_module->connect(RTLIL::SigSig(w_cmp, this_condition)); } @@ -247,10 +236,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, assert_cell->set("\\EN", RTLIL::SigSpec(1, 1)); } - RTLIL::Wire *w_trigger = new RTLIL::Wire; - w_trigger->name = "\\trigger"; + RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger"); w_trigger->port_output = true; - miter_module->add(w_trigger); RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, "$not"); not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); From d68c993ed2ea384db4d6af5161b3b36096828499 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 21:16:05 +0200 Subject: [PATCH 443/750] Changed more code to the new RTLIL::Wire constructors --- kernel/rtlil.cc | 14 +++++++++- kernel/rtlil.h | 16 ++++++----- passes/cmds/rename.cc | 14 +++------- passes/cmds/splice.cc | 10 +++---- passes/sat/expose.cc | 55 +++++++++----------------------------- passes/techmap/extract.cc | 5 +--- passes/techmap/iopadmap.cc | 9 ++----- passes/techmap/techmap.cc | 10 +++---- 8 files changed, 52 insertions(+), 81 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 930e8a71..240bbc6b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -777,7 +777,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const new_mod->attributes = attributes; for (auto &it : wires) - new_mod->wires[it.first] = new RTLIL::Wire(*it.second); + new_mod->addWire(it.first, it.second); for (auto &it : memories) new_mod->memories[it.first] = new RTLIL::Memory(*it.second); @@ -952,6 +952,18 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width) return wire; } +RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *other) +{ + RTLIL::Wire *wire = addWire(name); + wire->width = other->width; + wire->start_offset = other->start_offset; + wire->port_id = other->port_id; + wire->port_input = other->port_input; + wire->port_output = other->port_output; + wire->attributes = other->attributes; + return wire; +} + RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) { RTLIL::Cell *cell = new RTLIL::Cell; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f43e7b67..cbb61247 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -273,6 +273,11 @@ struct RTLIL::Design { struct RTLIL::Module { +protected: + void add(RTLIL::Wire *wire); + void add(RTLIL::Cell *cell); + +public: RTLIL::IdString name; std::set avail_parameters; std::map wires; @@ -297,9 +302,6 @@ struct RTLIL::Module void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; - void add(RTLIL::Wire *wire); - void add(RTLIL::Cell *cell); - // Removing wires is expensive. If you have to remove wires, remove them all at once. void remove(const std::set &wires); void remove(RTLIL::Cell *cell); @@ -309,6 +311,8 @@ struct RTLIL::Module void rename(RTLIL::IdString old_name, RTLIL::IdString new_name); RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); + RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other); + RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); @@ -445,7 +449,7 @@ struct RTLIL::Module struct RTLIL::Wire { -//protected: +protected: // use module->addWire() and module->remove() to create or destroy wires friend struct RTLIL::Module; Wire(); @@ -453,8 +457,8 @@ struct RTLIL::Wire public: // do not simply copy wires - //Wire(RTLIL::Wire &other) = delete; - //void operator=(RTLIL::Wire &other) = delete; + Wire(RTLIL::Wire &other) = delete; + void operator=(RTLIL::Wire &other) = delete; RTLIL::IdString name; int width, start_offset, port_id; diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 519dce45..721d5c98 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -31,21 +31,15 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: for (auto &it : module->wires) if (it.first == from_name) { - RTLIL::Wire *wire = it.second; - log("Renaming wire %s to %s in module %s.\n", wire->name.c_str(), to_name.c_str(), module->name.c_str()); - module->wires.erase(wire->name); - wire->name = to_name; - module->add(wire); + log("Renaming wire %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module)); + module->rename(it.second, to_name); return; } for (auto &it : module->cells) if (it.first == from_name) { - RTLIL::Cell *cell = it.second; - log("Renaming cell %s to %s in module %s.\n", cell->name.c_str(), to_name.c_str(), module->name.c_str()); - module->cells.erase(cell->name); - cell->name = to_name; - module->add(cell); + log("Renaming cell %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module)); + module->rename(it.second, to_name); return; } diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 8b7e0406..61de4406 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -224,14 +224,14 @@ struct SpliceWorker for (auto &it : rework_wires) { - module->wires.erase(it.first->name); - RTLIL::Wire *new_port = new RTLIL::Wire(*it.first); - it.first->name = NEW_ID; + std::string orig_name = it.first->name; + module->rename(it.first, NEW_ID); + + RTLIL::Wire *new_port = module->addWire(orig_name, it.first); it.first->port_id = 0; it.first->port_input = false; it.first->port_output = false; - module->add(it.first); - module->add(new_port); + module->connect(RTLIL::SigSig(new_port, it.second)); } } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 9ce3b43d..21af63a3 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -208,11 +208,11 @@ static void create_dff_dq_map(std::map &map, RTLIL: } } -static void add_new_wire(RTLIL::Module *module, RTLIL::Wire *wire) +static RTLIL::Wire *add_new_wire(RTLIL::Module *module, std::string name, int width = 1) { - if (module->count_id(wire->name)) - log_error("Attempting to create wire %s, but a wire of this name exists already! Hint: Try another value for -sep.\n", RTLIL::id2cstr(wire->name)); - module->add(wire); + if (module->count_id(name)) + log_error("Attempting to create wire %s, but a wire of this name exists already! Hint: Try another value for -sep.\n", log_id(name)); + return module->addWire(name, width); } struct ExposePass : public Pass { @@ -448,7 +448,6 @@ struct ExposePass : public Pass { SigMap sigmap(module); SigMap out_to_in_map; - std::vector new_wires; for (auto &it : module->wires) { @@ -468,20 +467,14 @@ struct ExposePass : public Pass { } if (flag_cut) { - RTLIL::Wire *in_wire = new RTLIL::Wire; - in_wire->name = it.second->name + sep + "i"; - in_wire->width = it.second->width; + RTLIL::Wire *in_wire = add_new_wire(module, it.second->name + sep + "i", it.second->width); in_wire->port_input = true; out_to_in_map.add(sigmap(it.second), in_wire); - new_wires.push_back(in_wire); } } if (flag_cut) { - for (auto it : new_wires) - add_new_wire(module, it); - for (auto &it : module->cells) { if (!ct.cell_known(it.second->type)) continue; @@ -507,10 +500,7 @@ struct ExposePass : public Pass { dff_map_info_t &info = dq.second; - RTLIL::Wire *wire_dummy_q = new RTLIL::Wire; - wire_dummy_q->name = NEW_ID; - wire_dummy_q->width = 0; - add_new_wire(module, wire_dummy_q); + RTLIL::Wire *wire_dummy_q = add_new_wire(module, NEW_ID, 0); for (auto &cell_name : info.cells) { RTLIL::Cell *cell = module->cells.at(cell_name); @@ -521,12 +511,9 @@ struct ExposePass : public Pass { cell->set("\\Q", cell_q_bits); } - RTLIL::Wire *wire_q = new RTLIL::Wire; - wire_q->name = wire->name + sep + "q"; - wire_q->width = wire->width; + RTLIL::Wire *wire_q = add_new_wire(module, wire->name + sep + "q", wire->width); wire_q->port_input = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_q->name)); - add_new_wire(module, wire_q); RTLIL::SigSig connect_q; for (size_t i = 0; i < wire_bits_vec.size(); i++) { @@ -538,19 +525,14 @@ struct ExposePass : public Pass { } module->connect(connect_q); - RTLIL::Wire *wire_d = new RTLIL::Wire; - wire_d->name = wire->name + sep + "d"; - wire_d->width = wire->width; + RTLIL::Wire *wire_d = add_new_wire(module, wire->name + sep + "d", wire->width); wire_d->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_d->name)); - add_new_wire(module, wire_d); module->connect(RTLIL::SigSig(wire_d, info.sig_d)); - RTLIL::Wire *wire_c = new RTLIL::Wire; - wire_c->name = wire->name + sep + "c"; + RTLIL::Wire *wire_c = add_new_wire(module, wire->name + sep + "c"); wire_c->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_c->name)); - add_new_wire(module, wire_c); if (info.clk_polarity) { module->connect(RTLIL::SigSig(wire_c, info.sig_clk)); } else { @@ -564,11 +546,9 @@ struct ExposePass : public Pass { if (info.sig_arst != RTLIL::State::Sm) { - RTLIL::Wire *wire_r = new RTLIL::Wire; - wire_r->name = wire->name + sep + "r"; + RTLIL::Wire *wire_r = add_new_wire(module, wire->name + sep + "r"); wire_r->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_r->name)); - add_new_wire(module, wire_r); if (info.arst_polarity) { module->connect(RTLIL::SigSig(wire_r, info.sig_arst)); } else { @@ -580,12 +560,9 @@ struct ExposePass : public Pass { c->set("\\Y", wire_r); } - RTLIL::Wire *wire_v = new RTLIL::Wire; - wire_v->name = wire->name + sep + "v"; - wire_v->width = wire->width; + RTLIL::Wire *wire_v = add_new_wire(module, wire->name + sep + "v", wire->width); wire_v->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_v->name)); - add_new_wire(module, wire_v); module->connect(RTLIL::SigSig(wire_v, info.arst_value)); } } @@ -616,14 +593,11 @@ struct ExposePass : public Pass { if (!p->port_input && !p->port_output) continue; - RTLIL::Wire *w = new RTLIL::Wire; - w->name = cell->name + sep + RTLIL::unescape_id(p->name); - w->width = p->width; + RTLIL::Wire *w = add_new_wire(module, cell->name + sep + RTLIL::unescape_id(p->name), p->width); if (p->port_input) w->port_output = true; if (p->port_output) w->port_input = true; - add_new_wire(module, w); log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); @@ -641,14 +615,11 @@ struct ExposePass : public Pass { { for (auto &it : cell->connections()) { - RTLIL::Wire *w = new RTLIL::Wire; - w->name = cell->name + sep + RTLIL::unescape_id(it.first); - w->width = it.second.size(); + RTLIL::Wire *w = add_new_wire(module, cell->name + sep + RTLIL::unescape_id(it.first), it.second.size()); if (ct.cell_input(cell->type, it.first)) w->port_output = true; if (ct.cell_output(cell->type, it.first)) w->port_input = true; - add_new_wire(module, w); log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index b8c349f5..92bcafc0 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -729,13 +729,10 @@ struct ExtractPass : public Pass { int portCounter = 1; for (auto wire : wires) { - RTLIL::Wire *newWire = new RTLIL::Wire; - newWire->name = wire->name; - newWire->width = wire->width; + RTLIL::Wire *newWire = newMod->addWire(wire->name, wire->width); newWire->port_id = portCounter++; newWire->port_input = true; newWire->port_output = true; - newMod->add(newWire); } for (auto cell : cells) { diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 114d28e2..ab3bb3ed 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -164,13 +164,8 @@ struct IopadmapPass : public Pass { log("Mapping port %s.%s using %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name), celltype.c_str()); RTLIL::Wire *new_wire = NULL; - if (!portname2.empty()) { - new_wire = new RTLIL::Wire; - *new_wire = *wire; - wire->name = NEW_ID; - module->wires[wire->name] = wire; - module->wires[new_wire->name] = new_wire; - } + if (!portname2.empty()) + new_wire = module->addWire(NEW_ID, wire); if (flag_bits) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 9dcd6a45..bee1df40 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -128,14 +128,14 @@ struct TechmapWorker for (auto &it : tpl->wires) { if (it.second->port_id > 0) positional_ports[stringf("$%d", it.second->port_id)] = it.first; - RTLIL::Wire *w = new RTLIL::Wire(*it.second); - apply_prefix(cell->name, w->name); + std::string w_name = it.second->name; + apply_prefix(cell->name, w_name); + RTLIL::Wire *w = module->addWire(w_name, it.second); w->port_input = false; w->port_output = false; w->port_id = 0; if (it.second->get_bool_attribute("\\_techmap_special_")) w->attributes.clear(); - module->add(w); design->select(module, w); } @@ -381,7 +381,6 @@ struct TechmapWorker log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(data.wire->name), log_signal(data.value)); techmap_wire_names.erase(it.first); - tpl->wires.erase(data.wire->name); const char *p = data.wire->name.c_str(); const char *q = strrchr(p+1, '.'); @@ -391,8 +390,7 @@ struct TechmapWorker std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12); while (tpl->wires.count(new_name)) new_name += "_"; - data.wire->name = new_name; - tpl->add(data.wire); + tpl->rename(data.wire, new_name); std::string cmd_string = data.value.as_const().decode_string(); Pass::call_on_module(map, tpl, cmd_string); From d7916a49aff3c47b7c1ce07abe3b6e3d5714079b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 21:34:19 +0200 Subject: [PATCH 444/750] New message for completion of build --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6809ffd0..462861c8 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,7 @@ endif top-all: $(TARGETS) $(EXTRA_TARGETS) @echo "" - @echo " It's a Yosys." + @echo " Build successful." @echo "" yosys: $(OBJS) From f9946232adf887e5aa4a48c64f88eaa17e424009 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 01:49:51 +0200 Subject: [PATCH 445/750] Refactoring: Renamed RTLIL::Module::wires to wires_ --- backends/autotest/autotest.cc | 4 +-- backends/blif/blif.cc | 2 +- backends/btor/btor.cc | 4 +-- backends/edif/edif.cc | 2 +- backends/ilang/ilang_backend.cc | 2 +- backends/intersynth/intersynth.cc | 2 +- backends/spice/spice.cc | 4 +-- backends/verilog/verilog_backend.cc | 8 ++--- frontends/ast/genrtlil.cc | 10 +++--- frontends/liberty/liberty.cc | 6 ++-- kernel/celltypes.h | 8 ++--- kernel/driver.cc | 2 +- kernel/modwalker.h | 2 +- kernel/rtlil.cc | 40 +++++++++++----------- kernel/rtlil.h | 2 +- manual/CHAPTER_Prog/stubnets.cc | 2 +- manual/PRESENTATION_Prog/my_cmd.cc | 6 ++-- passes/abc/abc.cc | 52 ++++++++++++++--------------- passes/abc/blifparse.cc | 16 ++++----- passes/cmds/add.cc | 6 ++-- passes/cmds/delete.cc | 4 +-- passes/cmds/rename.cc | 10 +++--- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 32 +++++++++--------- passes/cmds/setattr.cc | 2 +- passes/cmds/setundef.cc | 2 +- passes/cmds/show.cc | 2 +- passes/cmds/splice.cc | 6 ++-- passes/cmds/splitnets.cc | 2 +- passes/cmds/stat.cc | 2 +- passes/fsm/fsm_detect.cc | 4 +-- passes/fsm/fsm_extract.cc | 6 ++-- passes/hierarchy/hierarchy.cc | 8 ++--- passes/hierarchy/submod.cc | 2 +- passes/memory/memory_map.cc | 2 +- passes/memory/memory_share.cc | 2 +- passes/opt/opt_clean.cc | 10 +++--- passes/opt/opt_const.cc | 2 +- passes/opt/opt_muxtree.cc | 2 +- passes/opt/opt_rmdff.cc | 2 +- passes/opt/opt_share.cc | 2 +- passes/proc/proc_arst.cc | 4 +-- passes/sat/eval.cc | 22 ++++++------ passes/sat/expose.cc | 22 ++++++------ passes/sat/freduce.cc | 2 +- passes/sat/miter.cc | 14 ++++---- passes/sat/sat.cc | 8 ++--- passes/techmap/extract.cc | 6 ++-- passes/techmap/iopadmap.cc | 2 +- passes/techmap/techmap.cc | 16 ++++----- 50 files changed, 191 insertions(+), 191 deletions(-) diff --git a/backends/autotest/autotest.cc b/backends/autotest/autotest.cc index db49880a..06b2c2a9 100644 --- a/backends/autotest/autotest.cc +++ b/backends/autotest/autotest.cc @@ -105,7 +105,7 @@ static void autotest(FILE *f, RTLIL::Design *design) int count_ports = 0; log("Generating test bench for module `%s'.\n", it->first.c_str()); - for (auto it2 = mod->wires.begin(); it2 != mod->wires.end(); it2++) { + for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); it2++) { RTLIL::Wire *wire = it2->second; if (wire->port_output) { count_ports++; @@ -134,7 +134,7 @@ static void autotest(FILE *f, RTLIL::Design *design) } } fprintf(f, "%s %s(\n", id(mod->name).c_str(), idy("uut", mod->name).c_str()); - for (auto it2 = mod->wires.begin(); it2 != mod->wires.end(); it2++) { + for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); it2++) { RTLIL::Wire *wire = it2->second; if (wire->port_output || wire->port_input) fprintf(f, "\t.%s(%s)%s\n", id(wire->name).c_str(), diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index cb40834b..7ae9965d 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -103,7 +103,7 @@ struct BlifDumper std::map inputs, outputs; - for (auto &wire_it : module->wires) { + for (auto &wire_it : module->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_input) inputs[wire->port_id] = wire; diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index f731e17e..f1e95ee1 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -80,7 +80,7 @@ struct BtorDumper { line_num=0; str.clear(); - for(auto it=module->wires.begin(); it!=module->wires.end(); ++it) + for(auto it=module->wires_.begin(); it!=module->wires_.end(); ++it) { if(it->second->port_input) { @@ -880,7 +880,7 @@ struct BtorDumper std::map inputs, outputs; std::vector safety; - for (auto &wire_it : module->wires) { + for (auto &wire_it : module->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_input) inputs[wire->port_id] = wire; diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index fc2f4a7e..e99d094f 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -255,7 +255,7 @@ struct EdifBackend : public Backend { fprintf(f, " (view VIEW_NETLIST\n"); fprintf(f, " (viewType NETLIST)\n"); fprintf(f, " (interface\n"); - for (auto &wire_it : module->wires) { + for (auto &wire_it : module->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_id == 0) continue; diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index 6678f19d..c0b7dab9 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -280,7 +280,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module if (print_body) { - for (auto it = module->wires.begin(); it != module->wires.end(); it++) + for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) if (!only_selected || design->selected(module, it->second)) { if (only_selected) fprintf(f, "\n"); diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 8c08747c..4e8c321b 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -147,7 +147,7 @@ struct IntersynthBackend : public Backend { netlists_code += stringf("netlist %s\n", RTLIL::id2cstr(module->name)); // Module Ports: "std::set celltypes_code" prevents duplicate top level ports - for (auto wire_it : module->wires) { + for (auto wire_it : module->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_input || wire->port_output) { celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n", diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 07736877..ef31e06a 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -68,7 +68,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de RTLIL::Module *mod = design->modules.at(cell->type); std::vector ports; - for (auto wire_it : mod->wires) { + for (auto wire_it : mod->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_id == 0) continue; @@ -195,7 +195,7 @@ struct SpiceBackend : public Backend { } std::vector ports; - for (auto wire_it : module->wires) { + for (auto wire_it : module->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_id == 0) continue; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index d9186c04..5e98a4c5 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -76,7 +76,7 @@ void reset_auto_counter(RTLIL::Module *module) reset_auto_counter_id(module->name, false); - for (auto it = module->wires.begin(); it != module->wires.end(); it++) + for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) reset_auto_counter_id(it->second->name, true); for (auto it = module->cells.begin(); it != module->cells.end(); it++) { @@ -920,7 +920,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) reg_bits.insert(std::pair(chunk.wire, chunk.offset+i)); } } - for (auto &it : module->wires) + for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) @@ -936,7 +936,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) bool keep_running = true; for (int port_id = 1; keep_running; port_id++) { keep_running = false; - for (auto it = module->wires.begin(); it != module->wires.end(); it++) { + for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) { RTLIL::Wire *wire = it->second; if (wire->port_id == port_id) { if (port_id != 1) @@ -949,7 +949,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) } fprintf(f, ");\n"); - for (auto it = module->wires.begin(); it != module->wires.end(); it++) + for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) dump_wire(f, indent + " ", it->second); for (auto it = module->memories.begin(); it != module->memories.end(); it++) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3bc9b06e..064aec93 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 d7068d46..c476de87 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; diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 76914583..d3c848f4 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -181,8 +181,8 @@ struct CellTypes if (cell_types.count(type) == 0) { for (auto design : designs) if (design->modules.count(type) > 0) { - if (design->modules.at(type)->wires.count(port)) - return design->modules.at(type)->wires.at(port)->port_output; + if (design->modules.at(type)->wires_.count(port)) + return design->modules.at(type)->wires_.at(port)->port_output; return false; } return false; @@ -204,8 +204,8 @@ struct CellTypes if (cell_types.count(type) == 0) { for (auto design : designs) if (design->modules.count(type) > 0) { - if (design->modules.at(type)->wires.count(port)) - return design->modules.at(type)->wires.at(port)->port_input; + if (design->modules.at(type)->wires_.count(port)) + return design->modules.at(type)->wires_.at(port)->port_input; return false; } return false; diff --git a/kernel/driver.cc b/kernel/driver.cc index 97910aa9..3fbb9658 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -243,7 +243,7 @@ static char *readline_obj_generator(const char *text, int state) { RTLIL::Module *module = design->modules.at(design->selected_active_module); - for (auto &it : module->wires) + for (auto &it : module->wires_) if (RTLIL::unescape_id(it.first).substr(0, len) == text) obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); diff --git a/kernel/modwalker.h b/kernel/modwalker.h index a3983a2c..a90d739e 100644 --- a/kernel/modwalker.h +++ b/kernel/modwalker.h @@ -121,7 +121,7 @@ struct ModWalker signal_inputs.clear(); signal_outputs.clear(); - for (auto &it : module->wires) + for (auto &it : module->wires_) add_wire(it.second); for (auto &it : module->cells) if (filter_ct == NULL || filter_ct->cell_known(it.second->type)) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 240bbc6b..0cfcf018 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -203,7 +203,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) if (it.second.size() == 0) del_list.push_back(it.first); - else if (it.second.size() == design->modules[it.first]->wires.size() + design->modules[it.first]->memories.size() + + else if (it.second.size() == design->modules[it.first]->wires_.size() + design->modules[it.first]->memories.size() + design->modules[it.first]->cells.size() + design->modules[it.first]->processes.size()) add_list.push_back(it.first); for (auto mod_name : del_list) @@ -276,7 +276,7 @@ bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString me RTLIL::Module::~Module() { - for (auto it = wires.begin(); it != wires.end(); it++) + for (auto it = wires_.begin(); it != wires_.end(); it++) delete it->second; for (auto it = memories.begin(); it != memories.end(); it++) delete it->second; @@ -293,7 +293,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::mapname); assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); assert(it.second->width >= 0); @@ -776,7 +776,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const new_mod->connections_ = connections_; new_mod->attributes = attributes; - for (auto &it : wires) + for (auto &it : wires_) new_mod->addWire(it.first, it.second); for (auto &it : memories) @@ -796,7 +796,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const std::vector chunks = sig.chunks(); for (auto &c : chunks) if (c.wire != NULL) - c.wire = mod->wires.at(c.wire->name); + c.wire = mod->wires_.at(c.wire->name); sig = chunks; } }; @@ -817,7 +817,7 @@ void RTLIL::Module::add(RTLIL::Wire *wire) { assert(!wire->name.empty()); assert(count_id(wire->name) == 0); - wires[wire->name] = wire; + wires_[wire->name] = wire; } void RTLIL::Module::add(RTLIL::Cell *cell) @@ -848,9 +848,9 @@ namespace { #if 0 void RTLIL::Module::remove(RTLIL::Wire *wire) { - std::set wires; - wires.insert(wire); - remove(wires); + std::set wires_; + wires_.insert(wire); + remove(wires_); } #endif @@ -862,7 +862,7 @@ void RTLIL::Module::remove(const std::set &wires) rewrite_sigspecs(delete_wire_worker); for (auto &it : wires) { - this->wires.erase(it->name); + this->wires_.erase(it->name); delete it; } } @@ -876,8 +876,8 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) { - assert(wires[wire->name] == wire); - wires.erase(wire->name); + assert(wires_[wire->name] == wire); + wires_.erase(wire->name); wire->name = new_name; add(wire); } @@ -893,8 +893,8 @@ void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name) void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name) { assert(count_id(old_name) != 0); - if (wires.count(old_name)) - rename(wires.at(old_name), new_name); + if (wires_.count(old_name)) + rename(wires_.at(old_name), new_name); else if (cells.count(old_name)) rename(cells.at(old_name), new_name); else @@ -932,7 +932,7 @@ void RTLIL::Module::fixup_ports() { std::vector all_ports; - for (auto &w : wires) + for (auto &w : wires_) if (w.second->port_input || w.second->port_output) all_ports.push_back(w.second); else @@ -2457,7 +2457,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri if (netname[0] != '$' && netname[0] != '\\') netname = "\\" + netname; - if (module->wires.count(netname) == 0) { + if (module->wires_.count(netname) == 0) { size_t indices_pos = netname.size()-1; if (indices_pos > 2 && netname[indices_pos] == ']') { @@ -2474,10 +2474,10 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri } } - if (module->wires.count(netname) == 0) + if (module->wires_.count(netname) == 0) return false; - RTLIL::Wire *wire = module->wires.at(netname); + RTLIL::Wire *wire = module->wires_.at(netname); if (!indices.empty()) { std::vector index_tokens; sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':'); @@ -2514,7 +2514,7 @@ bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL sig = RTLIL::SigSpec(); RTLIL::Selection &sel = design->selection_vars.at(str); - for (auto &it : module->wires) + for (auto &it : module->wires_) if (sel.selected_member(module->name, it.first)) sig.append(it.second); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index cbb61247..1d040975 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -280,7 +280,7 @@ protected: public: RTLIL::IdString name; std::set avail_parameters; - std::map wires; + std::map wires_; std::map memories; std::map cells; std::map processes; diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index f67ffe1e..9eacfbcb 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -43,7 +43,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re } // for each wire in the module - for (auto &wire_iter : module->wires) + for (auto &wire_iter : module->wires_) { RTLIL::Wire *wire = wire_iter.second; diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/manual/PRESENTATION_Prog/my_cmd.cc index cf8a4add..0cd1da80 100644 --- a/manual/PRESENTATION_Prog/my_cmd.cc +++ b/manual/PRESENTATION_Prog/my_cmd.cc @@ -14,7 +14,7 @@ struct MyPass : public Pass { log("Modules in current design:\n"); for (auto &mod : design->modules) log(" %s (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), - mod.second->wires.size(), mod.second->cells.size()); + mod.second->wires_.size(), mod.second->cells.size()); } } MyPass; @@ -58,8 +58,8 @@ struct Test2Pass : public Pass { RTLIL::Module *module = design->modules.at("\\test"); - RTLIL::SigSpec a(module->wires.at("\\a")), x(module->wires.at("\\x")), - y(module->wires.at("\\y")); + RTLIL::SigSpec a(module->wires_.at("\\a")), x(module->wires_.at("\\x")), + y(module->wires_.at("\\y")); log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" SigMap sigmap(module); diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 41cfe88f..184f143a 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -453,8 +453,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std clk_polarity = false; clk_str = clk_str.substr(1); } - if (module->wires.count(RTLIL::escape_id(clk_str)) != 0) - clk_sig = assign_map(RTLIL::SigSpec(module->wires.at(RTLIL::escape_id(clk_str)), 0)); + if (module->wires_.count(RTLIL::escape_id(clk_str)) != 0) + clk_sig = assign_map(RTLIL::SigSpec(module->wires_.at(RTLIL::escape_id(clk_str)), 0)); } if (dff_mode && clk_sig.size() == 0) @@ -495,7 +495,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std for (auto c : cells) extract_cell(c, keepff); - for (auto &wire_it : module->wires) { + for (auto &wire_it : module->wires_) { if (wire_it.second->port_id > 0 || wire_it.second->get_bool_attribute("\\keep")) mark_port(RTLIL::SigSpec(wire_it.second)); } @@ -687,7 +687,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::Module *mapped_mod = mapped_design->modules["\\netlist"]; if (mapped_mod == NULL) log_error("ABC output file does not contain a module `netlist'.\n"); - for (auto &it : mapped_mod->wires) { + for (auto &it : mapped_mod->wires_) { RTLIL::Wire *w = it.second; RTLIL::Wire *wire = module->addWire(remap_name(w->name)); design->select(module, wire); @@ -701,47 +701,47 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); module->connect(conn); continue; } if (c->type == "\\BUF") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)]); - conn.second = RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)]); module->connect(conn); continue; } if (c->type == "\\INV") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_INV_"); - cell->set("\\A", RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)])); - cell->set("\\Y", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)])); + cell->set("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)])); + cell->set("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); - cell->set("\\A", RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)])); - cell->set("\\B", RTLIL::SigSpec(module->wires[remap_name(c->get("\\B").as_wire()->name)])); - cell->set("\\Y", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)])); + cell->set("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)])); + cell->set("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\B").as_wire()->name)])); + cell->set("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\MUX") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_"); - cell->set("\\A", RTLIL::SigSpec(module->wires[remap_name(c->get("\\A").as_wire()->name)])); - cell->set("\\B", RTLIL::SigSpec(module->wires[remap_name(c->get("\\B").as_wire()->name)])); - cell->set("\\S", RTLIL::SigSpec(module->wires[remap_name(c->get("\\S").as_wire()->name)])); - cell->set("\\Y", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Y").as_wire()->name)])); + cell->set("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)])); + cell->set("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\B").as_wire()->name)])); + cell->set("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\S").as_wire()->name)])); + cell->set("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\DFF") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->set("\\D", RTLIL::SigSpec(module->wires[remap_name(c->get("\\D").as_wire()->name)])); - cell->set("\\Q", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Q").as_wire()->name)])); + cell->set("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\D").as_wire()->name)])); + cell->set("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Q").as_wire()->name)])); cell->set("\\C", clk_sig); design->select(module, cell); continue; @@ -757,7 +757,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\_const0_" || c->type == "\\_const1_") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires[remap_name(c->connections().begin()->second.as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->connections().begin()->second.as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\_const0_" ? 0 : 1, 1); module->connect(conn); continue; @@ -765,8 +765,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std if (c->type == "\\_dff_") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->set("\\D", RTLIL::SigSpec(module->wires[remap_name(c->get("\\D").as_wire()->name)])); - cell->set("\\Q", RTLIL::SigSpec(module->wires[remap_name(c->get("\\Q").as_wire()->name)])); + cell->set("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\D").as_wire()->name)])); + cell->set("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Q").as_wire()->name)])); cell->set("\\C", clk_sig); design->select(module, cell); continue; @@ -779,7 +779,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std if (c.width == 0) continue; assert(c.width == 1); - newsig.append(module->wires[remap_name(c.wire->name)]); + newsig.append(module->wires_[remap_name(c.wire->name)]); } cell->set(conn.first, newsig); } @@ -789,9 +789,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std for (auto conn : mapped_mod->connections()) { if (!conn.first.is_fully_const()) - conn.first = RTLIL::SigSpec(module->wires[remap_name(conn.first.as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(conn.first.as_wire()->name)]); if (!conn.second.is_fully_const()) - conn.second = RTLIL::SigSpec(module->wires[remap_name(conn.second.as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires_[remap_name(conn.second.as_wire()->name)]); module->connect(conn); } @@ -805,10 +805,10 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std RTLIL::SigSig conn; if (si.type >= 0) { conn.first = si.bit; - conn.second = RTLIL::SigSpec(module->wires[remap_name(buffer)]); + conn.second = RTLIL::SigSpec(module->wires_[remap_name(buffer)]); out_wires++; } else { - conn.first = RTLIL::SigSpec(module->wires[remap_name(buffer)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(buffer)]); conn.second = si.bit; in_wires++; } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index e86afa1b..773bbe5d 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -113,15 +113,15 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) char *d = strtok(NULL, " \t\r\n"); char *q = strtok(NULL, " \t\r\n"); - if (module->wires.count(RTLIL::escape_id(d)) == 0) + if (module->wires_.count(RTLIL::escape_id(d)) == 0) module->addWire(RTLIL::escape_id(d)); - if (module->wires.count(RTLIL::escape_id(q)) == 0) + if (module->wires_.count(RTLIL::escape_id(q)) == 0) module->addWire(RTLIL::escape_id(q)); RTLIL::Cell *cell = module->addCell(NEW_ID, dff_name); - cell->set("\\D", module->wires.at(RTLIL::escape_id(d))); - cell->set("\\Q", module->wires.at(RTLIL::escape_id(q))); + cell->set("\\D", module->wires_.at(RTLIL::escape_id(d))); + cell->set("\\Q", module->wires_.at(RTLIL::escape_id(q))); continue; } @@ -138,9 +138,9 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) if (q == NULL || !q[0] || !q[1]) goto error; *(q++) = 0; - if (module->wires.count(RTLIL::escape_id(q)) == 0) + if (module->wires_.count(RTLIL::escape_id(q)) == 0) module->addWire(RTLIL::escape_id(q)); - cell->set(RTLIL::escape_id(p), module->wires.at(RTLIL::escape_id(q))); + cell->set(RTLIL::escape_id(p), module->wires_.at(RTLIL::escape_id(q))); } continue; } @@ -151,8 +151,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) RTLIL::SigSpec input_sig, output_sig; while ((p = strtok(NULL, " \t\r\n")) != NULL) { RTLIL::Wire *wire; - if (module->wires.count(stringf("\\%s", p)) > 0) { - wire = module->wires.at(stringf("\\%s", p)); + if (module->wires_.count(stringf("\\%s", p)) > 0) { + wire = module->wires_.at(stringf("\\%s", p)); } else { wire = module->addWire(stringf("\\%s", p)); } diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 7e9ba97e..e97bf8fc 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -28,8 +28,8 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n if (module->count_id(name) != 0) { - if (module->wires.count(name) > 0) - wire = module->wires.at(name); + if (module->wires_.count(name) > 0) + wire = module->wires_.at(name); if (wire != NULL && wire->width != width) wire = NULL; @@ -52,7 +52,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n wire->port_output = flag_output; if (flag_input || flag_output) { - wire->port_id = module->wires.size(); + wire->port_id = module->wires_.size(); module->fixup_ports(); } diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index df5a3d4b..460dd966 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -79,7 +79,7 @@ struct DeletePass : public Pass { RTLIL::Module *module = mod_it.second; if (flag_input || flag_output) { - for (auto &it : module->wires) + for (auto &it : module->wires_) if (design->selected(module, it.second)) { if (flag_input) it.second->port_input = false; @@ -95,7 +95,7 @@ struct DeletePass : public Pass { std::set delete_procs; std::set delete_mems; - for (auto &it : module->wires) + for (auto &it : module->wires_) if (design->selected(module, it.second)) delete_wires.insert(it.second); diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 721d5c98..e163e724 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -29,7 +29,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: if (module->count_id(to_name)) log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name.c_str(), module->name.c_str()); - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.first == from_name) { log("Renaming wire %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module)); module->rename(it.second, to_name); @@ -105,13 +105,13 @@ struct RenamePass : public Pass { continue; std::map new_wires; - for (auto &it : module->wires) { + for (auto &it : module->wires_) { if (it.first[0] == '$' && design->selected(module, it.second)) do it.second->name = stringf("\\_%d_", counter++); while (module->count_id(it.second->name) > 0); new_wires[it.second->name] = it.second; } - module->wires.swap(new_wires); + module->wires_.swap(new_wires); std::map new_cells; for (auto &it : module->cells) { @@ -135,13 +135,13 @@ struct RenamePass : public Pass { continue; std::map new_wires; - for (auto &it : module->wires) { + for (auto &it : module->wires_) { if (design->selected(module, it.second)) if (it.first[0] == '\\' && it.second->port_id == 0) it.second->name = NEW_ID; new_wires[it.second->name] = it.second; } - module->wires.swap(new_wires); + module->wires_.swap(new_wires); std::map new_cells; for (auto &it : module->cells) { diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 3380a935..7e2b2fc9 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -114,7 +114,7 @@ struct SccWorker SigPool selectedSignals; SigSet sigToNextCells; - for (auto &it : module->wires) + for (auto &it : module->wires_) if (design->selected(module, it.second)) selectedSignals.add(sigmap(RTLIL::SigSpec(it.second))); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index e0f1a6d6..0cabdc06 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -161,7 +161,7 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) } RTLIL::Module *mod = mod_it.second; - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (!lhs.selected_member(mod_it.first, it.first)) new_sel.selected_members[mod->name].insert(it.first); for (auto &it : mod->memories) @@ -215,11 +215,11 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) SigMap sigmap(mod_it.second); SigPool selected_bits; - for (auto &it : mod_it.second->wires) + for (auto &it : mod_it.second->wires_) if (lhs.selected_member(mod_it.first, it.first)) selected_bits.add(sigmap(it.second)); - for (auto &it : mod_it.second->wires) + for (auto &it : mod_it.second->wires_) if (!lhs.selected_member(mod_it.first, it.first) && selected_bits.check_any(sigmap(it.second))) lhs.selected_members[mod_it.first].insert(it.first); } @@ -278,7 +278,7 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R if (lhs.selected_modules.count(mod->name) > 0) { - for (auto &it : mod->wires) + for (auto &it : mod->wires_) lhs.selected_members[mod->name].insert(it.first); for (auto &it : mod->memories) lhs.selected_members[mod->name].insert(it.first); @@ -376,7 +376,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v RTLIL::Module *mod = mod_it.second; std::set selected_wires; - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0) selected_wires.insert(it.second); @@ -700,22 +700,22 @@ static void select_stmt(RTLIL::Design *design, std::string arg) RTLIL::Module *mod = mod_it.second; if (arg_memb.substr(0, 2) == "w:") { - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.substr(0, 2) == "i:") { - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (it.second->port_input && match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.substr(0, 2) == "o:") { - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (it.second->port_output && match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.substr(0, 2) == "x:") { - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else @@ -723,7 +723,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) size_t delim = arg_memb.substr(2).find(':'); if (delim == std::string::npos) { int width = atoi(arg_memb.substr(2).c_str()); - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (it.second->width == width) sel.selected_members[mod->name].insert(it.first); } else { @@ -731,7 +731,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) std::string max_str = arg_memb.substr(2+delim+1); int min_width = min_str.empty() ? 0 : atoi(min_str.c_str()); int max_width = max_str.empty() ? -1 : atoi(max_str.c_str()); - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (min_width <= it.second->width && (it.second->width <= max_width || max_width == -1)) sel.selected_members[mod->name].insert(it.first); } @@ -757,7 +757,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.substr(0, 2) == "a:") { - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); for (auto &it : mod->memories) @@ -777,7 +777,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } else { if (arg_memb.substr(0, 2) == "n:") arg_memb = arg_memb.substr(2); - for (auto &it : mod->wires) + for (auto &it : mod->wires_) if (match_ids(it.first, arg_memb)) sel.selected_members[mod->name].insert(it.first); for (auto &it : mod->memories) @@ -1152,7 +1152,7 @@ struct SelectPass : public Pass { if (sel->selected_whole_module(mod_it.first) && list_mode) log("%s\n", id2cstr(mod_it.first)); if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires) + for (auto &it : mod_it.second->wires_) if (sel->selected_member(mod_it.first, it.first)) LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); for (auto &it : mod_it.second->memories) @@ -1219,7 +1219,7 @@ struct SelectPass : public Pass { sel->optimize(design); for (auto mod_it : design->modules) if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires) + for (auto &it : mod_it.second->wires_) if (sel->selected_member(mod_it.first, it.first)) total_count++; for (auto &it : mod_it.second->memories) @@ -1374,7 +1374,7 @@ struct LsPass : public Pass { if (design->modules.count(design->selected_active_module) > 0) { RTLIL::Module *module = design->modules.at(design->selected_active_module); - counter += log_matches("wires", pattern, module->wires); + counter += log_matches("wires", pattern, module->wires_); counter += log_matches("memories", pattern, module->memories); counter += log_matches("cells", pattern, module->cells); counter += log_matches("processes", pattern, module->processes); diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 8d98df71..0b4f2a8a 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -111,7 +111,7 @@ struct SetattrPass : public Pass { if (!design->selected(module)) continue; - for (auto &it : module->wires) + for (auto &it : module->wires_) if (design->selected(module, it.second)) do_setunset(it.second->attributes, setunset_list); diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index e2610610..82dc1d99 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -129,7 +129,7 @@ struct SetundefPass : public Pass { SigMap sigmap(module); SigPool undriven_signals; - for (auto &it : module->wires) + for (auto &it : module->wires_) if (!it.second->port_input) undriven_signals.add(sigmap(it.second)); diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index d63d9897..1feb90af 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -305,7 +305,7 @@ struct ShowWorker std::set all_sources, all_sinks; std::map wires_on_demand; - for (auto &it : module->wires) { + for (auto &it : module->wires_) { if (!design->selected_member(module->name, it.first)) continue; const char *shape = "diamond"; diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 61de4406..691d972c 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -149,7 +149,7 @@ struct SpliceWorker driven_bits.push_back(RTLIL::State::Sm); driven_bits.push_back(RTLIL::State::Sm); - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.second->port_input) { RTLIL::SigSpec sig = sigmap(it.second); driven_chunks.insert(sig); @@ -175,7 +175,7 @@ struct SpliceWorker SigPool selected_bits; if (!sel_by_cell) - for (auto &it : module->wires) + for (auto &it : module->wires_) if (design->selected(module, it.second)) selected_bits.add(sigmap(it.second)); @@ -203,7 +203,7 @@ struct SpliceWorker std::vector> rework_wires; - for (auto &it : module->wires) + for (auto &it : module->wires_) if (!no_outputs && it.second->port_output) { if (!design->selected(module, it.second)) continue; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 6bffba62..accb178b 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -163,7 +163,7 @@ struct SplitnetsPass : public Pass { } else { - for (auto &w : module->wires) { + for (auto &w : module->wires_) { RTLIL::Wire *wire = w.second; if (wire->width > 1 && (wire->port_id == 0 || flag_ports) && design->selected(module, w.second)) worker.splitmap[wire] = std::vector(); diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 83477007..fabf1a73 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -69,7 +69,7 @@ namespace STAT_INT_MEMBERS #undef X - for (auto &it : mod->wires) + for (auto &it : mod->wires_) { if (!design->selected(mod, it.second)) continue; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 55fe336f..cb420f90 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -173,11 +173,11 @@ struct FsmDetectPass : public Pass { } } - for (auto &wire_it : module->wires) + for (auto &wire_it : module->wires_) if (wire_it.second->port_id != 0) sig_at_port.add(assign_map(RTLIL::SigSpec(wire_it.second))); - for (auto &wire_it : module->wires) + for (auto &wire_it : module->wires_) if (design->selected(module, wire_it.second)) detect_fsm(wire_it.second); } diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 51a4a75e..85ff4af2 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -283,10 +283,10 @@ static void extract_fsm(RTLIL::Wire *wire) // rename original state wire - module->wires.erase(wire->name); + module->wires_.erase(wire->name); wire->attributes.erase("\\fsm_encoding"); wire->name = stringf("$fsm$oldstate%s", wire->name.c_str()); - module->wires[wire->name] = wire; + module->wires_[wire->name] = wire; // unconnect control outputs from old drivers @@ -356,7 +356,7 @@ struct FsmExtractPass : public Pass { } std::vector wire_list; - for (auto &wire_it : module->wires) + for (auto &wire_it : module->wires_) if (wire_it.second->attributes.count("\\fsm_encoding") > 0 && wire_it.second->attributes["\\fsm_encoding"].decode_string() != "none") if (design->selected(module, wire_it.second)) wire_list.push_back(wire_it.second); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 8c09d2ea..a266c344 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -221,15 +221,15 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla std::string portname = conn.first; if (portname.substr(0, 1) == "$") { int port_id = atoi(portname.substr(1).c_str()); - for (auto &wire_it : mod->wires) + for (auto &wire_it : mod->wires_) if (wire_it.second->port_id == port_id) { portname = wire_it.first; break; } } - if (mod->wires.count(portname) == 0) + if (mod->wires_.count(portname) == 0) log_error("Array cell `%s.%s' connects to unkown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); - int port_size = mod->wires.at(portname)->width; + int port_size = mod->wires_.at(portname)->width; if (conn_size == port_size) continue; if (conn_size != port_size*num) @@ -492,7 +492,7 @@ struct HierarchyPass : public Pass { } for (auto module : pos_mods) - for (auto &wire_it : module->wires) { + for (auto &wire_it : module->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_id > 0) pos_map[std::pair(module, wire->port_id)] = wire->name; diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index e39f96ca..774aabae 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -212,7 +212,7 @@ struct SubmodWorker if (opt_name.empty()) { - for (auto &it : module->wires) + for (auto &it : module->wires_) it.second->attributes.erase("\\submod"); for (auto &it : module->cells) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 32c7e63a..4f166653 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -131,7 +131,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->set("\\D", data_reg_in.back()); std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); - if (module->wires.count(w_out_name) > 0) + if (module->wires_.count(w_out_name) > 0) w_out_name = genid(cell->name, "", i, "$q"); RTLIL::Wire *w_out = module->addWire(w_out_name, mem_width); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index df1a2697..35a28d17 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -137,7 +137,7 @@ struct MemoryShareWorker std::map> muxtree_upstream_map; std::set non_feedback_nets; - for (auto wire_it : module->wires) + for (auto wire_it : module->wires_) if (wire_it.second->port_output) { std::vector bits = RTLIL::SigSpec(wire_it.second); non_feedback_nets.insert(bits.begin(), bits.end()); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 63d03b20..9542e10d 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -52,7 +52,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) unused.insert(cell); } - for (auto &it : module->wires) { + for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; if (wire->port_output || wire->get_bool_attribute("\\keep")) { std::set cell_list; @@ -175,12 +175,12 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (ct_all.cell_output(cell->type, it2.first)) direct_sigs.insert(assign_map(it2.second)); } - for (auto &it : module->wires) { + for (auto &it : module->wires_) { if (direct_sigs.count(assign_map(it.second)) || it.second->port_input) direct_wires.insert(it.second); } - for (auto &it : module->wires) { + for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) { RTLIL::SigBit s1 = RTLIL::SigBit(wire, i), s2 = assign_map(s1); @@ -202,7 +202,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool used_signals_nodrivers.add(it2.second); } } - for (auto &it : module->wires) { + for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; if (wire->port_id > 0) { RTLIL::SigSpec sig = RTLIL::SigSpec(wire); @@ -219,7 +219,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } std::vector maybe_del_wires; - for (auto &it : module->wires) { + for (auto &it : module->wires_) { RTLIL::Wire *wire = it.second; if ((!purge_mode && check_public_name(wire->name)) || wire->port_id != 0 || wire->get_bool_attribute("\\keep")) { RTLIL::SigSpec s1 = RTLIL::SigSpec(wire), s2 = s1; diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 67218600..290d4ffd 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -45,7 +45,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) used_signals.add(sigmap(conn.second)); } - for (auto &it : module->wires) { + for (auto &it : module->wires_) { if (it.second->port_input) driven_signals.add(sigmap(it.second)); if (it.second->port_output) diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 8487152f..16dedef5 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -136,7 +136,7 @@ struct OptMuxtreeWorker } } } - for (auto &it : module->wires) { + for (auto &it : module->wires_) { if (it.second->port_output) for (int idx : sig2bits(RTLIL::SigSpec(it.second))) bit2info[idx].seen_non_mux = true; diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 8c09f541..b26e8b37 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -173,7 +173,7 @@ struct OptRmdffPass : public Pass { assign_map.set(mod_it.second); dff_init_map.set(mod_it.second); - for (auto &it : mod_it.second->wires) + for (auto &it : mod_it.second->wires_) if (it.second->attributes.count("\\init") != 0) dff_init_map.add(it.second, it.second->attributes.at("\\init")); mux_drivers.clear(); diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 4f733a37..c91f037d 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -237,7 +237,7 @@ struct OptShareWorker assign_map.set(module); dff_init_map.set(module); - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.second->attributes.count("\\init") != 0) dff_init_map.add(it.second, it.second->attributes.at("\\init")); diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 114f2567..565d86a7 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -243,7 +243,7 @@ struct ProcArstPass : public Pass { if (!design->selected(mod_it.second, proc_it.second)) continue; proc_arst(mod_it.second, proc_it.second, assign_map); - if (global_arst.empty() || mod_it.second->wires.count(global_arst) == 0) + if (global_arst.empty() || mod_it.second->wires_.count(global_arst) == 0) continue; std::vector arst_actions; for (auto sync : proc_it.second->syncs) @@ -266,7 +266,7 @@ struct ProcArstPass : public Pass { if (!arst_actions.empty()) { RTLIL::SyncRule *sync = new RTLIL::SyncRule; sync->type = global_arst_neg ? RTLIL::SyncType::ST0 : RTLIL::SyncType::ST1; - sync->signal = mod_it.second->wires.at(global_arst); + sync->signal = mod_it.second->wires_.at(global_arst); sync->actions = arst_actions; proc_it.second->syncs.push_back(sync); } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 6949b76d..d4ff2a86 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -87,16 +87,16 @@ struct BruteForceEquivChecker mod1(mod1), mod2(mod2), counter(0), errors(0), ignore_x_mod1(ignore_x_mod1) { log("Checking for equivialence (brute-force): %s vs %s\n", mod1->name.c_str(), mod2->name.c_str()); - for (auto &w : mod1->wires) + for (auto &w : mod1->wires_) { RTLIL::Wire *wire1 = w.second; if (wire1->port_id == 0) continue; - if (mod2->wires.count(wire1->name) == 0) + if (mod2->wires_.count(wire1->name) == 0) log_cmd_error("Port %s in module 1 has no counterpart in module 2!\n", wire1->name.c_str()); - RTLIL::Wire *wire2 = mod2->wires.at(wire1->name); + RTLIL::Wire *wire2 = mod2->wires_.at(wire1->name); if (wire1->width != wire2->width || wire1->port_input != wire2->port_input || wire1->port_output != wire2->port_output) log_cmd_error("Port %s in module 1 does not match its counterpart in module 2!\n", wire1->name.c_str()); @@ -153,11 +153,11 @@ struct VlogHammerReporter ez.assume(satgen.signals_eq(recorded_set_vars, recorded_set_vals)); - std::vector y_vec = satgen.importDefSigSpec(module->wires.at("\\y")); + std::vector y_vec = satgen.importDefSigSpec(module->wires_.at("\\y")); std::vector y_values; if (model_undef) { - std::vector y_undef_vec = satgen.importUndefSigSpec(module->wires.at("\\y")); + std::vector y_undef_vec = satgen.importUndefSigSpec(module->wires_.at("\\y")); y_vec.insert(y_vec.end(), y_undef_vec.begin(), y_undef_vec.end()); } @@ -252,7 +252,7 @@ struct VlogHammerReporter std::vector bits(patterns[idx].bits.begin(), patterns[idx].bits.begin() + total_input_width); for (int i = 0; i < int(inputs.size()); i++) { - RTLIL::Wire *wire = module->wires.at(inputs[i]); + RTLIL::Wire *wire = module->wires_.at(inputs[i]); for (int j = input_widths[i]-1; j >= 0; j--) { ce.set(RTLIL::SigSpec(wire, j), bits.back()); recorded_set_vars.append(RTLIL::SigSpec(wire, j)); @@ -268,10 +268,10 @@ struct VlogHammerReporter } } - if (module->wires.count("\\y") == 0) + if (module->wires_.count("\\y") == 0) log_error("No output wire (y) found in module %s!\n", RTLIL::id2cstr(module->name)); - RTLIL::SigSpec sig(module->wires.at("\\y")); + RTLIL::SigSpec sig(module->wires_.at("\\y")); RTLIL::SigSpec undef; while (!ce.eval(sig, undef)) { @@ -318,9 +318,9 @@ struct VlogHammerReporter int width = -1; RTLIL::IdString esc_name = RTLIL::escape_id(name); for (auto mod : modules) { - if (mod->wires.count(esc_name) == 0) + if (mod->wires_.count(esc_name) == 0) log_error("Can't find input %s in module %s!\n", name.c_str(), RTLIL::id2cstr(mod->name)); - RTLIL::Wire *port = mod->wires.at(esc_name); + RTLIL::Wire *port = mod->wires_.at(esc_name); if (!port->port_input || port->port_output) log_error("Wire %s in module %s is not an input!\n", name.c_str(), RTLIL::id2cstr(mod->name)); if (width >= 0 && width != port->width) @@ -469,7 +469,7 @@ struct EvalPass : public Pass { } if (shows.size() == 0) { - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.second->port_output) shows.push_back(it.second->name); } diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 21af63a3..c30e6e0c 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -87,7 +87,7 @@ static void find_dff_wires(std::set &dff_wires, RTLIL::Module *modu dffsignals.add(sigmap(it.second->get("\\Q"))); } - for (auto &it : module->wires) { + for (auto &it : module->wires_) { if (dffsignals.check_any(it.second)) dff_wires.insert(it.first); } @@ -161,7 +161,7 @@ static void create_dff_dq_map(std::map &map, RTLIL: } std::map empty_dq_map; - for (auto &it : module->wires) + for (auto &it : module->wires_) { if (!consider_wire(it.second, empty_dq_map)) continue; @@ -321,7 +321,7 @@ struct ExposePass : public Pass { for (auto &it : shared_dff_wires) { if (!dff_dq_maps[mod_it.second].count(it)) continue; - if (!compare_wires(first_module->wires.at(it), mod_it.second->wires.at(it))) + if (!compare_wires(first_module->wires_.at(it), mod_it.second->wires_.at(it))) continue; new_shared_dff_wires.insert(it); } @@ -365,7 +365,7 @@ struct ExposePass : public Pass { if (first_module == NULL) { - for (auto &it : module->wires) + for (auto &it : module->wires_) if (design->selected(module, it.second) && consider_wire(it.second, dff_dq_maps[module])) if (!flag_dff || dff_wires.count(it.first)) shared_wires.insert(it.first); @@ -385,16 +385,16 @@ struct ExposePass : public Pass { { RTLIL::Wire *wire; - if (module->wires.count(it) == 0) + if (module->wires_.count(it) == 0) goto delete_shared_wire; - wire = module->wires.at(it); + wire = module->wires_.at(it); if (!design->selected(module, wire)) goto delete_shared_wire; if (!consider_wire(wire, dff_dq_maps[module])) goto delete_shared_wire; - if (!compare_wires(first_module->wires.at(it), wire)) + if (!compare_wires(first_module->wires_.at(it), wire)) goto delete_shared_wire; if (flag_dff && !dff_wires.count(it)) goto delete_shared_wire; @@ -449,7 +449,7 @@ struct ExposePass : public Pass { SigMap out_to_in_map; - for (auto &it : module->wires) + for (auto &it : module->wires_) { if (flag_shared) { if (shared_wires.count(it.first) == 0) @@ -491,10 +491,10 @@ struct ExposePass : public Pass { for (auto &dq : dff_dq_maps[module]) { - if (!module->wires.count(dq.first)) + if (!module->wires_.count(dq.first)) continue; - RTLIL::Wire *wire = module->wires.at(dq.first); + RTLIL::Wire *wire = module->wires_.at(dq.first); std::set wire_bits_set = sigmap(wire).to_sigbit_set(); std::vector wire_bits_vec = sigmap(wire).to_sigbit_vector(); @@ -587,7 +587,7 @@ struct ExposePass : public Pass { { RTLIL::Module *mod = design->modules.at(cell->type); - for (auto &it : mod->wires) + for (auto &it : mod->wires_) { RTLIL::Wire *p = it.second; if (!p->port_input && !p->port_output) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index d5336ca0..5d23318c 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -602,7 +602,7 @@ struct FreduceWorker int bits_full_total = 0; std::vector> batches; - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.second->port_input) { batches.push_back(sigmap(it.second).to_sigbit_set()); bits_full_total += it.second->width; diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 0c5989b1..248f934c 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -73,13 +73,13 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::Module *gold_module = design->modules.at(gold_name); RTLIL::Module *gate_module = design->modules.at(gate_name); - for (auto &it : gold_module->wires) { + for (auto &it : gold_module->wires_) { RTLIL::Wire *w1 = it.second, *w2; if (w1->port_id == 0) continue; - if (gate_module->wires.count(it.second->name) == 0) + if (gate_module->wires_.count(it.second->name) == 0) goto match_gold_port_error; - w2 = gate_module->wires.at(it.second->name); + w2 = gate_module->wires_.at(it.second->name); if (w1->port_input != w2->port_input) goto match_gold_port_error; if (w1->port_output != w2->port_output) @@ -91,13 +91,13 @@ static void create_miter_equiv(struct Pass *that, std::vector args, log_cmd_error("No matching port in gate module was found for %s!\n", it.second->name.c_str()); } - for (auto &it : gate_module->wires) { + for (auto &it : gate_module->wires_) { RTLIL::Wire *w1 = it.second, *w2; if (w1->port_id == 0) continue; - if (gold_module->wires.count(it.second->name) == 0) + if (gold_module->wires_.count(it.second->name) == 0) goto match_gate_port_error; - w2 = gold_module->wires.at(it.second->name); + w2 = gold_module->wires_.at(it.second->name); if (w1->port_input != w2->port_input) goto match_gate_port_error; if (w1->port_output != w2->port_output) @@ -120,7 +120,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::SigSpec all_conditions; - for (auto &it : gold_module->wires) + for (auto &it : gold_module->wires_) { RTLIL::Wire *w1 = it.second; diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 71eba2f7..90c67116 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -94,7 +94,7 @@ struct SatHelper RTLIL::SigSpec big_lhs, big_rhs; - for (auto &it : module->wires) + for (auto &it : module->wires_) { if (it.second->attributes.count("\\init") == 0) continue; @@ -1158,19 +1158,19 @@ struct SatPass : public Pass { log_cmd_error("The options -set-init-undef, -set-init-def, and -set-init-zero are exclusive!\n"); if (set_def_inputs) { - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.second->port_input) sets_def.push_back(it.second->name); } if (show_inputs) { - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.second->port_input) shows.push_back(it.second->name); } if (show_outputs) { - for (auto &it : module->wires) + for (auto &it : module->wires_) if (it.second->port_output) shows.push_back(it.second->name); } diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 92bcafc0..813e0e3e 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -271,7 +271,7 @@ namespace } // mark external signals (used in module ports) - for (auto &wire_it : mod->wires) + for (auto &wire_it : mod->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_id > 0) @@ -300,7 +300,7 @@ namespace RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), RTLIL::autoidx++), needle->name); // create cell ports - for (auto &it : needle->wires) { + for (auto &it : needle->wires_) { RTLIL::Wire *wire = it.second; if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) @@ -742,7 +742,7 @@ struct ExtractPass : public Pass { std::vector chunks = sigmap(conn.second); for (auto &chunk : chunks) if (chunk.wire != NULL) - chunk.wire = newMod->wires.at(chunk.wire->name); + chunk.wire = newMod->wires_.at(chunk.wire->name); newCell->set(conn.first, chunks); } } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index ab3bb3ed..6f7427f0 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -118,7 +118,7 @@ struct IopadmapPass : public Pass { if (!design->selected(module) || module->get_bool_attribute("\\blackbox")) continue; - for (auto &it2 : module->wires) + for (auto &it2 : module->wires_) { RTLIL::Wire *wire = it2.second; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index bee1df40..03aac669 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -46,8 +46,8 @@ static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module if (chunk.wire != NULL) { std::string wire_name = chunk.wire->name; apply_prefix(prefix, wire_name); - assert(module->wires.count(wire_name) > 0); - chunk.wire = module->wires[wire_name]; + assert(module->wires_.count(wire_name) > 0); + chunk.wire = module->wires_[wire_name]; } sig = chunks; } @@ -72,7 +72,7 @@ struct TechmapWorker if (module == NULL) return result; - for (auto &it : module->wires) { + for (auto &it : module->wires_) { const char *p = it.first.c_str(); if (*p == '$') continue; @@ -125,7 +125,7 @@ struct TechmapWorker std::map positional_ports; - for (auto &it : tpl->wires) { + for (auto &it : tpl->wires_) { if (it.second->port_id > 0) positional_ports[stringf("$%d", it.second->port_id)] = it.first; std::string w_name = it.second->name; @@ -145,12 +145,12 @@ struct TechmapWorker RTLIL::IdString portname = it.first; if (positional_ports.count(portname) > 0) portname = positional_ports.at(portname); - if (tpl->wires.count(portname) == 0 || tpl->wires.at(portname)->port_id == 0) { + if (tpl->wires_.count(portname) == 0 || tpl->wires_.at(portname)->port_id == 0) { if (portname.substr(0, 1) == "$") log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str()); continue; } - RTLIL::Wire *w = tpl->wires.at(portname); + RTLIL::Wire *w = tpl->wires_.at(portname); RTLIL::SigSig c; if (w->port_output) { c.first = it.second; @@ -265,7 +265,7 @@ struct TechmapWorker for (auto conn : cell->connections()) { if (conn.first.substr(0, 1) == "$") continue; - if (tpl->wires.count(conn.first) > 0 && tpl->wires.at(conn.first)->port_id > 0) + if (tpl->wires_.count(conn.first) > 0 && tpl->wires_.at(conn.first)->port_id > 0) continue; if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0) goto next_tpl; @@ -388,7 +388,7 @@ struct TechmapWorker assert(!strncmp(q, "_TECHMAP_DO_", 12)); std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12); - while (tpl->wires.count(new_name)) + while (tpl->wires_.count(new_name)) new_name += "_"; tpl->rename(data.wire, new_name); From 4c4b6021562c598c4510831bd547edaa97d14dac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 01:51:45 +0200 Subject: [PATCH 446/750] Refactoring: Renamed RTLIL::Module::cells to cells_ --- backends/blif/blif.cc | 2 +- backends/btor/btor.cc | 6 +++--- backends/edif/edif.cc | 6 +++--- backends/ilang/ilang_backend.cc | 2 +- backends/intersynth/intersynth.cc | 4 ++-- backends/spice/spice.cc | 2 +- backends/verilog/verilog_backend.cc | 6 +++--- frontends/liberty/liberty.cc | 4 ++-- kernel/consteval.h | 2 +- kernel/driver.cc | 2 +- kernel/modwalker.h | 2 +- kernel/rtlil.cc | 24 ++++++++++++------------ kernel/rtlil.h | 4 ++-- manual/CHAPTER_Prog/stubnets.cc | 2 +- manual/PRESENTATION_Prog/my_cmd.cc | 2 +- passes/abc/abc.cc | 12 ++++++------ passes/cmds/add.cc | 2 +- passes/cmds/connect.cc | 6 +++--- passes/cmds/connwrappers.cc | 4 ++-- passes/cmds/delete.cc | 2 +- passes/cmds/rename.cc | 10 +++++----- passes/cmds/scatter.cc | 2 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 28 ++++++++++++++-------------- passes/cmds/setattr.cc | 4 ++-- passes/cmds/setundef.cc | 2 +- passes/cmds/show.cc | 6 +++--- passes/cmds/splice.cc | 4 ++-- passes/cmds/splitnets.cc | 2 +- passes/cmds/stat.cc | 2 +- passes/fsm/fsm_detect.cc | 2 +- passes/fsm/fsm_expand.cc | 4 ++-- passes/fsm/fsm_export.cc | 2 +- passes/fsm/fsm_extract.cc | 10 +++++----- passes/fsm/fsm_info.cc | 2 +- passes/fsm/fsm_map.cc | 2 +- passes/fsm/fsm_opt.cc | 2 +- passes/fsm/fsm_recode.cc | 2 +- passes/hierarchy/hierarchy.cc | 10 +++++----- passes/hierarchy/submod.cc | 6 +++--- passes/memory/memory_collect.cc | 2 +- passes/memory/memory_dff.cc | 6 +++--- passes/memory/memory_map.cc | 2 +- passes/memory/memory_share.cc | 4 ++-- passes/memory/memory_unpack.cc | 4 ++-- passes/opt/opt_clean.cc | 8 ++++---- passes/opt/opt_const.cc | 6 +++--- passes/opt/opt_muxtree.cc | 2 +- passes/opt/opt_reduce.cc | 10 +++++----- passes/opt/opt_rmdff.cc | 6 +++--- passes/opt/opt_share.cc | 4 ++-- passes/proc/proc_arst.cc | 2 +- passes/sat/eval.cc | 2 +- passes/sat/expose.cc | 18 +++++++++--------- passes/sat/freduce.cc | 2 +- passes/sat/sat.cc | 2 +- passes/sat/share.cc | 4 ++-- passes/techmap/dfflibmap.cc | 2 +- passes/techmap/extract.cc | 6 +++--- passes/techmap/simplemap.cc | 2 +- passes/techmap/techmap.cc | 10 +++++----- 61 files changed, 152 insertions(+), 152 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 7ae9965d..936dea02 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -140,7 +140,7 @@ struct BlifDumper fprintf(f, ".names $true\n1\n"); } - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index f1e95ee1..ef0f0dd8 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -192,7 +192,7 @@ struct BtorDumper if(cell_id == curr_cell) break; log(" -- found cell %s\n", cstr(cell_id)); - RTLIL::Cell* cell = module->cells.at(cell_id); + RTLIL::Cell* cell = module->cells_.at(cell_id); const RTLIL::SigSpec* cell_output = get_cell_output(cell); int cell_line = dump_cell(cell); @@ -832,7 +832,7 @@ struct BtorDumper log("creating intermediate wires map\n"); //creating map of intermediate wires as output of some cell - for (auto it = module->cells.begin(); it != module->cells.end(); ++it) + for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it) { RTLIL::Cell *cell = it->second; const RTLIL::SigSpec* output_sig = get_cell_output(cell); @@ -911,7 +911,7 @@ struct BtorDumper } log("writing cells\n"); - for(auto cell_it = module->cells.begin(); cell_it != module->cells.end(); ++cell_it) + for(auto cell_it = module->cells_.begin(); cell_it != module->cells_.end(); ++cell_it) { dump_cell(cell_it->second); } diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index e99d094f..d23e99e7 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -143,7 +143,7 @@ struct EdifBackend : public Backend { if (module->memories.size() != 0) log_error("Found munmapped emories in module %s: unmapped memories are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name)); - for (auto cell_it : module->cells) + for (auto cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (!design->modules.count(cell->type) || design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) { @@ -215,7 +215,7 @@ struct EdifBackend : public Backend { std::map> module_deps; for (auto &mod_it : design->modules) { module_deps[mod_it.second] = std::set(); - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) if (design->modules.count(cell_it.second->type) > 0) module_deps[mod_it.second].insert(design->modules.at(cell_it.second->type)); } @@ -280,7 +280,7 @@ struct EdifBackend : public Backend { fprintf(f, " (contents\n"); fprintf(f, " (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n"); fprintf(f, " (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n"); - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; fprintf(f, " (instance %s\n", EDIF_DEF(cell->name)); fprintf(f, " (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type), diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index c0b7dab9..be4e2777 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -294,7 +294,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module dump_memory(f, indent + " ", it->second); } - for (auto it = module->cells.begin(); it != module->cells.end(); it++) + for (auto it = module->cells_.begin(); it != module->cells_.end(); it++) if (!only_selected || design->selected(module, it->second)) { if (only_selected) fprintf(f, "\n"); diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 4e8c321b..a463f5ec 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -128,7 +128,7 @@ struct IntersynthBackend : public Backend { if (module->get_bool_attribute("\\blackbox")) continue; - if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells.size() == 0) + if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells_.size() == 0) continue; if (selected && !design->selected_whole_module(module->name)) { @@ -159,7 +159,7 @@ struct IntersynthBackend : public Backend { } // Submodules: "std::set celltypes_code" prevents duplicate cell types - for (auto cell_it : module->cells) + for (auto cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; std::string celltype_code, node_code; diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index ef31e06a..c58e4bec 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -47,7 +47,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de SigMap sigmap(module); int cell_counter = 0, conn_counter = 0, nc_counter = 0; - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; fprintf(f, "X%d", cell_counter++); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 5e98a4c5..098e29f9 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -79,7 +79,7 @@ void reset_auto_counter(RTLIL::Module *module) for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) reset_auto_counter_id(it->second->name, true); - for (auto it = module->cells.begin(); it != module->cells.end(); it++) { + for (auto it = module->cells_.begin(); it != module->cells_.end(); it++) { reset_auto_counter_id(it->second->name, true); reset_auto_counter_id(it->second->type, false); } @@ -905,7 +905,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) if (!noexpr) { std::set> reg_bits; - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; if (!reg_ct.cell_known(cell->type) || !cell->has("\\Q")) @@ -955,7 +955,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto it = module->memories.begin(); it != module->memories.end(); it++) dump_memory(f, indent + " ", it->second); - for (auto it = module->cells.begin(); it != module->cells.end(); it++) + for (auto it = module->cells_.begin(); it != module->cells_.end(); it++) dump_cell(f, indent + " ", it->second); for (auto it = module->processes.begin(); it != module->processes.end(); it++) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index c476de87..0107b974 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; diff --git a/kernel/consteval.h b/kernel/consteval.h index 3a5c5347..1727d91c 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -40,7 +40,7 @@ struct ConstEval ct.setup_internals(); ct.setup_stdcells(); - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (!ct.cell_known(it.second->type)) continue; for (auto &it2 : it.second->connections()) diff --git a/kernel/driver.cc b/kernel/driver.cc index 3fbb9658..edf23cd2 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -251,7 +251,7 @@ static char *readline_obj_generator(const char *text, int state) if (RTLIL::unescape_id(it.first).substr(0, len) == text) obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - for (auto &it : module->cells) + for (auto &it : module->cells_) if (RTLIL::unescape_id(it.first).substr(0, len) == text) obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); diff --git a/kernel/modwalker.h b/kernel/modwalker.h index a90d739e..09f815b8 100644 --- a/kernel/modwalker.h +++ b/kernel/modwalker.h @@ -123,7 +123,7 @@ struct ModWalker for (auto &it : module->wires_) add_wire(it.second); - for (auto &it : module->cells) + for (auto &it : module->cells_) if (filter_ct == NULL || filter_ct->cell_known(it.second->type)) add_cell(it.second); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 0cfcf018..f307be43 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -204,7 +204,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) if (it.second.size() == 0) del_list.push_back(it.first); else if (it.second.size() == design->modules[it.first]->wires_.size() + design->modules[it.first]->memories.size() + - design->modules[it.first]->cells.size() + design->modules[it.first]->processes.size()) + design->modules[it.first]->cells_.size() + design->modules[it.first]->processes.size()) add_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -280,7 +280,7 @@ RTLIL::Module::~Module() delete it->second; for (auto it = memories.begin(); it != memories.end(); it++) delete it->second; - for (auto it = cells.begin(); it != cells.end(); it++) + for (auto it = cells_.begin(); it != cells_.end(); it++) delete it->second; for (auto it = processes.begin(); it != processes.end(); it++) delete it->second; @@ -293,7 +293,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, std::mapname); assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$')); @@ -782,7 +782,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const for (auto &it : memories) new_mod->memories[it.first] = new RTLIL::Memory(*it.second); - for (auto &it : cells) + for (auto &it : cells_) new_mod->addCell(it.first, it.second); for (auto &it : processes) @@ -824,7 +824,7 @@ void RTLIL::Module::add(RTLIL::Cell *cell) { assert(!cell->name.empty()); assert(count_id(cell->name) == 0); - cells[cell->name] = cell; + cells_[cell->name] = cell; } namespace { @@ -869,8 +869,8 @@ void RTLIL::Module::remove(const std::set &wires) void RTLIL::Module::remove(RTLIL::Cell *cell) { - assert(cells.count(cell->name) != 0); - cells.erase(cell->name); + assert(cells_.count(cell->name) != 0); + cells_.erase(cell->name); delete cell; } @@ -884,8 +884,8 @@ void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name) { - assert(cells[cell->name] == cell); - cells.erase(cell->name); + assert(cells_[cell->name] == cell); + cells_.erase(cell->name); cell->name = new_name; add(cell); } @@ -895,8 +895,8 @@ void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name) assert(count_id(old_name) != 0); if (wires_.count(old_name)) rename(wires_.at(old_name), new_name); - else if (cells.count(old_name)) - rename(cells.at(old_name), new_name); + else if (cells_.count(old_name)) + rename(cells_.at(old_name), new_name); else log_abort(); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1d040975..f8d2892f 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -282,7 +282,7 @@ public: std::set avail_parameters; std::map wires_; std::map memories; - std::map cells; + std::map cells_; std::map processes; std::vector connections_; RTLIL_ATTRIBUTE_MEMBERS @@ -719,7 +719,7 @@ struct RTLIL::Process { template void RTLIL::Module::rewrite_sigspecs(T functor) { - for (auto &it : cells) + for (auto &it : cells_) it.second->rewrite_sigspecs(functor); for (auto &it : processes) it.second->rewrite_sigspecs(functor); diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index 9eacfbcb..a5790743 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -29,7 +29,7 @@ static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool re log("Looking for stub wires in module %s:\n", RTLIL::id2cstr(module->name)); // For all ports on all cells - for (auto &cell_iter : module->cells) + for (auto &cell_iter : module->cells_) for (auto &conn : cell_iter.second->connections()) { // Get the signals on the port diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/manual/PRESENTATION_Prog/my_cmd.cc index 0cd1da80..c724ce37 100644 --- a/manual/PRESENTATION_Prog/my_cmd.cc +++ b/manual/PRESENTATION_Prog/my_cmd.cc @@ -14,7 +14,7 @@ struct MyPass : public Pass { log("Modules in current design:\n"); for (auto &mod : design->modules) log(" %s (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), - mod.second->wires_.size(), mod.second->cells.size()); + mod.second->wires_.size(), mod.second->cells_.size()); } } MyPass; diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 184f143a..7ba9424e 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -462,7 +462,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std int best_dff_counter = 0; std::map, int> dff_counters; - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; if (cell->type != "$_DFF_N_" && cell->type != "$_DFF_P_") @@ -488,8 +488,8 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std mark_port(clk_sig); std::vector cells; - cells.reserve(module->cells.size()); - for (auto &it : module->cells) + cells.reserve(module->cells_.size()); + for (auto &it : module->cells_) if (design->selected(current_module, it.second)) cells.push_back(it.second); for (auto c : cells) @@ -500,7 +500,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std mark_port(RTLIL::SigSpec(wire_it.second)); } - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) for (auto &port_it : cell_it.second->connections()) mark_port(port_it.second); @@ -696,7 +696,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std std::map cell_stats; if (builtin_lib) { - for (auto &it : mapped_mod->cells) { + for (auto &it : mapped_mod->cells_) { RTLIL::Cell *c = it.second; cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { @@ -751,7 +751,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } else { - for (auto &it : mapped_mod->cells) + for (auto &it : mapped_mod->cells_) { RTLIL::Cell *c = it.second; cell_stats[RTLIL::unescape_id(c->type)]++; diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index e97bf8fc..49aa7c98 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -62,7 +62,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n if (!flag_global) return; - for (auto &it : module->cells) + for (auto &it : module->cells_) { if (design->modules.count(it.second->type) == 0) continue; diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 99a28d4a..6494ea6f 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -29,7 +29,7 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size()); - for (auto &it : module->cells) + for (auto &it : module->cells_) for (auto &port : it.second->connections_) if (ct.cell_output(it.second->type, port.first)) sigmap(port.second).replace(sig, dummy_wire, &port.second); @@ -169,14 +169,14 @@ struct ConnectPass : public Pass { if (flag_nounset) log_cmd_error("Cant use -port together with -nounset.\n"); - if (module->cells.count(RTLIL::escape_id(port_cell)) == 0) + if (module->cells_.count(RTLIL::escape_id(port_cell)) == 0) log_cmd_error("Can't find cell %s.\n", port_cell.c_str()); RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cells.at(RTLIL::escape_id(port_cell))->set(RTLIL::escape_id(port_port), sigmap(sig)); + module->cells_.at(RTLIL::escape_id(port_cell))->set(RTLIL::escape_id(port_port), sigmap(sig)); } else log_cmd_error("Expected -set, -unset, or -port.\n"); diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 9faeffaf..cc8147c5 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -67,7 +67,7 @@ struct ConnwrappersWorker std::map> extend_map; SigMap sigmap(module); - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; @@ -102,7 +102,7 @@ struct ConnwrappersWorker } } - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 460dd966..2c2c370d 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -103,7 +103,7 @@ struct DeletePass : public Pass { if (design->selected(module, it.second)) delete_mems.insert(it.first); - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (design->selected(module, it.second)) delete_cells.insert(it.second); if ((it.second->type == "$memrd" || it.second->type == "$memwr") && diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index e163e724..c8b8160f 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -36,7 +36,7 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std:: return; } - for (auto &it : module->cells) + for (auto &it : module->cells_) if (it.first == from_name) { log("Renaming cell %s to %s in module %s.\n", log_id(it.second), log_id(to_name), log_id(module)); module->rename(it.second, to_name); @@ -114,13 +114,13 @@ struct RenamePass : public Pass { module->wires_.swap(new_wires); std::map new_cells; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (it.first[0] == '$' && design->selected(module, it.second)) do it.second->name = stringf("\\_%d_", counter++); while (module->count_id(it.second->name) > 0); new_cells[it.second->name] = it.second; } - module->cells.swap(new_cells); + module->cells_.swap(new_cells); } } else @@ -144,13 +144,13 @@ struct RenamePass : public Pass { module->wires_.swap(new_wires); std::map new_cells; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (design->selected(module, it.second)) if (it.first[0] == '\\') it.second->name = NEW_ID; new_cells[it.second->name] = it.second; } - module->cells.swap(new_cells); + module->cells_.swap(new_cells); } } else diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index 0b95fe02..a1c12f1e 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -48,7 +48,7 @@ struct ScatterPass : public Pass { if (!design->selected(mod_it.second)) continue; - for (auto &c : mod_it.second->cells) + for (auto &c : mod_it.second->cells_) for (auto &p : c.second->connections_) { RTLIL::Wire *wire = mod_it.second->addWire(NEW_ID, p.second.size()); diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 7e2b2fc9..c9504341 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -118,7 +118,7 @@ struct SccWorker if (design->selected(module, it.second)) selectedSignals.add(sigmap(RTLIL::SigSpec(it.second))); - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 0cabdc06..306b7a5b 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -167,7 +167,7 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) for (auto &it : mod->memories) if (!lhs.selected_member(mod_it.first, it.first)) new_sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells) + for (auto &it : mod->cells_) if (!lhs.selected_member(mod_it.first, it.first)) new_sel.selected_members[mod->name].insert(it.first); for (auto &it : mod->processes) @@ -185,7 +185,7 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) { if (lhs.selected_whole_module(mod_it.first)) { - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) { if (design->modules.count(cell_it.second->type) == 0) continue; @@ -282,7 +282,7 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R lhs.selected_members[mod->name].insert(it.first); for (auto &it : mod->memories) lhs.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells) + for (auto &it : mod->cells_) lhs.selected_members[mod->name].insert(it.first); for (auto &it : mod->processes) lhs.selected_members[mod->name].insert(it.first); @@ -395,7 +395,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v } } - for (auto &cell : mod->cells) + for (auto &cell : mod->cells_) for (auto &conn : cell.second->connections()) { char last_mode = '-'; @@ -742,12 +742,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.substr(0, 2) == "c:") { - for (auto &it : mod->cells) + for (auto &it : mod->cells_) if (match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.substr(0, 2) == "t:") { - for (auto &it : mod->cells) + for (auto &it : mod->cells_) if (match_ids(it.second->type, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else @@ -763,7 +763,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) for (auto &it : mod->memories) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells) + for (auto &it : mod->cells_) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); for (auto &it : mod->processes) @@ -771,7 +771,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.substr(0, 2) == "r:") { - for (auto &it : mod->cells) + for (auto &it : mod->cells_) if (match_attr(it.second->parameters, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else { @@ -783,7 +783,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) for (auto &it : mod->memories) if (match_ids(it.first, arg_memb)) sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells) + for (auto &it : mod->cells_) if (match_ids(it.first, arg_memb)) sel.selected_members[mod->name].insert(it.first); for (auto &it : mod->processes) @@ -1158,7 +1158,7 @@ struct SelectPass : public Pass { for (auto &it : mod_it.second->memories) if (sel->selected_member(mod_it.first, it.first)) LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); - for (auto &it : mod_it.second->cells) + for (auto &it : mod_it.second->cells_) if (sel->selected_member(mod_it.first, it.first)) LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); for (auto &it : mod_it.second->processes) @@ -1225,7 +1225,7 @@ struct SelectPass : public Pass { for (auto &it : mod_it.second->memories) if (sel->selected_member(mod_it.first, it.first)) total_count++; - for (auto &it : mod_it.second->cells) + for (auto &it : mod_it.second->cells_) if (sel->selected_member(mod_it.first, it.first)) total_count++; for (auto &it : mod_it.second->processes) @@ -1303,8 +1303,8 @@ struct CdPass : public Pass { RTLIL::Module *module = NULL; if (design->modules.count(design->selected_active_module) > 0) module = design->modules.at(design->selected_active_module); - if (module != NULL && module->cells.count(modname) > 0) - modname = module->cells.at(modname)->type; + if (module != NULL && module->cells_.count(modname) > 0) + modname = module->cells_.at(modname)->type; } if (design->modules.count(modname) > 0) { @@ -1376,7 +1376,7 @@ struct LsPass : public Pass { RTLIL::Module *module = design->modules.at(design->selected_active_module); counter += log_matches("wires", pattern, module->wires_); counter += log_matches("memories", pattern, module->memories); - counter += log_matches("cells", pattern, module->cells); + counter += log_matches("cells", pattern, module->cells_); counter += log_matches("processes", pattern, module->processes); } diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 0b4f2a8a..ea5221f6 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -119,7 +119,7 @@ struct SetattrPass : public Pass { if (design->selected(module, it.second)) do_setunset(it.second->attributes, setunset_list); - for (auto &it : module->cells) + for (auto &it : module->cells_) if (design->selected(module, it.second)) do_setunset(it.second->attributes, setunset_list); @@ -171,7 +171,7 @@ struct SetparamPass : public Pass { if (!design->selected(module)) continue; - for (auto &it : module->cells) + for (auto &it : module->cells_) if (design->selected(module, it.second)) do_setunset(it.second->parameters, setunset_list); } diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 82dc1d99..e7779415 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -134,7 +134,7 @@ struct SetundefPass : public Pass { undriven_signals.add(sigmap(it.second)); CellTypes ct(design); - for (auto &it : module->cells) + for (auto &it : module->cells_) for (auto &conn : it.second->connections()) if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) undriven_signals.del(sigmap(conn.second)); diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 1feb90af..18af8dfc 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -337,7 +337,7 @@ struct ShowWorker fprintf(f, "}\n"); } - for (auto &it : module->cells) + for (auto &it : module->cells_) { if (!design->selected_member(module->name, it.first)) continue; @@ -516,7 +516,7 @@ struct ShowWorker log("Skipping blackbox module %s.\n", id2cstr(module->name)); continue; } else - if (module->cells.empty() && module->connections().empty() && module->processes.empty()) { + if (module->cells_.empty() && module->connections().empty() && module->processes.empty()) { log("Skipping empty module %s.\n", id2cstr(module->name)); continue; } else @@ -695,7 +695,7 @@ struct ShowPass : public Pass { for (auto &mod_it : design->modules) { if (mod_it.second->get_bool_attribute("\\blackbox")) continue; - if (mod_it.second->cells.empty() && mod_it.second->connections().empty()) + if (mod_it.second->cells_.empty() && mod_it.second->connections().empty()) continue; if (design->selected_module(mod_it.first)) modcount++; diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 691d972c..dcd2f819 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -158,7 +158,7 @@ struct SpliceWorker driven_bits.push_back(RTLIL::State::Sm); } - for (auto &it : module->cells) + for (auto &it : module->cells_) for (auto &conn : it.second->connections()) if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) { RTLIL::SigSpec sig = sigmap(conn.second); @@ -179,7 +179,7 @@ struct SpliceWorker if (design->selected(module, it.second)) selected_bits.add(sigmap(it.second)); - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (!sel_by_wire && !design->selected(module, it.second)) continue; for (auto &conn : it.second->connections_) diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index accb178b..0998a162 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -131,7 +131,7 @@ struct SplitnetsPass : public Pass { std::map> split_wires_at; - for (auto &c : module->cells) + for (auto &c : module->cells_) for (auto &p : c.second->connections()) { if (!ct.cell_known(c.second->type)) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index fabf1a73..153226ab 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -90,7 +90,7 @@ namespace num_memory_bits += it.second->width * it.second->size; } - for (auto &it : mod->cells) { + for (auto &it : mod->cells_) { if (!design->selected(mod, it.second)) continue; num_cells++; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index cb420f90..e1528f31 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -159,7 +159,7 @@ struct FsmDetectPass : public Pass { sig2driver.clear(); sig2user.clear(); sig_at_port.clear(); - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) for (auto &conn_it : cell_it.second->connections()) { if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) { RTLIL::SigSpec sig = conn_it.second; diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 186ea2fd..40ec55c1 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -205,7 +205,7 @@ struct FsmExpand assign_map.set(module); ct.setup_internals(); - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *c = cell_it.second; if (ct.cell_known(c->type) && design->selected(mod, c)) for (auto &p : c->connections()) { @@ -262,7 +262,7 @@ struct FsmExpandPass : public Pass { if (!design->selected(mod_it.second)) continue; std::vector fsm_cells; - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) fsm_cells.push_back(cell_it.second); for (auto c : fsm_cells) { diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index cc328ce3..129e7f9a 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -176,7 +176,7 @@ struct FsmExportPass : public Pass { for (auto &mod_it : design->modules) if (design->selected(mod_it.second)) - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) { attr_it = cell_it.second->attributes.find("\\fsm_export"); if (!flag_noauto || (attr_it != cell_it.second->attributes.end())) { diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 85ff4af2..64b01064 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -53,7 +53,7 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL std::set cellport_list; sig2driver.find(sig, cellport_list); for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells.at(cellport.first); + RTLIL::Cell *cell = module->cells_.at(cellport.first); if ((cell->type != "$mux" && cell->type != "$pmux" && cell->type != "$safe_pmux") || cellport.second != "\\Y") { log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); return false; @@ -179,7 +179,7 @@ static void extract_fsm(RTLIL::Wire *wire) std::set cellport_list; sig2driver.find(dff_out, cellport_list); for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells.at(cellport.first); + RTLIL::Cell *cell = module->cells_.at(cellport.first); if ((cell->type != "$dff" && cell->type != "$adff") || cellport.second != "\\Q") continue; log(" found %s cell for state register: %s\n", cell->type.c_str(), cell->name.c_str()); @@ -223,7 +223,7 @@ static void extract_fsm(RTLIL::Wire *wire) cellport_list.clear(); sig2trigger.find(dff_out, cellport_list); for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells.at(cellport.first); + RTLIL::Cell *cell = module->cells_.at(cellport.first); RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); RTLIL::SigSpec sig_y = assign_map(cell->get("\\Y")); @@ -293,7 +293,7 @@ static void extract_fsm(RTLIL::Wire *wire) cellport_list.clear(); sig2driver.find(ctrl_out, cellport_list); for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells.at(cellport.first); + RTLIL::Cell *cell = module->cells_.at(cellport.first); RTLIL::SigSpec port_sig = assign_map(cell->get(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++), unconn_sig.size()); @@ -340,7 +340,7 @@ struct FsmExtractPass : public Pass { sig2driver.clear(); sig2trigger.clear(); - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) for (auto &conn_it : cell_it.second->connections()) { if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) { RTLIL::SigSpec sig = conn_it.second; diff --git a/passes/fsm/fsm_info.cc b/passes/fsm/fsm_info.cc index f2d0c1a8..4526939c 100644 --- a/passes/fsm/fsm_info.cc +++ b/passes/fsm/fsm_info.cc @@ -45,7 +45,7 @@ struct FsmInfoPass : public Pass { for (auto &mod_it : design->modules) if (design->selected(mod_it.second)) - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) { log("\n"); log("FSM `%s' from module `%s':\n", cell_it.second->name.c_str(), mod_it.first.c_str()); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 7ab15954..f6ef12a7 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -313,7 +313,7 @@ struct FsmMapPass : public Pass { if (!design->selected(mod_it.second)) continue; std::vector fsm_cells; - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) fsm_cells.push_back(cell_it.second); for (auto cell : fsm_cells) diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 1441378a..165b0974 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -290,7 +290,7 @@ struct FsmOptPass : public Pass { for (auto &mod_it : design->modules) { if (design->selected(mod_it.second)) - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" and design->selected(mod_it.second, cell_it.second)) FsmData::optimize_fsm(cell_it.second, mod_it.second); } diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index b0228796..1b2eeb23 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -146,7 +146,7 @@ struct FsmRecodePass : public Pass { for (auto &mod_it : design->modules) if (design->selected(mod_it.second)) - for (auto &cell_it : mod_it.second->cells) + for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) fsm_recode(cell_it.second, mod_it.second, fm_set_fsm_file, default_encoding); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index a266c344..550ec39f 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -38,7 +38,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell std::set found_celltypes; for (auto i1 : design->modules) - for (auto i2 : i1.second->cells) + for (auto i2 : i1.second->cells_) { RTLIL::Cell *cell = i2.second; if (cell->type[0] == '$' || design->modules.count(cell->type) > 0) @@ -56,7 +56,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell log("Generate module for cell type %s:\n", celltype.c_str()); for (auto i1 : design->modules) - for (auto i2 : i1.second->cells) + for (auto i2 : i1.second->cells_) if (i2.second->type == celltype) { for (auto &conn : i2.second->connections()) { if (conn.first[0] != '$') @@ -137,7 +137,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla std::map> array_cells; std::string filename; - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; @@ -252,7 +252,7 @@ static void hierarchy_worker(RTLIL::Design *design, std::set &us log("Used module: %*s%s\n", indent, "", mod->name.c_str()); used.insert(mod); - for (auto &it : mod->cells) { + for (auto &it : mod->cells_) { if (design->modules.count(it.second->type) > 0) hierarchy_worker(design, used, design->modules[it.second->type], indent+4); } @@ -479,7 +479,7 @@ struct HierarchyPass : public Pass { std::vector> pos_work; for (auto &mod_it : design->modules) - for (auto &cell_it : mod_it.second->cells) { + for (auto &cell_it : mod_it.second->cells_) { RTLIL::Cell *cell = cell_it.second; if (design->modules.count(cell->type) == 0) continue; diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 774aabae..37410275 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -87,7 +87,7 @@ struct SubmodWorker flag_signal(conn.second, true, true, true, false, false); } } - for (auto &it : module->cells) { + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; if (submod.cells.count(cell) > 0) continue; @@ -215,7 +215,7 @@ struct SubmodWorker for (auto &it : module->wires_) it.second->attributes.erase("\\submod"); - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].bits.size() == 0) { @@ -239,7 +239,7 @@ struct SubmodWorker } else { - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; if (!design->selected(module, cell)) diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index a8caf883..d5995ee0 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -61,7 +61,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) std::vector del_cells; std::vector memcells; - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if ((cell->type == "$memwr" || cell->type == "$memrd") && cell->parameters["\\MEMID"].decode_string() == memory->name) memcells.push_back(cell); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index b63b3aec..bb8b052d 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -38,7 +38,7 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI if (bit.wire == NULL) continue; - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; @@ -120,7 +120,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$dff") { RTLIL::SigSpec new_q = cell->get("\\Q"); @@ -170,7 +170,7 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) static void handle_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_wr_only) { - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { if (!design->selected(module, cell_it.second)) continue; if (cell_it.second->type == "$memwr" && !cell_it.second->parameters["\\CLK_ENABLE"].as_bool()) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 4f166653..4bb0c8cc 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -295,7 +295,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) static void handle_module(RTLIL::Design *design, RTLIL::Module *module) { std::vector cells; - for (auto &it : module->cells) + for (auto &it : module->cells_) if (it.second->type == "$mem" && design->selected(module, it.second)) cells.push_back(it.second); for (auto cell : cells) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index 35a28d17..b25cf73a 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -143,7 +143,7 @@ struct MemoryShareWorker non_feedback_nets.insert(bits.begin(), bits.end()); } - for (auto cell_it : module->cells) + for (auto cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; bool ignore_data_port = false; @@ -650,7 +650,7 @@ struct MemoryShareWorker std::map, std::vector>> memindex; sigmap_xmux = sigmap; - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index f0835076..48b83f5f 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -80,11 +80,11 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) static void handle_module(RTLIL::Design *design, RTLIL::Module *module) { std::vector memcells; - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) if (cell_it.second->type == "$mem" && design->selected(module, cell_it.second)) memcells.push_back(cell_it.first); for (auto &it : memcells) - handle_memory(module, module->cells.at(it)); + handle_memory(module, module->cells_.at(it)); } struct MemoryUnpackPass : public Pass { diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 9542e10d..4cc5fc89 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -38,7 +38,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) std::set> queue, unused; SigSet wire2driver; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; for (auto &it2 : cell->connections()) { if (!ct.cell_input(cell->type, it2.first)) { @@ -155,7 +155,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool SigPool connected_signals; if (!purge_mode) - for (auto &it : module->cells) { + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; if (ct_reg.cell_known(cell->type)) for (auto &it2 : cell->connections()) @@ -168,7 +168,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool SigMap assign_map(module); std::set direct_sigs; std::set direct_wires; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; if (ct_all.cell_known(cell->type)) for (auto &it2 : cell->connections()) @@ -193,7 +193,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool SigPool used_signals; SigPool used_signals_nodrivers; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; for (auto &it2 : cell->connections_) { assign_map.apply(it2.second); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 290d4ffd..39e2254e 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -37,7 +37,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) SigPool used_signals; SigPool all_signals; - for (auto &it : module->cells) + for (auto &it : module->cells_) for (auto &conn : it.second->connections()) { if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) driven_signals.add(sigmap(conn.second)); @@ -199,8 +199,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo std::map invert_map; std::vector cells; - cells.reserve(module->cells.size()); - for (auto &cell_it : module->cells) + cells.reserve(module->cells_.size()); + for (auto &cell_it : module->cells_) if (design->selected(module, cell_it.second)) { if ((cell_it.second->type == "$_INV_" || cell_it.second->type == "$not" || cell_it.second->type == "$logic_not") && cell_it.second->get("\\A").size() == 1 && cell_it.second->get("\\Y").size() == 1) diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 16dedef5..1d4916b5 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -83,7 +83,7 @@ struct OptMuxtreeWorker // .ctrl_sigs // .input_sigs // .const_activated - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 1f8648c4..d7de7235 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -254,14 +254,14 @@ struct OptReduceWorker did_something = true; SigPool mem_wren_sigs; - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mem") mem_wren_sigs.add(assign_map(cell->get("\\WR_EN"))); if (cell->type == "$memwr") mem_wren_sigs.add(assign_map(cell->get("\\EN"))); } - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->get("\\Q")))) mem_wren_sigs.add(assign_map(cell->get("\\D"))); @@ -270,7 +270,7 @@ struct OptReduceWorker bool keep_expanding_mem_wren_sigs = true; while (keep_expanding_mem_wren_sigs) { keep_expanding_mem_wren_sigs = false; - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->get("\\Y")))) { if (!mem_wren_sigs.check_all(assign_map(cell->get("\\A"))) || @@ -295,7 +295,7 @@ struct OptReduceWorker SigSet drivers; std::set cells; - for (auto &cell_it : module->cells) { + for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type != type || !design->selected(module, cell)) continue; @@ -313,7 +313,7 @@ struct OptReduceWorker std::vector cells; - for (auto &it : module->cells) + for (auto &it : module->cells_) if ((it.second->type == "$mux" || it.second->type == "$pmux" || it.second->type == "$safe_pmux") && design->selected(module, it.second)) cells.push_back(it.second); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index b26e8b37..14b734d7 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -179,7 +179,7 @@ struct OptRmdffPass : public Pass { mux_drivers.clear(); std::vector dff_list; - for (auto &it : mod_it.second->cells) { + for (auto &it : mod_it.second->cells_) { if (it.second->type == "$mux" || it.second->type == "$pmux") { if (it.second->get("\\A").size() == it.second->get("\\B").size()) mux_drivers.insert(assign_map(it.second->get("\\Y")), it.second); @@ -202,8 +202,8 @@ struct OptRmdffPass : public Pass { } for (auto &id : dff_list) { - if (mod_it.second->cells.count(id) > 0 && - handle_dff(mod_it.second, mod_it.second->cells[id])) + if (mod_it.second->cells_.count(id) > 0 && + handle_dff(mod_it.second, mod_it.second->cells_[id])) total_count++; } } diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index c91f037d..304ba9f8 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -248,8 +248,8 @@ struct OptShareWorker cell_hash_cache.clear(); #endif std::vector cells; - cells.reserve(module->cells.size()); - for (auto &it : module->cells) { + cells.reserve(module->cells_.size()); + for (auto &it : module->cells_) { if (ct.cell_known(it.second->type) && design->selected(module, it.second)) cells.push_back(it.second); } diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 565d86a7..63d04d35 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -33,7 +33,7 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp if (signal == ref) return true; - for (auto &cell_it : mod->cells) { + for (auto &cell_it : mod->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$reduce_or" && cell->get("\\Y") == signal) return check_signal(mod, cell->get("\\A"), ref, polarity); diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index d4ff2a86..45423326 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -147,7 +147,7 @@ struct VlogHammerReporter SatGen satgen(&ez, &sigmap); satgen.model_undef = model_undef; - for (auto &c : module->cells) + for (auto &c : module->cells_) if (!satgen.importCell(c.second)) log_error("Failed to import cell %s (type %s) to SAT database.\n", RTLIL::id2cstr(c.first), RTLIL::id2cstr(c.second->type)); diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index c30e6e0c..24b812bb 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -82,7 +82,7 @@ static void find_dff_wires(std::set &dff_wires, RTLIL::Module *modu SigMap sigmap(module); SigPool dffsignals; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (ct.cell_known(it.second->type) && it.second->has("\\Q")) dffsignals.add(sigmap(it.second->get("\\Q"))); } @@ -98,7 +98,7 @@ static void create_dff_dq_map(std::map &map, RTLIL: std::map bit_info; SigMap sigmap(module); - for (auto &it : module->cells) + for (auto &it : module->cells_) { if (!design->selected(module, it.second)) continue; @@ -371,7 +371,7 @@ struct ExposePass : public Pass { shared_wires.insert(it.first); if (flag_evert) - for (auto &it : module->cells) + for (auto &it : module->cells_) if (design->selected(module, it.second) && consider_cell(design, dff_cells[module], it.second)) shared_cells.insert(it.first); @@ -409,16 +409,16 @@ struct ExposePass : public Pass { { RTLIL::Cell *cell; - if (module->cells.count(it) == 0) + if (module->cells_.count(it) == 0) goto delete_shared_cell; - cell = module->cells.at(it); + cell = module->cells_.at(it); if (!design->selected(module, cell)) goto delete_shared_cell; if (!consider_cell(design, dff_cells[module], cell)) goto delete_shared_cell; - if (!compare_cells(first_module->cells.at(it), cell)) + if (!compare_cells(first_module->cells_.at(it), cell)) goto delete_shared_cell; if (0) @@ -475,7 +475,7 @@ struct ExposePass : public Pass { if (flag_cut) { - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (!ct.cell_known(it.second->type)) continue; for (auto &conn : it.second->connections_) @@ -503,7 +503,7 @@ struct ExposePass : public Pass { RTLIL::Wire *wire_dummy_q = add_new_wire(module, NEW_ID, 0); for (auto &cell_name : info.cells) { - RTLIL::Cell *cell = module->cells.at(cell_name); + RTLIL::Cell *cell = module->cells_.at(cell_name); std::vector cell_q_bits = sigmap(cell->get("\\Q")).to_sigbit_vector(); for (auto &bit : cell_q_bits) if (wire_bits_set.count(bit)) @@ -571,7 +571,7 @@ struct ExposePass : public Pass { { std::vector delete_cells; - for (auto &it : module->cells) + for (auto &it : module->cells_) { if (flag_shared) { if (shared_cells.count(it.first) == 0) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 5d23318c..f8d5cf6c 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -607,7 +607,7 @@ struct FreduceWorker batches.push_back(sigmap(it.second).to_sigbit_set()); bits_full_total += it.second->width; } - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (ct.cell_known(it.second->type)) { std::set inputs, outputs; for (auto &port : it.second->connections()) { diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 90c67116..3e1c7222 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -317,7 +317,7 @@ struct SatHelper } int import_cell_counter = 0; - for (auto &c : module->cells) + for (auto &c : module->cells_) if (design->selected(module, c.second)) { // log("Import cell: %s\n", RTLIL::id2cstr(c.first)); if (satgen.importCell(c.second, timestep)) { diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 0ee5af18..facacf19 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -61,7 +61,7 @@ struct ShareWorker queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end()); - for (auto &it : module->cells) + for (auto &it : module->cells_) if (!fwd_ct.cell_known(it.second->type)) { std::set &bits = modwalker.cell_inputs[it.second]; queue_bits.insert(bits.begin(), bits.end()); @@ -101,7 +101,7 @@ struct ShareWorker void find_shareable_cells() { - for (auto &it : module->cells) + for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index eabc56bd..01284656 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -388,7 +388,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) log("Mapping DFF cells in module `%s':\n", module->name.c_str()); std::vector cell_list; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0) cell_list.push_back(it.second); } diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 813e0e3e..b66a11b8 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -182,7 +182,7 @@ namespace std::map, int> sig_use_count; if (max_fanout > 0) - for (auto &cell_it : mod->cells) + for (auto &cell_it : mod->cells_) { RTLIL::Cell *cell = cell_it.second; if (!sel || sel->selected(mod, cell)) @@ -196,7 +196,7 @@ namespace } // create graph nodes from cells - for (auto &cell_it : mod->cells) + for (auto &cell_it : mod->cells_) { RTLIL::Cell *cell = cell_it.second; if (sel && !sel->selected(mod, cell)) @@ -253,7 +253,7 @@ namespace } // mark external signals (used in non-selected cells) - for (auto &cell_it : mod->cells) + for (auto &cell_it : mod->cells_) { RTLIL::Cell *cell = cell_it.second; if (sel && !sel->selected(mod, cell)) diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 355c07c8..8c7f6423 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -439,7 +439,7 @@ struct SimplemapPass : public Pass { if (!design->selected(mod_it.second)) continue; std::vector delete_cells; - for (auto &cell_it : mod_it.second->cells) { + for (auto &cell_it : mod_it.second->cells_) { if (mappers.count(cell_it.second->type) == 0) continue; if (!design->selected(mod_it.second, cell_it.second)) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 03aac669..86d9e73a 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -116,7 +116,7 @@ struct TechmapWorker std::string orig_cell_name; if (!flatten_mode) - for (auto &it : tpl->cells) + for (auto &it : tpl->cells_) if (it.first == "\\_TECHMAP_REPLACE_") { orig_cell_name = cell->name; module->rename(cell, stringf("$techmap%d", RTLIL::autoidx++) + cell->name); @@ -180,7 +180,7 @@ struct TechmapWorker } } - for (auto &it : tpl->cells) + for (auto &it : tpl->cells_) { RTLIL::IdString c_name = it.second->name; @@ -224,15 +224,15 @@ struct TechmapWorker std::vector cell_names; SigMap sigmap(module); - for (auto &cell_it : module->cells) + for (auto &cell_it : module->cells_) cell_names.push_back(cell_it.first); for (auto &cell_name : cell_names) { - if (module->cells.count(cell_name) == 0) + if (module->cells_.count(cell_name) == 0) continue; - RTLIL::Cell *cell = module->cells[cell_name]; + RTLIL::Cell *cell = module->cells_[cell_name]; if (!design->selected(module, cell) || handled_cells.count(cell) > 0) continue; From c91570bde32d59679ea8b72ed041ef8f6bb0d51a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 02:00:04 +0200 Subject: [PATCH 447/750] Mostly cosmetic changes to rtlil.h --- kernel/rtlil.h | 74 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f8d2892f..f235b1de 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -32,7 +32,7 @@ std::string stringf(const char *fmt, ...); namespace RTLIL { - enum State { + enum State : unsigned char { S0 = 0, S1 = 1, Sx = 2, // undefined value or conflict @@ -41,7 +41,7 @@ namespace RTLIL Sm = 5 // marker (used internally by some passes) }; - enum SyncType { + enum SyncType : unsigned char { ST0 = 0, // level sensitive: 0 ST1 = 1, // level sensitive: 1 STp = 2, // edge sensitive: posedge @@ -51,7 +51,7 @@ namespace RTLIL STi = 6 // init }; - enum ConstFlags { + enum ConstFlags : unsigned char { CONST_FLAG_NONE = 0, CONST_FLAG_STRING = 1, CONST_FLAG_SIGNED = 2, // only used for parameters @@ -191,67 +191,87 @@ namespace RTLIL RTLIL::Const const_neg (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); }; -struct RTLIL::Const { +struct RTLIL::Const +{ int flags; std::vector bits; + Const(); Const(std::string str); Const(int val, int width = 32); Const(RTLIL::State bit, int width = 1); Const(std::vector bits) : bits(bits) { flags = CONST_FLAG_NONE; }; + bool operator <(const RTLIL::Const &other) const; bool operator ==(const RTLIL::Const &other) const; bool operator !=(const RTLIL::Const &other) const; + bool as_bool() const; int as_int() const; std::string as_string() const; + std::string decode_string() const; }; -struct RTLIL::Selection { +struct RTLIL::Selection +{ bool full_selection; std::set selected_modules; std::map> selected_members; + Selection(bool full = true) : full_selection(full) { } + bool selected_module(RTLIL::IdString mod_name) const; bool selected_whole_module(RTLIL::IdString mod_name) const; bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const; void optimize(RTLIL::Design *design); + template void select(T1 *module) { if (!full_selection && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); selected_members.erase(module->name); } } + template void select(T1 *module, T2 *member) { if (!full_selection && selected_modules.count(module->name) == 0) selected_members[module->name].insert(member->name); } + bool empty() const { return !full_selection && selected_modules.empty() && selected_members.empty(); } }; -struct RTLIL::Design { +struct RTLIL::Design +{ std::map modules; + std::vector selection_stack; std::map selection_vars; std::string selected_active_module; + ~Design(); + void check(); void optimize(); + bool selected_module(RTLIL::IdString mod_name) const; bool selected_whole_module(RTLIL::IdString mod_name) const; bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const; + bool full_selection() const { return selection_stack.back().full_selection; } + template bool selected(T1 *module) const { return selected_module(module->name); } + template bool selected(T1 *module, T2 *member) const { return selected_member(module->name, member->name); } + template void select(T1 *module, T2 *member) { if (selection_stack.size() > 0) { RTLIL::Selection &sel = selection_stack.back(); @@ -278,13 +298,14 @@ protected: void add(RTLIL::Cell *cell); public: + std::map wires_; + std::map cells_; + std::vector connections_; + RTLIL::IdString name; std::set avail_parameters; - std::map wires_; std::map memories; - std::map cells_; std::map processes; - std::vector connections_; RTLIL_ATTRIBUTE_MEMBERS virtual ~Module(); @@ -507,10 +528,12 @@ public: template void rewrite_sigspecs(T functor); }; -struct RTLIL::SigChunk { +struct RTLIL::SigChunk +{ RTLIL::Wire *wire; RTLIL::Const data; // only used if wire == NULL, LSB at index 0 int width, offset; + SigChunk(); SigChunk(const RTLIL::Const &value); SigChunk(RTLIL::Wire *wire); @@ -519,16 +542,20 @@ struct RTLIL::SigChunk { SigChunk(int val, int width = 32); SigChunk(RTLIL::State bit, int width = 1); SigChunk(RTLIL::SigBit bit); + RTLIL::SigChunk extract(int offset, int length) const; + bool operator <(const RTLIL::SigChunk &other) const; bool operator ==(const RTLIL::SigChunk &other) const; bool operator !=(const RTLIL::SigChunk &other) const; }; -struct RTLIL::SigBit { +struct RTLIL::SigBit +{ RTLIL::Wire *wire; RTLIL::State data; int offset; + SigBit() : wire(NULL), data(RTLIL::State::S0), offset(0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit), offset(0) { } SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { assert(!wire || wire->width == 1); } @@ -536,26 +563,32 @@ struct RTLIL::SigBit { SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[0]), offset(chunk.offset) { assert(chunk.width == 1); } SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[index]), offset(chunk.wire ? chunk.offset + index : 0) { } SigBit(const RTLIL::SigSpec &sig); + bool operator <(const RTLIL::SigBit &other) const { return (wire != other.wire) ? (wire < other.wire) : wire ? (offset < other.offset) : (data < other.data); } + bool operator ==(const RTLIL::SigBit &other) const { return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data)); } + bool operator !=(const RTLIL::SigBit &other) const { return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data)); } }; -struct RTLIL::SigSpecIterator { +struct RTLIL::SigSpecIterator +{ RTLIL::SigSpec *sig_p; int index; + inline RTLIL::SigBit &operator*() const; inline bool operator!=(const RTLIL::SigSpecIterator &other) { return index != other.index; } inline void operator++() { index++; } }; -struct RTLIL::SigSpec { +struct RTLIL::SigSpec +{ private: int width_; unsigned long hash_; @@ -675,10 +708,12 @@ inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { *this = SigBit(sig.chunks().front()); } -struct RTLIL::CaseRule { +struct RTLIL::CaseRule +{ std::vector compare; std::vector actions; std::vector switches; + ~CaseRule(); void optimize(); @@ -686,17 +721,20 @@ struct RTLIL::CaseRule { RTLIL::CaseRule *clone() const; }; -struct RTLIL::SwitchRule { +struct RTLIL::SwitchRule +{ RTLIL::SigSpec signal; RTLIL_ATTRIBUTE_MEMBERS std::vector cases; + ~SwitchRule(); template void rewrite_sigspecs(T functor); RTLIL::SwitchRule *clone() const; }; -struct RTLIL::SyncRule { +struct RTLIL::SyncRule +{ RTLIL::SyncType type; RTLIL::SigSpec signal; std::vector actions; @@ -705,11 +743,13 @@ struct RTLIL::SyncRule { RTLIL::SyncRule *clone() const; }; -struct RTLIL::Process { +struct RTLIL::Process +{ RTLIL::IdString name; RTLIL_ATTRIBUTE_MEMBERS RTLIL::CaseRule root_case; std::vector syncs; + ~Process(); template void rewrite_sigspecs(T functor); From 7f3dc86ecd00a9ed5f5b7f09e02a6fe584259f79 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 02:11:57 +0200 Subject: [PATCH 448/750] Added RTLIL::SigSpec move constructor and move assignment operator --- kernel/rtlil.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f235b1de..97d01617 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -625,6 +625,21 @@ public: SigSpec(std::vector bits); SigSpec(std::set bits); + SigSpec(RTLIL::SigSpec &&other) { + width_ = other.width_; + hash_ = other.hash_; + chunks_.swap(other.chunks_); + bits_.swap(other.bits_); + } + + const RTLIL::SigSpec &operator=(RTLIL::SigSpec &&other) { + width_ = other.width_; + hash_ = other.hash_; + chunks_.swap(other.chunks_); + bits_.swap(other.bits_); + return *this; + } + inline const std::vector &chunks() const { pack(); return chunks_; } inline const std::vector &bits() const { inline_unpack(); return bits_; } From ddc5b4184836e795e143fc00786b4b87a6e69bc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 09:20:59 +0200 Subject: [PATCH 449/750] Using std::move() in SigSpec move constructor --- kernel/rtlil.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 97d01617..91c9a1ba 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -628,15 +628,15 @@ public: SigSpec(RTLIL::SigSpec &&other) { width_ = other.width_; hash_ = other.hash_; - chunks_.swap(other.chunks_); - bits_.swap(other.bits_); + chunks_ = std::move(other.chunks_); + bits_ = std::move(other.bits_); } const RTLIL::SigSpec &operator=(RTLIL::SigSpec &&other) { width_ = other.width_; hash_ = other.hash_; - chunks_.swap(other.chunks_); - bits_.swap(other.bits_); + chunks_ = std::move(other.chunks_); + bits_ = std::move(other.bits_); return *this; } From 1c8fdaeef86d6e33668e325556380bfa67ec0a6f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:13:22 +0200 Subject: [PATCH 450/750] Added RTLIL::ObjIterator and RTLIL::ObjRange --- kernel/rtlil.cc | 29 ++++++++++++---- kernel/rtlil.h | 89 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 7 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f307be43..5fdcb025 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -274,6 +274,12 @@ bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString me return selection_stack.back().selected_member(mod_name, memb_name); } +RTLIL::Module::Module() +{ + refcount_wires_ = 0; + refcount_cells_ = 0; +} + RTLIL::Module::~Module() { for (auto it = wires_.begin(); it != wires_.end(); it++) @@ -772,6 +778,9 @@ void RTLIL::Module::optimize() void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const { + log_assert(new_mod->refcount_wires_ == 0); + log_assert(new_mod->refcount_cells_ == 0); + new_mod->name = name; new_mod->connections_ = connections_; new_mod->attributes = attributes; @@ -815,15 +824,17 @@ RTLIL::Module *RTLIL::Module::clone() const void RTLIL::Module::add(RTLIL::Wire *wire) { - assert(!wire->name.empty()); - assert(count_id(wire->name) == 0); + log_assert(!wire->name.empty()); + log_assert(count_id(wire->name) == 0); + log_assert(refcount_wires_ == 0); wires_[wire->name] = wire; } void RTLIL::Module::add(RTLIL::Cell *cell) { - assert(!cell->name.empty()); - assert(count_id(cell->name) == 0); + log_assert(!cell->name.empty()); + log_assert(count_id(cell->name) == 0); + log_assert(refcount_cells_ == 0); cells_[cell->name] = cell; } @@ -856,20 +867,24 @@ void RTLIL::Module::remove(RTLIL::Wire *wire) void RTLIL::Module::remove(const std::set &wires) { + log_assert(refcount_wires_ == 0); + DeleteWireWorker delete_wire_worker; delete_wire_worker.module = this; delete_wire_worker.wires_p = &wires; rewrite_sigspecs(delete_wire_worker); for (auto &it : wires) { - this->wires_.erase(it->name); + log_assert(wires_.count(it->name) != 0); + wires_.erase(it->name); delete it; } } void RTLIL::Module::remove(RTLIL::Cell *cell) { - assert(cells_.count(cell->name) != 0); + log_assert(cells_.count(cell->name) != 0); + log_assert(refcount_cells_ == 0); cells_.erase(cell->name); delete cell; } @@ -877,6 +892,7 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) { assert(wires_[wire->name] == wire); + log_assert(refcount_wires_ == 0); wires_.erase(wire->name); wire->name = new_name; add(wire); @@ -885,6 +901,7 @@ void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name) { assert(cells_[cell->name] == cell); + log_assert(refcount_wires_ == 0); cells_.erase(cell->name); cell->name = new_name; add(cell); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 91c9a1ba..be282270 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -189,6 +189,86 @@ namespace RTLIL RTLIL::Const const_pos (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_bu0 (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_neg (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); + + + // This iterator-range-pair is used for Design::modules(), Module::wires() and Module::cells(). + // It maintains a reference counter that is used to make sure that the container is not modified while being iterated over. + + template + struct ObjIterator + { + typename std::map::iterator it; + std::map *list_p; + int *refcount_p; + + ObjIterator() : list_p(nullptr), refcount_p(nullptr) { + } + + ObjIterator(decltype(list_p) list_p, int *refcount_p) : list_p(list_p), refcount_p(refcount_p) { + if (list_p->empty()) { + this->list_p = nullptr; + this->refcount_p = nullptr; + } else { + it = list_p->begin(); + (*refcount_p)++; + } + } + + ObjIterator(const RTLIL::ObjIterator &other) { + it = other.it; + list_p = other.list_p; + refcount_p = other.refcount_p; + if (refcount_p) + (*refcount_p)++; + } + + ObjIterator &operator=(const RTLIL::ObjIterator &other) { + if (refcount_p) + (*refcount_p)--; + it = other.it; + list_p = other.list_p; + refcount_p = other.refcount_p; + if (refcount_p) + (*refcount_p)++; + return *this; + } + + ~ObjIterator() { + if (refcount_p) + (*refcount_p)--; + } + + inline T operator*() const { + assert(list_p != nullptr); + return it->second; + } + + inline bool operator!=(const RTLIL::ObjIterator &other) const { + if (list_p == nullptr || other.list_p == nullptr) + return list_p != other.list_p; + return it != other.it; + } + + inline void operator++() { + assert(list_p != nullptr); + if (++it == list_p->end()) { + (*refcount_p)--; + list_p = nullptr; + refcount_p = nullptr; + } + } + }; + + template + struct ObjRange + { + std::map *list_p; + int *refcount_p; + + ObjRange(decltype(list_p) list_p, int *refcount_p) : list_p(list_p), refcount_p(refcount_p) { } + RTLIL::ObjIterator begin() { return RTLIL::ObjIterator(list_p, refcount_p); } + RTLIL::ObjIterator end() { return RTLIL::ObjIterator(); } + }; }; struct RTLIL::Const @@ -298,6 +378,9 @@ protected: void add(RTLIL::Cell *cell); public: + int refcount_wires_; + int refcount_cells_; + std::map wires_; std::map cells_; std::vector connections_; @@ -308,6 +391,7 @@ public: std::map processes; RTLIL_ATTRIBUTE_MEMBERS + Module(); virtual ~Module(); virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); virtual size_t count_id(RTLIL::IdString id); @@ -323,6 +407,9 @@ public: void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; + RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } + RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } + // Removing wires is expensive. If you have to remove wires, remove them all at once. void remove(const std::set &wires); void remove(RTLIL::Cell *cell); @@ -583,7 +670,7 @@ struct RTLIL::SigSpecIterator int index; inline RTLIL::SigBit &operator*() const; - inline bool operator!=(const RTLIL::SigSpecIterator &other) { return index != other.index; } + inline bool operator!=(const RTLIL::SigSpecIterator &other) const { return index != other.index; } inline void operator++() { index++; } }; From d088854b47f5f77c6a62be2ba4b895164938d7a2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:41:06 +0200 Subject: [PATCH 451/750] Added conversion from ObjRange to std::vector and std::set --- kernel/rtlil.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index be282270..2fbfe804 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -268,6 +268,21 @@ namespace RTLIL ObjRange(decltype(list_p) list_p, int *refcount_p) : list_p(list_p), refcount_p(refcount_p) { } RTLIL::ObjIterator begin() { return RTLIL::ObjIterator(list_p, refcount_p); } RTLIL::ObjIterator end() { return RTLIL::ObjIterator(); } + + operator std::set() const { + std::set result; + for (auto &it : *list_p) + result.insert(it.second); + return result; + } + + operator std::vector() const { + std::vector result; + result.reserve(list_p->size()); + for (auto &it : *list_p) + result.push_back(it.second); + return result; + } }; }; From 10e5791c5e5660cb784503d36439ee90d61eb06b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:18:00 +0200 Subject: [PATCH 452/750] Refactoring: Renamed RTLIL::Design::modules to modules_ --- backends/autotest/autotest.cc | 4 +- backends/blif/blif.cc | 8 ++-- backends/btor/btor.cc | 4 +- backends/edif/edif.cc | 12 +++--- backends/ilang/ilang_backend.cc | 4 +- backends/intersynth/intersynth.cc | 2 +- backends/spice/spice.cc | 8 ++-- backends/verilog/verilog_backend.cc | 2 +- frontends/ast/ast.cc | 10 ++--- frontends/liberty/liberty.cc | 4 +- kernel/celltypes.h | 14 +++---- kernel/driver.cc | 6 +-- kernel/rtlil.cc | 18 ++++----- kernel/rtlil.h | 2 +- manual/CHAPTER_Prog/stubnets.cc | 2 +- manual/PRESENTATION_Prog/my_cmd.cc | 8 ++-- passes/abc/abc.cc | 4 +- passes/abc/blifparse.cc | 2 +- passes/cmds/add.cc | 6 +-- passes/cmds/connect.cc | 2 +- passes/cmds/connwrappers.cc | 2 +- passes/cmds/copy.cc | 8 ++-- passes/cmds/delete.cc | 6 +-- passes/cmds/design.cc | 22 +++++------ passes/cmds/rename.cc | 14 +++---- passes/cmds/scatter.cc | 2 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 40 +++++++++---------- passes/cmds/setattr.cc | 4 +- passes/cmds/setundef.cc | 2 +- passes/cmds/show.cc | 4 +- passes/cmds/splice.cc | 2 +- passes/cmds/splitnets.cc | 2 +- passes/cmds/stat.cc | 6 +-- passes/fsm/fsm_detect.cc | 2 +- passes/fsm/fsm_expand.cc | 2 +- passes/fsm/fsm_export.cc | 2 +- passes/fsm/fsm_extract.cc | 2 +- passes/fsm/fsm_info.cc | 2 +- passes/fsm/fsm_map.cc | 2 +- passes/fsm/fsm_opt.cc | 2 +- passes/fsm/fsm_recode.cc | 2 +- passes/hierarchy/hierarchy.cc | 60 ++++++++++++++--------------- passes/hierarchy/submod.cc | 12 +++--- passes/memory/memory_collect.cc | 2 +- passes/memory/memory_dff.cc | 2 +- passes/memory/memory_map.cc | 2 +- passes/memory/memory_share.cc | 2 +- passes/memory/memory_unpack.cc | 2 +- passes/opt/opt_clean.cc | 4 +- passes/opt/opt_const.cc | 2 +- passes/opt/opt_muxtree.cc | 2 +- passes/opt/opt_reduce.cc | 2 +- passes/opt/opt_rmdff.cc | 2 +- passes/opt/opt_share.cc | 2 +- passes/proc/proc_arst.cc | 2 +- passes/proc/proc_clean.cc | 2 +- passes/proc/proc_dff.cc | 2 +- passes/proc/proc_init.cc | 2 +- passes/proc/proc_mux.cc | 2 +- passes/proc/proc_rmdead.cc | 2 +- passes/sat/eval.cc | 12 +++--- passes/sat/expose.cc | 12 +++--- passes/sat/freduce.cc | 2 +- passes/sat/miter.cc | 12 +++--- passes/sat/sat.cc | 2 +- passes/sat/share.cc | 2 +- passes/techmap/dfflibmap.cc | 2 +- passes/techmap/extract.cc | 12 +++--- passes/techmap/hilomap.cc | 2 +- passes/techmap/iopadmap.cc | 2 +- passes/techmap/simplemap.cc | 2 +- passes/techmap/techmap.cc | 22 +++++------ 73 files changed, 223 insertions(+), 223 deletions(-) diff --git a/backends/autotest/autotest.cc b/backends/autotest/autotest.cc index 06b2c2a9..3bb0f9d6 100644 --- a/backends/autotest/autotest.cc +++ b/backends/autotest/autotest.cc @@ -91,7 +91,7 @@ static void autotest(FILE *f, RTLIL::Design *design) fprintf(f, "end\n"); fprintf(f, "endtask\n\n"); - for (auto it = design->modules.begin(); it != design->modules.end(); it++) + for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { std::map signal_in; std::map signal_const; @@ -292,7 +292,7 @@ static void autotest(FILE *f, RTLIL::Design *design) fprintf(f, "initial begin\n"); fprintf(f, "\t// $dumpfile(\"testbench.vcd\");\n"); fprintf(f, "\t// $dumpvars(0, testbench);\n"); - for (auto it = design->modules.begin(); it != design->modules.end(); it++) + for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) if (!it->second->get_bool_attribute("\\gentb_skip")) fprintf(f, "\t%s;\n", idy(it->first, "test").c_str()); fprintf(f, "\t$finish;\n"); diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 936dea02..2b783e73 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -89,9 +89,9 @@ struct BlifDumper { if (!config->gates_mode) return "subckt"; - if (!design->modules.count(RTLIL::escape_id(cell_type))) + if (!design->modules_.count(RTLIL::escape_id(cell_type))) return "gate"; - if (design->modules.at(RTLIL::escape_id(cell_type))->get_bool_attribute("\\blackbox")) + if (design->modules_.at(RTLIL::escape_id(cell_type))->get_bool_attribute("\\blackbox")) return "gate"; return "subckt"; } @@ -362,7 +362,7 @@ struct BlifBackend : public Backend { extra_args(f, filename, args, argidx); if (top_module_name.empty()) - for (auto & mod_it:design->modules) + for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) top_module_name = mod_it.first; @@ -370,7 +370,7 @@ struct BlifBackend : public Backend { std::vector mod_list; - for (auto module_it : design->modules) + for (auto module_it : design->modules_) { RTLIL::Module *module = module_it.second; if (module->get_bool_attribute("\\blackbox")) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index ef0f0dd8..4af12100 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -964,7 +964,7 @@ struct BtorBackend : public Backend { extra_args(f, filename, args, argidx); if (top_module_name.empty()) - for (auto & mod_it:design->modules) + for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) top_module_name = mod_it.first; @@ -975,7 +975,7 @@ struct BtorBackend : public Backend { std::vector mod_list; - for (auto module_it : design->modules) + for (auto module_it : design->modules_) { RTLIL::Module *module = module_it.second; if (module->get_bool_attribute("\\blackbox")) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index d23e99e7..5eff4598 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -125,11 +125,11 @@ struct EdifBackend : public Backend { extra_args(f, filename, args, argidx); if (top_module_name.empty()) - for (auto & mod_it:design->modules) + for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) top_module_name = mod_it.first; - for (auto module_it : design->modules) + for (auto module_it : design->modules_) { RTLIL::Module *module = module_it.second; if (module->get_bool_attribute("\\blackbox")) @@ -146,7 +146,7 @@ struct EdifBackend : public Backend { for (auto cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (!design->modules.count(cell->type) || design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) { + if (!design->modules_.count(cell->type) || design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) { lib_cell_ports[cell->type]; for (auto p : cell->connections()) { if (p.second.size() > 1) @@ -213,11 +213,11 @@ struct EdifBackend : public Backend { // extract module dependencies std::map> module_deps; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { module_deps[mod_it.second] = std::set(); for (auto &cell_it : mod_it.second->cells_) - if (design->modules.count(cell_it.second->type) > 0) - module_deps[mod_it.second].insert(design->modules.at(cell_it.second->type)); + if (design->modules_.count(cell_it.second->type) > 0) + module_deps[mod_it.second].insert(design->modules_.at(cell_it.second->type)); } // simple good-enough topological sort diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index be4e2777..d45e94a0 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -339,7 +339,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ if (!flag_m) { int count_selected_mods = 0; - for (auto it = design->modules.begin(); it != design->modules.end(); it++) { + for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { if (design->selected_whole_module(it->first)) flag_m = true; if (design->selected(it->second)) @@ -355,7 +355,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ fprintf(f, "autoidx %d\n", RTLIL::autoidx); } - for (auto it = design->modules.begin(); it != design->modules.end(); it++) { + for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { if (!only_selected || design->selected(it->second)) { if (only_selected) fprintf(f, "\n"); diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index a463f5ec..2f94e290 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -121,7 +121,7 @@ struct IntersynthBackend : public Backend { for (auto lib : libs) ct.setup_design(lib); - for (auto module_it : design->modules) + for (auto module_it : design->modules_) { RTLIL::Module *module = module_it.second; SigMap sigmap(module); diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index c58e4bec..283448c3 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -54,7 +54,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de std::vector port_sigs; - if (design->modules.count(cell->type) == 0) + if (design->modules_.count(cell->type) == 0) { log("Warning: no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n", RTLIL::id2cstr(cell->type), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name)); @@ -65,7 +65,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de } else { - RTLIL::Module *mod = design->modules.at(cell->type); + RTLIL::Module *mod = design->modules_.at(cell->type); std::vector ports; for (auto wire_it : mod->wires_) { @@ -171,14 +171,14 @@ struct SpiceBackend : public Backend { extra_args(f, filename, args, argidx); if (top_module_name.empty()) - for (auto & mod_it:design->modules) + for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) top_module_name = mod_it.first; fprintf(f, "* SPICE netlist generated by %s\n", yosys_version_str); fprintf(f, "\n"); - for (auto module_it : design->modules) + for (auto module_it : design->modules_) { RTLIL::Module *module = module_it.second; if (module->get_bool_attribute("\\blackbox")) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 098e29f9..f7f0ecaf 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1055,7 +1055,7 @@ struct VerilogBackend : public Backend { extra_args(f, filename, args, argidx); fprintf(f, "/* Generated by %s */\n", yosys_version_str); - for (auto it = design->modules.begin(); it != design->modules.end(); it++) { + for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { if (it->second->get_bool_attribute("\\blackbox") != blackboxes) continue; if (selected && !design->selected_whole_module(it->first)) { diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3f704bea..17041686 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 0107b974..d5f172f0 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:; } diff --git a/kernel/celltypes.h b/kernel/celltypes.h index d3c848f4..20d68d55 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -171,7 +171,7 @@ struct CellTypes if (cell_types.count(type) > 0) return true; for (auto design : designs) - if (design->modules.count(type) > 0) + if (design->modules_.count(type) > 0) return true; return false; } @@ -180,9 +180,9 @@ struct CellTypes { if (cell_types.count(type) == 0) { for (auto design : designs) - if (design->modules.count(type) > 0) { - if (design->modules.at(type)->wires_.count(port)) - return design->modules.at(type)->wires_.at(port)->port_output; + if (design->modules_.count(type) > 0) { + if (design->modules_.at(type)->wires_.count(port)) + return design->modules_.at(type)->wires_.at(port)->port_output; return false; } return false; @@ -203,9 +203,9 @@ struct CellTypes { if (cell_types.count(type) == 0) { for (auto design : designs) - if (design->modules.count(type) > 0) { - if (design->modules.at(type)->wires_.count(port)) - return design->modules.at(type)->wires_.at(port)->port_input; + if (design->modules_.count(type) > 0) { + if (design->modules_.at(type)->wires_.count(port)) + return design->modules_.at(type)->wires_.at(port)->port_input; return false; } return false; diff --git a/kernel/driver.cc b/kernel/driver.cc index edf23cd2..7a1c7ed1 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -234,14 +234,14 @@ static char *readline_obj_generator(const char *text, int state) if (design->selected_active_module.empty()) { - for (auto &it : design->modules) + for (auto &it : design->modules_) if (RTLIL::unescape_id(it.first).substr(0, len) == text) obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); } else - if (design->modules.count(design->selected_active_module) > 0) + if (design->modules_.count(design->selected_active_module) > 0) { - RTLIL::Module *module = design->modules.at(design->selected_active_module); + RTLIL::Module *module = design->modules_.at(design->selected_active_module); for (auto &it : module->wires_) if (RTLIL::unescape_id(it.first).substr(0, len) == text) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 5fdcb025..5709875e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -175,7 +175,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto mod_name : selected_modules) { - if (design->modules.count(mod_name) == 0) + if (design->modules_.count(mod_name) == 0) del_list.push_back(mod_name); selected_members.erase(mod_name); } @@ -184,7 +184,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto &it : selected_members) - if (design->modules.count(it.first) == 0) + if (design->modules_.count(it.first) == 0) del_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -192,7 +192,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) { del_list.clear(); for (auto memb_name : it.second) - if (design->modules[it.first]->count_id(memb_name) == 0) + if (design->modules_[it.first]->count_id(memb_name) == 0) del_list.push_back(memb_name); for (auto memb_name : del_list) it.second.erase(memb_name); @@ -203,8 +203,8 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) if (it.second.size() == 0) del_list.push_back(it.first); - else if (it.second.size() == design->modules[it.first]->wires_.size() + design->modules[it.first]->memories.size() + - design->modules[it.first]->cells_.size() + design->modules[it.first]->processes.size()) + else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() + + design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size()) add_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -213,7 +213,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) selected_modules.insert(mod_name); } - if (selected_modules.size() == design->modules.size()) { + if (selected_modules.size() == design->modules_.size()) { full_selection = true; selected_modules.clear(); selected_members.clear(); @@ -222,14 +222,14 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) RTLIL::Design::~Design() { - for (auto it = modules.begin(); it != modules.end(); it++) + for (auto it = modules_.begin(); it != modules_.end(); it++) delete it->second; } void RTLIL::Design::check() { #ifndef NDEBUG - for (auto &it : modules) { + for (auto &it : modules_) { assert(it.first == it.second->name); assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); it.second->check(); @@ -239,7 +239,7 @@ void RTLIL::Design::check() void RTLIL::Design::optimize() { - for (auto &it : modules) + for (auto &it : modules_) it.second->optimize(); for (auto &it : selection_stack) it.optimize(this); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 2fbfe804..7249f0ca 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -340,7 +340,7 @@ struct RTLIL::Selection struct RTLIL::Design { - std::map modules; + std::map modules_; std::vector selection_stack; std::map selection_vars; diff --git a/manual/CHAPTER_Prog/stubnets.cc b/manual/CHAPTER_Prog/stubnets.cc index a5790743..4d1452c9 100644 --- a/manual/CHAPTER_Prog/stubnets.cc +++ b/manual/CHAPTER_Prog/stubnets.cc @@ -120,7 +120,7 @@ struct StubnetsPass : public Pass { // call find_stub_nets() for each module that is either // selected as a whole or contains selected objects. - for (auto &it : design->modules) + for (auto &it : design->modules_) if (design->selected_module(it.first)) find_stub_nets(design, it.second, report_bits); } diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/manual/PRESENTATION_Prog/my_cmd.cc index c724ce37..8dc72c75 100644 --- a/manual/PRESENTATION_Prog/my_cmd.cc +++ b/manual/PRESENTATION_Prog/my_cmd.cc @@ -12,7 +12,7 @@ struct MyPass : public Pass { log(" %s\n", arg.c_str()); log("Modules in current design:\n"); - for (auto &mod : design->modules) + for (auto &mod : design->modules_) log(" %s (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), mod.second->wires_.size(), mod.second->cells_.size()); } @@ -40,11 +40,11 @@ struct Test1Pass : public Pass { log("Name of this module: %s\n", RTLIL::id2cstr(module->name)); - if (design->modules.count(module->name) != 0) + if (design->modules_.count(module->name) != 0) log_error("A module with the name %s already exists!\n", RTLIL::id2cstr(module->name)); - design->modules[module->name] = module; + design->modules_[module->name] = module; } } Test1Pass; @@ -56,7 +56,7 @@ struct Test2Pass : public Pass { if (design->selection_stack.back().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); - RTLIL::Module *module = design->modules.at("\\test"); + RTLIL::Module *module = design->modules_.at("\\test"); RTLIL::SigSpec a(module->wires_.at("\\a")), x(module->wires_.at("\\x")), y(module->wires_.at("\\y")); diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 7ba9424e..03fc9f93 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -684,7 +684,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std free(p); log_header("Re-integrating ABC results.\n"); - RTLIL::Module *mapped_mod = mapped_design->modules["\\netlist"]; + RTLIL::Module *mapped_mod = mapped_design->modules_["\\netlist"]; if (mapped_mod == NULL) log_error("ABC output file does not contain a module `netlist'.\n"); for (auto &it : mapped_mod->wires_) { @@ -1000,7 +1000,7 @@ struct AbcPass : public Pass { if (!constr_file.empty() && liberty_file.empty()) log_cmd_error("Got -constr but no -liberty!\n"); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) { if (mod_it.second->processes.size() > 0) log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str()); diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 773bbe5d..4bcbc013 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -60,7 +60,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) int port_count = 0; module->name = "\\netlist"; - design->modules[module->name] = module; + design->modules_[module->name] = module; size_t buffer_size = 4096; char *buffer = (char*)malloc(buffer_size); diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 49aa7c98..62995a49 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -64,10 +64,10 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n for (auto &it : module->cells_) { - if (design->modules.count(it.second->type) == 0) + if (design->modules_.count(it.second->type) == 0) continue; - RTLIL::Module *mod = design->modules.at(it.second->type); + RTLIL::Module *mod = design->modules_.at(it.second->type); if (!design->selected_whole_module(mod->name)) continue; if (mod->get_bool_attribute("\\blackbox")) @@ -136,7 +136,7 @@ struct AddPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod : design->modules) + for (auto &mod : design->modules_) { RTLIL::Module *module = mod.second; if (!design->selected_whole_module(module->name)) diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 6494ea6f..3e13fd4d 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -75,7 +75,7 @@ struct ConnectPass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { RTLIL::Module *module = NULL; - for (auto &it : design->modules) { + for (auto &it : design->modules_) { if (!design->selected(it.second)) continue; if (module != NULL) diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index cc8147c5..5125ff5e 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -197,7 +197,7 @@ struct ConnwrappersPass : public Pass { log_header("Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n"); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) worker.work(design, mod_it.second); } diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc index 4b1a8db8..fc801f61 100644 --- a/passes/cmds/copy.cc +++ b/passes/cmds/copy.cc @@ -41,14 +41,14 @@ struct CopyPass : public Pass { std::string src_name = RTLIL::escape_id(args[1]); std::string trg_name = RTLIL::escape_id(args[2]); - if (design->modules.count(src_name) == 0) + if (design->modules_.count(src_name) == 0) log_cmd_error("Can't find source module %s.\n", src_name.c_str()); - if (design->modules.count(trg_name) != 0) + if (design->modules_.count(trg_name) != 0) log_cmd_error("Target module name %s already exists.\n", trg_name.c_str()); - design->modules[trg_name] = design->modules.at(src_name)->clone(); - design->modules[trg_name]->name = trg_name; + design->modules_[trg_name] = design->modules_.at(src_name)->clone(); + design->modules_[trg_name]->name = trg_name; } } CopyPass; diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 2c2c370d..67b4d939 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -66,7 +66,7 @@ struct DeletePass : public Pass { std::vector delete_mods; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (design->selected_whole_module(mod_it.first) && !flag_input && !flag_output) { delete_mods.push_back(mod_it.first); @@ -134,8 +134,8 @@ struct DeletePass : public Pass { } for (auto &it : delete_mods) { - delete design->modules.at(it); - design->modules.erase(it); + delete design->modules_.at(it); + design->modules_.erase(it); } } } DeletePass; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 7b8889d6..bd1ee68f 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -165,7 +165,7 @@ struct DesignPass : public Pass { argidx = args.size(); } - for (auto &it : copy_from_design->modules) { + for (auto &it : copy_from_design->modules_) { if (sel.selected_whole_module(it.first)) { copy_src_modules.push_back(it.second); continue; @@ -192,10 +192,10 @@ struct DesignPass : public Pass { { std::string trg_name = as_name.empty() ? mod->name : RTLIL::escape_id(as_name); - if (copy_to_design->modules.count(trg_name)) - delete copy_to_design->modules.at(trg_name); - copy_to_design->modules[trg_name] = mod->clone(); - copy_to_design->modules[trg_name]->name = trg_name; + if (copy_to_design->modules_.count(trg_name)) + delete copy_to_design->modules_.at(trg_name); + copy_to_design->modules_[trg_name] = mod->clone(); + copy_to_design->modules_[trg_name]->name = trg_name; } } @@ -203,8 +203,8 @@ struct DesignPass : public Pass { { RTLIL::Design *design_copy = new RTLIL::Design; - for (auto &it : design->modules) - design_copy->modules[it.first] = it.second->clone(); + for (auto &it : design->modules_) + design_copy->modules_[it.first] = it.second->clone(); design_copy->selection_stack = design->selection_stack; design_copy->selection_vars = design->selection_vars; @@ -221,9 +221,9 @@ struct DesignPass : public Pass { if (reset_mode || !load_name.empty() || push_mode || pop_mode) { - for (auto &it : design->modules) + for (auto &it : design->modules_) delete it.second; - design->modules.clear(); + design->modules_.clear(); design->selection_stack.clear(); design->selection_vars.clear(); @@ -239,8 +239,8 @@ struct DesignPass : public Pass { if (pop_mode) pushed_designs.pop_back(); - for (auto &it : saved_design->modules) - design->modules[it.first] = it.second->clone(); + for (auto &it : saved_design->modules_) + design->modules_[it.first] = it.second->clone(); design->selection_stack = saved_design->selection_stack; design->selection_vars = saved_design->selection_vars; diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index c8b8160f..3a600872 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -96,7 +96,7 @@ struct RenamePass : public Pass { { extra_args(args, argidx, design); - for (auto &mod : design->modules) + for (auto &mod : design->modules_) { int counter = 0; @@ -128,7 +128,7 @@ struct RenamePass : public Pass { { extra_args(args, argidx, design); - for (auto &mod : design->modules) + for (auto &mod : design->modules_) { RTLIL::Module *module = mod.second; if (!design->selected(module)) @@ -163,19 +163,19 @@ struct RenamePass : public Pass { if (!design->selected_active_module.empty()) { - if (design->modules.count(design->selected_active_module) > 0) - rename_in_module(design->modules.at(design->selected_active_module), from_name, to_name); + if (design->modules_.count(design->selected_active_module) > 0) + rename_in_module(design->modules_.at(design->selected_active_module), from_name, to_name); } else { - for (auto &mod : design->modules) { + for (auto &mod : design->modules_) { if (mod.first == from_name || RTLIL::unescape_id(mod.first) == from_name) { to_name = RTLIL::escape_id(to_name); log("Renaming module %s to %s.\n", mod.first.c_str(), to_name.c_str()); RTLIL::Module *module = mod.second; - design->modules.erase(module->name); + design->modules_.erase(module->name); module->name = to_name; - design->modules[module->name] = module; + design->modules_[module->name] = module; goto rename_ok; } } diff --git a/passes/cmds/scatter.cc b/passes/cmds/scatter.cc index a1c12f1e..e09c0012 100644 --- a/passes/cmds/scatter.cc +++ b/passes/cmds/scatter.cc @@ -43,7 +43,7 @@ struct ScatterPass : public Pass { CellTypes ct(design); extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index c9504341..1fa1b4c9 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -280,7 +280,7 @@ struct SccPass : public Pass { RTLIL::Selection newSelection(false); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) { SccWorker worker(design, mod_it.second, allCellTypes, maxDepth); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 306b7a5b..85c52277 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -151,7 +151,7 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) RTLIL::Selection new_sel(false); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (lhs.selected_whole_module(mod_it.first)) continue; @@ -181,13 +181,13 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) { - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (lhs.selected_whole_module(mod_it.first)) { for (auto &cell_it : mod_it.second->cells_) { - if (design->modules.count(cell_it.second->type) == 0) + if (design->modules_.count(cell_it.second->type) == 0) continue; lhs.selected_modules.insert(cell_it.second->type); } @@ -205,7 +205,7 @@ static void select_op_fullmod(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) { - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (lhs.selected_whole_module(mod_it.first)) continue; @@ -260,7 +260,7 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) return; lhs.full_selection = false; - for (auto &it : design->modules) + for (auto &it : design->modules_) lhs.selected_modules.insert(it.first); } @@ -271,10 +271,10 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R for (auto &it : rhs.selected_members) { - if (design->modules.count(it.first) == 0) + if (design->modules_.count(it.first) == 0) continue; - RTLIL::Module *mod = design->modules[it.first]; + RTLIL::Module *mod = design->modules_[it.first]; if (lhs.selected_modules.count(mod->name) > 0) { @@ -304,7 +304,7 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co if (lhs.full_selection) { lhs.full_selection = false; - for (auto &it : design->modules) + for (auto &it : design->modules_) lhs.selected_modules.insert(it.first); } @@ -368,7 +368,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v { int sel_objects = 0; bool is_input, is_output; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (lhs.selected_whole_module(mod_it.first) || !lhs.selected_module(mod_it.first)) continue; @@ -684,7 +684,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } sel.full_selection = false; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (arg_mod.substr(0, 2) == "A:") { if (!match_attr(mod_it.second->attributes, arg_mod.substr(2))) @@ -1078,7 +1078,7 @@ struct SelectPass : public Pass { } if (arg == "-module" && argidx+1 < args.size()) { RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]); - if (design->modules.count(mod_name) == 0) + if (design->modules_.count(mod_name) == 0) log_cmd_error("No such module: %s\n", id2cstr(mod_name)); design->selected_active_module = mod_name; got_module = true; @@ -1147,7 +1147,7 @@ struct SelectPass : public Pass { if (work_stack.size() > 0) sel = &work_stack.back(); sel->optimize(design); - for (auto mod_it : design->modules) + for (auto mod_it : design->modules_) { if (sel->selected_whole_module(mod_it.first) && list_mode) log("%s\n", id2cstr(mod_it.first)); @@ -1217,7 +1217,7 @@ struct SelectPass : public Pass { log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); sel->optimize(design); - for (auto mod_it : design->modules) + for (auto mod_it : design->modules_) if (sel->selected_module(mod_it.first)) { for (auto &it : mod_it.second->wires_) if (sel->selected_member(mod_it.first, it.first)) @@ -1299,15 +1299,15 @@ struct CdPass : public Pass { std::string modname = RTLIL::escape_id(args[1]); - if (design->modules.count(modname) == 0 && !design->selected_active_module.empty()) { + if (design->modules_.count(modname) == 0 && !design->selected_active_module.empty()) { RTLIL::Module *module = NULL; - if (design->modules.count(design->selected_active_module) > 0) - module = design->modules.at(design->selected_active_module); + if (design->modules_.count(design->selected_active_module) > 0) + module = design->modules_.at(design->selected_active_module); if (module != NULL && module->cells_.count(modname) > 0) modname = module->cells_.at(modname)->type; } - if (design->modules.count(modname) > 0) { + if (design->modules_.count(modname) > 0) { design->selected_active_module = modname; design->selection_stack.back() = RTLIL::Selection(); select_filter_active_mod(design, design->selection_stack.back()); @@ -1368,12 +1368,12 @@ struct LsPass : public Pass { if (design->selected_active_module.empty()) { - counter += log_matches("modules", pattern, design->modules); + counter += log_matches("modules", pattern, design->modules_); } else - if (design->modules.count(design->selected_active_module) > 0) + if (design->modules_.count(design->selected_active_module) > 0) { - RTLIL::Module *module = design->modules.at(design->selected_active_module); + RTLIL::Module *module = design->modules_.at(design->selected_active_module); counter += log_matches("wires", pattern, module->wires_); counter += log_matches("memories", pattern, module->memories); counter += log_matches("cells", pattern, module->cells_); diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index ea5221f6..029c0ec7 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -98,7 +98,7 @@ struct SetattrPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod : design->modules) + for (auto &mod : design->modules_) { RTLIL::Module *module = mod.second; @@ -164,7 +164,7 @@ struct SetparamPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod : design->modules) + for (auto &mod : design->modules_) { RTLIL::Module *module = mod.second; diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index e7779415..c72e64b8 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -115,7 +115,7 @@ struct SetundefPass : public Pass { if (!got_value) log_cmd_error("One of the options -zero, -one, or -random must be specified.\n"); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { RTLIL::Module *module = mod_it.second; if (!design->selected(module)) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 18af8dfc..7ab1daf0 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -506,7 +506,7 @@ struct ShowWorker design->optimize(); page_counter = 0; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { module = mod_it.second; if (!design->selected_module(module->name)) @@ -692,7 +692,7 @@ struct ShowPass : public Pass { if (format != "ps") { int modcount = 0; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (mod_it.second->get_bool_attribute("\\blackbox")) continue; if (mod_it.second->cells_.empty() && mod_it.second->connections().empty()) diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index dcd2f819..5fce2d6c 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -327,7 +327,7 @@ struct SplicePass : public Pass { log_header("Executing SPLICE pass (creating cells for signal splicing).\n"); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 0998a162..6b1dbe13 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -117,7 +117,7 @@ struct SplitnetsPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { RTLIL::Module *module = mod_it.second; if (!design->selected(module)) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 153226ab..fabc80ec 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -166,16 +166,16 @@ struct StatPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-top" && argidx+1 < args.size()) { - if (design->modules.count(RTLIL::escape_id(args[argidx+1])) == 0) + if (design->modules_.count(RTLIL::escape_id(args[argidx+1])) == 0) log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str()); - top_mod = design->modules.at(RTLIL::escape_id(args[++argidx])); + top_mod = design->modules_.at(RTLIL::escape_id(args[++argidx])); continue; } break; } extra_args(args, argidx, design); - for (auto &it : design->modules) + for (auto &it : design->modules_) { if (!design->selected_module(it.first)) continue; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index e1528f31..a619cf57 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -148,7 +148,7 @@ struct FsmDetectPass : public Pass { ct.setup_stdcells(); ct.setup_stdcells_mem(); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 40ec55c1..f107366d 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -258,7 +258,7 @@ struct FsmExpandPass : public Pass { log_header("Executing FSM_EXPAND pass (merging auxiliary logic into FSMs).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; std::vector fsm_cells; diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index 129e7f9a..f84f372a 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -174,7 +174,7 @@ struct FsmExportPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) { diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 64b01064..99352b10 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -330,7 +330,7 @@ struct FsmExtractPass : public Pass { ct.setup_stdcells(); ct.setup_stdcells_mem(); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; diff --git a/passes/fsm/fsm_info.cc b/passes/fsm/fsm_info.cc index 4526939c..45d68a90 100644 --- a/passes/fsm/fsm_info.cc +++ b/passes/fsm/fsm_info.cc @@ -43,7 +43,7 @@ struct FsmInfoPass : public Pass { log_header("Executing FSM_INFO pass (dumping all available information on FSM cells).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) { diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index f6ef12a7..8b9ad6be 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -309,7 +309,7 @@ struct FsmMapPass : public Pass { log_header("Executing FSM_MAP pass (mapping FSMs to basic logic).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; std::vector fsm_cells; diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 165b0974..9d9156ae 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -288,7 +288,7 @@ struct FsmOptPass : public Pass { log_header("Executing FSM_OPT pass (simple optimizations of FSMs).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (design->selected(mod_it.second)) for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" and design->selected(mod_it.second, cell_it.second)) diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 1b2eeb23..40fed130 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -144,7 +144,7 @@ struct FsmRecodePass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) for (auto &cell_it : mod_it.second->cells_) if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 550ec39f..8aec25eb 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -37,11 +37,11 @@ static void generate(RTLIL::Design *design, const std::vector &cell { std::set found_celltypes; - for (auto i1 : design->modules) + for (auto i1 : design->modules_) for (auto i2 : i1.second->cells_) { RTLIL::Cell *cell = i2.second; - if (cell->type[0] == '$' || design->modules.count(cell->type) > 0) + if (cell->type[0] == '$' || design->modules_.count(cell->type) > 0) continue; for (auto &pattern : celltypes) if (!fnmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str(), FNM_NOESCAPE)) @@ -55,7 +55,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell std::map portwidths; log("Generate module for cell type %s:\n", celltype.c_str()); - for (auto i1 : design->modules) + for (auto i1 : design->modules_) for (auto i2 : i1.second->cells_) if (i2.second->type == celltype) { for (auto &conn : i2.second->connections()) { @@ -115,7 +115,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell RTLIL::Module *mod = new RTLIL::Module; mod->name = celltype; mod->attributes["\\blackbox"] = RTLIL::Const(1); - design->modules[mod->name] = mod; + design->modules_[mod->name] = mod; for (auto &decl : ports) { RTLIL::Wire *wire = mod->addWire(decl.portname, portwidths.at(decl.portname)); @@ -151,11 +151,11 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla cell->type = cell->type.substr(pos_type + 1); } - if (design->modules.count(cell->type) == 0) + if (design->modules_.count(cell->type) == 0) { - if (design->modules.count("$abstract" + cell->type)) + if (design->modules_.count("$abstract" + cell->type)) { - cell->type = design->modules.at("$abstract" + cell->type)->derive(design, cell->parameters); + cell->type = design->modules_.at("$abstract" + cell->type)->derive(design, cell->parameters); cell->parameters.clear(); did_something = true; continue; @@ -189,7 +189,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla continue; loaded_module: - if (design->modules.count(cell->type) == 0) + if (design->modules_.count(cell->type) == 0) log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str()); did_something = true; } @@ -197,10 +197,10 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla if (cell->parameters.size() == 0) continue; - if (design->modules.at(cell->type)->get_bool_attribute("\\blackbox")) + if (design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) continue; - RTLIL::Module *mod = design->modules[cell->type]; + RTLIL::Module *mod = design->modules_[cell->type]; cell->type = mod->derive(design, cell->parameters); cell->parameters.clear(); did_something = true; @@ -211,10 +211,10 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla RTLIL::Cell *cell = it.first; int idx = it.second.first, num = it.second.second; - if (design->modules.count(cell->type) == 0) + if (design->modules_.count(cell->type) == 0) log_error("Array cell `%s.%s' of unkown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); - RTLIL::Module *mod = design->modules[cell->type]; + RTLIL::Module *mod = design->modules_[cell->type]; for (auto &conn : cell->connections_) { int conn_size = conn.second.size(); @@ -253,8 +253,8 @@ static void hierarchy_worker(RTLIL::Design *design, std::set &us used.insert(mod); for (auto &it : mod->cells_) { - if (design->modules.count(it.second->type) > 0) - hierarchy_worker(design, used, design->modules[it.second->type], indent+4); + if (design->modules_.count(it.second->type) > 0) + hierarchy_worker(design, used, design->modules_[it.second->type], indent+4); } } @@ -264,7 +264,7 @@ static void hierarchy(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib, hierarchy_worker(design, used, top, 0); std::vector del_modules; - for (auto &it : design->modules) + for (auto &it : design->modules_) if (used.count(it.second) == 0) del_modules.push_back(it.second); @@ -274,7 +274,7 @@ static void hierarchy(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib, if (!purge_lib && mod->get_bool_attribute("\\blackbox")) continue; log("Removing unused module `%s'.\n", mod->name.c_str()); - design->modules.erase(mod->name); + design->modules_.erase(mod->name); delete mod; } @@ -412,11 +412,11 @@ struct HierarchyPass : public Pass { if (args[argidx] == "-top") { if (++argidx >= args.size()) log_cmd_error("Option -top requires an additional argument!\n"); - top_mod = design->modules.count(RTLIL::escape_id(args[argidx])) ? design->modules.at(RTLIL::escape_id(args[argidx])) : NULL; - if (top_mod == NULL && design->modules.count("$abstract" + RTLIL::escape_id(args[argidx]))) { + top_mod = design->modules_.count(RTLIL::escape_id(args[argidx])) ? design->modules_.at(RTLIL::escape_id(args[argidx])) : NULL; + if (top_mod == NULL && design->modules_.count("$abstract" + RTLIL::escape_id(args[argidx]))) { std::map empty_parameters; - design->modules.at("$abstract" + RTLIL::escape_id(args[argidx]))->derive(design, empty_parameters); - top_mod = design->modules.count(RTLIL::escape_id(args[argidx])) ? design->modules.at(RTLIL::escape_id(args[argidx])) : NULL; + design->modules_.at("$abstract" + RTLIL::escape_id(args[argidx]))->derive(design, empty_parameters); + top_mod = design->modules_.count(RTLIL::escape_id(args[argidx])) ? design->modules_.at(RTLIL::escape_id(args[argidx])) : NULL; } if (top_mod == NULL) log_cmd_error("Module `%s' not found!\n", args[argidx].c_str()); @@ -434,7 +434,7 @@ struct HierarchyPass : public Pass { log_push(); if (top_mod == NULL) - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (mod_it.second->get_bool_attribute("\\top")) top_mod = mod_it.second; @@ -446,13 +446,13 @@ struct HierarchyPass : public Pass { while (did_something) { did_something = false; std::vector modnames; - modnames.reserve(design->modules.size()); - for (auto &mod_it : design->modules) + modnames.reserve(design->modules_.size()); + for (auto &mod_it : design->modules_) modnames.push_back(mod_it.first); for (auto &modname : modnames) { - if (design->modules.count(modname) == 0) + if (design->modules_.count(modname) == 0) continue; - if (expand_module(design, design->modules[modname], flag_check, libdirs)) + if (expand_module(design, design->modules_[modname], flag_check, libdirs)) did_something = true; } if (did_something) @@ -465,7 +465,7 @@ struct HierarchyPass : public Pass { } if (top_mod != NULL) { - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (mod_it.second == top_mod) mod_it.second->attributes["\\top"] = RTLIL::Const(1); else @@ -478,14 +478,14 @@ struct HierarchyPass : public Pass { std::map, RTLIL::IdString> pos_map; std::vector> pos_work; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) for (auto &cell_it : mod_it.second->cells_) { RTLIL::Cell *cell = cell_it.second; - if (design->modules.count(cell->type) == 0) + if (design->modules_.count(cell->type) == 0) continue; for (auto &conn : cell->connections()) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { - pos_mods.insert(design->modules.at(cell->type)); + pos_mods.insert(design->modules_.at(cell->type)); pos_work.push_back(std::pair(mod_it.second, cell)); break; } @@ -507,7 +507,7 @@ struct HierarchyPass : public Pass { for (auto &conn : cell->connections()) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { int id = atoi(conn.first.c_str()+1); - std::pair key(design->modules.at(cell->type), id); + std::pair key(design->modules_.at(cell->type), id); if (pos_map.count(key) == 0) { log(" Failed to map positional argument %d of cell %s.%s (%s).\n", id, RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 37410275..d32b5e1d 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -105,7 +105,7 @@ struct SubmodWorker RTLIL::Module *new_mod = new RTLIL::Module; new_mod->name = submod.full_name; - design->modules[new_mod->name] = new_mod; + design->modules_[new_mod->name] = new_mod; int port_counter = 1, auto_name_counter = 1; std::set all_wire_names; @@ -229,7 +229,7 @@ struct SubmodWorker if (submodules.count(submod_str) == 0) { submodules[submod_str].name = submod_str; submodules[submod_str].full_name = module->name + "_" + submod_str; - while (design->modules.count(submodules[submod_str].full_name) != 0 || + while (design->modules_.count(submodules[submod_str].full_name) != 0 || module->count_id(submodules[submod_str].full_name) != 0) submodules[submod_str].full_name += "_"; } @@ -312,12 +312,12 @@ struct SubmodPass : public Pass { while (did_something) { did_something = false; std::vector queued_modules; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (handled_modules.count(mod_it.first) == 0 && design->selected_whole_module(mod_it.first)) queued_modules.push_back(mod_it.first); for (auto &modname : queued_modules) - if (design->modules.count(modname) != 0) { - SubmodWorker worker(design, design->modules[modname]); + if (design->modules_.count(modname) != 0) { + SubmodWorker worker(design, design->modules_[modname]); handled_modules.insert(modname); did_something = true; } @@ -328,7 +328,7 @@ struct SubmodPass : public Pass { else { RTLIL::Module *module = NULL; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected_module(mod_it.first)) continue; if (module != NULL) diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index d5995ee0..d2803ae7 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -200,7 +200,7 @@ struct MemoryCollectPass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing MEMORY_COLLECT pass (generating $mem cells).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) handle_module(design, mod_it.second); } diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index bb8b052d..9a1e9679 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -212,7 +212,7 @@ struct MemoryDffPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) handle_module(design, mod_it.second, flag_wr_only); } diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 4bb0c8cc..53394b19 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -317,7 +317,7 @@ struct MemoryMapPass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) handle_module(design, mod_it.second); } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index b25cf73a..e61661a2 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -734,7 +734,7 @@ struct MemorySharePass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing MEMORY_SHARE pass (consolidating $memrc/$memwr cells).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) MemoryShareWorker(design, mod_it.second); } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 48b83f5f..d2b9c0ee 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -102,7 +102,7 @@ struct MemoryUnpackPass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing MEMORY_UNPACK pass (generating $memrd/$memwr cells form $mem cells).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) handle_module(design, mod_it.second); } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 4cc5fc89..c219bc04 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -338,7 +338,7 @@ struct OptCleanPass : public Pass { ct_reg.setup_internals_mem(); ct_reg.setup_stdcells_mem(); - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected_whole_module(mod_it.first)) { if (design->selected(mod_it.second)) log("Skipping module %s as it is only partially selected.\n", id2cstr(mod_it.second->name)); @@ -402,7 +402,7 @@ struct CleanPass : public Pass { count_rm_cells = 0; count_rm_wires = 0; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (design->selected_whole_module(mod_it.first) && mod_it.second->processes.size() == 0) do { OPT_DID_SOMETHING = false; diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 39e2254e..bfd0161b 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -939,7 +939,7 @@ struct OptConstPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (undriven) replace_undriven(design, mod_it.second); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 1d4916b5..82cc78be 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -423,7 +423,7 @@ struct OptMuxtreePass : public Pass { extra_args(args, 1, design); int total_count = 0; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected_whole_module(mod_it.first)) { if (design->selected(mod_it.second)) log("Skipping module %s as it is only partially selected.\n", id2cstr(mod_it.second->name)); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index d7de7235..b2b7cc8b 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -367,7 +367,7 @@ struct OptReducePass : public Pass { extra_args(args, argidx, design); int total_count = 0; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; OptReduceWorker worker(design, mod_it.second, do_fine); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 14b734d7..b01778b5 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -166,7 +166,7 @@ struct OptRmdffPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 304ba9f8..45130229 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -315,7 +315,7 @@ struct OptSharePass : public Pass { extra_args(args, argidx, design); int total_count = 0; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; OptShareWorker worker(design, mod_it.second, mode_nomux); diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 63d04d35..e8439477 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -236,7 +236,7 @@ struct ProcArstPass : public Pass { extra_args(args, argidx, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) { SigMap assign_map(mod_it.second); for (auto &proc_it : mod_it.second->processes) { diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 682515c5..678d620b 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -149,7 +149,7 @@ struct ProcCleanPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { std::vector delme; if (!design->selected(mod_it.second)) continue; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index cfd2eb7a..7bd909a6 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -371,7 +371,7 @@ struct ProcDffPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) { ConstEval ce(mod_it.second); for (auto &proc_it : mod_it.second->processes) diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index 5976c216..3607905f 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -101,7 +101,7 @@ struct ProcInitPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) for (auto &proc_it : mod_it.second->processes) if (design->selected(mod_it.second, proc_it.second)) diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index 67113a68..bcbee6cf 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -276,7 +276,7 @@ struct ProcMuxPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) for (auto &proc_it : mod_it.second->processes) if (design->selected(mod_it.second, proc_it.second)) diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index d5fbef0d..e7e4bbc5 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -79,7 +79,7 @@ struct ProcRmdeadPass : public Pass { extra_args(args, 1, design); int total_counter = 0; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; for (auto &proc_it : mod_it.second->processes) { diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 45423326..8a2dd929 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -306,10 +306,10 @@ struct VlogHammerReporter { for (auto name : split(module_list, ",")) { RTLIL::IdString esc_name = RTLIL::escape_id(module_prefix + name); - if (design->modules.count(esc_name) == 0) + if (design->modules_.count(esc_name) == 0) log_error("Can't find module %s in current design!\n", name.c_str()); log("Using module %s (%s).\n", esc_name.c_str(), name.c_str()); - modules.push_back(design->modules.at(esc_name)); + modules.push_back(design->modules_.at(esc_name)); module_names.push_back(name); } @@ -416,11 +416,11 @@ struct EvalPass : public Pass { /* this should only be used for regression testing of ConstEval -- see vloghammer */ std::string mod1_name = RTLIL::escape_id(args[++argidx]); std::string mod2_name = RTLIL::escape_id(args[++argidx]); - if (design->modules.count(mod1_name) == 0) + if (design->modules_.count(mod1_name) == 0) log_error("Can't find module `%s'!\n", mod1_name.c_str()); - if (design->modules.count(mod2_name) == 0) + if (design->modules_.count(mod2_name) == 0) log_error("Can't find module `%s'!\n", mod2_name.c_str()); - BruteForceEquivChecker checker(design->modules.at(mod1_name), design->modules.at(mod2_name), args[argidx-2] == "-brute_force_equiv_checker_x"); + BruteForceEquivChecker checker(design->modules_.at(mod1_name), design->modules_.at(mod2_name), args[argidx-2] == "-brute_force_equiv_checker_x"); if (checker.errors > 0) log_cmd_error("Modules are not equivialent!\n"); log("Verified %s = %s (using brute-force check on %d cases).\n", @@ -442,7 +442,7 @@ struct EvalPass : public Pass { extra_args(args, argidx, design); RTLIL::Module *module = NULL; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) { if (module) log_cmd_error("Only one module must be selected for the EVAL pass! (selected: %s and %s)\n", diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 24b812bb..f2b89b00 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -50,7 +50,7 @@ static bool consider_cell(RTLIL::Design *design, std::set &dff_cell { if (cell->name[0] == '$' || dff_cells.count(cell->name)) return false; - if (cell->type.at(0) == '\\' && !design->modules.count(cell->type)) + if (cell->type.at(0) == '\\' && !design->modules_.count(cell->type)) return false; return true; } @@ -302,7 +302,7 @@ struct ExposePass : public Pass { RTLIL::Module *first_module = NULL; std::set shared_dff_wires; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; @@ -352,7 +352,7 @@ struct ExposePass : public Pass { { RTLIL::Module *first_module = NULL; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { RTLIL::Module *module = mod_it.second; @@ -434,7 +434,7 @@ struct ExposePass : public Pass { } } - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) { RTLIL::Module *module = mod_it.second; @@ -583,9 +583,9 @@ struct ExposePass : public Pass { RTLIL::Cell *cell = it.second; - if (design->modules.count(cell->type)) + if (design->modules_.count(cell->type)) { - RTLIL::Module *mod = design->modules.at(cell->type); + RTLIL::Module *mod = design->modules_.at(cell->type); for (auto &it : mod->wires_) { diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index f8d5cf6c..ad304c72 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -817,7 +817,7 @@ struct FreducePass : public Pass { extra_args(args, argidx, design); int bitcount = 0; - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { RTLIL::Module *module = mod_it.second; if (design->selected(module)) bitcount += FreduceWorker(design, module).run(); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 248f934c..0f00e71a 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -63,15 +63,15 @@ static void create_miter_equiv(struct Pass *that, std::vector args, std::string gate_name = RTLIL::escape_id(args[argidx++]); std::string miter_name = RTLIL::escape_id(args[argidx++]); - if (design->modules.count(gold_name) == 0) + if (design->modules_.count(gold_name) == 0) log_cmd_error("Can't find gold module %s!\n", gold_name.c_str()); - if (design->modules.count(gate_name) == 0) + if (design->modules_.count(gate_name) == 0) log_cmd_error("Can't find gate module %s!\n", gate_name.c_str()); - if (design->modules.count(miter_name) != 0) + if (design->modules_.count(miter_name) != 0) log_cmd_error("There is already a module %s!\n", gate_name.c_str()); - RTLIL::Module *gold_module = design->modules.at(gold_name); - RTLIL::Module *gate_module = design->modules.at(gate_name); + RTLIL::Module *gold_module = design->modules_.at(gold_name); + RTLIL::Module *gate_module = design->modules_.at(gate_name); for (auto &it : gold_module->wires_) { RTLIL::Wire *w1 = it.second, *w2; @@ -113,7 +113,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::Module *miter_module = new RTLIL::Module; miter_module->name = miter_name; - design->modules[miter_name] = miter_module; + design->modules_[miter_name] = miter_module; RTLIL::Cell *gold_cell = miter_module->addCell("\\gold", gold_name); RTLIL::Cell *gate_cell = miter_module->addCell("\\gate", gate_name); diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 3e1c7222..dce31206 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -1141,7 +1141,7 @@ struct SatPass : public Pass { extra_args(args, argidx, design); RTLIL::Module *module = NULL; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) { if (module) log_cmd_error("Only one module must be selected for the SAT pass! (selected: %s and %s)\n", diff --git a/passes/sat/share.cc b/passes/sat/share.cc index facacf19..671a631d 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -961,7 +961,7 @@ struct SharePass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (design->selected(mod_it.second)) ShareWorker(config, design, mod_it.second); } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 01284656..ffe24118 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -524,7 +524,7 @@ struct DfflibmapPass : public Pass { log(" final dff cell mappings:\n"); logmap_all(); - for (auto &it : design->modules) + for (auto &it : design->modules_) if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox")) dfflibmap(design, it.second); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index b66a11b8..8587f53b 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -604,9 +604,9 @@ struct ExtractPass : public Pass { delete map; log_cmd_error("Can't saved design `%s'.\n", filename.c_str()+1); } - for (auto &it : saved_designs.at(filename.substr(1))->modules) - if (!map->modules.count(it.first)) - map->modules[it.first] = it.second->clone(); + for (auto &it : saved_designs.at(filename.substr(1))->modules_) + if (!map->modules_.count(it.first)) + map->modules_[it.first] = it.second->clone(); } else { @@ -632,7 +632,7 @@ struct ExtractPass : public Pass { log_header("Creating graphs for SubCircuit library.\n"); if (!mine_mode) - for (auto &mod_it : map->modules) { + for (auto &mod_it : map->modules_) { SubCircuit::Graph mod_graph; std::string graph_name = "needle_" + RTLIL::unescape_id(mod_it.first); log("Creating needle graph %s.\n", graph_name.c_str()); @@ -643,7 +643,7 @@ struct ExtractPass : public Pass { } } - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { SubCircuit::Graph mod_graph; std::string graph_name = "haystack_" + RTLIL::unescape_id(mod_it.first); log("Creating haystack graph %s.\n", graph_name.c_str()); @@ -725,7 +725,7 @@ struct ExtractPass : public Pass { RTLIL::Module *newMod = new RTLIL::Module; newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, id2cstr(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits); - map->modules[newMod->name] = newMod; + map->modules_[newMod->name] = newMod; int portCounter = 1; for (auto wire : wires) { diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index 30977787..a3261dcc 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -104,7 +104,7 @@ struct HilomapPass : public Pass { } extra_args(args, argidx, design); - for (auto &it : design->modules) + for (auto &it : design->modules_) { module = it.second; diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 6f7427f0..10627cd1 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -111,7 +111,7 @@ struct IopadmapPass : public Pass { } extra_args(args, argidx, design); - for (auto &it : design->modules) + for (auto &it : design->modules_) { RTLIL::Module *module = it.second; diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 8c7f6423..6def1008 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -435,7 +435,7 @@ struct SimplemapPass : public Pass { std::map mappers; simplemap_get_mappers(mappers); - for (auto &mod_it : design->modules) { + for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; std::vector delete_cells; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 86d9e73a..32e18e08 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -243,7 +243,7 @@ struct TechmapWorker for (auto &tpl_name : celltypeMap.at(cell->type)) { std::string derived_name = tpl_name; - RTLIL::Module *tpl = map->modules[tpl_name]; + RTLIL::Module *tpl = map->modules_[tpl_name]; std::map parameters = cell->parameters; if (tpl->get_bool_attribute("\\blackbox")) @@ -334,7 +334,7 @@ struct TechmapWorker } else { if (cell->parameters.size() != 0) { derived_name = tpl->derive(map, parameters); - tpl = map->modules[derived_name]; + tpl = map->modules_[derived_name]; log_continue = true; } techmap_cache[key] = tpl; @@ -592,15 +592,15 @@ struct TechmapPass : public Pass { } std::map modules_new; - for (auto &it : map->modules) { + for (auto &it : map->modules_) { if (it.first.substr(0, 2) == "\\$") it.second->name = it.first.substr(1); modules_new[it.second->name] = it.second; } - map->modules.swap(modules_new); + map->modules_.swap(modules_new); std::map> celltypeMap; - for (auto &it : map->modules) { + for (auto &it : map->modules_) { if (it.second->attributes.count("\\techmap_celltype") && !it.second->attributes.at("\\techmap_celltype").bits.empty()) { char *p = strdup(it.second->attributes.at("\\techmap_celltype").decode_string().c_str()); for (char *q = strtok(p, " \t\r\n"); q; q = strtok(NULL, " \t\r\n")) @@ -614,7 +614,7 @@ struct TechmapPass : public Pass { std::set handled_cells; while (did_something) { did_something = false; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (worker.techmap_module(design, mod_it.second, map, handled_cells, celltypeMap, false)) did_something = true; if (did_something) @@ -653,12 +653,12 @@ struct FlattenPass : public Pass { TechmapWorker worker; std::map> celltypeMap; - for (auto &it : design->modules) + for (auto &it : design->modules_) celltypeMap[it.first].insert(it.first); RTLIL::Module *top_mod = NULL; if (design->full_selection()) - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (mod_it.second->get_bool_attribute("\\top")) top_mod = mod_it.second; @@ -670,7 +670,7 @@ struct FlattenPass : public Pass { if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true)) did_something = true; } else { - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (worker.techmap_module(design, mod_it.second, design, handled_cells, celltypeMap, true)) did_something = true; } @@ -680,14 +680,14 @@ struct FlattenPass : public Pass { if (top_mod != NULL) { std::map new_modules; - for (auto &mod_it : design->modules) + for (auto &mod_it : design->modules_) if (mod_it.second == top_mod || mod_it.second->get_bool_attribute("\\blackbox")) { new_modules[mod_it.first] = mod_it.second; } else { log("Deleting now unused module %s.\n", RTLIL::id2cstr(mod_it.first)); delete mod_it.second; } - design->modules.swap(new_modules); + design->modules_.swap(new_modules); } log_pop(); From 0bd8fafbd2f36f59327289e52abf962c166dab8b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:40:31 +0200 Subject: [PATCH 453/750] Added RTLIL::Design::modules() --- kernel/rtlil.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7249f0ca..6eb52cf2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -340,6 +340,7 @@ struct RTLIL::Selection struct RTLIL::Design { + int refcount_modules_; std::map modules_; std::vector selection_stack; @@ -348,6 +349,8 @@ struct RTLIL::Design ~Design(); + RTLIL::ObjRange modules() { return RTLIL::ObjRange(&modules_, &refcount_modules_); } + void check(); void optimize(); From 675cb93da9e67f5c2fe8a3760de5893176ea906d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 11:03:56 +0200 Subject: [PATCH 454/750] Added RTLIL::Module::wire(id) and cell(id) lookup functions --- kernel/rtlil.cc | 12 ++++++++++++ kernel/rtlil.h | 10 ++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 5709875e..db85f9e3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -274,6 +274,16 @@ bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString me return selection_stack.back().selected_member(mod_name, memb_name); } +bool RTLIL::Design::selected_module(RTLIL::Module *mod) const +{ + return selected_module(mod->name); +} + +bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const +{ + return selected_whole_module(mod->name); +} + RTLIL::Module::Module() { refcount_wires_ = 0; @@ -1502,6 +1512,7 @@ RTLIL::SigChunk::SigChunk(const RTLIL::Const &value) RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire) { + log_assert(wire != nullptr); this->wire = wire; this->width = wire->width; this->offset = 0; @@ -1509,6 +1520,7 @@ RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire) RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int offset, int width) { + log_assert(wire != nullptr); this->wire = wire; this->width = width; this->offset = offset; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6eb52cf2..7c69ff64 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -358,6 +358,9 @@ struct RTLIL::Design bool selected_whole_module(RTLIL::IdString mod_name) const; bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const; + bool selected_module(RTLIL::Module *mod) const; + bool selected_whole_module(RTLIL::Module *mod) const; + bool full_selection() const { return selection_stack.back().full_selection; } @@ -425,6 +428,9 @@ public: void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; + RTLIL::Wire* wire(RTLIL::IdString id) { return wires_.count(id) ? wires_.at(id) : nullptr; } + RTLIL::Cell* cell(RTLIL::IdString id) { return cells_.count(id) ? cells_.at(id) : nullptr; } + RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } @@ -663,8 +669,8 @@ struct RTLIL::SigBit SigBit() : wire(NULL), data(RTLIL::State::S0), offset(0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit), offset(0) { } - SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { assert(!wire || wire->width == 1); } - SigBit(RTLIL::Wire *wire, int offset) : wire(wire), data(RTLIL::State::S0), offset(offset) { } + SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { assert(wire && wire->width == 1); } + SigBit(RTLIL::Wire *wire, int offset) : wire(wire), data(RTLIL::State::S0), offset(offset) { assert(wire); } SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[0]), offset(chunk.offset) { assert(chunk.width == 1); } SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[index]), offset(chunk.wire ? chunk.offset + index : 0) { } SigBit(const RTLIL::SigSpec &sig); From 49f72421d5ec499da5da713466e058aae2a67436 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:41:42 +0200 Subject: [PATCH 455/750] Using new obj iterator API in a few places --- passes/memory/memory_dff.cc | 26 +++++++++++--------------- passes/opt/opt_muxtree.cc | 23 +++++++++++------------ passes/proc/proc_arst.cc | 25 +++++++++++++++---------- passes/proc/proc_clean.cc | 16 ++++++++-------- passes/proc/proc_dff.cc | 12 ++++++------ passes/proc/proc_init.cc | 10 +++++----- passes/proc/proc_mux.cc | 10 +++++----- passes/proc/proc_rmdead.cc | 10 +++++----- passes/techmap/simplemap.cc | 20 +++++++++----------- passes/techmap/techmap.cc | 20 ++++++++++---------- 10 files changed, 85 insertions(+), 87 deletions(-) diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 9a1e9679..85249142 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -38,10 +38,8 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI if (bit.wire == NULL) continue; - for (auto &cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; - if (cell->type != "$dff") continue; @@ -120,14 +118,12 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); - for (auto &cell_it : module->cells_) { - RTLIL::Cell *cell = cell_it.second; + for (auto cell : module->cells()) if (cell->type == "$dff") { RTLIL::SigSpec new_q = cell->get("\\Q"); new_q.replace(sig, new_sig); cell->set("\\Q", new_q); } - } } static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) @@ -170,13 +166,13 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) static void handle_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_wr_only) { - for (auto &cell_it : module->cells_) { - if (!design->selected(module, cell_it.second)) + for (auto cell : module->cells()) { + if (!design->selected(module, cell)) continue; - if (cell_it.second->type == "$memwr" && !cell_it.second->parameters["\\CLK_ENABLE"].as_bool()) - handle_wr_cell(module, cell_it.second); - if (!flag_wr_only && cell_it.second->type == "$memrd" && !cell_it.second->parameters["\\CLK_ENABLE"].as_bool()) - handle_rd_cell(module, cell_it.second); + if (cell->type == "$memwr" && !cell->parameters["\\CLK_ENABLE"].as_bool()) + handle_wr_cell(module, cell); + if (!flag_wr_only && cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool()) + handle_rd_cell(module, cell); } } @@ -212,9 +208,9 @@ struct MemoryDffPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - handle_module(design, mod_it.second, flag_wr_only); + for (auto mod : design->modules()) + if (design->selected(mod)) + handle_module(design, mod, flag_wr_only); } } MemoryDffPass; diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 82cc78be..73baaf90 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -83,9 +83,8 @@ struct OptMuxtreeWorker // .ctrl_sigs // .input_sigs // .const_activated - for (auto &cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") { RTLIL::SigSpec sig_a = cell->get("\\A"); @@ -136,9 +135,9 @@ struct OptMuxtreeWorker } } } - for (auto &it : module->wires_) { - if (it.second->port_output) - for (int idx : sig2bits(RTLIL::SigSpec(it.second))) + for (auto wire : module->wires()) { + if (wire->port_output) + for (int idx : sig2bits(RTLIL::SigSpec(wire))) bit2info[idx].seen_non_mux = true; } @@ -423,16 +422,16 @@ struct OptMuxtreePass : public Pass { extra_args(args, 1, design); int total_count = 0; - for (auto &mod_it : design->modules_) { - if (!design->selected_whole_module(mod_it.first)) { - if (design->selected(mod_it.second)) - log("Skipping module %s as it is only partially selected.\n", id2cstr(mod_it.second->name)); + for (auto mod : design->modules()) { + if (!design->selected_whole_module(mod)) { + if (design->selected(mod)) + log("Skipping module %s as it is only partially selected.\n", log_id(mod)); continue; } - if (mod_it.second->processes.size() > 0) { - log("Skipping module %s as it contains processes.\n", id2cstr(mod_it.second->name)); + if (mod->processes.size() > 0) { + log("Skipping module %s as it contains processes.\n", log_id(mod)); } else { - OptMuxtreeWorker worker(design, mod_it.second); + OptMuxtreeWorker worker(design, mod); total_count += worker.removed_count; } } diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index e8439477..676469fe 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -33,20 +33,24 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp if (signal == ref) return true; - for (auto &cell_it : mod->cells_) { - RTLIL::Cell *cell = cell_it.second; + for (auto cell : mod->cells()) + { if (cell->type == "$reduce_or" && cell->get("\\Y") == signal) return check_signal(mod, cell->get("\\A"), ref, polarity); + if (cell->type == "$reduce_bool" && cell->get("\\Y") == signal) return check_signal(mod, cell->get("\\A"), ref, polarity); + if (cell->type == "$logic_not" && cell->get("\\Y") == signal) { polarity = !polarity; return check_signal(mod, cell->get("\\A"), ref, polarity); } + if (cell->type == "$not" && cell->get("\\Y") == signal) { polarity = !polarity; return check_signal(mod, cell->get("\\A"), ref, polarity); } + if ((cell->type == "$eq" || cell->type == "$eqx") && cell->get("\\Y") == signal) { if (cell->get("\\A").is_fully_const()) { if (!cell->get("\\A").as_bool()) @@ -59,6 +63,7 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp return check_signal(mod, cell->get("\\A"), ref, polarity); } } + if ((cell->type == "$ne" || cell->type == "$nex") && cell->get("\\Y") == signal) { if (cell->get("\\A").is_fully_const()) { if (cell->get("\\A").as_bool()) @@ -236,14 +241,14 @@ struct ProcArstPass : public Pass { extra_args(args, argidx, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) { - SigMap assign_map(mod_it.second); - for (auto &proc_it : mod_it.second->processes) { - if (!design->selected(mod_it.second, proc_it.second)) + for (auto mod : design->modules()) + if (design->selected(mod)) { + SigMap assign_map(mod); + for (auto &proc_it : mod->processes) { + if (!design->selected(mod, proc_it.second)) continue; - proc_arst(mod_it.second, proc_it.second, assign_map); - if (global_arst.empty() || mod_it.second->wires_.count(global_arst) == 0) + proc_arst(mod, proc_it.second, assign_map); + if (global_arst.empty() || mod->wire(global_arst) == nullptr) continue; std::vector arst_actions; for (auto sync : proc_it.second->syncs) @@ -266,7 +271,7 @@ struct ProcArstPass : public Pass { if (!arst_actions.empty()) { RTLIL::SyncRule *sync = new RTLIL::SyncRule; sync->type = global_arst_neg ? RTLIL::SyncType::ST0 : RTLIL::SyncType::ST1; - sync->signal = mod_it.second->wires_.at(global_arst); + sync->signal = mod->wire(global_arst); sync->actions = arst_actions; proc_it.second->syncs.push_back(sync); } diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 678d620b..e4c52663 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -149,23 +149,23 @@ struct ProcCleanPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules_) { + for (auto mod : design->modules()) { std::vector delme; - if (!design->selected(mod_it.second)) + if (!design->selected(mod)) continue; - for (auto &proc_it : mod_it.second->processes) { - if (!design->selected(mod_it.second, proc_it.second)) + for (auto &proc_it : mod->processes) { + if (!design->selected(mod, proc_it.second)) continue; - proc_clean(mod_it.second, proc_it.second, total_count); + proc_clean(mod, proc_it.second, total_count); if (proc_it.second->syncs.size() == 0 && proc_it.second->root_case.switches.size() == 0 && proc_it.second->root_case.actions.size() == 0) { - log("Removing empty process `%s.%s'.\n", mod_it.first.c_str(), proc_it.second->name.c_str()); + log("Removing empty process `%s.%s'.\n", log_id(mod), proc_it.second->name.c_str()); delme.push_back(proc_it.first); } } for (auto &id : delme) { - delete mod_it.second->processes[id]; - mod_it.second->processes.erase(id); + delete mod->processes[id]; + mod->processes.erase(id); } } diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 7bd909a6..dc310bde 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -371,12 +371,12 @@ struct ProcDffPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) { - ConstEval ce(mod_it.second); - for (auto &proc_it : mod_it.second->processes) - if (design->selected(mod_it.second, proc_it.second)) - proc_dff(mod_it.second, proc_it.second, ce); + for (auto mod : design->modules()) + if (design->selected(mod)) { + ConstEval ce(mod); + for (auto &proc_it : mod->processes) + if (design->selected(mod, proc_it.second)) + proc_dff(mod, proc_it.second, ce); } } } ProcDffPass; diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index 3607905f..99498505 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -101,11 +101,11 @@ struct ProcInitPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - for (auto &proc_it : mod_it.second->processes) - if (design->selected(mod_it.second, proc_it.second)) - proc_init(mod_it.second, proc_it.second); + for (auto mod : design->modules()) + if (design->selected(mod)) + for (auto &proc_it : mod->processes) + if (design->selected(mod, proc_it.second)) + proc_init(mod, proc_it.second); } } ProcInitPass; diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index bcbee6cf..fb49182c 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -276,11 +276,11 @@ struct ProcMuxPass : public Pass { extra_args(args, 1, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - for (auto &proc_it : mod_it.second->processes) - if (design->selected(mod_it.second, proc_it.second)) - proc_mux(mod_it.second, proc_it.second); + for (auto mod : design->modules()) + if (design->selected(mod)) + for (auto &proc_it : mod->processes) + if (design->selected(mod, proc_it.second)) + proc_mux(mod, proc_it.second); } } ProcMuxPass; diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index e7e4bbc5..9e5f413a 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -79,18 +79,18 @@ struct ProcRmdeadPass : public Pass { extra_args(args, 1, design); int total_counter = 0; - for (auto &mod_it : design->modules_) { - if (!design->selected(mod_it.second)) + for (auto mod : design->modules()) { + if (!design->selected(mod)) continue; - for (auto &proc_it : mod_it.second->processes) { - if (!design->selected(mod_it.second, proc_it.second)) + for (auto &proc_it : mod->processes) { + if (!design->selected(mod, proc_it.second)) continue; int counter = 0; for (auto switch_it : proc_it.second->root_case.switches) proc_rmdead(switch_it, counter); if (counter > 0) log("Removed %d dead cases from process %s in module %s.\n", counter, - proc_it.first.c_str(), mod_it.first.c_str()); + proc_it.first.c_str(), log_id(mod)); total_counter += counter; } } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 6def1008..b327ba83 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -435,21 +435,19 @@ struct SimplemapPass : public Pass { std::map mappers; simplemap_get_mappers(mappers); - for (auto &mod_it : design->modules_) { - if (!design->selected(mod_it.second)) + for (auto mod : design->modules()) { + if (!design->selected(mod)) continue; - std::vector delete_cells; - for (auto &cell_it : mod_it.second->cells_) { - if (mappers.count(cell_it.second->type) == 0) + std::vector cells = mod->cells(); + for (auto cell : cells) { + if (mappers.count(cell->type) == 0) continue; - if (!design->selected(mod_it.second, cell_it.second)) + if (!design->selected(mod, cell)) continue; - log("Mapping %s.%s (%s).\n", RTLIL::id2cstr(mod_it.first), RTLIL::id2cstr(cell_it.first), RTLIL::id2cstr(cell_it.second->type)); - mappers.at(cell_it.second->type)(mod_it.second, cell_it.second); - delete_cells.push_back(cell_it.second); + log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type)); + mappers.at(cell->type)(mod, cell); + mod->remove(cell); } - for (auto c : delete_cells) - mod_it.second->remove(c); } } } SimplemapPass; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 32e18e08..bcae4409 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -658,9 +658,9 @@ struct FlattenPass : public Pass { RTLIL::Module *top_mod = NULL; if (design->full_selection()) - for (auto &mod_it : design->modules_) - if (mod_it.second->get_bool_attribute("\\top")) - top_mod = mod_it.second; + for (auto mod : design->modules()) + if (mod->get_bool_attribute("\\top")) + top_mod = mod; bool did_something = true; std::set handled_cells; @@ -670,8 +670,8 @@ struct FlattenPass : public Pass { if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true)) did_something = true; } else { - for (auto &mod_it : design->modules_) - if (worker.techmap_module(design, mod_it.second, design, handled_cells, celltypeMap, true)) + for (auto mod : design->modules()) + if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, true)) did_something = true; } } @@ -680,12 +680,12 @@ struct FlattenPass : public Pass { if (top_mod != NULL) { std::map new_modules; - for (auto &mod_it : design->modules_) - if (mod_it.second == top_mod || mod_it.second->get_bool_attribute("\\blackbox")) { - new_modules[mod_it.first] = mod_it.second; + for (auto mod : design->modules()) + if (mod == top_mod || mod->get_bool_attribute("\\blackbox")) { + new_modules[mod->name] = mod; } else { - log("Deleting now unused module %s.\n", RTLIL::id2cstr(mod_it.first)); - delete mod_it.second; + log("Deleting now unused module %s.\n", log_id(mod)); + delete mod; } design->modules_.swap(new_modules); } From 6b34215efde97fe4f1e6ecffb398455f609a9a49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 11:56:35 +0200 Subject: [PATCH 456/750] Fixed ilang parser for new RTLIL API --- frontends/ilang/parser.y | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 20490e0d..a594adfb 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 '}' { From 7661ded8ddf85e8cd80ccce0bec211d9bf46e56b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 12:00:28 +0200 Subject: [PATCH 457/750] Fixed verific bindings for new RTLIL api --- frontends/verific/Makefile.inc | 10 ++-- frontends/verific/verific.cc | 87 +++++++++++++++------------------- 2 files changed, 42 insertions(+), 55 deletions(-) diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index eca23e58..13f242c4 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 c973988b..aee38703 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); } } } From d878fcbdc76f4b612ba8578213f73f27585fc792 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 12:04:12 +0200 Subject: [PATCH 458/750] Added log_cmd_error_expection --- kernel/driver.cc | 6 +++--- kernel/log.cc | 2 +- kernel/log.h | 2 ++ passes/fsm/fsm_export.cc | 5 +---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 7a1c7ed1..380315e7 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -141,9 +141,9 @@ static void run_frontend(std::string filename, std::string command, RTLIL::Desig Pass::call(design, command); } } - catch (...) { + catch (log_cmd_error_expection) { Frontend::current_script_file = backup_script_file; - std::rethrow_exception(std::current_exception()); + throw log_cmd_error_expection(); } Frontend::current_script_file = backup_script_file; @@ -329,7 +329,7 @@ static void shell(RTLIL::Design *design) try { assert(design->selection_stack.size() == 1); Pass::call(design, command); - } catch (int) { + } catch (log_cmd_error_expection) { while (design->selection_stack.size() > 1) design->selection_stack.pop_back(); log_reset_stack(); diff --git a/kernel/log.cc b/kernel/log.cc index 63a0a84d..b8a47e1c 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -160,7 +160,7 @@ void log_cmd_error(const char *format, ...) log("ERROR: "); logv(format, ap); log_flush(); - throw 0; + throw log_cmd_error_expection(); } logv_error(format, ap); diff --git a/kernel/log.h b/kernel/log.h index 1658800d..abfb810f 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -34,6 +34,8 @@ #define S__LINE__sub1(x) S__LINE__sub2(x) #define S__LINE__ S__LINE__sub1(__LINE__) +struct log_cmd_error_expection { }; + extern std::vector log_files; extern FILE *log_errfile; extern bool log_time; diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index f84f372a..f6f9faa9 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -32,10 +32,7 @@ * Convert a signal into a KISS-compatible textual representation. */ std::string kiss_convert_signal(const RTLIL::SigSpec &sig) { - if (!sig.is_fully_const()) { - throw 0; - } - + log_assert(sig.is_fully_const()); return sig.as_const().as_string(); } From dbb3556e3f1e82a6b69d5e8714a0266c1d461c7c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 13:19:05 +0200 Subject: [PATCH 459/750] Fixed a bug in opt_clean and some RTLIL API usage cleanups --- passes/opt/opt_clean.cc | 7 ++++--- passes/opt/opt_const.cc | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index c219bc04..21bda6e4 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -219,8 +219,8 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool } std::vector maybe_del_wires; - for (auto &it : module->wires_) { - RTLIL::Wire *wire = it.second; + for (auto wire : module->wires()) + { if ((!purge_mode && check_public_name(wire->name)) || wire->port_id != 0 || wire->get_bool_attribute("\\keep")) { RTLIL::SigSpec s1 = RTLIL::SigSpec(wire), s2 = s1; assign_map.apply(s2); @@ -244,6 +244,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (!used_signals.check_any(RTLIL::SigSpec(wire))) maybe_del_wires.push_back(wire); } + RTLIL::SigSpec sig = assign_map(RTLIL::SigSpec(wire)); if (!used_signals_nodrivers.check_any(sig)) { std::string unused_bits; @@ -269,7 +270,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool std::set del_wires; int del_wires_count = 0; - for (auto wire : del_wires) + for (auto wire : maybe_del_wires) if (!used_signals.check_any(RTLIL::SigSpec(wire))) { if (check_public_name(wire->name) && verbose) { log(" removing unused non-port wire %s.\n", wire->name.c_str()); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index bfd0161b..9a21bdca 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -37,20 +37,20 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) SigPool used_signals; SigPool all_signals; - for (auto &it : module->cells_) - for (auto &conn : it.second->connections()) { - if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) { + if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) driven_signals.add(sigmap(conn.second)); - if (!ct.cell_known(it.second->type) || ct.cell_input(it.second->type, conn.first)) + if (!ct.cell_known(cell->type) || ct.cell_input(cell->type, conn.first)) used_signals.add(sigmap(conn.second)); } - for (auto &it : module->wires_) { - if (it.second->port_input) - driven_signals.add(sigmap(it.second)); - if (it.second->port_output) - used_signals.add(sigmap(it.second)); - all_signals.add(sigmap(it.second)); + for (auto wire : module->wires()) { + if (wire->port_input) + driven_signals.add(sigmap(wire)); + if (wire->port_output) + used_signals.add(sigmap(wire)); + all_signals.add(sigmap(wire)); } all_signals.del(driven_signals); From cbc3a46a9717f0f6e90b20b29c9003c3720a5aa0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 14:47:23 +0200 Subject: [PATCH 460/750] Added RTLIL::SigSpecConstIterator --- kernel/rtlil.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7c69ff64..4341e067 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -70,6 +70,7 @@ namespace RTLIL struct SigChunk; struct SigBit; struct SigSpecIterator; + struct SigSpecConstIterator; struct SigSpec; struct CaseRule; struct SwitchRule; @@ -698,6 +699,16 @@ struct RTLIL::SigSpecIterator inline void operator++() { index++; } }; +struct RTLIL::SigSpecConstIterator +{ + const RTLIL::SigSpec *sig_p; + int index; + + inline const RTLIL::SigBit &operator*() const; + inline bool operator!=(const RTLIL::SigSpecConstIterator &other) const { return index != other.index; } + inline void operator++() { index++; } +}; + struct RTLIL::SigSpec { private: @@ -762,6 +773,9 @@ public: inline RTLIL::SigSpecIterator begin() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = 0; return it; } inline RTLIL::SigSpecIterator end() { RTLIL::SigSpecIterator it; it.sig_p = this; it.index = width_; return it; } + inline RTLIL::SigSpecConstIterator begin() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = 0; return it; } + inline RTLIL::SigSpecConstIterator end() const { RTLIL::SigSpecConstIterator it; it.sig_p = this; it.index = width_; return it; } + void sort(); void sort_and_unify(); @@ -829,6 +843,10 @@ inline RTLIL::SigBit &RTLIL::SigSpecIterator::operator*() const { return (*sig_p)[index]; } +inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const { + return (*sig_p)[index]; +} + inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { assert(sig.size() == 1 && sig.chunks().size() == 1); *this = SigBit(sig.chunks().front()); From 4be645860bf83de75cdd00fbe615f3fe05221d54 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 14:47:48 +0200 Subject: [PATCH 461/750] Added RTLIL::SigSpec::remove_const() handling of packed SigSpecs --- kernel/rtlil.cc | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index db85f9e3..9f9bd7e0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1978,19 +1978,36 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) void RTLIL::SigSpec::remove_const() { - cover("kernel.rtlil.sigspec.remove_const"); + if (packed()) + { + cover("kernel.rtlil.sigspec.remove_const.packed"); - unpack(); + std::vector new_chunks; + new_chunks.reserve(SIZE(chunks_)); - std::vector new_bits; - new_bits.reserve(width_); + width_ = 0; + for (auto &chunk : chunks_) + if (chunk.wire != NULL) { + new_chunks.push_back(chunk); + width_ += chunk.width; + } - for (auto &bit : bits_) - if (bit.wire != NULL) - new_bits.push_back(bit); + chunks_.swap(new_chunks); + } + else + { + cover("kernel.rtlil.sigspec.remove_const.unpacked"); - bits_.swap(new_bits); - width_ = bits_.size(); + std::vector new_bits; + new_bits.reserve(width_); + + for (auto &bit : bits_) + if (bit.wire != NULL) + new_bits.push_back(bit); + + bits_.swap(new_bits); + width_ = bits_.size(); + } check(); } From d07a871d35401b6b8628dd3f1df3b91149e827d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 14:50:25 +0200 Subject: [PATCH 462/750] Improved performance of opt_const on large modules --- kernel/toposort.h | 103 ++++++++++++++++++++++++++++++++++++++++ passes/opt/opt_const.cc | 83 +++++++++++++++++++++----------- 2 files changed, 157 insertions(+), 29 deletions(-) create mode 100644 kernel/toposort.h diff --git a/kernel/toposort.h b/kernel/toposort.h new file mode 100644 index 00000000..7e978c1e --- /dev/null +++ b/kernel/toposort.h @@ -0,0 +1,103 @@ +/* + * 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. + * + */ + +#ifndef TOPOSORT_H +#define TOPOSORT_H + +template +struct TopoSort +{ + bool analyze_loops, found_loops; + std::map> database; + std::set> loops; + std::vector sorted; + + TopoSort() + { + analyze_loops = true; + found_loops = false; + } + + void node(T n) + { + if (database.count(n) == 0) + database[n] = std::set(); + } + + void edge(T left, T right) + { + node(left); + database[right].insert(left); + } + + void sort_worker(T n, std::set &marked_cells, std::set &active_cells, std::vector active_stack) + { + if (active_cells.count(n)) { + found_loops = false; + if (analyze_loops) { + std::set loop; + for (int i = SIZE(active_stack)-1; i >= 0; i--) { + loop.insert(active_stack[i]); + if (active_stack[i] == n) + break; + } + loops.insert(loop); + } + return; + } + + if (marked_cells.count(n)) + return; + + if (!database.at(n).empty()) + { + if (analyze_loops) + active_stack.push_back(n); + active_cells.insert(n); + + for (auto &left_n : database.at(n)) + sort_worker(left_n, marked_cells, active_cells, active_stack); + + if (analyze_loops) + active_stack.pop_back(); + active_cells.erase(n); + } + + marked_cells.insert(n); + sorted.push_back(n); + } + + bool sort() + { + loops.clear(); + sorted.clear(); + found_loops = false; + + std::set marked_cells; + std::set active_cells; + std::vector active_stack; + + for (auto &it : database) + sort_worker(it.first, marked_cells, active_cells, active_stack); + + return !found_loops; + } +}; + +#endif diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 9a21bdca..7578f192 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -21,6 +21,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/toposort.h" #include "kernel/log.h" #include #include @@ -71,7 +72,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) } } -static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) +static void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { RTLIL::SigSpec Y = cell->get(out_port); out_val.extend_u0(Y.size(), false); @@ -80,7 +81,8 @@ static void replace_cell(RTLIL::Module *module, RTLIL::Cell *cell, std::string i cell->type.c_str(), cell->name.c_str(), info.c_str(), module->name.c_str(), log_signal(Y), log_signal(out_val)); // ILANG_BACKEND::dump_cell(stderr, "--> ", cell); - module->connect(RTLIL::SigSig(Y, out_val)); + assign_map.add(Y, out_val); + module->connect(Y, out_val); module->remove(cell); OPT_DID_SOMETHING = true; did_something = true; @@ -195,22 +197,45 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (!design->selected(module)) return; + CellTypes ct_combinational; + ct_combinational.setup_internals(); + ct_combinational.setup_stdcells(); + SigMap assign_map(module); std::map invert_map; - std::vector cells; - cells.reserve(module->cells_.size()); - for (auto &cell_it : module->cells_) - if (design->selected(module, cell_it.second)) { - if ((cell_it.second->type == "$_INV_" || cell_it.second->type == "$not" || cell_it.second->type == "$logic_not") && - cell_it.second->get("\\A").size() == 1 && cell_it.second->get("\\Y").size() == 1) - invert_map[assign_map(cell_it.second->get("\\Y"))] = assign_map(cell_it.second->get("\\A")); - cells.push_back(cell_it.second); + TopoSort cells; + std::map> cell_to_inbit; + std::map> outbit_to_cell; + + for (auto cell : module->cells()) + if (design->selected(module, cell) && cell->type[0] == '$') { + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && + cell->get("\\A").size() == 1 && cell->get("\\Y").size() == 1) + invert_map[assign_map(cell->get("\\Y"))] = assign_map(cell->get("\\A")); + if (ct_combinational.cell_known(cell->type)) + for (auto &conn : cell->connections()) { + RTLIL::SigSpec sig = assign_map(conn.second); + sig.remove_const(); + if (ct_combinational.cell_input(cell->type, conn.first)) + cell_to_inbit[cell].insert(sig.begin(), sig.end()); + if (ct_combinational.cell_output(cell->type, conn.first)) + for (auto &bit : sig) + outbit_to_cell[bit].insert(cell); + } + cells.node(cell); } - for (auto cell : cells) + for (auto &it_right : cell_to_inbit) + for (auto &it_sigbit : it_right.second) + for (auto &it_left : outbit_to_cell[it_sigbit]) + cells.edge(it_left, it_right.first); + + cells.sort(); + + for (auto cell : cells.sorted) { -#define ACTION_DO(_p_, _s_) do { cover("opt.opt_const.action_" S__LINE__); replace_cell(module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) +#define ACTION_DO(_p_, _s_) do { cover("opt.opt_const.action_" S__LINE__); replace_cell(assign_map, module, cell, input.as_string(), _p_, _s_); goto next_cell; } while (0) #define ACTION_DO_Y(_v_) ACTION_DO("\\Y", RTLIL::SigSpec(RTLIL::State::S ## _v_)) if (do_fine) @@ -304,13 +329,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$logic_or" && (assign_map(cell->get("\\A")) == RTLIL::State::S1 || assign_map(cell->get("\\B")) == RTLIL::State::S1)) { cover("opt.opt_const.one_high"); - replace_cell(module, cell, "one high", "\\Y", RTLIL::State::S1); + replace_cell(assign_map, module, cell, "one high", "\\Y", RTLIL::State::S1); goto next_cell; } if (cell->type == "$logic_and" && (assign_map(cell->get("\\A")) == RTLIL::State::S0 || assign_map(cell->get("\\B")) == RTLIL::State::S0)) { cover("opt.opt_const.one_low"); - replace_cell(module, cell, "one low", "\\Y", RTLIL::State::S0); + replace_cell(assign_map, module, cell, "one low", "\\Y", RTLIL::State::S0); goto next_cell; } @@ -340,9 +365,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") - replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); + replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); else - replace_cell(module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->get("\\Y").size())); + replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->get("\\Y").size())); goto next_cell; } } @@ -350,7 +375,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->get("\\Y").size() == 1 && invert_map.count(assign_map(cell->get("\\A"))) != 0) { cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); - replace_cell(module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->get("\\A")))); + replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->get("\\A")))); goto next_cell; } @@ -476,7 +501,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type); RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S0 : RTLIL::State::S1); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); - replace_cell(module, cell, "isneq", "\\Y", new_y); + replace_cell(assign_map, module, cell, "isneq", "\\Y", new_y); goto next_cell; } if (a[i] == b[i]) @@ -489,7 +514,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type); RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S1 : RTLIL::State::S0); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); - replace_cell(module, cell, "empty", "\\Y", new_y); + replace_cell(assign_map, module, cell, "empty", "\\Y", new_y); goto next_cell; } @@ -607,7 +632,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->get("\\A") == RTLIL::SigSpec(0, 1) && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); - replace_cell(module, cell, "mux_bool", "\\Y", cell->get("\\S")); + replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->get("\\S")); goto next_cell; } @@ -674,7 +699,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->get("\\A").is_fully_undef() && cell->get("\\B").is_fully_undef()) || cell->get("\\S").is_fully_undef()) { cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); - replace_cell(module, cell, "mux_undef", "\\Y", cell->get("\\A")); + replace_cell(assign_map, module, cell, "mux_undef", "\\Y", cell->get("\\A")); goto next_cell; } for (int i = 0; i < cell->get("\\S").size(); i++) { @@ -693,12 +718,12 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_s.size() == 0) { cover_list("opt.opt_const.mux_empty", "$mux", "$pmux", cell->type); - replace_cell(module, cell, "mux_empty", "\\Y", new_a); + replace_cell(assign_map, module, cell, "mux_empty", "\\Y", new_a); goto next_cell; } if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { cover_list("opt.opt_const.mux_sel01", "$mux", "$pmux", cell->type); - replace_cell(module, cell, "mux_sel01", "\\Y", new_s); + replace_cell(assign_map, module, cell, "mux_sel01", "\\Y", new_s); goto next_cell; } if (cell->get("\\S").size() != new_s.size()) { @@ -728,7 +753,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->parameters["\\A_SIGNED"].as_bool(), false, \ cell->parameters["\\Y_WIDTH"].as_int())); \ cover("opt.opt_const.const.$" #_t); \ - replace_cell(module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ + replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), "\\Y", y); \ goto next_cell; \ } \ } @@ -743,7 +768,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->parameters["\\B_SIGNED"].as_bool(), \ cell->parameters["\\Y_WIDTH"].as_int())); \ cover("opt.opt_const.const.$" #_t); \ - replace_cell(module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), "\\Y", y); \ + replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), "\\Y", y); \ goto next_cell; \ } \ } @@ -939,17 +964,17 @@ struct OptConstPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod_it : design->modules_) + for (auto module : design->modules()) { if (undriven) - replace_undriven(design, mod_it.second); + replace_undriven(design, module); do { do { did_something = false; - replace_const_cells(design, mod_it.second, false, mux_undef, mux_bool, do_fine, keepdc); + replace_const_cells(design, module, false, mux_undef, mux_bool, do_fine, keepdc); } while (did_something); - replace_const_cells(design, mod_it.second, true, mux_undef, mux_bool, do_fine, keepdc); + replace_const_cells(design, module, true, mux_undef, mux_bool, do_fine, keepdc); } while (did_something); } From 77a1462f2d6602d5c46a2a15ca534550ec5bb9a4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 15:13:29 +0200 Subject: [PATCH 463/750] Fixed bug in opt_clean --- passes/opt/opt_clean.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 21bda6e4..76a905b2 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -251,7 +251,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (int i = 0; i < SIZE(sig); i++) { if (sig[i].wire == NULL) continue; - if (!used_signals_nodrivers.check_any(sig)) { + if (!used_signals_nodrivers.check_any(sig[i])) { if (!unused_bits.empty()) unused_bits += " "; unused_bits += stringf("%zd", i); From ddd31a0b66259a458f7bfb3475f53c30aa859bc8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 15:14:02 +0200 Subject: [PATCH 464/750] Small improvements in PerformanceTimer API --- kernel/log.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/kernel/log.h b/kernel/log.h index abfb810f..ca1e7c67 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -199,12 +199,12 @@ struct PerformanceTimer total_ns = 0; } - void add() { - total_ns += query(); + void begin() { + total_ns -= query(); } - void sub() { - total_ns -= query(); + void end() { + total_ns += query(); } float sec() const { @@ -212,8 +212,8 @@ struct PerformanceTimer } #else void reset() { } - void add() { } - void sub() { } + void begin() { } + void end() { } float sec() const { return 0; } #endif }; @@ -235,6 +235,7 @@ static inline void log_dump_val_worker(double v) { log("%f", v); } static inline void log_dump_val_worker(const char *v) { log("%s", v); } static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); } static inline void log_dump_val_worker(RTLIL::SigSpec v) { log("%s", log_signal(v)); } +static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); } static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } template From 0c86d6106c3ff4cd7628b1206281eb6080f8bf51 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 15:38:02 +0200 Subject: [PATCH 465/750] Added SigPool::check(bit) --- kernel/sigtools.h | 5 +++++ passes/opt/opt_clean.cc | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 7035db73..52e4aa0f 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -93,6 +93,11 @@ struct SigPool return result; } + bool check(RTLIL::SigBit bit) + { + return bit.wire != NULL && bits.count(bit); + } + bool check_any(RTLIL::SigSpec sig) { for (auto &bit : sig) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 76a905b2..6c20bddb 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -251,10 +251,10 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool for (int i = 0; i < SIZE(sig); i++) { if (sig[i].wire == NULL) continue; - if (!used_signals_nodrivers.check_any(sig[i])) { + if (!used_signals_nodrivers.check(sig[i])) { if (!unused_bits.empty()) unused_bits += " "; - unused_bits += stringf("%zd", i); + unused_bits += stringf("%d", i); } } if (unused_bits.empty() || wire->port_id != 0) From 5da343b7de8c4fd45695af68aaba3d5091d8e670 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 16:19:24 +0200 Subject: [PATCH 466/750] Added topological sorting to techmap --- kernel/toposort.h | 3 +- passes/techmap/techmap.cc | 72 ++++++++++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/kernel/toposort.h b/kernel/toposort.h index 7e978c1e..4226e270 100644 --- a/kernel/toposort.h +++ b/kernel/toposort.h @@ -46,7 +46,7 @@ struct TopoSort database[right].insert(left); } - void sort_worker(T n, std::set &marked_cells, std::set &active_cells, std::vector active_stack) + void sort_worker(const T &n, std::set &marked_cells, std::set &active_cells, std::vector &active_stack) { if (active_cells.count(n)) { found_loops = false; @@ -96,6 +96,7 @@ struct TopoSort for (auto &it : database) sort_worker(it.first, marked_cells, active_cells, active_stack); + log_assert(SIZE(sorted) == SIZE(database)); return !found_loops; } }; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index bcae4409..3595b7b5 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -20,6 +20,7 @@ #include "kernel/compatibility.h" #include "kernel/register.h" #include "kernel/sigtools.h" +#include "kernel/toposort.h" #include "kernel/log.h" #include #include @@ -221,25 +222,55 @@ struct TechmapWorker bool log_continue = false; bool did_something = false; - std::vector cell_names; SigMap sigmap(module); - for (auto &cell_it : module->cells_) - cell_names.push_back(cell_it.first); - for (auto &cell_name : cell_names) + TopoSort cells; + std::map> cell_to_inbit; + std::map> outbit_to_cell; + + for (auto cell : module->cells()) { - if (module->cells_.count(cell_name) == 0) - continue; - - RTLIL::Cell *cell = module->cells_[cell_name]; - if (!design->selected(module, cell) || handled_cells.count(cell) > 0) continue; if (celltypeMap.count(cell->type) == 0) continue; + for (auto &conn : cell->connections()) + { + RTLIL::SigSpec sig = sigmap(conn.second); + sig.remove_const(); + + if (SIZE(sig) == 0) + continue; + + for (auto &tpl_name : celltypeMap.at(cell->type)) { + RTLIL::Module *tpl = map->modules_[tpl_name]; + RTLIL::Wire *port = tpl->wire(conn.first); + if (port && port->port_input) + cell_to_inbit[cell].insert(sig.begin(), sig.end()); + if (port && port->port_output) + for (auto &bit : sig) + outbit_to_cell[bit].insert(cell); + } + } + + cells.node(cell); + } + + for (auto &it_right : cell_to_inbit) + for (auto &it_sigbit : it_right.second) + for (auto &it_left : outbit_to_cell[it_sigbit]) + cells.edge(it_left, it_right.first); + + cells.sort(); + + for (auto cell : cells.sorted) + { + log_assert(handled_cells.count(cell) == 0); + log_assert(cell == module->cell(cell->name)); + for (auto &tpl_name : celltypeMap.at(cell->type)) { std::string derived_name = tpl_name; @@ -610,17 +641,18 @@ struct TechmapPass : public Pass { celltypeMap[it.first].insert(it.first); } - bool did_something = true; - std::set handled_cells; - while (did_something) { - did_something = false; - for (auto &mod_it : design->modules_) - if (worker.techmap_module(design, mod_it.second, map, handled_cells, celltypeMap, false)) - did_something = true; - if (did_something) - design->check(); - if (max_iter > 0 && --max_iter == 0) - break; + for (auto module : design->modules()) { + bool did_something = true; + std::set handled_cells; + while (did_something) { + did_something = false; + if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false)) + did_something = true; + if (did_something) + module->check(); + if (max_iter > 0 && --max_iter == 0) + break; + } } log("No more expansions possible.\n"); From c4bdba78cb88df6628d975aad7a92c8cebc5d95f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 21:12:09 +0200 Subject: [PATCH 467/750] Added proper Design->addModule interface --- frontends/ast/ast.cc | 1 + kernel/rtlil.cc | 39 ++++++++++++++++++++++++++++++++++++--- kernel/rtlil.h | 7 ++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 17041686..d38cb5e3 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(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9f9bd7e0..aec0a045 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -226,6 +226,39 @@ RTLIL::Design::~Design() delete it->second; } +RTLIL::ObjRange RTLIL::Design::modules() +{ + return RTLIL::ObjRange(&modules_, &refcount_modules_); +} + +RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name) +{ + return modules_.count(name) ? modules_.at(name) : NULL; +} + +void RTLIL::Design::add(RTLIL::Module *module) +{ + assert(modules_.count(module->name) == 0); + assert(refcount_modules_ == 0); + modules_[module->name] = module; +} + +RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) +{ + assert(modules_.count(name) == 0); + assert(refcount_modules_ == 0); + modules_[name] = new RTLIL::Module; + modules_[name]->name = name; + return modules_[name]; +} + +void RTLIL::Design::remove(RTLIL::Module *module) +{ + assert(modules_.at(module->name) == module); + modules_.erase(module->name); + delete module; +} + void RTLIL::Design::check() { #ifndef NDEBUG @@ -412,7 +445,7 @@ namespace { void check() { if (cell->type[0] != '$' || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || - cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:") + cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:") return; if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") { @@ -791,7 +824,6 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const log_assert(new_mod->refcount_wires_ == 0); log_assert(new_mod->refcount_cells_ == 0); - new_mod->name = name; new_mod->connections_ = connections_; new_mod->attributes = attributes; @@ -828,6 +860,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const RTLIL::Module *RTLIL::Module::clone() const { RTLIL::Module *new_mod = new RTLIL::Module; + new_mod->name = name; cloneInto(new_mod); return new_mod; } @@ -1455,7 +1488,7 @@ void RTLIL::Cell::check() void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) { if (type[0] != '$' || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || - type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:") + type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") return; if (type == "$mux" || type == "$pmux" || type == "$safe_pmux") diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 4341e067..cd00b43d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -350,7 +350,12 @@ struct RTLIL::Design ~Design(); - RTLIL::ObjRange modules() { return RTLIL::ObjRange(&modules_, &refcount_modules_); } + RTLIL::ObjRange modules(); + RTLIL::Module *module(RTLIL::IdString name); + + void add(RTLIL::Module *module); + RTLIL::Module *addModule(RTLIL::IdString name); + void remove(RTLIL::Module *module); void check(); void optimize(); From 8b0f50792c404d70ae91e623f80c4e7f06d39429 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 21:13:23 +0200 Subject: [PATCH 468/750] Added techmap -extern --- passes/techmap/techmap.cc | 80 ++++++++++++++++++++++++++++-------- tests/vloghtb/common.sh | 26 ++++++++++++ tests/vloghtb/test_mapopt.sh | 3 +- 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 3595b7b5..79e70a59 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -58,6 +58,7 @@ struct TechmapWorker std::map simplemap_mappers; std::map>, RTLIL::Module*> techmap_cache; std::map techmap_do_cache; + std::set module_queue; struct TechmapWireData { RTLIL::Wire *wire; @@ -215,7 +216,7 @@ struct TechmapWorker } bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, - const std::map> &celltypeMap, bool flatten_mode) + const std::map> &celltypeMap, bool flatten_mode, bool extern_mode) { if (!design->selected(module)) return false; @@ -282,15 +283,24 @@ struct TechmapWorker if (!flatten_mode) { - if (tpl->get_bool_attribute("\\techmap_simplemap")) { - log("Mapping %s.%s (%s) with simplemap.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); - if (simplemap_mappers.count(cell->type) == 0) - log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); - simplemap_mappers.at(cell->type)(module, cell); - module->remove(cell); - cell = NULL; - did_something = true; - break; + if (tpl->get_bool_attribute("\\techmap_simplemap")) + { + if (extern_mode) + { + log("WARNING: Mapping simplat cell %s.%s (%s) in -extern mode is not supported yet.\n", log_id(module), log_id(cell), log_id(cell->type)); + break; + } + else + { + log("Mapping %s.%s (%s) with simplemap.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + if (simplemap_mappers.count(cell->type) == 0) + log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); + simplemap_mappers.at(cell->type)(module, cell); + module->remove(cell); + cell = NULL; + did_something = true; + break; + } } for (auto conn : cell->connections()) { @@ -454,9 +464,33 @@ struct TechmapWorker log_continue = false; } - techmap_module_worker(design, module, cell, tpl, flatten_mode); + if (extern_mode) + { + std::string m_name = stringf("$extern:%s", log_id(tpl)); + + if (!design->module(m_name)) + { + RTLIL::Module *m = design->addModule(m_name); + tpl->cloneInto(m); + + for (auto cell : m->cells()) { + if (cell->type.substr(0, 2) == "\\$") + cell->type = cell->type.substr(1); + } + + module_queue.insert(m); + } + + log("Mapping %s.%s to imported %s.\n", log_id(module), log_id(cell), log_id(m_name)); + cell->type = m_name; + cell->parameters.clear(); + } + else + { + techmap_module_worker(design, module, cell, tpl, flatten_mode); + cell = NULL; + } did_something = true; - cell = NULL; break; } @@ -495,6 +529,10 @@ struct TechmapPass : public Pass { log(" yosys data files are). this is mainly used internally when techmap\n"); log(" is called from other commands.\n"); log("\n"); + log(" -extern\n"); + log(" load the cell implementations as separate modules into the design\n"); + log(" instead of inlining them.\n"); + log("\n"); log(" -max_iter \n"); log(" only run the specified number of iterations.\n"); log("\n"); @@ -576,6 +614,7 @@ struct TechmapPass : public Pass { std::vector map_files; std::string verilog_frontend = "verilog -ignore_redef"; + bool extern_mode = false; int max_iter = -1; size_t argidx; @@ -601,6 +640,10 @@ struct TechmapPass : public Pass { verilog_frontend += " -I " + args[++argidx]; continue; } + if (args[argidx] == "-extern") { + extern_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -641,12 +684,17 @@ struct TechmapPass : public Pass { celltypeMap[it.first].insert(it.first); } - for (auto module : design->modules()) { + worker.module_queue = design->modules(); + while (!worker.module_queue.empty()) + { + RTLIL::Module *module = *worker.module_queue.begin(); + worker.module_queue.erase(module); + bool did_something = true; std::set handled_cells; while (did_something) { did_something = false; - if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false)) + if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false, extern_mode)) did_something = true; if (did_something) module->check(); @@ -699,11 +747,11 @@ struct FlattenPass : public Pass { while (did_something) { did_something = false; if (top_mod != NULL) { - if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true)) + if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true, false)) did_something = true; } else { for (auto mod : design->modules()) - if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, true)) + if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, true, false)) did_something = true; } } diff --git a/tests/vloghtb/common.sh b/tests/vloghtb/common.sh index 1c60d794..3f7fc258 100644 --- a/tests/vloghtb/common.sh +++ b/tests/vloghtb/common.sh @@ -8,6 +8,32 @@ log_fail() printf "%-15s %s %s %s\n" "$1" "$2" "`printf "%20s" "$2" | tr -d a-zA-Z0-9_ | tr ' ' .`" "FAIL." } +test_autotest() +{ + # Usage: + # test_autotest + + test_name="$1" + mod_name="$2" + vlog_file="$3" + shift 3 + + mkdir -p log_test_$test_name + rm -rf log_test_$test_name/$mod_name.* + + cp $vlog_file log_test_$test_name/$mod_name.v + + cd log_test_$test_name + if bash ../../tools/autotest.sh "$@" $mod_name.v > /dev/null 2>&1; then + mv $mod_name.out $mod_name.txt + log_pass test_$test_name $mod_name + else + log_fail test_$test_name $mod_name + fi + + cd .. +} + test_equiv() { # Usage: diff --git a/tests/vloghtb/test_mapopt.sh b/tests/vloghtb/test_mapopt.sh index ad8b3ef6..ba39adb3 100644 --- a/tests/vloghtb/test_mapopt.sh +++ b/tests/vloghtb/test_mapopt.sh @@ -6,6 +6,7 @@ source common.sh f=$1 n=$(basename ${f%.v}) -test_equiv mapopt "opt -fine; techmap; opt" "-set-def-inputs" $n $f +test_equiv mapopt_1 "opt -fine; techmap; opt" "-set-def-inputs" $n $f +test_autotest mapopt_2 $n $f -p "opt; techmap -extern; opt" exit 0 From c469be883b80137c9d3d79287b72d05aaaa17128 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 09:15:40 +0200 Subject: [PATCH 469/750] Improvements in tests/vloghtb --- tests/vloghtb/common.sh | 21 +++++++++++---------- tests/vloghtb/test_mapopt.sh | 7 ++++++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tests/vloghtb/common.sh b/tests/vloghtb/common.sh index 3f7fc258..3965b04c 100644 --- a/tests/vloghtb/common.sh +++ b/tests/vloghtb/common.sh @@ -11,27 +11,28 @@ log_fail() test_autotest() { # Usage: - # test_autotest + # test_autotest test_name="$1" - mod_name="$2" - vlog_file="$3" - shift 3 + synth_cmd="$2" + mod_name="$3" + vlog_file="$4" mkdir -p log_test_$test_name rm -rf log_test_$test_name/$mod_name.* - cp $vlog_file log_test_$test_name/$mod_name.v + ../../yosys -q -l log_test_$test_name/$mod_name.out -o log_test_$test_name/$mod_name.v -p "$synth_cmd" "$vlog_file" + cat spec/${mod_name}_spec.v scripts/check.v >> log_test_$test_name/$mod_name.v + iverilog -o log_test_$test_name/$mod_name.bin -D"REFDAT_FN=\"refdat/${mod_name}_refdat.txt\"" log_test_$test_name/$mod_name.v - cd log_test_$test_name - if bash ../../tools/autotest.sh "$@" $mod_name.v > /dev/null 2>&1; then - mv $mod_name.out $mod_name.txt + if log_test_$test_name/$mod_name.bin 2>&1 | tee -a log_test_$test_name/$mod_name.out | grep -q '++OK++'; then + mv log_test_$test_name/$mod_name.out log_test_$test_name/$mod_name.txt log_pass test_$test_name $mod_name else + mv log_test_$test_name/$mod_name.out log_test_$test_name/$mod_name.err log_fail test_$test_name $mod_name + exit 1 fi - - cd .. } test_equiv() diff --git a/tests/vloghtb/test_mapopt.sh b/tests/vloghtb/test_mapopt.sh index ba39adb3..61528c2b 100644 --- a/tests/vloghtb/test_mapopt.sh +++ b/tests/vloghtb/test_mapopt.sh @@ -6,7 +6,12 @@ source common.sh f=$1 n=$(basename ${f%.v}) +mkdir -p log_test_mapopt +rm -f log_test_mapopt/$n.* + test_equiv mapopt_1 "opt -fine; techmap; opt" "-set-def-inputs" $n $f -test_autotest mapopt_2 $n $f -p "opt; techmap -extern; opt" +test_autotest mapopt_2 "proc; opt; techmap; opt" $n $f + +tail -n20 log_test_mapopt_1/$n.txt log_test_mapopt_2/$n.txt > log_test_mapopt/$n.txt exit 0 From ee65dea738fefbf44b91a2ac10f9a93b35115af6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 10:10:08 +0200 Subject: [PATCH 470/750] Fixed signdness detection of expressions with bit- and part-selects --- frontends/ast/genrtlil.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 064aec93..95e15903 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) From f99495a895eda0b1de6c1d7e8e1d5b1074316b34 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 10:52:30 +0200 Subject: [PATCH 471/750] Added cover() to all SigSpec constructors --- kernel/rtlil.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index aec0a045..610ab6a8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1691,6 +1691,8 @@ const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other) RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) { + cover("kernel.rtlil.sigspec.init.const"); + chunks_.push_back(RTLIL::SigChunk(value)); width_ = chunks_.back().width; hash_ = 0; @@ -1699,6 +1701,8 @@ RTLIL::SigSpec::SigSpec(const RTLIL::Const &value) RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) { + cover("kernel.rtlil.sigspec.init.chunk"); + chunks_.push_back(chunk); width_ = chunks_.back().width; hash_ = 0; @@ -1707,6 +1711,8 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk) RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) { + cover("kernel.rtlil.sigspec.init.wire"); + chunks_.push_back(RTLIL::SigChunk(wire)); width_ = chunks_.back().width; hash_ = 0; @@ -1715,6 +1721,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire) RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width) { + cover("kernel.rtlil.sigspec.init.wire_part"); + chunks_.push_back(RTLIL::SigChunk(wire, offset, width)); width_ = chunks_.back().width; hash_ = 0; @@ -1723,6 +1731,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width) RTLIL::SigSpec::SigSpec(const std::string &str) { + cover("kernel.rtlil.sigspec.init.str"); + chunks_.push_back(RTLIL::SigChunk(str)); width_ = chunks_.back().width; hash_ = 0; @@ -1731,6 +1741,8 @@ RTLIL::SigSpec::SigSpec(const std::string &str) RTLIL::SigSpec::SigSpec(int val, int width) { + cover("kernel.rtlil.sigspec.init.int"); + chunks_.push_back(RTLIL::SigChunk(val, width)); width_ = width; hash_ = 0; @@ -1739,6 +1751,8 @@ RTLIL::SigSpec::SigSpec(int val, int width) RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) { + cover("kernel.rtlil.sigspec.init.state"); + chunks_.push_back(RTLIL::SigChunk(bit, width)); width_ = width; hash_ = 0; @@ -1747,6 +1761,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width) RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) { + cover("kernel.rtlil.sigspec.init.bit"); + if (bit.wire == NULL) chunks_.push_back(RTLIL::SigChunk(bit.data, width)); else @@ -1759,6 +1775,8 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width) RTLIL::SigSpec::SigSpec(std::vector chunks) { + cover("kernel.rtlil.sigspec.init.stdvec_chunks"); + width_ = 0; hash_ = 0; for (auto &c : chunks) @@ -1768,6 +1786,8 @@ RTLIL::SigSpec::SigSpec(std::vector chunks) RTLIL::SigSpec::SigSpec(std::vector bits) { + cover("kernel.rtlil.sigspec.init.stdvec_bits"); + width_ = 0; hash_ = 0; for (auto &bit : bits) @@ -1777,6 +1797,8 @@ RTLIL::SigSpec::SigSpec(std::vector bits) RTLIL::SigSpec::SigSpec(std::set bits) { + cover("kernel.rtlil.sigspec.init.stdset_bits"); + width_ = 0; hash_ = 0; for (auto &bit : bits) From d86a25f145012ccb6b2048af3aae22f13b97b505 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 10:52:58 +0200 Subject: [PATCH 472/750] Added std::initializer_list<> constructor to SigSpec --- kernel/rtlil.cc | 12 ++++++++++++ kernel/rtlil.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 610ab6a8..753c4009 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1652,6 +1652,18 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigSpec &other) *this = other; } +RTLIL::SigSpec::SigSpec(std::initializer_list parts) +{ + cover("kernel.rtlil.sigspec.init.list"); + + width_ = 0; + hash_ = 0; + + std::vector parts_vec(parts.begin(), parts.end()); + for (auto it = parts_vec.rbegin(); it != parts_vec.rend(); it++) + append(*it); +} + const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other) { cover("kernel.rtlil.sigspec.assign"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index cd00b43d..331ea377 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -26,6 +26,8 @@ #include #include +#include + // various helpers (unrelated to RTLIL) std::string stringf(const char *fmt, ...); #define SIZE(__obj) int(__obj.size()) @@ -738,6 +740,7 @@ private: public: SigSpec(); SigSpec(const RTLIL::SigSpec &other); + SigSpec(std::initializer_list parts); const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other); SigSpec(const RTLIL::Const &value); From 7bd2d1064f2eceddc3c93c121c4154a2f594a040 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 11:08:55 +0200 Subject: [PATCH 473/750] Using log_assert() instead of assert() --- backends/blif/blif.cc | 1 - backends/btor/btor.cc | 2 +- backends/edif/edif.cc | 1 - backends/ilang/ilang_backend.cc | 5 +- backends/intersynth/intersynth.cc | 1 - backends/spice/spice.cc | 1 - backends/verilog/verilog_backend.cc | 5 +- 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 - kernel/bitpattern.h | 4 +- kernel/calc.cc | 1 - kernel/celltypes.h | 2 +- kernel/consteval.h | 8 +- kernel/driver.cc | 2 +- kernel/log.cc | 57 +++++++++++- kernel/log.h | 56 +++--------- kernel/register.cc | 15 ++-- kernel/rtlil.cc | 119 ++++++++++++------------- kernel/rtlil.h | 16 ++-- kernel/satgen.h | 8 +- kernel/sigtools.h | 13 ++- passes/abc/abc.cc | 9 +- passes/cmds/scc.cc | 6 +- passes/cmds/select.cc | 2 +- passes/cmds/show.cc | 2 +- passes/fsm/fsm_expand.cc | 6 +- passes/fsm/fsm_extract.cc | 2 +- passes/hierarchy/hierarchy.cc | 4 +- passes/hierarchy/submod.cc | 2 +- passes/memory/memory_collect.cc | 23 +++-- passes/memory/memory_dff.cc | 1 - passes/memory/memory_map.cc | 1 - passes/memory/memory_unpack.cc | 1 - passes/opt/opt_clean.cc | 3 +- passes/opt/opt_const.cc | 3 +- passes/opt/opt_muxtree.cc | 1 - passes/opt/opt_reduce.cc | 1 - passes/opt/opt_share.cc | 1 - passes/proc/proc_dff.cc | 3 +- passes/proc/proc_init.cc | 2 +- passes/proc/proc_mux.cc | 13 ++- passes/proc/proc_rmdead.cc | 1 - passes/sat/sat.cc | 2 +- passes/techmap/extract.cc | 3 +- passes/techmap/simplemap.cc | 1 - passes/techmap/techmap.cc | 7 +- 52 files changed, 236 insertions(+), 251 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 2b783e73..d167c3f4 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -27,7 +27,6 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include -#include struct BlifDumperConfig { diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 4af12100..f721fdc9 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -549,7 +549,7 @@ struct BtorDumper int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); l1_width = pow(2, ceil(log(l1_width)/log(2))); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); - //assert(l2_width <= ceil(log(l1_width)/log(2)) ); + //log_assert(l2_width <= ceil(log(l1_width)/log(2)) ); int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), l1_width); int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); int cell_output = ++line_num; diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 5eff4598..49f719a4 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -26,7 +26,6 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include -#include #define EDIF_DEF(_id) edif_names(RTLIL::unescape_id(_id), true).c_str() #define EDIF_REF(_id) edif_names(RTLIL::unescape_id(_id), false).c_str() diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index d45e94a0..87a3d6cb 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -27,7 +27,6 @@ #include "kernel/register.h" #include "kernel/log.h" #include -#include #include #include @@ -41,7 +40,7 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int if (width == 32 && autoint) { int32_t val = 0; for (int i = 0; i < width; i++) { - assert(offset+i < (int)data.bits.size()); + log_assert(offset+i < (int)data.bits.size()); switch (data.bits[offset+i]) { case RTLIL::S0: break; case RTLIL::S1: val |= 1 << i; break; @@ -55,7 +54,7 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int } fprintf(f, "%d'", width); for (int i = offset+width-1; i >= offset; i--) { - assert(i < (int)data.bits.size()); + log_assert(i < (int)data.bits.size()); switch (data.bits[i]) { case RTLIL::S0: fprintf(f, "0"); break; case RTLIL::S1: fprintf(f, "1"); break; diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 2f94e290..9faed77c 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -23,7 +23,6 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include -#include static std::string netname(std::set &conntypes_code, std::set &celltypes_code, std::set &constcells_code, RTLIL::SigSpec sig) diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index 283448c3..ab5316ec 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -23,7 +23,6 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include -#include static void print_spice_net(FILE *f, RTLIL::SigBit s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) { diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index f7f0ecaf..fe2c2b24 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -30,7 +30,6 @@ #include "kernel/register.h" #include "kernel/celltypes.h" #include "kernel/log.h" -#include #include #include #include @@ -161,7 +160,7 @@ void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = if (width == 32 && !no_decimal) { int32_t val = 0; for (int i = offset+width-1; i >= offset; i--) { - assert(i < (int)data.bits.size()); + log_assert(i < (int)data.bits.size()); if (data.bits[i] != RTLIL::S0 && data.bits[i] != RTLIL::S1) goto dump_bits; if (data.bits[i] == RTLIL::S1) @@ -175,7 +174,7 @@ void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = if (width == 0) fprintf(f, "0"); for (int i = offset+width-1; i >= offset; i--) { - assert(i < (int)data.bits.size()); + log_assert(i < (int)data.bits.size()); switch (data.bits[i]) { case RTLIL::S0: fprintf(f, "0"); break; case RTLIL::S1: fprintf(f, "1"); break; diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d38cb5e3..cec199b6 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 95e15903..25881d63 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 6302260a..2a55adef 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 aee38703..80170394 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 8491a6b4..446f5e50 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 873ae3d5..67b2ffa7 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 437fc3ec..cbc594e8 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 4392ed44..63dc85ac 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 diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 05b2bbc2..91f54593 100644 --- a/kernel/bitpattern.h +++ b/kernel/bitpattern.h @@ -66,8 +66,8 @@ struct BitPatternPool bool match(bits_t a, bits_t b) { - assert(int(a.size()) == width); - assert(int(b.size()) == width); + log_assert(int(a.size()) == width); + log_assert(int(b.size()) == width); for (int i = 0; i < width; i++) if (a[i] <= RTLIL::State::S1 && b[i] <= RTLIL::State::S1 && a[i] != b[i]) return false; diff --git a/kernel/calc.cc b/kernel/calc.cc index 749589f2..b413760d 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -24,7 +24,6 @@ #include "kernel/log.h" #include "kernel/rtlil.h" #include "libs/bigint/BigIntegerLibrary.hh" -#include static void extend(RTLIL::Const &arg, int width, bool is_signed) { diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 20d68d55..43c23add 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -313,7 +313,7 @@ struct CellTypes return ret; } - assert(sel.bits.size() == 0); + log_assert(sel.bits.size() == 0); return eval(cell, arg1, arg2); } }; diff --git a/kernel/consteval.h b/kernel/consteval.h index 1727d91c..e5cae102 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -72,7 +72,7 @@ struct ConstEval #ifndef NDEBUG RTLIL::SigSpec current_val = values_map(sig); for (int i = 0; i < SIZE(current_val); i++) - assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]); + log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]); #endif values_map.add(sig, RTLIL::SigSpec(value)); } @@ -87,7 +87,7 @@ struct ConstEval { RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; - assert(cell->has("\\Y")); + log_assert(cell->has("\\Y")); sig_y = values_map(assign_map(cell->get("\\Y"))); if (sig_y.is_fully_const()) return true; @@ -133,7 +133,7 @@ struct ConstEval std::vector y_values; - assert(y_candidates.size() > 0); + log_assert(y_candidates.size() > 0); for (auto &yc : y_candidates) { if (!eval(yc, undef, cell)) return false; @@ -146,7 +146,7 @@ struct ConstEval for (size_t i = 1; i < y_values.size(); i++) { std::vector &slave_bits = y_values.at(i).bits; - assert(master_bits.size() == slave_bits.size()); + log_assert(master_bits.size() == slave_bits.size()); for (size_t j = 0; j < master_bits.size(); j++) if (master_bits[j] != slave_bits[j]) master_bits[j] = RTLIL::State::Sx; diff --git a/kernel/driver.cc b/kernel/driver.cc index 380315e7..a55fbbed 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -327,7 +327,7 @@ static void shell(RTLIL::Design *design) } try { - assert(design->selection_stack.size() == 1); + log_assert(design->selection_stack.size() == 1); Pass::call(design, command); } catch (log_cmd_error_expection) { while (design->selection_stack.size() > 1) diff --git a/kernel/log.cc b/kernel/log.cc index b8a47e1c..8036b236 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -18,6 +18,8 @@ */ #include "kernel/log.h" +#include "kernel/rtlil.h" +#include "kernel/register.h" #include "kernel/compatibility.h" #include "backends/ilang/ilang_backend.h" @@ -29,9 +31,6 @@ #include #include -// declared extern in log.h -std::map> extra_coverage_data; - std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; @@ -192,6 +191,10 @@ void log_flush() fflush(f); } +void log_dump_val_worker(RTLIL::SigSpec v) { + log("%s", log_signal(v)); +} + const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) { char *ptr; @@ -231,3 +234,51 @@ void log_cell(RTLIL::Cell *cell, std::string indent) free(ptr); } +// --------------------------------------------------- +// This is the magic behind the code coverage counters +// --------------------------------------------------- + +std::map> extra_coverage_data; + +void cover_extra(std::string parent, std::string id, bool increment) { + if (extra_coverage_data.count(id) == 0) { + for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) + if (p->id == parent) + extra_coverage_data[id].first = stringf("%s:%d:%s", p->file, p->line, p->func); + log_assert(extra_coverage_data.count(id)); + } + if (increment) + extra_coverage_data[id].second++; +} + +std::map> get_coverage_data() +{ + std::map> coverage_data; + + for (auto &it : REGISTER_INTERN::pass_register) { + std::string key = stringf("passes.%s", it.first.c_str()); + coverage_data[key].first = stringf("%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); + coverage_data[key].second += it.second->call_counter; + } + + for (auto &it : extra_coverage_data) { + if (coverage_data.count(it.first)) + log("WARNING: found duplicate coverage id \"%s\".\n", it.first.c_str()); + coverage_data[it.first].first = it.second.first; + coverage_data[it.first].second += it.second.second; + } + + for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { + if (coverage_data.count(p->id)) + log("WARNING: found duplicate coverage id \"%s\".\n", p->id); + coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); + coverage_data[p->id].second += p->counter; + } + + for (auto &it : coverage_data) + if (!it.second.first.compare(0, strlen(YOSYS_SRC "/"), YOSYS_SRC "/")) + it.second.first = it.second.first.substr(strlen(YOSYS_SRC "/")); + + return coverage_data; +} + diff --git a/kernel/log.h b/kernel/log.h index ca1e7c67..3152fc5a 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -20,15 +20,15 @@ #ifndef LOG_H #define LOG_H -#include "kernel/rtlil.h" -#include "kernel/register.h" - #include #include #include #include #include + +#include #include +#include #define S__LINE__sub2(x) #x #define S__LINE__sub1(x) S__LINE__sub2(x) @@ -59,6 +59,11 @@ void log_pop(); void log_reset_stack(); void log_flush(); +namespace RTLIL { + struct SigSpec; + struct Cell; +} + const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); const char *log_id(std::string id); @@ -96,47 +101,8 @@ extern "C" struct CoverData __stop_yosys_cover_list[]; extern std::map> extra_coverage_data; -static inline void cover_extra(std::string parent, std::string id, bool increment = true) { - if (extra_coverage_data.count(id) == 0) { - for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) - if (p->id == parent) - extra_coverage_data[id].first = stringf("%s:%d:%s", p->file, p->line, p->func); - log_assert(extra_coverage_data.count(id)); - } - if (increment) - extra_coverage_data[id].second++; -} - -static inline std::map> get_coverage_data() -{ - std::map> coverage_data; - - for (auto &it : REGISTER_INTERN::pass_register) { - std::string key = stringf("passes.%s", it.first.c_str()); - coverage_data[key].first = stringf("%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); - coverage_data[key].second += it.second->call_counter; - } - - for (auto &it : extra_coverage_data) { - if (coverage_data.count(it.first)) - log("WARNING: found duplicate coverage id \"%s\".\n", it.first.c_str()); - coverage_data[it.first].first = it.second.first; - coverage_data[it.first].second += it.second.second; - } - - for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { - if (coverage_data.count(p->id)) - log("WARNING: found duplicate coverage id \"%s\".\n", p->id); - coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); - coverage_data[p->id].second += p->counter; - } - - for (auto &it : coverage_data) - if (!it.second.first.compare(0, strlen(YOSYS_SRC "/"), YOSYS_SRC "/")) - it.second.first = it.second.first.substr(strlen(YOSYS_SRC "/")); - - return coverage_data; -} +void cover_extra(std::string parent, std::string id, bool increment = true); +std::map> get_coverage_data(); #define cover_list(_id, ...) do { cover(_id); \ std::string r = cover_list_worker(_id, __VA_ARGS__); \ @@ -234,9 +200,9 @@ static inline void log_dump_val_worker(bool v) { log("%s", v ? "true" : "false") static inline void log_dump_val_worker(double v) { log("%f", v); } static inline void log_dump_val_worker(const char *v) { log("%s", v); } static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); } -static inline void log_dump_val_worker(RTLIL::SigSpec v) { log("%s", log_signal(v)); } static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); } static inline void log_dump_args_worker(const char *p) { log_assert(*p == 0); } +void log_dump_val_worker(RTLIL::SigSpec v); template static inline void log_dump_val_worker(T *ptr) { log("%p", ptr); } diff --git a/kernel/register.cc b/kernel/register.cc index 59667ac9..da356983 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -20,7 +20,6 @@ #include "kernel/compatibility.h" #include "kernel/register.h" #include "kernel/log.h" -#include #include #include #include @@ -50,7 +49,7 @@ Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_he void Pass::run_register() { - assert(pass_register.count(pass_name) == 0); + log_assert(pass_register.count(pass_name) == 0); pass_register[pass_name] = this; } @@ -67,7 +66,7 @@ void Pass::done_register() frontend_register.clear(); pass_register.clear(); backend_register.clear(); - assert(first_queued_pass == NULL); + log_assert(first_queued_pass == NULL); } Pass::~Pass() @@ -252,10 +251,10 @@ Frontend::Frontend(std::string name, std::string short_help) : Pass("read_"+name void Frontend::run_register() { - assert(pass_register.count(pass_name) == 0); + log_assert(pass_register.count(pass_name) == 0); pass_register[pass_name] = this; - assert(frontend_register.count(frontend_name) == 0); + log_assert(frontend_register.count(frontend_name) == 0); frontend_register[frontend_name] = this; } @@ -265,7 +264,7 @@ Frontend::~Frontend() void Frontend::execute(std::vector args, RTLIL::Design *design) { - assert(next_args.empty()); + log_assert(next_args.empty()); do { FILE *f = NULL; next_args.clear(); @@ -383,10 +382,10 @@ Backend::Backend(std::string name, std::string short_help) : Pass("write_"+name, void Backend::run_register() { - assert(pass_register.count(pass_name) == 0); + log_assert(pass_register.count(pass_name) == 0); pass_register[pass_name] = this; - assert(backend_register.count(backend_name) == 0); + log_assert(backend_register.count(backend_name) == 0); backend_register[backend_name] = this; } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 753c4009..78328618 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -23,7 +23,6 @@ #include "frontends/verilog/verilog_frontend.h" #include "backends/ilang/ilang_backend.h" -#include #include #include @@ -238,15 +237,15 @@ RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name) void RTLIL::Design::add(RTLIL::Module *module) { - assert(modules_.count(module->name) == 0); - assert(refcount_modules_ == 0); + log_assert(modules_.count(module->name) == 0); + log_assert(refcount_modules_ == 0); modules_[module->name] = module; } RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) { - assert(modules_.count(name) == 0); - assert(refcount_modules_ == 0); + log_assert(modules_.count(name) == 0); + log_assert(refcount_modules_ == 0); modules_[name] = new RTLIL::Module; modules_[name]->name = name; return modules_[name]; @@ -254,7 +253,7 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) void RTLIL::Design::remove(RTLIL::Module *module) { - assert(modules_.at(module->name) == module); + log_assert(modules_.at(module->name) == module); modules_.erase(module->name); delete module; } @@ -263,8 +262,8 @@ void RTLIL::Design::check() { #ifndef NDEBUG for (auto &it : modules_) { - assert(it.first == it.second->name); - assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(it.first == it.second->name); + log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); it.second->check(); } #endif @@ -760,57 +759,57 @@ void RTLIL::Module::check() { #ifndef NDEBUG for (auto &it : wires_) { - assert(it.first == it.second->name); - assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); - assert(it.second->width >= 0); - assert(it.second->port_id >= 0); + log_assert(it.first == it.second->name); + log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(it.second->width >= 0); + log_assert(it.second->port_id >= 0); for (auto &it2 : it.second->attributes) { - assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); } } for (auto &it : memories) { - assert(it.first == it.second->name); - assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); - assert(it.second->width >= 0); - assert(it.second->size >= 0); + log_assert(it.first == it.second->name); + log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(it.second->width >= 0); + log_assert(it.second->size >= 0); for (auto &it2 : it.second->attributes) { - assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); } } for (auto &it : cells_) { - assert(it.first == it.second->name); - assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); - assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$')); + log_assert(it.first == it.second->name); + log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$')); for (auto &it2 : it.second->connections()) { - assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); it2.second.check(); } for (auto &it2 : it.second->attributes) { - assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); } for (auto &it2 : it.second->parameters) { - assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); } InternalCellChecker checker(this, it.second); checker.check(); } for (auto &it : processes) { - assert(it.first == it.second->name); - assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(it.first == it.second->name); + log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); // FIXME: More checks here.. } for (auto &it : connections_) { - assert(it.first.size() == it.second.size()); + log_assert(it.first.size() == it.second.size()); it.first.check(); it.second.check(); } for (auto &it : attributes) { - assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); } #endif } @@ -934,7 +933,7 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) { - assert(wires_[wire->name] == wire); + log_assert(wires_[wire->name] == wire); log_assert(refcount_wires_ == 0); wires_.erase(wire->name); wire->name = new_name; @@ -943,7 +942,7 @@ void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name) { - assert(cells_[cell->name] == cell); + log_assert(cells_[cell->name] == cell); log_assert(refcount_wires_ == 0); cells_.erase(cell->name); cell->name = new_name; @@ -952,7 +951,7 @@ void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name) void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name) { - assert(count_id(old_name) != 0); + log_assert(count_id(old_name) != 0); if (wires_.count(old_name)) rename(wires_.at(old_name), new_name); else if (cells_.count(old_name)) @@ -1927,11 +1926,11 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec pattern.unpack(); with.unpack(); - assert(other != NULL); - assert(width_ == other->width_); + log_assert(other != NULL); + log_assert(width_ == other->width_); other->unpack(); - assert(pattern.width_ == with.width_); + log_assert(pattern.width_ == with.width_); std::map pattern_map; for (int i = 0; i < SIZE(pattern.bits_); i++) @@ -1966,7 +1965,7 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe unpack(); if (other != NULL) { - assert(width_ == other->width_); + log_assert(width_ == other->width_); other->unpack(); } @@ -2005,7 +2004,7 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, const RTLIL::SigS if (other != NULL) other->pack(); - assert(other == NULL || width_ == other->width_); + log_assert(other == NULL || width_ == other->width_); std::set pat = pattern.to_sigbit_set(); std::vector bits_match = to_sigbit_vector(); @@ -2033,9 +2032,9 @@ void RTLIL::SigSpec::replace(int offset, const RTLIL::SigSpec &with) unpack(); with.unpack(); - assert(offset >= 0); - assert(with.width_ >= 0); - assert(offset+with.width_ <= width_); + log_assert(offset >= 0); + log_assert(with.width_ >= 0); + log_assert(offset+with.width_ <= width_); for (int i = 0; i < with.width_; i++) bits_.at(offset + i) = with.bits_.at(i); @@ -2085,9 +2084,9 @@ void RTLIL::SigSpec::remove(int offset, int length) unpack(); - assert(offset >= 0); - assert(length >= 0); - assert(offset + length <= width_); + log_assert(offset >= 0); + log_assert(length >= 0); + log_assert(offset + length <= width_); bits_.erase(bits_.begin() + offset, bits_.begin() + offset + length); width_ = bits_.size(); @@ -2236,28 +2235,28 @@ void RTLIL::SigSpec::check() const const RTLIL::SigChunk chunk = chunks_[i]; if (chunk.wire == NULL) { if (i > 0) - assert(chunks_[i-1].wire != NULL); - assert(chunk.offset == 0); - assert(chunk.data.bits.size() == (size_t)chunk.width); + log_assert(chunks_[i-1].wire != NULL); + log_assert(chunk.offset == 0); + log_assert(chunk.data.bits.size() == (size_t)chunk.width); } else { if (i > 0 && chunks_[i-1].wire == chunk.wire) - assert(chunk.offset != chunks_[i-1].offset + chunks_[i-1].width); - assert(chunk.offset >= 0); - assert(chunk.width >= 0); - assert(chunk.offset + chunk.width <= chunk.wire->width); - assert(chunk.data.bits.size() == 0); + log_assert(chunk.offset != chunks_[i-1].offset + chunks_[i-1].width); + log_assert(chunk.offset >= 0); + log_assert(chunk.width >= 0); + log_assert(chunk.offset + chunk.width <= chunk.wire->width); + log_assert(chunk.data.bits.size() == 0); } w += chunk.width; } - assert(w == width_); - assert(bits_.empty()); + log_assert(w == width_); + log_assert(bits_.empty()); } else { cover("kernel.rtlil.sigspec.check.unpacked"); - assert(width_ == SIZE(bits_)); - assert(chunks_.empty()); + log_assert(width_ == SIZE(bits_)); + log_assert(chunks_.empty()); } } #endif @@ -2402,7 +2401,7 @@ bool RTLIL::SigSpec::as_bool() const cover("kernel.rtlil.sigspec.as_bool"); pack(); - assert(is_fully_const() && SIZE(chunks_) <= 1); + log_assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) return chunks_[0].data.as_bool(); return false; @@ -2413,7 +2412,7 @@ int RTLIL::SigSpec::as_int() const cover("kernel.rtlil.sigspec.as_int"); pack(); - assert(is_fully_const() && SIZE(chunks_) <= 1); + log_assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) return chunks_[0].data.as_int(); return 0; @@ -2441,7 +2440,7 @@ RTLIL::Const RTLIL::SigSpec::as_const() const cover("kernel.rtlil.sigspec.as_const"); pack(); - assert(is_fully_const() && SIZE(chunks_) <= 1); + log_assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) return chunks_[0].data; return RTLIL::Const(); @@ -2452,7 +2451,7 @@ RTLIL::Wire *RTLIL::SigSpec::as_wire() const cover("kernel.rtlil.sigspec.as_wire"); pack(); - assert(is_wire()); + log_assert(is_wire()); return chunks_[0].wire; } @@ -2461,7 +2460,7 @@ RTLIL::SigChunk RTLIL::SigSpec::as_chunk() const cover("kernel.rtlil.sigspec.as_chunk"); pack(); - assert(is_chunk()); + log_assert(is_chunk()); return chunks_[0]; } @@ -2471,7 +2470,7 @@ bool RTLIL::SigSpec::match(std::string pattern) const pack(); std::string str = as_string(); - assert(pattern.size() == str.size()); + log_assert(pattern.size() == str.size()); for (size_t i = 0; i < pattern.size(); i++) { if (pattern[i] == ' ') diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 331ea377..d78a6df2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -24,8 +24,8 @@ #include #include #include -#include +#include "kernel/log.h" #include // various helpers (unrelated to RTLIL) @@ -107,7 +107,7 @@ namespace RTLIL return std::string(*this) < std::string(rhs); } void check() const { - assert(empty() || (size() >= 2 && (at(0) == '$' || at(0) == '\\'))); + log_assert(empty() || (size() >= 2 && (at(0) == '$' || at(0) == '\\'))); } }; #endif @@ -242,7 +242,7 @@ namespace RTLIL } inline T operator*() const { - assert(list_p != nullptr); + log_assert(list_p != nullptr); return it->second; } @@ -253,7 +253,7 @@ namespace RTLIL } inline void operator++() { - assert(list_p != nullptr); + log_assert(list_p != nullptr); if (++it == list_p->end()) { (*refcount_p)--; list_p = nullptr; @@ -677,9 +677,9 @@ struct RTLIL::SigBit SigBit() : wire(NULL), data(RTLIL::State::S0), offset(0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit), offset(0) { } - SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { assert(wire && wire->width == 1); } - SigBit(RTLIL::Wire *wire, int offset) : wire(wire), data(RTLIL::State::S0), offset(offset) { assert(wire); } - SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[0]), offset(chunk.offset) { assert(chunk.width == 1); } + SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { log_assert(wire && wire->width == 1); } + SigBit(RTLIL::Wire *wire, int offset) : wire(wire), data(RTLIL::State::S0), offset(offset) { log_assert(wire); } + SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[0]), offset(chunk.offset) { log_assert(chunk.width == 1); } SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[index]), offset(chunk.wire ? chunk.offset + index : 0) { } SigBit(const RTLIL::SigSpec &sig); @@ -856,7 +856,7 @@ inline const RTLIL::SigBit &RTLIL::SigSpecConstIterator::operator*() const { } inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) { - assert(sig.size() == 1 && sig.chunks().size() == 1); + log_assert(sig.size() == 1 && sig.chunks().size() == 1); *this = SigBit(sig.chunks().front()); } diff --git a/kernel/satgen.h b/kernel/satgen.h index 6a288a8d..27a29cb5 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -116,7 +116,7 @@ struct SatGen if (timestep_rhs < 0) timestep_rhs = timestep_lhs; - assert(lhs.size() == rhs.size()); + log_assert(lhs.size() == rhs.size()); std::vector vec_lhs = importSigSpec(lhs, timestep_lhs); std::vector vec_rhs = importSigSpec(rhs, timestep_rhs); @@ -163,14 +163,14 @@ struct SatGen void undefGating(std::vector &vec_y, std::vector &vec_yy, std::vector &vec_undef) { - assert(model_undef); - assert(vec_y.size() == vec_yy.size()); + log_assert(model_undef); + log_assert(vec_y.size() == vec_yy.size()); if (vec_y.size() > vec_undef.size()) { std::vector trunc_y(vec_y.begin(), vec_y.begin() + vec_undef.size()); std::vector trunc_yy(vec_yy.begin(), vec_yy.begin() + vec_undef.size()); ez->assume(ez->expression(ezSAT::OpAnd, ez->vec_or(vec_undef, ez->vec_iff(trunc_y, trunc_yy)))); } else { - assert(vec_y.size() == vec_undef.size()); + log_assert(vec_y.size() == vec_undef.size()); ez->assume(ez->expression(ezSAT::OpAnd, ez->vec_or(vec_undef, ez->vec_iff(vec_y, vec_yy)))); } } diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 52e4aa0f..79a9fb23 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -22,7 +22,6 @@ #include "kernel/rtlil.h" #include "kernel/log.h" -#include #include struct SigPool @@ -67,7 +66,7 @@ struct SigPool void expand(RTLIL::SigSpec from, RTLIL::SigSpec to) { - assert(SIZE(from) == SIZE(to)); + log_assert(SIZE(from) == SIZE(to)); for (int i = 0; i < SIZE(from); i++) { bitDef_t bit_from(from[i]), bit_to(to[i]); if (bit_from.first != NULL && bit_to.first != NULL && bits.count(bit_from) > 0) @@ -304,11 +303,11 @@ struct SigMap // internal helper function void merge_bit(const RTLIL::SigBit &bit1, const RTLIL::SigBit &bit2) { - assert(bit1.wire != NULL && bit2.wire != NULL); + log_assert(bit1.wire != NULL && bit2.wire != NULL); shared_bit_data_t *bd1 = bits[bit1]; shared_bit_data_t *bd2 = bits[bit2]; - assert(bd1 != NULL && bd2 != NULL); + log_assert(bd1 != NULL && bd2 != NULL); if (bd1 == bd2) return; @@ -333,8 +332,8 @@ struct SigMap // internal helper function void set_bit(const RTLIL::SigBit &bit1, const RTLIL::SigBit &bit2) { - assert(bit1.wire != NULL); - assert(bits.count(bit1) > 0); + log_assert(bit1.wire != NULL); + log_assert(bits.count(bit1) > 0); bits[bit1]->map_to = bit2; } @@ -347,7 +346,7 @@ struct SigMap void add(RTLIL::SigSpec from, RTLIL::SigSpec to) { - assert(SIZE(from) == SIZE(to)); + log_assert(SIZE(from) == SIZE(to)); for (int i = 0; i < SIZE(from); i++) { diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 03fc9f93..d2be7dcf 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -39,7 +39,6 @@ #include "kernel/log.h" #include #include -#include #include #include #include @@ -273,7 +272,7 @@ static void handle_loops() // log("Removing non-loop node %d from graph: %s\n", id, log_signal(signal_list[id].bit)); for (int id2 : edges[id]) { - assert(in_edges_count[id2] > 0); + log_assert(in_edges_count[id2] > 0); if (--in_edges_count[id2] == 0) workpool.insert(id2); } @@ -331,7 +330,7 @@ static void handle_loops() int id3 = map_signal(RTLIL::SigSpec(wire)); signal_list[id1].is_port = true; signal_list[id3].is_port = true; - assert(id3 == int(in_edges_count.size())); + log_assert(id3 == int(in_edges_count.size())); in_edges_count.push_back(0); workpool.insert(id3); @@ -778,7 +777,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std for (auto &c : conn.second.chunks()) { if (c.width == 0) continue; - assert(c.width == 1); + log_assert(c.width == 1); newsig.append(module->wires_[remap_name(c.wire->name)]); } cell->set(conn.first, newsig); @@ -831,7 +830,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std struct dirent **namelist; int n = scandir(tempdir_name, &namelist, 0, alphasort); - assert(n >= 0); + log_assert(n >= 0); for (int i = 0; i < n; i++) { if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) { if (asprintf(&p, "%s/%s", tempdir_name, namelist[i]->d_name) < 0) log_abort(); diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 1fa1b4c9..8c039e3e 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -51,7 +51,7 @@ struct SccWorker void run(RTLIL::Cell *cell, int depth, int maxDepth) { - assert(workQueue.count(cell) > 0); + log_assert(workQueue.count(cell) > 0); workQueue.erase(cell); cellLabels[cell] = std::pair(labelCounter, labelCounter); @@ -166,7 +166,7 @@ struct SccWorker while (workQueue.size() > 0) { RTLIL::Cell *cell = *workQueue.begin(); - assert(cellStack.size() == 0); + log_assert(cellStack.size() == 0); cellDepth.clear(); run(cell, 0, maxDepth); } @@ -290,7 +290,7 @@ struct SccPass : public Pass { } if (selectMode) { - assert(origSelectPos >= 0); + log_assert(origSelectPos >= 0); design->selection_stack[origSelectPos] = newSelection; design->selection_stack[origSelectPos].optimize(design); } diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 85c52277..bbfa396b 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1120,7 +1120,7 @@ struct SelectPass : public Pass { work_stack.pop_back(); } - assert(design->selection_stack.size() > 0); + log_assert(design->selection_stack.size() > 0); if (clear_mode) { design->selection_stack.back() = RTLIL::Selection(true); diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 7ab1daf0..a2dd8051 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -202,7 +202,7 @@ struct ShowWorker for (int i = int(sig.chunks().size())-1; i >= 0; i--) { const RTLIL::SigChunk &c = sig.chunks().at(i); net = gen_signode_simple(c, false); - assert(!net.empty()); + log_assert(!net.empty()); if (driver) { label_string += stringf(" %d:%d - %d:%d |", i, pos, pos-c.width+1, c.offset+c.width-1, c.offset); net_conn_map[net].in.insert(stringf("x%d:s%d", idx, i)); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index f107366d..2da4794e 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -157,9 +157,9 @@ struct FsmExpand A.replace(input_sig, RTLIL::SigSpec(in_val)); B.replace(input_sig, RTLIL::SigSpec(in_val)); S.replace(input_sig, RTLIL::SigSpec(in_val)); - assert(A.is_fully_const()); - assert(B.is_fully_const()); - assert(S.is_fully_const()); + log_assert(A.is_fully_const()); + log_assert(B.is_fully_const()); + log_assert(S.is_fully_const()); truth_tab.push_back(ct.eval(cell, A.as_const(), B.as_const(), S.as_const())); } diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 99352b10..6da46832 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -109,7 +109,7 @@ static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_d RTLIL::SigSpec undef, constval; if (ce.eval(ctrl_out, undef) && ce.eval(dff_in, undef)) { - assert(ctrl_out.is_fully_const() && dff_in.is_fully_const()); + log_assert(ctrl_out.is_fully_const() && dff_in.is_fully_const()); FsmData::transition_t tr; tr.state_in = state_in; tr.state_out = states[ce.values_map(ce.assign_map(dff_in)).as_const()]; diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 8aec25eb..c869ec72 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -98,7 +98,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell generate_port_decl_t d = decl; d.portname = portname; d.index = *indices.begin(); - assert(!indices.empty()); + log_assert(!indices.empty()); indices.erase(d.index); ports[d.index-1] = d; portwidths[d.portname] = std::max(portwidths[d.portname], 1); @@ -110,7 +110,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell portnames.erase(portname); } - assert(indices.empty()); + log_assert(indices.empty()); RTLIL::Module *mod = new RTLIL::Module; mod->name = celltype; diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index d32b5e1d..84c6b916 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -171,7 +171,7 @@ struct SubmodWorker for (auto &conn : new_cell->connections_) for (auto &bit : conn.second) if (bit.wire != NULL) { - assert(wire_flags.count(bit.wire) > 0); + log_assert(wire_flags.count(bit.wire) > 0); bit.wire = wire_flags[bit.wire].new_wire; } log(" cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str()); diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index d2803ae7..40c68abc 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -22,7 +22,6 @@ #include #include #include -#include static bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b) { @@ -136,12 +135,12 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->parameters["\\SIZE"] = RTLIL::Const(memory->size); mem->parameters["\\ABITS"] = RTLIL::Const(addr_bits); - assert(sig_wr_clk.size() == wr_ports); - assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const()); - assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const()); - assert(sig_wr_addr.size() == wr_ports * addr_bits); - assert(sig_wr_data.size() == wr_ports * memory->width); - assert(sig_wr_en.size() == wr_ports * memory->width); + log_assert(sig_wr_clk.size() == wr_ports); + log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const()); + log_assert(sig_wr_clk_polarity.size() == wr_ports && sig_wr_clk_polarity.is_fully_const()); + log_assert(sig_wr_addr.size() == wr_ports * addr_bits); + log_assert(sig_wr_data.size() == wr_ports * memory->width); + log_assert(sig_wr_en.size() == wr_ports * memory->width); mem->parameters["\\WR_PORTS"] = RTLIL::Const(wr_ports); mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : RTLIL::Const(0, 0); @@ -152,11 +151,11 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->set("\\WR_DATA", sig_wr_data); mem->set("\\WR_EN", sig_wr_en); - assert(sig_rd_clk.size() == rd_ports); - assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); - assert(sig_rd_clk_polarity.size() == rd_ports && sig_rd_clk_polarity.is_fully_const()); - assert(sig_rd_addr.size() == rd_ports * addr_bits); - assert(sig_rd_data.size() == rd_ports * memory->width); + log_assert(sig_rd_clk.size() == rd_ports); + log_assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); + log_assert(sig_rd_clk_polarity.size() == rd_ports && sig_rd_clk_polarity.is_fully_const()); + log_assert(sig_rd_addr.size() == rd_ports * addr_bits); + log_assert(sig_rd_data.size() == rd_ports * memory->width); mem->parameters["\\RD_PORTS"] = RTLIL::Const(rd_ports); mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : RTLIL::Const(0, 0); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 85249142..32505617 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -20,7 +20,6 @@ #include "kernel/register.h" #include "kernel/log.h" #include -#include #include static void normalize_sig(RTLIL::Module *module, RTLIL::SigSpec &sig) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 53394b19..49291656 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -22,7 +22,6 @@ #include #include #include -#include static std::string genid(std::string name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "") { diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index d2b9c0ee..cdf7db04 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -22,7 +22,6 @@ #include #include #include -#include static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) { diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 6c20bddb..4182c6f5 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -23,7 +23,6 @@ #include "kernel/log.h" #include "kernel/celltypes.h" #include -#include #include #include @@ -227,7 +226,7 @@ static void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool if (!used_signals.check_any(s2) && wire->port_id == 0 && !wire->get_bool_attribute("\\keep")) { maybe_del_wires.push_back(wire); } else { - assert(SIZE(s1) == SIZE(s2)); + log_assert(SIZE(s1) == SIZE(s2)); RTLIL::SigSig new_conn; for (int i = 0; i < SIZE(s1); i++) if (s1[i] != s2[i]) { diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 7578f192..254fe5bb 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -24,7 +24,6 @@ #include "kernel/toposort.h" #include "kernel/log.h" #include -#include #include #include @@ -495,7 +494,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec new_a, new_b; - assert(SIZE(a) == SIZE(b)); + log_assert(SIZE(a) == SIZE(b)); for (int i = 0; i < SIZE(a); i++) { if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) { cover_list("opt.opt_const.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 73baaf90..de12542d 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -23,7 +23,6 @@ #include "kernel/log.h" #include "kernel/celltypes.h" #include -#include #include #include diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index b2b7cc8b..8aadd1f2 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -24,7 +24,6 @@ #include "kernel/celltypes.h" #include "libs/sha1/sha1.h" #include -#include #include #include diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 45130229..ad6e1a74 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -24,7 +24,6 @@ #include "kernel/celltypes.h" #include "libs/sha1/sha1.h" #include -#include #include #include diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index dc310bde..91cafe3b 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -24,7 +24,6 @@ #include #include #include -#include static RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) { @@ -288,7 +287,7 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) inputs.append(it->signal); compare.append(it->type == RTLIL::SyncType::ST0 ? RTLIL::State::S1 : RTLIL::State::S0); } - assert(inputs.size() == compare.size()); + log_assert(inputs.size() == compare.size()); RTLIL::Cell *cell = mod->addCell(NEW_ID, "$ne"); cell->parameters["\\A_SIGNED"] = RTLIL::Const(false, 1); diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc index 99498505..c72840c0 100644 --- a/passes/proc/proc_init.cc +++ b/passes/proc/proc_init.cc @@ -25,7 +25,7 @@ static void proc_get_const(RTLIL::SigSpec &sig, RTLIL::CaseRule &rule) { - assert(rule.compare.size() == 0); + log_assert(rule.compare.size() == 0); while (1) { RTLIL::SigSpec tmp = sig; diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index fb49182c..e7661245 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -23,7 +23,6 @@ #include #include #include -#include static RTLIL::SigSpec find_any_lvalue(const RTLIL::CaseRule *cs) { @@ -67,7 +66,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, RTLIL::SigSpec sig = signal; // get rid of don't-care bits - assert(sig.size() == comp.size()); + log_assert(sig.size() == comp.size()); for (int i = 0; i < comp.size(); i++) if (comp[i] == RTLIL::State::Sa) { sig.remove(i); @@ -125,7 +124,7 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::SigSpec else_signal, RTLIL::Cell *&last_mux_cell, RTLIL::SwitchRule *sw) { - assert(when_signal.size() == else_signal.size()); + log_assert(when_signal.size() == else_signal.size()); std::stringstream sstr; sstr << "$procmux$" << (RTLIL::autoidx++); @@ -138,7 +137,7 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); if (ctrl_sig.size() == 0) return when_signal; - assert(ctrl_sig.size() == 1); + log_assert(ctrl_sig.size() == 1); // prepare multiplexer output signal RTLIL::Wire *result_wire = mod->addWire(sstr.str() + "_Y", when_signal.size()); @@ -159,11 +158,11 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw) { - assert(last_mux_cell != NULL); - assert(when_signal.size() == last_mux_cell->get("\\A").size()); + log_assert(last_mux_cell != NULL); + log_assert(when_signal.size() == last_mux_cell->get("\\A").size()); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); - assert(ctrl_sig.size() == 1); + log_assert(ctrl_sig.size() == 1); last_mux_cell->type = "$pmux"; RTLIL::SigSpec new_s = last_mux_cell->get("\\S"); diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index 9e5f413a..61844d5e 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -23,7 +23,6 @@ #include #include #include -#include #include static void proc_rmdead(RTLIL::SwitchRule *sw, int &counter) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index dce31206..430628e4 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -335,7 +335,7 @@ struct SatHelper int setup_proof(int timestep = -1) { - assert(prove.size() || prove_x.size() || prove_asserts); + log_assert(prove.size() || prove_x.size() || prove_asserts); RTLIL::SigSpec big_lhs, big_rhs; std::vector prove_bits; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 8587f53b..9c5fa7f7 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -23,7 +23,6 @@ #include "libs/subcircuit/subcircuit.h" #include #include -#include #include #include @@ -100,7 +99,7 @@ namespace RTLIL::Cell *haystackCell = (RTLIL::Cell*) haystackUserData; if (!needleCell || !haystackCell) { - assert(!needleCell && !haystackCell); + log_assert(!needleCell && !haystackCell); return true; } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index b327ba83..5c3e4c68 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -21,7 +21,6 @@ #include "kernel/sigtools.h" #include "kernel/log.h" #include -#include #include #include diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 79e70a59..5a69baca 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -23,7 +23,6 @@ #include "kernel/toposort.h" #include "kernel/log.h" #include -#include #include #include @@ -47,7 +46,7 @@ static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module if (chunk.wire != NULL) { std::string wire_name = chunk.wire->name; apply_prefix(prefix, wire_name); - assert(module->wires_.count(wire_name) > 0); + log_assert(module->wires_.count(wire_name) > 0); chunk.wire = module->wires_[wire_name]; } sig = chunks; @@ -167,7 +166,7 @@ struct TechmapWorker c.second.remove(c.first.size(), c.second.size() - c.first.size()); if (c.second.size() < c.first.size()) c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.size() - c.second.size())); - assert(c.first.size() == c.second.size()); + log_assert(c.first.size() == c.second.size()); if (flatten_mode) { // more conservative approach: // connect internal and external wires @@ -427,7 +426,7 @@ struct TechmapWorker const char *q = strrchr(p+1, '.'); q = q ? q : p+1; - assert(!strncmp(q, "_TECHMAP_DO_", 12)); + log_assert(!strncmp(q, "_TECHMAP_DO_", 12)); std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12); while (tpl->wires_.count(new_name)) new_name += "_"; From 3c45277ee0f5822181c6058f679de632f834e7d2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 12:12:13 +0200 Subject: [PATCH 474/750] Added wire->upto flag for signals such as "wire [0:7] x;" --- backends/ilang/ilang_backend.cc | 2 ++ frontends/ast/genrtlil.cc | 3 +++ frontends/ilang/lexer.l | 1 + frontends/ilang/parser.y | 5 ++++- kernel/rtlil.cc | 2 ++ kernel/rtlil.h | 2 +- 6 files changed, 13 insertions(+), 2 deletions(-) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index 87a3d6cb..c055c133 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -123,6 +123,8 @@ void ILANG_BACKEND::dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wi fprintf(f, "%s" "wire ", indent.c_str()); if (wire->width != 1) fprintf(f, "width %d ", wire->width); + if (wire->upto) + fprintf(f, "upto "); if (wire->start_offset != 0) fprintf(f, "offset %d ", wire->start_offset); if (wire->port_input && !wire->port_output) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 25881d63..8ee46eb8 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 c40b81af..f3bdeb1a 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 a594adfb..38d3054b 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; } | diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 78328618..b562e2af 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1019,6 +1019,7 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *oth wire->port_id = other->port_id; wire->port_input = other->port_input; wire->port_output = other->port_output; + wire->upto = other->upto; wire->attributes = other->attributes; return wire; } @@ -1443,6 +1444,7 @@ RTLIL::Wire::Wire() port_id = 0; port_input = false; port_output = false; + upto = false; } RTLIL::Memory::Memory() diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d78a6df2..097af9d2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -602,7 +602,7 @@ public: RTLIL::IdString name; int width, start_offset, port_id; - bool port_input, port_output; + bool port_input, port_output, upto; RTLIL_ATTRIBUTE_MEMBERS }; From 27a872d1e7041be4894bc643a420587ff5894125 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 14:25:03 +0200 Subject: [PATCH 475/750] Added support for "upto" wires to Verilog front- and back-end --- backends/verilog/verilog_backend.cc | 31 +++++++++++----- frontends/ast/ast.cc | 5 ++- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 19 ++++------ frontends/ast/simplify.cc | 4 ++ tests/simple/partsel.v | 57 +++++++++++++++++++++++++++++ 6 files changed, 96 insertions(+), 22 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index fe2c2b24..5826aea8 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -211,14 +211,23 @@ void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool no_decimal = fals if (chunk.wire == NULL) { dump_const(f, chunk.data, chunk.width, chunk.offset, no_decimal); } else { - if (chunk.width == chunk.wire->width && chunk.offset == 0) + if (chunk.width == chunk.wire->width && chunk.offset == 0) { fprintf(f, "%s", id(chunk.wire->name).c_str()); - else if (chunk.width == 1) - fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset); - else - fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(), - chunk.offset + chunk.wire->start_offset + chunk.width - 1, - chunk.offset + chunk.wire->start_offset); + } else if (chunk.width == 1) { + if (chunk.wire->upto) + fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset); + else + fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset); + } else { + if (chunk.wire->upto) + fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(), + (chunk.wire->width - (chunk.offset + chunk.width - 1) - 1) + chunk.wire->start_offset, + (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset); + else + fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(), + (chunk.offset + chunk.width - 1) + chunk.wire->start_offset, + chunk.offset + chunk.wire->start_offset); + } } } @@ -267,8 +276,12 @@ void dump_wire(FILE *f, std::string indent, RTLIL::Wire *wire) #else // do not use Verilog-2k "outut reg" syntax in verilog export std::string range = ""; - if (wire->width != 1) - range = stringf(" [%d:%d]", wire->width - 1 + wire->start_offset, wire->start_offset); + if (wire->width != 1) { + if (wire->upto) + range = stringf(" [%d:%d]", wire->start_offset, wire->width - 1 + wire->start_offset); + else + range = stringf(" [%d:%d]", wire->width - 1 + wire->start_offset, wire->start_offset); + } if (wire->port_input && !wire->port_output) fprintf(f, "%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); if (!wire->port_input && wire->port_output) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index cec199b6..5b3214f5 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 8253a205..6c15c03a 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 8ee46eb8..5545fc16 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 2a55adef..7aa6d24c 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; } diff --git a/tests/simple/partsel.v b/tests/simple/partsel.v index 9b1a9985..7461358a 100644 --- a/tests/simple/partsel.v +++ b/tests/simple/partsel.v @@ -3,3 +3,60 @@ wire [5:0] offset = idx << 2; assign slice_up = data[offset +: 4]; assign slice_down = data[offset + 3 -: 4]; endmodule + +module partsel_test002 ( + input clk, rst, + input [7:0] a, + input [0:7] b, + input [1:0] s, + output [7:0] x1, x2, x3, + output [0:7] x4, x5, x6, + output [7:0] y1, y2, y3, + output [0:7] y4, y5, y6, + output [7:0] z1, z2, z3, + output [0:7] z4, z5, z6, + output [7:0] w1, w2, w3, + output [0:7] w4, w5, w6, + output [7:0] p1, p2, p3, p4, p5, p6, + output [0:7] q1, q2, q3, q4, q5, q6, + output reg [7:0] r1, + output reg [0:7] r2 +); + +assign x1 = a, x2 = a + b, x3 = b; +assign x4 = a, x5 = a + b, x6 = b; +assign y1 = a[4 +: 3], y2 = a[4 +: 3] + b[4 +: 3], y3 = b[4 +: 3]; +assign y4 = a[4 +: 3], y5 = a[4 +: 3] + b[4 +: 3], y6 = b[4 +: 3]; +assign z1 = a[4 -: 3], z2 = a[4 -: 3] + b[4 -: 3], z3 = b[4 -: 3]; +assign z4 = a[4 -: 3], z5 = a[4 -: 3] + b[4 -: 3], z6 = b[4 -: 3]; +assign w1 = a[6:3], w2 = a[6:3] + b[3:6], w3 = b[3:6]; +assign w4 = a[6:3], w5 = a[6:3] + b[3:6], w6 = b[3:6]; +assign p1 = a[s], p2 = b[s], p3 = a[s+2 +: 2], p4 = b[s+2 +: 2], p5 = a[s+2 -: 2], p6 = b[s+2 -: 2]; +assign q1 = a[s], q2 = b[s], q3 = a[s+2 +: 2], q4 = b[s+2 +: 2], q5 = a[s+2 -: 2], q6 = b[s+2 -: 2]; + +always @(posedge clk) begin + if (rst) begin + { r1, r2 } = 16'h1337 ^ {a, b}; + end else begin + case (s) + 0: begin + r1[3:0] <= r2[0:3] ^ x1; + r2[4:7] <= r1[7:4] ^ x4; + end + 1: begin + r1[2 +: 3] <= r2[5 -: 3] + x1; + r2[3 +: 3] <= r1[6 -: 3] + x4; + end + 2: begin + r1[6 -: 3] <= r2[3 +: 3] - x1; + r2[7 -: 3] <= r1[4 +: 3] - x4; + end + 3: begin + r1 <= r2; + r2 <= r1; + end + endcase + end +end + +endmodule From 0598bc8708d942a0e533ddeba6a4f7b5effe7f39 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 15:19:34 +0200 Subject: [PATCH 476/750] Fixed width detection for part selects --- frontends/ast/genrtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 5545fc16..9e186683 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; From 55521c085ae1ec735d3cffb80a9880b3cb3e8bca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 15:31:19 +0200 Subject: [PATCH 477/750] Fixed RTLIL code generator for part select of parameter --- frontends/ast/genrtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9e186683..ca61cb39 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); } } From a03297a7df6c729bc13f629412ae020eb05f7c64 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 16:09:50 +0200 Subject: [PATCH 478/750] Set results of out-of-bounds static bit/part select to undef --- frontends/ast/genrtlil.cc | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index ca61cb39..b4115f0c 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); From ec589659674ba9699b5dc73129ad69f25738e87e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 16:45:26 +0200 Subject: [PATCH 479/750] Fixed part selects of parameters --- frontends/ast/genrtlil.cc | 15 ++++++++++----- frontends/ast/simplify.cc | 23 +++++++++++++++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b4115f0c..9b8e0faa 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 7aa6d24c..d47bfb5e 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) From 48822e79a34880c5f0b07e9889e463e7b6d7111b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 19:38:30 +0200 Subject: [PATCH 480/750] Removed left over debug code --- frontends/ast/genrtlil.cc | 1 - frontends/ast/simplify.cc | 1 - 2 files changed, 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9b8e0faa..cb666679 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 d47bfb5e..5665cd43 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) From 397b00252dc0c4af725614bd12fc299147ba8efa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 14:42:33 +0200 Subject: [PATCH 481/750] Added $shift and $shiftx cell types (needed for correct part select behavior) --- CHECKLISTS | 2 + backends/btor/btor.cc | 4 +- frontends/ast/genrtlil.cc | 16 +++++--- kernel/calc.cc | 43 ++++++++++++++++++--- kernel/celltypes.h | 6 ++- kernel/rtlil.cc | 5 ++- kernel/rtlil.h | 22 +++++++---- kernel/satgen.h | 18 +++++++-- passes/memory/memory_share.cc | 2 + passes/opt/opt_const.cc | 16 ++++---- techlibs/common/simlib.v | 48 +++++++++++++++++++++++ techlibs/common/stdcells.v | 72 +++++++++++++++++++++++++++++++---- 12 files changed, 214 insertions(+), 40 deletions(-) diff --git a/CHECKLISTS b/CHECKLISTS index 3f824fc2..8a149a53 100644 --- a/CHECKLISTS +++ b/CHECKLISTS @@ -123,6 +123,8 @@ Things to do right away: - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) - Add to InternalCellChecker::check() in kernel/rtlil.cc + - Add to techlibs/common/simlib.v + - Add to techlibs/common/stdcells.v Things to do after finalizing the cell interface: diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index f721fdc9..43c03669 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -111,6 +111,8 @@ struct BtorDumper cell_type_translation["$shl"] = "sll"; cell_type_translation["$sshr"] = "sra"; cell_type_translation["$sshl"] = "sll"; + cell_type_translation["$shift"] = "srl"; + cell_type_translation["$shiftx"] = "srl"; cell_type_translation["$lt"] = "ult"; cell_type_translation["$le"] = "ulte"; cell_type_translation["$gt"] = "ugt"; @@ -540,7 +542,7 @@ struct BtorDumper } line_ref[cell->name]=line_num; } - else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") + else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl" || cell->type == "$shift" || cell->type == "$shiftx") { log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index cb666679..b7f33635 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; diff --git a/kernel/calc.cc b/kernel/calc.cc index b413760d..b3ff3cf2 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -276,7 +276,7 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const return result; } -static RTLIL::Const const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len) +static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len) { int undef_bit_pos = -1; BigInteger offset = const2big(arg2, false, undef_bit_pos) * direction; @@ -305,28 +305,61 @@ RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2 { RTLIL::Const arg1_ext = arg1; extend_u0(arg1_ext, result_len, signed1); - return const_shift(arg1_ext, arg2, false, -1, result_len); + return const_shift_worker(arg1_ext, arg2, false, -1, result_len); } RTLIL::Const RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; extend_u0(arg1_ext, result_len, signed1); - return const_shift(arg1_ext, arg2, false, +1, result_len); + return const_shift_worker(arg1_ext, arg2, false, +1, result_len); } RTLIL::Const RTLIL::const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { if (!signed1) return const_shl(arg1, arg2, signed1, signed2, result_len); - return const_shift(arg1, arg2, true, -1, result_len); + return const_shift_worker(arg1, arg2, true, -1, result_len); } RTLIL::Const RTLIL::const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { if (!signed1) return const_shr(arg1, arg2, signed1, signed2, result_len); - return const_shift(arg1, arg2, true, +1, result_len); + return const_shift_worker(arg1, arg2, true, +1, result_len); +} + +static RTLIL::Const const_shift_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool, bool signed2, int result_len, RTLIL::State other_bits) +{ + int undef_bit_pos = -1; + BigInteger offset = const2big(arg2, signed2, undef_bit_pos); + + if (result_len < 0) + result_len = arg1.bits.size(); + + RTLIL::Const result(RTLIL::State::Sx, result_len); + if (undef_bit_pos >= 0) + return result; + + for (int i = 0; i < result_len; i++) { + BigInteger pos = BigInteger(i) + offset; + if (pos < 0 || pos >= arg1.bits.size()) + result.bits[i] = other_bits; + else + result.bits[i] = arg1.bits[pos.toInt()]; + } + + return result; +} + +RTLIL::Const RTLIL::const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) +{ + return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::S0); +} + +RTLIL::Const RTLIL::const_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) +{ + return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::Sx); } RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 43c23add..e1a1110d 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -75,6 +75,8 @@ struct CellTypes cell_types.insert("$shr"); cell_types.insert("$sshl"); cell_types.insert("$sshr"); + cell_types.insert("$shift"); + cell_types.insert("$shiftx"); cell_types.insert("$lt"); cell_types.insert("$le"); cell_types.insert("$eq"); @@ -224,7 +226,7 @@ struct CellTypes if (type == "$sshl" && !signed1) type = "$shl"; - if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && + if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" && type != "$pos" && type != "$neg" && type != "$not" && type != "$bu0") { if (!signed1 || !signed2) signed1 = false, signed2 = false; @@ -248,6 +250,8 @@ struct CellTypes HANDLE_CELL_TYPE(shr) HANDLE_CELL_TYPE(sshl) HANDLE_CELL_TYPE(sshr) + HANDLE_CELL_TYPE(shift) + HANDLE_CELL_TYPE(shiftx) HANDLE_CELL_TYPE(lt) HANDLE_CELL_TYPE(le) HANDLE_CELL_TYPE(eq) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b562e2af..83bbd7b1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -474,7 +474,8 @@ namespace { return; } - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { + if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || + cell->type == "$shift" || cell->type == "$shiftx") { param_bool("\\A_SIGNED"); param_bool("\\B_SIGNED"); port("\\A", param("\\A_WIDTH")); @@ -1101,6 +1102,8 @@ DEF_METHOD(Shl, sig_a.size(), "$shl") DEF_METHOD(Shr, sig_a.size(), "$shr") DEF_METHOD(Sshl, sig_a.size(), "$sshl") DEF_METHOD(Sshr, sig_a.size(), "$sshr") +DEF_METHOD(Shift, sig_a.size(), "$shift") +DEF_METHOD(Shiftx, sig_a.size(), "$shiftx") DEF_METHOD(Lt, 1, "$lt") DEF_METHOD(Le, 1, "$le") DEF_METHOD(Eq, 1, "$eq") diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 097af9d2..e8d05e7e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -172,6 +172,8 @@ namespace RTLIL RTLIL::Const const_shr (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_sshl (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_sshr (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); + RTLIL::Const const_shift (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); + RTLIL::Const const_shiftx (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_lt (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_le (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); @@ -474,10 +476,12 @@ public: RTLIL::Cell* addReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); - RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); - RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); - RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); - RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addShift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); + RTLIL::Cell* addShiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addLt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addLe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); @@ -551,10 +555,12 @@ public: RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); RTLIL::SigSpec ReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false); - RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); - RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); - RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); - RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Shift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); + RTLIL::SigSpec Shiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); RTLIL::SigSpec Lt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); RTLIL::SigSpec Le (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false); diff --git a/kernel/satgen.h b/kernel/satgen.h index 27a29cb5..a079b42f 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -597,7 +597,7 @@ struct SatGen return true; } - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") + if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") { std::vector a = importDefSigSpec(cell->get("\\A"), timestep); std::vector b = importDefSigSpec(cell->get("\\B"), timestep); @@ -605,6 +605,7 @@ struct SatGen char shift_left = cell->type == "$shl" || cell->type == "$sshl"; bool sign_extend = cell->type == "$sshr" && cell->parameters["\\A_SIGNED"].as_bool(); + bool shift_shiftx = cell->type == "$shift" || cell->type == "$shiftx"; while (y.size() < a.size()) y.push_back(ez->literal()); @@ -616,9 +617,13 @@ struct SatGen std::vector tmp = a; for (size_t i = 0; i < b.size(); i++) { + bool shift_left_this = shift_left; + if (shift_shiftx && i == b.size()-1 && cell->parameters["\\B_SIGNED"].as_bool()) + shift_left_this = true; + std::vector tmp_shifted(tmp.size()); for (size_t j = 0; j < tmp.size(); j++) { - int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left ? -1 : +1); + int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left_this ? -1 : +1); tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : sign_extend ? tmp.back() : ez->FALSE; } tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp); @@ -639,10 +644,15 @@ struct SatGen tmp = undef_a; for (size_t i = 0; i < b.size(); i++) { + bool shift_left_this = shift_left; + if (shift_shiftx && i == b.size()-1 && cell->parameters["\\B_SIGNED"].as_bool()) + shift_left_this = true; + std::vector tmp_shifted(tmp.size()); for (size_t j = 0; j < tmp.size(); j++) { - int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left ? -1 : +1); - tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : sign_extend ? tmp.back() : ez->FALSE; + int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left_this ? -1 : +1); + tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : + sign_extend ? tmp.back() : cell->type == "$shiftx" ? ez->TRUE : ez->FALSE; } tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp); } diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index e61661a2..b1629b7c 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -695,6 +695,8 @@ struct MemoryShareWorker cone_ct.cell_types.erase("$shr"); cone_ct.cell_types.erase("$sshl"); cone_ct.cell_types.erase("$sshr"); + cone_ct.cell_types.erase("$shift"); + cone_ct.cell_types.erase("$shiftx"); modwalker.setup(design, module, &cone_ct); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 254fe5bb..3e7487c3 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -338,7 +338,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || + if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$shift" || cell->type == "$shiftx" || cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt" || cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || @@ -347,7 +347,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); RTLIL::SigSpec sig_b = cell->has("\\B") ? assign_map(cell->get("\\B")) : RTLIL::SigSpec(); - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") + if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") sig_a = RTLIL::SigSpec(); for (auto &bit : sig_a.to_sigbit_vector()) @@ -360,8 +360,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (0) { found_the_x_bit: - cover_list("opt.opt_const.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$lt", "$le", "$ge", "$gt", - "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); + cover_list("opt.opt_const.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", + "$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); @@ -572,7 +572,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo identity_wrt_a = true; } - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") + if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") { RTLIL::SigSpec b = assign_map(cell->get("\\B")); @@ -603,9 +603,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (identity_wrt_a || identity_wrt_b) { if (identity_wrt_a) - cover_list("opt.opt_const.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$mul", "$div", cell->type); + cover_list("opt.opt_const.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type); if (identity_wrt_b) - cover_list("opt.opt_const.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$mul", "$div", cell->type); + cover_list("opt.opt_const.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type); log("Replacing %s cell `%s' in module `%s' with identity for port %c.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); @@ -792,6 +792,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo FOLD_2ARG_CELL(shr) FOLD_2ARG_CELL(sshl) FOLD_2ARG_CELL(sshr) + FOLD_2ARG_CELL(shift) + FOLD_2ARG_CELL(shiftx) FOLD_2ARG_CELL(lt) FOLD_2ARG_CELL(le) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 1b50959c..76aa4a52 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -418,6 +418,54 @@ endmodule // -------------------------------------------------------- +module \$shift (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +generate + if (B_SIGNED) begin:BLOCK1 + assign Y = $signed(B) < 0 ? A << -B : A >> B; + end else begin:BLOCK2 + assign Y = A >> B; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$shiftx (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +generate + if (B_SIGNED) begin:BLOCK1 + assign Y = A[$signed(B) +: Y_WIDTH]; + end else begin:BLOCK2 + assign Y = A[B +: Y_WIDTH]; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + module \$lt (A, B, Y); parameter A_SIGNED = 0; diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index a05ea278..ee59048c 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -129,12 +129,12 @@ endmodule // -------------------------------------------------------- -module \$__shift (X, A, Y); +module \$__shift (XL, XR, A, Y); parameter WIDTH = 1; parameter SHIFT = 0; -input X; +input XL, XR; input [WIDTH-1:0] A; output [WIDTH-1:0] Y; @@ -142,12 +142,12 @@ genvar i; generate for (i = 0; i < WIDTH; i = i + 1) begin:V if (i+SHIFT < 0) begin - assign Y[i] = 0; + assign Y[i] = XR; end else if (i+SHIFT < WIDTH) begin assign Y[i] = A[i+SHIFT]; end else begin - assign Y[i] = X; + assign Y[i] = XL; end end endgenerate @@ -196,7 +196,8 @@ generate .WIDTH(WIDTH), .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) ) sh ( - .X(0), + .XL(1'b0), + .XR(1'b0), .A(unshifted), .Y(shifted) ); @@ -255,7 +256,8 @@ generate .WIDTH(WIDTH), .SHIFT(2 ** (i > 30 ? 30 : i)) ) sh ( - .X(0), + .XL(1'b0), + .XR(1'b0), .A(unshifted), .Y(shifted) ); @@ -314,7 +316,8 @@ generate .WIDTH(WIDTH), .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) ) sh ( - .X(0), + .XL(1'b0), + .XR(1'b0), .A(unshifted), .Y(shifted) ); @@ -382,7 +385,8 @@ generate .WIDTH(WIDTH), .SHIFT(2 ** (i > 30 ? 30 : i)) ) sh ( - .X(A_SIGNED && A[A_WIDTH-1]), + .XL(A_SIGNED && A[A_WIDTH-1]), + .XR(1'b0), .A(unshifted), .Y(shifted) ); @@ -401,6 +405,58 @@ endmodule // -------------------------------------------------------- +module \$shift (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +generate + if (B_SIGNED) begin:BLOCK1 + assign Y = $signed(B) < 0 ? A << -B : A >> B; + end else begin:BLOCK2 + assign Y = A >> B; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + +module \$shiftx (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +\$shift #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH), +) sh ( + .A(A), + .B(B), + .Y(Y) +); + +endmodule + +// -------------------------------------------------------- + module \$__fulladd (A, B, C, X, Y); // {X, Y} = A + B + C From 03c96f9ce7120adf1c9bab93485a3b4bf6493ae9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 16:06:27 +0200 Subject: [PATCH 482/750] Added "techmap -map %{design-name}" --- kernel/rtlil.cc | 5 +++++ kernel/rtlil.h | 5 +++++ passes/techmap/extract.cc | 6 +++--- passes/techmap/techmap.cc | 23 ++++++++++++++++------- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 83bbd7b1..f864d88c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -219,6 +219,11 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) } } +RTLIL::Design::Design() +{ + refcount_modules_ = 0; +} + RTLIL::Design::~Design() { for (auto it = modules_.begin(); it != modules_.end(); it++) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e8d05e7e..1f25542f 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -352,11 +352,16 @@ struct RTLIL::Design std::map selection_vars; std::string selected_active_module; + Design(); ~Design(); RTLIL::ObjRange modules(); RTLIL::Module *module(RTLIL::IdString name); + bool has(RTLIL::IdString id) const { + return modules_.count(id) != 0; + } + void add(RTLIL::Module *module); RTLIL::Module *addModule(RTLIL::IdString name); void remove(RTLIL::Module *module); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 9c5fa7f7..19d32334 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -603,9 +603,9 @@ struct ExtractPass : public Pass { delete map; log_cmd_error("Can't saved design `%s'.\n", filename.c_str()+1); } - for (auto &it : saved_designs.at(filename.substr(1))->modules_) - if (!map->modules_.count(it.first)) - map->modules_[it.first] = it.second->clone(); + for (auto mod : saved_designs.at(filename.substr(1))->modules()) + if (!map->has(mod->name)) + map->add(mod->clone()); } else { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 5a69baca..0ae5220e 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -656,13 +656,22 @@ struct TechmapPass : public Pass { Frontend::frontend_call(map, f, "", verilog_frontend); fclose(f); } else - for (auto &fn : map_files) { - FILE *f = fopen(fn.c_str(), "rt"); - if (f == NULL) - log_cmd_error("Can't open map file `%s'\n", fn.c_str()); - Frontend::frontend_call(map, f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend); - fclose(f); - } + for (auto &fn : map_files) + if (fn.substr(0, 1) == "%") { + if (!saved_designs.count(fn.substr(1))) { + delete map; + log_cmd_error("Can't saved design `%s'.\n", fn.c_str()+1); + } + for (auto mod : saved_designs.at(fn.substr(1))->modules()) + if (!map->has(mod->name)) + map->add(mod->clone()); + } else { + FILE *f = fopen(fn.c_str(), "rt"); + if (f == NULL) + log_cmd_error("Can't open map file `%s'\n", fn.c_str()); + Frontend::frontend_call(map, f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend); + fclose(f); + } std::map modules_new; for (auto &it : map->modules_) { From 77e2d39cd079ba98340f55f57e8a6462fb709442 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 16:33:56 +0200 Subject: [PATCH 483/750] Allow "hierarchy -generate" for $__ cells --- passes/hierarchy/hierarchy.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index c869ec72..a1361c68 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -41,7 +41,9 @@ static void generate(RTLIL::Design *design, const std::vector &cell for (auto i2 : i1.second->cells_) { RTLIL::Cell *cell = i2.second; - if (cell->type[0] == '$' || design->modules_.count(cell->type) > 0) + if (design->has(cell->type)) + continue; + if (cell->type.substr(0, 1) == "$" && cell->type.substr(0, 3) != "$__") continue; for (auto &pattern : celltypes) if (!fnmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str(), FNM_NOESCAPE)) From 2145e57ef08784484e875e64cb43b6d1f4dbe50c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 19:23:31 +0200 Subject: [PATCH 484/750] Bugfix in simlib.v for iverilog --- techlibs/common/simlib.v | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 76aa4a52..c2f6cb27 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -455,11 +455,12 @@ input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; generate - if (B_SIGNED) begin:BLOCK1 - assign Y = A[$signed(B) +: Y_WIDTH]; - end else begin:BLOCK2 - assign Y = A[B +: Y_WIDTH]; - end + if (Y_WIDTH > 0) + if (B_SIGNED) begin:BLOCK1 + assign Y = A[$signed(B) +: Y_WIDTH]; + end else begin:BLOCK2 + assign Y = A[B +: Y_WIDTH]; + end endgenerate endmodule From e605af8a4937533b35068071e14f5bd92c2e5b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 20:14:25 +0200 Subject: [PATCH 485/750] Fixed Verilog pre-processor for files with no trailing newline --- frontends/verilog/preproc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 67b2ffa7..9ff68822 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) From e6df25bf740b259027541db3543a769ecfc92d4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 21:12:50 +0200 Subject: [PATCH 486/750] Renamed "write_autotest" to "test_autotb" and moved to passes/tests/ --- backends/autotest/Makefile.inc | 3 --- kernel/register.cc | 4 +++- passes/tests/Makefile.inc | 3 +++ .../autotest.cc => passes/tests/test_autotb.cc | 10 +++++----- tests/tools/autotest.sh | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) delete mode 100644 backends/autotest/Makefile.inc create mode 100644 passes/tests/Makefile.inc rename backends/autotest/autotest.cc => passes/tests/test_autotb.cc (97%) diff --git a/backends/autotest/Makefile.inc b/backends/autotest/Makefile.inc deleted file mode 100644 index 9308dcd4..00000000 --- a/backends/autotest/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/autotest/autotest.o - diff --git a/kernel/register.cc b/kernel/register.cc index da356983..4569481f 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -376,7 +376,9 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam design->check(); } -Backend::Backend(std::string name, std::string short_help) : Pass("write_"+name, short_help), backend_name(name) +Backend::Backend(std::string name, std::string short_help) : + Pass(name.substr(0, 1) == "=" ? name.substr(1) : "write_"+name, short_help), + backend_name(name.substr(0, 1) == "=" ? name.substr(1) : name) { } diff --git a/passes/tests/Makefile.inc b/passes/tests/Makefile.inc new file mode 100644 index 00000000..6497f86e --- /dev/null +++ b/passes/tests/Makefile.inc @@ -0,0 +1,3 @@ + +OBJS += passes/tests/test_autotb.o + diff --git a/backends/autotest/autotest.cc b/passes/tests/test_autotb.cc similarity index 97% rename from backends/autotest/autotest.cc rename to passes/tests/test_autotb.cc index 3bb0f9d6..f121089b 100644 --- a/backends/autotest/autotest.cc +++ b/passes/tests/test_autotb.cc @@ -301,13 +301,13 @@ static void autotest(FILE *f, RTLIL::Design *design) fprintf(f, "endmodule\n"); } -struct AutotestBackend : public Backend { - AutotestBackend() : Backend("autotest", "generate simple test benches") { } +struct TestAutotbBackend : public Backend { + TestAutotbBackend() : Backend("=test_autotb", "generate simple test benches") { } virtual void help() { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" write_autotest [filename]\n"); + log(" test_autotb [filename]\n"); log("\n"); log("Automatically create primitive verilog test benches for all modules in the\n"); log("design. The generated testbenches toggle the input pins of the module in\n"); @@ -327,9 +327,9 @@ struct AutotestBackend : public Backend { } virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) { - log_header("Executing AUTOTEST backend (auto-generate pseudo-random test benches).\n"); + log_header("Executing TEST_AUTOTB backend (auto-generate pseudo-random test benches).\n"); extra_args(f, filename, args, 1); autotest(f, design); } -} AutotestBackend; +} TestAutotbBackend; diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index c383e19f..1130bbb7 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -93,7 +93,7 @@ do cd ${bn}.out cp ../$fn $fn if [ ! -f ../${bn}_tb.v ]; then - "$toolsdir"/../../yosys -b autotest -o ${bn}_tb.v $fn + "$toolsdir"/../../yosys -b test_autotb -o ${bn}_tb.v $fn else cp ../${bn}_tb.v ${bn}_tb.v fi From 273383692a50490f02a51d0c44ba63b9f557da4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 22:05:00 +0200 Subject: [PATCH 487/750] Added "test_cell" command --- kernel/driver.cc | 2 +- passes/tests/Makefile.inc | 1 + passes/tests/test_cell.cc | 184 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 passes/tests/test_cell.cc diff --git a/kernel/driver.cc b/kernel/driver.cc index a55fbbed..2e56f9a3 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -289,7 +289,7 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) str += "yosys"; if (!design->selected_active_module.empty()) str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); - if (!design->selection_stack.back().full_selection) { + if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { if (design->selected_active_module.empty()) str += "*"; else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || diff --git a/passes/tests/Makefile.inc b/passes/tests/Makefile.inc index 6497f86e..a60cfe66 100644 --- a/passes/tests/Makefile.inc +++ b/passes/tests/Makefile.inc @@ -1,3 +1,4 @@ OBJS += passes/tests/test_autotb.o +OBJS += passes/tests/test_cell.o diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc new file mode 100644 index 00000000..41671a8e --- /dev/null +++ b/passes/tests/test_cell.cc @@ -0,0 +1,184 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Johann Glaser + * + * 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/rtlil.h" +#include "kernel/log.h" + +static uint32_t xorshift32(uint32_t limit) { + static uint32_t x = 123456789; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return x % limit; +} + +static void create_gold_module(RTLIL::Design *design, std::string cell_type, std::string cell_type_flags) +{ + RTLIL::Module *module = design->addModule("\\gold"); + RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); + + if (cell_type_flags.find('A') != std::string::npos) { + RTLIL::Wire *wire = module->addWire("\\A"); + wire->width = 1 + xorshift32(8); + wire->port_input = true; + cell->set("\\A", wire); + } + + if (cell_type_flags.find('B') != std::string::npos) { + RTLIL::Wire *wire = module->addWire("\\B"); + if (cell_type_flags.find('h') != std::string::npos) + wire->width = 1 + xorshift32(6); + else + wire->width = 1 + xorshift32(8); + wire->port_input = true; + cell->set("\\B", wire); + } + + if (cell_type_flags.find('S') != std::string::npos && xorshift32(2)) { + if (cell_type_flags.find('A') != std::string::npos) + cell->parameters["\\A_SIGNED"] = true; + if (cell_type_flags.find('B') != std::string::npos) + cell->parameters["\\B_SIGNED"] = true; + } + + if (cell_type_flags.find('s') != std::string::npos) { + if (cell_type_flags.find('A') != std::string::npos && xorshift32(2)) + cell->parameters["\\A_SIGNED"] = true; + if (cell_type_flags.find('B') != std::string::npos && xorshift32(2)) + cell->parameters["\\B_SIGNED"] = true; + } + + if (cell_type_flags.find('Y') != std::string::npos) { + RTLIL::Wire *wire = module->addWire("\\Y"); + wire->width = 1 + xorshift32(8); + wire->port_output = true; + cell->set("\\Y", wire); + } + + module->fixup_ports(); + cell->fixup_parameters(); + cell->check(); +} + +struct TestCellPass : public Pass { + TestCellPass() : Pass("test_cell", "automatically test the implementation of a cell type") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" test_cell {cell-type}\n"); + log("\n"); + log("Tests the internal implementation of the given cell type (for example '$mux')\n"); + log("by comparing SAT solver, EVAL and TECHMAP implementations of the cell type..\n"); + log("\n"); + log("Run with '-all' instead of a cell type to run the test on all supported\n"); + log("cell types.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *current_design) + { + if (SIZE(args) != 2) + log_cmd_error("Expecting exactly one argument.\n"); + + std::map cell_types; + cell_types["$not"] = "ASY"; + cell_types["$pos"] = "ASY"; + cell_types["$bu0"] = "ASY"; + cell_types["$neg"] = "ASY"; + + cell_types["$and"] = "ABSY"; + cell_types["$or"] = "ABSY"; + cell_types["$xor"] = "ABSY"; + cell_types["$xnor"] = "ABSY"; + + cell_types["$reduce_and"] = "ASY"; + cell_types["$reduce_or"] = "ASY"; + cell_types["$reduce_xor"] = "ASY"; + cell_types["$reduce_xnor"] = "ASY"; + cell_types["$reduce_bool"] = "ASY"; + + cell_types["$shl"] = "ABshY"; + cell_types["$shr"] = "ABshY"; + cell_types["$sshl"] = "ABshY"; + cell_types["$sshr"] = "ABshY"; + // cell_types["$shift"] = "ABshY"; <-- FIXME + // cell_types["$shiftx"] = "ABshY"; + + cell_types["$lt"] = "ABSY"; + cell_types["$le"] = "ABSY"; + cell_types["$eq"] = "ABSY"; + cell_types["$ne"] = "ABSY"; + // cell_types["$eqx"] = "ABSY"; + // cell_types["$nex"] = "ABSY"; + cell_types["$ge"] = "ABSY"; + cell_types["$gt"] = "ABSY"; + + cell_types["$add"] = "ABSY"; + cell_types["$sub"] = "ABSY"; + cell_types["$mul"] = "ABSY"; + cell_types["$div"] = "ABSY"; + cell_types["$mod"] = "ABSY"; + // cell_types["$pow"] = "ABsY"; + + cell_types["$logic_not"] = "ASY"; + cell_types["$logic_and"] = "ABSY"; + cell_types["$logic_or"] = "ABSY"; + + // cell_types["$mux"] = "A"; + // cell_types["$pmux"] = "A"; + // cell_types["$slice"] = "A"; + // cell_types["$concat"] = "A"; + // cell_types["$safe_pmux"] = "A"; + // cell_types["$lut"] = "A"; + // cell_types["$assert"] = "A"; + + if (args[1] == "-all") { + for (auto &it : cell_types) + Pass::call(current_design, "test_cell " + it.first); + return; + } + + if (cell_types.count(args[1]) == 0) { + std::string cell_type_list; + int charcount = 100; + for (auto &it : cell_types) { + if (charcount > 60) { + cell_type_list += "\n" + it.first; + charcount = 0; + } else + cell_type_list += " " + it.first; + charcount += SIZE(it.first); + } + log_cmd_error("This cell type is currently not supported. Try one of these:%s\n", cell_type_list.c_str()); + } + + for (int i = 0; i < 100; i++) + { + RTLIL::Design *design = new RTLIL::Design; + create_gold_module(design, args[1], cell_types.at(args[1])); + Pass::call(design, "copy gold gate; techmap gate; opt gate; dump gold"); + Pass::call(design, "miter -equiv -flatten -ignore_gold_x gold gate miter"); + Pass::call(design, "sat -verify -enable_undef -prove trigger 0 miter"); + delete design; + } + } +} TestCellPass; + From a7c6b37abf3e4628dd921bb12f77987d1f94c45f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 14:10:15 +0200 Subject: [PATCH 488/750] Added "kernel/yosys.h" and "kernel/yosys.cc" --- Makefile | 2 +- kernel/driver.cc | 4 +-- kernel/log.cc | 24 +------------ kernel/log.h | 6 ++-- kernel/register.h | 18 ---------- kernel/rtlil.h | 14 ++------ kernel/yosys.cc | 40 ++++++++++++++++++++++ kernel/yosys.h | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 133 insertions(+), 61 deletions(-) create mode 100644 kernel/yosys.cc create mode 100644 kernel/yosys.h diff --git a/Makefile b/Makefile index 462861c8..73d44833 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,7 @@ S = endif OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o -OBJS += kernel/compatibility.o +OBJS += kernel/compatibility.o kernel/yosys.o OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o diff --git a/kernel/driver.cc b/kernel/driver.cc index 2e56f9a3..c20be1dc 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -30,9 +30,7 @@ #include #include -#include "kernel/rtlil.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" bool fgetline(FILE *f, std::string &buffer) { diff --git a/kernel/log.cc b/kernel/log.cc index 8036b236..5fe0d086 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -17,10 +17,7 @@ * */ -#include "kernel/log.h" -#include "kernel/rtlil.h" -#include "kernel/register.h" -#include "kernel/compatibility.h" +#include "kernel/yosys.h" #include "backends/ilang/ilang_backend.h" #include @@ -43,25 +40,6 @@ std::list string_buf; static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; -std::string stringf(const char *fmt, ...) -{ - std::string string; - char *str = NULL; - va_list ap; - - va_start(ap, fmt); - if (vasprintf(&str, fmt, ap) < 0) - str = NULL; - va_end(ap); - - if (str != NULL) { - string = str; - free(str); - } - - return string; -} - void logv(const char *format, va_list ap) { if (log_time) { diff --git a/kernel/log.h b/kernel/log.h index 3152fc5a..803365b3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -17,6 +17,8 @@ * */ +#include "kernel/yosys.h" + #ifndef LOG_H #define LOG_H @@ -26,10 +28,6 @@ #include #include -#include -#include -#include - #define S__LINE__sub2(x) #x #define S__LINE__sub1(x) S__LINE__sub2(x) #define S__LINE__ S__LINE__sub1(__LINE__) diff --git a/kernel/register.h b/kernel/register.h index 73875e96..68f09c82 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -26,24 +26,6 @@ #include #include -#ifdef YOSYS_ENABLE_TCL -#include -extern Tcl_Interp *yosys_get_tcl_interp(); -#endif - -// from kernel/version_*.o (cc source generated from Makefile) -extern const char *yosys_version_str; - -// implemented in driver.cc -extern RTLIL::Design *yosys_get_design(); -extern std::string proc_self_dirname(); -extern std::string proc_share_dirname(); -extern const char *create_prompt(RTLIL::Design *design, int recursion_counter); - -// from passes/cmds/design.cc -extern std::map saved_designs; -extern std::vector pushed_designs; - struct Pass { std::string pass_name, short_help; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1f25542f..d6acb5bc 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -17,21 +17,11 @@ * */ +#include "kernel/yosys.h" + #ifndef RTLIL_H #define RTLIL_H -#include -#include -#include -#include - -#include "kernel/log.h" -#include - -// various helpers (unrelated to RTLIL) -std::string stringf(const char *fmt, ...); -#define SIZE(__obj) int(__obj.size()) - namespace RTLIL { enum State : unsigned char { diff --git a/kernel/yosys.cc b/kernel/yosys.cc new file mode 100644 index 00000000..d2544382 --- /dev/null +++ b/kernel/yosys.cc @@ -0,0 +1,40 @@ +/* + * 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/yosys.h" + +std::string stringf(const char *fmt, ...) +{ + std::string string; + char *str = NULL; + va_list ap; + + va_start(ap, fmt); + if (vasprintf(&str, fmt, ap) < 0) + str = NULL; + va_end(ap); + + if (str != NULL) { + string = str; + free(str); + } + + return string; +} + diff --git a/kernel/yosys.h b/kernel/yosys.h new file mode 100644 index 00000000..67629d9b --- /dev/null +++ b/kernel/yosys.h @@ -0,0 +1,86 @@ +/* + * 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. + * + */ + + +// *** NOTE TO THE READER *** +// +// Maybe you have just opened this file in the hope to learn more about the +// Yosys API. Let me congratulate you on this great decision! ;) +// +// If you want to know how the design is represented by Yosys in the memory, +// you should read "kernel/rtlil.h". +// +// If you want to know how to register a command with Yosys, you could read +// "kernel/register.h", but it would be easier to just look at a simple +// example instead. A simple one would be "passes/cmds/log.cc". + + +#ifndef YOSYS_H +#define YOSYS_H + +#include +#include +#include +#include +#include + +#if 0 +# define YOSYS_NAMESPACE_BEGIN namespace Yosys { +# define YOSYS_NAMESPACE_END } +#else +# define YOSYS_NAMESPACE_BEGIN +# define YOSYS_NAMESPACE_END +#endif + +YOSYS_NAMESPACE_BEGIN + +std::string stringf(const char *fmt, ...); + +#define SIZE(__obj) int(__obj.size()) + +YOSYS_NAMESPACE_END + +#include "kernel/log.h" +#include "kernel/rtlil.h" +#include "kernel/register.h" +#include "kernel/compatibility.h" + +YOSYS_NAMESPACE_BEGIN + +#ifdef YOSYS_ENABLE_TCL +#include +extern Tcl_Interp *yosys_get_tcl_interp(); +#endif + +// from kernel/version_*.o (cc source generated from Makefile) +extern const char *yosys_version_str; + +// implemented in driver.cc +extern RTLIL::Design *yosys_get_design(); +extern std::string proc_self_dirname(); +extern std::string proc_share_dirname(); +extern const char *create_prompt(RTLIL::Design *design, int recursion_counter); + +// from passes/cmds/design.cc +extern std::map saved_designs; +extern std::vector pushed_designs; + +YOSYS_NAMESPACE_END + +#endif From e2a029b5d583c3268df4d798f8e79874919eb601 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 14:10:49 +0200 Subject: [PATCH 489/750] Added CodingStyle document --- CodingStyle | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 CodingStyle diff --git a/CodingStyle b/CodingStyle new file mode 100644 index 00000000..e076cbd8 --- /dev/null +++ b/CodingStyle @@ -0,0 +1,43 @@ + + +Section 0: Notes on the existing codebase +----------------------------------------- + +Not all parts of Yosys adhere to this coding styles for historical +reasons. When adding code to existing parts of the system, adhere +to this guide for the new code instead of trying to mimic to style +of the surrounding code. + + + +Section 1: Formatting of code +----------------------------- + +- Yosys code is using tabs for indentation. Tabs are 8 characters. + +- A continuation of a statement in the following line is indented by + two additional tabs. + +- Lines are as long as you want them to be. A good rule of thumb is + to break lines at about column 150. + +- Opening braces can be put on the same or next line as the statement + opening the block (if, switch, for, while, do). Put the opening brace + on its own line for larger blocks. + +- Otherwise stick to the Linux Kernel Coding Stlye: + https://www.kernel.org/doc/Documentation/CodingStyle + + +Section 2: C++ Langugage +------------------------ + +Yosys is written in C++11. At the moment only constructs supported by +gcc 4.6 is allowed in Yosys code. This will change in future releases. + +In general Yosys uses "int" instead of "size_t". To avoid compiler +warnings for implicit type casts, always use "SIZE(foobar)" instead +of "foobar.size()". (the macro SIZE() is defined by kernel/yosys.h) + +Use range-based for loops whenever applicable. + From 45fd26b76e1ca72927ab0a8ce207aab0d024eba3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 15:58:21 +0200 Subject: [PATCH 490/750] Added "log_dump_val_worker(char *v)" --- kernel/log.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/log.h b/kernel/log.h index 803365b3..a491d067 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -196,6 +196,7 @@ static inline void log_dump_val_worker(char c) { log(c >= 32 && c < 127 ? "'%c'" static inline void log_dump_val_worker(unsigned char c) { log(c >= 32 && c < 127 ? "'%c'" : "'\\x%02x'", c); } static inline void log_dump_val_worker(bool v) { log("%s", v ? "true" : "false"); } static inline void log_dump_val_worker(double v) { log("%f", v); } +static inline void log_dump_val_worker(char *v) { log("%s", v); } static inline void log_dump_val_worker(const char *v) { log("%s", v); } static inline void log_dump_val_worker(std::string v) { log("%s", v.c_str()); } static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p.sec()); } From 9b566a7efa9813b0dd343bc96fe145f9e3e68d4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 17:17:31 +0200 Subject: [PATCH 491/750] Added native support for shift operations to ezSAT --- libs/ezsat/ezsat.cc | 90 +++++++++++++++++++++++++++++++++++++++++++++ libs/ezsat/ezsat.h | 6 ++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc index 4c0b624b..13ed112e 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -977,6 +977,96 @@ std::vector ezSAT::vec_srl(const std::vector &vec1, int shift) return vec; } +std::vector ezSAT::vec_shift(const std::vector &vec1, int shift, int extend_left, int extend_right) +{ + std::vector vec; + for (int i = 0; i < int(vec1.size()); i++) { + int j = i+shift; + if (j < 0) + vec.push_back(extend_right); + else if (j >= int(vec1.size())) + vec.push_back(extend_left); + else + vec.push_back(vec1[j]); + } + return vec; +} + +static int my_clog2(int x) +{ + int result = 0; + for (x--; x > 0; result++) + x >>= 1; + return result; +} + +std::vector ezSAT::vec_shift_right(const std::vector &vec1, const std::vector &vec2, bool vec2_signed, int extend_left, int extend_right) +{ + int vec2_bits = std::min(my_clog2(vec1.size()) + (vec2_signed ? 1 : 0), int(vec2.size())); + + std::vector overflow_bits(vec2.begin() + vec2_bits, vec2.end()); + int overflow_left = FALSE, overflow_right = FALSE; + + if (vec2_signed) { + int overflow = FALSE; + for (auto bit : overflow_bits) + overflow = OR(overflow, XOR(bit, vec2[vec2_bits-1])); + overflow_left = AND(overflow, NOT(vec2.back())); + overflow_right = AND(overflow, vec2.back()); + } else + overflow_left = vec_reduce_or(overflow_bits); + + std::vector buffer = vec1; + + if (vec2_signed) + while (buffer.size() < vec1.size() + (1 << vec2_bits)) + buffer.push_back(extend_left); + + std::vector overflow_pattern_left(buffer.size(), extend_left); + std::vector overflow_pattern_right(buffer.size(), extend_right); + + buffer = vec_ite(overflow_left, overflow_pattern_left, buffer); + + if (vec2_signed) + buffer = vec_ite(overflow_right, overflow_pattern_left, buffer); + + for (int i = vec2_bits-1; i >= 0; i--) { + std::vector shifted_buffer; + if (vec2_signed && i == vec2_bits-1) + shifted_buffer = vec_shift(buffer, -(1 << i), extend_left, extend_right); + else + shifted_buffer = vec_shift(buffer, 1 << i, extend_left, extend_right); + buffer = vec_ite(vec2[i], shifted_buffer, buffer); + } + + buffer.resize(vec1.size()); + return buffer; +} + +std::vector ezSAT::vec_shift_left(const std::vector &vec1, const std::vector &vec2, bool vec2_signed, int extend_left, int extend_right) +{ + // vec2_signed is not implemented in vec_shift_left() yet + assert(vec2_signed == false); + + int vec2_bits = std::min(my_clog2(vec1.size()), int(vec2.size())); + + std::vector overflow_bits(vec2.begin() + vec2_bits, vec2.end()); + int overflow = vec_reduce_or(overflow_bits); + + std::vector buffer = vec1; + std::vector overflow_pattern_right(buffer.size(), extend_right); + buffer = vec_ite(overflow, overflow_pattern_right, buffer); + + for (int i = 0; i < vec2_bits; i++) { + std::vector shifted_buffer; + shifted_buffer = vec_shift(buffer, -(1 << i), extend_left, extend_right); + buffer = vec_ite(vec2[i], shifted_buffer, buffer); + } + + buffer.resize(vec1.size()); + return buffer; +} + void ezSAT::vec_append(std::vector &vec, const std::vector &vec1) const { for (auto bit : vec1) diff --git a/libs/ezsat/ezsat.h b/libs/ezsat/ezsat.h index 83e1b23c..c5ef6b0a 100644 --- a/libs/ezsat/ezsat.h +++ b/libs/ezsat/ezsat.h @@ -237,7 +237,7 @@ public: std::vector vec_iff(const std::vector &vec1, const std::vector &vec2); std::vector vec_ite(const std::vector &vec1, const std::vector &vec2, const std::vector &vec3); - std::vector vec_ite(int sel, const std::vector &vec2, const std::vector &vec3); + std::vector vec_ite(int sel, const std::vector &vec1, const std::vector &vec2); std::vector vec_count(const std::vector &vec, int numBits, bool clip = true); std::vector vec_add(const std::vector &vec1, const std::vector &vec2); @@ -265,6 +265,10 @@ public: std::vector vec_shr(const std::vector &vec1, int shift, bool signExtend = false) { return vec_shl(vec1, -shift, signExtend); } std::vector vec_srr(const std::vector &vec1, int shift) { return vec_srl(vec1, -shift); } + std::vector vec_shift(const std::vector &vec1, int shift, int extend_left, int extend_right); + std::vector vec_shift_right(const std::vector &vec1, const std::vector &vec2, bool vec2_signed, int extend_left, int extend_right); + std::vector vec_shift_left(const std::vector &vec1, const std::vector &vec2, bool vec2_signed, int extend_left, int extend_right); + void vec_append(std::vector &vec, const std::vector &vec1) const; void vec_append_signed(std::vector &vec, const std::vector &vec1, int64_t value); void vec_append_unsigned(std::vector &vec, const std::vector &vec1, uint64_t value); From 3f0a5746ef0940accb5fd14d97804c75c0531c0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 17:18:31 +0200 Subject: [PATCH 492/750] Using native ezSAT shift ops in satgen, fixed $shift and $shiftx SAT models --- kernel/satgen.h | 71 ++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index a079b42f..ce2c9028 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -603,63 +603,66 @@ struct SatGen std::vector b = importDefSigSpec(cell->get("\\B"), timestep); std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); - char shift_left = cell->type == "$shl" || cell->type == "$sshl"; - bool sign_extend = cell->type == "$sshr" && cell->parameters["\\A_SIGNED"].as_bool(); - bool shift_shiftx = cell->type == "$shift" || cell->type == "$shiftx"; + int extend_bit = ez->FALSE; + + if (cell->type != "$shift" && cell->type != "$shiftx" && cell->parameters["\\A_SIGNED"].as_bool()) + extend_bit = a.back(); while (y.size() < a.size()) y.push_back(ez->literal()); while (y.size() > a.size()) - a.push_back(cell->parameters["\\A_SIGNED"].as_bool() ? a.back() : ez->FALSE); + a.push_back(extend_bit); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; + std::vector shifted_a; - std::vector tmp = a; - for (size_t i = 0; i < b.size(); i++) - { - bool shift_left_this = shift_left; - if (shift_shiftx && i == b.size()-1 && cell->parameters["\\B_SIGNED"].as_bool()) - shift_left_this = true; + if (cell->type == "$shl" || cell->type == "$sshl") + shifted_a = ez->vec_shift_left(a, b, false, ez->FALSE, ez->FALSE); - std::vector tmp_shifted(tmp.size()); - for (size_t j = 0; j < tmp.size(); j++) { - int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left_this ? -1 : +1); - tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : sign_extend ? tmp.back() : ez->FALSE; - } - tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp); - } - ez->assume(ez->vec_eq(tmp, yy)); + if (cell->type == "$shr") + shifted_a = ez->vec_shift_right(a, b, false, ez->FALSE, ez->FALSE); + + if (cell->type == "$sshr") + shifted_a = ez->vec_shift_right(a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? a.back() : ez->FALSE, ez->FALSE); + + if (cell->type == "$shift" || cell->type == "$shiftx") + shifted_a = ez->vec_shift_right(a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->FALSE, ez->FALSE); + + ez->assume(ez->vec_eq(shifted_a, yy)); if (model_undef) { std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a_shifted; + + if (cell->type != "$shift" && cell->type != "$shiftx" && cell->parameters["\\A_SIGNED"].as_bool()) + extend_bit = undef_a.back(); while (undef_y.size() < undef_a.size()) undef_y.push_back(ez->literal()); while (undef_y.size() > undef_a.size()) - undef_a.push_back(cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : ez->FALSE); + undef_a.push_back(extend_bit); - tmp = undef_a; - for (size_t i = 0; i < b.size(); i++) - { - bool shift_left_this = shift_left; - if (shift_shiftx && i == b.size()-1 && cell->parameters["\\B_SIGNED"].as_bool()) - shift_left_this = true; + if (cell->type == "$shl" || cell->type == "$sshl") + undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->FALSE, ez->FALSE); - std::vector tmp_shifted(tmp.size()); - for (size_t j = 0; j < tmp.size(); j++) { - int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left_this ? -1 : +1); - tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : - sign_extend ? tmp.back() : cell->type == "$shiftx" ? ez->TRUE : ez->FALSE; - } - tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp); - } + if (cell->type == "$shr") + undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->FALSE, ez->FALSE); + + if (cell->type == "$sshr") + undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : ez->FALSE, ez->FALSE); + + if (cell->type == "$shift") + undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->FALSE, ez->FALSE); + + if (cell->type == "$shiftx") + undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->TRUE, ez->TRUE); int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); std::vector undef_all_y_bits(undef_y.size(), undef_any_b); - ez->assume(ez->vec_eq(ez->vec_or(tmp, undef_all_y_bits), undef_y)); + ez->assume(ez->vec_eq(ez->vec_or(undef_a_shifted, undef_all_y_bits), undef_y)); undefGating(y, yy, undef_y); } return true; From 6c05badc43f7c1691932d1c38869492311f9bd44 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 15:59:05 +0200 Subject: [PATCH 493/750] New techmap default rules for $shr $sshr $shl $sshl --- techlibs/common/stdcells.v | 372 ++++++++----------------------------- 1 file changed, 76 insertions(+), 296 deletions(-) diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index ee59048c..a2fce131 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -30,6 +30,9 @@ * */ +`define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +`define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) + // -------------------------------------------------------- (* techmap_simplemap *) @@ -65,7 +68,7 @@ output [Y_WIDTH-1:0] Y; .A_WIDTH(1), .B_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH) -) sub ( +) _TECHMAP_REPLACE_ ( .A(1'b0), .B(A), .Y(Y) @@ -129,34 +132,55 @@ endmodule // -------------------------------------------------------- -module \$__shift (XL, XR, A, Y); +(* techmap_celltype = "$shr $shl $sshl $sshr" *) +module shift_ops_shr_shl_sshl_sshr (A, B, Y); -parameter WIDTH = 1; -parameter SHIFT = 0; +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; -input XL, XR; -input [WIDTH-1:0] A; -output [WIDTH-1:0] Y; +parameter _TECHMAP_CELLTYPE_ = ""; +localparam shift_left = _TECHMAP_CELLTYPE_ == "$shl" || _TECHMAP_CELLTYPE_ == "$sshl"; +localparam sign_extend = A_SIGNED && _TECHMAP_CELLTYPE_ == "$sshr"; -genvar i; -generate - for (i = 0; i < WIDTH; i = i + 1) begin:V - if (i+SHIFT < 0) begin - assign Y[i] = XR; - end else - if (i+SHIFT < WIDTH) begin - assign Y[i] = A[i+SHIFT]; - end else begin - assign Y[i] = XL; +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH); +localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH); + +wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; + +integer i; +reg [WIDTH-1:0] buffer; +reg overflow; + +always @* begin + overflow = B_WIDTH > BB_WIDTH ? |B[B_WIDTH-1:BB_WIDTH] : 1'b0; + buffer = overflow ? {WIDTH{sign_extend ? A[A_WIDTH-1] : 1'b0}} : {{WIDTH-A_WIDTH{A_SIGNED ? A[A_WIDTH-1] : 1'b0}}, A}; + + for (i = 0; i < BB_WIDTH; i = i+1) + if (B[i]) begin + if (shift_left) + buffer = {buffer, (2**i)'b0}; + else if (2**i < WIDTH) + buffer = {{2**i{sign_extend ? buffer[WIDTH-1] : 1'b0}}, buffer[WIDTH-1 : 2**i]}; + else + buffer = {WIDTH{sign_extend ? buffer[WIDTH-1] : 1'b0}}; end - end -endgenerate +end + +assign Y = buffer; endmodule // -------------------------------------------------------- -module \$shl (A, B, Y); +(* techmap_celltype = "$shift $shiftx" *) +module shift_shiftx (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; @@ -164,294 +188,50 @@ parameter A_WIDTH = 1; parameter B_WIDTH = 1; parameter Y_WIDTH = 1; -parameter WIDTH = Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; - input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; -genvar i; -generate - wire [WIDTH*(BB_WIDTH+1)-1:0] chain; - \$bu0 #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; - for (i = 0; i < BB_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - wire BBIT; - if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) - assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; - else - assign BBIT = B[i]; - \$__shift #( - .WIDTH(WIDTH), - .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) - ) sh ( - .XL(1'b0), - .XR(1'b0), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(BBIT) - ); - end -endgenerate +localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH); +localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0); -endmodule +parameter _TECHMAP_CELLTYPE_ = ""; +localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx; -// -------------------------------------------------------- +wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; -module \$shr (A, B, Y); +integer i; +reg [WIDTH-1:0] buffer; +reg overflow; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; +always @* begin + overflow = 0; + buffer = {WIDTH{extbit}}; + buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A; -localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - wire [WIDTH*(BB_WIDTH+1)-1:0] chain; - \$bu0 #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; - for (i = 0; i < BB_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - wire BBIT; - if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) - assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; - else - assign BBIT = B[i]; - \$__shift #( - .WIDTH(WIDTH), - .SHIFT(2 ** (i > 30 ? 30 : i)) - ) sh ( - .XL(1'b0), - .XR(1'b0), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(BBIT) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$sshl (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -localparam WIDTH = Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - wire [WIDTH*(BB_WIDTH+1)-1:0] chain; - \$bu0 #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - assign Y = chain[WIDTH*(BB_WIDTH+1)-1 : WIDTH*BB_WIDTH]; - for (i = 0; i < BB_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - wire BBIT; - if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) - assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; - else - assign BBIT = B[i]; - \$__shift #( - .WIDTH(WIDTH), - .SHIFT(0 - (2 ** (i > 30 ? 30 : i))) - ) sh ( - .XL(1'b0), - .XR(1'b0), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(BBIT) - ); - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$sshr (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -genvar i; -generate - wire [WIDTH*(BB_WIDTH+1)-1:0] chain; - \$bu0 #( - .A_SIGNED(A_SIGNED), - .A_WIDTH(A_WIDTH), - .Y_WIDTH(WIDTH) - ) expand ( - .A(A), - .Y(chain[WIDTH-1:0]) - ); - for (i = 0; i < Y_WIDTH; i = i + 1) begin:Y - if (i < WIDTH) begin - assign Y[i] = chain[WIDTH*BB_WIDTH + i]; + if (B_WIDTH > BB_WIDTH) begin + if (B_SIGNED) begin + for (i = BB_WIDTH; i < B_WIDTH; i = i+1) + if (B[i] != B[BB_WIDTH-1]) + overflow = 1; end else - if (A_SIGNED) begin - assign Y[i] = chain[WIDTH*BB_WIDTH + WIDTH-1]; - end else begin - assign Y[i] = 0; + overflow = |B[B_WIDTH-1:BB_WIDTH]; + if (overflow) + buffer = {WIDTH{extbit}}; + end + + for (i = BB_WIDTH-1; i >= 0; i = i-1) + if (B[i]) begin + if (B_SIGNED && i == BB_WIDTH-1) + buffer = {buffer, {2**i{extbit}}}; + else if (2**i < WIDTH) + buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]}; + else + buffer = {WIDTH{extbit}}; end - end - for (i = 0; i < BB_WIDTH; i = i + 1) begin:V - wire [WIDTH-1:0] unshifted, shifted, result; - assign unshifted = chain[WIDTH*i + WIDTH-1 : WIDTH*i]; - assign chain[WIDTH*(i+1) + WIDTH-1 : WIDTH*(i+1)] = result; - wire BBIT; - if (i == BB_WIDTH-1 && BB_WIDTH < B_WIDTH) - assign BBIT = |B[B_WIDTH-1:BB_WIDTH-1]; - else - assign BBIT = B[i]; - \$__shift #( - .WIDTH(WIDTH), - .SHIFT(2 ** (i > 30 ? 30 : i)) - ) sh ( - .XL(A_SIGNED && A[A_WIDTH-1]), - .XR(1'b0), - .A(unshifted), - .Y(shifted) - ); - \$mux #( - .WIDTH(WIDTH) - ) mux ( - .A(unshifted), - .B(shifted), - .Y(result), - .S(BBIT) - ); - end -endgenerate +end -endmodule - -// -------------------------------------------------------- - -module \$shift (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -generate - if (B_SIGNED) begin:BLOCK1 - assign Y = $signed(B) < 0 ? A << -B : A >> B; - end else begin:BLOCK2 - assign Y = A >> B; - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$shiftx (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -\$shift #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(Y_WIDTH), -) sh ( - .A(A), - .B(B), - .Y(Y) -); +assign Y = buffer; endmodule From ceecf5b1535cf2e567c144bdbe143c8ba66c69d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 15:59:38 +0200 Subject: [PATCH 494/750] Improvements in test_cell --- passes/tests/test_cell.cc | 130 +++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 38 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 41671a8e..d504cea9 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -18,9 +18,8 @@ * */ -#include "kernel/register.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" +#include "kernel/yosys.h" +#include static uint32_t xorshift32(uint32_t limit) { static uint32_t x = 123456789; @@ -84,21 +83,52 @@ struct TestCellPass : public Pass { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" test_cell {cell-type}\n"); + log(" test_cell [options] {cell-types}\n"); log("\n"); log("Tests the internal implementation of the given cell type (for example '$mux')\n"); - log("by comparing SAT solver, EVAL and TECHMAP implementations of the cell type..\n"); + log("by comparing SAT solver, EVAL and TECHMAP implementations of the cell types..\n"); log("\n"); - log("Run with '-all' instead of a cell type to run the test on all supported\n"); + log("Run with 'all' instead of a cell type to run the test on all supported\n"); log("cell types.\n"); log("\n"); + log(" -n {integer}\n"); + log(" create this number of cell instances and test them (default = 100).\n"); + log("\n"); + log(" -f {ilang_file}\n"); + log(" don't generate circuits. instead load the specified ilang file.\n"); + log("\n"); + log(" -map {filename}\n"); + log(" pass this option to techmap.\n"); + log("\n"); } - virtual void execute(std::vector args, RTLIL::Design *current_design) + virtual void execute(std::vector args, RTLIL::Design*) { - if (SIZE(args) != 2) - log_cmd_error("Expecting exactly one argument.\n"); + int num_iter = 100; + std::string techmap_cmd = "techmap"; + std::string ilang_file; + + int argidx; + for (argidx = 1; argidx < SIZE(args); argidx++) + { + if (args[argidx] == "-n" && argidx+1 < SIZE(args)) { + num_iter = atoi(args[++argidx].c_str()); + continue; + } + if (args[argidx] == "-map" && argidx+1 < SIZE(args)) { + techmap_cmd += " -map " + args[++argidx]; + continue; + } + if (args[argidx] == "-f" && argidx+1 < SIZE(args)) { + ilang_file = args[++argidx]; + num_iter = 1; + continue; + } + break; + } std::map cell_types; + std::vector selected_cell_types; + cell_types["$not"] = "ASY"; cell_types["$pos"] = "ASY"; cell_types["$bu0"] = "ASY"; @@ -119,8 +149,8 @@ struct TestCellPass : public Pass { cell_types["$shr"] = "ABshY"; cell_types["$sshl"] = "ABshY"; cell_types["$sshr"] = "ABshY"; - // cell_types["$shift"] = "ABshY"; <-- FIXME - // cell_types["$shiftx"] = "ABshY"; + cell_types["$shift"] = "ABshY"; + cell_types["$shiftx"] = "ABshY"; cell_types["$lt"] = "ABSY"; cell_types["$le"] = "ABSY"; @@ -150,35 +180,59 @@ struct TestCellPass : public Pass { // cell_types["$lut"] = "A"; // cell_types["$assert"] = "A"; - if (args[1] == "-all") { - for (auto &it : cell_types) - Pass::call(current_design, "test_cell " + it.first); - return; - } - - if (cell_types.count(args[1]) == 0) { - std::string cell_type_list; - int charcount = 100; - for (auto &it : cell_types) { - if (charcount > 60) { - cell_type_list += "\n" + it.first; - charcount = 0; - } else - cell_type_list += " " + it.first; - charcount += SIZE(it.first); - } - log_cmd_error("This cell type is currently not supported. Try one of these:%s\n", cell_type_list.c_str()); - } - - for (int i = 0; i < 100; i++) + for (; argidx < SIZE(args); argidx++) { - RTLIL::Design *design = new RTLIL::Design; - create_gold_module(design, args[1], cell_types.at(args[1])); - Pass::call(design, "copy gold gate; techmap gate; opt gate; dump gold"); - Pass::call(design, "miter -equiv -flatten -ignore_gold_x gold gate miter"); - Pass::call(design, "sat -verify -enable_undef -prove trigger 0 miter"); - delete design; + if (args[argidx].rfind("-", 0) == 0) + log_cmd_error("Unexpected option: %s\n", args[argidx].c_str()); + + if (args[argidx] == "all") { + for (auto &it : cell_types) + if (std::count(selected_cell_types.begin(), selected_cell_types.end(), it.first) == 0) + selected_cell_types.push_back(it.first); + continue; + } + + if (cell_types.count(args[argidx]) == 0) { + std::string cell_type_list; + int charcount = 100; + for (auto &it : cell_types) { + if (charcount > 60) { + cell_type_list += "\n" + it.first; + charcount = 0; + } else + cell_type_list += " " + it.first; + charcount += SIZE(it.first); + } + log_cmd_error("The cell type `%s' is currently not supported. Try one of these:%s\n", + args[argidx].c_str(), cell_type_list.c_str()); + } + + if (std::count(selected_cell_types.begin(), selected_cell_types.end(), args[argidx]) == 0) + selected_cell_types.push_back(args[argidx]); } + + if (!ilang_file.empty()) { + if (!selected_cell_types.empty()) + log_cmd_error("Do not specify any cell types when using -f.\n"); + selected_cell_types.push_back("ilang"); + } + + if (selected_cell_types.empty()) + log_cmd_error("No cell type to test specified.\n"); + + for (auto cell_type : selected_cell_types) + for (int i = 0; i < num_iter; i++) + { + RTLIL::Design *design = new RTLIL::Design; + if (cell_type == "ilang") + Frontend::frontend_call(design, NULL, std::string(), "ilang " + ilang_file); + else + create_gold_module(design, cell_type, cell_types.at(cell_type)); + Pass::call(design, stringf("copy gold gate; %s gate; opt gate", techmap_cmd.c_str())); + Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter; dump gold"); + Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); + delete design; + } } } TestCellPass; From 7d98645fe8efcb446079a8a3cd8721ef5e27ee79 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 19:21:52 +0200 Subject: [PATCH 495/750] Added "make -j{N}" support to "make test" --- Makefile | 20 ++++++++++---------- tests/asicworld/run-test.sh | 2 +- tests/hana/run-test.sh | 2 +- tests/simple/run-test.sh | 2 +- tests/tools/autotest.mk | 8 ++++++++ tests/tools/autotest.sh | 21 +++++++++++++++------ tests/vloghtb/run-test.sh | 6 +++--- 7 files changed, 39 insertions(+), 22 deletions(-) create mode 100644 tests/tools/autotest.mk diff --git a/Makefile b/Makefile index 73d44833..4436be3d 100644 --- a/Makefile +++ b/Makefile @@ -218,15 +218,15 @@ yosys-abc: abc/abc-$(ABCREV) $(P) cp abc/abc-$(ABCREV) yosys-abc test: $(TARGETS) $(EXTRA_TARGETS) - cd tests/simple && bash run-test.sh - cd tests/hana && bash run-test.sh - cd tests/asicworld && bash run-test.sh - cd tests/realmath && bash run-test.sh - cd tests/share && bash run-test.sh - cd tests/techmap && bash run-test.sh - cd tests/memories && bash run-test.sh - cd tests/various && bash run-test.sh - cd tests/sat && bash run-test.sh + +cd tests/simple && bash run-test.sh + +cd tests/hana && bash run-test.sh + +cd tests/asicworld && bash run-test.sh + +cd tests/realmath && bash run-test.sh + +cd tests/share && bash run-test.sh + +cd tests/techmap && bash run-test.sh + +cd tests/memories && bash run-test.sh + +cd tests/various && bash run-test.sh + +cd tests/sat && bash run-test.sh @echo "" @echo " Passed \"make test\"." @echo "" @@ -240,7 +240,7 @@ vgtest: $(TARGETS) $(EXTRA_TARGETS) @echo "" vloghtb: $(TARGETS) $(EXTRA_TARGETS) - cd tests/vloghtb && bash run-test.sh + +cd tests/vloghtb && bash run-test.sh @echo "" @echo " Passed \"make vloghtb\"." @echo "" diff --git a/tests/asicworld/run-test.sh b/tests/asicworld/run-test.sh index a204360d..2477181a 100755 --- a/tests/asicworld/run-test.sh +++ b/tests/asicworld/run-test.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec bash ../tools/autotest.sh -G *.v +exec ${MAKE:-make} -f ../tools/autotest.mk *.v diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh index 89be6d05..410f9b4d 100755 --- a/tests/hana/run-test.sh +++ b/tests/hana/run-test.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec bash ../tools/autotest.sh -G -l hana_vlib.v test_*.v +exec ${MAKE:-make} -f ../tools/autotest.mk EXTRA_FLAGS="-l hana_vlib.v" test_*.v diff --git a/tests/simple/run-test.sh b/tests/simple/run-test.sh index ec1802cb..6531d51a 100755 --- a/tests/simple/run-test.sh +++ b/tests/simple/run-test.sh @@ -6,4 +6,4 @@ if ! which iverilog > /dev/null ; then exit 1 fi -exec bash ../tools/autotest.sh -G *.v +exec ${MAKE:-make} -f ../tools/autotest.mk *.v diff --git a/tests/tools/autotest.mk b/tests/tools/autotest.mk new file mode 100644 index 00000000..f65002ce --- /dev/null +++ b/tests/tools/autotest.mk @@ -0,0 +1,8 @@ + +EXTRA_FLAGS= + +$(MAKECMDGOALS): + @$(basename $(MAKEFILE_LIST)).sh -G -j $(EXTRA_FLAGS) $@ + +.PHONY: $(MAKECMDGOALS) + diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 1130bbb7..781dc167 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -6,6 +6,7 @@ use_xsim=false use_modelsim=false verbose=false keeprunning=false +makejmode=false frontend="verilog" backend_opts="-noattr -noexpr" scriptfiles="" @@ -17,7 +18,7 @@ if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdat ( set -ex; gcc -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1 fi -while getopts xmGl:wkvrf:s:p: opt; do +while getopts xmGl:wkjvrf:s:p: opt; do case "$opt" in x) use_xsim=true ;; @@ -31,6 +32,8 @@ while getopts xmGl:wkvrf:s:p: opt; do genvcd=true ;; k) keeprunning=true ;; + j) + makejmode=true ;; v) verbose=true ;; r) @@ -43,7 +46,7 @@ while getopts xmGl:wkvrf:s:p: opt; do p) scriptopt="$OPTARG" ;; *) - echo "Usage: $0 [-x|-m] [-w] [-k] [-v] [-r] [-l libs] [-f frontend] [-s script] [-p cmdstring] verilog-files\n" >&2 + echo "Usage: $0 [-x|-m] [-w] [-k] [-j] [-v] [-r] [-l libs] [-f frontend] [-s script] [-p cmdstring] verilog-files\n" >&2 exit 1 esac done @@ -83,7 +86,13 @@ do exit 1 fi [[ "$bn" == *_tb ]] && continue - echo -n "Test: $bn " + + if $makejmode; then + status_prefix="Test: $bn " + else + status_prefix="" + echo -n "Test: $bn " + fi rm -f ${bn}.{err,log,sikp} mkdir -p ${bn}.out @@ -144,12 +153,12 @@ do if [ -f ${bn}.log ]; then mv ${bn}.err ${bn}.log - echo "-> ok" + echo "${status_prefix}-> ok" elif [ -f ${bn}.skip ]; then mv ${bn}.err ${bn}.skip - echo "-> skip" + echo "${status_prefix}-> skip" else - echo "-> ERROR!" + echo "${status_prefix}-> ERROR!" if $warn_iverilog_git; then echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of icarus verilog." fi diff --git a/tests/vloghtb/run-test.sh b/tests/vloghtb/run-test.sh index b1b205a2..ad99226e 100755 --- a/tests/vloghtb/run-test.sh +++ b/tests/vloghtb/run-test.sh @@ -9,7 +9,7 @@ tar --strip=1 -xjf vloghammer_tb.tar.bz2 make clean rm -rf log_test_* -make -j4 EXIT_ON_ERROR=1 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys -make -j4 -f test_makefile MODE=share -make -j4 -f test_makefile MODE=mapopt +${MAKE:-make} EXIT_ON_ERROR=1 YOSYS_BIN=$PWD/../../yosys YOSYS_SCRIPT="proc;;" check_yosys +${MAKE:-make} -f test_makefile MODE=share +${MAKE:-make} -f test_makefile MODE=mapopt From 6400ae36489a7ada5419d7bc502934f6d05e69bb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 19:59:29 +0200 Subject: [PATCH 496/750] Added write_file command --- kernel/register.cc | 8 +++-- kernel/register.h | 4 +-- passes/cmds/Makefile.inc | 1 + passes/cmds/write_file.cc | 76 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 passes/cmds/write_file.cc diff --git a/kernel/register.cc b/kernel/register.cc index 4569481f..c7bd2cce 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -245,7 +245,9 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vec design->selected_active_module = backup_selected_active_module; } -Frontend::Frontend(std::string name, std::string short_help) : Pass("read_"+name, short_help), frontend_name(name) +Frontend::Frontend(std::string name, std::string short_help) : + Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help), + frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name) { } @@ -377,8 +379,8 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam } Backend::Backend(std::string name, std::string short_help) : - Pass(name.substr(0, 1) == "=" ? name.substr(1) : "write_"+name, short_help), - backend_name(name.substr(0, 1) == "=" ? name.substr(1) : name) + Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "write_" + name, short_help), + backend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name) { } diff --git a/kernel/register.h b/kernel/register.h index 68f09c82..41780bfb 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -66,7 +66,7 @@ struct Frontend : Pass Frontend(std::string name, std::string short_help = "** document me **"); virtual void run_register(); virtual ~Frontend(); - virtual void execute(std::vector args, RTLIL::Design *design); + virtual void execute(std::vector args, RTLIL::Design *design) override final; virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; static std::vector next_args; @@ -82,7 +82,7 @@ struct Backend : Pass Backend(std::string name, std::string short_help = "** document me **"); virtual void run_register(); virtual ~Backend(); - virtual void execute(std::vector args, RTLIL::Design *design); + virtual void execute(std::vector args, RTLIL::Design *design) override final; virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; void extra_args(FILE *&f, std::string &filename, std::vector args, size_t argidx); diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 6ae4495a..26c0ef8a 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -16,6 +16,7 @@ OBJS += passes/cmds/splice.o OBJS += passes/cmds/scc.o OBJS += passes/cmds/log.o OBJS += passes/cmds/tee.o +OBJS += passes/cmds/write_file.o OBJS += passes/cmds/connwrappers.o OBJS += passes/cmds/cover.o diff --git a/passes/cmds/write_file.cc b/passes/cmds/write_file.cc new file mode 100644 index 00000000..a7cd7b43 --- /dev/null +++ b/passes/cmds/write_file.cc @@ -0,0 +1,76 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Johann Glaser + * + * 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/yosys.h" + +struct WriteFileFrontend : public Frontend { + WriteFileFrontend() : Frontend("=write_file", "write a text to a file") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" write_file [options] output_file [input_file]\n"); + log("\n"); + log("Write the text fron the input file to the output file.\n"); + log("\n"); + log(" -a\n"); + log(" Append to output file (instead of overwriting)\n"); + log("\n"); + log("\n"); + log("Inside a script the input file can also can a here-document:\n"); + log("\n"); + log(" write_file hello.txt < args, RTLIL::Design*) + { + bool append_mode = false; + std::string output_filename; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-a") { + append_mode = true; + continue; + } + break; + } + + if (argidx < args.size() && args[argidx].rfind("-", 0) != 0) + output_filename = args[argidx++]; + else + log_cmd_error("Missing putput filename.\n"); + + extra_args(f, filename, args, argidx); + + FILE *of = fopen(output_filename.c_str(), append_mode ? "a" : "w"); + char buffer[64 * 1024]; + size_t bytes; + + while (0 < (bytes = fread(buffer, 1, sizeof(buffer), f))) + fwrite(buffer, bytes, 1, of); + + fclose(of); + } +} WriteFileFrontend; + From 7daad40ca408732786d46fee8b5485bf45595807 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 20:18:48 +0200 Subject: [PATCH 497/750] 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(-) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 0839f5cf..00deeb0b 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 9ff68822..2cfa8ca7 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; } From 254148910556d057ec296e4f8c44e92bdb8c09a3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 22:04:30 +0200 Subject: [PATCH 498/750] Added techmap CONSTMAP feature --- kernel/rtlil.h | 3 + passes/techmap/techmap.cc | 129 ++++++++++++++++++++++++++++++++++--- techlibs/common/stdcells.v | 6 +- 3 files changed, 126 insertions(+), 12 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d6acb5bc..7bd75bd1 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -278,6 +278,9 @@ namespace RTLIL result.push_back(it.second); return result; } + + std::set to_set() const { return *this; } + std::vector to_vector() const { return *this; } }; }; diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 0ae5220e..75b9dee9 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -17,11 +17,11 @@ * */ -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/sigtools.h" +#include "kernel/yosys.h" #include "kernel/toposort.h" -#include "kernel/log.h" +#include "kernel/sigtools.h" +#include "libs/sha1/sha1.h" + #include #include #include @@ -66,6 +66,36 @@ struct TechmapWorker typedef std::map> TechmapWires; + std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose) + { + std::string constmap_info; + std::map> connbits_map; + + for (auto conn : cell->connections()) + for (int i = 0; i < SIZE(conn.second); i++) { + RTLIL::SigBit bit = sigmap(conn.second[i]); + if (bit.wire == nullptr) { + if (verbose) + log(" Constant input on bit %d of port %s: %s\n", i, log_id(conn.first), log_signal(bit)); + constmap_info += stringf("|%s %d %d", log_id(conn.first), i, bit.data); + } else if (connbits_map.count(bit)) { + if (verbose) + log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, log_id(conn.first), + connbits_map.at(bit).second, log_id(connbits_map.at(bit).first)); + constmap_info += stringf("|%s %d %s %d", log_id(conn.first), i, + log_id(connbits_map.at(bit).first), connbits_map.at(bit).second); + } else + connbits_map[bit] = std::pair(conn.first, i);stringf("%s %d", log_id(conn.first), i, bit.data); + } + + unsigned char hash[20]; + char hash_hex_string[41]; + sha1::calc(constmap_info.c_str(), constmap_info.size(), hash); + sha1::toHexString(hash, hash_hex_string); + + return stringf("$paramod$constmap$%s%s", hash_hex_string, tpl->name.c_str()); + } + TechmapWires techmap_find_special_wires(RTLIL::Module *module) { TechmapWires result; @@ -374,14 +404,19 @@ struct TechmapWorker } else { if (cell->parameters.size() != 0) { derived_name = tpl->derive(map, parameters); - tpl = map->modules_[derived_name]; + tpl = map->module(derived_name); log_continue = true; } techmap_cache[key] = tpl; } - if (flatten_mode) + if (flatten_mode) { techmap_do_cache[tpl] = true; + } else { + RTLIL::Module *constmapped_tpl = map->module(constmap_tpl_name(sigmap, tpl, cell, false)); + if (constmapped_tpl != nullptr) + tpl = constmapped_tpl; + } if (techmap_do_cache.count(tpl) == 0) { @@ -426,14 +461,80 @@ struct TechmapWorker const char *q = strrchr(p+1, '.'); q = q ? q : p+1; + std::string cmd_string = data.value.as_const().decode_string(); + + if (cmd_string.rfind("CONSTMAP; ", 0) == 0) + { + cmd_string = cmd_string.substr(strlen("CONSTMAP; ")); + + log("Analyzing pattern of constant bits for this cell:\n"); + std::string new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true); + log("Creating constmapped module `%s'.\n", log_id(new_tpl_name)); + log_assert(map->module(new_tpl_name) == nullptr); + + RTLIL::Module *new_tpl = map->addModule(new_tpl_name); + tpl->cloneInto(new_tpl); + + techmap_do_cache.erase(tpl); + techmap_do_cache[new_tpl] = true; + tpl = new_tpl; + + std::map port_new2old_map; + std::map port_connmap; + std::map cellbits_to_tplbits; + + for (auto wire : tpl->wires().to_vector()) + { + if (!wire->port_input || wire->port_output) + continue; + + std::string port_name = wire->name; + tpl->rename(wire, NEW_ID); + + RTLIL::Wire *new_wire = tpl->addWire(port_name, wire); + wire->port_input = false; + + for (int i = 0; i < wire->width; i++) { + port_new2old_map[RTLIL::SigBit(new_wire, i)] = RTLIL::SigBit(wire, i); + port_connmap[RTLIL::SigBit(wire, i)] = RTLIL::SigBit(new_wire, i); + } + } + + for (auto conn : cell->connections()) + for (int i = 0; i < SIZE(conn.second); i++) + { + RTLIL::SigBit bit = sigmap(conn.second[i]); + RTLIL::SigBit tplbit(tpl->wire(conn.first), i); + + if (bit.wire == nullptr) + { + RTLIL::SigBit oldbit = port_new2old_map.at(tplbit); + port_connmap.at(oldbit) = bit; + } + else if (cellbits_to_tplbits.count(bit)) + { + RTLIL::SigBit oldbit = port_new2old_map.at(tplbit); + port_connmap.at(oldbit) = cellbits_to_tplbits[bit]; + } + else + cellbits_to_tplbits[bit] = tplbit; + } + + RTLIL::SigSig port_conn; + for (auto &it : port_connmap) { + port_conn.first.append_bit(it.first); + port_conn.second.append_bit(it.second); + } + tpl->connect(port_conn); + } + + Pass::call_on_module(map, tpl, cmd_string); + log_assert(!strncmp(q, "_TECHMAP_DO_", 12)); std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12); while (tpl->wires_.count(new_name)) new_name += "_"; - tpl->rename(data.wire, new_name); - - std::string cmd_string = data.value.as_const().decode_string(); - Pass::call_on_module(map, tpl, cmd_string); + tpl->rename(data.wire->name, new_name); keep_running = true; break; @@ -571,6 +672,14 @@ struct TechmapPass : public Pass { log(" wire to start out as non-constant and evaluate to a constant value\n"); log(" during processing of other _TECHMAP_DO_* commands.\n"); log("\n"); + log(" A _TECHMAP_DO_* command may start with the special token 'CONSTMAP; '.\n"); + log(" in this case techmap will create a copy for each distinct configuration\n"); + log(" of constant inputs and shorted inputs at this point and import the\n"); + log(" constant and connected bits into the map module. All further commands\n"); + log(" are executed in this copy. This is a very convenient way of creating\n"); + log(" optimizied specializations of techmap modules without using the special\n"); + log(" parameters described below.\n"); + log("\n"); log("In addition to this special wires, techmap also supports special parameters in\n"); log("modules in the map file:\n"); log("\n"); diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index a2fce131..7ee2771e 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -152,7 +152,8 @@ output [Y_WIDTH-1:0] Y; localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH); localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH); -wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; +wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; +wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; integer i; reg [WIDTH-1:0] buffer; @@ -198,7 +199,8 @@ localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0); parameter _TECHMAP_CELLTYPE_ = ""; localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx; -wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; +wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; +wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; integer i; reg [WIDTH-1:0] buffer; From e5c245df9d086595063978298139a9aaed68979d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 00:53:21 +0200 Subject: [PATCH 499/750] Added "yosys -Q" --- kernel/driver.cc | 61 +++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index c20be1dc..ab8ecba9 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -555,6 +555,7 @@ int main(int argc, char **argv) std::string scriptfile = ""; bool scriptfile_tcl = false; bool got_output_filename = false; + bool print_banner = true; int history_offset = 0; std::string history_file; @@ -565,10 +566,13 @@ int main(int argc, char **argv) } int opt; - while ((opt = getopt(argc, argv, "VSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) + while ((opt = getopt(argc, argv, "QVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) { switch (opt) { + case 'Q': + print_banner = false; + break; case 'V': printf("%s\n", yosys_version_str); exit(0); @@ -634,9 +638,12 @@ int main(int argc, char **argv) break; default: fprintf(stderr, "\n"); - fprintf(stderr, "Usage: %s [-V] [-S] [-q] [-v [-t] [-l ] [-o ] [-f ] [-h cmd] \\\n", argv[0]); + fprintf(stderr, "Usage: %s [-V -S -Q -q] [-v [-t] [-l ] [-o ] [-f ] [-h cmd] \\\n", argv[0]); fprintf(stderr, " %*s[{-s|-c} ] [-p [-p ..]] [-b ] [-m ] [ [..]]\n", int(strlen(argv[0])+1), ""); fprintf(stderr, "\n"); + fprintf(stderr, " -Q\n"); + fprintf(stderr, " suppress printing of banner (copyright, disclaimer, version)\n"); + fprintf(stderr, "\n"); fprintf(stderr, " -q\n"); fprintf(stderr, " quiet operation. only write error messages to console\n"); fprintf(stderr, "\n"); @@ -699,29 +706,31 @@ int main(int argc, char **argv) if (log_errfile == NULL) log_files.push_back(stderr); - log("\n"); - log(" /-----------------------------------------------------------------------------\\\n"); - log(" | |\n"); - log(" | yosys -- Yosys Open SYnthesis Suite |\n"); - log(" | |\n"); - log(" | Copyright (C) 2012 Clifford Wolf |\n"); - log(" | |\n"); - log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); - log(" | purpose with or without fee is hereby granted, provided that the above |\n"); - log(" | copyright notice and this permission notice appear in all copies. |\n"); - log(" | |\n"); - log(" | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |\n"); - log(" | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |\n"); - log(" | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |\n"); - log(" | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |\n"); - log(" | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |\n"); - log(" | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |\n"); - log(" | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |\n"); - log(" | |\n"); - log(" \\-----------------------------------------------------------------------------/\n"); - log("\n"); - log(" %s\n", yosys_version_str); - log("\n"); + if (print_banner) { + log("\n"); + log(" /-----------------------------------------------------------------------------\\\n"); + log(" | |\n"); + log(" | yosys -- Yosys Open SYnthesis Suite |\n"); + log(" | |\n"); + log(" | Copyright (C) 2012 Clifford Wolf |\n"); + log(" | |\n"); + log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); + log(" | purpose with or without fee is hereby granted, provided that the above |\n"); + log(" | copyright notice and this permission notice appear in all copies. |\n"); + log(" | |\n"); + log(" | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |\n"); + log(" | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |\n"); + log(" | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |\n"); + log(" | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |\n"); + log(" | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |\n"); + log(" | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |\n"); + log(" | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |\n"); + log(" | |\n"); + log(" \\-----------------------------------------------------------------------------/\n"); + log("\n"); + log(" %s\n", yosys_version_str); + log("\n"); + } Pass::init_register(); @@ -785,7 +794,7 @@ int main(int argc, char **argv) } #endif - log("\nREADY.\n"); + log("\nEnd of script.\n"); log_pop(); if (!history_file.empty()) { From 6166c768313f6a2dee774f0ba0a531816b24502d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 01:05:27 +0200 Subject: [PATCH 500/750] Added "yosys -A" --- kernel/driver.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index ab8ecba9..d9ef2223 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -556,6 +556,7 @@ int main(int argc, char **argv) bool scriptfile_tcl = false; bool got_output_filename = false; bool print_banner = true; + bool call_abort = false; int history_offset = 0; std::string history_file; @@ -566,10 +567,13 @@ int main(int argc, char **argv) } int opt; - while ((opt = getopt(argc, argv, "QVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) + while ((opt = getopt(argc, argv, "AQVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) { switch (opt) { + case 'A': + call_abort = true; + break; case 'Q': print_banner = false; break; @@ -683,6 +687,9 @@ int main(int argc, char **argv) fprintf(stderr, " -m module_file\n"); fprintf(stderr, " load the specified module (aka plugin)\n"); fprintf(stderr, "\n"); + fprintf(stderr, " -A\n"); + fprintf(stderr, " will call abort() at the end of the script. useful for debugging\n"); + fprintf(stderr, "\n"); fprintf(stderr, " -V\n"); fprintf(stderr, " print version information and exit\n"); fprintf(stderr, "\n"); @@ -795,6 +802,8 @@ int main(int argc, char **argv) #endif log("\nEnd of script.\n"); + if (call_abort) + abort(); log_pop(); if (!history_file.empty()) { From 41555cde1026ecc269071ede4f99d86ff61f7078 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 02:21:06 +0200 Subject: [PATCH 501/750] Reorganized stdcells.v (no actual code change, just moved and indented stuff) --- techlibs/common/stdcells.v | 1323 ++++++++++++++++-------------------- 1 file changed, 583 insertions(+), 740 deletions(-) diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index 7ee2771e..54652868 100644 --- a/techlibs/common/stdcells.v +++ b/techlibs/common/stdcells.v @@ -33,910 +33,753 @@ `define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) `define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) + +// -------------------------------------------------------- +// Use simplemap for trivial cell types // -------------------------------------------------------- (* techmap_simplemap *) -module \$not ; +(* techmap_celltype = "$pos $bu0" *) +module simplemap_buffers; endmodule -// -------------------------------------------------------- - (* techmap_simplemap *) -module \$pos ; +(* techmap_celltype = "$not $and $or $xor $xnor" *) +module simplemap_bool_ops; endmodule -// -------------------------------------------------------- - (* techmap_simplemap *) -module \$bu0 ; +(* techmap_celltype = "$reduce_and $reduce_or $reduce_xor $reduce_xnor $reduce_bool" *) +module simplemap_reduce_ops; endmodule +(* techmap_simplemap *) +(* techmap_celltype = "$logic_not $logic_and $logic_or" *) +module simplemap_logic_ops; +endmodule + +(* techmap_simplemap *) +(* techmap_celltype = "$slice $concat $mux" *) +module simplemap_various; +endmodule + +(* techmap_simplemap *) +(* techmap_celltype = "$sr $dff $adff $dffsr $dlatch" *) +module simplemap_registers; +endmodule + + +// -------------------------------------------------------- +// Trivial substitutions // -------------------------------------------------------- module \$neg (A, Y); + parameter A_SIGNED = 0; + parameter A_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter A_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -output [Y_WIDTH-1:0] Y; - -\$sub #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(1), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) -) _TECHMAP_REPLACE_ ( - .A(1'b0), - .B(A), - .Y(Y) -); + input [A_WIDTH-1:0] A; + output [Y_WIDTH-1:0] Y; + \$sub #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(1), + .B_WIDTH(A_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(1'b0), + .B(A), + .Y(Y) + ); endmodule +module \$ge (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + \$le #( + .A_SIGNED(B_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(B_WIDTH), + .B_WIDTH(A_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(B), + .B(A), + .Y(Y) + ); +endmodule + +module \$gt (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + \$lt #( + .A_SIGNED(B_SIGNED), + .B_SIGNED(A_SIGNED), + .A_WIDTH(B_WIDTH), + .B_WIDTH(A_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) _TECHMAP_REPLACE_ ( + .A(B), + .B(A), + .Y(Y) + ); +endmodule + + // -------------------------------------------------------- - -(* techmap_simplemap *) -module \$and ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$or ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$xor ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$xnor ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$reduce_and ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$reduce_or ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$reduce_xor ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$reduce_xnor ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$reduce_bool ; -endmodule - +// Shift operators // -------------------------------------------------------- (* techmap_celltype = "$shr $shl $sshl $sshr" *) module shift_ops_shr_shl_sshl_sshr (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + parameter _TECHMAP_CELLTYPE_ = ""; + localparam shift_left = _TECHMAP_CELLTYPE_ == "$shl" || _TECHMAP_CELLTYPE_ == "$sshl"; + localparam sign_extend = A_SIGNED && _TECHMAP_CELLTYPE_ == "$sshr"; -parameter _TECHMAP_CELLTYPE_ = ""; -localparam shift_left = _TECHMAP_CELLTYPE_ == "$shl" || _TECHMAP_CELLTYPE_ == "$sshl"; -localparam sign_extend = A_SIGNED && _TECHMAP_CELLTYPE_ == "$sshr"; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; + localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH); + localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH); -localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH); -localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH); + wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; + wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; -wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; -wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; + integer i; + reg [WIDTH-1:0] buffer; + reg overflow; -integer i; -reg [WIDTH-1:0] buffer; -reg overflow; + always @* begin + overflow = B_WIDTH > BB_WIDTH ? |B[B_WIDTH-1:BB_WIDTH] : 1'b0; + buffer = overflow ? {WIDTH{sign_extend ? A[A_WIDTH-1] : 1'b0}} : {{WIDTH-A_WIDTH{A_SIGNED ? A[A_WIDTH-1] : 1'b0}}, A}; -always @* begin - overflow = B_WIDTH > BB_WIDTH ? |B[B_WIDTH-1:BB_WIDTH] : 1'b0; - buffer = overflow ? {WIDTH{sign_extend ? A[A_WIDTH-1] : 1'b0}} : {{WIDTH-A_WIDTH{A_SIGNED ? A[A_WIDTH-1] : 1'b0}}, A}; - - for (i = 0; i < BB_WIDTH; i = i+1) - if (B[i]) begin - if (shift_left) - buffer = {buffer, (2**i)'b0}; - else if (2**i < WIDTH) - buffer = {{2**i{sign_extend ? buffer[WIDTH-1] : 1'b0}}, buffer[WIDTH-1 : 2**i]}; - else - buffer = {WIDTH{sign_extend ? buffer[WIDTH-1] : 1'b0}}; - end -end - -assign Y = buffer; + for (i = 0; i < BB_WIDTH; i = i+1) + if (B[i]) begin + if (shift_left) + buffer = {buffer, (2**i)'b0}; + else if (2**i < WIDTH) + buffer = {{2**i{sign_extend ? buffer[WIDTH-1] : 1'b0}}, buffer[WIDTH-1 : 2**i]}; + else + buffer = {WIDTH{sign_extend ? buffer[WIDTH-1] : 1'b0}}; + end + end + assign Y = buffer; endmodule -// -------------------------------------------------------- - (* techmap_celltype = "$shift $shiftx" *) module shift_shiftx (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; + localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH); + localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0); -localparam BB_WIDTH = `MIN($clog2(`MAX(A_WIDTH, Y_WIDTH)) + (B_SIGNED ? 2 : 1), B_WIDTH); -localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH) + (B_SIGNED ? 2**(BB_WIDTH-1) : 0); + parameter _TECHMAP_CELLTYPE_ = ""; + localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx; -parameter _TECHMAP_CELLTYPE_ = ""; -localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx; + wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; + wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; -wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; -wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; + integer i; + reg [WIDTH-1:0] buffer; + reg overflow; -integer i; -reg [WIDTH-1:0] buffer; -reg overflow; + always @* begin + overflow = 0; + buffer = {WIDTH{extbit}}; + buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A; -always @* begin - overflow = 0; - buffer = {WIDTH{extbit}}; - buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A; - - if (B_WIDTH > BB_WIDTH) begin - if (B_SIGNED) begin - for (i = BB_WIDTH; i < B_WIDTH; i = i+1) - if (B[i] != B[BB_WIDTH-1]) - overflow = 1; - end else - overflow = |B[B_WIDTH-1:BB_WIDTH]; - if (overflow) - buffer = {WIDTH{extbit}}; - end - - for (i = BB_WIDTH-1; i >= 0; i = i-1) - if (B[i]) begin - if (B_SIGNED && i == BB_WIDTH-1) - buffer = {buffer, {2**i{extbit}}}; - else if (2**i < WIDTH) - buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]}; - else + if (B_WIDTH > BB_WIDTH) begin + if (B_SIGNED) begin + for (i = BB_WIDTH; i < B_WIDTH; i = i+1) + if (B[i] != B[BB_WIDTH-1]) + overflow = 1; + end else + overflow = |B[B_WIDTH-1:BB_WIDTH]; + if (overflow) buffer = {WIDTH{extbit}}; end -end -assign Y = buffer; + for (i = BB_WIDTH-1; i >= 0; i = i-1) + if (B[i]) begin + if (B_SIGNED && i == BB_WIDTH-1) + buffer = {buffer, {2**i{extbit}}}; + else if (2**i < WIDTH) + buffer = {{2**i{extbit}}, buffer[WIDTH-1 : 2**i]}; + else + buffer = {WIDTH{extbit}}; + end + end + assign Y = buffer; endmodule + +// -------------------------------------------------------- +// ALU Infrastructure // -------------------------------------------------------- module \$__fulladd (A, B, C, X, Y); + // {X, Y} = A + B + C + input A, B, C; + output X, Y; -// {X, Y} = A + B + C -input A, B, C; -output X, Y; + // {t1, t2} = A + B + wire t1, t2, t3; -// {t1, t2} = A + B -wire t1, t2, t3; + \$_AND_ gate1 ( .A(A), .B(B), .Y(t1) ); + \$_XOR_ gate2 ( .A(A), .B(B), .Y(t2) ); + \$_AND_ gate3 ( .A(t2), .B(C), .Y(t3) ); + \$_XOR_ gate4 ( .A(t2), .B(C), .Y(Y) ); + \$_OR_ gate5 ( .A(t1), .B(t3), .Y(X) ); +endmodule -\$_AND_ gate1 ( .A(A), .B(B), .Y(t1) ); -\$_XOR_ gate2 ( .A(A), .B(B), .Y(t2) ); -\$_AND_ gate3 ( .A(t2), .B(C), .Y(t3) ); -\$_XOR_ gate4 ( .A(t2), .B(C), .Y(Y) ); -\$_OR_ gate5 ( .A(t1), .B(t3), .Y(X) ); +module \$__alu (A, B, Cin, Y, Cout, Csign); + parameter WIDTH = 1; + input [WIDTH-1:0] A, B; + input Cin; + + output [WIDTH-1:0] Y; + output Cout, Csign; + + wire [WIDTH:0] carry; + assign carry[0] = Cin; + assign Cout = carry[WIDTH]; + assign Csign = carry[WIDTH-1]; + + genvar i; + generate + for (i = 0; i < WIDTH; i = i + 1) begin:V + \$__fulladd adder ( + .A(A[i]), + .B(B[i]), + .C(carry[i]), + .X(carry[i+1]), + .Y(Y[i]) + ); + end + endgenerate endmodule // -------------------------------------------------------- - -module \$__alu (A, B, Cin, Y, Cout, Csign); - -parameter WIDTH = 1; - -input [WIDTH-1:0] A, B; -input Cin; - -output [WIDTH-1:0] Y; -output Cout, Csign; - -wire [WIDTH:0] carry; -assign carry[0] = Cin; -assign Cout = carry[WIDTH]; -assign Csign = carry[WIDTH-1]; - -genvar i; -generate - for (i = 0; i < WIDTH; i = i + 1) begin:V - \$__fulladd adder ( - .A(A[i]), - .B(B[i]), - .C(carry[i]), - .X(carry[i+1]), - .Y(Y[i]) - ); - end -endgenerate - -endmodule - +// Compare cells // -------------------------------------------------------- module \$lt (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; -localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; + wire carry, carry_sign; + wire [WIDTH-1:0] A_buf, B_buf, Y_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf, Y_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + \$__alu #( + .WIDTH(WIDTH) + ) alu ( + .A(A_buf), + .B(~B_buf), + .Cin(1'b1), + .Y(Y_buf), + .Cout(carry), + .Csign(carry_sign) + ); -\$__alu #( - .WIDTH(WIDTH) -) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign) -); - -// ALU flags -wire cf, of, zf, sf; -assign cf = !carry; -assign of = carry ^ carry_sign; -assign zf = ~|Y_buf; -assign sf = Y_buf[WIDTH-1]; - -generate - if (A_SIGNED && B_SIGNED) begin - assign Y = of != sf; - end else begin - assign Y = cf; - end -endgenerate + // ALU flags + wire cf, of, zf, sf; + assign cf = !carry; + assign of = carry ^ carry_sign; + assign zf = ~|Y_buf; + assign sf = Y_buf[WIDTH-1]; + generate + if (A_SIGNED && B_SIGNED) begin + assign Y = of != sf; + end else begin + assign Y = cf; + end + endgenerate endmodule -// -------------------------------------------------------- - module \$le (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; -localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; + wire carry, carry_sign; + wire [WIDTH-1:0] A_buf, B_buf, Y_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf, Y_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + \$__alu #( + .WIDTH(WIDTH) + ) alu ( + .A(A_buf), + .B(~B_buf), + .Cin(1'b1), + .Y(Y_buf), + .Cout(carry), + .Csign(carry_sign) + ); -\$__alu #( - .WIDTH(WIDTH) -) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign) -); - -// ALU flags -wire cf, of, zf, sf; -assign cf = !carry; -assign of = carry ^ carry_sign; -assign zf = ~|Y_buf; -assign sf = Y_buf[WIDTH-1]; - -generate - if (A_SIGNED && B_SIGNED) begin - assign Y = zf || (of != sf); - end else begin - assign Y = zf || cf; - end -endgenerate + // ALU flags + wire cf, of, zf, sf; + assign cf = !carry; + assign of = carry ^ carry_sign; + assign zf = ~|Y_buf; + assign sf = Y_buf[WIDTH-1]; + generate + if (A_SIGNED && B_SIGNED) begin + assign Y = zf || (of != sf); + end else begin + assign Y = zf || cf; + end + endgenerate endmodule + // -------------------------------------------------------- - -module \$eq (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf; -\$bu0 #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$bu0 #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -assign Y = ~|(A_buf ^ B_buf); - -endmodule - -// -------------------------------------------------------- - -module \$ne (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf; -\$bu0 #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$bu0 #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -assign Y = |(A_buf ^ B_buf); - -endmodule - -// -------------------------------------------------------- - -module \$eqx (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -assign Y = ~|(A_buf ^ B_buf); - -endmodule - -// -------------------------------------------------------- - -module \$nex (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire carry, carry_sign; -wire [WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - -assign Y = |(A_buf ^ B_buf); - -endmodule - -// -------------------------------------------------------- - -module \$ge (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -\$le #( - .A_SIGNED(B_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(B_WIDTH), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) -) ge_via_le ( - .A(B), - .B(A), - .Y(Y) -); - -endmodule - -// -------------------------------------------------------- - -module \$gt (A, B, Y); - -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -\$lt #( - .A_SIGNED(B_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(B_WIDTH), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) -) gt_via_lt ( - .A(B), - .B(A), - .Y(Y) -); - -endmodule - +// Add and Subtract // -------------------------------------------------------- module \$add (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$__alu #( - .WIDTH(Y_WIDTH) -) alu ( - .A(A_buf), - .B(B_buf), - .Cin(1'b0), - .Y(Y) -); + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + \$__alu #( + .WIDTH(Y_WIDTH) + ) alu ( + .A(A_buf), + .B(B_buf), + .Cin(1'b0), + .Y(Y) + ); endmodule -// -------------------------------------------------------- - module \$sub (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$__alu #( - .WIDTH(Y_WIDTH) -) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y) -); + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + \$__alu #( + .WIDTH(Y_WIDTH) + ) alu ( + .A(A_buf), + .B(~B_buf), + .Cin(1'b1), + .Y(Y) + ); endmodule + +// -------------------------------------------------------- +// Multiply // -------------------------------------------------------- module \$__arraymul (A, B, Y); + parameter WIDTH = 8; + input [WIDTH-1:0] A, B; + output [WIDTH-1:0] Y; -parameter WIDTH = 8; -input [WIDTH-1:0] A, B; -output [WIDTH-1:0] Y; + wire [WIDTH*WIDTH-1:0] partials; -wire [WIDTH*WIDTH-1:0] partials; - -genvar i; -assign partials[WIDTH-1 : 0] = A[0] ? B : 0; -generate for (i = 1; i < WIDTH; i = i+1) begin:gen - assign partials[WIDTH*(i+1)-1 : WIDTH*i] = (A[i] ? B << i : 0) + partials[WIDTH*i-1 : WIDTH*(i-1)]; -end endgenerate - -assign Y = partials[WIDTH*WIDTH-1 : WIDTH*(WIDTH-1)]; + genvar i; + assign partials[WIDTH-1 : 0] = A[0] ? B : 0; + generate for (i = 1; i < WIDTH; i = i+1) begin:gen + assign partials[WIDTH*(i+1)-1 : WIDTH*i] = (A[i] ? B << i : 0) + partials[WIDTH*i-1 : WIDTH*(i-1)]; + end endgenerate + assign Y = partials[WIDTH*WIDTH-1 : WIDTH*(WIDTH-1)]; endmodule -// -------------------------------------------------------- - module \$mul (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire [Y_WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - -\$__arraymul #( - .WIDTH(Y_WIDTH) -) arraymul ( - .A(A_buf), - .B(B_buf), - .Y(Y) -); + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + \$__arraymul #( + .WIDTH(Y_WIDTH) + ) arraymul ( + .A(A_buf), + .B(B_buf), + .Y(Y) + ); endmodule + +// -------------------------------------------------------- +// Divide and Modulo // -------------------------------------------------------- module \$__div_mod_u (A, B, Y, R); + parameter WIDTH = 1; -parameter WIDTH = 1; + input [WIDTH-1:0] A, B; + output [WIDTH-1:0] Y, R; -input [WIDTH-1:0] A, B; -output [WIDTH-1:0] Y, R; + wire [WIDTH*WIDTH-1:0] chaindata; + assign R = chaindata[WIDTH*WIDTH-1:WIDTH*(WIDTH-1)]; -wire [WIDTH*WIDTH-1:0] chaindata; -assign R = chaindata[WIDTH*WIDTH-1:WIDTH*(WIDTH-1)]; + genvar i; + generate begin + for (i = 0; i < WIDTH; i=i+1) begin:stage + wire [WIDTH-1:0] stage_in; -genvar i; -generate begin - for (i = 0; i < WIDTH; i=i+1) begin:stage - wire [WIDTH-1:0] stage_in; + if (i == 0) begin:cp + assign stage_in = A; + end else begin:cp + assign stage_in = chaindata[i*WIDTH-1:(i-1)*WIDTH]; + end - if (i == 0) begin:cp - assign stage_in = A; - end else begin:cp - assign stage_in = chaindata[i*WIDTH-1:(i-1)*WIDTH]; + assign Y[WIDTH-(i+1)] = stage_in >= {B, {WIDTH-(i+1){1'b0}}}; + assign chaindata[(i+1)*WIDTH-1:i*WIDTH] = Y[WIDTH-(i+1)] ? stage_in - {B, {WIDTH-(i+1){1'b0}}} : stage_in; end - - assign Y[WIDTH-(i+1)] = stage_in >= {B, {WIDTH-(i+1){1'b0}}}; - assign chaindata[(i+1)*WIDTH-1:i*WIDTH] = Y[WIDTH-(i+1)] ? stage_in - {B, {WIDTH-(i+1){1'b0}}} : stage_in; - end -end endgenerate - + end endgenerate endmodule -// -------------------------------------------------------- - module \$__div_mod (A, B, Y, R); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; + localparam WIDTH = + A_WIDTH >= B_WIDTH && A_WIDTH >= Y_WIDTH ? A_WIDTH : + B_WIDTH >= A_WIDTH && B_WIDTH >= Y_WIDTH ? B_WIDTH : Y_WIDTH; -localparam WIDTH = - A_WIDTH >= B_WIDTH && A_WIDTH >= Y_WIDTH ? A_WIDTH : - B_WIDTH >= A_WIDTH && B_WIDTH >= Y_WIDTH ? B_WIDTH : Y_WIDTH; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y, R; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y, R; + wire [WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); -wire [WIDTH-1:0] A_buf, B_buf; -\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); -\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + wire [WIDTH-1:0] A_buf_u, B_buf_u, Y_u, R_u; + assign A_buf_u = A_SIGNED && A_buf[WIDTH-1] ? -A_buf : A_buf; + assign B_buf_u = B_SIGNED && B_buf[WIDTH-1] ? -B_buf : B_buf; -wire [WIDTH-1:0] A_buf_u, B_buf_u, Y_u, R_u; -assign A_buf_u = A_SIGNED && A_buf[WIDTH-1] ? -A_buf : A_buf; -assign B_buf_u = B_SIGNED && B_buf[WIDTH-1] ? -B_buf : B_buf; - -\$__div_mod_u #( - .WIDTH(WIDTH) -) div_mod_u ( - .A(A_buf_u), - .B(B_buf_u), - .Y(Y_u), - .R(R_u) -); - -assign Y = A_SIGNED && B_SIGNED && (A_buf[WIDTH-1] != B_buf[WIDTH-1]) ? -Y_u : Y_u; -assign R = A_SIGNED && B_SIGNED && A_buf[WIDTH-1] ? -R_u : R_u; + \$__div_mod_u #( + .WIDTH(WIDTH) + ) div_mod_u ( + .A(A_buf_u), + .B(B_buf_u), + .Y(Y_u), + .R(R_u) + ); + assign Y = A_SIGNED && B_SIGNED && (A_buf[WIDTH-1] != B_buf[WIDTH-1]) ? -Y_u : Y_u; + assign R = A_SIGNED && B_SIGNED && A_buf[WIDTH-1] ? -R_u : R_u; endmodule -// -------------------------------------------------------- - module \$div (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -\$__div_mod #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(Y_WIDTH) -) div_mod ( - .A(A), - .B(B), - .Y(Y) -); + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + \$__div_mod #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) div_mod ( + .A(A), + .B(B), + .Y(Y) + ); endmodule -// -------------------------------------------------------- - module \$mod (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -\$__div_mod #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(Y_WIDTH) -) div_mod ( - .A(A), - .B(B), - .R(Y) -); + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + \$__div_mod #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(Y_WIDTH) + ) div_mod ( + .A(A), + .B(B), + .R(Y) + ); endmodule -/**** + +// -------------------------------------------------------- +// Power // -------------------------------------------------------- module \$pow (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; - -wire signed [A_WIDTH:0] buffer_a = A_SIGNED ? $signed(A) : A; -wire signed [B_WIDTH:0] buffer_b = B_SIGNED ? $signed(B) : B; - -assign Y = buffer_a ** buffer_b; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + wire _TECHMAP_FAIL_ = 1; endmodule + // -------------------------------------------------------- -****/ - -(* techmap_simplemap *) -module \$logic_not ; -endmodule - +// Equal and Not-Equal // -------------------------------------------------------- -(* techmap_simplemap *) -module \$logic_and ; +module \$eq (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + wire carry, carry_sign; + wire [WIDTH-1:0] A_buf, B_buf; + \$bu0 #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$bu0 #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + + assign Y = ~|(A_buf ^ B_buf); endmodule +module \$ne (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + wire carry, carry_sign; + wire [WIDTH-1:0] A_buf, B_buf; + \$bu0 #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$bu0 #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + + assign Y = |(A_buf ^ B_buf); +endmodule + +module \$eqx (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + wire carry, carry_sign; + wire [WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + + assign Y = ~|(A_buf ^ B_buf); +endmodule + +module \$nex (A, B, Y); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + wire carry, carry_sign; + wire [WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); + + assign Y = |(A_buf ^ B_buf); +endmodule + + // -------------------------------------------------------- - -(* techmap_simplemap *) -module \$logic_or ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$slice ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$concat ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$mux ; -endmodule - +// Parallel Multiplexers // -------------------------------------------------------- module \$pmux (A, B, S, Y); + parameter WIDTH = 1; + parameter S_WIDTH = 1; -parameter WIDTH = 1; -parameter S_WIDTH = 1; + input [WIDTH-1:0] A; + input [WIDTH*S_WIDTH-1:0] B; + input [S_WIDTH-1:0] S; + output [WIDTH-1:0] Y; -input [WIDTH-1:0] A; -input [WIDTH*S_WIDTH-1:0] B; -input [S_WIDTH-1:0] S; -output [WIDTH-1:0] Y; + wire [WIDTH-1:0] Y_B; -wire [WIDTH-1:0] Y_B; - -genvar i, j; -generate - wire [WIDTH*S_WIDTH-1:0] B_AND_S; - for (i = 0; i < S_WIDTH; i = i + 1) begin:B_AND - assign B_AND_S[WIDTH*(i+1)-1:WIDTH*i] = B[WIDTH*(i+1)-1:WIDTH*i] & {WIDTH{S[i]}}; - end:B_AND - for (i = 0; i < WIDTH; i = i + 1) begin:B_OR - wire [S_WIDTH-1:0] B_AND_BITS; - for (j = 0; j < S_WIDTH; j = j + 1) begin:B_AND_BITS_COLLECT - assign B_AND_BITS[j] = B_AND_S[WIDTH*j+i]; - end:B_AND_BITS_COLLECT - assign Y_B[i] = |B_AND_BITS; - end:B_OR -endgenerate - -assign Y = |S ? Y_B : A; + genvar i, j; + generate + wire [WIDTH*S_WIDTH-1:0] B_AND_S; + for (i = 0; i < S_WIDTH; i = i + 1) begin:B_AND + assign B_AND_S[WIDTH*(i+1)-1:WIDTH*i] = B[WIDTH*(i+1)-1:WIDTH*i] & {WIDTH{S[i]}}; + end:B_AND + for (i = 0; i < WIDTH; i = i + 1) begin:B_OR + wire [S_WIDTH-1:0] B_AND_BITS; + for (j = 0; j < S_WIDTH; j = j + 1) begin:B_AND_BITS_COLLECT + assign B_AND_BITS[j] = B_AND_S[WIDTH*j+i]; + end:B_AND_BITS_COLLECT + assign Y_B[i] = |B_AND_BITS; + end:B_OR + endgenerate + assign Y = |S ? Y_B : A; endmodule -// -------------------------------------------------------- - module \$safe_pmux (A, B, S, Y); + parameter WIDTH = 1; + parameter S_WIDTH = 1; -parameter WIDTH = 1; -parameter S_WIDTH = 1; + input [WIDTH-1:0] A; + input [WIDTH*S_WIDTH-1:0] B; + input [S_WIDTH-1:0] S; + output [WIDTH-1:0] Y; -input [WIDTH-1:0] A; -input [WIDTH*S_WIDTH-1:0] B; -input [S_WIDTH-1:0] S; -output [WIDTH-1:0] Y; + wire [S_WIDTH-1:0] status_found_first; + wire [S_WIDTH-1:0] status_found_second; -wire [S_WIDTH-1:0] status_found_first; -wire [S_WIDTH-1:0] status_found_second; - -genvar i; -generate - for (i = 0; i < S_WIDTH; i = i + 1) begin:GEN1 - wire pre_first; - if (i > 0) begin:GEN2 - assign pre_first = status_found_first[i-1]; - end:GEN2 else begin:GEN3 - assign pre_first = 0; - end:GEN3 - assign status_found_first[i] = pre_first | S[i]; - assign status_found_second[i] = pre_first & S[i]; - end:GEN1 -endgenerate - -\$pmux #( - .WIDTH(WIDTH), - .S_WIDTH(S_WIDTH) -) pmux_cell ( - .A(A), - .B(B), - .S(S & {S_WIDTH{~|status_found_second}}), - .Y(Y) -); + genvar i; + generate + for (i = 0; i < S_WIDTH; i = i + 1) begin:GEN1 + wire pre_first; + if (i > 0) begin:GEN2 + assign pre_first = status_found_first[i-1]; + end:GEN2 else begin:GEN3 + assign pre_first = 0; + end:GEN3 + assign status_found_first[i] = pre_first | S[i]; + assign status_found_second[i] = pre_first & S[i]; + end:GEN1 + endgenerate + \$pmux #( + .WIDTH(WIDTH), + .S_WIDTH(S_WIDTH) + ) pmux_cell ( + .A(A), + .B(B), + .S(S & {S_WIDTH{~|status_found_second}}), + .Y(Y) + ); endmodule -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$sr ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$dff ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$adff ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$dffsr ; -endmodule - -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$dlatch ; -endmodule - -// -------------------------------------------------------- - From 6ca0c569d92883b6eac1725204de90aee4af31bc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 02:21:41 +0200 Subject: [PATCH 502/750] Added "techmap -assert" --- passes/techmap/techmap.cc | 55 ++++++++++++++++++++++++++++++--------- passes/tests/test_cell.cc | 2 +- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 75b9dee9..50936af0 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -66,6 +66,17 @@ struct TechmapWorker typedef std::map> TechmapWires; + bool extern_mode; + bool assert_mode; + bool flatten_mode; + + TechmapWorker() + { + extern_mode = false; + assert_mode = false; + flatten_mode = false; + } + std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose) { std::string constmap_info; @@ -131,7 +142,7 @@ struct TechmapWorker return result; } - void techmap_module_worker(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, bool flatten_mode) + void techmap_module_worker(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl) { log("Mapping `%s.%s' using `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(tpl->name)); @@ -245,7 +256,7 @@ struct TechmapWorker } bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, - const std::map> &celltypeMap, bool flatten_mode, bool extern_mode) + const std::map> &celltypeMap) { if (!design->selected(module)) return false; @@ -264,8 +275,11 @@ struct TechmapWorker if (!design->selected(module, cell) || handled_cells.count(cell) > 0) continue; - if (celltypeMap.count(cell->type) == 0) + if (celltypeMap.count(cell->type) == 0) { + if (assert_mode && cell->type.back() != '_') + log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell->type)); continue; + } for (auto &conn : cell->connections()) { @@ -300,6 +314,7 @@ struct TechmapWorker { log_assert(handled_cells.count(cell) == 0); log_assert(cell == module->cell(cell->name)); + bool mapped_cell = false; for (auto &tpl_name : celltypeMap.at(cell->type)) { @@ -316,7 +331,7 @@ struct TechmapWorker { if (extern_mode) { - log("WARNING: Mapping simplat cell %s.%s (%s) in -extern mode is not supported yet.\n", log_id(module), log_id(cell), log_id(cell->type)); + log("WARNING: Mapping simplemap cell %s.%s (%s) in -extern mode is not supported yet.\n", log_id(module), log_id(cell), log_id(cell->type)); break; } else @@ -328,6 +343,7 @@ struct TechmapWorker module->remove(cell); cell = NULL; did_something = true; + mapped_cell = true; break; } } @@ -587,13 +603,17 @@ struct TechmapWorker } else { - techmap_module_worker(design, module, cell, tpl, flatten_mode); + techmap_module_worker(design, module, cell, tpl); cell = NULL; } did_something = true; + mapped_cell = true; break; } + if (assert_mode && !mapped_cell) + log_error("(ASSERT MODE) Failed to map cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + handled_cells.insert(cell); } @@ -636,6 +656,11 @@ struct TechmapPass : public Pass { log(" -max_iter \n"); log(" only run the specified number of iterations.\n"); log("\n"); + log(" -assert\n"); + log(" this option will cause techmap to exit with an error if it can't map\n"); + log(" a selected cell. only cell types that end on an underscore are accepted\n"); + log(" as final cell types by this mode.\n"); + log("\n"); log(" -D , -I \n"); log(" this options are passed as-is to the verilog frontend for loading the\n"); log(" map file. Note that the verilog frontend is also called with the\n"); @@ -720,9 +745,11 @@ struct TechmapPass : public Pass { log_header("Executing TECHMAP pass (map to technology primitives).\n"); log_push(); + TechmapWorker worker; + simplemap_get_mappers(worker.simplemap_mappers); + std::vector map_files; std::string verilog_frontend = "verilog -ignore_redef"; - bool extern_mode = false; int max_iter = -1; size_t argidx; @@ -748,17 +775,18 @@ struct TechmapPass : public Pass { verilog_frontend += " -I " + args[++argidx]; continue; } + if (args[argidx] == "-assert") { + worker.assert_mode = true; + continue; + } if (args[argidx] == "-extern") { - extern_mode = true; + worker.extern_mode = true; continue; } break; } extra_args(args, argidx, design); - TechmapWorker worker; - simplemap_get_mappers(worker.simplemap_mappers); - RTLIL::Design *map = new RTLIL::Design; if (map_files.empty()) { FILE *f = fmemopen(stdcells_code, strlen(stdcells_code), "rt"); @@ -811,7 +839,7 @@ struct TechmapPass : public Pass { std::set handled_cells; while (did_something) { did_something = false; - if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false, extern_mode)) + if (worker.techmap_module(design, module, map, handled_cells, celltypeMap)) did_something = true; if (did_something) module->check(); @@ -848,6 +876,7 @@ struct FlattenPass : public Pass { extra_args(args, 1, design); TechmapWorker worker; + worker.flatten_mode = true; std::map> celltypeMap; for (auto &it : design->modules_) @@ -864,11 +893,11 @@ struct FlattenPass : public Pass { while (did_something) { did_something = false; if (top_mod != NULL) { - if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, true, false)) + if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap)) did_something = true; } else { for (auto mod : design->modules()) - if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, true, false)) + if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap)) did_something = true; } } diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index d504cea9..4034f120 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -104,7 +104,7 @@ struct TestCellPass : public Pass { virtual void execute(std::vector args, RTLIL::Design*) { int num_iter = 100; - std::string techmap_cmd = "techmap"; + std::string techmap_cmd = "techmap -assert"; std::string ilang_file; int argidx; From 1202f7aa4bb0f9afde157ebc4701d64e7e38abd8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 02:32:00 +0200 Subject: [PATCH 503/750] Renamed "stdcells.v" to "techmap.v" --- CHECKLISTS | 2 +- README | 3 +-- manual/CHAPTER_Techmap.tex | 2 +- passes/techmap/.gitignore | 2 +- passes/techmap/Makefile.inc | 6 +++--- passes/techmap/techmap.cc | 4 ++-- techlibs/common/Makefile.inc | 6 +++++- techlibs/common/simcells.v | 2 +- techlibs/common/{stdcells.v => techmap.v} | 0 9 files changed, 15 insertions(+), 12 deletions(-) rename techlibs/common/{stdcells.v => techmap.v} (100%) diff --git a/CHECKLISTS b/CHECKLISTS index 8a149a53..3a06e61e 100644 --- a/CHECKLISTS +++ b/CHECKLISTS @@ -124,7 +124,7 @@ Things to do right away: - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) - Add to InternalCellChecker::check() in kernel/rtlil.cc - Add to techlibs/common/simlib.v - - Add to techlibs/common/stdcells.v + - Add to techlibs/common/techmap.v Things to do after finalizing the cell interface: diff --git a/README b/README index 4384cfbd..1e0ade91 100644 --- a/README +++ b/README @@ -304,8 +304,7 @@ Roadmap / Large-scale TODOs - yosys-bigsim: https://github.com/cliffordwolf/yosys-bigsim - Technology mapping for real-world applications - - Add bit-wise const-folding via cell parameters to techmap pass - - Rewrite current stdcells.v techmap rules (modular and clean) + - Rewrite current techmap.v rules (modular and clean) - Improve Xilinx FGPA synthesis (RAMB, CARRY4, SLR, etc.) - Implement SAT-based formal equivialence checker diff --git a/manual/CHAPTER_Techmap.tex b/manual/CHAPTER_Techmap.tex index be74c356..26632d0b 100644 --- a/manual/CHAPTER_Techmap.tex +++ b/manual/CHAPTER_Techmap.tex @@ -27,7 +27,7 @@ cells with the provided implementation. When no map file is provided, {\tt techmap} uses a built-in map file that maps the Yosys RTL cell types to the internal gate library used by Yosys. -The curious reader may find this map file as {\tt techlibs/common/stdcells.v} in +The curious reader may find this map file as {\tt techlibs/common/techmap.v} in the Yosys source tree. Additional features have been added to {\tt techmap} to allow for conditional diff --git a/passes/techmap/.gitignore b/passes/techmap/.gitignore index ca9d3942..e6dcc6bc 100644 --- a/passes/techmap/.gitignore +++ b/passes/techmap/.gitignore @@ -1 +1 @@ -stdcells.inc +techmap.inc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index e54c018a..b49259a8 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -10,16 +10,16 @@ OBJS += passes/techmap/hilomap.o OBJS += passes/techmap/extract.o endif -GENFILES += passes/techmap/stdcells.inc +GENFILES += passes/techmap/techmap.inc -passes/techmap/stdcells.inc: techlibs/common/stdcells.v +passes/techmap/techmap.inc: techlibs/common/techmap.v $(P) echo "// autogenerated from $<" > $@.new $(Q) echo "static char stdcells_code[] = {" >> $@.new $(Q) od -v -td1 -An $< | $(SED) -e 's/[0-9][0-9]*/&,/g' >> $@.new $(Q) echo "0};" >> $@.new $(Q) mv $@.new $@ -passes/techmap/techmap.o: passes/techmap/stdcells.inc +passes/techmap/techmap.o: passes/techmap/techmap.inc TARGETS += yosys-filterlib GENFILES += passes/techmap/filterlib.o diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 50936af0..2aa59e61 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -26,7 +26,7 @@ #include #include -#include "passes/techmap/stdcells.inc" +#include "passes/techmap/techmap.inc" // see simplemap.cc extern void simplemap_get_mappers(std::map &mappers); @@ -790,7 +790,7 @@ struct TechmapPass : public Pass { RTLIL::Design *map = new RTLIL::Design; if (map_files.empty()) { FILE *f = fmemopen(stdcells_code, strlen(stdcells_code), "rt"); - Frontend::frontend_call(map, f, "", verilog_frontend); + Frontend::frontend_call(map, f, "", verilog_frontend); fclose(f); } else for (auto &fn : map_files) diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index a76d1a07..2be27b92 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -5,7 +5,7 @@ techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib. $(P) cat techlibs/common/simlib.v techlibs/common/simcells.v | $(SED) -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new $(Q) mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v -EXTRA_TARGETS += share/simlib.v share/simcells.v share/blackbox.v share/pmux2mux.v +EXTRA_TARGETS += share/simlib.v share/simcells.v share/techmap.v share/blackbox.v share/pmux2mux.v share/simlib.v: techlibs/common/simlib.v $(P) mkdir -p share @@ -15,6 +15,10 @@ share/simcells.v: techlibs/common/simcells.v $(P) mkdir -p share $(Q) cp techlibs/common/simcells.v share/simcells.v +share/techmap.v: techlibs/common/techmap.v + $(P) mkdir -p share + $(Q) cp techlibs/common/techmap.v share/techmap.v + share/blackbox.v: techlibs/common/blackbox.v $(P) mkdir -p share $(Q) cp techlibs/common/blackbox.v share/blackbox.v diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 5ecec789..d492c2f1 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -21,7 +21,7 @@ * * This verilog library contains simple simulation models for the internal * logic cells ($_INV_ , $_AND_ , ...) that are generated by the default technology - * mapper (see "stdcells.v" in this directory) and expected by the "abc" pass. + * mapper (see "techmap.v" in this directory) and expected by the "abc" pass. * */ diff --git a/techlibs/common/stdcells.v b/techlibs/common/techmap.v similarity index 100% rename from techlibs/common/stdcells.v rename to techlibs/common/techmap.v From 1cb25c05b37b0172dbc50e140fe20f25d973dd8a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 13:19:47 +0200 Subject: [PATCH 504/750] Moved some stuff to kernel/yosys.{h,cc}, using Yosys:: namespace --- backends/ilang/ilang_backend.cc | 6 +- backends/ilang/ilang_backend.h | 6 +- frontends/ast/ast.cc | 6 +- frontends/ast/ast.h | 4 + frontends/ast/genrtlil.cc | 24 +- frontends/ast/simplify.cc | 60 +-- frontends/ilang/ilang_frontend.cc | 4 + frontends/ilang/ilang_frontend.h | 6 +- frontends/ilang/parser.y | 9 +- frontends/liberty/liberty.cc | 3 + frontends/verific/verific.cc | 8 +- frontends/verilog/const2ast.cc | 4 + frontends/verilog/lexer.l | 3 + frontends/verilog/parser.y | 7 +- frontends/verilog/preproc.cc | 4 + frontends/verilog/verilog_frontend.cc | 3 + frontends/verilog/verilog_frontend.h | 6 +- frontends/vhdl2verilog/vhdl2verilog.cc | 4 + kernel/calc.cc | 7 +- kernel/driver.cc | 546 +----------------------- kernel/log.cc | 6 +- kernel/log.h | 6 +- kernel/register.cc | 34 +- kernel/register.h | 14 +- kernel/rtlil.cc | 8 +- kernel/rtlil.h | 18 +- kernel/sigtools.h | 8 +- kernel/yosys.cc | 565 +++++++++++++++++++++++++ kernel/yosys.h | 38 +- libs/subcircuit/subcircuit.cc | 4 +- passes/abc/abc.cc | 4 +- passes/cmds/design.cc | 4 + passes/fsm/fsm_extract.cc | 4 +- passes/memory/memory_collect.cc | 2 +- passes/memory/memory_dff.cc | 2 +- passes/memory/memory_map.cc | 2 +- passes/memory/memory_unpack.cc | 2 +- passes/proc/proc_dff.cc | 6 +- passes/proc/proc_mux.cc | 4 +- passes/techmap/extract.cc | 2 +- passes/techmap/techmap.cc | 2 +- 41 files changed, 790 insertions(+), 665 deletions(-) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index c055c133..b7088f59 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -336,7 +336,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { - int init_autoidx = RTLIL::autoidx; + int init_autoidx = autoidx; if (!flag_m) { int count_selected_mods = 0; @@ -353,7 +353,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ if (!only_selected || flag_m) { if (only_selected) fprintf(f, "\n"); - fprintf(f, "autoidx %d\n", RTLIL::autoidx); + fprintf(f, "autoidx %d\n", autoidx); } for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { @@ -364,7 +364,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ } } - log_assert(init_autoidx == RTLIL::autoidx); + log_assert(init_autoidx == autoidx); } struct IlangBackend : public Backend { diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h index fecbcc1f..b0fec488 100644 --- a/backends/ilang/ilang_backend.h +++ b/backends/ilang/ilang_backend.h @@ -25,9 +25,11 @@ #ifndef ILANG_BACKEND_H #define ILANG_BACKEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include +YOSYS_NAMESPACE_BEGIN + namespace ILANG_BACKEND { void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint = true); @@ -44,4 +46,6 @@ namespace ILANG_BACKEND { void dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); } +YOSYS_NAMESPACE_END + #endif diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5b3214f5..d548a679 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 6c15c03a..83798edf 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 b7f33635..0cc4f4c4 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 5665cd43..c51692f1 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 572a3572..2d4b99c5 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 5e768c3b..317ec0d5 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 38d3054b..ab763b2b 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 d5f172f0..da16ab33 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 80170394..6e692c5a 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 00deeb0b..fdb9bb02 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 ce7b9927..c62e761e 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 2cfa8ca7..8efd4d7c 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 cbc594e8..4466e1cb 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 6d01a153..dac5b3d0 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 63dc85ac..f0545700 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + struct Vhdl2verilogPass : public Pass { Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } virtual void help() @@ -190,3 +192,5 @@ struct Vhdl2verilogPass : public Pass { } } Vhdl2verilogPass; +YOSYS_NAMESPACE_END + diff --git a/kernel/calc.cc b/kernel/calc.cc index b3ff3cf2..29717aad 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -21,10 +21,11 @@ // Schneier, Bruce (1996). Applied Cryptography: Protocols, Algorithms, and Source Code in C, // Second Edition (2nd ed.). Wiley. ISBN 978-0-471-11709-4, page 244 -#include "kernel/log.h" -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "libs/bigint/BigIntegerLibrary.hh" +YOSYS_NAMESPACE_BEGIN + static void extend(RTLIL::Const &arg, int width, bool is_signed) { RTLIL::State padding = RTLIL::State::S0; @@ -592,3 +593,5 @@ RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, boo return RTLIL::const_sub(zero, arg1_ext, false, signed1, result_len); } +YOSYS_NAMESPACE_END + diff --git a/kernel/driver.cc b/kernel/driver.cc index d9ef2223..01ade7d4 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -17,9 +17,12 @@ * */ -#include +#include "kernel/yosys.h" + #include #include + +#include #include #include #include @@ -27,523 +30,7 @@ #include #include -#include -#include - -#include "kernel/yosys.h" - -bool fgetline(FILE *f, std::string &buffer) -{ - buffer = ""; - char block[4096]; - while (1) { - if (fgets(block, 4096, f) == NULL) - return false; - buffer += block; - if (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) { - while (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) - buffer.resize(buffer.size()-1); - return true; - } - } -} - -static void handle_label(std::string &command, bool &from_to_active, const std::string &run_from, const std::string &run_to) -{ - int pos = 0; - std::string label; - - while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) - pos++; - - while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') - label += command[pos++]; - - if (label.back() == ':' && SIZE(label) > 1) - { - label = label.substr(0, SIZE(label)-1); - command = command.substr(pos); - - if (label == run_from) - from_to_active = true; - else if (label == run_to || (run_from == run_to && !run_from.empty())) - from_to_active = false; - } -} - -static void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) -{ - if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") - command = "verilog"; - else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") - command = "verilog -sv"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") - command = "ilang"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") - command = "script"; - else if (filename == "-") - command = "script"; - else - log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str()); - } - - if (command == "script") - { - std::string run_from, run_to; - bool from_to_active = true; - - if (from_to_label != NULL) { - size_t pos = from_to_label->find(':'); - if (pos == std::string::npos) { - run_from = *from_to_label; - run_to = *from_to_label; - } else { - run_from = from_to_label->substr(0, pos); - run_to = from_to_label->substr(pos+1); - } - from_to_active = run_from.empty(); - } - - log("\n-- Executing script file `%s' --\n", filename.c_str()); - - FILE *f = stdin; - - if (filename != "-") - f = fopen(filename.c_str(), "r"); - - if (f == NULL) - log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); - - FILE *backup_script_file = Frontend::current_script_file; - Frontend::current_script_file = f; - - try { - std::string command; - while (fgetline(f, command)) { - while (!command.empty() && command[command.size()-1] == '\\') { - std::string next_line; - if (!fgetline(f, next_line)) - break; - command.resize(command.size()-1); - command += next_line; - } - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); - } - - if (!command.empty()) { - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); - } - } - catch (log_cmd_error_expection) { - Frontend::current_script_file = backup_script_file; - throw log_cmd_error_expection(); - } - - Frontend::current_script_file = backup_script_file; - - if (filename != "-") - fclose(f); - - if (backend_command != NULL && *backend_command == "auto") - *backend_command = ""; - - return; - } - - if (filename == "-") { - log("\n-- Parsing stdin using frontend `%s' --\n", command.c_str()); - } else { - log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str()); - } - - Frontend::frontend_call(design, NULL, filename, command); -} - -static void run_pass(std::string command, RTLIL::Design *design) -{ - log("\n-- Running pass `%s' --\n", command.c_str()); - - Pass::call(design, command); -} - -static void run_backend(std::string filename, std::string command, RTLIL::Design *design) -{ - if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") - command = "verilog"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") - command = "ilang"; - else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") - command = "blif"; - else if (filename == "-") - command = "ilang"; - else if (filename.empty()) - return; - else - log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename.c_str()); - } - - if (filename.empty()) - filename = "-"; - - if (filename == "-") { - log("\n-- Writing to stdout using backend `%s' --\n", command.c_str()); - } else { - log("\n-- Writing to `%s' using backend `%s' --\n", filename.c_str(), command.c_str()); - } - - Backend::backend_call(design, NULL, filename, command); -} - -static char *readline_cmd_generator(const char *text, int state) -{ - static std::map::iterator it; - static int len; - - if (!state) { - it = REGISTER_INTERN::pass_register.begin(); - len = strlen(text); - } - - for (; it != REGISTER_INTERN::pass_register.end(); it++) { - if (it->first.substr(0, len) == text) - return strdup((it++)->first.c_str()); - } - return NULL; -} - -static char *readline_obj_generator(const char *text, int state) -{ - static std::vector obj_names; - static size_t idx; - - if (!state) - { - idx = 0; - obj_names.clear(); - - RTLIL::Design *design = yosys_get_design(); - int len = strlen(text); - - if (design->selected_active_module.empty()) - { - for (auto &it : design->modules_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - } - else - if (design->modules_.count(design->selected_active_module) > 0) - { - RTLIL::Module *module = design->modules_.at(design->selected_active_module); - - for (auto &it : module->wires_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->memories) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->cells_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->processes) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - } - - std::sort(obj_names.begin(), obj_names.end()); - } - - if (idx < obj_names.size()) - return strdup(obj_names[idx++]); - - idx = 0; - obj_names.clear(); - return NULL; -} - -static char **readline_completion(const char *text, int start, int) -{ - if (start == 0) - return rl_completion_matches(text, readline_cmd_generator); - if (strncmp(rl_line_buffer, "read_", 5) && strncmp(rl_line_buffer, "write_", 6)) - return rl_completion_matches(text, readline_obj_generator); - return NULL; -} - -const char *create_prompt(RTLIL::Design *design, int recursion_counter) -{ - static char buffer[100]; - std::string str = "\n"; - if (recursion_counter > 1) - str += stringf("(%d) ", recursion_counter); - str += "yosys"; - if (!design->selected_active_module.empty()) - str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); - if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { - if (design->selected_active_module.empty()) - str += "*"; - else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || - design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) - str += "*"; - } - snprintf(buffer, 100, "%s> ", str.c_str()); - return buffer; -} - -static void shell(RTLIL::Design *design) -{ - static int recursion_counter = 0; - - recursion_counter++; - log_cmd_error_throw = true; - - rl_readline_name = "yosys"; - rl_attempted_completion_function = readline_completion; - rl_basic_word_break_characters = " \t\n"; - - char *command = NULL; - while ((command = readline(create_prompt(design, recursion_counter))) != NULL) - { - if (command[strspn(command, " \t\r\n")] == 0) - continue; - add_history(command); - - char *p = command + strspn(command, " \t\r\n"); - if (!strncmp(p, "exit", 4)) { - p += 4; - p += strspn(p, " \t\r\n"); - if (*p == 0) - break; - } - - try { - log_assert(design->selection_stack.size() == 1); - Pass::call(design, command); - } catch (log_cmd_error_expection) { - while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); - log_reset_stack(); - } - } - if (command == NULL) - printf("exit\n"); - - recursion_counter--; - log_cmd_error_throw = false; -} - -struct ShellPass : public Pass { - ShellPass() : Pass("shell", "enter interactive command mode") { } - virtual void help() { - log("\n"); - log(" shell\n"); - log("\n"); - log("This command enters the interactive command mode. This can be useful\n"); - log("in a script to interrupt the script at a certain point and allow for\n"); - log("interactive inspection or manual synthesis of the design at this point.\n"); - log("\n"); - log("The command prompt of the interactive shell indicates the current\n"); - log("selection (see 'help select'):\n"); - log("\n"); - log(" yosys>\n"); - log(" the entire design is selected\n"); - log("\n"); - log(" yosys*>\n"); - log(" only part of the design is selected\n"); - log("\n"); - log(" yosys [modname]>\n"); - log(" the entire module 'modname' is selected using 'select -module modname'\n"); - log("\n"); - log(" yosys [modname]*>\n"); - log(" only part of current module 'modname' is selected\n"); - log("\n"); - log("When in interactive shell, some errors (e.g. invalid command arguments)\n"); - log("do not terminate yosys but return to the command prompt.\n"); - log("\n"); - log("This command is the default action if nothing else has been specified\n"); - log("on the command line.\n"); - log("\n"); - log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - extra_args(args, 1, design, false); - shell(design); - } -} ShellPass; - -struct HistoryPass : public Pass { - HistoryPass() : Pass("history", "show last interactive commands") { } - virtual void help() { - log("\n"); - log(" history\n"); - log("\n"); - log("This command prints all commands in the shell history buffer. This are\n"); - log("all commands executed in an interactive session, but not the commands\n"); - log("from executed scripts.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - extra_args(args, 1, design, false); - for(HIST_ENTRY **list = history_list(); *list != NULL; list++) - log("%s\n", (*list)->line); - } -} HistoryPass; - -struct ScriptPass : public Pass { - ScriptPass() : Pass("script", "execute commands from script file") { } - virtual void help() { - log("\n"); - log(" script [:]\n"); - log("\n"); - log("This command executes the yosys commands in the specified file.\n"); - log("\n"); - log("The 2nd argument can be used to only execute the section of the\n"); - log("file between the specified labels. An empty from label is synonymous\n"); - log("for the beginning of the file and an empty to label is synonymous\n"); - log("for the end of the file.\n"); - log("\n"); - log("If only one label is specified (without ':') then only the block\n"); - log("marked with that label (until the next label) is executed.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - if (args.size() < 2) - log_cmd_error("Missing script file.\n"); - else if (args.size() == 2) - run_frontend(args[1], "script", design, NULL, NULL); - else if (args.size() == 3) - run_frontend(args[1], "script", design, NULL, &args[2]); - else - extra_args(args, 2, design, false); - } -} ScriptPass; - -#ifdef YOSYS_ENABLE_TCL -static Tcl_Interp *yosys_tcl_interp = NULL; - -static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[]) -{ - std::vector args; - for (int i = 1; i < argc; i++) - args.push_back(argv[i]); - - if (args.size() >= 1 && args[0] == "-import") { - for (auto &it : REGISTER_INTERN::pass_register) { - std::string tcl_command_name = it.first; - if (tcl_command_name == "proc") - tcl_command_name = "procs"; - Tcl_CmdInfo info; - if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) { - log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str()); - } else { - std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name.c_str(), it.first.c_str()); - Tcl_Eval(interp, tcl_script.c_str()); - } - } - return TCL_OK; - } - - if (args.size() == 1) { - Pass::call(yosys_get_design(), args[0]); - return TCL_OK; - } - - Pass::call(yosys_get_design(), args); - return TCL_OK; -} - -extern Tcl_Interp *yosys_get_tcl_interp() -{ - if (yosys_tcl_interp == NULL) { - yosys_tcl_interp = Tcl_CreateInterp(); - Tcl_CreateCommand(yosys_tcl_interp, "yosys", tcl_yosys_cmd, NULL, NULL); - } - return yosys_tcl_interp; -} - -struct TclPass : public Pass { - TclPass() : Pass("tcl", "execute a TCL script file") { } - virtual void help() { - log("\n"); - log(" tcl \n"); - log("\n"); - log("This command executes the tcl commands in the specified file.\n"); - log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); - log("\n"); - log("The tcl command 'yosys -import' can be used to import all yosys\n"); - log("commands directly as tcl commands to the tcl shell. The yosys\n"); - log("command 'proc' is wrapped using the tcl command 'procs' in order\n"); - log("to avoid a name collision with the tcl builting command 'proc'.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - if (args.size() < 2) - log_cmd_error("Missing script file.\n"); - if (args.size() > 2) - extra_args(args, 1, design, false); - if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK) - log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); - } -} TclPass; -#endif - -static RTLIL::Design *yosys_design = NULL; - -extern RTLIL::Design *yosys_get_design() -{ - return yosys_design; -} - -#if defined(__linux__) -std::string proc_self_dirname () -{ - char path [PATH_MAX]; - ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); - if (buflen < 0) { - log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); - log_abort(); - } - while (buflen > 0 && path[buflen-1] != '/') - buflen--; - return std::string(path, buflen); -} -#elif defined(__APPLE__) -#include -std::string proc_self_dirname () -{ - char * path = NULL; - uint32_t buflen = 0; - while (_NSGetExecutablePath(path, &buflen) != 0) - path = (char *) realloc((void *) path, buflen); - while (buflen > 0 && path[buflen-1] != '/') - buflen--; - return std::string(path, buflen); -} -#else - #error Dont know how to determine process executable base path! -#endif - -std::string proc_share_dirname () -{ - std::string proc_self_path = proc_self_dirname(); - std::string proc_share_path = proc_self_path + "share/"; - if (access(proc_share_path.c_str(), X_OK) == 0) - return proc_share_path; - proc_share_path = proc_self_path + "../share/yosys/"; - if (access(proc_share_path.c_str(), X_OK) == 0) - return proc_share_path; - log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); - log_abort(); -} +USING_YOSYS_NAMESPACE int main(int argc, char **argv) { @@ -739,11 +226,7 @@ int main(int argc, char **argv) log("\n"); } - Pass::init_register(); - - yosys_design = new RTLIL::Design; - yosys_design->selection_stack.push_back(RTLIL::Selection()); - log_push(); + yosys_setup(); if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) { if (!got_output_filename) @@ -804,7 +287,6 @@ int main(int argc, char **argv) log("\nEnd of script.\n"); if (call_abort) abort(); - log_pop(); if (!history_file.empty()) { if (history_offset > 0) { @@ -819,25 +301,11 @@ int main(int argc, char **argv) if (hist_list != NULL) free(hist_list); - for (auto f : log_files) - if (f != stderr) - fclose(f); - log_errfile = NULL; - log_files.clear(); - - Pass::done_register(); + yosys_shutdown(); for (auto mod : loaded_modules) dlclose(mod); -#ifdef YOSYS_ENABLE_TCL - if (yosys_tcl_interp != NULL) { - Tcl_DeleteInterp(yosys_tcl_interp); - Tcl_Finalize(); - yosys_tcl_interp = NULL; - } -#endif - return 0; } diff --git a/kernel/log.cc b/kernel/log.cc index 5fe0d086..64dd7a92 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; @@ -233,7 +235,7 @@ std::map> get_coverage_data() { std::map> coverage_data; - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { std::string key = stringf("passes.%s", it.first.c_str()); coverage_data[key].first = stringf("%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); coverage_data[key].second += it.second->call_counter; @@ -260,3 +262,5 @@ std::map> get_coverage_data() return coverage_data; } +YOSYS_NAMESPACE_END + diff --git a/kernel/log.h b/kernel/log.h index a491d067..0109faf6 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + #define S__LINE__sub2(x) #x #define S__LINE__sub1(x) S__LINE__sub2(x) #define S__LINE__ S__LINE__sub1(__LINE__) @@ -40,8 +42,6 @@ extern bool log_time; extern bool log_cmd_error_throw; extern int log_verbose_level; -std::string stringf(const char *fmt, ...); - void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); void logv_error(const char *format, va_list ap) __attribute__ ((noreturn)); @@ -246,4 +246,6 @@ void log_dump_args_worker(const char *p, T first, Args ... args) log("\n"); \ } while (0) +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/register.cc b/kernel/register.cc index c7bd2cce..7469b3e8 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -17,26 +17,22 @@ * */ -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include #include #include #include -using namespace REGISTER_INTERN; +YOSYS_NAMESPACE_BEGIN + #define MAX_REG_COUNT 1000 -namespace REGISTER_INTERN -{ - bool echo_mode = false; - Pass *first_queued_pass; +bool echo_mode = false; +Pass *first_queued_pass; - std::map frontend_register; - std::map pass_register; - std::map backend_register; -} +std::map frontend_register; +std::map pass_register; +std::map backend_register; std::vector Frontend::next_args; @@ -552,7 +548,7 @@ struct HelpPass : public Pass { { if (args.size() == 1) { log("\n"); - for (auto &it : REGISTER_INTERN::pass_register) + for (auto &it : pass_register) log(" %-20s %s\n", it.first.c_str(), it.second->short_help.c_str()); log("\n"); log("Type 'help ' for more information on a command.\n"); @@ -562,7 +558,7 @@ struct HelpPass : public Pass { if (args.size() == 2) { if (args[1] == "-all") { - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { log("\n\n"); log("%s -- %s\n", it.first.c_str(), it.second->short_help.c_str()); for (size_t i = 0; i < it.first.size() + it.second->short_help.size() + 6; i++) @@ -575,7 +571,7 @@ struct HelpPass : public Pass { else if (args[1] == "-write-tex-command-reference-manual") { FILE *f = fopen("command-reference-manual.tex", "wt"); fprintf(f, "%% Generated using the yosys 'help -write-tex-command-reference-manual' command.\n\n"); - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { size_t memsize; char *memptr; FILE *memf = open_memstream(&memptr, &memsize); @@ -591,7 +587,7 @@ struct HelpPass : public Pass { // this option is undocumented as it is for internal use only else if (args[1] == "-write-web-command-reference-manual") { FILE *f = fopen("templates/cmd_index.in", "wt"); - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { size_t memsize; char *memptr; FILE *memf = open_memstream(&memptr, &memsize); @@ -604,10 +600,10 @@ struct HelpPass : public Pass { } fclose(f); } - else if (REGISTER_INTERN::pass_register.count(args[1]) == 0) + else if (pass_register.count(args[1]) == 0) log("No such command: %s\n", args[1].c_str()); else - REGISTER_INTERN::pass_register.at(args[1])->help(); + pass_register.at(args[1])->help(); return; } @@ -648,3 +644,5 @@ struct EchoPass : public Pass { } } EchoPass; +YOSYS_NAMESPACE_END + diff --git a/kernel/register.h b/kernel/register.h index 41780bfb..17942ca9 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -20,12 +20,14 @@ #ifndef REGISTER_H #define REGISTER_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include #include #include #include +YOSYS_NAMESPACE_BEGIN + struct Pass { std::string pass_name, short_help; @@ -94,10 +96,10 @@ struct Backend : Pass // implemented in passes/cmds/select.cc extern void handle_extra_select_args(Pass *pass, std::vector args, size_t argidx, size_t args_size, RTLIL::Design *design); -namespace REGISTER_INTERN { - extern std::map pass_register; - extern std::map frontend_register; - extern std::map backend_register; -} +extern std::map pass_register; +extern std::map frontend_register; +extern std::map backend_register; + +YOSYS_NAMESPACE_END #endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f864d88c..82fa7aec 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -17,16 +17,14 @@ * */ -#include "kernel/compatibility.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include "frontends/verilog/verilog_frontend.h" #include "backends/ilang/ilang_backend.h" #include #include -int RTLIL::autoidx = 1; +YOSYS_NAMESPACE_BEGIN RTLIL::Const::Const() { @@ -2736,3 +2734,5 @@ RTLIL::Process *RTLIL::Process::clone() const return new_proc; } +YOSYS_NAMESPACE_END + diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7bd75bd1..4d8581c7 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -22,6 +22,8 @@ #ifndef RTLIL_H #define RTLIL_H +YOSYS_NAMESPACE_BEGIN + namespace RTLIL { enum State : unsigned char { @@ -50,8 +52,6 @@ namespace RTLIL CONST_FLAG_REAL = 4 // unused -- to be used for parameters }; - extern int autoidx; - struct Const; struct Selection; struct Design; @@ -123,18 +123,6 @@ namespace RTLIL return str.c_str(); } - static IdString new_id(std::string file, int line, std::string func) __attribute__((unused)); - static IdString new_id(std::string file, int line, std::string func) { - std::string str = "$auto$"; - size_t pos = file.find_last_of('/'); - str += pos != std::string::npos ? file.substr(pos+1) : file; - str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++); - return str; - } - -#define NEW_ID \ - RTLIL::new_id(__FILE__, __LINE__, __FUNCTION__) - template struct sort_by_name { bool operator()(T *a, T *b) const { return a->name < b->name; @@ -969,4 +957,6 @@ void RTLIL::Process::rewrite_sigspecs(T functor) it->rewrite_sigspecs(functor); } +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 79a9fb23..b691749a 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -20,9 +20,9 @@ #ifndef SIGTOOLS_H #define SIGTOOLS_H -#include "kernel/rtlil.h" -#include "kernel/log.h" -#include +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN struct SigPool { @@ -398,4 +398,6 @@ struct SigMap } }; +YOSYS_NAMESPACE_END + #endif /* SIGTOOLS_H */ diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d2544382..34800ce8 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -19,6 +19,21 @@ #include "kernel/yosys.h" +#include +#include + +#include +#include + +YOSYS_NAMESPACE_BEGIN + +int autoidx = 1; +RTLIL::Design *yosys_design = NULL; + +#ifdef YOSYS_ENABLE_TCL +Tcl_Interp *yosys_tcl_interp = NULL; +#endif + std::string stringf(const char *fmt, ...) { std::string string; @@ -38,3 +53,553 @@ std::string stringf(const char *fmt, ...) return string; } +void yosys_setup() +{ + Pass::init_register(); + + yosys_design = new RTLIL::Design; + yosys_design->selection_stack.push_back(RTLIL::Selection()); + log_push(); +} + +void yosys_shutdown() +{ + log_pop(); + + for (auto f : log_files) + if (f != stderr) + fclose(f); + log_errfile = NULL; + log_files.clear(); + + Pass::done_register(); + +#ifdef YOSYS_ENABLE_TCL + if (yosys_tcl_interp != NULL) { + Tcl_DeleteInterp(yosys_tcl_interp); + Tcl_Finalize(); + yosys_tcl_interp = NULL; + } +#endif +} + +RTLIL::IdString new_id(std::string file, int line, std::string func) +{ + std::string str = "$auto$"; + size_t pos = file.find_last_of('/'); + str += pos != std::string::npos ? file.substr(pos+1) : file; + str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++); + return str; +} + +RTLIL::Design *yosys_get_design() +{ + return yosys_design; +} + +const char *create_prompt(RTLIL::Design *design, int recursion_counter) +{ + static char buffer[100]; + std::string str = "\n"; + if (recursion_counter > 1) + str += stringf("(%d) ", recursion_counter); + str += "yosys"; + if (!design->selected_active_module.empty()) + str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); + if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { + if (design->selected_active_module.empty()) + str += "*"; + else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || + design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) + str += "*"; + } + snprintf(buffer, 100, "%s> ", str.c_str()); + return buffer; +} + +#ifdef YOSYS_ENABLE_TCL +static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[]) +{ + std::vector args; + for (int i = 1; i < argc; i++) + args.push_back(argv[i]); + + if (args.size() >= 1 && args[0] == "-import") { + for (auto &it : pass_register) { + std::string tcl_command_name = it.first; + if (tcl_command_name == "proc") + tcl_command_name = "procs"; + Tcl_CmdInfo info; + if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) { + log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str()); + } else { + std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name.c_str(), it.first.c_str()); + Tcl_Eval(interp, tcl_script.c_str()); + } + } + return TCL_OK; + } + + if (args.size() == 1) { + Pass::call(yosys_get_design(), args[0]); + return TCL_OK; + } + + Pass::call(yosys_get_design(), args); + return TCL_OK; +} + +extern Tcl_Interp *yosys_get_tcl_interp() +{ + if (yosys_tcl_interp == NULL) { + yosys_tcl_interp = Tcl_CreateInterp(); + Tcl_CreateCommand(yosys_tcl_interp, "yosys", tcl_yosys_cmd, NULL, NULL); + } + return yosys_tcl_interp; +} + +struct TclPass : public Pass { + TclPass() : Pass("tcl", "execute a TCL script file") { } + virtual void help() { + log("\n"); + log(" tcl \n"); + log("\n"); + log("This command executes the tcl commands in the specified file.\n"); + log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); + log("\n"); + log("The tcl command 'yosys -import' can be used to import all yosys\n"); + log("commands directly as tcl commands to the tcl shell. The yosys\n"); + log("command 'proc' is wrapped using the tcl command 'procs' in order\n"); + log("to avoid a name collision with the tcl builting command 'proc'.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + if (args.size() > 2) + extra_args(args, 1, design, false); + if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK) + log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); + } +} TclPass; +#endif + +#if defined(__linux__) +std::string proc_self_dirname () +{ + char path [PATH_MAX]; + ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); + if (buflen < 0) { + log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); + log_abort(); + } + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#elif defined(__APPLE__) +#include +std::string proc_self_dirname () +{ + char * path = NULL; + uint32_t buflen = 0; + while (_NSGetExecutablePath(path, &buflen) != 0) + path = (char *) realloc((void *) path, buflen); + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#else + #error Dont know how to determine process executable base path! +#endif + +std::string proc_share_dirname () +{ + std::string proc_self_path = proc_self_dirname(); + std::string proc_share_path = proc_self_path + "share/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + proc_share_path = proc_self_path + "../share/yosys/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); + log_abort(); +} + +bool fgetline(FILE *f, std::string &buffer) +{ + buffer = ""; + char block[4096]; + while (1) { + if (fgets(block, 4096, f) == NULL) + return false; + buffer += block; + if (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) { + while (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) + buffer.resize(buffer.size()-1); + return true; + } + } +} + +static void handle_label(std::string &command, bool &from_to_active, const std::string &run_from, const std::string &run_to) +{ + int pos = 0; + std::string label; + + while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) + pos++; + + while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') + label += command[pos++]; + + if (label.back() == ':' && SIZE(label) > 1) + { + label = label.substr(0, SIZE(label)-1); + command = command.substr(pos); + + if (label == run_from) + from_to_active = true; + else if (label == run_to || (run_from == run_to && !run_from.empty())) + from_to_active = false; + } +} + +void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) +{ + if (command == "auto") { + if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + command = "verilog"; + else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") + command = "verilog -sv"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + command = "ilang"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") + command = "script"; + else if (filename == "-") + command = "script"; + else + log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str()); + } + + if (command == "script") + { + std::string run_from, run_to; + bool from_to_active = true; + + if (from_to_label != NULL) { + size_t pos = from_to_label->find(':'); + if (pos == std::string::npos) { + run_from = *from_to_label; + run_to = *from_to_label; + } else { + run_from = from_to_label->substr(0, pos); + run_to = from_to_label->substr(pos+1); + } + from_to_active = run_from.empty(); + } + + log("\n-- Executing script file `%s' --\n", filename.c_str()); + + FILE *f = stdin; + + if (filename != "-") + f = fopen(filename.c_str(), "r"); + + if (f == NULL) + log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); + + FILE *backup_script_file = Frontend::current_script_file; + Frontend::current_script_file = f; + + try { + std::string command; + while (fgetline(f, command)) { + while (!command.empty() && command[command.size()-1] == '\\') { + std::string next_line; + if (!fgetline(f, next_line)) + break; + command.resize(command.size()-1); + command += next_line; + } + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + + if (!command.empty()) { + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + } + catch (log_cmd_error_expection) { + Frontend::current_script_file = backup_script_file; + throw log_cmd_error_expection(); + } + + Frontend::current_script_file = backup_script_file; + + if (filename != "-") + fclose(f); + + if (backend_command != NULL && *backend_command == "auto") + *backend_command = ""; + + return; + } + + if (filename == "-") { + log("\n-- Parsing stdin using frontend `%s' --\n", command.c_str()); + } else { + log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str()); + } + + Frontend::frontend_call(design, NULL, filename, command); +} + +void run_pass(std::string command, RTLIL::Design *design) +{ + log("\n-- Running pass `%s' --\n", command.c_str()); + + Pass::call(design, command); +} + +void run_backend(std::string filename, std::string command, RTLIL::Design *design) +{ + if (command == "auto") { + if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + command = "verilog"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + command = "ilang"; + else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") + command = "blif"; + else if (filename == "-") + command = "ilang"; + else if (filename.empty()) + return; + else + log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename.c_str()); + } + + if (filename.empty()) + filename = "-"; + + if (filename == "-") { + log("\n-- Writing to stdout using backend `%s' --\n", command.c_str()); + } else { + log("\n-- Writing to `%s' using backend `%s' --\n", filename.c_str(), command.c_str()); + } + + Backend::backend_call(design, NULL, filename, command); +} + +static char *readline_cmd_generator(const char *text, int state) +{ + static std::map::iterator it; + static int len; + + if (!state) { + it = pass_register.begin(); + len = strlen(text); + } + + for (; it != pass_register.end(); it++) { + if (it->first.substr(0, len) == text) + return strdup((it++)->first.c_str()); + } + return NULL; +} + +static char *readline_obj_generator(const char *text, int state) +{ + static std::vector obj_names; + static size_t idx; + + if (!state) + { + idx = 0; + obj_names.clear(); + + RTLIL::Design *design = yosys_get_design(); + int len = strlen(text); + + if (design->selected_active_module.empty()) + { + for (auto &it : design->modules_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + } + else + if (design->modules_.count(design->selected_active_module) > 0) + { + RTLIL::Module *module = design->modules_.at(design->selected_active_module); + + for (auto &it : module->wires_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->memories) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->cells_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->processes) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + } + + std::sort(obj_names.begin(), obj_names.end()); + } + + if (idx < obj_names.size()) + return strdup(obj_names[idx++]); + + idx = 0; + obj_names.clear(); + return NULL; +} + +static char **readline_completion(const char *text, int start, int) +{ + if (start == 0) + return rl_completion_matches(text, readline_cmd_generator); + if (strncmp(rl_line_buffer, "read_", 5) && strncmp(rl_line_buffer, "write_", 6)) + return rl_completion_matches(text, readline_obj_generator); + return NULL; +} + +void shell(RTLIL::Design *design) +{ + static int recursion_counter = 0; + + recursion_counter++; + log_cmd_error_throw = true; + + rl_readline_name = "yosys"; + rl_attempted_completion_function = readline_completion; + rl_basic_word_break_characters = " \t\n"; + + char *command = NULL; + while ((command = readline(create_prompt(design, recursion_counter))) != NULL) + { + if (command[strspn(command, " \t\r\n")] == 0) + continue; + add_history(command); + + char *p = command + strspn(command, " \t\r\n"); + if (!strncmp(p, "exit", 4)) { + p += 4; + p += strspn(p, " \t\r\n"); + if (*p == 0) + break; + } + + try { + log_assert(design->selection_stack.size() == 1); + Pass::call(design, command); + } catch (log_cmd_error_expection) { + while (design->selection_stack.size() > 1) + design->selection_stack.pop_back(); + log_reset_stack(); + } + } + if (command == NULL) + printf("exit\n"); + + recursion_counter--; + log_cmd_error_throw = false; +} + +struct ShellPass : public Pass { + ShellPass() : Pass("shell", "enter interactive command mode") { } + virtual void help() { + log("\n"); + log(" shell\n"); + log("\n"); + log("This command enters the interactive command mode. This can be useful\n"); + log("in a script to interrupt the script at a certain point and allow for\n"); + log("interactive inspection or manual synthesis of the design at this point.\n"); + log("\n"); + log("The command prompt of the interactive shell indicates the current\n"); + log("selection (see 'help select'):\n"); + log("\n"); + log(" yosys>\n"); + log(" the entire design is selected\n"); + log("\n"); + log(" yosys*>\n"); + log(" only part of the design is selected\n"); + log("\n"); + log(" yosys [modname]>\n"); + log(" the entire module 'modname' is selected using 'select -module modname'\n"); + log("\n"); + log(" yosys [modname]*>\n"); + log(" only part of current module 'modname' is selected\n"); + log("\n"); + log("When in interactive shell, some errors (e.g. invalid command arguments)\n"); + log("do not terminate yosys but return to the command prompt.\n"); + log("\n"); + log("This command is the default action if nothing else has been specified\n"); + log("on the command line.\n"); + log("\n"); + log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + extra_args(args, 1, design, false); + shell(design); + } +} ShellPass; + +struct HistoryPass : public Pass { + HistoryPass() : Pass("history", "show last interactive commands") { } + virtual void help() { + log("\n"); + log(" history\n"); + log("\n"); + log("This command prints all commands in the shell history buffer. This are\n"); + log("all commands executed in an interactive session, but not the commands\n"); + log("from executed scripts.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + extra_args(args, 1, design, false); + for(HIST_ENTRY **list = history_list(); *list != NULL; list++) + log("%s\n", (*list)->line); + } +} HistoryPass; + +struct ScriptPass : public Pass { + ScriptPass() : Pass("script", "execute commands from script file") { } + virtual void help() { + log("\n"); + log(" script [:]\n"); + log("\n"); + log("This command executes the yosys commands in the specified file.\n"); + log("\n"); + log("The 2nd argument can be used to only execute the section of the\n"); + log("file between the specified labels. An empty from label is synonymous\n"); + log("for the beginning of the file and an empty to label is synonymous\n"); + log("for the end of the file.\n"); + log("\n"); + log("If only one label is specified (without ':') then only the block\n"); + log("marked with that label (until the next label) is executed.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + else if (args.size() == 2) + run_frontend(args[1], "script", design, NULL, NULL); + else if (args.size() == 3) + run_frontend(args[1], "script", design, NULL, &args[2]); + else + extra_args(args, 2, design, false); + } +} ScriptPass; + +YOSYS_NAMESPACE_END + diff --git a/kernel/yosys.h b/kernel/yosys.h index 67629d9b..9b36ebcc 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -29,6 +29,9 @@ // If you want to know how to register a command with Yosys, you could read // "kernel/register.h", but it would be easier to just look at a simple // example instead. A simple one would be "passes/cmds/log.cc". +// +// This header is very boring. It just defines some general things that +// belong nowhere else and includes the interesting headers. #ifndef YOSYS_H @@ -38,20 +41,24 @@ #include #include #include +#include #include #if 0 # define YOSYS_NAMESPACE_BEGIN namespace Yosys { # define YOSYS_NAMESPACE_END } +# define YOSYS_NAMESPACE_PREFIX Yosys:: +# define USING_YOSYS_NAMESPACE using namespace Yosys; #else # define YOSYS_NAMESPACE_BEGIN # define YOSYS_NAMESPACE_END +# define YOSYS_NAMESPACE_PREFIX +# define USING_YOSYS_NAMESPACE #endif YOSYS_NAMESPACE_BEGIN std::string stringf(const char *fmt, ...); - #define SIZE(__obj) int(__obj.size()) YOSYS_NAMESPACE_END @@ -63,20 +70,35 @@ YOSYS_NAMESPACE_END YOSYS_NAMESPACE_BEGIN +void yosys_setup(); +void yosys_shutdown(); + #ifdef YOSYS_ENABLE_TCL #include -extern Tcl_Interp *yosys_get_tcl_interp(); +Tcl_Interp *yosys_get_tcl_interp(); #endif +extern int autoidx; +extern RTLIL::Design *yosys_design; + +RTLIL::IdString new_id(std::string file, int line, std::string func); + +#define NEW_ID \ + YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) + +RTLIL::Design *yosys_get_design(); +std::string proc_self_dirname(); +std::string proc_share_dirname(); +const char *create_prompt(RTLIL::Design *design, int recursion_counter); + +void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label); +void run_pass(std::string command, RTLIL::Design *design); +void run_backend(std::string filename, std::string command, RTLIL::Design *design); +void shell(RTLIL::Design *design); + // from kernel/version_*.o (cc source generated from Makefile) extern const char *yosys_version_str; -// implemented in driver.cc -extern RTLIL::Design *yosys_get_design(); -extern std::string proc_self_dirname(); -extern std::string proc_share_dirname(); -extern const char *create_prompt(RTLIL::Design *design, int recursion_counter); - // from passes/cmds/design.cc extern std::map saved_designs; extern std::vector pushed_designs; diff --git a/libs/subcircuit/subcircuit.cc b/libs/subcircuit/subcircuit.cc index da263879..84f23d63 100644 --- a/libs/subcircuit/subcircuit.cc +++ b/libs/subcircuit/subcircuit.cc @@ -26,8 +26,8 @@ #include #ifdef _YOSYS_ -# include "kernel/log.h" -# define my_printf log +# include "kernel/yosys.h" +# define my_printf YOSYS_NAMESPACE_PREFIX log #else # define my_printf printf #endif diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index d2be7dcf..d204e93c 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -313,7 +313,7 @@ static void handle_loops() } std::stringstream sstr; - sstr << "$abcloop$" << (RTLIL::autoidx++); + sstr << "$abcloop$" << (autoidx++); RTLIL::Wire *wire = module->addWire(sstr.str()); bool first_line = true; @@ -400,7 +400,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str, bool keepff) { module = current_module; - map_autoidx = RTLIL::autoidx++; + map_autoidx = autoidx++; signal_map.clear(); signal_list.clear(); diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index bd1ee68f..79695c63 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -22,6 +22,8 @@ #include "kernel/rtlil.h" #include "kernel/log.h" +YOSYS_NAMESPACE_BEGIN + std::map saved_designs; std::vector pushed_designs; @@ -249,3 +251,5 @@ struct DesignPass : public Pass { } } DesignPass; +YOSYS_NAMESPACE_END + diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 6da46832..718f779b 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -270,7 +270,7 @@ static void extract_fsm(RTLIL::Wire *wire) // create fsm cell - RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), RTLIL::autoidx++), "$fsm"); + RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); fsm_cell->set("\\CLK", clk); fsm_cell->set("\\ARST", arst); fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); @@ -296,7 +296,7 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::Cell *cell = module->cells_.at(cellport.first); RTLIL::SigSpec port_sig = assign_map(cell->get(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); - RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++), unconn_sig.size()); + RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), autoidx++), unconn_sig.size()); port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); } } diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 40c68abc..aecb7bd6 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -126,7 +126,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) } std::stringstream sstr; - sstr << "$mem$" << memory->name << "$" << (RTLIL::autoidx++); + sstr << "$mem$" << memory->name << "$" << (autoidx++); RTLIL::Cell *mem = module->addCell(sstr.str(), "$mem"); mem->parameters["\\MEMID"] = RTLIL::Const(memory->name); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 32505617..6cbce781 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -113,7 +113,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) sig.sort_and_unify(); std::stringstream sstr; - sstr << "$memory_dff_disconnected$" << (RTLIL::autoidx++); + sstr << "$memory_dff_disconnected$" << (autoidx++); RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 49291656..0000bd50 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -41,7 +41,7 @@ static std::string genid(std::string name, std::string token1 = "", int i = -1, if (k >= 0) sstr << "[" << k << "]"; - sstr << token4 << "$" << (RTLIL::autoidx++); + sstr << token4 << "$" << (autoidx++); return sstr.str(); } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index cdf7db04..3f675ede 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -31,7 +31,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at("\\MEMID").decode_string()); while (module->memories.count(mem_name) != 0) - mem_name += stringf("_%d", RTLIL::autoidx++); + mem_name += stringf("_%d", autoidx++); RTLIL::Memory *mem = new RTLIL::Memory; mem->name = mem_name; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 91cafe3b..d894b442 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -122,7 +122,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S } std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; @@ -144,7 +144,7 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec bool clk_polarity, bool set_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec set, RTLIL::Process *proc) { std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.size()); RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size()); @@ -191,7 +191,7 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ bool clk_polarity, bool arst_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec *arst, RTLIL::Process *proc) { std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::Cell *cell = mod->addCell(sstr.str(), arst ? "$adff" : "$dff"); cell->attributes = proc->attributes; diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index e7661245..b18ce492 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -57,7 +57,7 @@ static void extract_core_signal(const RTLIL::CaseRule *cs, RTLIL::SigSpec &sig) static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SwitchRule *sw) { std::stringstream sstr; - sstr << "$procmux$" << (RTLIL::autoidx++); + sstr << "$procmux$" << (autoidx++); RTLIL::Wire *cmp_wire = mod->addWire(sstr.str() + "_CMP", 0); @@ -127,7 +127,7 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, log_assert(when_signal.size() == else_signal.size()); std::stringstream sstr; - sstr << "$procmux$" << (RTLIL::autoidx++); + sstr << "$procmux$" << (autoidx++); // the trivial cases if (compare.size() == 0 || when_signal == else_signal) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 19d32334..ed389f2f 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -296,7 +296,7 @@ namespace SigSet> sig2port; // create new cell - RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), RTLIL::autoidx++), needle->name); + RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), autoidx++), needle->name); // create cell ports for (auto &it : needle->wires_) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 2aa59e61..c2e5960f 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -161,7 +161,7 @@ struct TechmapWorker for (auto &it : tpl->cells_) if (it.first == "\\_TECHMAP_REPLACE_") { orig_cell_name = cell->name; - module->rename(cell, stringf("$techmap%d", RTLIL::autoidx++) + cell->name); + module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name); break; } From e6d33513a5b809facc6e3e5e75d2248bfa94f82b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 14:11:39 +0200 Subject: [PATCH 505/750] 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 +- kernel/rtlil.cc | 83 ++++++++++++++++++++++++++++++ kernel/rtlil.h | 20 +++++++ manual/PRESENTATION_Prog/Makefile | 6 +-- manual/PRESENTATION_Prog/my_cmd.cc | 35 +++++-------- passes/abc/blifparse.cc | 2 +- passes/cmds/copy.cc | 5 +- passes/cmds/design.cc | 5 +- passes/hierarchy/hierarchy.cc | 2 +- passes/hierarchy/submod.cc | 2 +- passes/sat/miter.cc | 2 +- passes/techmap/extract.cc | 2 +- 15 files changed, 142 insertions(+), 44 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d548a679..46b717ce 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 ab763b2b..67cc7da7 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 da16ab33..d3168ab8 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 6e692c5a..c7b99c7a 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)); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 82fa7aec..9f10b5d8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -243,6 +243,7 @@ void RTLIL::Design::add(RTLIL::Module *module) log_assert(modules_.count(module->name) == 0); log_assert(refcount_modules_ == 0); modules_[module->name] = module; + module->design = this; } RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) @@ -250,6 +251,7 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) log_assert(modules_.count(name) == 0); log_assert(refcount_modules_ == 0); modules_[name] = new RTLIL::Module; + modules_[name]->design = this; modules_[name]->name = name; return modules_[name]; } @@ -265,6 +267,7 @@ void RTLIL::Design::check() { #ifndef NDEBUG for (auto &it : modules_) { + log_assert(this == it.second->design); log_assert(it.first == it.second->name); log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); it.second->check(); @@ -319,6 +322,38 @@ bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const return selected_whole_module(mod->name); } +std::vector RTLIL::Design::selected_modules() const +{ + std::vector result; + result.reserve(modules_.size()); + for (auto &it : modules_) + if (selected_module(it.first)) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Design::selected_whole_modules() const +{ + std::vector result; + result.reserve(modules_.size()); + for (auto &it : modules_) + if (selected_whole_module(it.first)) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Design::selected_whole_modules_warn() const +{ + std::vector result; + result.reserve(modules_.size()); + for (auto &it : modules_) + if (selected_whole_module(it.first)) + result.push_back(it.second); + else if (selected_module(it.first)) + log("Warning: Ignoring partially selected module %s.\n", log_id(it.first)); + return result; +} + RTLIL::Module::Module() { refcount_wires_ = 0; @@ -763,6 +798,7 @@ void RTLIL::Module::check() { #ifndef NDEBUG for (auto &it : wires_) { + log_assert(this == it.second->module); log_assert(it.first == it.second->name); log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); log_assert(it.second->width >= 0); @@ -783,6 +819,7 @@ void RTLIL::Module::check() } for (auto &it : cells_) { + log_assert(this == it.second->module); log_assert(it.first == it.second->name); log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); log_assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$')); @@ -868,12 +905,57 @@ RTLIL::Module *RTLIL::Module::clone() const return new_mod; } +bool RTLIL::Module::has_memories() const +{ + return !memories.empty(); +} + +bool RTLIL::Module::has_processes() const +{ + return !processes.empty(); +} + +bool RTLIL::Module::has_memories_warn() const +{ + if (!memories.empty()) + log("Warning: Ignoring module %s because it contains memories (run 'memory' command first).\n", log_id(this)); + return !memories.empty(); +} + +bool RTLIL::Module::has_processes_warn() const +{ + if (!processes.empty()) + log("Warning: Ignoring module %s because it contains processes (run 'proc' command first).\n", log_id(this)); + return !processes.empty(); +} + +std::vector RTLIL::Module::selected_wires() const +{ + std::vector result; + result.reserve(wires_.size()); + for (auto &it : wires_) + if (design->selected(this, it.second)) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Module::selected_cells() const +{ + std::vector result; + result.reserve(wires_.size()); + for (auto &it : cells_) + if (design->selected(this, it.second)) + result.push_back(it.second); + return result; +} + void RTLIL::Module::add(RTLIL::Wire *wire) { log_assert(!wire->name.empty()); log_assert(count_id(wire->name) == 0); log_assert(refcount_wires_ == 0); wires_[wire->name] = wire; + wire->module = this; } void RTLIL::Module::add(RTLIL::Cell *cell) @@ -882,6 +964,7 @@ void RTLIL::Module::add(RTLIL::Cell *cell) log_assert(count_id(cell->name) == 0); log_assert(refcount_cells_ == 0); cells_[cell->name] = cell; + cell->module = this; } namespace { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 4d8581c7..1163dcce 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -252,6 +252,10 @@ namespace RTLIL RTLIL::ObjIterator begin() { return RTLIL::ObjIterator(list_p, refcount_p); } RTLIL::ObjIterator end() { return RTLIL::ObjIterator(); } + size_t size() const { + return list_p->size(); + } + operator std::set() const { std::set result; for (auto &it : *list_p) @@ -375,6 +379,10 @@ struct RTLIL::Design sel.select(module, member); } } + + std::vector selected_modules() const; + std::vector selected_whole_modules() const; + std::vector selected_whole_modules_warn() const; }; #define RTLIL_ATTRIBUTE_MEMBERS \ @@ -395,6 +403,7 @@ protected: void add(RTLIL::Cell *cell); public: + RTLIL::Design *design; int refcount_wires_; int refcount_cells_; @@ -424,6 +433,15 @@ public: void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; + bool has_memories() const; + bool has_processes() const; + + bool has_memories_warn() const; + bool has_processes_warn() const; + + std::vector selected_wires() const; + std::vector selected_cells() const; + RTLIL::Wire* wire(RTLIL::IdString id) { return wires_.count(id) ? wires_.at(id) : nullptr; } RTLIL::Cell* cell(RTLIL::IdString id) { return cells_.count(id) ? cells_.at(id) : nullptr; } @@ -592,6 +610,7 @@ public: Wire(RTLIL::Wire &other) = delete; void operator=(RTLIL::Wire &other) = delete; + RTLIL::Module *module; RTLIL::IdString name; int width, start_offset, port_id; bool port_input, port_output, upto; @@ -620,6 +639,7 @@ public: Cell(RTLIL::Cell &other) = delete; void operator=(RTLIL::Cell &other) = delete; + RTLIL::Module *module; RTLIL::IdString name; RTLIL::IdString type; std::map connections_; diff --git a/manual/PRESENTATION_Prog/Makefile b/manual/PRESENTATION_Prog/Makefile index 8da6bcd6..794f5c12 100644 --- a/manual/PRESENTATION_Prog/Makefile +++ b/manual/PRESENTATION_Prog/Makefile @@ -5,14 +5,14 @@ my_cmd.so: my_cmd.cc ../../yosys-config --exec --cxx --cxxflags --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs test0.log: my_cmd.so - ../../yosys -l test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v + ../../yosys -Ql test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v mv test0.log_new test0.log test1.log: my_cmd.so - ../../yosys -l test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v + ../../yosys -Ql test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v mv test1.log_new test1.log test2.log: my_cmd.so - ../../yosys -l test2.log_new -m ./my_cmd.so -p 'test2' sigmap_test.v + ../../yosys -Ql test2.log_new -m ./my_cmd.so -p 'test2' sigmap_test.v mv test2.log_new test2.log diff --git a/manual/PRESENTATION_Prog/my_cmd.cc b/manual/PRESENTATION_Prog/my_cmd.cc index 8dc72c75..381b0587 100644 --- a/manual/PRESENTATION_Prog/my_cmd.cc +++ b/manual/PRESENTATION_Prog/my_cmd.cc @@ -1,6 +1,4 @@ -#include "kernel/rtlil.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include "kernel/sigtools.h" struct MyPass : public Pass { @@ -12,9 +10,9 @@ struct MyPass : public Pass { log(" %s\n", arg.c_str()); log("Modules in current design:\n"); - for (auto &mod : design->modules_) - log(" %s (%zd wires, %zd cells)\n", RTLIL::id2cstr(mod.first), - mod.second->wires_.size(), mod.second->cells_.size()); + for (auto mod : design->modules()) + log(" %s (%zd wires, %zd cells)\n", log_id(mod), + SIZE(mod->wires()), SIZE(mod->cells())); } } MyPass; @@ -23,28 +21,24 @@ struct Test1Pass : public Pass { Test1Pass() : Pass("test1", "creating the absval module") { } virtual void execute(std::vector, RTLIL::Design *design) { - RTLIL::Module *module = new RTLIL::Module; - module->name = "\\absval"; + if (design->has("\\absval") != 0) + log_error("A module with the name absval already exists!\n"); - RTLIL::Wire *a = module->new_wire(4, "\\a"); + RTLIL::Module *module = design->addModule("\\absval"); + + RTLIL::Wire *a = module->addWire("\\a", 4); a->port_input = true; a->port_id = 1; - RTLIL::Wire *y = module->new_wire(4, "\\y"); + RTLIL::Wire *y = module->addWire("\\y", 4); y->port_output = true; y->port_id = 2; - RTLIL::Wire *a_inv = module->new_wire(4, NEW_ID); + RTLIL::Wire *a_inv = module->addWire(NEW_ID, 4); module->addNeg(NEW_ID, a, a_inv, true); - module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 1, 3), y); + module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 3), y); - log("Name of this module: %s\n", RTLIL::id2cstr(module->name)); - - if (design->modules_.count(module->name) != 0) - log_error("A module with the name %s already exists!\n", - RTLIL::id2cstr(module->name)); - - design->modules_[module->name] = module; + log("Name of this module: %s\n", log_id(module)); } } Test1Pass; @@ -58,8 +52,7 @@ struct Test2Pass : public Pass { RTLIL::Module *module = design->modules_.at("\\test"); - RTLIL::SigSpec a(module->wires_.at("\\a")), x(module->wires_.at("\\x")), - y(module->wires_.at("\\y")); + RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")), y(module->wire("\\y")); log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" SigMap sigmap(module); diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 4bcbc013..e10cb109 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -60,7 +60,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) int port_count = 0; module->name = "\\netlist"; - design->modules_[module->name] = module; + design->add(module); size_t buffer_size = 4096; char *buffer = (char*)malloc(buffer_size); diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc index fc801f61..be775820 100644 --- a/passes/cmds/copy.cc +++ b/passes/cmds/copy.cc @@ -47,8 +47,9 @@ struct CopyPass : public Pass { if (design->modules_.count(trg_name) != 0) log_cmd_error("Target module name %s already exists.\n", trg_name.c_str()); - design->modules_[trg_name] = design->modules_.at(src_name)->clone(); - design->modules_[trg_name]->name = trg_name; + RTLIL::Module *new_mod = design->module(src_name)->clone(); + new_mod->name = trg_name; + design->add(new_mod); } } CopyPass; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 79695c63..41548f62 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -198,6 +198,7 @@ struct DesignPass : public Pass { delete copy_to_design->modules_.at(trg_name); copy_to_design->modules_[trg_name] = mod->clone(); copy_to_design->modules_[trg_name]->name = trg_name; + copy_to_design->modules_[trg_name]->design = copy_to_design; } } @@ -206,7 +207,7 @@ struct DesignPass : public Pass { RTLIL::Design *design_copy = new RTLIL::Design; for (auto &it : design->modules_) - design_copy->modules_[it.first] = it.second->clone(); + design_copy->add(it.second->clone()); design_copy->selection_stack = design->selection_stack; design_copy->selection_vars = design->selection_vars; @@ -242,7 +243,7 @@ struct DesignPass : public Pass { pushed_designs.pop_back(); for (auto &it : saved_design->modules_) - design->modules_[it.first] = it.second->clone(); + design->add(it.second->clone()); design->selection_stack = saved_design->selection_stack; design->selection_vars = saved_design->selection_vars; diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index a1361c68..67b57a94 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -117,7 +117,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell RTLIL::Module *mod = new RTLIL::Module; mod->name = celltype; mod->attributes["\\blackbox"] = RTLIL::Const(1); - design->modules_[mod->name] = mod; + design->add(mod); for (auto &decl : ports) { RTLIL::Wire *wire = mod->addWire(decl.portname, portwidths.at(decl.portname)); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 84c6b916..d0c9f4b5 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -105,7 +105,7 @@ struct SubmodWorker RTLIL::Module *new_mod = new RTLIL::Module; new_mod->name = submod.full_name; - design->modules_[new_mod->name] = new_mod; + design->add(new_mod); int port_counter = 1, auto_name_counter = 1; std::set all_wire_names; diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 0f00e71a..ffd9f1b6 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -113,7 +113,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::Module *miter_module = new RTLIL::Module; miter_module->name = miter_name; - design->modules_[miter_name] = miter_module; + design->add(miter_module); RTLIL::Cell *gold_cell = miter_module->addCell("\\gold", gold_name); RTLIL::Cell *gate_cell = miter_module->addCell("\\gate", gate_name); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index ed389f2f..060a8740 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -724,7 +724,7 @@ struct ExtractPass : public Pass { RTLIL::Module *newMod = new RTLIL::Module; newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, id2cstr(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits); - map->modules_[newMod->name] = newMod; + map->add(newMod); int portCounter = 1; for (auto wire : wires) { From cd9407404a7bf3a5b8735af00c8f13ff97ac1495 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 14:34:12 +0200 Subject: [PATCH 506/750] Added RTLIL::Monitor --- kernel/rtlil.cc | 173 ++++++++++++++++++++++-------------------------- kernel/rtlil.h | 20 +++++- 2 files changed, 97 insertions(+), 96 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9f10b5d8..28de216c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -244,20 +244,32 @@ void RTLIL::Design::add(RTLIL::Module *module) log_assert(refcount_modules_ == 0); modules_[module->name] = module; module->design = this; + + for (auto mon : monitors) + mon->notify_module_add(module); } RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) { log_assert(modules_.count(name) == 0); log_assert(refcount_modules_ == 0); - modules_[name] = new RTLIL::Module; - modules_[name]->design = this; - modules_[name]->name = name; - return modules_[name]; + + RTLIL::Module *module = new RTLIL::Module; + modules_[name] = module; + module->design = this; + module->name = name; + + for (auto mon : monitors) + mon->notify_module_add(module); + + return module; } void RTLIL::Design::remove(RTLIL::Module *module) { + for (auto mon : monitors) + mon->notify_module_del(module); + log_assert(modules_.at(module->name) == module); modules_.erase(module->name); delete module; @@ -356,6 +368,7 @@ std::vector RTLIL::Design::selected_whole_modules_warn() const RTLIL::Module::Module() { + design = nullptr; refcount_wires_ = 0; refcount_cells_ = 0; } @@ -1061,12 +1074,31 @@ static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) void RTLIL::Module::connect(const RTLIL::SigSig &conn) { + for (auto mon : monitors) + mon->notify_connect(this, conn); + + if (design) + for (auto mon : design->monitors) + mon->notify_connect(this, conn); + connections_.push_back(conn); } void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs) { - connections_.push_back(RTLIL::SigSig(lhs, rhs)); + connect(RTLIL::SigSig(lhs, rhs)); +} + +void RTLIL::Module::new_connections(const std::vector &new_conn) +{ + for (auto mon : monitors) + mon->notify_new_connections(this, new_conn); + + if (design) + for (auto mon : design->monitors) + mon->notify_new_connections(this, new_conn); + + connections_ = new_conn; } const std::vector &RTLIL::Module::connections() const @@ -1131,15 +1163,12 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth #define DEF_METHOD(_func, _y_size, _type) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ + RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\A_WIDTH"] = sig_a.size(); \ cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ cell->set("\\A", sig_a); \ cell->set("\\Y", sig_y); \ - add(cell); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed) { \ @@ -1161,9 +1190,7 @@ DEF_METHOD(LogicNot, 1, "$logic_not") #define DEF_METHOD(_func, _y_size, _type) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ + RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\B_SIGNED"] = is_signed; \ cell->parameters["\\A_WIDTH"] = sig_a.size(); \ @@ -1172,7 +1199,6 @@ DEF_METHOD(LogicNot, 1, "$logic_not") cell->set("\\A", sig_a); \ cell->set("\\B", sig_b); \ cell->set("\\Y", sig_y); \ - add(cell); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed) { \ @@ -1209,9 +1235,7 @@ DEF_METHOD(LogicOr, 1, "$logic_or") #define DEF_METHOD(_func, _type, _pmux) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ + RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters["\\WIDTH"] = sig_a.size(); \ cell->parameters["\\WIDTH"] = sig_b.size(); \ if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ @@ -1219,7 +1243,6 @@ DEF_METHOD(LogicOr, 1, "$logic_or") cell->set("\\B", sig_b); \ cell->set("\\S", sig_s); \ cell->set("\\Y", sig_y); \ - add(cell); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \ @@ -1234,12 +1257,9 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) #define DEF_METHOD_2(_func, _type, _P1, _P2) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ + RTLIL::Cell *cell = addCell(name, _type); \ cell->set("\\" #_P1, sig1); \ cell->set("\\" #_P2, sig2); \ - add(cell); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1) { \ @@ -1249,13 +1269,10 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) } #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ + RTLIL::Cell *cell = addCell(name, _type); \ cell->set("\\" #_P1, sig1); \ cell->set("\\" #_P2, sig2); \ cell->set("\\" #_P3, sig3); \ - add(cell); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ @@ -1265,14 +1282,11 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) } #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3, RTLIL::SigSpec sig4) { \ - RTLIL::Cell *cell = new RTLIL::Cell; \ - cell->name = name; \ - cell->type = _type; \ + RTLIL::Cell *cell = addCell(name, _type); \ cell->set("\\" #_P1, sig1); \ cell->set("\\" #_P2, sig2); \ cell->set("\\" #_P3, sig3); \ cell->set("\\" #_P4, sig4); \ - add(cell); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ @@ -1291,9 +1305,7 @@ DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y) RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$pow"; + RTLIL::Cell *cell = addCell(name, "$pow"); cell->parameters["\\A_SIGNED"] = a_signed; cell->parameters["\\B_SIGNED"] = b_signed; cell->parameters["\\A_WIDTH"] = sig_a.size(); @@ -1302,97 +1314,76 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R cell->set("\\A", sig_a); cell->set("\\B", sig_b); cell->set("\\Y", sig_y); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$slice"; + RTLIL::Cell *cell = addCell(name, "$slice"); cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig_y.size(); cell->parameters["\\OFFSET"] = offset; cell->set("\\A", sig_a); cell->set("\\Y", sig_y); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$concat"; + RTLIL::Cell *cell = addCell(name, "$concat"); cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\B_WIDTH"] = sig_b.size(); cell->set("\\A", sig_a); cell->set("\\B", sig_b); cell->set("\\Y", sig_y); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, RTLIL::SigSpec sig_o, RTLIL::Const lut) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$lut"; + RTLIL::Cell *cell = addCell(name, "$lut"); cell->parameters["\\LUT"] = lut; cell->parameters["\\WIDTH"] = sig_i.size(); cell->set("\\I", sig_i); cell->set("\\O", sig_o); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$assert"; + RTLIL::Cell *cell = addCell(name, "$assert"); cell->set("\\A", sig_a); cell->set("\\EN", sig_en); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$sr"; + RTLIL::Cell *cell = addCell(name, "$sr"); cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); cell->set("\\SET", sig_set); cell->set("\\CLR", sig_clr); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$dff"; + RTLIL::Cell *cell = addCell(name, "$dff"); cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); cell->set("\\CLK", sig_clk); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$dffsr"; + RTLIL::Cell *cell = addCell(name, "$dffsr"); cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; @@ -1402,16 +1393,13 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl cell->set("\\CLR", sig_clr); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$adff"; + RTLIL::Cell *cell = addCell(name, "$adff"); cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\ARST_POLARITY"] = arst_polarity; cell->parameters["\\ARST_VALUE"] = arst_value; @@ -1420,30 +1408,24 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk cell->set("\\ARST", sig_arst); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$dlatch"; + RTLIL::Cell *cell = addCell(name, "$dlatch"); cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); cell->set("\\EN", sig_en); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = "$dlatchsr"; + RTLIL::Cell *cell = addCell(name, "$dlatchsr"); cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; @@ -1453,81 +1435,66 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig cell->set("\\CLR", sig_clr); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); + RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); cell->set("\\C", sig_clk); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); + RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); cell->set("\\C", sig_clk); cell->set("\\S", sig_set); cell->set("\\R", sig_clr); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool arst_value, bool clk_polarity, bool arst_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'); + RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); cell->set("\\C", sig_clk); cell->set("\\R", sig_arst); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'); + RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); cell->set("\\E", sig_en); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = name; - cell->type = stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'); + RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); cell->set("\\E", sig_en); cell->set("\\S", sig_set); cell->set("\\R", sig_clr); cell->set("\\D", sig_d); cell->set("\\Q", sig_q); - add(cell); return cell; } RTLIL::Wire::Wire() { + module = nullptr; width = 1; start_offset = 0; port_id = 0; @@ -1542,18 +1509,36 @@ RTLIL::Memory::Memory() size = 0; } -bool RTLIL::Cell::has(RTLIL::IdString portname) +bool RTLIL::Cell::has(RTLIL::IdString portname) const { return connections_.count(portname) != 0; } void RTLIL::Cell::unset(RTLIL::IdString portname) { + std::pair new_conn(portname, RTLIL::SigSpec()); + + for (auto mon : module->monitors) + mon->notify_cell_connect(this, new_conn); + + if (module->design) + for (auto mon : module->design->monitors) + mon->notify_cell_connect(this, new_conn); + connections_.erase(portname); } void RTLIL::Cell::set(RTLIL::IdString portname, RTLIL::SigSpec signal) { + std::pair new_conn(portname, signal); + + for (auto mon : module->monitors) + mon->notify_cell_connect(this, new_conn); + + if (module->design) + for (auto mon : module->design->monitors) + mon->notify_cell_connect(this, new_conn); + connections_[portname] = signal; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1163dcce..5107e5f2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -54,6 +54,7 @@ namespace RTLIL struct Const; struct Selection; + struct Monitor; struct Design; struct Module; struct Wire; @@ -328,8 +329,20 @@ struct RTLIL::Selection } }; +struct RTLIL::Monitor +{ + virtual void notify_module_add(RTLIL::Module*) { } + virtual void notify_module_del(RTLIL::Module*) { } + virtual void notify_cell_connect(RTLIL::Cell*, const std::pair&) { } + virtual void notify_connect(RTLIL::Module*, const RTLIL::SigSig&) { } + virtual void notify_new_connections(RTLIL::Module*, const std::vector&) { } + virtual void notify_blackout(RTLIL::Module*) { } +}; + struct RTLIL::Design { + std::set monitors; + int refcount_modules_; std::map modules_; @@ -404,6 +417,8 @@ protected: public: RTLIL::Design *design; + std::set monitors; + int refcount_wires_; int refcount_cells_; @@ -426,6 +441,7 @@ public: void connect(const RTLIL::SigSig &conn); void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); + void new_connections(const std::vector &new_conn); const std::vector &connections() const; void fixup_ports(); @@ -631,7 +647,7 @@ struct RTLIL::Cell protected: // use module->addCell() and module->remove() to create or destroy cells friend struct RTLIL::Module; - Cell() { }; + Cell() : module(nullptr) { }; ~Cell() { }; public: @@ -647,7 +663,7 @@ public: RTLIL_ATTRIBUTE_MEMBERS // access cell ports - bool has(RTLIL::IdString portname); + bool has(RTLIL::IdString portname) const; void unset(RTLIL::IdString portname); void set(RTLIL::IdString portname, RTLIL::SigSpec signal); const RTLIL::SigSpec &get(RTLIL::IdString portname) const; From b5a9e51b966abdfedc9309defa79b5141928e84a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 15:02:16 +0200 Subject: [PATCH 507/750] Added "trace" command --- kernel/yosys.h | 3 ++ passes/cmds/Makefile.inc | 1 + passes/cmds/tee.cc | 4 +- passes/cmds/trace.cc | 97 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 passes/cmds/trace.cc diff --git a/kernel/yosys.h b/kernel/yosys.h index 9b36ebcc..119e7e8a 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -44,6 +44,9 @@ #include #include +#define PRIVATE_NAMESPACE_BEGIN namespace { +#define PRIVATE_NAMESPACE_END } + #if 0 # define YOSYS_NAMESPACE_BEGIN namespace Yosys { # define YOSYS_NAMESPACE_END } diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 26c0ef8a..b55af995 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -19,4 +19,5 @@ OBJS += passes/cmds/tee.o OBJS += passes/cmds/write_file.o OBJS += passes/cmds/connwrappers.o OBJS += passes/cmds/cover.o +OBJS += passes/cmds/trace.o diff --git a/passes/cmds/tee.cc b/passes/cmds/tee.cc index e2f69e59..6f80ef72 100644 --- a/passes/cmds/tee.cc +++ b/passes/cmds/tee.cc @@ -73,11 +73,11 @@ struct TeePass : public Pass { try { std::vector new_args(args.begin() + argidx, args.end()); Pass::call(design, new_args); - } catch (int ex) { + } catch (log_cmd_error_expection) { for (auto cf : files_to_close) fclose(cf); log_files = backup_log_files; - throw ex; + throw log_cmd_error_expection(); } for (auto cf : files_to_close) diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc new file mode 100644 index 00000000..b4bc45c2 --- /dev/null +++ b/passes/cmds/trace.cc @@ -0,0 +1,97 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Johann Glaser + * + * 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/yosys.h" + +PRIVATE_NAMESPACE_BEGIN + +struct TraceMonitor : public RTLIL::Monitor +{ + virtual void notify_module_add(RTLIL::Module *module) override + { + log("#TRACE# Module add: %s\n", log_id(module)); + } + + virtual void notify_module_del(RTLIL::Module *module) override + { + log("#TRACE# Module delete: %s\n", log_id(module)); + } + + virtual void notify_cell_connect(RTLIL::Cell *cell, const std::pair &conn) override + { + log("#TRACE# Cell connect: %s.%s.%s = %s\n", log_id(cell->module), log_id(cell), log_id(conn.first), log_signal(conn.second)); + } + + virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override + { + log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second)); + } + + virtual void notify_new_connections(RTLIL::Module *module, const std::vector &sigsig_vec) override + { + log("#TRACE# New connections in module %s:\n", log_id(module)); + for (auto &sigsig : sigsig_vec) + log("## %s = %s\n", log_signal(sigsig.first), log_signal(sigsig.second)); + } + + virtual void notify_blackout(RTLIL::Module *module) override + { + log("#TRACE# Blackout in module %s:\n", log_id(module)); + } +}; + +struct TracePass : public Pass { + TracePass() : Pass("trace", "redirect command output to file") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" trace cmd\n"); + log("\n"); + log("Execute the specified command, logging all changes the command performs on\n"); + log("the design in real time.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + // .. parse options .. + break; + } + + TraceMonitor monitor; + design->monitors.insert(&monitor); + + try { + std::vector new_args(args.begin() + argidx, args.end()); + Pass::call(design, new_args); + } catch (log_cmd_error_expection) { + design->monitors.erase(&monitor); + throw log_cmd_error_expection(); + } + + design->monitors.erase(&monitor); + } +} TracePass; + +PRIVATE_NAMESPACE_END + From cdae8abe16847c533171fed111beea7b52202cce Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 16:38:54 +0200 Subject: [PATCH 508/750] Renamed port access function on RTLIL::Cell, added param access functions --- backends/blif/blif.cc | 20 +-- backends/btor/btor.cc | 68 +++++----- backends/spice/spice.cc | 4 +- backends/verilog/verilog_backend.cc | 80 ++++++------ frontends/ast/genrtlil.cc | 44 +++---- frontends/ilang/parser.y | 4 +- frontends/liberty/liberty.cc | 122 ++++++++--------- kernel/consteval.h | 16 +-- kernel/rtlil.cc | 184 ++++++++++++++------------ kernel/rtlil.h | 15 ++- kernel/satgen.h | 170 ++++++++++++------------ passes/abc/abc.cc | 64 ++++----- passes/abc/blifparse.cc | 10 +- passes/cmds/add.cc | 4 +- passes/cmds/connect.cc | 2 +- passes/cmds/splice.cc | 14 +- passes/fsm/fsm_detect.cc | 14 +- passes/fsm/fsm_expand.cc | 54 ++++---- passes/fsm/fsm_extract.cc | 34 ++--- passes/fsm/fsm_map.cc | 48 +++---- passes/fsm/fsm_opt.cc | 14 +- passes/fsm/fsmdata.h | 4 +- passes/hierarchy/submod.cc | 2 +- passes/memory/memory_collect.cc | 28 ++-- passes/memory/memory_dff.cc | 38 +++--- passes/memory/memory_map.cc | 70 +++++----- passes/memory/memory_share.cc | 106 +++++++-------- passes/memory/memory_unpack.cc | 14 +- passes/opt/opt_const.cc | 196 ++++++++++++++-------------- passes/opt/opt_muxtree.cc | 22 ++-- passes/opt/opt_reduce.cc | 80 ++++++------ passes/opt/opt_rmdff.cc | 36 ++--- passes/opt/opt_share.cc | 6 +- passes/proc/proc_arst.cc | 44 +++---- passes/proc/proc_dff.cc | 88 ++++++------- passes/proc/proc_mux.cc | 30 ++--- passes/sat/expose.cc | 48 +++---- passes/sat/freduce.cc | 6 +- passes/sat/miter.cc | 56 ++++---- passes/sat/share.cc | 84 ++++++------ passes/techmap/dfflibmap.cc | 2 +- passes/techmap/extract.cc | 12 +- passes/techmap/hilomap.cc | 4 +- passes/techmap/iopadmap.cc | 8 +- passes/techmap/simplemap.cc | 170 ++++++++++++------------ passes/tests/test_cell.cc | 6 +- 46 files changed, 1086 insertions(+), 1059 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index d167c3f4..b31d6ce6 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -145,56 +145,56 @@ struct BlifDumper if (!config->icells_mode && cell->type == "$_INV_") { fprintf(f, ".names %s %s\n0 1\n", - cstr(cell->get("\\A")), cstr(cell->get("\\Y"))); + cstr(cell->getPort("\\A")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_AND_") { fprintf(f, ".names %s %s %s\n11 1\n", - cstr(cell->get("\\A")), cstr(cell->get("\\B")), cstr(cell->get("\\Y"))); + cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_OR_") { fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n", - cstr(cell->get("\\A")), cstr(cell->get("\\B")), cstr(cell->get("\\Y"))); + cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_XOR_") { fprintf(f, ".names %s %s %s\n10 1\n01 1\n", - cstr(cell->get("\\A")), cstr(cell->get("\\B")), cstr(cell->get("\\Y"))); + cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_MUX_") { fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n", - cstr(cell->get("\\A")), cstr(cell->get("\\B")), - cstr(cell->get("\\S")), cstr(cell->get("\\Y"))); + cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), + cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_N_") { fprintf(f, ".latch %s %s fe %s\n", - cstr(cell->get("\\D")), cstr(cell->get("\\Q")), cstr(cell->get("\\C"))); + cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_P_") { fprintf(f, ".latch %s %s re %s\n", - cstr(cell->get("\\D")), cstr(cell->get("\\Q")), cstr(cell->get("\\C"))); + cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C"))); continue; } if (!config->icells_mode && cell->type == "$lut") { fprintf(f, ".names"); - auto &inputs = cell->get("\\I"); + auto &inputs = cell->getPort("\\I"); auto width = cell->parameters.at("\\WIDTH").as_int(); log_assert(inputs.size() == width); for (int i = 0; i < inputs.size(); i++) { fprintf(f, " %s", cstr(inputs.extract(i, 1))); } - auto &output = cell->get("\\O"); + auto &output = cell->getPort("\\O"); log_assert(output.size() == 1); fprintf(f, " %s", cstr(output)); fprintf(f, "\n"); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 43c03669..d8a54234 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -389,8 +389,8 @@ struct BtorDumper if(cell->type == "$assert") { log("writing assert cell - %s\n", cstr(cell->type)); - const RTLIL::SigSpec* expr = &cell->get(RTLIL::IdString("\\A")); - const RTLIL::SigSpec* en = &cell->get(RTLIL::IdString("\\EN")); + const RTLIL::SigSpec* expr = &cell->getPort(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* en = &cell->getPort(RTLIL::IdString("\\EN")); log_assert(expr->size() == 1); log_assert(en->size() == 1); int expr_line = dump_sigspec(expr, 1); @@ -422,7 +422,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); w = w>output_width ? w:output_width; //padding of w - int l = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), w); int cell_line = l; if(cell->type != "$pos") { @@ -446,7 +446,7 @@ struct BtorDumper int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), w); + int l = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), w); if(cell->type == "$logic_not" && w > 1) { ++line_num; @@ -483,8 +483,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -517,8 +517,8 @@ struct BtorDumper l1_width = l1_width > l2_width ? l1_width : l2_width; l2_width = l2_width > l1_width ? l2_width : l1_width; - int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), l2_width); + int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width); ++line_num; std::string op = cell_type_translation.at(cell->type); @@ -552,8 +552,8 @@ struct BtorDumper l1_width = pow(2, ceil(log(l1_width)/log(2))); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); //log_assert(l2_width <= ceil(log(l1_width)/log(2)) ); - int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), l1_width); - int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); + int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); int cell_output = ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), l1_width, l1, l2); fprintf(f, "%s\n", str.c_str()); @@ -561,7 +561,7 @@ struct BtorDumper if(l2_width > ceil(log(l1_width)/log(2))) { int extra_width = l2_width - ceil(log(l1_width)/log(2)); - l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), l2_width); + l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width); ++line_num; str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width); fprintf(f, "%s\n", str.c_str()); @@ -594,8 +594,8 @@ struct BtorDumper log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output_width == 1); - int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), output_width); + int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), output_width); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); if(l1_width >1) @@ -630,9 +630,9 @@ struct BtorDumper { log("writing mux cell\n"); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int l1 = dump_sigspec(&cell->get(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->get(RTLIL::IdString("\\B")), output_width); - int s = dump_sigspec(&cell->get(RTLIL::IdString("\\S")), 1); + int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), output_width); + int s = dump_sigspec(&cell->getPort(RTLIL::IdString("\\S")), 1); ++line_num; str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell @@ -646,10 +646,10 @@ struct BtorDumper log("writing cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); log(" - width is %d\n", output_width); - int cond = dump_sigspec(&cell->get(RTLIL::IdString("\\CLK")), 1); + int cond = dump_sigspec(&cell->getPort(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - const RTLIL::SigSpec* cell_output = &cell->get(RTLIL::IdString("\\Q")); - int value = dump_sigspec(&cell->get(RTLIL::IdString("\\D")), output_width); + const RTLIL::SigSpec* cell_output = &cell->getPort(RTLIL::IdString("\\Q")); + int value = dump_sigspec(&cell->getPort(RTLIL::IdString("\\D")), output_width); unsigned start_bit = 0; for(unsigned i=0; ichunks().size(); ++i) { @@ -667,9 +667,9 @@ struct BtorDumper } if(cell->type == "$dffsr") { - int sync_reset = dump_sigspec(&cell->get(RTLIL::IdString("\\CLR")), 1); + int sync_reset = dump_sigspec(&cell->getPort(RTLIL::IdString("\\CLR")), 1); bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); - int sync_reset_value = dump_sigspec(&cell->get(RTLIL::IdString("\\SET")), + int sync_reset_value = dump_sigspec(&cell->getPort(RTLIL::IdString("\\SET")), output_width); bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); ++line_num; @@ -687,7 +687,7 @@ struct BtorDumper int next = line_num; if(cell->type == "$adff") { - int async_reset = dump_sigspec(&cell->get(RTLIL::IdString("\\ARST")), 1); + int async_reset = dump_sigspec(&cell->getPort(RTLIL::IdString("\\ARST")), 1); bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), output_width, 0); @@ -712,7 +712,7 @@ struct BtorDumper str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->get(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->getPort(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); ++line_num; str = stringf("%d read %d %d %d", line_num, data_width, mem, address); @@ -724,13 +724,13 @@ struct BtorDumper log("writing memwr cell\n"); if (cell->parameters.at("\\CLK_ENABLE").as_bool() == false) log_error("The btor backen does not support $memwr cells without built-in registers. Run memory_dff (but with -wr_only).\n"); - int clk = dump_sigspec(&cell->get(RTLIL::IdString("\\CLK")), 1); + int clk = dump_sigspec(&cell->getPort(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); - int enable = dump_sigspec(&cell->get(RTLIL::IdString("\\EN")), 1); + int enable = dump_sigspec(&cell->getPort(RTLIL::IdString("\\EN")), 1); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); - int address = dump_sigspec(&cell->get(RTLIL::IdString("\\ADDR")), address_width); + int address = dump_sigspec(&cell->getPort(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - int data = dump_sigspec(&cell->get(RTLIL::IdString("\\DATA")), data_width); + int data = dump_sigspec(&cell->getPort(RTLIL::IdString("\\DATA")), data_width); str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); ++line_num; @@ -759,11 +759,11 @@ struct BtorDumper else if(cell->type == "$slice") { log("writing slice cell\n"); - const RTLIL::SigSpec* input = &cell->get(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input = &cell->getPort(RTLIL::IdString("\\A")); int input_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input->size() == input_width); int input_line = dump_sigspec(input, input_width); - const RTLIL::SigSpec* output = &cell->get(RTLIL::IdString("\\Y")); + const RTLIL::SigSpec* output = &cell->getPort(RTLIL::IdString("\\Y")); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); log_assert(output->size() == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); @@ -775,11 +775,11 @@ struct BtorDumper else if(cell->type == "$concat") { log("writing concat cell\n"); - const RTLIL::SigSpec* input_a = &cell->get(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* input_a = &cell->getPort(RTLIL::IdString("\\A")); int input_a_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); log_assert(input_a->size() == input_a_width); int input_a_line = dump_sigspec(input_a, input_a_width); - const RTLIL::SigSpec* input_b = &cell->get(RTLIL::IdString("\\B")); + const RTLIL::SigSpec* input_b = &cell->getPort(RTLIL::IdString("\\B")); int input_b_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); log_assert(input_b->size() == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); @@ -803,7 +803,7 @@ struct BtorDumper const RTLIL::SigSpec *output_sig = nullptr; if (cell->type == "$memrd") { - output_sig = &cell->get(RTLIL::IdString("\\DATA")); + output_sig = &cell->getPort(RTLIL::IdString("\\DATA")); } else if(cell->type == "$memwr" || cell->type == "$assert") { @@ -811,11 +811,11 @@ struct BtorDumper } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - output_sig = &cell->get(RTLIL::IdString("\\Q")); + output_sig = &cell->getPort(RTLIL::IdString("\\Q")); } else { - output_sig = &cell->get(RTLIL::IdString("\\Y")); + output_sig = &cell->getPort(RTLIL::IdString("\\Y")); } return output_sig; } diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index ab5316ec..a445e9cc 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -79,8 +79,8 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de for (RTLIL::Wire *wire : ports) { log_assert(wire != NULL); RTLIL::SigSpec sig(RTLIL::State::Sz, wire->width); - if (cell->has(wire->name)) { - sig = sigmap(cell->get(wire->name)); + if (cell->hasPort(wire->name)) { + sig = sigmap(cell->getPort(wire->name)); sig.extend(wire->width, false); } port_sigs.push_back(sig); diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 5826aea8..4bba32a6 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -305,17 +305,17 @@ void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_ { if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) { fprintf(f, "$signed("); - dump_sigspec(f, cell->get("\\" + port)); + dump_sigspec(f, cell->getPort("\\" + port)); fprintf(f, ")"); } else - dump_sigspec(f, cell->get("\\" + port)); + dump_sigspec(f, cell->getPort("\\" + port)); } std::string cellname(RTLIL::Cell *cell) { - if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->has("\\Q")) + if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->hasPort("\\Q")) { - RTLIL::SigSpec sig = cell->get("\\Q"); + RTLIL::SigSpec sig = cell->getPort("\\Q"); if (SIZE(sig) != 1 || sig.is_fully_const()) goto no_special_reg_name; @@ -350,7 +350,7 @@ no_special_reg_name: void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = %s ", op.c_str()); dump_attributes(f, "", cell->attributes, ' '); dump_cell_expr_port(f, cell, "A", true); @@ -360,7 +360,7 @@ void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::s void dump_cell_expr_binop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = "); dump_cell_expr_port(f, cell, "A", true); fprintf(f, " %s ", op.c_str()); @@ -373,7 +373,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) { if (cell->type == "$_INV_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = "); fprintf(f, "~"); dump_attributes(f, "", cell->attributes, ' '); @@ -384,7 +384,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = "); dump_cell_expr_port(f, cell, "A", false); fprintf(f, " "); @@ -403,7 +403,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$_MUX_") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = "); dump_cell_expr_port(f, cell, "S", false); fprintf(f, " ? "); @@ -418,23 +418,23 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type.substr(0, 6) == "$_DFF_") { std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->get("\\Q"), reg_name); + bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); fprintf(f, "%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->get("\\C")); + dump_sigspec(f, cell->getPort("\\C")); if (cell->type[7] != '_') { fprintf(f, " or %sedge ", cell->type[7] == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->get("\\R")); + dump_sigspec(f, cell->getPort("\\R")); } fprintf(f, ")\n"); if (cell->type[7] != '_') { fprintf(f, "%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!"); - dump_sigspec(f, cell->get("\\R")); + dump_sigspec(f, cell->getPort("\\R")); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); fprintf(f, "%s" " else\n", indent.c_str()); @@ -446,7 +446,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Q")); + dump_sigspec(f, cell->getPort("\\Q")); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -458,27 +458,27 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10]; std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->get("\\Q"), reg_name); + bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->get("\\C")); + dump_sigspec(f, cell->getPort("\\C")); fprintf(f, " or %sedge ", pol_s == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->get("\\S")); + dump_sigspec(f, cell->getPort("\\S")); fprintf(f, " or %sedge ", pol_r == 'P' ? "pos" : "neg"); - dump_sigspec(f, cell->get("\\R")); + dump_sigspec(f, cell->getPort("\\R")); fprintf(f, ")\n"); fprintf(f, "%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!"); - dump_sigspec(f, cell->get("\\R")); + dump_sigspec(f, cell->getPort("\\R")); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str()); fprintf(f, "%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!"); - dump_sigspec(f, cell->get("\\S")); + dump_sigspec(f, cell->getPort("\\S")); fprintf(f, ")\n"); fprintf(f, "%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str()); @@ -489,7 +489,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Q")); + dump_sigspec(f, cell->getPort("\\Q")); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -547,7 +547,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$pmux_safe") { int width = cell->parameters["\\WIDTH"].as_int(); - int s_width = cell->get("\\S").size(); + int s_width = cell->getPort("\\S").size(); std::string func_name = cellname(cell); fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); @@ -579,13 +579,13 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, "%s" "endfunction\n", indent.c_str()); fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = %s(", func_name.c_str()); - dump_sigspec(f, cell->get("\\A")); + dump_sigspec(f, cell->getPort("\\A")); fprintf(f, ", "); - dump_sigspec(f, cell->get("\\B")); + dump_sigspec(f, cell->getPort("\\B")); fprintf(f, ", "); - dump_sigspec(f, cell->get("\\S")); + dump_sigspec(f, cell->getPort("\\S")); fprintf(f, ");\n"); return true; } @@ -593,9 +593,9 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$slice") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = "); - dump_sigspec(f, cell->get("\\A")); + dump_sigspec(f, cell->getPort("\\A")); fprintf(f, " >> %d;\n", cell->parameters.at("\\OFFSET").as_int()); return true; } @@ -603,14 +603,14 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$bu0") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); if (cell->parameters["\\A_SIGNED"].as_bool()) { fprintf(f, " = $signed("); - dump_sigspec(f, cell->get("\\A")); + dump_sigspec(f, cell->getPort("\\A")); fprintf(f, ");\n"); } else { fprintf(f, " = { 1'b0, "); - dump_sigspec(f, cell->get("\\A")); + dump_sigspec(f, cell->getPort("\\A")); fprintf(f, " };\n"); } return true; @@ -619,11 +619,11 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$concat") { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Y")); + dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = { "); - dump_sigspec(f, cell->get("\\B")); + dump_sigspec(f, cell->getPort("\\B")); fprintf(f, " , "); - dump_sigspec(f, cell->get("\\A")); + dump_sigspec(f, cell->getPort("\\A")); fprintf(f, " };\n"); return true; } @@ -633,17 +633,17 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) RTLIL::SigSpec sig_clk, sig_arst, val_arst; bool pol_clk, pol_arst = false; - sig_clk = cell->get("\\CLK"); + sig_clk = cell->getPort("\\CLK"); pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool(); if (cell->type == "$adff") { - sig_arst = cell->get("\\ARST"); + sig_arst = cell->getPort("\\ARST"); pol_arst = cell->parameters["\\ARST_POLARITY"].as_bool(); val_arst = RTLIL::SigSpec(cell->parameters["\\ARST_VALUE"]); } std::string reg_name = cellname(cell); - bool out_is_reg_wire = is_reg_wire(cell->get("\\Q"), reg_name); + bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); if (!out_is_reg_wire) fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str()); @@ -672,7 +672,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (!out_is_reg_wire) { fprintf(f, "%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->get("\\Q")); + dump_sigspec(f, cell->getPort("\\Q")); fprintf(f, " = %s;\n", reg_name.c_str()); } @@ -920,10 +920,10 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; - if (!reg_ct.cell_known(cell->type) || !cell->has("\\Q")) + if (!reg_ct.cell_known(cell->type) || !cell->hasPort("\\Q")) continue; - RTLIL::SigSpec sig = cell->get("\\Q"); + RTLIL::SigSpec sig = cell->getPort("\\Q"); if (sig.is_chunk()) { RTLIL::SigChunk chunk = sig.as_chunk(); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 0cc4f4c4..f4f82823 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 67cc7da7..f696140e 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 d3168ab8..72e370b9 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 { diff --git a/kernel/consteval.h b/kernel/consteval.h index e5cae102..529d8962 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -87,22 +87,22 @@ struct ConstEval { RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; - log_assert(cell->has("\\Y")); - sig_y = values_map(assign_map(cell->get("\\Y"))); + log_assert(cell->hasPort("\\Y")); + sig_y = values_map(assign_map(cell->getPort("\\Y"))); if (sig_y.is_fully_const()) return true; - if (cell->has("\\S")) { - sig_s = cell->get("\\S"); + if (cell->hasPort("\\S")) { + sig_s = cell->getPort("\\S"); if (!eval(sig_s, undef, cell)) return false; } - if (cell->has("\\A")) - sig_a = cell->get("\\A"); + if (cell->hasPort("\\A")) + sig_a = cell->getPort("\\A"); - if (cell->has("\\B")) - sig_b = cell->get("\\B"); + if (cell->hasPort("\\B")) + sig_b = cell->getPort("\\B"); if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 28de216c..01225314 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -447,9 +447,9 @@ namespace { void port(const char *name, int width) { - if (!cell->has(name)) + if (!cell->hasPort(name)) error(__LINE__); - if (cell->get(name).size() != width) + if (cell->getPort(name).size() != width) error(__LINE__); expected_ports.insert(name); } @@ -478,9 +478,9 @@ namespace { for (const char *p = ports; *p; p++) { char portname[3] = { '\\', *p, 0 }; - if (!cell->has(portname)) + if (!cell->hasPort(portname)) error(__LINE__); - if (cell->get(portname).size() != 1) + if (cell->getPort(portname).size() != 1) error(__LINE__); } @@ -1001,7 +1001,7 @@ namespace { #if 0 void RTLIL::Module::remove(RTLIL::Wire *wire) { - std::set wires_; + std::setPort wires_; wires_.insert(wire); remove(wires_); } @@ -1167,8 +1167,8 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\A_WIDTH"] = sig_a.size(); \ cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->set("\\A", sig_a); \ - cell->set("\\Y", sig_y); \ + cell->setPort("\\A", sig_a); \ + cell->setPort("\\Y", sig_y); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed) { \ @@ -1196,9 +1196,9 @@ DEF_METHOD(LogicNot, 1, "$logic_not") cell->parameters["\\A_WIDTH"] = sig_a.size(); \ cell->parameters["\\B_WIDTH"] = sig_b.size(); \ cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->set("\\A", sig_a); \ - cell->set("\\B", sig_b); \ - cell->set("\\Y", sig_y); \ + cell->setPort("\\A", sig_a); \ + cell->setPort("\\B", sig_b); \ + cell->setPort("\\Y", sig_y); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed) { \ @@ -1239,10 +1239,10 @@ DEF_METHOD(LogicOr, 1, "$logic_or") cell->parameters["\\WIDTH"] = sig_a.size(); \ cell->parameters["\\WIDTH"] = sig_b.size(); \ if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ - cell->set("\\A", sig_a); \ - cell->set("\\B", sig_b); \ - cell->set("\\S", sig_s); \ - cell->set("\\Y", sig_y); \ + cell->setPort("\\A", sig_a); \ + cell->setPort("\\B", sig_b); \ + cell->setPort("\\S", sig_s); \ + cell->setPort("\\Y", sig_y); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \ @@ -1258,8 +1258,8 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) #define DEF_METHOD_2(_func, _type, _P1, _P2) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ RTLIL::Cell *cell = addCell(name, _type); \ - cell->set("\\" #_P1, sig1); \ - cell->set("\\" #_P2, sig2); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1) { \ @@ -1270,9 +1270,9 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ RTLIL::Cell *cell = addCell(name, _type); \ - cell->set("\\" #_P1, sig1); \ - cell->set("\\" #_P2, sig2); \ - cell->set("\\" #_P3, sig3); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ @@ -1283,10 +1283,10 @@ DEF_METHOD(SafePmux, "$safe_pmux", 1) #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3, RTLIL::SigSpec sig4) { \ RTLIL::Cell *cell = addCell(name, _type); \ - cell->set("\\" #_P1, sig1); \ - cell->set("\\" #_P2, sig2); \ - cell->set("\\" #_P3, sig3); \ - cell->set("\\" #_P4, sig4); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ + cell->setPort("\\" #_P4, sig4); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ @@ -1311,9 +1311,9 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\B_WIDTH"] = sig_b.size(); cell->parameters["\\Y_WIDTH"] = sig_y.size(); - cell->set("\\A", sig_a); - cell->set("\\B", sig_b); - cell->set("\\Y", sig_y); + cell->setPort("\\A", sig_a); + cell->setPort("\\B", sig_b); + cell->setPort("\\Y", sig_y); return cell; } @@ -1323,8 +1323,8 @@ RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig_y.size(); cell->parameters["\\OFFSET"] = offset; - cell->set("\\A", sig_a); - cell->set("\\Y", sig_y); + cell->setPort("\\A", sig_a); + cell->setPort("\\Y", sig_y); return cell; } @@ -1333,9 +1333,9 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a RTLIL::Cell *cell = addCell(name, "$concat"); cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\B_WIDTH"] = sig_b.size(); - cell->set("\\A", sig_a); - cell->set("\\B", sig_b); - cell->set("\\Y", sig_y); + cell->setPort("\\A", sig_a); + cell->setPort("\\B", sig_b); + cell->setPort("\\Y", sig_y); return cell; } @@ -1344,16 +1344,16 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, R RTLIL::Cell *cell = addCell(name, "$lut"); cell->parameters["\\LUT"] = lut; cell->parameters["\\WIDTH"] = sig_i.size(); - cell->set("\\I", sig_i); - cell->set("\\O", sig_o); + cell->setPort("\\I", sig_i); + cell->setPort("\\O", sig_o); return cell; } RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en) { RTLIL::Cell *cell = addCell(name, "$assert"); - cell->set("\\A", sig_a); - cell->set("\\EN", sig_en); + cell->setPort("\\A", sig_a); + cell->setPort("\\EN", sig_en); return cell; } @@ -1363,9 +1363,9 @@ RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->set("\\SET", sig_set); - cell->set("\\CLR", sig_clr); - cell->set("\\Q", sig_q); + cell->setPort("\\SET", sig_set); + cell->setPort("\\CLR", sig_clr); + cell->setPort("\\Q", sig_q); return cell; } @@ -1374,9 +1374,9 @@ RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::Cell *cell = addCell(name, "$dff"); cell->parameters["\\CLK_POLARITY"] = clk_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->set("\\CLK", sig_clk); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\CLK", sig_clk); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1388,11 +1388,11 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->set("\\CLK", sig_clk); - cell->set("\\SET", sig_set); - cell->set("\\CLR", sig_clr); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\CLK", sig_clk); + cell->setPort("\\SET", sig_set); + cell->setPort("\\CLR", sig_clr); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1404,10 +1404,10 @@ RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk cell->parameters["\\ARST_POLARITY"] = arst_polarity; cell->parameters["\\ARST_VALUE"] = arst_value; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->set("\\CLK", sig_clk); - cell->set("\\ARST", sig_arst); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\CLK", sig_clk); + cell->setPort("\\ARST", sig_arst); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1416,9 +1416,9 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e RTLIL::Cell *cell = addCell(name, "$dlatch"); cell->parameters["\\EN_POLARITY"] = en_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->set("\\EN", sig_en); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\EN", sig_en); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1430,20 +1430,20 @@ RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig cell->parameters["\\SET_POLARITY"] = set_polarity; cell->parameters["\\CLR_POLARITY"] = clr_polarity; cell->parameters["\\WIDTH"] = sig_q.size(); - cell->set("\\EN", sig_en); - cell->set("\\SET", sig_set); - cell->set("\\CLR", sig_clr); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\EN", sig_en); + cell->setPort("\\SET", sig_set); + cell->setPort("\\CLR", sig_clr); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity) { RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); - cell->set("\\C", sig_clk); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\C", sig_clk); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1451,11 +1451,11 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec si RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity) { RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); - cell->set("\\C", sig_clk); - cell->set("\\S", sig_set); - cell->set("\\R", sig_clr); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\C", sig_clk); + cell->setPort("\\S", sig_set); + cell->setPort("\\R", sig_clr); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1463,19 +1463,19 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig bool arst_value, bool clk_polarity, bool arst_polarity) { RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); - cell->set("\\C", sig_clk); - cell->set("\\R", sig_arst); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\C", sig_clk); + cell->setPort("\\R", sig_arst); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); - cell->set("\\E", sig_en); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\E", sig_en); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1483,11 +1483,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity) { RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); - cell->set("\\E", sig_en); - cell->set("\\S", sig_set); - cell->set("\\R", sig_clr); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); + cell->setPort("\\E", sig_en); + cell->setPort("\\S", sig_set); + cell->setPort("\\R", sig_clr); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); return cell; } @@ -1509,12 +1509,12 @@ RTLIL::Memory::Memory() size = 0; } -bool RTLIL::Cell::has(RTLIL::IdString portname) const +bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const { return connections_.count(portname) != 0; } -void RTLIL::Cell::unset(RTLIL::IdString portname) +void RTLIL::Cell::unsetPort(RTLIL::IdString portname) { std::pair new_conn(portname, RTLIL::SigSpec()); @@ -1528,7 +1528,7 @@ void RTLIL::Cell::unset(RTLIL::IdString portname) connections_.erase(portname); } -void RTLIL::Cell::set(RTLIL::IdString portname, RTLIL::SigSpec signal) +void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal) { std::pair new_conn(portname, signal); @@ -1542,7 +1542,7 @@ void RTLIL::Cell::set(RTLIL::IdString portname, RTLIL::SigSpec signal) connections_[portname] = signal; } -const RTLIL::SigSpec &RTLIL::Cell::get(RTLIL::IdString portname) const +const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const { return connections_.at(portname); } @@ -1552,6 +1552,26 @@ const std::map &RTLIL::Cell::connections() cons return connections_; } +bool RTLIL::Cell::hasParam(RTLIL::IdString paramname) const +{ + return parameters.count(paramname); +} + +void RTLIL::Cell::unsetParam(RTLIL::IdString paramname) +{ + parameters.erase(paramname); +} + +void RTLIL::Cell::setParam(RTLIL::IdString paramname, RTLIL::Const value) +{ + parameters[paramname] = value; +} + +const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const +{ + return parameters.at(paramname); +} + void RTLIL::Cell::check() { #ifndef NDEBUG diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 5107e5f2..796d45df 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -331,6 +331,7 @@ struct RTLIL::Selection struct RTLIL::Monitor { + virtual ~Monitor() { } virtual void notify_module_add(RTLIL::Module*) { } virtual void notify_module_del(RTLIL::Module*) { } virtual void notify_cell_connect(RTLIL::Cell*, const std::pair&) { } @@ -663,12 +664,18 @@ public: RTLIL_ATTRIBUTE_MEMBERS // access cell ports - bool has(RTLIL::IdString portname) const; - void unset(RTLIL::IdString portname); - void set(RTLIL::IdString portname, RTLIL::SigSpec signal); - const RTLIL::SigSpec &get(RTLIL::IdString portname) const; + bool hasPort(RTLIL::IdString portname) const; + void unsetPort(RTLIL::IdString portname); + void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal); + const RTLIL::SigSpec &getPort(RTLIL::IdString portname) const; const std::map &connections() const; + // access cell parameters + bool hasParam(RTLIL::IdString portname) const; + void unsetParam(RTLIL::IdString portname); + void setParam(RTLIL::IdString portname, RTLIL::Const value); + const RTLIL::Const &getParam(RTLIL::IdString portname) const; + void check(); void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); diff --git a/kernel/satgen.h b/kernel/satgen.h index ce2c9028..1ada1e16 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -182,9 +182,9 @@ struct SatGen if (model_undef && (cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || is_arith_compare)) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); if (is_arith_compare) extendSignalWidth(undef_a, undef_b, cell, true); else @@ -195,7 +195,7 @@ struct SatGen int undef_y_bit = ez->OR(undef_any_a, undef_any_b); if (cell->type == "$div" || cell->type == "$mod") { - std::vector b = importSigSpec(cell->get("\\B"), timestep); + std::vector b = importSigSpec(cell->getPort("\\B"), timestep); undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b))); } @@ -215,9 +215,9 @@ struct SatGen cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$sub") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector b = importDefSigSpec(cell->get("\\B"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -237,9 +237,9 @@ struct SatGen if (model_undef && !arith_undef_handled) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, undef_y, cell, false); if (cell->type == "$and" || cell->type == "$_AND_") { @@ -265,7 +265,7 @@ struct SatGen } else if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -273,16 +273,16 @@ struct SatGen if (cell->type == "$_INV_" || cell->type == "$not") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_not(a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, true); ez->assume(ez->vec_eq(undef_a, undef_y)); undefGating(y, yy, undef_y); @@ -292,20 +292,20 @@ struct SatGen if (cell->type == "$_MUX_" || cell->type == "$mux") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector b = importDefSigSpec(cell->get("\\B"), timestep); - std::vector s = importDefSigSpec(cell->get("\\S"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector s = importDefSigSpec(cell->getPort("\\S"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->get("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); std::vector unequal_ab = ez->vec_not(ez->vec_iff(a, b)); std::vector undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); @@ -318,10 +318,10 @@ struct SatGen if (cell->type == "$pmux" || cell->type == "$safe_pmux") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector b = importDefSigSpec(cell->get("\\B"), timestep); - std::vector s = importDefSigSpec(cell->get("\\S"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector s = importDefSigSpec(cell->getPort("\\S"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -336,10 +336,10 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_s = importUndefSigSpec(cell->get("\\S"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); int maybe_one_hot = ez->FALSE; int maybe_many_hot = ez->FALSE; @@ -387,8 +387,8 @@ struct SatGen if (cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidthUnary(a, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -402,8 +402,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidthUnary(undef_a, undef_y, cell, cell->type != "$bu0"); if (cell->type == "$pos" || cell->type == "$bu0") { @@ -422,8 +422,8 @@ struct SatGen if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$reduce_bool" || cell->type == "$logic_not") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -442,8 +442,8 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); int aX = ez->expression(ezSAT::OpOr, undef_a); if (cell->type == "$reduce_and") { @@ -469,12 +469,12 @@ struct SatGen if (cell->type == "$logic_and" || cell->type == "$logic_or") { - std::vector vec_a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector vec_b = importDefSigSpec(cell->get("\\B"), timestep); + std::vector vec_a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector vec_b = importDefSigSpec(cell->getPort("\\B"), timestep); int a = ez->expression(ez->OpOr, vec_a); int b = ez->expression(ez->OpOr, vec_b); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -487,9 +487,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a))); int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); @@ -516,16 +516,16 @@ struct SatGen if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") { bool is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector b = importDefSigSpec(cell->get("\\B"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(a, b, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); a = ez->vec_or(a, undef_a); b = ez->vec_or(b, undef_b); @@ -548,9 +548,9 @@ struct SatGen if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); if (cell->type == "$eqx") @@ -565,9 +565,9 @@ struct SatGen } else if (model_undef && (cell->type == "$eq" || cell->type == "$ne")) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, cell, true); int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); @@ -589,7 +589,7 @@ struct SatGen else { if (model_undef) { - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); undefGating(y, yy, undef_y); } log_assert(!model_undef || arith_undef_handled); @@ -599,9 +599,9 @@ struct SatGen if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector b = importDefSigSpec(cell->get("\\B"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); int extend_bit = ez->FALSE; @@ -632,9 +632,9 @@ struct SatGen if (model_undef) { - std::vector undef_a = importUndefSigSpec(cell->get("\\A"), timestep); - std::vector undef_b = importUndefSigSpec(cell->get("\\B"), timestep); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); std::vector undef_a_shifted; if (cell->type != "$shift" && cell->type != "$shiftx" && cell->parameters["\\A_SIGNED"].as_bool()) @@ -670,9 +670,9 @@ struct SatGen if (cell->type == "$mul") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector b = importDefSigSpec(cell->get("\\B"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -689,7 +689,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -697,9 +697,9 @@ struct SatGen if (cell->type == "$div" || cell->type == "$mod") { - std::vector a = importDefSigSpec(cell->get("\\A"), timestep); - std::vector b = importDefSigSpec(cell->get("\\B"), timestep); - std::vector y = importDefSigSpec(cell->get("\\Y"), timestep); + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(a, b, y, cell); std::vector yy = model_undef ? ez->vec_var(y.size()) : y; @@ -753,11 +753,11 @@ struct SatGen only_first_one.at(0) = ez->TRUE; div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones); } else { - div_zero_result.insert(div_zero_result.end(), cell->get("\\A").size(), ez->TRUE); + div_zero_result.insert(div_zero_result.end(), cell->getPort("\\A").size(), ez->TRUE); div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->FALSE); } } else { - int copy_a_bits = std::min(cell->get("\\A").size(), cell->get("\\B").size()); + int copy_a_bits = std::min(cell->getPort("\\A").size(), cell->getPort("\\B").size()); div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back()); @@ -769,7 +769,7 @@ struct SatGen if (model_undef) { log_assert(arith_undef_handled); - std::vector undef_y = importUndefSigSpec(cell->get("\\Y"), timestep); + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); undefGating(y, yy, undef_y); } return true; @@ -777,17 +777,17 @@ struct SatGen if (cell->type == "$slice") { - RTLIL::SigSpec a = cell->get("\\A"); - RTLIL::SigSpec y = cell->get("\\Y"); + RTLIL::SigSpec a = cell->getPort("\\A"); + RTLIL::SigSpec y = cell->getPort("\\Y"); ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.size()), y, timestep)); return true; } if (cell->type == "$concat") { - RTLIL::SigSpec a = cell->get("\\A"); - RTLIL::SigSpec b = cell->get("\\B"); - RTLIL::SigSpec y = cell->get("\\Y"); + RTLIL::SigSpec a = cell->getPort("\\A"); + RTLIL::SigSpec b = cell->getPort("\\B"); + RTLIL::SigSpec y = cell->getPort("\\Y"); RTLIL::SigSpec ab = a; ab.append(b); @@ -800,20 +800,20 @@ struct SatGen { if (timestep == 1) { - initial_state.add((*sigmap)(cell->get("\\Q"))); + initial_state.add((*sigmap)(cell->getPort("\\Q"))); } else { - std::vector d = importDefSigSpec(cell->get("\\D"), timestep-1); - std::vector q = importDefSigSpec(cell->get("\\Q"), timestep); + std::vector d = importDefSigSpec(cell->getPort("\\D"), timestep-1); + std::vector q = importDefSigSpec(cell->getPort("\\Q"), timestep); std::vector qq = model_undef ? ez->vec_var(q.size()) : q; ez->assume(ez->vec_eq(d, qq)); if (model_undef) { - std::vector undef_d = importUndefSigSpec(cell->get("\\D"), timestep-1); - std::vector undef_q = importUndefSigSpec(cell->get("\\Q"), timestep); + std::vector undef_d = importUndefSigSpec(cell->getPort("\\D"), timestep-1); + std::vector undef_q = importUndefSigSpec(cell->getPort("\\Q"), timestep); ez->assume(ez->vec_eq(undef_d, undef_q)); undefGating(q, qq, undef_q); @@ -825,8 +825,8 @@ struct SatGen if (cell->type == "$assert") { std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); - asserts_a[pf].append((*sigmap)(cell->get("\\A"))); - asserts_en[pf].append((*sigmap)(cell->get("\\EN"))); + asserts_a[pf].append((*sigmap)(cell->getPort("\\A"))); + asserts_en[pf].append((*sigmap)(cell->getPort("\\EN"))); return true; } diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index d204e93c..4b2e82ca 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -110,11 +110,11 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) { if (clk_polarity != (cell->type == "$_DFF_P_")) return; - if (clk_sig != assign_map(cell->get("\\C"))) + if (clk_sig != assign_map(cell->getPort("\\C"))) return; - RTLIL::SigSpec sig_d = cell->get("\\D"); - RTLIL::SigSpec sig_q = cell->get("\\Q"); + RTLIL::SigSpec sig_d = cell->getPort("\\D"); + RTLIL::SigSpec sig_q = cell->getPort("\\Q"); if (keepff) for (auto &c : sig_q.chunks()) @@ -132,8 +132,8 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_INV_") { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); assign_map.apply(sig_a); assign_map.apply(sig_y); @@ -146,9 +146,9 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_b = cell->get("\\B"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -172,10 +172,10 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) if (cell->type == "$_MUX_") { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_b = cell->get("\\B"); - RTLIL::SigSpec sig_s = cell->get("\\S"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_s = cell->getPort("\\S"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); assign_map.apply(sig_a); assign_map.apply(sig_b); @@ -467,7 +467,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std if (cell->type != "$_DFF_N_" && cell->type != "$_DFF_P_") continue; - std::pair key(cell->type == "$_DFF_P_", assign_map(cell->get("\\C"))); + std::pair key(cell->type == "$_DFF_P_", assign_map(cell->getPort("\\C"))); if (++dff_counters[key] > best_dff_counter) { best_dff_counter = dff_counters[key]; clk_polarity = key.first; @@ -700,48 +700,48 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\ZERO" || c->type == "\\ONE") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]); conn.second = RTLIL::SigSpec(c->type == "\\ZERO" ? 0 : 1, 1); module->connect(conn); continue; } if (c->type == "\\BUF") { RTLIL::SigSig conn; - conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)]); - conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)]); + conn.first = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]); + conn.second = RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]); module->connect(conn); continue; } if (c->type == "\\INV") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_INV_"); - cell->set("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)])); - cell->set("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)])); + cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); + cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); - cell->set("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)])); - cell->set("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\B").as_wire()->name)])); - cell->set("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)])); + cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); + cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); + cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\MUX") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX_"); - cell->set("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\A").as_wire()->name)])); - cell->set("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\B").as_wire()->name)])); - cell->set("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\S").as_wire()->name)])); - cell->set("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Y").as_wire()->name)])); + cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); + cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); + cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); + cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); design->select(module, cell); continue; } if (c->type == "\\DFF") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->set("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\D").as_wire()->name)])); - cell->set("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Q").as_wire()->name)])); - cell->set("\\C", clk_sig); + cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); + cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)])); + cell->setPort("\\C", clk_sig); design->select(module, cell); continue; } @@ -764,9 +764,9 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std if (c->type == "\\_dff_") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); - cell->set("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\D").as_wire()->name)])); - cell->set("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->get("\\Q").as_wire()->name)])); - cell->set("\\C", clk_sig); + cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); + cell->setPort("\\Q", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Q").as_wire()->name)])); + cell->setPort("\\C", clk_sig); design->select(module, cell); continue; } @@ -780,7 +780,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std log_assert(c.width == 1); newsig.append(module->wires_[remap_name(c.wire->name)]); } - cell->set(conn.first, newsig); + cell->setPort(conn.first, newsig); } design->select(module, cell); } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index e10cb109..1891a745 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -120,8 +120,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) module->addWire(RTLIL::escape_id(q)); RTLIL::Cell *cell = module->addCell(NEW_ID, dff_name); - cell->set("\\D", module->wires_.at(RTLIL::escape_id(d))); - cell->set("\\Q", module->wires_.at(RTLIL::escape_id(q))); + cell->setPort("\\D", module->wires_.at(RTLIL::escape_id(d))); + cell->setPort("\\Q", module->wires_.at(RTLIL::escape_id(q))); continue; } @@ -140,7 +140,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) *(q++) = 0; if (module->wires_.count(RTLIL::escape_id(q)) == 0) module->addWire(RTLIL::escape_id(q)); - cell->set(RTLIL::escape_id(p), module->wires_.at(RTLIL::escape_id(q))); + cell->setPort(RTLIL::escape_id(p), module->wires_.at(RTLIL::escape_id(q))); } continue; } @@ -196,8 +196,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) RTLIL::Cell *cell = module->addCell(NEW_ID, "$lut"); cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size()); cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size()); - cell->set("\\I", input_sig); - cell->set("\\O", output_sig); + cell->setPort("\\I", input_sig); + cell->setPort("\\O", output_sig); lutptr = &cell->parameters.at("\\LUT"); lut_default_state = RTLIL::State::Sx; continue; diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 62995a49..e3fde855 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -72,10 +72,10 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n continue; if (mod->get_bool_attribute("\\blackbox")) continue; - if (it.second->has(name)) + if (it.second->hasPort(name)) continue; - it.second->set(name, wire); + it.second->setPort(name, wire); log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str()); } } diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index 3e13fd4d..30c80f73 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -176,7 +176,7 @@ struct ConnectPass : public Pass { if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cells_.at(RTLIL::escape_id(port_cell))->set(RTLIL::escape_id(port_port), sigmap(sig)); + module->cells_.at(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); } else log_cmd_error("Expected -set, -unset, or -port.\n"); diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 5fce2d6c..07c6150c 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -74,9 +74,9 @@ struct SpliceWorker cell->parameters["\\OFFSET"] = offset; cell->parameters["\\A_WIDTH"] = sig_a.size(); cell->parameters["\\Y_WIDTH"] = sig.size(); - cell->set("\\A", sig_a); - cell->set("\\Y", module->addWire(NEW_ID, sig.size())); - new_sig = cell->get("\\Y"); + cell->setPort("\\A", sig_a); + cell->setPort("\\Y", module->addWire(NEW_ID, sig.size())); + new_sig = cell->getPort("\\Y"); } sliced_signals_cache[sig] = new_sig; @@ -130,10 +130,10 @@ struct SpliceWorker RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat"); cell->parameters["\\A_WIDTH"] = new_sig.size(); cell->parameters["\\B_WIDTH"] = sig2.size(); - cell->set("\\A", new_sig); - cell->set("\\B", sig2); - cell->set("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size())); - new_sig = cell->get("\\Y"); + cell->setPort("\\A", new_sig); + cell->setPort("\\B", sig2); + cell->setPort("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size())); + new_sig = cell->getPort("\\Y"); } spliced_signals_cache[sig] = new_sig; diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index a619cf57..6025de15 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -52,8 +52,8 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig for (auto &cellport : cellport_list) { if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux" && cellport.first->type != "$safe_pmux") || cellport.second != "\\Y") return false; - RTLIL::SigSpec sig_a = assign_map(cellport.first->get("\\A")); - RTLIL::SigSpec sig_b = assign_map(cellport.first->get("\\B")); + RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A")); + RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B")); if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) return false; for (int i = 0; i < sig_b.size(); i += sig_a.size()) @@ -80,14 +80,14 @@ static bool check_state_users(RTLIL::SigSpec sig) continue; if (cellport.second != "\\A" && cellport.second != "\\B") return false; - if (!cell->has("\\A") || !cell->has("\\B") || !cell->has("\\Y")) + if (!cell->hasPort("\\A") || !cell->hasPort("\\B") || !cell->hasPort("\\Y")) return false; for (auto &port_it : cell->connections()) if (port_it.first != "\\A" && port_it.first != "\\B" && port_it.first != "\\Y") return false; - if (assign_map(cell->get("\\A")) == sig && cell->get("\\B").is_fully_const()) + if (assign_map(cell->getPort("\\A")) == sig && cell->getPort("\\B").is_fully_const()) continue; - if (assign_map(cell->get("\\B")) == sig && cell->get("\\A").is_fully_const()) + if (assign_map(cell->getPort("\\B")) == sig && cell->getPort("\\A").is_fully_const()) continue; return false; } @@ -109,8 +109,8 @@ static void detect_fsm(RTLIL::Wire *wire) continue; muxtree_cells.clear(); SigPool recursion_monitor; - RTLIL::SigSpec sig_q = assign_map(cellport.first->get("\\Q")); - RTLIL::SigSpec sig_d = assign_map(cellport.first->get("\\D")); + RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort("\\Q")); + RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort("\\D")); if (sig_q == RTLIL::SigSpec(wire) && check_state_mux_tree(sig_q, sig_d, recursion_monitor) && check_state_users(sig_q)) { log("Found FSM state register %s in module %s.\n", wire->name.c_str(), module->name.c_str()); wire->attributes["\\fsm_encoding"] = RTLIL::Const("auto"); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 2da4794e..670fae1d 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -43,34 +43,34 @@ struct FsmExpand bool is_cell_merge_candidate(RTLIL::Cell *cell) { if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") - if (cell->get("\\A").size() < 2) + if (cell->getPort("\\A").size() < 2) return true; RTLIL::SigSpec new_signals; - if (cell->has("\\A")) - new_signals.append(assign_map(cell->get("\\A"))); - if (cell->has("\\B")) - new_signals.append(assign_map(cell->get("\\B"))); - if (cell->has("\\S")) - new_signals.append(assign_map(cell->get("\\S"))); - if (cell->has("\\Y")) - new_signals.append(assign_map(cell->get("\\Y"))); + if (cell->hasPort("\\A")) + new_signals.append(assign_map(cell->getPort("\\A"))); + if (cell->hasPort("\\B")) + new_signals.append(assign_map(cell->getPort("\\B"))); + if (cell->hasPort("\\S")) + new_signals.append(assign_map(cell->getPort("\\S"))); + if (cell->hasPort("\\Y")) + new_signals.append(assign_map(cell->getPort("\\Y"))); new_signals.sort_and_unify(); new_signals.remove_const(); - new_signals.remove(assign_map(fsm_cell->get("\\CTRL_IN"))); - new_signals.remove(assign_map(fsm_cell->get("\\CTRL_OUT"))); + new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_IN"))); + new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_OUT"))); if (new_signals.size() > 3) return false; - if (cell->has("\\Y")) { - new_signals.append(assign_map(cell->get("\\Y"))); + if (cell->hasPort("\\Y")) { + new_signals.append(assign_map(cell->getPort("\\Y"))); new_signals.sort_and_unify(); new_signals.remove_const(); - new_signals.remove(assign_map(fsm_cell->get("\\CTRL_IN"))); - new_signals.remove(assign_map(fsm_cell->get("\\CTRL_OUT"))); + new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_IN"))); + new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_OUT"))); } if (new_signals.size() > 2) @@ -83,10 +83,10 @@ struct FsmExpand { std::vector cell_list; - for (auto c : sig2driver.find(assign_map(fsm_cell->get("\\CTRL_IN")))) + for (auto c : sig2driver.find(assign_map(fsm_cell->getPort("\\CTRL_IN")))) cell_list.push_back(c); - for (auto c : sig2user.find(assign_map(fsm_cell->get("\\CTRL_OUT")))) + for (auto c : sig2user.find(assign_map(fsm_cell->getPort("\\CTRL_OUT")))) cell_list.push_back(c); current_set.clear(); @@ -148,12 +148,12 @@ struct FsmExpand for (int i = 0; i < (1 << input_sig.size()); i++) { RTLIL::Const in_val(i, input_sig.size()); RTLIL::SigSpec A, B, S; - if (cell->has("\\A")) - A = assign_map(cell->get("\\A")); - if (cell->has("\\B")) - B = assign_map(cell->get("\\B")); - if (cell->has("\\S")) - S = assign_map(cell->get("\\S")); + if (cell->hasPort("\\A")) + A = assign_map(cell->getPort("\\A")); + if (cell->hasPort("\\B")) + B = assign_map(cell->getPort("\\B")); + if (cell->hasPort("\\S")) + S = assign_map(cell->getPort("\\S")); A.replace(input_sig, RTLIL::SigSpec(in_val)); B.replace(input_sig, RTLIL::SigSpec(in_val)); S.replace(input_sig, RTLIL::SigSpec(in_val)); @@ -167,14 +167,14 @@ struct FsmExpand fsm_data.copy_from_cell(fsm_cell); fsm_data.num_inputs += input_sig.size(); - RTLIL::SigSpec new_ctrl_in = fsm_cell->get("\\CTRL_IN"); + RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort("\\CTRL_IN"); new_ctrl_in.append(input_sig); - fsm_cell->set("\\CTRL_IN", new_ctrl_in); + fsm_cell->setPort("\\CTRL_IN", new_ctrl_in); fsm_data.num_outputs += output_sig.size(); - RTLIL::SigSpec new_ctrl_out = fsm_cell->get("\\CTRL_OUT"); + RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort("\\CTRL_OUT"); new_ctrl_out.append(output_sig); - fsm_cell->set("\\CTRL_OUT", new_ctrl_out); + fsm_cell->setPort("\\CTRL_OUT", new_ctrl_out); std::vector new_transition_table; for (auto &tr : fsm_data.transition_table) { diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 718f779b..cf2075fb 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -58,9 +58,9 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); return false; } - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); - RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); - RTLIL::SigSpec sig_s = assign_map(cell->get("\\S")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S")); if (reset_state && RTLIL::SigSpec(*reset_state).is_fully_undef()) do { if (sig_a.is_fully_def()) @@ -183,12 +183,12 @@ static void extract_fsm(RTLIL::Wire *wire) if ((cell->type != "$dff" && cell->type != "$adff") || cellport.second != "\\Q") continue; log(" found %s cell for state register: %s\n", cell->type.c_str(), cell->name.c_str()); - RTLIL::SigSpec sig_q = assign_map(cell->get("\\Q")); - RTLIL::SigSpec sig_d = assign_map(cell->get("\\D")); - clk = cell->get("\\CLK"); + RTLIL::SigSpec sig_q = assign_map(cell->getPort("\\Q")); + RTLIL::SigSpec sig_d = assign_map(cell->getPort("\\D")); + clk = cell->getPort("\\CLK"); clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); if (cell->type == "$adff") { - arst = cell->get("\\ARST"); + arst = cell->getPort("\\ARST"); arst_polarity = cell->parameters["\\ARST_POLARITY"].as_bool(); reset_state = cell->parameters["\\ARST_VALUE"]; } @@ -224,9 +224,9 @@ static void extract_fsm(RTLIL::Wire *wire) sig2trigger.find(dff_out, cellport_list); for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells_.at(cellport.first); - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); - RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); - RTLIL::SigSpec sig_y = assign_map(cell->get("\\Y")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y")); if (cellport.second == "\\A" && !sig_b.is_fully_const()) continue; if (cellport.second == "\\B" && !sig_a.is_fully_const()) @@ -271,12 +271,12 @@ static void extract_fsm(RTLIL::Wire *wire) // create fsm cell RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); - fsm_cell->set("\\CLK", clk); - fsm_cell->set("\\ARST", arst); + fsm_cell->setPort("\\CLK", clk); + fsm_cell->setPort("\\ARST", arst); fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); fsm_cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity ? 1 : 0, 1); - fsm_cell->set("\\CTRL_IN", ctrl_in); - fsm_cell->set("\\CTRL_OUT", ctrl_out); + fsm_cell->setPort("\\CTRL_IN", ctrl_in); + fsm_cell->setPort("\\CTRL_OUT", ctrl_out); fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name); fsm_cell->attributes = wire->attributes; fsm_data.copy_to_cell(fsm_cell); @@ -294,7 +294,7 @@ static void extract_fsm(RTLIL::Wire *wire) sig2driver.find(ctrl_out, cellport_list); for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells_.at(cellport.first); - RTLIL::SigSpec port_sig = assign_map(cell->get(cellport.second)); + RTLIL::SigSpec port_sig = assign_map(cell->getPort(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), autoidx++), unconn_sig.size()); port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); @@ -347,8 +347,8 @@ struct FsmExtractPass : public Pass { assign_map.apply(sig); sig2driver.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); } - if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->has("\\Y") && - cell_it.second->get("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { + if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->hasPort("\\Y") && + cell_it.second->getPort("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); sig2trigger.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 8b9ad6be..99b736c1 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -58,9 +58,9 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$eq"); - eq_cell->set("\\A", eq_sig_a); - eq_cell->set("\\B", eq_sig_b); - eq_cell->set("\\Y", RTLIL::SigSpec(eq_wire)); + eq_cell->setPort("\\A", eq_sig_a); + eq_cell->setPort("\\B", eq_sig_b); + eq_cell->setPort("\\Y", RTLIL::SigSpec(eq_wire)); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size()); @@ -80,8 +80,8 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$reduce_or"); - or_cell->set("\\A", or_sig); - or_cell->set("\\Y", RTLIL::SigSpec(or_wire)); + or_cell->setPort("\\A", or_sig); + or_cell->setPort("\\Y", RTLIL::SigSpec(or_wire)); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); @@ -96,9 +96,9 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapaddCell(NEW_ID, "$and"); - and_cell->set("\\A", and_sig.extract(0, 1)); - and_cell->set("\\B", and_sig.extract(1, 1)); - and_cell->set("\\Y", RTLIL::SigSpec(and_wire)); + and_cell->setPort("\\A", and_sig.extract(0, 1)); + and_cell->setPort("\\B", and_sig.extract(1, 1)); + and_cell->setPort("\\Y", RTLIL::SigSpec(and_wire)); and_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); and_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); and_cell->parameters["\\A_WIDTH"] = RTLIL::Const(1); @@ -119,8 +119,8 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map 1) { RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or"); - or_cell->set("\\A", cases_vector); - or_cell->set("\\Y", output); + or_cell->setPort("\\A", cases_vector); + or_cell->setPort("\\Y", output); or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size()); or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); @@ -138,8 +138,8 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) FsmData fsm_data; fsm_data.copy_from_cell(fsm_cell); - RTLIL::SigSpec ctrl_in = fsm_cell->get("\\CTRL_IN"); - RTLIL::SigSpec ctrl_out = fsm_cell->get("\\CTRL_OUT"); + RTLIL::SigSpec ctrl_in = fsm_cell->getPort("\\CTRL_IN"); + RTLIL::SigSpec ctrl_out = fsm_cell->getPort("\\CTRL_OUT"); // create state register @@ -151,7 +151,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits); RTLIL::Cell *state_dff = module->addCell(NEW_ID, ""); - if (fsm_cell->get("\\ARST").is_fully_const()) { + if (fsm_cell->getPort("\\ARST").is_fully_const()) { state_dff->type = "$dff"; } else { state_dff->type = "$adff"; @@ -160,13 +160,13 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) for (auto &bit : state_dff->parameters["\\ARST_VALUE"].bits) if (bit != RTLIL::State::S1) bit = RTLIL::State::S0; - state_dff->set("\\ARST", fsm_cell->get("\\ARST")); + state_dff->setPort("\\ARST", fsm_cell->getPort("\\ARST")); } state_dff->parameters["\\WIDTH"] = RTLIL::Const(fsm_data.state_bits); state_dff->parameters["\\CLK_POLARITY"] = fsm_cell->parameters["\\CLK_POLARITY"]; - state_dff->set("\\CLK", fsm_cell->get("\\CLK")); - state_dff->set("\\D", RTLIL::SigSpec(next_state_wire)); - state_dff->set("\\Q", RTLIL::SigSpec(state_wire)); + state_dff->setPort("\\CLK", fsm_cell->getPort("\\CLK")); + state_dff->setPort("\\D", RTLIL::SigSpec(next_state_wire)); + state_dff->setPort("\\Q", RTLIL::SigSpec(state_wire)); // decode state register @@ -194,9 +194,9 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) encoding_is_onehot = false; RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq"); - eq_cell->set("\\A", sig_a); - eq_cell->set("\\B", sig_b); - eq_cell->set("\\Y", RTLIL::SigSpec(state_onehot, i)); + eq_cell->setPort("\\A", sig_a); + eq_cell->setPort("\\B", sig_b); + eq_cell->setPort("\\Y", RTLIL::SigSpec(state_onehot, i)); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false); eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size()); @@ -260,10 +260,10 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) } RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux"); - mux_cell->set("\\A", sig_a); - mux_cell->set("\\B", sig_b); - mux_cell->set("\\S", sig_s); - mux_cell->set("\\Y", RTLIL::SigSpec(next_state_wire)); + mux_cell->setPort("\\A", sig_a); + mux_cell->setPort("\\B", sig_b); + mux_cell->setPort("\\S", sig_s); + mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire)); mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); } diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index 9d9156ae..bcaa89bf 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -52,7 +52,7 @@ struct FsmOpt void opt_const_and_unused_inputs() { - RTLIL::SigSpec ctrl_in = cell->get("\\CTRL_IN"); + RTLIL::SigSpec ctrl_in = cell->getPort("\\CTRL_IN"); std::vector ctrl_in_used(ctrl_in.size()); std::vector new_transition_table; @@ -73,15 +73,15 @@ struct FsmOpt for (int i = int(ctrl_in_used.size())-1; i >= 0; i--) { if (!ctrl_in_used[i]) { - log(" Removing unused input signal %s.\n", log_signal(cell->get("\\CTRL_IN").extract(i, 1))); + log(" Removing unused input signal %s.\n", log_signal(cell->getPort("\\CTRL_IN").extract(i, 1))); for (auto &tr : new_transition_table) { RTLIL::SigSpec tmp(tr.ctrl_in); tmp.remove(i, 1); tr.ctrl_in = tmp.as_const(); } - RTLIL::SigSpec new_ctrl_in = cell->get("\\CTRL_IN"); + RTLIL::SigSpec new_ctrl_in = cell->getPort("\\CTRL_IN"); new_ctrl_in.remove(i, 1); - cell->set("\\CTRL_IN", new_ctrl_in); + cell->setPort("\\CTRL_IN", new_ctrl_in); fsm_data.num_inputs--; } } @@ -93,12 +93,12 @@ struct FsmOpt void opt_unused_outputs() { for (int i = 0; i < fsm_data.num_outputs; i++) { - RTLIL::SigSpec sig = cell->get("\\CTRL_OUT").extract(i, 1); + RTLIL::SigSpec sig = cell->getPort("\\CTRL_OUT").extract(i, 1); if (signal_is_unused(sig)) { log(" Removing unused output signal %s.\n", log_signal(sig)); - RTLIL::SigSpec new_ctrl_out = cell->get("\\CTRL_OUT"); + RTLIL::SigSpec new_ctrl_out = cell->getPort("\\CTRL_OUT"); new_ctrl_out.remove(i, 1); - cell->set("\\CTRL_OUT", new_ctrl_out); + cell->setPort("\\CTRL_OUT", new_ctrl_out); for (auto &tr : fsm_data.transition_table) { RTLIL::SigSpec tmp(tr.ctrl_out); tmp.remove(i, 1); diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index 8f0e5d62..7a44dd45 100644 --- a/passes/fsm/fsmdata.h +++ b/passes/fsm/fsmdata.h @@ -141,13 +141,13 @@ struct FsmData log("\n"); log(" Input signals:\n"); - RTLIL::SigSpec sig_in = cell->get("\\CTRL_IN"); + RTLIL::SigSpec sig_in = cell->getPort("\\CTRL_IN"); for (int i = 0; i < SIZE(sig_in); i++) log(" %3d: %s\n", i, log_signal(sig_in[i])); log("\n"); log(" Output signals:\n"); - RTLIL::SigSpec sig_out = cell->get("\\CTRL_OUT"); + RTLIL::SigSpec sig_out = cell->getPort("\\CTRL_OUT"); for (int i = 0; i < SIZE(sig_out); i++) log(" %3d: %s\n", i, log_signal(sig_out[i])); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index d0c9f4b5..2a47002e 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -185,7 +185,7 @@ struct SubmodWorker RTLIL::Wire *old_wire = it.first; RTLIL::Wire *new_wire = it.second.new_wire; if (new_wire->port_id > 0) - new_cell->set(new_wire->name, RTLIL::SigSpec(old_wire)); + new_cell->setPort(new_wire->name, RTLIL::SigSpec(old_wire)); } } diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index aecb7bd6..8887d195 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -75,12 +75,12 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) wr_ports++; del_cells.push_back(cell); - RTLIL::SigSpec clk = cell->get("\\CLK"); + RTLIL::SigSpec clk = cell->getPort("\\CLK"); RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); - RTLIL::SigSpec addr = cell->get("\\ADDR"); - RTLIL::SigSpec data = cell->get("\\DATA"); - RTLIL::SigSpec en = cell->get("\\EN"); + RTLIL::SigSpec addr = cell->getPort("\\ADDR"); + RTLIL::SigSpec data = cell->getPort("\\DATA"); + RTLIL::SigSpec en = cell->getPort("\\EN"); clk.extend(1, false); clk_enable.extend(1, false); @@ -102,12 +102,12 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) rd_ports++; del_cells.push_back(cell); - RTLIL::SigSpec clk = cell->get("\\CLK"); + RTLIL::SigSpec clk = cell->getPort("\\CLK"); RTLIL::SigSpec clk_enable = RTLIL::SigSpec(cell->parameters["\\CLK_ENABLE"]); RTLIL::SigSpec clk_polarity = RTLIL::SigSpec(cell->parameters["\\CLK_POLARITY"]); RTLIL::SigSpec transparent = RTLIL::SigSpec(cell->parameters["\\TRANSPARENT"]); - RTLIL::SigSpec addr = cell->get("\\ADDR"); - RTLIL::SigSpec data = cell->get("\\DATA"); + RTLIL::SigSpec addr = cell->getPort("\\ADDR"); + RTLIL::SigSpec data = cell->getPort("\\DATA"); clk.extend(1, false); clk_enable.extend(1, false); @@ -146,10 +146,10 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : RTLIL::Const(0, 0); mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : RTLIL::Const(0, 0); - mem->set("\\WR_CLK", sig_wr_clk); - mem->set("\\WR_ADDR", sig_wr_addr); - mem->set("\\WR_DATA", sig_wr_data); - mem->set("\\WR_EN", sig_wr_en); + mem->setPort("\\WR_CLK", sig_wr_clk); + mem->setPort("\\WR_ADDR", sig_wr_addr); + mem->setPort("\\WR_DATA", sig_wr_data); + mem->setPort("\\WR_EN", sig_wr_en); log_assert(sig_rd_clk.size() == rd_ports); log_assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const()); @@ -162,9 +162,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : RTLIL::Const(0, 0); mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : RTLIL::Const(0, 0); - mem->set("\\RD_CLK", sig_rd_clk); - mem->set("\\RD_ADDR", sig_rd_addr); - mem->set("\\RD_DATA", sig_rd_data); + mem->setPort("\\RD_CLK", sig_rd_clk); + mem->setPort("\\RD_ADDR", sig_rd_addr); + mem->setPort("\\RD_DATA", sig_rd_data); for (auto c : del_cells) module->remove(c); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 6cbce781..e92d726c 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -43,21 +43,21 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI continue; if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - if (cell->get("\\CLK") != clk) + if (cell->getPort("\\CLK") != clk) continue; if (cell->parameters["\\CLK_POLARITY"].as_bool() != clk_polarity) continue; } - RTLIL::SigSpec q_norm = cell->get(after ? "\\D" : "\\Q"); + RTLIL::SigSpec q_norm = cell->getPort(after ? "\\D" : "\\Q"); normalize_sig(module, q_norm); - RTLIL::SigSpec d = q_norm.extract(bit, &cell->get(after ? "\\Q" : "\\D")); + RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? "\\Q" : "\\D")); if (d.size() != 1) continue; bit = d; - clk = cell->get("\\CLK"); + clk = cell->getPort("\\CLK"); clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool(); goto replaced_this_bit; } @@ -76,29 +76,29 @@ static void handle_wr_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec clk = RTLIL::SigSpec(RTLIL::State::Sx); bool clk_polarity = 0; - RTLIL::SigSpec sig_addr = cell->get("\\ADDR"); + RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR"); if (!find_sig_before_dff(module, sig_addr, clk, clk_polarity)) { log("no (compatible) $dff for address input found.\n"); return; } - RTLIL::SigSpec sig_data = cell->get("\\DATA"); + RTLIL::SigSpec sig_data = cell->getPort("\\DATA"); if (!find_sig_before_dff(module, sig_data, clk, clk_polarity)) { log("no (compatible) $dff for data input found.\n"); return; } - RTLIL::SigSpec sig_en = cell->get("\\EN"); + RTLIL::SigSpec sig_en = cell->getPort("\\EN"); if (!find_sig_before_dff(module, sig_en, clk, clk_polarity)) { log("no (compatible) $dff for enable input found.\n"); return; } if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { - cell->set("\\CLK", clk); - cell->set("\\ADDR", sig_addr); - cell->set("\\DATA", sig_data); - cell->set("\\EN", sig_en); + cell->setPort("\\CLK", clk); + cell->setPort("\\ADDR", sig_addr); + cell->setPort("\\DATA", sig_data); + cell->setPort("\\EN", sig_en); cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); log("merged $dff to cell.\n"); @@ -119,9 +119,9 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) for (auto cell : module->cells()) if (cell->type == "$dff") { - RTLIL::SigSpec new_q = cell->get("\\Q"); + RTLIL::SigSpec new_q = cell->getPort("\\Q"); new_q.replace(sig, new_sig); - cell->set("\\Q", new_q); + cell->setPort("\\Q", new_q); } } @@ -132,13 +132,13 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) bool clk_polarity = 0; RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_data = cell->get("\\DATA"); + RTLIL::SigSpec sig_data = cell->getPort("\\DATA"); if (find_sig_before_dff(module, sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) { disconnect_dff(module, sig_data); - cell->set("\\CLK", clk_data); - cell->set("\\DATA", sig_data); + cell->setPort("\\CLK", clk_data); + cell->setPort("\\DATA", sig_data); cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0); @@ -147,12 +147,12 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx); - RTLIL::SigSpec sig_addr = cell->get("\\ADDR"); + RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR"); if (find_sig_before_dff(module, sig_addr, clk_addr, clk_polarity) && clk_addr != RTLIL::SigSpec(RTLIL::State::Sx)) { - cell->set("\\CLK", clk_addr); - cell->set("\\ADDR", sig_addr); + cell->setPort("\\CLK", clk_addr); + cell->setPort("\\ADDR", sig_addr); cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); cell->parameters["\\TRANSPARENT"] = RTLIL::Const(1); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 0000bd50..f1917b97 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -61,20 +61,20 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) } // all write ports must share the same clock - RTLIL::SigSpec clocks = cell->get("\\WR_CLK"); + RTLIL::SigSpec clocks = cell->getPort("\\WR_CLK"); RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"]; RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"]; RTLIL::SigSpec refclock; RTLIL::State refclock_pol = RTLIL::State::Sx; for (int i = 0; i < clocks.size(); i++) { - RTLIL::SigSpec wr_en = cell->get("\\WR_EN").extract(i * mem_width, mem_width); + RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(i * mem_width, mem_width); if (wr_en.is_fully_const() && !wr_en.as_bool()) { static_ports.insert(i); continue; } if (clocks_en.bits[i] != RTLIL::State::S1) { - RTLIL::SigSpec wr_addr = cell->get("\\WR_ADDR").extract(i*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->get("\\WR_DATA").extract(i*mem_width, mem_width); + RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(i*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(i*mem_width, mem_width); if (wr_addr.is_fully_const()) { // FIXME: Actually we should check for wr_en.is_fully_const() also and // create a $adff cell with this ports wr_en input as reset pin when wr_en @@ -119,15 +119,15 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; if (clocks_pol.bits.size() > 0) { c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]); - c->set("\\CLK", clocks.extract(0, 1)); + c->setPort("\\CLK", clocks.extract(0, 1)); } else { c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1); - c->set("\\CLK", RTLIL::SigSpec(RTLIL::State::S0)); + c->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::S0)); } RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width); data_reg_in.push_back(RTLIL::SigSpec(w_in)); - c->set("\\D", data_reg_in.back()); + c->setPort("\\D", data_reg_in.back()); std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); if (module->wires_.count(w_out_name) > 0) @@ -137,7 +137,7 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) w_out->start_offset = mem_offset; data_reg_out.push_back(RTLIL::SigSpec(w_out)); - c->set("\\Q", data_reg_out.back()); + c->setPort("\\Q", data_reg_out.back()); } } @@ -147,10 +147,10 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++) { - RTLIL::SigSpec rd_addr = cell->get("\\RD_ADDR").extract(i*mem_abits, mem_abits); + RTLIL::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits); std::vector rd_signals; - rd_signals.push_back(cell->get("\\RD_DATA").extract(i*mem_width, mem_width)); + rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width)); if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1) { @@ -159,13 +159,13 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = RTLIL::Const(mem_abits); c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->set("\\CLK", cell->get("\\RD_CLK").extract(i, 1)); - c->set("\\D", rd_addr); + c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1)); + c->setPort("\\D", rd_addr); count_dff++; RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits); - c->set("\\Q", RTLIL::SigSpec(w)); + c->setPort("\\Q", RTLIL::SigSpec(w)); rd_addr = RTLIL::SigSpec(w); } else @@ -173,15 +173,15 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->set("\\CLK", cell->get("\\RD_CLK").extract(i, 1)); - c->set("\\Q", rd_signals.back()); + c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1)); + c->setPort("\\Q", rd_signals.back()); count_dff++; RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width); rd_signals.clear(); rd_signals.push_back(RTLIL::SigSpec(w)); - c->set("\\D", rd_signals.back()); + c->setPort("\\D", rd_signals.back()); } } @@ -193,15 +193,15 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) { RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; - c->set("\\Y", rd_signals[k]); - c->set("\\S", rd_addr.extract(mem_abits-j-1, 1)); + c->setPort("\\Y", rd_signals[k]); + c->setPort("\\S", rd_addr.extract(mem_abits-j-1, 1)); count_mux++; - c->set("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width)); - c->set("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width)); + c->setPort("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width)); + c->setPort("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width)); - next_rd_signals.push_back(c->get("\\A")); - next_rd_signals.push_back(c->get("\\B")); + next_rd_signals.push_back(c->getPort("\\A")); + next_rd_signals.push_back(c->getPort("\\B")); } next_rd_signals.swap(rd_signals); @@ -222,9 +222,9 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++) { - RTLIL::SigSpec wr_addr = cell->get("\\WR_ADDR").extract(j*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->get("\\WR_DATA").extract(j*mem_width, mem_width); - RTLIL::SigSpec wr_en = cell->get("\\WR_EN").extract(j*mem_width, mem_width); + RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width); + RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width); RTLIL::Cell *c = module->addCell(genid(cell->name, "$wreq", i, "", j), "$eq"); c->parameters["\\A_SIGNED"] = RTLIL::Const(0); @@ -232,12 +232,12 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\A_WIDTH"] = cell->parameters["\\ABITS"]; c->parameters["\\B_WIDTH"] = cell->parameters["\\ABITS"]; c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->set("\\A", RTLIL::SigSpec(i, mem_abits)); - c->set("\\B", wr_addr); + c->setPort("\\A", RTLIL::SigSpec(i, mem_abits)); + c->setPort("\\B", wr_addr); count_wrmux++; RTLIL::Wire *w_seladdr = module->addWire(genid(cell->name, "$wreq", i, "", j, "$y")); - c->set("\\Y", w_seladdr); + c->setPort("\\Y", w_seladdr); int wr_offset = 0; while (wr_offset < wr_en.size()) @@ -262,21 +262,21 @@ static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) c->parameters["\\A_WIDTH"] = RTLIL::Const(1); c->parameters["\\B_WIDTH"] = RTLIL::Const(1); c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->set("\\A", w); - c->set("\\B", wr_bit); + c->setPort("\\A", w); + c->setPort("\\B", wr_bit); w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y")); - c->set("\\Y", RTLIL::SigSpec(w)); + c->setPort("\\Y", RTLIL::SigSpec(w)); } c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); c->parameters["\\WIDTH"] = wr_width; - c->set("\\A", sig.extract(wr_offset, wr_width)); - c->set("\\B", wr_data.extract(wr_offset, wr_width)); - c->set("\\S", RTLIL::SigSpec(w)); + c->setPort("\\A", sig.extract(wr_offset, wr_width)); + c->setPort("\\B", wr_data.extract(wr_offset, wr_width)); + c->setPort("\\S", RTLIL::SigSpec(w)); w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); - c->set("\\Y", w); + c->setPort("\\Y", w); sig.replace(wr_offset, w); wr_offset += wr_width; diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index b1629b7c..b6e7cc83 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -64,18 +64,18 @@ struct MemoryShareWorker RTLIL::Cell *cell = sig_to_mux.at(sig).first; int bit_idx = sig_to_mux.at(sig).second; - std::vector sig_a = sigmap(cell->get("\\A")); - std::vector sig_b = sigmap(cell->get("\\B")); - std::vector sig_s = sigmap(cell->get("\\S")); - std::vector sig_y = sigmap(cell->get("\\Y")); + std::vector sig_a = sigmap(cell->getPort("\\A")); + std::vector sig_b = sigmap(cell->getPort("\\B")); + std::vector sig_s = sigmap(cell->getPort("\\S")); + std::vector sig_y = sigmap(cell->getPort("\\Y")); log_assert(sig_y.at(bit_idx) == sig); for (int i = 0; i < int(sig_s.size()); i++) if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) { if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) { - RTLIL::SigSpec new_b = cell->get("\\B"); + RTLIL::SigSpec new_b = cell->getPort("\\B"); new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); - cell->set("\\B", new_b); + cell->setPort("\\B", new_b); } return false; } @@ -90,9 +90,9 @@ struct MemoryShareWorker new_state[sig_s[i]] = true; if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) { - RTLIL::SigSpec new_b = cell->get("\\B"); + RTLIL::SigSpec new_b = cell->getPort("\\B"); new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx); - cell->set("\\B", new_b); + cell->setPort("\\B", new_b); } } @@ -101,9 +101,9 @@ struct MemoryShareWorker new_state[sig_s[i]] = false; if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) { - RTLIL::SigSpec new_a = cell->get("\\A"); + RTLIL::SigSpec new_a = cell->getPort("\\A"); new_a.replace(bit_idx, RTLIL::State::Sx); - cell->set("\\A", new_a); + cell->setPort("\\A", new_a); } return false; @@ -150,10 +150,10 @@ struct MemoryShareWorker if (cell->type == "$mux" || cell->type == "$pmux") { - std::vector sig_a = sigmap(cell->get("\\A")); - std::vector sig_b = sigmap(cell->get("\\B")); - std::vector sig_s = sigmap(cell->get("\\S")); - std::vector sig_y = sigmap(cell->get("\\Y")); + std::vector sig_a = sigmap(cell->getPort("\\A")); + std::vector sig_b = sigmap(cell->getPort("\\B")); + std::vector sig_s = sigmap(cell->getPort("\\S")); + std::vector sig_y = sigmap(cell->getPort("\\Y")); non_feedback_nets.insert(sig_s.begin(), sig_s.end()); @@ -200,8 +200,8 @@ struct MemoryShareWorker if (cell->parameters.at("\\CLK_ENABLE").as_bool()) continue; - RTLIL::SigSpec sig_addr = sigmap(cell->get("\\ADDR")); - std::vector sig_data = sigmap(cell->get("\\DATA")); + RTLIL::SigSpec sig_addr = sigmap(cell->getPort("\\ADDR")); + std::vector sig_data = sigmap(cell->getPort("\\DATA")); for (int i = 0; i < int(sig_data.size()); i++) if (non_feedback_nets.count(sig_data[i])) @@ -221,14 +221,14 @@ struct MemoryShareWorker for (auto cell : wr_ports) { - RTLIL::SigSpec sig_addr = sigmap_xmux(cell->get("\\ADDR")); + RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort("\\ADDR")); if (!async_rd_bits.count(sig_addr)) continue; log(" Analyzing write port %s.\n", log_id(cell)); - std::vector cell_data = cell->get("\\DATA"); - std::vector cell_en = cell->get("\\EN"); + std::vector cell_data = cell->getPort("\\DATA"); + std::vector cell_en = cell->getPort("\\EN"); int created_conditions = 0; for (int i = 0; i < int(cell_data.size()); i++) @@ -248,7 +248,7 @@ struct MemoryShareWorker if (created_conditions) { log(" Added enable logic for %d different cases.\n", created_conditions); - cell->set("\\EN", cell_en); + cell->setPort("\\EN", cell_en); } } } @@ -366,15 +366,15 @@ struct MemoryShareWorker for (int i = 0; i < int(wr_ports.size()); i++) { RTLIL::Cell *cell = wr_ports.at(i); - RTLIL::SigSpec addr = sigmap_xmux(cell->get("\\ADDR")); + RTLIL::SigSpec addr = sigmap_xmux(cell->getPort("\\ADDR")); if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->get("\\CLK")) != cache_clk || + (cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk || cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) { cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); - cache_clk = sigmap(cell->get("\\CLK")); + cache_clk = sigmap(cell->getPort("\\CLK")); last_port_by_addr.clear(); if (cache_clk_enable) @@ -386,7 +386,7 @@ struct MemoryShareWorker log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr)); log(" Active bits: "); - std::vector en_bits = sigmap(cell->get("\\EN")); + std::vector en_bits = sigmap(cell->getPort("\\EN")); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) { active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0; @@ -408,13 +408,13 @@ struct MemoryShareWorker // Force this ports addr input to addr directly (skip don't care muxes) - cell->set("\\ADDR", addr); + cell->setPort("\\ADDR", addr); // If any of the ports between `last_i' and `i' write to the same address, this // will have priority over whatever `last_i` wrote. So we need to revisit those // ports and mask the EN bits accordingly. - RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->get("\\EN")); + RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort("\\EN")); for (int j = last_i+1; j < i; j++) { @@ -429,20 +429,20 @@ struct MemoryShareWorker found_overlapping_bits_i_j: log(" Creating collosion-detect logic for port %d.\n", j); RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID); - module->addEq(NEW_ID, addr, wr_ports[j]->get("\\ADDR"), is_same_addr); - merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->get("\\EN"))); + module->addEq(NEW_ID, addr, wr_ports[j]->getPort("\\ADDR"), is_same_addr); + merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort("\\EN"))); } } // Then we need to merge the (masked) EN and the DATA signals. - RTLIL::SigSpec merged_data = wr_ports[last_i]->get("\\DATA"); + RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort("\\DATA"); if (found_overlapping_bits) { log(" Creating logic for merging DATA and EN ports.\n"); - merge_en_data(merged_en, merged_data, sigmap(cell->get("\\EN")), sigmap(cell->get("\\DATA"))); + merge_en_data(merged_en, merged_data, sigmap(cell->getPort("\\EN")), sigmap(cell->getPort("\\DATA"))); } else { - RTLIL::SigSpec cell_en = sigmap(cell->get("\\EN")); - RTLIL::SigSpec cell_data = sigmap(cell->get("\\DATA")); + RTLIL::SigSpec cell_en = sigmap(cell->getPort("\\EN")); + RTLIL::SigSpec cell_data = sigmap(cell->getPort("\\DATA")); for (int k = 0; k < int(en_bits.size()); k++) if (!active_bits_on_port[last_i][k]) { merged_en.replace(k, cell_en.extract(k, 1)); @@ -452,14 +452,14 @@ struct MemoryShareWorker // Connect the new EN and DATA signals and remove the old write port. - cell->set("\\EN", merged_en); - cell->set("\\DATA", merged_data); + cell->setPort("\\EN", merged_en); + cell->setPort("\\DATA", merged_data); module->remove(wr_ports[last_i]); wr_ports[last_i] = NULL; log(" Active bits: "); - std::vector en_bits = sigmap(cell->get("\\EN")); + std::vector en_bits = sigmap(cell->getPort("\\EN")); active_bits_on_port.push_back(std::vector(en_bits.size())); for (int k = int(en_bits.size())-1; k >= 0; k--) log("%c", active_bits_on_port[i][k] ? '1' : '0'); @@ -498,7 +498,7 @@ struct MemoryShareWorker std::set considered_port_pairs; for (int i = 0; i < int(wr_ports.size()); i++) { - std::vector bits = modwalker.sigmap(wr_ports[i]->get("\\EN")); + std::vector bits = modwalker.sigmap(wr_ports[i]->getPort("\\EN")); for (auto bit : bits) if (bit == RTLIL::State::S1) goto port_is_always_active; @@ -518,12 +518,12 @@ struct MemoryShareWorker RTLIL::Cell *cell = wr_ports.at(i); if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable || - (cache_clk_enable && (sigmap(cell->get("\\CLK")) != cache_clk || + (cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk || cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity))) { cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool(); cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool(); - cache_clk = sigmap(cell->get("\\CLK")); + cache_clk = sigmap(cell->getPort("\\CLK")); } else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i)) considered_port_pairs.insert(i); @@ -551,7 +551,7 @@ struct MemoryShareWorker for (int i = 0; i < int(wr_ports.size()); i++) if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1)) { - RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->get("\\EN")); + RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort("\\EN")); port_to_sat_variable[i] = ez.expression(ez.OpOr, satgen.importSigSpec(sig)); std::vector bits = sig; @@ -594,18 +594,18 @@ struct MemoryShareWorker log(" Merging port %d into port %d.\n", i-1, i); port_to_sat_variable.at(i) = ez.OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i)); - RTLIL::SigSpec last_addr = wr_ports[i-1]->get("\\ADDR"); - RTLIL::SigSpec last_data = wr_ports[i-1]->get("\\DATA"); - std::vector last_en = modwalker.sigmap(wr_ports[i-1]->get("\\EN")); + RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort("\\ADDR"); + RTLIL::SigSpec last_data = wr_ports[i-1]->getPort("\\DATA"); + std::vector last_en = modwalker.sigmap(wr_ports[i-1]->getPort("\\EN")); - RTLIL::SigSpec this_addr = wr_ports[i]->get("\\ADDR"); - RTLIL::SigSpec this_data = wr_ports[i]->get("\\DATA"); - std::vector this_en = modwalker.sigmap(wr_ports[i]->get("\\EN")); + RTLIL::SigSpec this_addr = wr_ports[i]->getPort("\\ADDR"); + RTLIL::SigSpec this_data = wr_ports[i]->getPort("\\DATA"); + std::vector this_en = modwalker.sigmap(wr_ports[i]->getPort("\\EN")); RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en); - wr_ports[i]->set("\\ADDR", module->Mux(NEW_ID, last_addr, this_addr, this_en_active)); - wr_ports[i]->set("\\DATA", module->Mux(NEW_ID, last_data, this_data, this_en_active)); + wr_ports[i]->setPort("\\ADDR", module->Mux(NEW_ID, last_addr, this_addr, this_en_active)); + wr_ports[i]->setPort("\\DATA", module->Mux(NEW_ID, last_data, this_data, this_en_active)); std::map, int> groups_en; RTLIL::SigSpec grouped_last_en, grouped_this_en, en; @@ -623,7 +623,7 @@ struct MemoryShareWorker } module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en); - wr_ports[i]->set("\\EN", en); + wr_ports[i]->setPort("\\EN", en); module->remove(wr_ports[i-1]); wr_ports[i-1] = NULL; @@ -662,18 +662,18 @@ struct MemoryShareWorker if (cell->type == "$mux") { - RTLIL::SigSpec sig_a = sigmap_xmux(cell->get("\\A")); - RTLIL::SigSpec sig_b = sigmap_xmux(cell->get("\\B")); + RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort("\\B")); if (sig_a.is_fully_undef()) - sigmap_xmux.add(cell->get("\\Y"), sig_b); + sigmap_xmux.add(cell->getPort("\\Y"), sig_b); else if (sig_b.is_fully_undef()) - sigmap_xmux.add(cell->get("\\Y"), sig_a); + sigmap_xmux.add(cell->getPort("\\Y"), sig_a); } if (cell->type == "$mux" || cell->type == "$pmux") { - std::vector sig_y = sigmap(cell->get("\\Y")); + std::vector sig_y = sigmap(cell->getPort("\\Y")); for (int i = 0; i < int(sig_y.size()); i++) sig_to_mux[sig_y[i]] = std::pair(cell, i); } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 3f675ede..68e9a969 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -53,9 +53,9 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_ENABLE")).extract(i, 1).as_const(); cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const(); cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const(); - cell->set("\\CLK", memory->get("\\RD_CLK").extract(i, 1)); - cell->set("\\ADDR", memory->get("\\RD_ADDR").extract(i*abits, abits)); - cell->set("\\DATA", memory->get("\\RD_DATA").extract(i*mem->width, mem->width)); + cell->setPort("\\CLK", memory->getPort("\\RD_CLK").extract(i, 1)); + cell->setPort("\\ADDR", memory->getPort("\\RD_ADDR").extract(i*abits, abits)); + cell->setPort("\\DATA", memory->getPort("\\RD_DATA").extract(i*mem->width, mem->width)); } for (int i = 0; i < num_wr_ports; i++) @@ -67,10 +67,10 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_ENABLE")).extract(i, 1).as_const(); cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const(); cell->parameters["\\PRIORITY"] = i; - cell->set("\\CLK", memory->get("\\WR_CLK").extract(i, 1)); - cell->set("\\EN", memory->get("\\WR_EN").extract(i*mem->width, mem->width)); - cell->set("\\ADDR", memory->get("\\WR_ADDR").extract(i*abits, abits)); - cell->set("\\DATA", memory->get("\\WR_DATA").extract(i*mem->width, mem->width)); + cell->setPort("\\CLK", memory->getPort("\\WR_CLK").extract(i, 1)); + cell->setPort("\\EN", memory->getPort("\\WR_EN").extract(i*mem->width, mem->width)); + cell->setPort("\\ADDR", memory->getPort("\\WR_ADDR").extract(i*abits, abits)); + cell->setPort("\\DATA", memory->getPort("\\WR_DATA").extract(i*mem->width, mem->width)); } module->remove(memory); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 3e7487c3..5dab5eca 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -73,7 +73,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) static void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) { - RTLIL::SigSpec Y = cell->get(out_port); + RTLIL::SigSpec Y = cell->getPort(out_port); out_val.extend_u0(Y.size(), false); log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", @@ -89,14 +89,14 @@ static void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, bool extend_u0, SigMap &sigmap) { - std::string b_name = cell->has("\\B") ? "\\B" : "\\A"; + std::string b_name = cell->hasPort("\\B") ? "\\B" : "\\A"; bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool(); bool b_signed = cell->parameters.at(b_name + "_SIGNED").as_bool(); - RTLIL::SigSpec sig_a = sigmap(cell->get("\\A")); - RTLIL::SigSpec sig_b = sigmap(cell->get(b_name)); - RTLIL::SigSpec sig_y = sigmap(cell->get("\\Y")); + RTLIL::SigSpec sig_a = sigmap(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = sigmap(cell->getPort(b_name)); + RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y")); if (extend_u0) { sig_a.extend_u0(sig_y.size(), a_signed); @@ -161,17 +161,17 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::Cell *c = module->addCell(NEW_ID, cell->type); - c->set("\\A", new_a); + c->setPort("\\A", new_a); c->parameters["\\A_WIDTH"] = new_a.size(); c->parameters["\\A_SIGNED"] = false; if (b_name == "\\B") { - c->set("\\B", new_b); + c->setPort("\\B", new_b); c->parameters["\\B_WIDTH"] = new_b.size(); c->parameters["\\B_SIGNED"] = false; } - c->set("\\Y", new_y); + c->setPort("\\Y", new_y); c->parameters["\\Y_WIDTH"] = new_y->width; c->check(); @@ -210,8 +210,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (auto cell : module->cells()) if (design->selected(module, cell) && cell->type[0] == '$') { if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && - cell->get("\\A").size() == 1 && cell->get("\\Y").size() == 1) - invert_map[assign_map(cell->get("\\Y"))] = assign_map(cell->get("\\A")); + cell->getPort("\\A").size() == 1 && cell->getPort("\\Y").size() == 1) + invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\A")); if (ct_combinational.cell_known(cell->type)) for (auto &conn : cell->connections()) { RTLIL::SigSpec sig = assign_map(conn.second); @@ -246,7 +246,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$reduce_and") { - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); RTLIL::State new_a = RTLIL::State::S1; for (auto &bit : sig_a.to_sigbit_vector()) @@ -264,7 +264,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover("opt.opt_const.fine.$reduce_and"); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->set("\\A", sig_a = new_a); + cell->setPort("\\A", sig_a = new_a); cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -273,7 +273,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$logic_not" || cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") { - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); RTLIL::State new_a = RTLIL::State::S0; for (auto &bit : sig_a.to_sigbit_vector()) @@ -291,7 +291,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); - cell->set("\\A", sig_a = new_a); + cell->setPort("\\A", sig_a = new_a); cell->parameters.at("\\A_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -300,7 +300,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$logic_and" || cell->type == "$logic_or") { - RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); RTLIL::State new_b = RTLIL::State::S0; for (auto &bit : sig_b.to_sigbit_vector()) @@ -318,7 +318,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cover_list("opt.opt_const.fine.B", "$logic_and", "$logic_or", cell->type); log("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); - cell->set("\\B", sig_b = new_b); + cell->setPort("\\B", sig_b = new_b); cell->parameters.at("\\B_WIDTH") = 1; OPT_DID_SOMETHING = true; did_something = true; @@ -326,13 +326,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } } - if (cell->type == "$logic_or" && (assign_map(cell->get("\\A")) == RTLIL::State::S1 || assign_map(cell->get("\\B")) == RTLIL::State::S1)) { + if (cell->type == "$logic_or" && (assign_map(cell->getPort("\\A")) == RTLIL::State::S1 || assign_map(cell->getPort("\\B")) == RTLIL::State::S1)) { cover("opt.opt_const.one_high"); replace_cell(assign_map, module, cell, "one high", "\\Y", RTLIL::State::S1); goto next_cell; } - if (cell->type == "$logic_and" && (assign_map(cell->get("\\A")) == RTLIL::State::S0 || assign_map(cell->get("\\B")) == RTLIL::State::S0)) { + if (cell->type == "$logic_and" && (assign_map(cell->getPort("\\A")) == RTLIL::State::S0 || assign_map(cell->getPort("\\B")) == RTLIL::State::S0)) { cover("opt.opt_const.one_low"); replace_cell(assign_map, module, cell, "one low", "\\Y", RTLIL::State::S0); goto next_cell; @@ -344,8 +344,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || cell->type == "$pow") { - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); - RTLIL::SigSpec sig_b = cell->has("\\B") ? assign_map(cell->get("\\B")) : RTLIL::SigSpec(); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = cell->hasPort("\\B") ? assign_map(cell->getPort("\\B")) : RTLIL::SigSpec(); if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") sig_a = RTLIL::SigSpec(); @@ -366,31 +366,31 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); else - replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->get("\\Y").size())); + replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort("\\Y").size())); goto next_cell; } } - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->get("\\Y").size() == 1 && - invert_map.count(assign_map(cell->get("\\A"))) != 0) { + if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->getPort("\\Y").size() == 1 && + invert_map.count(assign_map(cell->getPort("\\A"))) != 0) { cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); - replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->get("\\A")))); + replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->getPort("\\A")))); goto next_cell; } - if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->get("\\S"))) != 0) { + if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->getPort("\\S"))) != 0) { cover_list("opt.opt_const.invert.muxsel", "$_MUX_", "$mux", cell->type); - RTLIL::SigSpec tmp = cell->get("\\A"); - cell->set("\\A", cell->get("\\B")); - cell->set("\\B", tmp); - cell->set("\\S", invert_map.at(assign_map(cell->get("\\S")))); + RTLIL::SigSpec tmp = cell->getPort("\\A"); + cell->setPort("\\A", cell->getPort("\\B")); + cell->setPort("\\B", tmp); + cell->setPort("\\S", invert_map.at(assign_map(cell->getPort("\\S")))); OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } if (cell->type == "$_INV_") { - RTLIL::SigSpec input = cell->get("\\A"); + RTLIL::SigSpec input = cell->getPort("\\A"); assign_map.apply(input); if (input.match("1")) ACTION_DO_Y(0); if (input.match("0")) ACTION_DO_Y(1); @@ -399,8 +399,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_AND_") { RTLIL::SigSpec input; - input.append(cell->get("\\B")); - input.append(cell->get("\\A")); + input.append(cell->getPort("\\B")); + input.append(cell->getPort("\\A")); assign_map.apply(input); if (input.match(" 0")) ACTION_DO_Y(0); if (input.match("0 ")) ACTION_DO_Y(0); @@ -418,8 +418,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_OR_") { RTLIL::SigSpec input; - input.append(cell->get("\\B")); - input.append(cell->get("\\A")); + input.append(cell->getPort("\\B")); + input.append(cell->getPort("\\A")); assign_map.apply(input); if (input.match(" 1")) ACTION_DO_Y(1); if (input.match("1 ")) ACTION_DO_Y(1); @@ -437,8 +437,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_XOR_") { RTLIL::SigSpec input; - input.append(cell->get("\\B")); - input.append(cell->get("\\A")); + input.append(cell->getPort("\\B")); + input.append(cell->getPort("\\A")); assign_map.apply(input); if (input.match("00")) ACTION_DO_Y(0); if (input.match("01")) ACTION_DO_Y(1); @@ -452,9 +452,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$_MUX_") { RTLIL::SigSpec input; - input.append(cell->get("\\S")); - input.append(cell->get("\\B")); - input.append(cell->get("\\A")); + input.append(cell->getPort("\\S")); + input.append(cell->getPort("\\B")); + input.append(cell->getPort("\\A")); assign_map.apply(input); if (input.extract(2, 1) == input.extract(1, 1)) ACTION_DO("\\Y", input.extract(2, 1)); @@ -464,9 +464,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (input.match("10 ")) { cover("opt.opt_const.mux_to_inv"); cell->type = "$_INV_"; - cell->set("\\A", input.extract(0, 1)); - cell->unset("\\B"); - cell->unset("\\S"); + cell->setPort("\\A", input.extract(0, 1)); + cell->unsetPort("\\B"); + cell->unsetPort("\\S"); goto next_cell; } if (input.match("11 ")) ACTION_DO_Y(1); @@ -483,8 +483,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex") { - RTLIL::SigSpec a = cell->get("\\A"); - RTLIL::SigSpec b = cell->get("\\B"); + RTLIL::SigSpec a = cell->getPort("\\A"); + RTLIL::SigSpec b = cell->getPort("\\B"); if (cell->parameters["\\A_WIDTH"].as_int() != cell->parameters["\\B_WIDTH"].as_int()) { int width = std::max(cell->parameters["\\A_WIDTH"].as_int(), cell->parameters["\\B_WIDTH"].as_int()); @@ -519,8 +519,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (new_a.size() < a.size() || new_b.size() < b.size()) { cover_list("opt.opt_const.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type); - cell->set("\\A", new_a); - cell->set("\\B", new_b); + cell->setPort("\\A", new_a); + cell->setPort("\\B", new_b); cell->parameters["\\A_WIDTH"] = new_a.size(); cell->parameters["\\B_WIDTH"] = new_b.size(); } @@ -529,26 +529,26 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->type == "$eq" || cell->type == "$ne") && cell->parameters["\\Y_WIDTH"].as_int() == 1 && cell->parameters["\\A_WIDTH"].as_int() == 1 && cell->parameters["\\B_WIDTH"].as_int() == 1) { - RTLIL::SigSpec a = assign_map(cell->get("\\A")); - RTLIL::SigSpec b = assign_map(cell->get("\\B")); + RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); if (a.is_fully_const()) { cover_list("opt.opt_const.eqneq.swapconst", "$eq", "$ne", cell->type); - RTLIL::SigSpec tmp = cell->get("\\A"); - cell->set("\\A", cell->get("\\B")); - cell->set("\\B", tmp); + RTLIL::SigSpec tmp = cell->getPort("\\A"); + cell->setPort("\\A", cell->getPort("\\B")); + cell->setPort("\\B", tmp); } if (b.is_fully_const()) { if (b.as_bool() == (cell->type == "$eq")) { RTLIL::SigSpec input = b; - ACTION_DO("\\Y", cell->get("\\A")); + ACTION_DO("\\Y", cell->getPort("\\A")); } else { cover_list("opt.opt_const.eqneq.isnot", "$eq", "$ne", cell->type); cell->type = "$not"; cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); - cell->unset("\\B"); + cell->unsetPort("\\B"); } goto next_cell; } @@ -562,8 +562,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$or" || cell->type == "$xor") { - RTLIL::SigSpec a = assign_map(cell->get("\\A")); - RTLIL::SigSpec b = assign_map(cell->get("\\B")); + RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); if (cell->type != "$sub" && a.is_fully_const() && a.as_bool() == false) identity_wrt_b = true; @@ -574,7 +574,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") { - RTLIL::SigSpec b = assign_map(cell->get("\\B")); + RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); if (b.is_fully_const() && b.as_bool() == false) identity_wrt_a = true, identity_bu0 = true; @@ -582,8 +582,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$mul") { - RTLIL::SigSpec a = assign_map(cell->get("\\A")); - RTLIL::SigSpec b = assign_map(cell->get("\\B")); + RTLIL::SigSpec a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); if (a.is_fully_const() && a.size() <= 32 && a.as_int() == 1) identity_wrt_b = true; @@ -594,7 +594,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (cell->type == "$div") { - RTLIL::SigSpec b = assign_map(cell->get("\\B")); + RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); if (b.is_fully_const() && b.size() <= 32 && b.as_int() == 1) identity_wrt_a = true; @@ -611,13 +611,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); if (!identity_wrt_a) { - cell->set("\\A", cell->get("\\B")); + cell->setPort("\\A", cell->getPort("\\B")); cell->parameters.at("\\A_WIDTH") = cell->parameters.at("\\B_WIDTH"); cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); } cell->type = identity_bu0 ? "$bu0" : "$pos"; - cell->unset("\\B"); + cell->unsetPort("\\B"); cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); cell->check(); @@ -629,18 +629,18 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->get("\\A") == RTLIL::SigSpec(0, 1) && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { + cell->getPort("\\A") == RTLIL::SigSpec(0, 1) && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); - replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->get("\\S")); + replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->getPort("\\S")); goto next_cell; } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && - cell->get("\\A") == RTLIL::SigSpec(1, 1) && cell->get("\\B") == RTLIL::SigSpec(0, 1)) { + cell->getPort("\\A") == RTLIL::SigSpec(1, 1) && cell->getPort("\\B") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type); - cell->set("\\A", cell->get("\\S")); - cell->unset("\\B"); - cell->unset("\\S"); + cell->setPort("\\A", cell->getPort("\\S")); + cell->unsetPort("\\B"); + cell->unsetPort("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\Y_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -654,10 +654,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->get("\\A") == RTLIL::SigSpec(0, 1)) { + if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type); - cell->set("\\A", cell->get("\\S")); - cell->unset("\\S"); + cell->setPort("\\A", cell->getPort("\\S")); + cell->unsetPort("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -673,10 +673,10 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->get("\\B") == RTLIL::SigSpec(1, 1)) { + if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type); - cell->set("\\B", cell->get("\\S")); - cell->unset("\\S"); + cell->setPort("\\B", cell->getPort("\\S")); + cell->unsetPort("\\S"); if (cell->type == "$mux") { cell->parameters["\\A_WIDTH"] = cell->parameters["\\WIDTH"]; cell->parameters["\\B_WIDTH"] = cell->parameters["\\WIDTH"]; @@ -694,22 +694,22 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_undef && (cell->type == "$mux" || cell->type == "$pmux")) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->get("\\A").size(); - if ((cell->get("\\A").is_fully_undef() && cell->get("\\B").is_fully_undef()) || - cell->get("\\S").is_fully_undef()) { + int width = cell->getPort("\\A").size(); + if ((cell->getPort("\\A").is_fully_undef() && cell->getPort("\\B").is_fully_undef()) || + cell->getPort("\\S").is_fully_undef()) { cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); - replace_cell(assign_map, module, cell, "mux_undef", "\\Y", cell->get("\\A")); + replace_cell(assign_map, module, cell, "mux_undef", "\\Y", cell->getPort("\\A")); goto next_cell; } - for (int i = 0; i < cell->get("\\S").size(); i++) { - RTLIL::SigSpec old_b = cell->get("\\B").extract(i*width, width); - RTLIL::SigSpec old_s = cell->get("\\S").extract(i, 1); + for (int i = 0; i < cell->getPort("\\S").size(); i++) { + RTLIL::SigSpec old_b = cell->getPort("\\B").extract(i*width, width); + RTLIL::SigSpec old_s = cell->getPort("\\S").extract(i, 1); if (old_b.is_fully_undef() || old_s.is_fully_undef()) continue; new_b.append(old_b); new_s.append(old_s); } - new_a = cell->get("\\A"); + new_a = cell->getPort("\\A"); if (new_a.is_fully_undef() && new_s.size() > 0) { new_a = new_b.extract((new_s.size()-1)*width, width); new_b = new_b.extract(0, (new_s.size()-1)*width); @@ -725,11 +725,11 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo replace_cell(assign_map, module, cell, "mux_sel01", "\\Y", new_s); goto next_cell; } - if (cell->get("\\S").size() != new_s.size()) { + if (cell->getPort("\\S").size() != new_s.size()) { cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type); - cell->set("\\A", new_a); - cell->set("\\B", new_b); - cell->set("\\S", new_s); + cell->setPort("\\A", new_a); + cell->setPort("\\B", new_b); + cell->setPort("\\S", new_s); if (new_s.size() > 1) { cell->type = "$pmux"; cell->parameters["\\S_WIDTH"] = new_s.size(); @@ -744,7 +744,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo #define FOLD_1ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->get("\\A"); \ + RTLIL::SigSpec a = cell->getPort("\\A"); \ assign_map.apply(a); \ if (a.is_fully_const()) { \ RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \ @@ -758,8 +758,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } #define FOLD_2ARG_CELL(_t) \ if (cell->type == "$" #_t) { \ - RTLIL::SigSpec a = cell->get("\\A"); \ - RTLIL::SigSpec b = cell->get("\\B"); \ + RTLIL::SigSpec a = cell->getPort("\\A"); \ + RTLIL::SigSpec b = cell->getPort("\\B"); \ assign_map.apply(a), assign_map.apply(b); \ if (a.is_fully_const() && b.is_fully_const()) { \ RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \ @@ -815,13 +815,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo // be very conservative with optimizing $mux cells as we do not want to break mux trees if (cell->type == "$mux") { - RTLIL::SigSpec input = assign_map(cell->get("\\S")); - RTLIL::SigSpec inA = assign_map(cell->get("\\A")); - RTLIL::SigSpec inB = assign_map(cell->get("\\B")); + RTLIL::SigSpec input = assign_map(cell->getPort("\\S")); + RTLIL::SigSpec inA = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec inB = assign_map(cell->getPort("\\B")); if (input.is_fully_const()) - ACTION_DO("\\Y", input.as_bool() ? cell->get("\\B") : cell->get("\\A")); + ACTION_DO("\\Y", input.as_bool() ? cell->getPort("\\B") : cell->getPort("\\A")); else if (inA == inB) - ACTION_DO("\\Y", cell->get("\\A")); + ACTION_DO("\\Y", cell->getPort("\\A")); } if (!keepdc && cell->type == "$mul") @@ -830,9 +830,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo bool b_signed = cell->parameters["\\B_SIGNED"].as_bool(); bool swapped_ab = false; - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); - RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); - RTLIL::SigSpec sig_y = assign_map(cell->get("\\Y")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y")); if (sig_b.is_fully_const() && sig_b.size() <= 32) std::swap(sig_a, sig_b), std::swap(a_signed, b_signed), swapped_ab = true; @@ -868,7 +868,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo a_val, cell->name.c_str(), module->name.c_str(), i); if (!swapped_ab) { - cell->set("\\A", cell->get("\\B")); + cell->setPort("\\A", cell->getPort("\\B")); cell->parameters["\\A_WIDTH"] = cell->parameters["\\B_WIDTH"]; cell->parameters["\\A_SIGNED"] = cell->parameters["\\B_SIGNED"]; } @@ -881,7 +881,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$shl"; cell->parameters["\\B_WIDTH"] = SIZE(new_b); cell->parameters["\\B_SIGNED"] = false; - cell->set("\\B", new_b); + cell->setPort("\\B", new_b); cell->check(); OPT_DID_SOMETHING = true; diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index de12542d..2660b33d 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -86,10 +86,10 @@ struct OptMuxtreeWorker { if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_b = cell->get("\\B"); - RTLIL::SigSpec sig_s = cell->get("\\S"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_s = cell->getPort("\\S"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); muxinfo_t muxinfo; muxinfo.cell = cell; @@ -192,10 +192,10 @@ struct OptMuxtreeWorker continue; } - RTLIL::SigSpec sig_a = mi.cell->get("\\A"); - RTLIL::SigSpec sig_b = mi.cell->get("\\B"); - RTLIL::SigSpec sig_s = mi.cell->get("\\S"); - RTLIL::SigSpec sig_y = mi.cell->get("\\Y"); + RTLIL::SigSpec sig_a = mi.cell->getPort("\\A"); + RTLIL::SigSpec sig_b = mi.cell->getPort("\\B"); + RTLIL::SigSpec sig_s = mi.cell->getPort("\\S"); + RTLIL::SigSpec sig_y = mi.cell->getPort("\\Y"); RTLIL::SigSpec sig_ports = sig_b; sig_ports.append(sig_a); @@ -220,9 +220,9 @@ struct OptMuxtreeWorker } } - mi.cell->set("\\A", new_sig_a); - mi.cell->set("\\B", new_sig_b); - mi.cell->set("\\S", new_sig_s); + mi.cell->setPort("\\A", new_sig_a); + mi.cell->setPort("\\B", new_sig_b); + mi.cell->setPort("\\S", new_sig_s); if (new_sig_s.size() == 1) { mi.cell->type = "$mux"; mi.cell->parameters.erase("\\S_WIDTH"); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 8aadd1f2..80ec8974 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -42,7 +42,7 @@ struct OptReduceWorker return; cells.erase(cell); - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); std::set new_sig_a_bits; for (auto &bit : sig_a.to_sigbit_set()) @@ -72,8 +72,8 @@ struct OptReduceWorker for (auto child_cell : drivers.find(bit)) { if (child_cell->type == cell->type) { opt_reduce(cells, drivers, child_cell); - if (child_cell->get("\\Y")[0] == bit) { - std::set child_sig_a_bits = assign_map(child_cell->get("\\A")).to_sigbit_set(); + if (child_cell->getPort("\\Y")[0] == bit) { + std::set child_sig_a_bits = assign_map(child_cell->getPort("\\A")).to_sigbit_set(); new_sig_a_bits.insert(child_sig_a_bits.begin(), child_sig_a_bits.end()); } else new_sig_a_bits.insert(RTLIL::State::S0); @@ -86,23 +86,23 @@ struct OptReduceWorker RTLIL::SigSpec new_sig_a(new_sig_a_bits); - if (new_sig_a != sig_a || sig_a.size() != cell->get("\\A").size()) { + if (new_sig_a != sig_a || sig_a.size() != cell->getPort("\\A").size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; OPT_DID_SOMETHING = true; total_count++; } - cell->set("\\A", new_sig_a); + cell->setPort("\\A", new_sig_a); cell->parameters["\\A_WIDTH"] = RTLIL::Const(new_sig_a.size()); return; } void opt_mux(RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); - RTLIL::SigSpec sig_b = assign_map(cell->get("\\B")); - RTLIL::SigSpec sig_s = assign_map(cell->get("\\S")); + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); + RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S")); RTLIL::SigSpec new_sig_b, new_sig_s; std::set handled_sig; @@ -124,14 +124,14 @@ struct OptReduceWorker if (this_s.size() > 1) { RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, "$reduce_or"); - reduce_or_cell->set("\\A", this_s); + reduce_or_cell->setPort("\\A", this_s); reduce_or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); reduce_or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(this_s.size()); reduce_or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID); this_s = RTLIL::SigSpec(reduce_or_wire); - reduce_or_cell->set("\\Y", this_s); + reduce_or_cell->setPort("\\Y", this_s); } new_sig_b.append(this_b); @@ -148,14 +148,14 @@ struct OptReduceWorker if (new_sig_s.size() == 0) { - module->connect(RTLIL::SigSig(cell->get("\\Y"), cell->get("\\A"))); - assign_map.add(cell->get("\\Y"), cell->get("\\A")); + module->connect(RTLIL::SigSig(cell->getPort("\\Y"), cell->getPort("\\A"))); + assign_map.add(cell->getPort("\\Y"), cell->getPort("\\A")); module->remove(cell); } else { - cell->set("\\B", new_sig_b); - cell->set("\\S", new_sig_s); + cell->setPort("\\B", new_sig_b); + cell->setPort("\\S", new_sig_s); if (new_sig_s.size() > 1) { cell->parameters["\\S_WIDTH"] = RTLIL::Const(new_sig_s.size()); } else { @@ -167,9 +167,9 @@ struct OptReduceWorker void opt_mux_bits(RTLIL::Cell *cell) { - std::vector sig_a = assign_map(cell->get("\\A")).to_sigbit_vector(); - std::vector sig_b = assign_map(cell->get("\\B")).to_sigbit_vector(); - std::vector sig_y = assign_map(cell->get("\\Y")).to_sigbit_vector(); + std::vector sig_a = assign_map(cell->getPort("\\A")).to_sigbit_vector(); + std::vector sig_b = assign_map(cell->getPort("\\B")).to_sigbit_vector(); + std::vector sig_y = assign_map(cell->getPort("\\Y")).to_sigbit_vector(); std::vector new_sig_y; RTLIL::SigSig old_sig_conn; @@ -210,29 +210,29 @@ struct OptReduceWorker if (new_sig_y.size() != sig_y.size()) { log(" Consolidated identical input bits for %s cell %s:\n", cell->type.c_str(), cell->name.c_str()); - log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->get("\\A")), - log_signal(cell->get("\\B")), log_signal(cell->get("\\Y"))); + log(" Old ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")), + log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y"))); - cell->set("\\A", RTLIL::SigSpec()); + cell->setPort("\\A", RTLIL::SigSpec()); for (auto &in_tuple : consolidated_in_tuples) { - RTLIL::SigSpec new_a = cell->get("\\A"); + RTLIL::SigSpec new_a = cell->getPort("\\A"); new_a.append(in_tuple.at(0)); - cell->set("\\A", new_a); + cell->setPort("\\A", new_a); } - cell->set("\\B", RTLIL::SigSpec()); - for (int i = 1; i <= cell->get("\\S").size(); i++) + cell->setPort("\\B", RTLIL::SigSpec()); + for (int i = 1; i <= cell->getPort("\\S").size(); i++) for (auto &in_tuple : consolidated_in_tuples) { - RTLIL::SigSpec new_b = cell->get("\\B"); + RTLIL::SigSpec new_b = cell->getPort("\\B"); new_b.append(in_tuple.at(i)); - cell->set("\\B", new_b); + cell->setPort("\\B", new_b); } cell->parameters["\\WIDTH"] = RTLIL::Const(new_sig_y.size()); - cell->set("\\Y", new_sig_y); + cell->setPort("\\Y", new_sig_y); - log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->get("\\A")), - log_signal(cell->get("\\B")), log_signal(cell->get("\\Y"))); + log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort("\\A")), + log_signal(cell->getPort("\\B")), log_signal(cell->getPort("\\Y"))); log(" New connections: %s = %s\n", log_signal(old_sig_conn.first), log_signal(old_sig_conn.second)); module->connect(old_sig_conn); @@ -256,14 +256,14 @@ struct OptReduceWorker for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; if (cell->type == "$mem") - mem_wren_sigs.add(assign_map(cell->get("\\WR_EN"))); + mem_wren_sigs.add(assign_map(cell->getPort("\\WR_EN"))); if (cell->type == "$memwr") - mem_wren_sigs.add(assign_map(cell->get("\\EN"))); + mem_wren_sigs.add(assign_map(cell->getPort("\\EN"))); } for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->get("\\Q")))) - mem_wren_sigs.add(assign_map(cell->get("\\D"))); + if (cell->type == "$dff" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Q")))) + mem_wren_sigs.add(assign_map(cell->getPort("\\D"))); } bool keep_expanding_mem_wren_sigs = true; @@ -271,12 +271,12 @@ struct OptReduceWorker keep_expanding_mem_wren_sigs = false; for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->get("\\Y")))) { - if (!mem_wren_sigs.check_all(assign_map(cell->get("\\A"))) || - !mem_wren_sigs.check_all(assign_map(cell->get("\\B")))) + if (cell->type == "$mux" && mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y")))) { + if (!mem_wren_sigs.check_all(assign_map(cell->getPort("\\A"))) || + !mem_wren_sigs.check_all(assign_map(cell->getPort("\\B")))) keep_expanding_mem_wren_sigs = true; - mem_wren_sigs.add(assign_map(cell->get("\\A"))); - mem_wren_sigs.add(assign_map(cell->get("\\B"))); + mem_wren_sigs.add(assign_map(cell->getPort("\\A"))); + mem_wren_sigs.add(assign_map(cell->getPort("\\B"))); } } } @@ -298,7 +298,7 @@ struct OptReduceWorker RTLIL::Cell *cell = cell_it.second; if (cell->type != type || !design->selected(module, cell)) continue; - drivers.insert(assign_map(cell->get("\\Y")), cell); + drivers.insert(assign_map(cell->getPort("\\Y")), cell); cells.insert(cell); } @@ -320,7 +320,7 @@ struct OptReduceWorker { // this optimization is to aggressive for most coarse-grain applications. // but we always want it for multiplexers driving write enable ports. - if (do_fine || mem_wren_sigs.check_any(assign_map(cell->get("\\Y")))) + if (do_fine || mem_wren_sigs.check_any(assign_map(cell->getPort("\\Y")))) opt_mux_bits(cell); opt_mux(cell); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index b01778b5..c1e33caf 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -33,34 +33,34 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) RTLIL::Const val_cp, val_rp, val_rv; if (dff->type == "$_DFF_N_" || dff->type == "$_DFF_P_") { - sig_d = dff->get("\\D"); - sig_q = dff->get("\\Q"); - sig_c = dff->get("\\C"); + sig_d = dff->getPort("\\D"); + sig_q = dff->getPort("\\Q"); + sig_c = dff->getPort("\\C"); val_cp = RTLIL::Const(dff->type == "$_DFF_P_", 1); } else if (dff->type.substr(0,6) == "$_DFF_" && dff->type.substr(9) == "_" && (dff->type[6] == 'N' || dff->type[6] == 'P') && (dff->type[7] == 'N' || dff->type[7] == 'P') && (dff->type[8] == '0' || dff->type[8] == '1')) { - sig_d = dff->get("\\D"); - sig_q = dff->get("\\Q"); - sig_c = dff->get("\\C"); - sig_r = dff->get("\\R"); + sig_d = dff->getPort("\\D"); + sig_q = dff->getPort("\\Q"); + sig_c = dff->getPort("\\C"); + sig_r = dff->getPort("\\R"); val_cp = RTLIL::Const(dff->type[6] == 'P', 1); val_rp = RTLIL::Const(dff->type[7] == 'P', 1); val_rv = RTLIL::Const(dff->type[8] == '1', 1); } else if (dff->type == "$dff") { - sig_d = dff->get("\\D"); - sig_q = dff->get("\\Q"); - sig_c = dff->get("\\CLK"); + sig_d = dff->getPort("\\D"); + sig_q = dff->getPort("\\Q"); + sig_c = dff->getPort("\\CLK"); val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); } else if (dff->type == "$adff") { - sig_d = dff->get("\\D"); - sig_q = dff->get("\\Q"); - sig_c = dff->get("\\CLK"); - sig_r = dff->get("\\ARST"); + sig_d = dff->getPort("\\D"); + sig_q = dff->getPort("\\Q"); + sig_c = dff->getPort("\\CLK"); + sig_r = dff->getPort("\\ARST"); val_cp = RTLIL::Const(dff->parameters["\\CLK_POLARITY"].as_bool(), 1); val_rp = RTLIL::Const(dff->parameters["\\ARST_POLARITY"].as_bool(), 1); val_rv = dff->parameters["\\ARST_VALUE"]; @@ -85,8 +85,8 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) std::set muxes; mux_drivers.find(sig_d, muxes); for (auto mux : muxes) { - RTLIL::SigSpec sig_a = assign_map(mux->get("\\A")); - RTLIL::SigSpec sig_b = assign_map(mux->get("\\B")); + RTLIL::SigSpec sig_a = assign_map(mux->getPort("\\A")); + RTLIL::SigSpec sig_b = assign_map(mux->getPort("\\B")); if (sig_a == sig_q && sig_b.is_fully_const()) { RTLIL::SigSig conn(sig_q, sig_b); mod->connect(conn); @@ -181,8 +181,8 @@ struct OptRmdffPass : public Pass { std::vector dff_list; for (auto &it : mod_it.second->cells_) { if (it.second->type == "$mux" || it.second->type == "$pmux") { - if (it.second->get("\\A").size() == it.second->get("\\B").size()) - mux_drivers.insert(assign_map(it.second->get("\\Y")), it.second); + if (it.second->getPort("\\A").size() == it.second->getPort("\\B").size()) + mux_drivers.insert(assign_map(it.second->getPort("\\Y")), it.second); continue; } if (!design->selected(mod_it.second, it.second)) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index ad6e1a74..26d19414 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -179,8 +179,8 @@ struct OptShareWorker } if (cell1->type.substr(0, 1) == "$" && conn1.count("\\Q") != 0) { - std::vector q1 = dff_init_map(cell1->get("\\Q")).to_sigbit_vector(); - std::vector q2 = dff_init_map(cell2->get("\\Q")).to_sigbit_vector(); + std::vector q1 = dff_init_map(cell1->getPort("\\Q")).to_sigbit_vector(); + std::vector q2 = dff_init_map(cell2->getPort("\\Q")).to_sigbit_vector(); for (size_t i = 0; i < q1.size(); i++) if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { lt = q1.at(i) < q2.at(i); @@ -262,7 +262,7 @@ struct OptShareWorker log(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str()); for (auto &it : cell->connections()) { if (ct.cell_output(cell->type, it.first)) { - RTLIL::SigSpec other_sig = sharemap[cell]->get(it.first); + RTLIL::SigSpec other_sig = sharemap[cell]->getPort(it.first); log(" Redirecting output %s: %s = %s\n", it.first.c_str(), log_signal(it.second), log_signal(other_sig)); module->connect(RTLIL::SigSig(it.second, other_sig)); diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 676469fe..f11b328f 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -35,45 +35,45 @@ static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSp for (auto cell : mod->cells()) { - if (cell->type == "$reduce_or" && cell->get("\\Y") == signal) - return check_signal(mod, cell->get("\\A"), ref, polarity); + if (cell->type == "$reduce_or" && cell->getPort("\\Y") == signal) + return check_signal(mod, cell->getPort("\\A"), ref, polarity); - if (cell->type == "$reduce_bool" && cell->get("\\Y") == signal) - return check_signal(mod, cell->get("\\A"), ref, polarity); + if (cell->type == "$reduce_bool" && cell->getPort("\\Y") == signal) + return check_signal(mod, cell->getPort("\\A"), ref, polarity); - if (cell->type == "$logic_not" && cell->get("\\Y") == signal) { + if (cell->type == "$logic_not" && cell->getPort("\\Y") == signal) { polarity = !polarity; - return check_signal(mod, cell->get("\\A"), ref, polarity); + return check_signal(mod, cell->getPort("\\A"), ref, polarity); } - if (cell->type == "$not" && cell->get("\\Y") == signal) { + if (cell->type == "$not" && cell->getPort("\\Y") == signal) { polarity = !polarity; - return check_signal(mod, cell->get("\\A"), ref, polarity); + return check_signal(mod, cell->getPort("\\A"), ref, polarity); } - if ((cell->type == "$eq" || cell->type == "$eqx") && cell->get("\\Y") == signal) { - if (cell->get("\\A").is_fully_const()) { - if (!cell->get("\\A").as_bool()) + if ((cell->type == "$eq" || cell->type == "$eqx") && cell->getPort("\\Y") == signal) { + if (cell->getPort("\\A").is_fully_const()) { + if (!cell->getPort("\\A").as_bool()) polarity = !polarity; - return check_signal(mod, cell->get("\\B"), ref, polarity); + return check_signal(mod, cell->getPort("\\B"), ref, polarity); } - if (cell->get("\\B").is_fully_const()) { - if (!cell->get("\\B").as_bool()) + if (cell->getPort("\\B").is_fully_const()) { + if (!cell->getPort("\\B").as_bool()) polarity = !polarity; - return check_signal(mod, cell->get("\\A"), ref, polarity); + return check_signal(mod, cell->getPort("\\A"), ref, polarity); } } - if ((cell->type == "$ne" || cell->type == "$nex") && cell->get("\\Y") == signal) { - if (cell->get("\\A").is_fully_const()) { - if (cell->get("\\A").as_bool()) + if ((cell->type == "$ne" || cell->type == "$nex") && cell->getPort("\\Y") == signal) { + if (cell->getPort("\\A").is_fully_const()) { + if (cell->getPort("\\A").as_bool()) polarity = !polarity; - return check_signal(mod, cell->get("\\B"), ref, polarity); + return check_signal(mod, cell->getPort("\\B"), ref, polarity); } - if (cell->get("\\B").is_fully_const()) { - if (cell->get("\\B").as_bool()) + if (cell->getPort("\\B").is_fully_const()) { + if (cell->getPort("\\B").as_bool()) polarity = !polarity; - return check_signal(mod, cell->get("\\A"), ref, polarity); + return check_signal(mod, cell->getPort("\\A"), ref, polarity); } } } diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index d894b442..e69e8023 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -76,8 +76,8 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->set("\\A", sync_low_signals); - cell->set("\\Y", sync_low_signals = mod->addWire(NEW_ID)); + cell->setPort("\\A", sync_low_signals); + cell->setPort("\\Y", sync_low_signals = mod->addWire(NEW_ID)); } if (sync_low_signals.size() > 0) { @@ -85,9 +85,9 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->set("\\A", sync_low_signals); - cell->set("\\Y", mod->addWire(NEW_ID)); - sync_high_signals.append(cell->get("\\Y")); + cell->setPort("\\A", sync_low_signals); + cell->setPort("\\Y", mod->addWire(NEW_ID)); + sync_high_signals.append(cell->getPort("\\Y")); } if (sync_high_signals.size() > 1) { @@ -95,30 +95,30 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->set("\\A", sync_high_signals); - cell->set("\\Y", sync_high_signals = mod->addWire(NEW_ID)); + cell->setPort("\\A", sync_high_signals); + cell->setPort("\\Y", sync_high_signals = mod->addWire(NEW_ID)); } RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, "$not"); inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size()); inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size()); - inv_cell->set("\\A", sync_value); - inv_cell->set("\\Y", sync_value_inv = mod->addWire(NEW_ID, sig_d.size())); + inv_cell->setPort("\\A", sync_value); + inv_cell->setPort("\\Y", sync_value_inv = mod->addWire(NEW_ID, sig_d.size())); RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, "$mux"); mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); - mux_set_cell->set("\\A", sig_sr_set); - mux_set_cell->set("\\B", sync_value); - mux_set_cell->set("\\S", sync_high_signals); - mux_set_cell->set("\\Y", sig_sr_set = mod->addWire(NEW_ID, sig_d.size())); + mux_set_cell->setPort("\\A", sig_sr_set); + mux_set_cell->setPort("\\B", sync_value); + mux_set_cell->setPort("\\S", sync_high_signals); + mux_set_cell->setPort("\\Y", sig_sr_set = mod->addWire(NEW_ID, sig_d.size())); RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, "$mux"); mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size()); - mux_clr_cell->set("\\A", sig_sr_clr); - mux_clr_cell->set("\\B", sync_value_inv); - mux_clr_cell->set("\\S", sync_high_signals); - mux_clr_cell->set("\\Y", sig_sr_clr = mod->addWire(NEW_ID, sig_d.size())); + mux_clr_cell->setPort("\\A", sig_sr_clr); + mux_clr_cell->setPort("\\B", sync_value_inv); + mux_clr_cell->setPort("\\S", sync_high_signals); + mux_clr_cell->setPort("\\Y", sig_sr_clr = mod->addWire(NEW_ID, sig_d.size())); } std::stringstream sstr; @@ -130,11 +130,11 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); - cell->set("\\D", sig_d); - cell->set("\\Q", sig_q); - cell->set("\\CLK", clk); - cell->set("\\SET", sig_sr_set); - cell->set("\\CLR", sig_sr_clr); + cell->setPort("\\D", sig_d); + cell->setPort("\\Q", sig_q); + cell->setPort("\\CLK", clk); + cell->setPort("\\SET", sig_sr_set); + cell->setPort("\\CLR", sig_sr_clr); log(" created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); @@ -154,22 +154,22 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0); inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size()); inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size()); - inv_set->set("\\A", sig_set); - inv_set->set("\\Y", sig_set_inv); + inv_set->setPort("\\A", sig_set); + inv_set->setPort("\\Y", sig_set_inv); RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux"); mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_set->set(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size())); - mux_sr_set->set(set_polarity ? "\\B" : "\\A", sig_set); - mux_sr_set->set("\\Y", sig_sr_set); - mux_sr_set->set("\\S", set); + mux_sr_set->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size())); + mux_sr_set->setPort(set_polarity ? "\\B" : "\\A", sig_set); + mux_sr_set->setPort("\\Y", sig_sr_set); + mux_sr_set->setPort("\\S", set); RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux"); mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size()); - mux_sr_clr->set(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size())); - mux_sr_clr->set(set_polarity ? "\\B" : "\\A", sig_set_inv); - mux_sr_clr->set("\\Y", sig_sr_clr); - mux_sr_clr->set("\\S", set); + mux_sr_clr->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size())); + mux_sr_clr->setPort(set_polarity ? "\\B" : "\\A", sig_set_inv); + mux_sr_clr->setPort("\\Y", sig_sr_clr); + mux_sr_clr->setPort("\\S", set); RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; @@ -177,11 +177,11 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1); cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1); - cell->set("\\D", sig_in); - cell->set("\\Q", sig_out); - cell->set("\\CLK", clk); - cell->set("\\SET", sig_sr_set); - cell->set("\\CLR", sig_sr_clr); + cell->setPort("\\D", sig_in); + cell->setPort("\\Q", sig_out); + cell->setPort("\\CLK", clk); + cell->setPort("\\SET", sig_sr_set); + cell->setPort("\\CLR", sig_sr_clr); log(" created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative", set_polarity ? "positive" : "negative"); @@ -203,11 +203,11 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ } cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1); - cell->set("\\D", sig_in); - cell->set("\\Q", sig_out); + cell->setPort("\\D", sig_in); + cell->setPort("\\Q", sig_out); if (arst) - cell->set("\\ARST", *arst); - cell->set("\\CLK", clk); + cell->setPort("\\ARST", *arst); + cell->setPort("\\CLK", clk); log(" created %s cell `%s' with %s edge clock", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative"); if (arst) @@ -295,9 +295,9 @@ static void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.size()); cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - cell->set("\\A", inputs); - cell->set("\\B", compare); - cell->set("\\Y", sync_level->signal); + cell->setPort("\\A", inputs); + cell->setPort("\\B", compare); + cell->setPort("\\Y", sync_level->signal); many_async_rules.clear(); } diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index b18ce492..c00b00a2 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -92,9 +92,9 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.size()); eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - eq_cell->set("\\A", sig); - eq_cell->set("\\B", comp); - eq_cell->set("\\Y", RTLIL::SigSpec(cmp_wire, cmp_wire->width++)); + eq_cell->setPort("\\A", sig); + eq_cell->setPort("\\B", comp); + eq_cell->setPort("\\Y", RTLIL::SigSpec(cmp_wire, cmp_wire->width++)); } } @@ -115,8 +115,8 @@ static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width); any_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - any_cell->set("\\A", cmp_wire); - any_cell->set("\\Y", RTLIL::SigSpec(ctrl_wire)); + any_cell->setPort("\\A", cmp_wire); + any_cell->setPort("\\Y", RTLIL::SigSpec(ctrl_wire)); } return RTLIL::SigSpec(ctrl_wire); @@ -147,10 +147,10 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, mux_cell->attributes = sw->attributes; mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size()); - mux_cell->set("\\A", else_signal); - mux_cell->set("\\B", when_signal); - mux_cell->set("\\S", ctrl_sig); - mux_cell->set("\\Y", RTLIL::SigSpec(result_wire)); + mux_cell->setPort("\\A", else_signal); + mux_cell->setPort("\\B", when_signal); + mux_cell->setPort("\\S", ctrl_sig); + mux_cell->setPort("\\Y", RTLIL::SigSpec(result_wire)); last_mux_cell = mux_cell; return RTLIL::SigSpec(result_wire); @@ -159,21 +159,21 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, static void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw) { log_assert(last_mux_cell != NULL); - log_assert(when_signal.size() == last_mux_cell->get("\\A").size()); + log_assert(when_signal.size() == last_mux_cell->getPort("\\A").size()); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw); log_assert(ctrl_sig.size() == 1); last_mux_cell->type = "$pmux"; - RTLIL::SigSpec new_s = last_mux_cell->get("\\S"); + RTLIL::SigSpec new_s = last_mux_cell->getPort("\\S"); new_s.append(ctrl_sig); - last_mux_cell->set("\\S", new_s); + last_mux_cell->setPort("\\S", new_s); - RTLIL::SigSpec new_b = last_mux_cell->get("\\B"); + RTLIL::SigSpec new_b = last_mux_cell->getPort("\\B"); new_b.append(when_signal); - last_mux_cell->set("\\B", new_b); + last_mux_cell->setPort("\\B", new_b); - last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->get("\\S").size(); + last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->getPort("\\S").size(); } static RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs, const RTLIL::SigSpec &sig, const RTLIL::SigSpec &defval) diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index f2b89b00..25b9e1d1 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -83,8 +83,8 @@ static void find_dff_wires(std::set &dff_wires, RTLIL::Module *modu SigPool dffsignals; for (auto &it : module->cells_) { - if (ct.cell_known(it.second->type) && it.second->has("\\Q")) - dffsignals.add(sigmap(it.second->get("\\Q"))); + if (ct.cell_known(it.second->type) && it.second->hasPort("\\Q")) + dffsignals.add(sigmap(it.second->getPort("\\Q"))); } for (auto &it : module->wires_) { @@ -113,10 +113,10 @@ static void create_dff_dq_map(std::map &map, RTLIL: info.cell = it.second; if (info.cell->type == "$dff") { - info.bit_clk = sigmap(info.cell->get("\\CLK")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->getPort("\\CLK")).to_single_sigbit(); info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool(); - std::vector sig_d = sigmap(info.cell->get("\\D")).to_sigbit_vector(); - std::vector sig_q = sigmap(info.cell->get("\\Q")).to_sigbit_vector(); + std::vector sig_d = sigmap(info.cell->getPort("\\D")).to_sigbit_vector(); + std::vector sig_q = sigmap(info.cell->getPort("\\Q")).to_sigbit_vector(); for (size_t i = 0; i < sig_d.size(); i++) { info.bit_d = sig_d.at(i); bit_info[sig_q.at(i)] = info; @@ -125,12 +125,12 @@ static void create_dff_dq_map(std::map &map, RTLIL: } if (info.cell->type == "$adff") { - info.bit_clk = sigmap(info.cell->get("\\CLK")).to_single_sigbit(); - info.bit_arst = sigmap(info.cell->get("\\ARST")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->getPort("\\CLK")).to_single_sigbit(); + info.bit_arst = sigmap(info.cell->getPort("\\ARST")).to_single_sigbit(); info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool(); info.arst_polarity = info.cell->parameters.at("\\ARST_POLARITY").as_bool(); - std::vector sig_d = sigmap(info.cell->get("\\D")).to_sigbit_vector(); - std::vector sig_q = sigmap(info.cell->get("\\Q")).to_sigbit_vector(); + std::vector sig_d = sigmap(info.cell->getPort("\\D")).to_sigbit_vector(); + std::vector sig_q = sigmap(info.cell->getPort("\\Q")).to_sigbit_vector(); std::vector arst_value = info.cell->parameters.at("\\ARST_VALUE").bits; for (size_t i = 0; i < sig_d.size(); i++) { info.bit_d = sig_d.at(i); @@ -141,21 +141,21 @@ static void create_dff_dq_map(std::map &map, RTLIL: } if (info.cell->type == "$_DFF_N_" || info.cell->type == "$_DFF_P_") { - info.bit_clk = sigmap(info.cell->get("\\C")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->getPort("\\C")).to_single_sigbit(); info.clk_polarity = info.cell->type == "$_DFF_P_"; - info.bit_d = sigmap(info.cell->get("\\D")).to_single_sigbit(); - bit_info[sigmap(info.cell->get("\\Q")).to_single_sigbit()] = info; + info.bit_d = sigmap(info.cell->getPort("\\D")).to_single_sigbit(); + bit_info[sigmap(info.cell->getPort("\\Q")).to_single_sigbit()] = info; continue; } if (info.cell->type.size() == 10 && info.cell->type.substr(0, 6) == "$_DFF_") { - info.bit_clk = sigmap(info.cell->get("\\C")).to_single_sigbit(); - info.bit_arst = sigmap(info.cell->get("\\R")).to_single_sigbit(); + info.bit_clk = sigmap(info.cell->getPort("\\C")).to_single_sigbit(); + info.bit_arst = sigmap(info.cell->getPort("\\R")).to_single_sigbit(); info.clk_polarity = info.cell->type[6] == 'P'; info.arst_polarity = info.cell->type[7] == 'P'; info.arst_value = info.cell->type[0] == '1' ? RTLIL::State::S1 : RTLIL::State::S0; - info.bit_d = sigmap(info.cell->get("\\D")).to_single_sigbit(); - bit_info[sigmap(info.cell->get("\\Q")).to_single_sigbit()] = info; + info.bit_d = sigmap(info.cell->getPort("\\D")).to_single_sigbit(); + bit_info[sigmap(info.cell->getPort("\\Q")).to_single_sigbit()] = info; continue; } } @@ -504,11 +504,11 @@ struct ExposePass : public Pass { for (auto &cell_name : info.cells) { RTLIL::Cell *cell = module->cells_.at(cell_name); - std::vector cell_q_bits = sigmap(cell->get("\\Q")).to_sigbit_vector(); + std::vector cell_q_bits = sigmap(cell->getPort("\\Q")).to_sigbit_vector(); for (auto &bit : cell_q_bits) if (wire_bits_set.count(bit)) bit = RTLIL::SigBit(wire_dummy_q, wire_dummy_q->width++); - cell->set("\\Q", cell_q_bits); + cell->setPort("\\Q", cell_q_bits); } RTLIL::Wire *wire_q = add_new_wire(module, wire->name + sep + "q", wire->width); @@ -540,8 +540,8 @@ struct ExposePass : public Pass { c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; - c->set("\\A", info.sig_clk); - c->set("\\Y", wire_c); + c->setPort("\\A", info.sig_clk); + c->setPort("\\Y", wire_c); } if (info.sig_arst != RTLIL::State::Sm) @@ -556,8 +556,8 @@ struct ExposePass : public Pass { c->parameters["\\A_SIGNED"] = 0; c->parameters["\\A_WIDTH"] = 1; c->parameters["\\Y_WIDTH"] = 1; - c->set("\\A", info.sig_arst); - c->set("\\Y", wire_r); + c->setPort("\\A", info.sig_arst); + c->setPort("\\Y", wire_r); } RTLIL::Wire *wire_v = add_new_wire(module, wire->name + sep + "v", wire->width); @@ -602,8 +602,8 @@ struct ExposePass : public Pass { log("New module port: %s/%s (%s)\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name), RTLIL::id2cstr(cell->type)); RTLIL::SigSpec sig; - if (cell->has(p->name)) - sig = cell->get(p->name); + if (cell->hasPort(p->name)) + sig = cell->getPort(p->name); sig.extend(w->width); if (w->port_input) module->connect(RTLIL::SigSig(sig, w)); diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index ad304c72..7b9fb207 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -624,7 +624,7 @@ struct FreduceWorker bits_full_total += outputs.size(); } if (inv_mode && it.second->type == "$_INV_") - inv_pairs.insert(std::pair(sigmap(it.second->get("\\A")), sigmap(it.second->get("\\Y")))); + inv_pairs.insert(std::pair(sigmap(it.second->getPort("\\A")), sigmap(it.second->getPort("\\Y")))); } int bits_count = 0; @@ -719,8 +719,8 @@ struct FreduceWorker inv_sig = module->addWire(NEW_ID); RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_INV_"); - inv_cell->set("\\A", grp[0].bit); - inv_cell->set("\\Y", inv_sig); + inv_cell->setPort("\\A", grp[0].bit); + inv_cell->setPort("\\Y", inv_sig); } module->connect(RTLIL::SigSig(grp[i].bit, inv_sig)); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index ffd9f1b6..1475b855 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -129,8 +129,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::Wire *w2 = miter_module->addWire("\\in_" + RTLIL::unescape_id(w1->name), w1->width); w2->port_input = true; - gold_cell->set(w1->name, w2); - gate_cell->set(w1->name, w2); + gold_cell->setPort(w1->name, w2); + gate_cell->setPort(w1->name, w2); } if (w1->port_output) @@ -141,8 +141,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, RTLIL::Wire *w2_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(w1->name), w1->width); w2_gate->port_output = flag_make_outputs; - gold_cell->set(w1->name, w2_gold); - gate_cell->set(w1->name, w2_gate); + gold_cell->setPort(w1->name, w2_gold); + gate_cell->setPort(w1->name, w2_gate); RTLIL::SigSpec this_condition; @@ -156,9 +156,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eqx_cell->parameters["\\Y_WIDTH"] = 1; eqx_cell->parameters["\\A_SIGNED"] = 0; eqx_cell->parameters["\\B_SIGNED"] = 0; - eqx_cell->set("\\A", RTLIL::SigSpec(w2_gold, i)); - eqx_cell->set("\\B", RTLIL::State::Sx); - eqx_cell->set("\\Y", gold_x.extract(i, 1)); + eqx_cell->setPort("\\A", RTLIL::SigSpec(w2_gold, i)); + eqx_cell->setPort("\\B", RTLIL::State::Sx); + eqx_cell->setPort("\\Y", gold_x.extract(i, 1)); } RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width); @@ -170,9 +170,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width; or_gold_cell->parameters["\\A_SIGNED"] = 0; or_gold_cell->parameters["\\B_SIGNED"] = 0; - or_gold_cell->set("\\A", w2_gold); - or_gold_cell->set("\\B", gold_x); - or_gold_cell->set("\\Y", gold_masked); + or_gold_cell->setPort("\\A", w2_gold); + or_gold_cell->setPort("\\B", gold_x); + or_gold_cell->setPort("\\Y", gold_masked); RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or"); or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width; @@ -180,9 +180,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width; or_gate_cell->parameters["\\A_SIGNED"] = 0; or_gate_cell->parameters["\\B_SIGNED"] = 0; - or_gate_cell->set("\\A", w2_gate); - or_gate_cell->set("\\B", gold_x); - or_gate_cell->set("\\Y", gate_masked); + or_gate_cell->setPort("\\A", w2_gate); + or_gate_cell->setPort("\\B", gold_x); + or_gate_cell->setPort("\\Y", gate_masked); RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; @@ -190,10 +190,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->set("\\A", gold_masked); - eq_cell->set("\\B", gate_masked); - eq_cell->set("\\Y", miter_module->addWire(NEW_ID)); - this_condition = eq_cell->get("\\Y"); + eq_cell->setPort("\\A", gold_masked); + eq_cell->setPort("\\B", gate_masked); + eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID)); + this_condition = eq_cell->getPort("\\Y"); } else { @@ -203,10 +203,10 @@ static void create_miter_equiv(struct Pass *that, std::vector args, eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->set("\\A", w2_gold); - eq_cell->set("\\B", w2_gate); - eq_cell->set("\\Y", miter_module->addWire(NEW_ID)); - this_condition = eq_cell->get("\\Y"); + eq_cell->setPort("\\A", w2_gold); + eq_cell->setPort("\\B", w2_gate); + eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID)); + this_condition = eq_cell->getPort("\\Y"); } if (flag_make_outcmp) @@ -225,15 +225,15 @@ static void create_miter_equiv(struct Pass *that, std::vector args, reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size(); reduce_cell->parameters["\\Y_WIDTH"] = 1; reduce_cell->parameters["\\A_SIGNED"] = 0; - reduce_cell->set("\\A", all_conditions); - reduce_cell->set("\\Y", miter_module->addWire(NEW_ID)); - all_conditions = reduce_cell->get("\\Y"); + reduce_cell->setPort("\\A", all_conditions); + reduce_cell->setPort("\\Y", miter_module->addWire(NEW_ID)); + all_conditions = reduce_cell->getPort("\\Y"); } if (flag_make_assert) { RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert"); - assert_cell->set("\\A", all_conditions); - assert_cell->set("\\EN", RTLIL::SigSpec(1, 1)); + assert_cell->setPort("\\A", all_conditions); + assert_cell->setPort("\\EN", RTLIL::SigSpec(1, 1)); } RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger"); @@ -244,8 +244,8 @@ static void create_miter_equiv(struct Pass *that, std::vector args, not_cell->parameters["\\A_WIDTH"] = all_conditions.size(); not_cell->parameters["\\Y_WIDTH"] = w_trigger->width; not_cell->parameters["\\A_SIGNED"] = 0; - not_cell->set("\\A", all_conditions); - not_cell->set("\\Y", w_trigger); + not_cell->setPort("\\A", all_conditions); + not_cell->setPort("\\Y", w_trigger); miter_module->fixup_ports(); diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 671a631d..1041227e 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -77,7 +77,7 @@ struct ShareWorker for (auto &pbit : portbits) { if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { - std::set bits = modwalker.sigmap(pbit.cell->get("\\S")).to_sigbit_set(); + std::set bits = modwalker.sigmap(pbit.cell->getPort("\\S")).to_sigbit_set(); terminal_bits.insert(bits.begin(), bits.end()); queue_bits.insert(bits.begin(), bits.end()); visited_cells.insert(pbit.cell); @@ -256,11 +256,11 @@ struct ShareWorker if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->get("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - RTLIL::SigSpec new_a = unsigned_cell->get("\\A"); + RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A"); new_a.append_bit(RTLIL::State::S0); - unsigned_cell->set("\\A", new_a); + unsigned_cell->setPort("\\A", new_a); } unsigned_cell->parameters.at("\\A_SIGNED") = true; unsigned_cell->check(); @@ -269,17 +269,17 @@ struct ShareWorker bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); - RTLIL::SigSpec a1 = c1->get("\\A"); - RTLIL::SigSpec y1 = c1->get("\\Y"); + RTLIL::SigSpec a1 = c1->getPort("\\A"); + RTLIL::SigSpec y1 = c1->getPort("\\Y"); - RTLIL::SigSpec a2 = c2->get("\\A"); - RTLIL::SigSpec y2 = c2->get("\\Y"); + RTLIL::SigSpec a2 = c2->getPort("\\A"); + RTLIL::SigSpec y2 = c2->getPort("\\Y"); int a_width = std::max(a1.size(), a2.size()); int y_width = std::max(y1.size(), y2.size()); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); @@ -288,8 +288,8 @@ struct ShareWorker supercell->parameters["\\A_SIGNED"] = a_signed; supercell->parameters["\\A_WIDTH"] = a_width; supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->set("\\A", a); - supercell->set("\\Y", y); + supercell->setPort("\\A", a); + supercell->setPort("\\Y", y); RTLIL::SigSpec new_y1(y, 0, y1.size()); RTLIL::SigSpec new_y2(y, 0, y2.size()); @@ -314,9 +314,9 @@ struct ShareWorker if (score_flipped < score_unflipped) { - RTLIL::SigSpec tmp = c2->get("\\A"); - c2->set("\\A", c2->get("\\B")); - c2->set("\\B", tmp); + RTLIL::SigSpec tmp = c2->getPort("\\A"); + c2->setPort("\\A", c2->getPort("\\B")); + c2->setPort("\\B", tmp); std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); @@ -328,11 +328,11 @@ struct ShareWorker { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->get("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->getPort("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; - RTLIL::SigSpec new_a = unsigned_cell->get("\\A"); + RTLIL::SigSpec new_a = unsigned_cell->getPort("\\A"); new_a.append_bit(RTLIL::State::S0); - unsigned_cell->set("\\A", new_a); + unsigned_cell->setPort("\\A", new_a); } unsigned_cell->parameters.at("\\A_SIGNED") = true; modified_src_cells = true; @@ -341,11 +341,11 @@ struct ShareWorker if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; - if (unsigned_cell->get("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { + if (unsigned_cell->getPort("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; - RTLIL::SigSpec new_b = unsigned_cell->get("\\B"); + RTLIL::SigSpec new_b = unsigned_cell->getPort("\\B"); new_b.append_bit(RTLIL::State::S0); - unsigned_cell->set("\\B", new_b); + unsigned_cell->setPort("\\B", new_b); } unsigned_cell->parameters.at("\\B_SIGNED") = true; modified_src_cells = true; @@ -365,13 +365,13 @@ struct ShareWorker if (c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") b_signed = false; - RTLIL::SigSpec a1 = c1->get("\\A"); - RTLIL::SigSpec b1 = c1->get("\\B"); - RTLIL::SigSpec y1 = c1->get("\\Y"); + RTLIL::SigSpec a1 = c1->getPort("\\A"); + RTLIL::SigSpec b1 = c1->getPort("\\B"); + RTLIL::SigSpec y1 = c1->getPort("\\Y"); - RTLIL::SigSpec a2 = c2->get("\\A"); - RTLIL::SigSpec b2 = c2->get("\\B"); - RTLIL::SigSpec y2 = c2->get("\\Y"); + RTLIL::SigSpec a2 = c2->getPort("\\A"); + RTLIL::SigSpec b2 = c2->getPort("\\B"); + RTLIL::SigSpec y2 = c2->getPort("\\Y"); int a_width = std::max(a1.size(), a2.size()); int b_width = std::max(b1.size(), b2.size()); @@ -381,20 +381,20 @@ struct ShareWorker { a_width = std::max(y_width, a_width); - if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->get("\\Y"); - if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->get("\\Y"); + if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->getPort("\\Y"); + if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->getPort("\\Y"); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->get("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->get("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->getPort("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->getPort("\\Y"); } else { - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->get("\\Y"); + if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); + if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); } - if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->get("\\Y"); - if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->get("\\Y"); + if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->getPort("\\Y"); + if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->getPort("\\Y"); RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); @@ -406,9 +406,9 @@ struct ShareWorker supercell->parameters["\\A_WIDTH"] = a_width; supercell->parameters["\\B_WIDTH"] = b_width; supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->set("\\A", a); - supercell->set("\\B", b); - supercell->set("\\Y", y); + supercell->setPort("\\A", a); + supercell->setPort("\\B", b); + supercell->setPort("\\Y", y); supercell->check(); RTLIL::SigSpec new_y1(y, 0, y1.size()); @@ -447,7 +447,7 @@ struct ShareWorker for (auto &bit : pbits) { if ((bit.cell->type == "$mux" || bit.cell->type == "$pmux") && bit.port == "\\S") - forbidden_controls_cache[cell].insert(bit.cell->get("\\S").extract(bit.offset, 1)); + forbidden_controls_cache[cell].insert(bit.cell->getPort("\\S").extract(bit.offset, 1)); consumer_cells.insert(bit.cell); } @@ -541,9 +541,9 @@ struct ShareWorker std::set used_in_b_parts; int width = c->parameters.at("\\WIDTH").as_int(); - std::vector sig_a = modwalker.sigmap(c->get("\\A")); - std::vector sig_b = modwalker.sigmap(c->get("\\B")); - std::vector sig_s = modwalker.sigmap(c->get("\\S")); + std::vector sig_a = modwalker.sigmap(c->getPort("\\A")); + std::vector sig_b = modwalker.sigmap(c->getPort("\\B")); + std::vector sig_s = modwalker.sigmap(c->getPort("\\S")); for (auto &bit : sig_a) if (cell_out_bits.count(bit)) diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index ffe24118..7712d18b 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -418,7 +418,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } else if (port.second != 0) log_abort(); - new_cell->set("\\" + port.first, sig); + new_cell->setPort("\\" + port.first, sig); } stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type.c_str(), new_cell->type.c_str())]++; diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 060a8740..53bc00da 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -127,7 +127,7 @@ namespace for (auto &conn : needleCell->connections()) { RTLIL::SigSpec needleSig = conn.second; - RTLIL::SigSpec haystackSig = haystackCell->get(portMapping.at(conn.first)); + RTLIL::SigSpec haystackSig = haystackCell->getPort(portMapping.at(conn.first)); for (int i = 0; i < std::min(needleSig.size(), haystackSig.size()); i++) { RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire; @@ -304,7 +304,7 @@ namespace if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair(wire->name, i)); - cell->set(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width)); + cell->setPort(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width)); } } @@ -323,10 +323,10 @@ namespace if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { for (int i = 0; i < sig.size(); i++) for (auto &port : sig2port.find(sig[i])) { - RTLIL::SigSpec bitsig = haystack_cell->get(mapping.portMapping[conn.first]).extract(i, 1); - RTLIL::SigSpec new_sig = cell->get(port.first); + RTLIL::SigSpec bitsig = haystack_cell->getPort(mapping.portMapping[conn.first]).extract(i, 1); + RTLIL::SigSpec new_sig = cell->getPort(port.first); new_sig.replace(port.second, bitsig); - cell->set(port.first, new_sig); + cell->setPort(port.first, new_sig); } } } @@ -742,7 +742,7 @@ struct ExtractPass : public Pass { for (auto &chunk : chunks) if (chunk.wire != NULL) chunk.wire = newMod->wires_.at(chunk.wire->name); - newCell->set(conn.first, chunks); + newCell->setPort(conn.first, chunks); } } } diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc index a3261dcc..784c4cf3 100644 --- a/passes/techmap/hilomap.cc +++ b/passes/techmap/hilomap.cc @@ -35,7 +35,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_hi == RTLIL::State::Sm) { last_hi = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype)); - cell->set(RTLIL::escape_id(hicell_portname), last_hi); + cell->setPort(RTLIL::escape_id(hicell_portname), last_hi); } bit = last_hi; } @@ -43,7 +43,7 @@ void hilomap_worker(RTLIL::SigSpec &sig) if (!singleton_mode || last_lo == RTLIL::State::Sm) { last_lo = module->addWire(NEW_ID); RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype)); - cell->set(RTLIL::escape_id(locell_portname), last_lo); + cell->setPort(RTLIL::escape_id(locell_portname), last_lo); } bit = last_lo; } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 10627cd1..194e06a4 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -172,9 +172,9 @@ struct IopadmapPass : public Pass { for (int i = 0; i < wire->width; i++) { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->set(RTLIL::escape_id(portname), RTLIL::SigSpec(wire, i)); + cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire, i)); if (!portname2.empty()) - cell->set(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire, i)); + cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire, i)); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1); if (!nameparam.empty()) @@ -185,9 +185,9 @@ struct IopadmapPass : public Pass { else { RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); - cell->set(RTLIL::escape_id(portname), RTLIL::SigSpec(wire)); + cell->setPort(RTLIL::escape_id(portname), RTLIL::SigSpec(wire)); if (!portname2.empty()) - cell->set(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire)); + cell->setPort(RTLIL::escape_id(portname2), RTLIL::SigSpec(new_wire)); if (!widthparam.empty()) cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width); if (!nameparam.empty()) diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 5c3e4c68..f1f334f6 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -28,22 +28,22 @@ extern void simplemap_get_mappers(std::mapget("\\A"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->set("\\A", sig_a[i]); - gate->set("\\Y", sig_y[i]); + gate->setPort("\\A", sig_a[i]); + gate->setPort("\\Y", sig_y[i]); } } static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); @@ -52,8 +52,8 @@ static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) static void simplemap_bu0(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); @@ -62,9 +62,9 @@ static void simplemap_bu0(RTLIL::Module *module, RTLIL::Cell *cell) static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_b = cell->get("\\B"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); sig_b.extend_u0(SIZE(sig_y), cell->parameters.at("\\B_SIGNED").as_bool()); @@ -75,8 +75,8 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->set("\\A", sig_t[i]); - gate->set("\\Y", sig_y[i]); + gate->setPort("\\A", sig_t[i]); + gate->setPort("\\Y", sig_y[i]); } sig_y = sig_t; @@ -91,16 +91,16 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->set("\\A", sig_a[i]); - gate->set("\\B", sig_b[i]); - gate->set("\\Y", sig_y[i]); + gate->setPort("\\A", sig_a[i]); + gate->setPort("\\B", sig_b[i]); + gate->setPort("\\Y", sig_y[i]); } } static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); if (sig_y.size() == 0) return; @@ -141,9 +141,9 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->set("\\A", sig_a[i]); - gate->set("\\B", sig_a[i+1]); - gate->set("\\Y", sig_t[i/2]); + gate->setPort("\\A", sig_a[i]); + gate->setPort("\\B", sig_a[i+1]); + gate->setPort("\\Y", sig_t[i/2]); last_output_cell = gate; } @@ -153,8 +153,8 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$reduce_xnor") { RTLIL::SigSpec sig_t = module->addWire(NEW_ID); RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->set("\\A", sig_a); - gate->set("\\Y", sig_t); + gate->setPort("\\A", sig_a); + gate->setPort("\\Y", sig_t); last_output_cell = gate; sig_a = sig_t; } @@ -162,7 +162,7 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (last_output_cell == NULL) { module->connect(RTLIL::SigSig(sig_y, sig_a)); } else { - last_output_cell->set("\\Y", sig_y); + last_output_cell->setPort("\\Y", sig_y); } } @@ -180,9 +180,9 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) } RTLIL::Cell *gate = module->addCell(NEW_ID, "$_OR_"); - gate->set("\\A", sig[i]); - gate->set("\\B", sig[i+1]); - gate->set("\\Y", sig_t[i/2]); + gate->setPort("\\A", sig[i]); + gate->setPort("\\B", sig[i+1]); + gate->setPort("\\Y", sig_t[i/2]); } sig = sig_t; @@ -194,10 +194,10 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig) static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); logic_reduce(module, sig_a); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); if (sig_y.size() == 0) return; @@ -208,19 +208,19 @@ static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) } RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); - gate->set("\\A", sig_a); - gate->set("\\Y", sig_y); + gate->setPort("\\A", sig_a); + gate->setPort("\\Y", sig_y); } static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->get("\\A"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); logic_reduce(module, sig_a); - RTLIL::SigSpec sig_b = cell->get("\\B"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); logic_reduce(module, sig_b); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); if (sig_y.size() == 0) return; @@ -236,39 +236,39 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) log_assert(!gate_type.empty()); RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->set("\\A", sig_a); - gate->set("\\B", sig_b); - gate->set("\\Y", sig_y); + gate->setPort("\\A", sig_a); + gate->setPort("\\B", sig_b); + gate->setPort("\\Y", sig_y); } static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_b = cell->get("\\B"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); for (int i = 0; i < SIZE(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, "$_MUX_"); - gate->set("\\A", sig_a[i]); - gate->set("\\B", sig_b[i]); - gate->set("\\S", cell->get("\\S")); - gate->set("\\Y", sig_y[i]); + gate->setPort("\\A", sig_a[i]); + gate->setPort("\\B", sig_b[i]); + gate->setPort("\\S", cell->getPort("\\S")); + gate->setPort("\\Y", sig_y[i]); } } static void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) { int offset = cell->parameters.at("\\OFFSET").as_int(); - RTLIL::SigSpec sig_a = cell->get("\\A"); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size()))); } static void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell) { - RTLIL::SigSpec sig_ab = cell->get("\\A"); - sig_ab.append(cell->get("\\B")); - RTLIL::SigSpec sig_y = cell->get("\\Y"); + RTLIL::SigSpec sig_ab = cell->getPort("\\A"); + sig_ab.append(cell->getPort("\\B")); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); module->connect(RTLIL::SigSig(sig_y, sig_ab)); } @@ -278,17 +278,17 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell) char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_s = cell->get("\\SET"); - RTLIL::SigSpec sig_r = cell->get("\\CLR"); - RTLIL::SigSpec sig_q = cell->get("\\Q"); + RTLIL::SigSpec sig_s = cell->getPort("\\SET"); + RTLIL::SigSpec sig_r = cell->getPort("\\CLR"); + RTLIL::SigSpec sig_q = cell->getPort("\\Q"); std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->set("\\S", sig_s[i]); - gate->set("\\R", sig_r[i]); - gate->set("\\Q", sig_q[i]); + gate->setPort("\\S", sig_s[i]); + gate->setPort("\\R", sig_r[i]); + gate->setPort("\\Q", sig_q[i]); } } @@ -297,17 +297,17 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell) int width = cell->parameters.at("\\WIDTH").as_int(); char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->get("\\CLK"); - RTLIL::SigSpec sig_d = cell->get("\\D"); - RTLIL::SigSpec sig_q = cell->get("\\Q"); + RTLIL::SigSpec sig_clk = cell->getPort("\\CLK"); + RTLIL::SigSpec sig_d = cell->getPort("\\D"); + RTLIL::SigSpec sig_q = cell->getPort("\\Q"); std::string gate_type = stringf("$_DFF_%c_", clk_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->set("\\C", sig_clk); - gate->set("\\D", sig_d[i]); - gate->set("\\Q", sig_q[i]); + gate->setPort("\\C", sig_clk); + gate->setPort("\\D", sig_d[i]); + gate->setPort("\\Q", sig_q[i]); } } @@ -318,21 +318,21 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell) char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N'; char clr_pol = cell->parameters.at("\\CLR_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_clk = cell->get("\\CLK"); - RTLIL::SigSpec sig_s = cell->get("\\SET"); - RTLIL::SigSpec sig_r = cell->get("\\CLR"); - RTLIL::SigSpec sig_d = cell->get("\\D"); - RTLIL::SigSpec sig_q = cell->get("\\Q"); + RTLIL::SigSpec sig_clk = cell->getPort("\\CLK"); + RTLIL::SigSpec sig_s = cell->getPort("\\SET"); + RTLIL::SigSpec sig_r = cell->getPort("\\CLR"); + RTLIL::SigSpec sig_d = cell->getPort("\\D"); + RTLIL::SigSpec sig_q = cell->getPort("\\Q"); std::string gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->set("\\C", sig_clk); - gate->set("\\S", sig_s[i]); - gate->set("\\R", sig_r[i]); - gate->set("\\D", sig_d[i]); - gate->set("\\Q", sig_q[i]); + gate->setPort("\\C", sig_clk); + gate->setPort("\\S", sig_s[i]); + gate->setPort("\\R", sig_r[i]); + gate->setPort("\\D", sig_d[i]); + gate->setPort("\\Q", sig_q[i]); } } @@ -346,20 +346,20 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell) while (int(rst_val.size()) < width) rst_val.push_back(RTLIL::State::S0); - RTLIL::SigSpec sig_clk = cell->get("\\CLK"); - RTLIL::SigSpec sig_rst = cell->get("\\ARST"); - RTLIL::SigSpec sig_d = cell->get("\\D"); - RTLIL::SigSpec sig_q = cell->get("\\Q"); + RTLIL::SigSpec sig_clk = cell->getPort("\\CLK"); + RTLIL::SigSpec sig_rst = cell->getPort("\\ARST"); + RTLIL::SigSpec sig_d = cell->getPort("\\D"); + RTLIL::SigSpec sig_q = cell->getPort("\\Q"); std::string gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol); std::string gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0); - gate->set("\\C", sig_clk); - gate->set("\\R", sig_rst); - gate->set("\\D", sig_d[i]); - gate->set("\\Q", sig_q[i]); + gate->setPort("\\C", sig_clk); + gate->setPort("\\R", sig_rst); + gate->setPort("\\D", sig_d[i]); + gate->setPort("\\Q", sig_q[i]); } } @@ -368,17 +368,17 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) int width = cell->parameters.at("\\WIDTH").as_int(); char en_pol = cell->parameters.at("\\EN_POLARITY").as_bool() ? 'P' : 'N'; - RTLIL::SigSpec sig_en = cell->get("\\EN"); - RTLIL::SigSpec sig_d = cell->get("\\D"); - RTLIL::SigSpec sig_q = cell->get("\\Q"); + RTLIL::SigSpec sig_en = cell->getPort("\\EN"); + RTLIL::SigSpec sig_d = cell->getPort("\\D"); + RTLIL::SigSpec sig_q = cell->getPort("\\Q"); std::string gate_type = stringf("$_DLATCH_%c_", en_pol); for (int i = 0; i < width; i++) { RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); - gate->set("\\E", sig_en); - gate->set("\\D", sig_d[i]); - gate->set("\\Q", sig_q[i]); + gate->setPort("\\E", sig_en); + gate->setPort("\\D", sig_d[i]); + gate->setPort("\\Q", sig_q[i]); } } diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 4034f120..94649013 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -38,7 +38,7 @@ static void create_gold_module(RTLIL::Design *design, std::string cell_type, std RTLIL::Wire *wire = module->addWire("\\A"); wire->width = 1 + xorshift32(8); wire->port_input = true; - cell->set("\\A", wire); + cell->setPort("\\A", wire); } if (cell_type_flags.find('B') != std::string::npos) { @@ -48,7 +48,7 @@ static void create_gold_module(RTLIL::Design *design, std::string cell_type, std else wire->width = 1 + xorshift32(8); wire->port_input = true; - cell->set("\\B", wire); + cell->setPort("\\B", wire); } if (cell_type_flags.find('S') != std::string::npos && xorshift32(2)) { @@ -69,7 +69,7 @@ static void create_gold_module(RTLIL::Design *design, std::string cell_type, std RTLIL::Wire *wire = module->addWire("\\Y"); wire->width = 1 + xorshift32(8); wire->port_output = true; - cell->set("\\Y", wire); + cell->setPort("\\Y", wire); } module->fixup_ports(); From c6fd82c70be33c566cdf312e3ad21401b5b8171b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 16:45:23 +0200 Subject: [PATCH 509/750] Fixed build of verific bindings --- frontends/verific/verific.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c7b99c7a..30f45218 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); } } } From 069fe0db4265aeed23b37bec252e81308daf8c65 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 23:07:00 +0200 Subject: [PATCH 510/750] Added compiler + compiler version + compiler flags to version string --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4436be3d..40eff3d0 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,8 @@ yosys: $(OBJS) kernel/version_$(GIT_REV).cc: Makefile $(P) rm -f kernel/version_*.o kernel/version_*.d kernel/version_*.cc - $(Q) echo "extern const char *yosys_version_str; const char *yosys_version_str=\"Yosys $(YOSYS_VER) (git sha1 $(GIT_REV))\";" > kernel/version_$(GIT_REV).cc + $(Q) echo "extern const char *yosys_version_str; const char *yosys_version_str=\"Yosys $(YOSYS_VER) (git sha1 $(GIT_REV), $(CXX) ` \ + $(CXX) --version | tr ' ()' '\n' | grep '^[0-9]' | head -n1` $(filter -f% -m% -O% -DNDEBUG,$(CXXFLAGS)))\";" > kernel/version_$(GIT_REV).cc yosys-config: yosys-config.in $(P) $(SED) -e 's,@CXX@,$(CXX),;' -e 's,@CXXFLAGS@,$(CXXFLAGS),;' -e 's,@LDFLAGS@,$(LDFLAGS),;' -e 's,@LDLIBS@,$(LDLIBS),;' \ From 62c8a7152551519d6e876319b1068a1987a14f3c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 23:14:17 +0200 Subject: [PATCH 511/750] Various cleanups in Makefile, Renamed default configurations --- Makefile | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 40eff3d0..41569f6c 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,7 @@ -CONFIG := clang-debug -# CONFIG := gcc-debug +CONFIG := clang +# CONFIG := gcc # CONFIG := gcc-4.7 -# CONFIG := release # features (the more the better) ENABLE_TCL := 1 @@ -44,7 +43,7 @@ else endif YOSYS_VER := 0.3.0+ -GIT_REV := $(shell git rev-parse --short HEAD || echo UNKOWN) +GIT_REV := $(shell git rev-parse --short HEAD 2> /dev/null || echo UNKOWN) OBJS = kernel/version_$(GIT_REV).o # set 'ABCREV = default' to use abc/ as it is @@ -58,24 +57,19 @@ ABCPULL = 1 -include Makefile.conf -ifeq ($(CONFIG),clang-debug) +ifeq ($(CONFIG),clang) CXX = clang CXXFLAGS += -std=c++11 -Os endif -ifeq ($(CONFIG),gcc-debug) +ifeq ($(CONFIG),gcc) CXX = gcc CXXFLAGS += -std=gnu++0x -Os endif ifeq ($(CONFIG),gcc-4.7) CXX = gcc-4.7 -CXXFLAGS += -std=gnu++0x -march=native -O3 -endif - -ifeq ($(CONFIG),release) -CXX = gcc -CXXFLAGS += -std=gnu++0x -march=native -O3 -DNDEBUG +CXXFLAGS += -std=gnu++0x -Os endif ifeq ($(ENABLE_TCL),1) @@ -282,20 +276,17 @@ qtcreator: config-clean: clean rm -f Makefile.conf -config-clang-debug: clean - echo 'CONFIG := clang-debug' > Makefile.conf +config-clang: clean + echo 'CONFIG := clang' > Makefile.conf -config-gcc-debug: clean - echo 'CONFIG := gcc-debug' > Makefile.conf +config-gcc: clean + echo 'CONFIG := gcc' > Makefile.conf config-gcc-4.7: clean echo 'CONFIG := gcc-4.7' > Makefile.conf -config-release: clean - echo 'CONFIG := release' > Makefile.conf - config-gprof: clean - echo 'CONFIG := gcc-debug' > Makefile.conf + echo 'CONFIG := gcc' > Makefile.conf echo 'ENABLE_GPROF := 1' >> Makefile.conf config-sudo: @@ -309,5 +300,5 @@ config-sudo: -include techlibs/*/*.d .PHONY: all top-all abc test install install-abc manual clean mrproper qtcreator -.PHONY: config-clean config-clang-debug config-gcc-debug config-release +.PHONY: config-clean config-clang config-gcc config-gcc-4.7 config-gprof config-sudo From 32a1cc3efdad7953af1805b245f2a0292698633a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 23:30:18 +0200 Subject: [PATCH 512/750] Renamed modwalker.h to modtools.h --- kernel/{modwalker.h => modtools.h} | 4 ++-- passes/memory/memory_share.cc | 11 ++++++----- passes/sat/share.cc | 11 ++++++----- 3 files changed, 14 insertions(+), 12 deletions(-) rename kernel/{modwalker.h => modtools.h} (99%) diff --git a/kernel/modwalker.h b/kernel/modtools.h similarity index 99% rename from kernel/modwalker.h rename to kernel/modtools.h index 09f815b8..06e96246 100644 --- a/kernel/modwalker.h +++ b/kernel/modtools.h @@ -17,8 +17,8 @@ * */ -#ifndef MODWALKER_H -#define MODWALKER_H +#ifndef MODTOOLS_H +#define MODTOOLS_H #include "kernel/sigtools.h" #include "kernel/celltypes.h" diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index b6e7cc83..fde6ea00 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -17,13 +17,12 @@ * */ -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "kernel/satgen.h" #include "kernel/sigtools.h" -#include "kernel/modwalker.h" -#include "kernel/register.h" -#include "kernel/log.h" -#include +#include "kernel/modtools.h" + +PRIVATE_NAMESPACE_BEGIN static bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b) { @@ -742,3 +741,5 @@ struct MemorySharePass : public Pass { } } MemorySharePass; +PRIVATE_NAMESPACE_END + diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 1041227e..ea7a9f63 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -17,13 +17,12 @@ * */ -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "kernel/satgen.h" #include "kernel/sigtools.h" -#include "kernel/modwalker.h" -#include "kernel/register.h" -#include "kernel/log.h" -#include +#include "kernel/modtools.h" + +PRIVATE_NAMESPACE_BEGIN struct ShareWorkerConfig { @@ -967,3 +966,5 @@ struct SharePass : public Pass { } } SharePass; +PRIVATE_NAMESPACE_END + From 03ef9a75c64f79596d6c931a1401184c33f9346b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 03:55:51 +0200 Subject: [PATCH 513/750] Added "test_autotb -n " option --- passes/tests/test_autotb.cc | 36 +++++++++++++++++++++++++++--------- tests/tools/autotest.sh | 7 +++++-- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index f121089b..844bcbc9 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -17,12 +17,12 @@ * */ -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include #include +#include -#define NUM_ITER 1000 +PRIVATE_NAMESPACE_BEGIN static std::string id(std::string internal_id) { @@ -70,7 +70,7 @@ static std::string idy(std::string str1, std::string str2 = std::string(), std:: return id(str1); } -static void autotest(FILE *f, RTLIL::Design *design) +static void autotest(FILE *f, RTLIL::Design *design, int num_iter) { fprintf(f, "module testbench;\n\n"); @@ -79,7 +79,7 @@ static void autotest(FILE *f, RTLIL::Design *design) fprintf(f, "reg [31:0] xorshift128_x = 123456789;\n"); fprintf(f, "reg [31:0] xorshift128_y = 362436069;\n"); fprintf(f, "reg [31:0] xorshift128_z = 521288629;\n"); - fprintf(f, "reg [31:0] xorshift128_w = 88675123;\n"); + fprintf(f, "reg [31:0] xorshift128_w = %u; // <-- seed value\n", int(time(NULL))); fprintf(f, "reg [31:0] xorshift128_t;\n\n"); fprintf(f, "task xorshift128;\n"); fprintf(f, "begin\n"); @@ -279,7 +279,7 @@ static void autotest(FILE *f, RTLIL::Design *design) fprintf(f, "begin\n"); fprintf(f, "\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name).c_str()); fprintf(f, "\t%s;\n", idy(mod->name, "reset").c_str()); - fprintf(f, "\tfor (i=0; i<%d; i=i+1) begin\n", NUM_ITER); + fprintf(f, "\tfor (i=0; i<%d; i=i+1) begin\n", num_iter); fprintf(f, "\t\tif (i %% 20 == 0) %s;\n", idy(mod->name, "print_header").c_str()); fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "update_data").c_str()); fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "update_clock").c_str()); @@ -307,7 +307,7 @@ struct TestAutotbBackend : public Backend { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" test_autotb [filename]\n"); + log(" test_autotb [options] [filename]\n"); log("\n"); log("Automatically create primitive verilog test benches for all modules in the\n"); log("design. The generated testbenches toggle the input pins of the module in\n"); @@ -324,12 +324,30 @@ struct TestAutotbBackend : public Backend { log("value after initialization. This can e.g. be used to force a reset signal\n"); log("low in order to explore more inner states in a state machine.\n"); log("\n"); + log(" -n \n"); + log(" number of iterations the test bench shuld run (default = 1000)\n"); + log("\n"); } virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) { + int num_iter = 1000; + log_header("Executing TEST_AUTOTB backend (auto-generate pseudo-random test benches).\n"); - extra_args(f, filename, args, 1); - autotest(f, design); + + int argidx; + for (argidx = 1; argidx < SIZE(args); argidx++) + { + if (args[argidx] == "-n" && argidx+1 < SIZE(args)) { + num_iter = atoi(args[++argidx].c_str()); + continue; + } + break; + } + + extra_args(f, filename, args, argidx); + autotest(f, design, num_iter); } } TestAutotbBackend; +PRIVATE_NAMESPACE_END + diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 781dc167..2d97e46f 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -9,6 +9,7 @@ keeprunning=false makejmode=false frontend="verilog" backend_opts="-noattr -noexpr" +autotb_opts="" scriptfiles="" scriptopt="" toolsdir="$(cd $(dirname $0); pwd)" @@ -18,7 +19,7 @@ if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdat ( set -ex; gcc -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1 fi -while getopts xmGl:wkjvrf:s:p: opt; do +while getopts xmGl:wkjvrf:s:p:n: opt; do case "$opt" in x) use_xsim=true ;; @@ -45,6 +46,8 @@ while getopts xmGl:wkjvrf:s:p: opt; do scriptfiles="$scriptfiles $OPTARG" ;; p) scriptopt="$OPTARG" ;; + n) + autotb_opts="$autotb_opts -n $OPTARG" ;; *) echo "Usage: $0 [-x|-m] [-w] [-k] [-j] [-v] [-r] [-l libs] [-f frontend] [-s script] [-p cmdstring] verilog-files\n" >&2 exit 1 @@ -102,7 +105,7 @@ do cd ${bn}.out cp ../$fn $fn if [ ! -f ../${bn}_tb.v ]; then - "$toolsdir"/../../yosys -b test_autotb -o ${bn}_tb.v $fn + "$toolsdir"/../../yosys -b "test_autotb $autotb_opts" -o ${bn}_tb.v $fn else cp ../${bn}_tb.v ${bn}_tb.v fi From 5e641acc905a5c99d037378f6b7a481c43eb7de0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 03:57:37 +0200 Subject: [PATCH 514/750] Consolidated hana test benches into fewer files for pf in test_simulation_{always,and,buffer,decoder,inc,mux,nand,nor,or,seq,shifter,sop,techmap,xnor,xor}; do gawk 'FNR == 1 { printf("\n// %s\n",FILENAME); } { gsub("^module *", sprintf("module f%d_",ARGIND)); print; }' \ ${pf}_*_test.v > $pf.v; ../tools/autotest.sh $pf.v; mv -v ${pf}_*_test.v Attic/; done; ..etc.. --- tests/hana/README | 10 - tests/hana/run-test.sh | 2 +- tests/hana/test_intermout.v | 418 ++++++++++++++++++ .../hana/test_intermout_always_comb_1_test.v | 13 - .../hana/test_intermout_always_comb_3_test.v | 10 - .../hana/test_intermout_always_comb_4_test.v | 9 - .../hana/test_intermout_always_comb_5_test.v | 11 - tests/hana/test_intermout_always_ff_3_test.v | 15 - tests/hana/test_intermout_always_ff_4_test.v | 11 - tests/hana/test_intermout_always_ff_5_test.v | 13 - tests/hana/test_intermout_always_ff_6_test.v | 7 - tests/hana/test_intermout_always_ff_8_test.v | 11 - tests/hana/test_intermout_always_ff_9_test.v | 14 - .../hana/test_intermout_always_latch_1_test.v | 9 - tests/hana/test_intermout_bufrm_1_test.v | 4 - tests/hana/test_intermout_bufrm_2_test.v | 7 - tests/hana/test_intermout_bufrm_6_test.v | 22 - tests/hana/test_intermout_bufrm_7_test.v | 33 -- tests/hana/test_intermout_exprs_add_test.v | 10 - .../hana/test_intermout_exprs_binlogic_test.v | 13 - .../test_intermout_exprs_bitwiseneg_test.v | 5 - tests/hana/test_intermout_exprs_buffer_test.v | 9 - .../test_intermout_exprs_condexpr_mux_test.v | 11 - ...est_intermout_exprs_condexpr_tribuf_test.v | 9 - tests/hana/test_intermout_exprs_const_test.v | 7 - .../test_intermout_exprs_constshift_test.v | 12 - tests/hana/test_intermout_exprs_div_test.v | 10 - .../hana/test_intermout_exprs_logicneg_test.v | 7 - tests/hana/test_intermout_exprs_mod_test.v | 10 - tests/hana/test_intermout_exprs_mul_test.v | 10 - tests/hana/test_intermout_exprs_redand_test.v | 5 - tests/hana/test_intermout_exprs_redop_test.v | 16 - tests/hana/test_intermout_exprs_sub_test.v | 10 - .../test_intermout_exprs_unaryminus_test.v | 5 - .../test_intermout_exprs_unaryplus_test.v | 4 - .../hana/test_intermout_exprs_varshift_test.v | 10 - tests/hana/test_parse2synthtrans.v | 117 +++++ .../test_parse2synthtrans_behavopt_1_test.v | 22 - .../hana/test_parse2synthtrans_case_1_test.v | 26 -- .../test_parse2synthtrans_contassign_1_test.v | 7 - ...test_parse2synthtrans_module_basic0_test.v | 2 - .../test_parse2synthtrans_operators_1_test.v | 11 - .../hana/test_parse2synthtrans_param_1_test.v | 7 - ...test_parse2synthtrans_port_scalar_1_test.v | 6 - ...test_parse2synthtrans_port_vector_1_test.v | 9 - ...synthtrans_v2k_comb_logic_sens_list_test.v | 9 - tests/hana/test_parser.v | 87 ++++ ...est_parser_constructs_module_basic1_test.v | 2 - ...test_parser_constructs_param_basic0_test.v | 10 - .../test_parser_constructs_port_basic0_test.v | 8 - ..._parser_directives_define_simpledef_test.v | 9 - tests/hana/test_parser_misc_operators_test.v | 29 -- ...test_parser_v2k_comb_port_data_type_test.v | 6 - ...test_parser_v2k_comma_sep_sens_list_test.v | 9 - tests/hana/test_simulation_always.v | 135 ++++++ tests/hana/test_simulation_always_15_test.v | 5 - tests/hana/test_simulation_always_17_test.v | 13 - tests/hana/test_simulation_always_18_test.v | 10 - tests/hana/test_simulation_always_19_test.v | 11 - tests/hana/test_simulation_always_1_test.v | 5 - tests/hana/test_simulation_always_20_test.v | 15 - tests/hana/test_simulation_always_21_test.v | 11 - tests/hana/test_simulation_always_22_test.v | 7 - tests/hana/test_simulation_always_23_test.v | 14 - tests/hana/test_simulation_always_27_test.v | 13 - tests/hana/test_simulation_always_29_test.v | 9 - tests/hana/test_simulation_and.v | 35 ++ tests/hana/test_simulation_and_1_test.v | 3 - tests/hana/test_simulation_and_2_test.v | 3 - tests/hana/test_simulation_and_3_test.v | 3 - tests/hana/test_simulation_and_4_test.v | 3 - tests/hana/test_simulation_and_5_test.v | 3 - tests/hana/test_simulation_and_6_test.v | 3 - tests/hana/test_simulation_and_7_test.v | 3 - tests/hana/test_simulation_buffer.v | 17 + tests/hana/test_simulation_buffer_1_test.v | 3 - tests/hana/test_simulation_buffer_2_test.v | 4 - tests/hana/test_simulation_buffer_3_test.v | 4 - ...der_8_test.v => test_simulation_decoder.v} | 145 +++++- tests/hana/test_simulation_decoder_2_test.v | 14 - tests/hana/test_simulation_decoder_3_test.v | 14 - tests/hana/test_simulation_decoder_4_test.v | 14 - tests/hana/test_simulation_decoder_5_test.v | 17 - tests/hana/test_simulation_decoder_6_test.v | 27 -- tests/hana/test_simulation_decoder_7_test.v | 43 -- tests/hana/test_simulation_inc.v | 42 ++ tests/hana/test_simulation_inc_16_test.v | 5 - tests/hana/test_simulation_inc_1_test.v | 5 - tests/hana/test_simulation_inc_2_test.v | 5 - tests/hana/test_simulation_inc_32_test.v | 5 - tests/hana/test_simulation_inc_4_test.v | 5 - tests/hana/test_simulation_inc_8_test.v | 5 - tests/hana/test_simulation_mod_1_xx.v | 13 - tests/hana/test_simulation_mux.v | 176 ++++++++ tests/hana/test_simulation_mux_16_test.v | 22 - tests/hana/test_simulation_mux_2_test.v | 8 - tests/hana/test_simulation_mux_32_test.v | 39 -- tests/hana/test_simulation_mux_4_test.v | 10 - tests/hana/test_simulation_mux_64_test.v | 71 --- tests/hana/test_simulation_mux_8_test.v | 14 - tests/hana/test_simulation_nand.v | 25 ++ tests/hana/test_simulation_nand_1_test.v | 3 - tests/hana/test_simulation_nand_3_test.v | 3 - tests/hana/test_simulation_nand_4_test.v | 3 - tests/hana/test_simulation_nand_5_test.v | 3 - tests/hana/test_simulation_nand_6_test.v | 3 - tests/hana/test_simulation_nor.v | 20 + tests/hana/test_simulation_nor_1_test.v | 3 - tests/hana/test_simulation_nor_2_test.v | 3 - tests/hana/test_simulation_nor_3_test.v | 3 - tests/hana/test_simulation_nor_4_test.v | 3 - ...mulation_opt_constprop_contassign_1_test.v | 3 - tests/hana/test_simulation_or.v | 30 ++ tests/hana/test_simulation_or_1_test.v | 3 - tests/hana/test_simulation_or_2_test.v | 3 - tests/hana/test_simulation_or_3_test.v | 3 - tests/hana/test_simulation_or_4_test.v | 3 - tests/hana/test_simulation_or_5_test.v | 3 - tests/hana/test_simulation_or_6_test.v | 3 - tests/hana/test_simulation_seq.v | 12 + tests/hana/test_simulation_seq_ff_1_test.v | 4 - tests/hana/test_simulation_seq_ff_2_test.v | 4 - tests/hana/test_simulation_shifter.v | 60 +++ .../test_simulation_shifter_left_16_test.v | 4 - .../test_simulation_shifter_left_32_test.v | 4 - .../test_simulation_shifter_left_4_test.v | 4 - .../test_simulation_shifter_left_64_test.v | 4 - .../test_simulation_shifter_left_8_test.v | 4 - .../test_simulation_shifter_right_16_test.v | 4 - .../test_simulation_shifter_right_32_test.v | 4 - .../test_simulation_shifter_right_4_test.v | 4 - .../test_simulation_shifter_right_64_test.v | 4 - .../test_simulation_shifter_right_8_test.v | 4 - tests/hana/test_simulation_sop.v | 65 +++ .../hana/test_simulation_sop_basic_10_test.v | 8 - .../hana/test_simulation_sop_basic_11_test.v | 10 - .../hana/test_simulation_sop_basic_12_test.v | 14 - .../hana/test_simulation_sop_basic_18_test.v | 5 - tests/hana/test_simulation_sop_basic_3_test.v | 3 - tests/hana/test_simulation_sop_basic_7_test.v | 3 - tests/hana/test_simulation_sop_basic_8_test.v | 3 - tests/hana/test_simulation_sop_basic_9_test.v | 3 - ...x_128_test.v => test_simulation_techmap.v} | 40 +- .../test_simulation_techmap_and_19_tech.v | 7 - .../hana/test_simulation_techmap_and_5_tech.v | 3 - tests/hana/test_simulation_techmap_buf_test.v | 3 - tests/hana/test_simulation_techmap_inv_test.v | 3 - .../hana/test_simulation_techmap_mux_0_test.v | 8 - .../hana/test_simulation_techmap_mux_8_test.v | 14 - .../test_simulation_techmap_nand_19_tech.v | 11 - .../test_simulation_techmap_nand_2_tech.v | 11 - .../test_simulation_techmap_nand_5_tech.v | 11 - .../test_simulation_techmap_nor_19_tech.v | 11 - .../hana/test_simulation_techmap_nor_2_tech.v | 11 - .../hana/test_simulation_techmap_nor_5_tech.v | 11 - .../hana/test_simulation_techmap_or_19_tech.v | 7 - .../hana/test_simulation_techmap_or_5_tech.v | 3 - tests/hana/test_simulation_techmap_tech.v | 143 ++++++ .../test_simulation_techmap_xnor_2_tech.v | 6 - .../test_simulation_techmap_xnor_5_tech.v | 6 - .../test_simulation_techmap_xor_19_tech.v | 3 - .../hana/test_simulation_techmap_xor_2_tech.v | 6 - .../hana/test_simulation_techmap_xor_5_tech.v | 6 - tests/hana/test_simulation_tribuf_2_test.v | 3 - ..._always_31_tt.v => test_simulation_vlib.v} | 17 +- tests/hana/test_simulation_xnor.v | 20 + tests/hana/test_simulation_xnor_1_test.v | 3 - tests/hana/test_simulation_xnor_2_test.v | 3 - tests/hana/test_simulation_xnor_3_test.v | 3 - tests/hana/test_simulation_xnor_4_test.v | 3 - tests/hana/test_simulation_xor.v | 20 + tests/hana/test_simulation_xor_1_test.v | 3 - tests/hana/test_simulation_xor_2_test.v | 3 - tests/hana/test_simulation_xor_3_test.v | 3 - tests/hana/test_simulation_xor_4_test.v | 3 - 175 files changed, 1622 insertions(+), 1332 deletions(-) create mode 100644 tests/hana/test_intermout.v delete mode 100644 tests/hana/test_intermout_always_comb_1_test.v delete mode 100644 tests/hana/test_intermout_always_comb_3_test.v delete mode 100644 tests/hana/test_intermout_always_comb_4_test.v delete mode 100644 tests/hana/test_intermout_always_comb_5_test.v delete mode 100644 tests/hana/test_intermout_always_ff_3_test.v delete mode 100644 tests/hana/test_intermout_always_ff_4_test.v delete mode 100644 tests/hana/test_intermout_always_ff_5_test.v delete mode 100644 tests/hana/test_intermout_always_ff_6_test.v delete mode 100644 tests/hana/test_intermout_always_ff_8_test.v delete mode 100644 tests/hana/test_intermout_always_ff_9_test.v delete mode 100644 tests/hana/test_intermout_always_latch_1_test.v delete mode 100644 tests/hana/test_intermout_bufrm_1_test.v delete mode 100644 tests/hana/test_intermout_bufrm_2_test.v delete mode 100644 tests/hana/test_intermout_bufrm_6_test.v delete mode 100644 tests/hana/test_intermout_bufrm_7_test.v delete mode 100644 tests/hana/test_intermout_exprs_add_test.v delete mode 100644 tests/hana/test_intermout_exprs_binlogic_test.v delete mode 100644 tests/hana/test_intermout_exprs_bitwiseneg_test.v delete mode 100644 tests/hana/test_intermout_exprs_buffer_test.v delete mode 100644 tests/hana/test_intermout_exprs_condexpr_mux_test.v delete mode 100644 tests/hana/test_intermout_exprs_condexpr_tribuf_test.v delete mode 100644 tests/hana/test_intermout_exprs_const_test.v delete mode 100644 tests/hana/test_intermout_exprs_constshift_test.v delete mode 100644 tests/hana/test_intermout_exprs_div_test.v delete mode 100644 tests/hana/test_intermout_exprs_logicneg_test.v delete mode 100644 tests/hana/test_intermout_exprs_mod_test.v delete mode 100644 tests/hana/test_intermout_exprs_mul_test.v delete mode 100644 tests/hana/test_intermout_exprs_redand_test.v delete mode 100644 tests/hana/test_intermout_exprs_redop_test.v delete mode 100644 tests/hana/test_intermout_exprs_sub_test.v delete mode 100644 tests/hana/test_intermout_exprs_unaryminus_test.v delete mode 100644 tests/hana/test_intermout_exprs_unaryplus_test.v delete mode 100644 tests/hana/test_intermout_exprs_varshift_test.v create mode 100644 tests/hana/test_parse2synthtrans.v delete mode 100644 tests/hana/test_parse2synthtrans_behavopt_1_test.v delete mode 100644 tests/hana/test_parse2synthtrans_case_1_test.v delete mode 100644 tests/hana/test_parse2synthtrans_contassign_1_test.v delete mode 100644 tests/hana/test_parse2synthtrans_module_basic0_test.v delete mode 100644 tests/hana/test_parse2synthtrans_operators_1_test.v delete mode 100644 tests/hana/test_parse2synthtrans_param_1_test.v delete mode 100644 tests/hana/test_parse2synthtrans_port_scalar_1_test.v delete mode 100644 tests/hana/test_parse2synthtrans_port_vector_1_test.v delete mode 100644 tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v create mode 100644 tests/hana/test_parser.v delete mode 100644 tests/hana/test_parser_constructs_module_basic1_test.v delete mode 100644 tests/hana/test_parser_constructs_param_basic0_test.v delete mode 100644 tests/hana/test_parser_constructs_port_basic0_test.v delete mode 100644 tests/hana/test_parser_directives_define_simpledef_test.v delete mode 100644 tests/hana/test_parser_misc_operators_test.v delete mode 100644 tests/hana/test_parser_v2k_comb_port_data_type_test.v delete mode 100644 tests/hana/test_parser_v2k_comma_sep_sens_list_test.v create mode 100644 tests/hana/test_simulation_always.v delete mode 100644 tests/hana/test_simulation_always_15_test.v delete mode 100644 tests/hana/test_simulation_always_17_test.v delete mode 100644 tests/hana/test_simulation_always_18_test.v delete mode 100644 tests/hana/test_simulation_always_19_test.v delete mode 100644 tests/hana/test_simulation_always_1_test.v delete mode 100644 tests/hana/test_simulation_always_20_test.v delete mode 100644 tests/hana/test_simulation_always_21_test.v delete mode 100644 tests/hana/test_simulation_always_22_test.v delete mode 100644 tests/hana/test_simulation_always_23_test.v delete mode 100644 tests/hana/test_simulation_always_27_test.v delete mode 100644 tests/hana/test_simulation_always_29_test.v create mode 100644 tests/hana/test_simulation_and.v delete mode 100644 tests/hana/test_simulation_and_1_test.v delete mode 100644 tests/hana/test_simulation_and_2_test.v delete mode 100644 tests/hana/test_simulation_and_3_test.v delete mode 100644 tests/hana/test_simulation_and_4_test.v delete mode 100644 tests/hana/test_simulation_and_5_test.v delete mode 100644 tests/hana/test_simulation_and_6_test.v delete mode 100644 tests/hana/test_simulation_and_7_test.v create mode 100644 tests/hana/test_simulation_buffer.v delete mode 100644 tests/hana/test_simulation_buffer_1_test.v delete mode 100644 tests/hana/test_simulation_buffer_2_test.v delete mode 100644 tests/hana/test_simulation_buffer_3_test.v rename tests/hana/{test_simulation_decoder_8_test.v => test_simulation_decoder.v} (56%) delete mode 100644 tests/hana/test_simulation_decoder_2_test.v delete mode 100644 tests/hana/test_simulation_decoder_3_test.v delete mode 100644 tests/hana/test_simulation_decoder_4_test.v delete mode 100644 tests/hana/test_simulation_decoder_5_test.v delete mode 100644 tests/hana/test_simulation_decoder_6_test.v delete mode 100644 tests/hana/test_simulation_decoder_7_test.v create mode 100644 tests/hana/test_simulation_inc.v delete mode 100644 tests/hana/test_simulation_inc_16_test.v delete mode 100644 tests/hana/test_simulation_inc_1_test.v delete mode 100644 tests/hana/test_simulation_inc_2_test.v delete mode 100644 tests/hana/test_simulation_inc_32_test.v delete mode 100644 tests/hana/test_simulation_inc_4_test.v delete mode 100644 tests/hana/test_simulation_inc_8_test.v delete mode 100644 tests/hana/test_simulation_mod_1_xx.v create mode 100644 tests/hana/test_simulation_mux.v delete mode 100644 tests/hana/test_simulation_mux_16_test.v delete mode 100644 tests/hana/test_simulation_mux_2_test.v delete mode 100644 tests/hana/test_simulation_mux_32_test.v delete mode 100644 tests/hana/test_simulation_mux_4_test.v delete mode 100644 tests/hana/test_simulation_mux_64_test.v delete mode 100644 tests/hana/test_simulation_mux_8_test.v create mode 100644 tests/hana/test_simulation_nand.v delete mode 100644 tests/hana/test_simulation_nand_1_test.v delete mode 100644 tests/hana/test_simulation_nand_3_test.v delete mode 100644 tests/hana/test_simulation_nand_4_test.v delete mode 100644 tests/hana/test_simulation_nand_5_test.v delete mode 100644 tests/hana/test_simulation_nand_6_test.v create mode 100644 tests/hana/test_simulation_nor.v delete mode 100644 tests/hana/test_simulation_nor_1_test.v delete mode 100644 tests/hana/test_simulation_nor_2_test.v delete mode 100644 tests/hana/test_simulation_nor_3_test.v delete mode 100644 tests/hana/test_simulation_nor_4_test.v delete mode 100644 tests/hana/test_simulation_opt_constprop_contassign_1_test.v create mode 100644 tests/hana/test_simulation_or.v delete mode 100644 tests/hana/test_simulation_or_1_test.v delete mode 100644 tests/hana/test_simulation_or_2_test.v delete mode 100644 tests/hana/test_simulation_or_3_test.v delete mode 100644 tests/hana/test_simulation_or_4_test.v delete mode 100644 tests/hana/test_simulation_or_5_test.v delete mode 100644 tests/hana/test_simulation_or_6_test.v create mode 100644 tests/hana/test_simulation_seq.v delete mode 100644 tests/hana/test_simulation_seq_ff_1_test.v delete mode 100644 tests/hana/test_simulation_seq_ff_2_test.v create mode 100644 tests/hana/test_simulation_shifter.v delete mode 100644 tests/hana/test_simulation_shifter_left_16_test.v delete mode 100644 tests/hana/test_simulation_shifter_left_32_test.v delete mode 100644 tests/hana/test_simulation_shifter_left_4_test.v delete mode 100644 tests/hana/test_simulation_shifter_left_64_test.v delete mode 100644 tests/hana/test_simulation_shifter_left_8_test.v delete mode 100644 tests/hana/test_simulation_shifter_right_16_test.v delete mode 100644 tests/hana/test_simulation_shifter_right_32_test.v delete mode 100644 tests/hana/test_simulation_shifter_right_4_test.v delete mode 100644 tests/hana/test_simulation_shifter_right_64_test.v delete mode 100644 tests/hana/test_simulation_shifter_right_8_test.v create mode 100644 tests/hana/test_simulation_sop.v delete mode 100644 tests/hana/test_simulation_sop_basic_10_test.v delete mode 100644 tests/hana/test_simulation_sop_basic_11_test.v delete mode 100644 tests/hana/test_simulation_sop_basic_12_test.v delete mode 100644 tests/hana/test_simulation_sop_basic_18_test.v delete mode 100644 tests/hana/test_simulation_sop_basic_3_test.v delete mode 100644 tests/hana/test_simulation_sop_basic_7_test.v delete mode 100644 tests/hana/test_simulation_sop_basic_8_test.v delete mode 100644 tests/hana/test_simulation_sop_basic_9_test.v rename tests/hana/{test_simulation_techmap_mux_128_test.v => test_simulation_techmap.v} (77%) delete mode 100644 tests/hana/test_simulation_techmap_and_19_tech.v delete mode 100644 tests/hana/test_simulation_techmap_and_5_tech.v delete mode 100644 tests/hana/test_simulation_techmap_buf_test.v delete mode 100644 tests/hana/test_simulation_techmap_inv_test.v delete mode 100644 tests/hana/test_simulation_techmap_mux_0_test.v delete mode 100644 tests/hana/test_simulation_techmap_mux_8_test.v delete mode 100644 tests/hana/test_simulation_techmap_nand_19_tech.v delete mode 100644 tests/hana/test_simulation_techmap_nand_2_tech.v delete mode 100644 tests/hana/test_simulation_techmap_nand_5_tech.v delete mode 100644 tests/hana/test_simulation_techmap_nor_19_tech.v delete mode 100644 tests/hana/test_simulation_techmap_nor_2_tech.v delete mode 100644 tests/hana/test_simulation_techmap_nor_5_tech.v delete mode 100644 tests/hana/test_simulation_techmap_or_19_tech.v delete mode 100644 tests/hana/test_simulation_techmap_or_5_tech.v create mode 100644 tests/hana/test_simulation_techmap_tech.v delete mode 100644 tests/hana/test_simulation_techmap_xnor_2_tech.v delete mode 100644 tests/hana/test_simulation_techmap_xnor_5_tech.v delete mode 100644 tests/hana/test_simulation_techmap_xor_19_tech.v delete mode 100644 tests/hana/test_simulation_techmap_xor_2_tech.v delete mode 100644 tests/hana/test_simulation_techmap_xor_5_tech.v delete mode 100644 tests/hana/test_simulation_tribuf_2_test.v rename tests/hana/{test_simulation_always_31_tt.v => test_simulation_vlib.v} (77%) create mode 100644 tests/hana/test_simulation_xnor.v delete mode 100644 tests/hana/test_simulation_xnor_1_test.v delete mode 100644 tests/hana/test_simulation_xnor_2_test.v delete mode 100644 tests/hana/test_simulation_xnor_3_test.v delete mode 100644 tests/hana/test_simulation_xnor_4_test.v create mode 100644 tests/hana/test_simulation_xor.v delete mode 100644 tests/hana/test_simulation_xor_1_test.v delete mode 100644 tests/hana/test_simulation_xor_2_test.v delete mode 100644 tests/hana/test_simulation_xor_3_test.v delete mode 100644 tests/hana/test_simulation_xor_4_test.v diff --git a/tests/hana/README b/tests/hana/README index 37049405..b2a08fd4 100644 --- a/tests/hana/README +++ b/tests/hana/README @@ -2,13 +2,3 @@ This test cases are copied from the hana project: https://sourceforge.net/projects/sim-sim/ -** Copy tests from hana: ** -while read fn; do cp -v $fn ALL_TESTS/${fn//\//_}; done < <(find test -name '*.v' ! -name '*_gold.v') - -** Eliminate test's we can't parse atm: ** -rm -f test_synthesizability*.v -rm -f test_parse2synthtrans_latch_1_test.v -rm -f test_parse2synthtrans_always_1_test.v -rm -f test_parse2synthtrans_always_2_test.v -for x in test_*.v; do ../../yosys -b "" $x || rm $x; done - diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh index 410f9b4d..d719c46b 100755 --- a/tests/hana/run-test.sh +++ b/tests/hana/run-test.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec ${MAKE:-make} -f ../tools/autotest.mk EXTRA_FLAGS="-l hana_vlib.v" test_*.v +exec ${MAKE:-make} -f ../tools/autotest.mk EXTRA_FLAGS="-l hana_vlib.v -n 300" test_*.v diff --git a/tests/hana/test_intermout.v b/tests/hana/test_intermout.v new file mode 100644 index 00000000..88b91ee4 --- /dev/null +++ b/tests/hana/test_intermout.v @@ -0,0 +1,418 @@ + +// test_intermout_always_comb_1_test.v +module f1_test(a, b, c, d, z); +input a, b, c, d; +output z; +reg z, temp1, temp2; + +always @(a or b or c or d) +begin + temp1 = a ^ b; + temp2 = c ^ d; + z = temp1 ^ temp2; +end + +endmodule + +// test_intermout_always_comb_3_test.v +module f2_test (in1, in2, out); +input in1, in2; +output reg out; + +always @ ( in1 or in2) + if(in1 > in2) + out = in1; + else + out = in2; +endmodule + +// test_intermout_always_comb_4_test.v +module f3_test(a, b, c); +input b, c; +output reg a; + +always @(b or c) begin +a = b; +a = c; +end +endmodule + +// test_intermout_always_comb_5_test.v +module f4_test(ctrl, in1, in2, out); +input ctrl; +input in1, in2; +output reg out; + +always @ (ctrl or in1 or in2) + if(ctrl) + out = in1 & in2; + else + out = in1 | in2; +endmodule + +// test_intermout_always_ff_3_test.v +module f5_NonBlockingEx(clk, merge, er, xmit, fddi, claim); +input clk, merge, er, xmit, fddi; +output reg claim; +reg fcr; + +always @(posedge clk) +begin + fcr = er | xmit; + + if(merge) + claim = fcr & fddi; + else + claim = fddi; +end +endmodule + +// test_intermout_always_ff_4_test.v +module f6_FlipFlop(clk, cs, ns); +input clk; +input [31:0] cs; +output [31:0] ns; +integer is; + +always @(posedge clk) + is <= cs; + +assign ns = is; +endmodule + +// test_intermout_always_ff_5_test.v +module f7_FlipFlop(clock, cs, ns); +input clock; +input [3:0] cs; +output reg [3:0] ns; +reg [3:0] temp; + +always @(posedge clock) +begin + temp = cs; + ns = temp; +end + +endmodule + +// test_intermout_always_ff_6_test.v +module f8_inc(clock, counter); + +input clock; +output reg [3:0] counter; +always @(posedge clock) + counter <= counter + 1; +endmodule + +// test_intermout_always_ff_8_test.v +module f9_NegEdgeClock(q, d, clk, reset); +input d, clk, reset; +output reg q; + +always @(negedge clk or negedge reset) + if(!reset) + q <= 1'b0; + else + q <= d; + +endmodule + +// test_intermout_always_ff_9_test.v +module f10_MyCounter (clock, preset, updown, presetdata, counter); +input clock, preset, updown; +input [1: 0] presetdata; +output reg [1:0] counter; + +always @(posedge clock) + if(preset) + counter <= presetdata; + else + if(updown) + counter <= counter + 1; + else + counter <= counter - 1; +endmodule + +// test_intermout_always_latch_1_test.v +module f11_test(en, in, out); +input en; +input [1:0] in; +output reg [2:0] out; + +always @ (en or in) + if(en) + out = in + 1; +endmodule + +// test_intermout_bufrm_1_test.v +module f12_test(input in, output out); +//no buffer removal +assign out = in; +endmodule + +// test_intermout_bufrm_2_test.v +module f13_test(input in, output out); +//intermediate buffers should be removed +wire w1, w2; +assign w1 = in; +assign w2 = w1; +assign out = w2; +endmodule + +// test_intermout_bufrm_6_test.v +module f14_test(in, out); +input in; +output out; + +wire w1, w2, w3, w4; +assign w1 = in; +assign w2 = w1; +assign w4 = w3; +assign out = w4; +f14_mybuf _f14_mybuf(w2, w3); +endmodule + +module f14_mybuf(in, out); +input in; +output out; +wire w1, w2, w3, w4; + +assign w1 = in; +assign w2 = w1; +assign out = w2; +endmodule + + +// test_intermout_bufrm_7_test.v +module f15_test(in1, in2, out); +input in1, in2; +output out; +// Y with cluster of f15_mybuf instances at the junction + +wire w1, w2, w3, w4, w5, w6, w7, w8, w9, w10; +assign w1 = in1; +assign w2 = w1; +assign w5 = in2; +assign w6 = w5; +assign w10 = w9; +assign out = w10; + +f15_mybuf _f15_mybuf0(w2, w3); +f15_mybuf _f15_mybuf1(w3, w4); + +f15_mybuf _f15_mybuf2(w6, w7); +f15_mybuf _f15_mybuf3(w7, w4); + +f15_mybuf _f15_mybuf4(w4, w8); +f15_mybuf _f15_mybuf5(w8, w9); +endmodule + +module f15_mybuf(in, out); +input in; +output out; +wire w1, w2, w3, w4; + +assign w1 = in; +assign w2 = w1; +assign out = w2; +endmodule + + +// test_intermout_exprs_add_test.v +module f16_test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 + in2; +assign vout1 = vin1 + vin2; +endmodule + +// test_intermout_exprs_binlogic_test.v +module f17_test(in1, in2, vin1, vin2, out, vout, vin3, vin4, vout1 ); +input in1, in2; +input [1:0] vin1; +input [3:0] vin2; +input [1:0] vin3; +input [3:0] vin4; +output vout, vout1; +output out; + +assign out = in1 && in2; +assign vout = vin1 && vin2; +assign vout1 = vin3 || vin4; +endmodule + +// test_intermout_exprs_bitwiseneg_test.v +module f18_test(output out, input in, output [1:0] vout, input [1:0] vin); + +assign out = ~in; +assign vout = ~vin; +endmodule + +// test_intermout_exprs_buffer_test.v +module f19_buffer(in, out, vin, vout); +input in; +output out; +input [1:0] vin; +output [1:0] vout; + +assign out = in; +assign vout = vin; +endmodule + +// test_intermout_exprs_condexpr_mux_test.v +module f20_test(in1, in2, out, vin1, vin2, vin3, vin4, vout1, vout2, en1, ven1, ven2); +input in1, in2, en1, ven1; +input [1:0] ven2; +output out; +input [1:0] vin1, vin2, vin3, vin4; +output [1:0] vout1, vout2; + +assign out = en1 ? in1 : in2; +assign vout1 = ven1 ? vin1 : vin2; +assign vout2 = ven2 ? vin3 : vin4; +endmodule + +// test_intermout_exprs_condexpr_tribuf_test.v +module f21_test(in, out, en, vin1, vout1, en1); +input in, en, en1; +output out; +input [1:0] vin1; +output [1:0] vout1; + +assign out = en ? in : 1'bz; +assign vout1 = en1 ? vin1 : 2'bzz; +endmodule + +// test_intermout_exprs_constshift_test.v +module f22_test(in, out, vin, vout, vin1, vout1, vin2, vout2); + +input in; +input [3:0] vin, vin1, vin2; +output [3:0] vout, vout1, vout2; +output out; + +assign out = in << 1; +assign vout = vin << 2; +assign vout1 = vin1 >> 2; +assign vout2 = vin2 >>> 2; +endmodule + +// test_intermout_exprs_const_test.v +module f23_test (out, vout); +output out; +output [7:0] vout; + +assign out = 1'b1; +assign vout = 9; +endmodule + +// test_intermout_exprs_div_test.v +module f24_test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 / in2; +assign vout1 = vin1 / vin2; +endmodule + +// test_intermout_exprs_logicneg_test.v +module f25_test(out, vout, in, vin); +output out, vout; +input in; +input [3:0] vin; +assign out = !in; +assign vout = !vin; +endmodule + +// test_intermout_exprs_mod_test.v +module f26_test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 % in2; +assign vout1 = vin1 % vin2; +endmodule + +// test_intermout_exprs_mul_test.v +module f27_test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 * in2; +assign vout1 = vin1 * vin2; +endmodule + +// test_intermout_exprs_redand_test.v +module f28_test(output out, input [1:0] vin, output out1, input [3:0] vin1); + +assign out = &vin; +assign out1 = &vin1; +endmodule + +// test_intermout_exprs_redop_test.v +module f29_Reduction (A1, A2, A3, A4, A5, A6, Y1, Y2, Y3, Y4, Y5, Y6); +input [1:0] A1; +input [1:0] A2; +input [1:0] A3; +input [1:0] A4; +input [1:0] A5; +input [1:0] A6; +output Y1, Y2, Y3, Y4, Y5, Y6; +//reg Y1, Y2, Y3, Y4, Y5, Y6; +assign Y1=&A1; //reduction AND +assign Y2=|A2; //reduction OR +assign Y3=~&A3; //reduction NAND +assign Y4=~|A4; //reduction NOR +assign Y5=^A5; //reduction XOR +assign Y6=~^A6; //reduction XNOR +endmodule + +// test_intermout_exprs_sub_test.v +module f30_test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 - in2; +assign vout1 = vin1 - vin2; +endmodule + +// test_intermout_exprs_unaryminus_test.v +module f31_test(output out, input in, output [31:0] vout, input [31:0] vin); + +assign out = -in; +assign vout = -vin; +endmodule + +// test_intermout_exprs_unaryplus_test.v +module f32_test(output out, input in); + +assign out = +in; +endmodule + +// test_intermout_exprs_varshift_test.v +module f33_test(vin0, vout0); +input [2:0] vin0; +output reg [7:0] vout0; + +wire [7:0] myreg0, myreg1, myreg2; +integer i; +assign myreg0 = vout0 << vin0; + +assign myreg1 = myreg2 >> i; +endmodule diff --git a/tests/hana/test_intermout_always_comb_1_test.v b/tests/hana/test_intermout_always_comb_1_test.v deleted file mode 100644 index 2d5abc4a..00000000 --- a/tests/hana/test_intermout_always_comb_1_test.v +++ /dev/null @@ -1,13 +0,0 @@ -module test(a, b, c, d, z); -input a, b, c, d; -output z; -reg z, temp1, temp2; - -always @(a or b or c or d) -begin - temp1 = a ^ b; - temp2 = c ^ d; - z = temp1 ^ temp2; -end - -endmodule diff --git a/tests/hana/test_intermout_always_comb_3_test.v b/tests/hana/test_intermout_always_comb_3_test.v deleted file mode 100644 index 234407ef..00000000 --- a/tests/hana/test_intermout_always_comb_3_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test (in1, in2, out); -input in1, in2; -output reg out; - -always @ ( in1 or in2) - if(in1 > in2) - out = in1; - else - out = in2; -endmodule diff --git a/tests/hana/test_intermout_always_comb_4_test.v b/tests/hana/test_intermout_always_comb_4_test.v deleted file mode 100644 index b0a94f29..00000000 --- a/tests/hana/test_intermout_always_comb_4_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module test(a, b, c); -input b, c; -output reg a; - -always @(b or c) begin -a = b; -a = c; -end -endmodule diff --git a/tests/hana/test_intermout_always_comb_5_test.v b/tests/hana/test_intermout_always_comb_5_test.v deleted file mode 100644 index 5152781d..00000000 --- a/tests/hana/test_intermout_always_comb_5_test.v +++ /dev/null @@ -1,11 +0,0 @@ -module test(ctrl, in1, in2, out); -input ctrl; -input in1, in2; -output reg out; - -always @ (ctrl or in1 or in2) - if(ctrl) - out = in1 & in2; - else - out = in1 | in2; -endmodule diff --git a/tests/hana/test_intermout_always_ff_3_test.v b/tests/hana/test_intermout_always_ff_3_test.v deleted file mode 100644 index ed8630c3..00000000 --- a/tests/hana/test_intermout_always_ff_3_test.v +++ /dev/null @@ -1,15 +0,0 @@ -module NonBlockingEx(clk, merge, er, xmit, fddi, claim); -input clk, merge, er, xmit, fddi; -output reg claim; -reg fcr; - -always @(posedge clk) -begin - fcr = er | xmit; - - if(merge) - claim = fcr & fddi; - else - claim = fddi; -end -endmodule diff --git a/tests/hana/test_intermout_always_ff_4_test.v b/tests/hana/test_intermout_always_ff_4_test.v deleted file mode 100644 index cac420a4..00000000 --- a/tests/hana/test_intermout_always_ff_4_test.v +++ /dev/null @@ -1,11 +0,0 @@ -module FlipFlop(clk, cs, ns); -input clk; -input [31:0] cs; -output [31:0] ns; -integer is; - -always @(posedge clk) - is <= cs; - -assign ns = is; -endmodule diff --git a/tests/hana/test_intermout_always_ff_5_test.v b/tests/hana/test_intermout_always_ff_5_test.v deleted file mode 100644 index 669b2a5f..00000000 --- a/tests/hana/test_intermout_always_ff_5_test.v +++ /dev/null @@ -1,13 +0,0 @@ -module FlipFlop(clock, cs, ns); -input clock; -input [3:0] cs; -output reg [3:0] ns; -reg [3:0] temp; - -always @(posedge clock) -begin - temp = cs; - ns = temp; -end - -endmodule diff --git a/tests/hana/test_intermout_always_ff_6_test.v b/tests/hana/test_intermout_always_ff_6_test.v deleted file mode 100644 index ad0a0df6..00000000 --- a/tests/hana/test_intermout_always_ff_6_test.v +++ /dev/null @@ -1,7 +0,0 @@ -module inc(clock, counter); - -input clock; -output reg [3:0] counter; -always @(posedge clock) - counter <= counter + 1; -endmodule diff --git a/tests/hana/test_intermout_always_ff_8_test.v b/tests/hana/test_intermout_always_ff_8_test.v deleted file mode 100644 index 0f29ea0a..00000000 --- a/tests/hana/test_intermout_always_ff_8_test.v +++ /dev/null @@ -1,11 +0,0 @@ -module NegEdgeClock(q, d, clk, reset); -input d, clk, reset; -output reg q; - -always @(negedge clk or negedge reset) - if(!reset) - q <= 1'b0; - else - q <= d; - -endmodule diff --git a/tests/hana/test_intermout_always_ff_9_test.v b/tests/hana/test_intermout_always_ff_9_test.v deleted file mode 100644 index f1f13bbe..00000000 --- a/tests/hana/test_intermout_always_ff_9_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module MyCounter (clock, preset, updown, presetdata, counter); -input clock, preset, updown; -input [1: 0] presetdata; -output reg [1:0] counter; - -always @(posedge clock) - if(preset) - counter <= presetdata; - else - if(updown) - counter <= counter + 1; - else - counter <= counter - 1; -endmodule diff --git a/tests/hana/test_intermout_always_latch_1_test.v b/tests/hana/test_intermout_always_latch_1_test.v deleted file mode 100644 index a83be20d..00000000 --- a/tests/hana/test_intermout_always_latch_1_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module test(en, in, out); -input en; -input [1:0] in; -output reg [2:0] out; - -always @ (en or in) - if(en) - out = in + 1; -endmodule diff --git a/tests/hana/test_intermout_bufrm_1_test.v b/tests/hana/test_intermout_bufrm_1_test.v deleted file mode 100644 index 8e3d4222..00000000 --- a/tests/hana/test_intermout_bufrm_1_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input in, output out); -//no buffer removal -assign out = in; -endmodule diff --git a/tests/hana/test_intermout_bufrm_2_test.v b/tests/hana/test_intermout_bufrm_2_test.v deleted file mode 100644 index 853f1dc9..00000000 --- a/tests/hana/test_intermout_bufrm_2_test.v +++ /dev/null @@ -1,7 +0,0 @@ -module test(input in, output out); -//intermediate buffers should be removed -wire w1, w2; -assign w1 = in; -assign w2 = w1; -assign out = w2; -endmodule diff --git a/tests/hana/test_intermout_bufrm_6_test.v b/tests/hana/test_intermout_bufrm_6_test.v deleted file mode 100644 index d4f3878d..00000000 --- a/tests/hana/test_intermout_bufrm_6_test.v +++ /dev/null @@ -1,22 +0,0 @@ -module test(in, out); -input in; -output out; - -wire w1, w2, w3, w4; -assign w1 = in; -assign w2 = w1; -assign w4 = w3; -assign out = w4; -mybuf _mybuf(w2, w3); -endmodule - -module mybuf(in, out); -input in; -output out; -wire w1, w2, w3, w4; - -assign w1 = in; -assign w2 = w1; -assign out = w2; -endmodule - diff --git a/tests/hana/test_intermout_bufrm_7_test.v b/tests/hana/test_intermout_bufrm_7_test.v deleted file mode 100644 index 7b651302..00000000 --- a/tests/hana/test_intermout_bufrm_7_test.v +++ /dev/null @@ -1,33 +0,0 @@ -module test(in1, in2, out); -input in1, in2; -output out; -// Y with cluster of mybuf instances at the junction - -wire w1, w2, w3, w4, w5, w6, w7, w8, w9, w10; -assign w1 = in1; -assign w2 = w1; -assign w5 = in2; -assign w6 = w5; -assign w10 = w9; -assign out = w10; - -mybuf _mybuf0(w2, w3); -mybuf _mybuf1(w3, w4); - -mybuf _mybuf2(w6, w7); -mybuf _mybuf3(w7, w4); - -mybuf _mybuf4(w4, w8); -mybuf _mybuf5(w8, w9); -endmodule - -module mybuf(in, out); -input in; -output out; -wire w1, w2, w3, w4; - -assign w1 = in; -assign w2 = w1; -assign out = w2; -endmodule - diff --git a/tests/hana/test_intermout_exprs_add_test.v b/tests/hana/test_intermout_exprs_add_test.v deleted file mode 100644 index ec70f347..00000000 --- a/tests/hana/test_intermout_exprs_add_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(out, in1, in2, vin1, vin2, vout1); -output out; -input in1, in2; -input [1:0] vin1; -input [2:0] vin2; -output [3:0] vout1; - -assign out = in1 + in2; -assign vout1 = vin1 + vin2; -endmodule diff --git a/tests/hana/test_intermout_exprs_binlogic_test.v b/tests/hana/test_intermout_exprs_binlogic_test.v deleted file mode 100644 index eec8c4b1..00000000 --- a/tests/hana/test_intermout_exprs_binlogic_test.v +++ /dev/null @@ -1,13 +0,0 @@ -module test(in1, in2, vin1, vin2, out, vout, vin3, vin4, vout1 ); -input in1, in2; -input [1:0] vin1; -input [3:0] vin2; -input [1:0] vin3; -input [3:0] vin4; -output vout, vout1; -output out; - -assign out = in1 && in2; -assign vout = vin1 && vin2; -assign vout1 = vin3 || vin4; -endmodule diff --git a/tests/hana/test_intermout_exprs_bitwiseneg_test.v b/tests/hana/test_intermout_exprs_bitwiseneg_test.v deleted file mode 100644 index 5b62bef0..00000000 --- a/tests/hana/test_intermout_exprs_bitwiseneg_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(output out, input in, output [1:0] vout, input [1:0] vin); - -assign out = ~in; -assign vout = ~vin; -endmodule diff --git a/tests/hana/test_intermout_exprs_buffer_test.v b/tests/hana/test_intermout_exprs_buffer_test.v deleted file mode 100644 index 2b4cbc3e..00000000 --- a/tests/hana/test_intermout_exprs_buffer_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module buffer(in, out, vin, vout); -input in; -output out; -input [1:0] vin; -output [1:0] vout; - -assign out = in; -assign vout = vin; -endmodule diff --git a/tests/hana/test_intermout_exprs_condexpr_mux_test.v b/tests/hana/test_intermout_exprs_condexpr_mux_test.v deleted file mode 100644 index 11006e8b..00000000 --- a/tests/hana/test_intermout_exprs_condexpr_mux_test.v +++ /dev/null @@ -1,11 +0,0 @@ -module test(in1, in2, out, vin1, vin2, vin3, vin4, vout1, vout2, en1, ven1, ven2); -input in1, in2, en1, ven1; -input [1:0] ven2; -output out; -input [1:0] vin1, vin2, vin3, vin4; -output [1:0] vout1, vout2; - -assign out = en1 ? in1 : in2; -assign vout1 = ven1 ? vin1 : vin2; -assign vout2 = ven2 ? vin3 : vin4; -endmodule diff --git a/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v b/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v deleted file mode 100644 index 5b778fe9..00000000 --- a/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module test(in, out, en, vin1, vout1, en1); -input in, en, en1; -output out; -input [1:0] vin1; -output [1:0] vout1; - -assign out = en ? in : 1'bz; -assign vout1 = en1 ? vin1 : 2'bzz; -endmodule diff --git a/tests/hana/test_intermout_exprs_const_test.v b/tests/hana/test_intermout_exprs_const_test.v deleted file mode 100644 index 484d8103..00000000 --- a/tests/hana/test_intermout_exprs_const_test.v +++ /dev/null @@ -1,7 +0,0 @@ -module test (out, vout); -output out; -output [7:0] vout; - -assign out = 1'b1; -assign vout = 9; -endmodule diff --git a/tests/hana/test_intermout_exprs_constshift_test.v b/tests/hana/test_intermout_exprs_constshift_test.v deleted file mode 100644 index eb21315d..00000000 --- a/tests/hana/test_intermout_exprs_constshift_test.v +++ /dev/null @@ -1,12 +0,0 @@ -module test(in, out, vin, vout, vin1, vout1, vin2, vout2); - -input in; -input [3:0] vin, vin1, vin2; -output [3:0] vout, vout1, vout2; -output out; - -assign out = in << 1; -assign vout = vin << 2; -assign vout1 = vin1 >> 2; -assign vout2 = vin2 >>> 2; -endmodule diff --git a/tests/hana/test_intermout_exprs_div_test.v b/tests/hana/test_intermout_exprs_div_test.v deleted file mode 100644 index 21765fcd..00000000 --- a/tests/hana/test_intermout_exprs_div_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(out, in1, in2, vin1, vin2, vout1); -output out; -input in1, in2; -input [1:0] vin1; -input [2:0] vin2; -output [3:0] vout1; - -assign out = in1 / in2; -assign vout1 = vin1 / vin2; -endmodule diff --git a/tests/hana/test_intermout_exprs_logicneg_test.v b/tests/hana/test_intermout_exprs_logicneg_test.v deleted file mode 100644 index b45b32b9..00000000 --- a/tests/hana/test_intermout_exprs_logicneg_test.v +++ /dev/null @@ -1,7 +0,0 @@ -module test(out, vout, in, vin); -output out, vout; -input in; -input [3:0] vin; -assign out = !in; -assign vout = !vin; -endmodule diff --git a/tests/hana/test_intermout_exprs_mod_test.v b/tests/hana/test_intermout_exprs_mod_test.v deleted file mode 100644 index cea6b02d..00000000 --- a/tests/hana/test_intermout_exprs_mod_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(out, in1, in2, vin1, vin2, vout1); -output out; -input in1, in2; -input [1:0] vin1; -input [2:0] vin2; -output [3:0] vout1; - -assign out = in1 % in2; -assign vout1 = vin1 % vin2; -endmodule diff --git a/tests/hana/test_intermout_exprs_mul_test.v b/tests/hana/test_intermout_exprs_mul_test.v deleted file mode 100644 index f9973dad..00000000 --- a/tests/hana/test_intermout_exprs_mul_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(out, in1, in2, vin1, vin2, vout1); -output out; -input in1, in2; -input [1:0] vin1; -input [2:0] vin2; -output [3:0] vout1; - -assign out = in1 * in2; -assign vout1 = vin1 * vin2; -endmodule diff --git a/tests/hana/test_intermout_exprs_redand_test.v b/tests/hana/test_intermout_exprs_redand_test.v deleted file mode 100644 index 35fdf73a..00000000 --- a/tests/hana/test_intermout_exprs_redand_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(output out, input [1:0] vin, output out1, input [3:0] vin1); - -assign out = &vin; -assign out1 = &vin1; -endmodule diff --git a/tests/hana/test_intermout_exprs_redop_test.v b/tests/hana/test_intermout_exprs_redop_test.v deleted file mode 100644 index 93fdb2e5..00000000 --- a/tests/hana/test_intermout_exprs_redop_test.v +++ /dev/null @@ -1,16 +0,0 @@ -module Reduction (A1, A2, A3, A4, A5, A6, Y1, Y2, Y3, Y4, Y5, Y6); -input [1:0] A1; -input [1:0] A2; -input [1:0] A3; -input [1:0] A4; -input [1:0] A5; -input [1:0] A6; -output Y1, Y2, Y3, Y4, Y5, Y6; -//reg Y1, Y2, Y3, Y4, Y5, Y6; -assign Y1=&A1; //reduction AND -assign Y2=|A2; //reduction OR -assign Y3=~&A3; //reduction NAND -assign Y4=~|A4; //reduction NOR -assign Y5=^A5; //reduction XOR -assign Y6=~^A6; //reduction XNOR -endmodule diff --git a/tests/hana/test_intermout_exprs_sub_test.v b/tests/hana/test_intermout_exprs_sub_test.v deleted file mode 100644 index 06e3a814..00000000 --- a/tests/hana/test_intermout_exprs_sub_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(out, in1, in2, vin1, vin2, vout1); -output out; -input in1, in2; -input [1:0] vin1; -input [2:0] vin2; -output [3:0] vout1; - -assign out = in1 - in2; -assign vout1 = vin1 - vin2; -endmodule diff --git a/tests/hana/test_intermout_exprs_unaryminus_test.v b/tests/hana/test_intermout_exprs_unaryminus_test.v deleted file mode 100644 index ee3f229a..00000000 --- a/tests/hana/test_intermout_exprs_unaryminus_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(output out, input in, output [31:0] vout, input [31:0] vin); - -assign out = -in; -assign vout = -vin; -endmodule diff --git a/tests/hana/test_intermout_exprs_unaryplus_test.v b/tests/hana/test_intermout_exprs_unaryplus_test.v deleted file mode 100644 index 07be5b24..00000000 --- a/tests/hana/test_intermout_exprs_unaryplus_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(output out, input in); - -assign out = +in; -endmodule diff --git a/tests/hana/test_intermout_exprs_varshift_test.v b/tests/hana/test_intermout_exprs_varshift_test.v deleted file mode 100644 index 2ca35c09..00000000 --- a/tests/hana/test_intermout_exprs_varshift_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(vin0, vout0); -input [2:0] vin0; -output reg [7:0] vout0; - -wire [7:0] myreg0, myreg1, myreg2; -integer i; -assign myreg0 = vout0 << vin0; - -assign myreg1 = myreg2 >> i; -endmodule diff --git a/tests/hana/test_parse2synthtrans.v b/tests/hana/test_parse2synthtrans.v new file mode 100644 index 00000000..a1c0bfdb --- /dev/null +++ b/tests/hana/test_parse2synthtrans.v @@ -0,0 +1,117 @@ + +// test_parse2synthtrans_behavopt_1_test.v +module f1_test(in, out, clk, reset); +input in, reset; +output reg out; +input clk; +reg signed [3:0] a; +reg signed [3:0] b; +reg signed [3:0] c; +reg [5:0] d; +reg [5:0] e; + +always @(clk or reset) begin + a = -4; + b = 2; + c = a + b; + d = a + b + c; + d = d*d; + if(b) + e = d*d; + else + e = d + d; +end +endmodule + +// test_parse2synthtrans_case_1_test.v +module f2_demultiplexer1_to_4 (out0, out1, out2, out3, in, s1, s0); +output out0, out1, out2, out3; +reg out0, out1, out2, out3; +input in; +input s1, s0; +reg [3:0] encoding; +reg [1:0] state; + always @(encoding) begin + case (encoding) + 4'bxx11: state = 1; + 4'bx0xx: state = 3; + 4'b11xx: state = 4; + 4'bx1xx: state = 2; + 4'bxx1x: state = 1; + 4'bxxx1: state = 0; + default: state = 0; + endcase + end + + always @(encoding) begin + case (encoding) + 4'b0000: state = 1; + default: state = 0; + endcase + end +endmodule + +// test_parse2synthtrans_contassign_1_test.v +module f3_test(in, out); + +input wire in; +output out; +assign out = (in+in); +assign out = 74; +endmodule + +// test_parse2synthtrans_module_basic0_test.v +module f4_test; +endmodule + +// test_parse2synthtrans_operators_1_test.v +module f5_test(in, out); +input in; +output out; +parameter p1 = 10; +parameter p2 = 5; + +assign out = +p1; +assign out = -p2; +assign out = p1 + p2; +assign out = p1 - p2; +endmodule + +// test_parse2synthtrans_param_1_test.v +module f6_test(in, out); +input in; +output out; +parameter p = 10; + +assign out = p; +endmodule + +// test_parse2synthtrans_port_scalar_1_test.v +module f7_test(in, out, io); +inout io; +output out; +input in; + +endmodule + +// test_parse2synthtrans_port_vector_1_test.v +module f8_test(in1, in2, out1, out2, io1, io2); +inout [1:0] io1; +inout [0:1] io2; +output [1:0] out1; +output [0:1] out2; +input [1:0] in1; +input [0:1] in2; + +endmodule + +// test_parse2synthtrans_v2k_comb_logic_sens_list_test.v +module f9_test(q, d, clk, reset); +output reg q; +input d, clk, reset; + +always @ (posedge clk, negedge reset) + if(!reset) q <= 0; + else q <= d; + +endmodule diff --git a/tests/hana/test_parse2synthtrans_behavopt_1_test.v b/tests/hana/test_parse2synthtrans_behavopt_1_test.v deleted file mode 100644 index c825739c..00000000 --- a/tests/hana/test_parse2synthtrans_behavopt_1_test.v +++ /dev/null @@ -1,22 +0,0 @@ -module test(in, out, clk, reset); -input in, reset; -output reg out; -input clk; -reg signed [3:0] a; -reg signed [3:0] b; -reg signed [3:0] c; -reg [5:0] d; -reg [5:0] e; - -always @(clk or reset) begin - a = -4; - b = 2; - c = a + b; - d = a + b + c; - d = d*d; - if(b) - e = d*d; - else - e = d + d; -end -endmodule diff --git a/tests/hana/test_parse2synthtrans_case_1_test.v b/tests/hana/test_parse2synthtrans_case_1_test.v deleted file mode 100644 index 348c566a..00000000 --- a/tests/hana/test_parse2synthtrans_case_1_test.v +++ /dev/null @@ -1,26 +0,0 @@ -module demultiplexer1_to_4 (out0, out1, out2, out3, in, s1, s0); -output out0, out1, out2, out3; -reg out0, out1, out2, out3; -input in; -input s1, s0; -reg [3:0] encoding; -reg [1:0] state; - always @(encoding) begin - case (encoding) - 4'bxx11: state = 1; - 4'bx0xx: state = 3; - 4'b11xx: state = 4; - 4'bx1xx: state = 2; - 4'bxx1x: state = 1; - 4'bxxx1: state = 0; - default: state = 0; - endcase - end - - always @(encoding) begin - case (encoding) - 4'b0000: state = 1; - default: state = 0; - endcase - end -endmodule diff --git a/tests/hana/test_parse2synthtrans_contassign_1_test.v b/tests/hana/test_parse2synthtrans_contassign_1_test.v deleted file mode 100644 index 78bf0077..00000000 --- a/tests/hana/test_parse2synthtrans_contassign_1_test.v +++ /dev/null @@ -1,7 +0,0 @@ -module test(in, out); - -input wire in; -output out; -assign out = (in+in); -assign out = 74; -endmodule diff --git a/tests/hana/test_parse2synthtrans_module_basic0_test.v b/tests/hana/test_parse2synthtrans_module_basic0_test.v deleted file mode 100644 index 67a272df..00000000 --- a/tests/hana/test_parse2synthtrans_module_basic0_test.v +++ /dev/null @@ -1,2 +0,0 @@ -module test; -endmodule diff --git a/tests/hana/test_parse2synthtrans_operators_1_test.v b/tests/hana/test_parse2synthtrans_operators_1_test.v deleted file mode 100644 index 93b5691f..00000000 --- a/tests/hana/test_parse2synthtrans_operators_1_test.v +++ /dev/null @@ -1,11 +0,0 @@ -module test(in, out); -input in; -output out; -parameter p1 = 10; -parameter p2 = 5; - -assign out = +p1; -assign out = -p2; -assign out = p1 + p2; -assign out = p1 - p2; -endmodule diff --git a/tests/hana/test_parse2synthtrans_param_1_test.v b/tests/hana/test_parse2synthtrans_param_1_test.v deleted file mode 100644 index 146eedf4..00000000 --- a/tests/hana/test_parse2synthtrans_param_1_test.v +++ /dev/null @@ -1,7 +0,0 @@ -module test(in, out); -input in; -output out; -parameter p = 10; - -assign out = p; -endmodule diff --git a/tests/hana/test_parse2synthtrans_port_scalar_1_test.v b/tests/hana/test_parse2synthtrans_port_scalar_1_test.v deleted file mode 100644 index 8cdf495a..00000000 --- a/tests/hana/test_parse2synthtrans_port_scalar_1_test.v +++ /dev/null @@ -1,6 +0,0 @@ -module test(in, out, io); -inout io; -output out; -input in; - -endmodule diff --git a/tests/hana/test_parse2synthtrans_port_vector_1_test.v b/tests/hana/test_parse2synthtrans_port_vector_1_test.v deleted file mode 100644 index a740282b..00000000 --- a/tests/hana/test_parse2synthtrans_port_vector_1_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module test(in1, in2, out1, out2, io1, io2); -inout [1:0] io1; -inout [0:1] io2; -output [1:0] out1; -output [0:1] out2; -input [1:0] in1; -input [0:1] in2; - -endmodule diff --git a/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v b/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v deleted file mode 100644 index 50f1d353..00000000 --- a/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module test(q, d, clk, reset); -output reg q; -input d, clk, reset; - -always @ (posedge clk, negedge reset) - if(!reset) q <= 0; - else q <= d; - -endmodule diff --git a/tests/hana/test_parser.v b/tests/hana/test_parser.v new file mode 100644 index 00000000..c7305356 --- /dev/null +++ b/tests/hana/test_parser.v @@ -0,0 +1,87 @@ + +// test_parser_constructs_module_basic1_test.v +module f1_test; +endmodule + +// test_parser_constructs_param_basic0_test.v +module f2_test #( parameter v2kparam = 5) +(in, out, io, vin, vout, vio); +input in; +output out; +inout io; +input [3:0] vin; +output [v2kparam:0] vout; +inout [0:3] vio; +parameter myparam = 10; +endmodule + +// test_parser_constructs_port_basic0_test.v +module f3_test(in, out, io, vin, vout, vio); +input in; +output out; +inout io; +input [3:0] vin; +output [3:0] vout; +inout [0:3] vio; +endmodule + +// test_parser_directives_define_simpledef_test.v +`define parvez ahmad +`define WIRE wire +`define TEN 10 + +module f4_`parvez(); +parameter param = `TEN; +`WIRE w; +assign w = `TEN; +endmodule + +// test_parser_misc_operators_test.v +module f5_test(out, i0, i1, i2, i3, s1, s0); +output out; +input i0, i1, i2, i3; +input s1, s0; + +assign out = (~s1 & s0 & i0) | + (~s1 & s0 & i1) | + (s1 & ~s0 & i2) | + (s1 & s0 & i3); + +endmodule + +module f5_ternaryop(out, i0, i1, i2, i3, s1, s0); +output out; +input i0, i1, i2, i3; +input s1, s0; + +assign out = s1 ? (s0 ? i3 : i2) : (s0 ? i1 : i0); + +endmodule + +module f5_fulladd4(sum, c_out, a, b, c_in); +output [3:0] sum; +output c_out; +input [3:0] a, b; +input c_in; + +assign {c_out, sum} = a + b + c_in; +endmodule + +// test_parser_v2k_comb_port_data_type_test.v +module f6_adder(sum , co, a, b, ci); +output reg [31:0] sum; +output reg co; +input wire [31:0] a, b; +input wire ci; +endmodule + +// test_parser_v2k_comma_sep_sens_list_test.v +module f7_test(q, d, clk, reset); +output reg q; +input d, clk, reset; + +always @ (posedge clk, negedge reset) + if(!reset) q <= 0; + else q <= d; + +endmodule diff --git a/tests/hana/test_parser_constructs_module_basic1_test.v b/tests/hana/test_parser_constructs_module_basic1_test.v deleted file mode 100644 index 67a272df..00000000 --- a/tests/hana/test_parser_constructs_module_basic1_test.v +++ /dev/null @@ -1,2 +0,0 @@ -module test; -endmodule diff --git a/tests/hana/test_parser_constructs_param_basic0_test.v b/tests/hana/test_parser_constructs_param_basic0_test.v deleted file mode 100644 index fd679230..00000000 --- a/tests/hana/test_parser_constructs_param_basic0_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test #( parameter v2kparam = 5) -(in, out, io, vin, vout, vio); -input in; -output out; -inout io; -input [3:0] vin; -output [v2kparam:0] vout; -inout [0:3] vio; -parameter myparam = 10; -endmodule diff --git a/tests/hana/test_parser_constructs_port_basic0_test.v b/tests/hana/test_parser_constructs_port_basic0_test.v deleted file mode 100644 index 8478e31d..00000000 --- a/tests/hana/test_parser_constructs_port_basic0_test.v +++ /dev/null @@ -1,8 +0,0 @@ -module test(in, out, io, vin, vout, vio); -input in; -output out; -inout io; -input [3:0] vin; -output [3:0] vout; -inout [0:3] vio; -endmodule diff --git a/tests/hana/test_parser_directives_define_simpledef_test.v b/tests/hana/test_parser_directives_define_simpledef_test.v deleted file mode 100644 index 4a5d2345..00000000 --- a/tests/hana/test_parser_directives_define_simpledef_test.v +++ /dev/null @@ -1,9 +0,0 @@ -`define parvez ahmad -`define WIRE wire -`define TEN 10 - -module `parvez(); -parameter param = `TEN; -`WIRE w; -assign w = `TEN; -endmodule diff --git a/tests/hana/test_parser_misc_operators_test.v b/tests/hana/test_parser_misc_operators_test.v deleted file mode 100644 index 8fe8e7ba..00000000 --- a/tests/hana/test_parser_misc_operators_test.v +++ /dev/null @@ -1,29 +0,0 @@ -module test(out, i0, i1, i2, i3, s1, s0); -output out; -input i0, i1, i2, i3; -input s1, s0; - -assign out = (~s1 & s0 & i0) | - (~s1 & s0 & i1) | - (s1 & ~s0 & i2) | - (s1 & s0 & i3); - -endmodule - -module ternaryop(out, i0, i1, i2, i3, s1, s0); -output out; -input i0, i1, i2, i3; -input s1, s0; - -assign out = s1 ? (s0 ? i3 : i2) : (s0 ? i1 : i0); - -endmodule - -module fulladd4(sum, c_out, a, b, c_in); -output [3:0] sum; -output c_out; -input [3:0] a, b; -input c_in; - -assign {c_out, sum} = a + b + c_in; -endmodule diff --git a/tests/hana/test_parser_v2k_comb_port_data_type_test.v b/tests/hana/test_parser_v2k_comb_port_data_type_test.v deleted file mode 100644 index 099585b5..00000000 --- a/tests/hana/test_parser_v2k_comb_port_data_type_test.v +++ /dev/null @@ -1,6 +0,0 @@ -module adder(sum , co, a, b, ci); -output reg [31:0] sum; -output reg co; -input wire [31:0] a, b; -input wire ci; -endmodule diff --git a/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v b/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v deleted file mode 100644 index 50f1d353..00000000 --- a/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module test(q, d, clk, reset); -output reg q; -input d, clk, reset; - -always @ (posedge clk, negedge reset) - if(!reset) q <= 0; - else q <= d; - -endmodule diff --git a/tests/hana/test_simulation_always.v b/tests/hana/test_simulation_always.v new file mode 100644 index 00000000..3ee75313 --- /dev/null +++ b/tests/hana/test_simulation_always.v @@ -0,0 +1,135 @@ + +// test_simulation_always_15_test.v +module f1_test(input [1:0] in, output reg [1:0] out); + +always @(in) + out = in; +endmodule + +// test_simulation_always_17_test.v +module f2_test(a, b, c, d, z); +input a, b, c, d; +output z; +reg z, temp1, temp2; + +always @(a or b or c or d) +begin + temp1 = a ^ b; + temp2 = c ^ d; + z = temp1 ^ temp2; +end + +endmodule + +// test_simulation_always_18_test.v +module f3_test (in1, in2, out); +input in1, in2; +output reg out; + +always @ ( in1 or in2) + if(in1 > in2) + out = in1; + else + out = in2; +endmodule + +// test_simulation_always_19_test.v +module f4_test(ctrl, in1, in2, out); +input ctrl; +input in1, in2; +output reg out; + +always @ (ctrl or in1 or in2) + if(ctrl) + out = in1 & in2; + else + out = in1 | in2; +endmodule + +// test_simulation_always_1_test.v +module f5_test(input in, output reg out); + +always @(in) + out = in; +endmodule + +// test_simulation_always_20_test.v +module f6_NonBlockingEx(clk, merge, er, xmit, fddi, claim); +input clk, merge, er, xmit, fddi; +output reg claim; +reg fcr; + +always @(posedge clk) +begin + fcr <= er | xmit; + + if(merge) + claim <= fcr & fddi; + else + claim <= fddi; +end +endmodule + +// test_simulation_always_21_test.v +module f7_FlipFlop(clk, cs, ns); +input clk; +input [7:0] cs; +output [7:0] ns; +integer is; + +always @(posedge clk) + is <= cs; + +assign ns = is; +endmodule + +// test_simulation_always_22_test.v +module f8_inc(clock, counter); + +input clock; +output reg [7:0] counter; +always @(posedge clock) + counter <= counter + 1; +endmodule + +// test_simulation_always_23_test.v +module f9_MyCounter (clock, preset, updown, presetdata, counter); +input clock, preset, updown; +input [1: 0] presetdata; +output reg [1:0] counter; + +always @(posedge clock) + if(preset) + counter <= presetdata; + else + if(updown) + counter <= counter + 1; + else + counter <= counter - 1; +endmodule + +// test_simulation_always_27_test.v +module f10_FlipFlop(clock, cs, ns); +input clock; +input cs; +output reg ns; +reg temp; + +always @(posedge clock) +begin + temp <= cs; + ns <= temp; +end + +endmodule + +// test_simulation_always_29_test.v +module f11_test(input in, output reg [1:0] out); + + always @(in) + begin + out = in; + out = out + in; + end + +endmodule diff --git a/tests/hana/test_simulation_always_15_test.v b/tests/hana/test_simulation_always_15_test.v deleted file mode 100644 index 5c5fed5b..00000000 --- a/tests/hana/test_simulation_always_15_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input [1:0] in, output reg [1:0] out); - -always @(in) - out = in; -endmodule diff --git a/tests/hana/test_simulation_always_17_test.v b/tests/hana/test_simulation_always_17_test.v deleted file mode 100644 index 2d5abc4a..00000000 --- a/tests/hana/test_simulation_always_17_test.v +++ /dev/null @@ -1,13 +0,0 @@ -module test(a, b, c, d, z); -input a, b, c, d; -output z; -reg z, temp1, temp2; - -always @(a or b or c or d) -begin - temp1 = a ^ b; - temp2 = c ^ d; - z = temp1 ^ temp2; -end - -endmodule diff --git a/tests/hana/test_simulation_always_18_test.v b/tests/hana/test_simulation_always_18_test.v deleted file mode 100644 index 234407ef..00000000 --- a/tests/hana/test_simulation_always_18_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test (in1, in2, out); -input in1, in2; -output reg out; - -always @ ( in1 or in2) - if(in1 > in2) - out = in1; - else - out = in2; -endmodule diff --git a/tests/hana/test_simulation_always_19_test.v b/tests/hana/test_simulation_always_19_test.v deleted file mode 100644 index 5152781d..00000000 --- a/tests/hana/test_simulation_always_19_test.v +++ /dev/null @@ -1,11 +0,0 @@ -module test(ctrl, in1, in2, out); -input ctrl; -input in1, in2; -output reg out; - -always @ (ctrl or in1 or in2) - if(ctrl) - out = in1 & in2; - else - out = in1 | in2; -endmodule diff --git a/tests/hana/test_simulation_always_1_test.v b/tests/hana/test_simulation_always_1_test.v deleted file mode 100644 index 211369cb..00000000 --- a/tests/hana/test_simulation_always_1_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input in, output reg out); - -always @(in) - out = in; -endmodule diff --git a/tests/hana/test_simulation_always_20_test.v b/tests/hana/test_simulation_always_20_test.v deleted file mode 100644 index 6b3e861d..00000000 --- a/tests/hana/test_simulation_always_20_test.v +++ /dev/null @@ -1,15 +0,0 @@ -module NonBlockingEx(clk, merge, er, xmit, fddi, claim); -input clk, merge, er, xmit, fddi; -output reg claim; -reg fcr; - -always @(posedge clk) -begin - fcr <= er | xmit; - - if(merge) - claim <= fcr & fddi; - else - claim <= fddi; -end -endmodule diff --git a/tests/hana/test_simulation_always_21_test.v b/tests/hana/test_simulation_always_21_test.v deleted file mode 100644 index 6c47b4bd..00000000 --- a/tests/hana/test_simulation_always_21_test.v +++ /dev/null @@ -1,11 +0,0 @@ -module FlipFlop(clk, cs, ns); -input clk; -input [7:0] cs; -output [7:0] ns; -integer is; - -always @(posedge clk) - is <= cs; - -assign ns = is; -endmodule diff --git a/tests/hana/test_simulation_always_22_test.v b/tests/hana/test_simulation_always_22_test.v deleted file mode 100644 index 8d91f815..00000000 --- a/tests/hana/test_simulation_always_22_test.v +++ /dev/null @@ -1,7 +0,0 @@ -module inc(clock, counter); - -input clock; -output reg [7:0] counter; -always @(posedge clock) - counter <= counter + 1; -endmodule diff --git a/tests/hana/test_simulation_always_23_test.v b/tests/hana/test_simulation_always_23_test.v deleted file mode 100644 index f1f13bbe..00000000 --- a/tests/hana/test_simulation_always_23_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module MyCounter (clock, preset, updown, presetdata, counter); -input clock, preset, updown; -input [1: 0] presetdata; -output reg [1:0] counter; - -always @(posedge clock) - if(preset) - counter <= presetdata; - else - if(updown) - counter <= counter + 1; - else - counter <= counter - 1; -endmodule diff --git a/tests/hana/test_simulation_always_27_test.v b/tests/hana/test_simulation_always_27_test.v deleted file mode 100644 index 577378fd..00000000 --- a/tests/hana/test_simulation_always_27_test.v +++ /dev/null @@ -1,13 +0,0 @@ -module FlipFlop(clock, cs, ns); -input clock; -input cs; -output reg ns; -reg temp; - -always @(posedge clock) -begin - temp <= cs; - ns <= temp; -end - -endmodule diff --git a/tests/hana/test_simulation_always_29_test.v b/tests/hana/test_simulation_always_29_test.v deleted file mode 100644 index 55606832..00000000 --- a/tests/hana/test_simulation_always_29_test.v +++ /dev/null @@ -1,9 +0,0 @@ -module test(input in, output reg [1:0] out); - - always @(in) - begin - out = in; - out = out + in; - end - -endmodule diff --git a/tests/hana/test_simulation_and.v b/tests/hana/test_simulation_and.v new file mode 100644 index 00000000..480e733d --- /dev/null +++ b/tests/hana/test_simulation_and.v @@ -0,0 +1,35 @@ + +// test_simulation_and_1_test.v +module f1_test(input [1:0] in, output out); +assign out = in[0] & in[1]; +endmodule + +// test_simulation_and_2_test.v +module f2_test(input [1:0] in, output out); +assign out = in[0] && in[1]; +endmodule + +// test_simulation_and_3_test.v +module f3_test(input [2:0] in, output out); +assign out = in[0] & in[1] & in[2]; +endmodule + +// test_simulation_and_4_test.v +module f4_test(input [2:0] in, output out); +assign out = in[0] && in[1] && in[2]; +endmodule + +// test_simulation_and_5_test.v +module f5_test(input [3:0] in, output out); +assign out = in[0] & in[1] & in[2] & in[3]; +endmodule + +// test_simulation_and_6_test.v +module f6_test(input [3:0] in, output out); +assign out = in[0] && in[1] && in[2] && in[3]; +endmodule + +// test_simulation_and_7_test.v +module f7_test(input [3:0] in, output out); +and myand(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/hana/test_simulation_and_1_test.v b/tests/hana/test_simulation_and_1_test.v deleted file mode 100644 index fba639ca..00000000 --- a/tests/hana/test_simulation_and_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = in[0] & in[1]; -endmodule diff --git a/tests/hana/test_simulation_and_2_test.v b/tests/hana/test_simulation_and_2_test.v deleted file mode 100644 index 715bc7ca..00000000 --- a/tests/hana/test_simulation_and_2_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = in[0] && in[1]; -endmodule diff --git a/tests/hana/test_simulation_and_3_test.v b/tests/hana/test_simulation_and_3_test.v deleted file mode 100644 index 74dccabf..00000000 --- a/tests/hana/test_simulation_and_3_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = in[0] & in[1] & in[2]; -endmodule diff --git a/tests/hana/test_simulation_and_4_test.v b/tests/hana/test_simulation_and_4_test.v deleted file mode 100644 index 48ed9102..00000000 --- a/tests/hana/test_simulation_and_4_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = in[0] && in[1] && in[2]; -endmodule diff --git a/tests/hana/test_simulation_and_5_test.v b/tests/hana/test_simulation_and_5_test.v deleted file mode 100644 index 29a35578..00000000 --- a/tests/hana/test_simulation_and_5_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = in[0] & in[1] & in[2] & in[3]; -endmodule diff --git a/tests/hana/test_simulation_and_6_test.v b/tests/hana/test_simulation_and_6_test.v deleted file mode 100644 index ebce4eeb..00000000 --- a/tests/hana/test_simulation_and_6_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = in[0] && in[1] && in[2] && in[3]; -endmodule diff --git a/tests/hana/test_simulation_and_7_test.v b/tests/hana/test_simulation_and_7_test.v deleted file mode 100644 index d394adad..00000000 --- a/tests/hana/test_simulation_and_7_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -and myand(out, in[0], in[1], in[2], in[3]); -endmodule diff --git a/tests/hana/test_simulation_buffer.v b/tests/hana/test_simulation_buffer.v new file mode 100644 index 00000000..d674b05c --- /dev/null +++ b/tests/hana/test_simulation_buffer.v @@ -0,0 +1,17 @@ + +// test_simulation_buffer_1_test.v +module f1_test(input in, output out); +assign out = in; +endmodule + +// test_simulation_buffer_2_test.v +module f2_test(input [1:0] in, output [1:0] out); +assign out[0] = in[0]; +assign out[1] = in[1]; +endmodule + +// test_simulation_buffer_3_test.v +module f3_test(input in, output [1:0] out); +assign out[0] = in; +assign out[1] = in; +endmodule diff --git a/tests/hana/test_simulation_buffer_1_test.v b/tests/hana/test_simulation_buffer_1_test.v deleted file mode 100644 index e9bb7f61..00000000 --- a/tests/hana/test_simulation_buffer_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input in, output out); -assign out = in; -endmodule diff --git a/tests/hana/test_simulation_buffer_2_test.v b/tests/hana/test_simulation_buffer_2_test.v deleted file mode 100644 index 9a3f5aa3..00000000 --- a/tests/hana/test_simulation_buffer_2_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [1:0] in, output [1:0] out); -assign out[0] = in[0]; -assign out[1] = in[1]; -endmodule diff --git a/tests/hana/test_simulation_buffer_3_test.v b/tests/hana/test_simulation_buffer_3_test.v deleted file mode 100644 index 9bca426d..00000000 --- a/tests/hana/test_simulation_buffer_3_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input in, output [1:0] out); -assign out[0] = in; -assign out[1] = in; -endmodule diff --git a/tests/hana/test_simulation_decoder_8_test.v b/tests/hana/test_simulation_decoder.v similarity index 56% rename from tests/hana/test_simulation_decoder_8_test.v rename to tests/hana/test_simulation_decoder.v index 751d60f6..ef9045aa 100644 --- a/tests/hana/test_simulation_decoder_8_test.v +++ b/tests/hana/test_simulation_decoder.v @@ -1,4 +1,147 @@ -module test (input [5:0] in, input enable, output reg [63:0] out); + +// test_simulation_decoder_2_test.v +module f1_test (input [1:0] in, input enable, output reg out); + +always @(in or enable) + if(!enable) + out = 4'b0000; + else begin + case (in) + 2'b00 : out = 0 ; + 2'b01 : out = 1; + 2'b10 : out = 0; + 2'b11 : out = 1; + endcase + end +endmodule + +// test_simulation_decoder_3_test.v +module f2_test (input [1:0] in, input enable, output reg [2:0] out); + +always @(in or enable) + if(!enable) + out = 3'b000; + else begin + case (in) + 2'b00 : out = 3'b001 ; + 2'b01 : out = 3'b010; + 2'b10 : out = 3'b010; + 2'b11 : out = 3'b100; + endcase + end +endmodule + +// test_simulation_decoder_4_test.v +module f3_test (input [2:0] in, output reg [7:0] out); + +always @(in ) + case (in) + 3'b000 : out = 8'b00000001; + 3'b001 : out = 8'b00000010; + 3'b010 : out = 8'b00000100; + 3'b011 : out = 8'b00001000; + 3'b100 : out = 8'b00010000; + 3'b101 : out = 8'b00100000; + 3'b110 : out = 8'b01000000; + 3'b111 : out = 8'b10000000; + endcase +endmodule + +// test_simulation_decoder_5_test.v +module f4_test (input [2:0] in, input enable, output reg [7:0] out); + +always @(in or enable ) + if(!enable) + out = 8'b00000000; + else + case (in) + 3'b000 : out = 8'b00000001; + 3'b001 : out = 8'b00000010; + 3'b010 : out = 8'b00000100; + 3'b011 : out = 8'b00001000; + 3'b100 : out = 8'b00010000; + 3'b101 : out = 8'b00100000; + 3'b110 : out = 8'b01000000; + 3'b111 : out = 8'b10000000; + endcase +endmodule + +// test_simulation_decoder_6_test.v +module f5_test (input [3:0] in, input enable, output reg [15:0] out); + +always @(in or enable) + if(!enable) + out = 16'b0000000000000000; + else begin + case (in) + 4'b0000 : out = 16'b0000000000000001; + 4'b0001 : out = 16'b0000000000000010; + 4'b0010 : out = 16'b0000000000000100; + 4'b0011 : out = 16'b0000000000001000; + 4'b0100 : out = 16'b0000000000010000; + 4'b0101 : out = 16'b0000000000100000; + 4'b0110 : out = 16'b0000000001000000; + 4'b0111 : out = 16'b0000000010000000; + 4'b1000 : out = 16'b0000000100000000; + 4'b1001 : out = 16'b0000001000000000; + 4'b1010 : out = 16'b0000010000000000; + 4'b1011 : out = 16'b0000100000000000; + 4'b1100 : out = 16'b0001000000000000; + 4'b1101 : out = 16'b0010000000000000; + 4'b1110 : out = 16'b0100000000000000; + 4'b1111 : out = 16'b1000000000000000; + endcase + end +endmodule + + +// test_simulation_decoder_7_test.v +module f6_test (input [4:0] in, input enable, output reg [31:0] out); + +always @(in or enable) + if(!enable) + out = 32'b00000000000000000000000000000000; + else begin + case (in) + 5'b00000 : out = 32'b00000000000000000000000000000001; + 5'b00001 : out = 32'b00000000000000000000000000000010; + 5'b00010 : out = 32'b00000000000000000000000000000100; + 5'b00011 : out = 32'b00000000000000000000000000001000; + 5'b00100 : out = 32'b00000000000000000000000000010000; + 5'b00101 : out = 32'b00000000000000000000000000100000; + 5'b00110 : out = 32'b00000000000000000000000001000000; + 5'b00111 : out = 32'b00000000000000000000000010000000; + 5'b01000 : out = 32'b00000000000000000000000100000000; + 5'b01001 : out = 32'b00000000000000000000001000000000; + 5'b01010 : out = 32'b00000000000000000000010000000000; + 5'b01011 : out = 32'b00000000000000000000100000000000; + 5'b01100 : out = 32'b00000000000000000001000000000000; + 5'b01101 : out = 32'b00000000000000000010000000000000; + 5'b01110 : out = 32'b00000000000000000100000000000000; + 5'b01111 : out = 32'b00000000000000001000000000000000; + 5'b10000 : out = 32'b00000000000000010000000000000000; + 5'b10001 : out = 32'b00000000000000100000000000000000; + 5'b10010 : out = 32'b00000000000001000000000000000000; + 5'b10011 : out = 32'b00000000000010000000000000000000; + 5'b10100 : out = 32'b00000000000100000000000000000000; + 5'b10101 : out = 32'b00000000001000000000000000000000; + 5'b10110 : out = 32'b00000000010000000000000000000000; + 5'b10111 : out = 32'b00000000100000000000000000000000; + 5'b11000 : out = 32'b00000001000000000000000000000000; + 5'b11001 : out = 32'b00000010000000000000000000000000; + 5'b11010 : out = 32'b00000100000000000000000000000000; + 5'b11011 : out = 32'b00001000000000000000000000000000; + 5'b11100 : out = 32'b00010000000000000000000000000000; + 5'b11101 : out = 32'b00100000000000000000000000000000; + 5'b11110 : out = 32'b01000000000000000000000000000000; + 5'b11111 : out = 32'b10000000000000000000000000000000; + endcase + end +endmodule + + +// test_simulation_decoder_8_test.v +module f7_test (input [5:0] in, input enable, output reg [63:0] out); always @(in or enable) if(!enable) diff --git a/tests/hana/test_simulation_decoder_2_test.v b/tests/hana/test_simulation_decoder_2_test.v deleted file mode 100644 index 5bdf1971..00000000 --- a/tests/hana/test_simulation_decoder_2_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module test (input [1:0] in, input enable, output reg out); - -always @(in or enable) - if(!enable) - out = 4'b0000; - else begin - case (in) - 2'b00 : out = 0 ; - 2'b01 : out = 1; - 2'b10 : out = 0; - 2'b11 : out = 1; - endcase - end -endmodule diff --git a/tests/hana/test_simulation_decoder_3_test.v b/tests/hana/test_simulation_decoder_3_test.v deleted file mode 100644 index 44f5de12..00000000 --- a/tests/hana/test_simulation_decoder_3_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module test (input [1:0] in, input enable, output reg [2:0] out); - -always @(in or enable) - if(!enable) - out = 3'b000; - else begin - case (in) - 2'b00 : out = 3'b001 ; - 2'b01 : out = 3'b010; - 2'b10 : out = 3'b010; - 2'b11 : out = 3'b100; - endcase - end -endmodule diff --git a/tests/hana/test_simulation_decoder_4_test.v b/tests/hana/test_simulation_decoder_4_test.v deleted file mode 100644 index 871a5bbf..00000000 --- a/tests/hana/test_simulation_decoder_4_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module test (input [2:0] in, output reg [7:0] out); - -always @(in ) - case (in) - 3'b000 : out = 8'b00000001; - 3'b001 : out = 8'b00000010; - 3'b010 : out = 8'b00000100; - 3'b011 : out = 8'b00001000; - 3'b100 : out = 8'b00010000; - 3'b101 : out = 8'b00100000; - 3'b110 : out = 8'b01000000; - 3'b111 : out = 8'b10000000; - endcase -endmodule diff --git a/tests/hana/test_simulation_decoder_5_test.v b/tests/hana/test_simulation_decoder_5_test.v deleted file mode 100644 index 497fa4bf..00000000 --- a/tests/hana/test_simulation_decoder_5_test.v +++ /dev/null @@ -1,17 +0,0 @@ -module test (input [2:0] in, input enable, output reg [7:0] out); - -always @(in or enable ) - if(!enable) - out = 8'b00000000; - else - case (in) - 3'b000 : out = 8'b00000001; - 3'b001 : out = 8'b00000010; - 3'b010 : out = 8'b00000100; - 3'b011 : out = 8'b00001000; - 3'b100 : out = 8'b00010000; - 3'b101 : out = 8'b00100000; - 3'b110 : out = 8'b01000000; - 3'b111 : out = 8'b10000000; - endcase -endmodule diff --git a/tests/hana/test_simulation_decoder_6_test.v b/tests/hana/test_simulation_decoder_6_test.v deleted file mode 100644 index fd19ad60..00000000 --- a/tests/hana/test_simulation_decoder_6_test.v +++ /dev/null @@ -1,27 +0,0 @@ -module test (input [3:0] in, input enable, output reg [15:0] out); - -always @(in or enable) - if(!enable) - out = 16'b0000000000000000; - else begin - case (in) - 4'b0000 : out = 16'b0000000000000001; - 4'b0001 : out = 16'b0000000000000010; - 4'b0010 : out = 16'b0000000000000100; - 4'b0011 : out = 16'b0000000000001000; - 4'b0100 : out = 16'b0000000000010000; - 4'b0101 : out = 16'b0000000000100000; - 4'b0110 : out = 16'b0000000001000000; - 4'b0111 : out = 16'b0000000010000000; - 4'b1000 : out = 16'b0000000100000000; - 4'b1001 : out = 16'b0000001000000000; - 4'b1010 : out = 16'b0000010000000000; - 4'b1011 : out = 16'b0000100000000000; - 4'b1100 : out = 16'b0001000000000000; - 4'b1101 : out = 16'b0010000000000000; - 4'b1110 : out = 16'b0100000000000000; - 4'b1111 : out = 16'b1000000000000000; - endcase - end -endmodule - diff --git a/tests/hana/test_simulation_decoder_7_test.v b/tests/hana/test_simulation_decoder_7_test.v deleted file mode 100644 index 462e9419..00000000 --- a/tests/hana/test_simulation_decoder_7_test.v +++ /dev/null @@ -1,43 +0,0 @@ -module test (input [4:0] in, input enable, output reg [31:0] out); - -always @(in or enable) - if(!enable) - out = 32'b00000000000000000000000000000000; - else begin - case (in) - 5'b00000 : out = 32'b00000000000000000000000000000001; - 5'b00001 : out = 32'b00000000000000000000000000000010; - 5'b00010 : out = 32'b00000000000000000000000000000100; - 5'b00011 : out = 32'b00000000000000000000000000001000; - 5'b00100 : out = 32'b00000000000000000000000000010000; - 5'b00101 : out = 32'b00000000000000000000000000100000; - 5'b00110 : out = 32'b00000000000000000000000001000000; - 5'b00111 : out = 32'b00000000000000000000000010000000; - 5'b01000 : out = 32'b00000000000000000000000100000000; - 5'b01001 : out = 32'b00000000000000000000001000000000; - 5'b01010 : out = 32'b00000000000000000000010000000000; - 5'b01011 : out = 32'b00000000000000000000100000000000; - 5'b01100 : out = 32'b00000000000000000001000000000000; - 5'b01101 : out = 32'b00000000000000000010000000000000; - 5'b01110 : out = 32'b00000000000000000100000000000000; - 5'b01111 : out = 32'b00000000000000001000000000000000; - 5'b10000 : out = 32'b00000000000000010000000000000000; - 5'b10001 : out = 32'b00000000000000100000000000000000; - 5'b10010 : out = 32'b00000000000001000000000000000000; - 5'b10011 : out = 32'b00000000000010000000000000000000; - 5'b10100 : out = 32'b00000000000100000000000000000000; - 5'b10101 : out = 32'b00000000001000000000000000000000; - 5'b10110 : out = 32'b00000000010000000000000000000000; - 5'b10111 : out = 32'b00000000100000000000000000000000; - 5'b11000 : out = 32'b00000001000000000000000000000000; - 5'b11001 : out = 32'b00000010000000000000000000000000; - 5'b11010 : out = 32'b00000100000000000000000000000000; - 5'b11011 : out = 32'b00001000000000000000000000000000; - 5'b11100 : out = 32'b00010000000000000000000000000000; - 5'b11101 : out = 32'b00100000000000000000000000000000; - 5'b11110 : out = 32'b01000000000000000000000000000000; - 5'b11111 : out = 32'b10000000000000000000000000000000; - endcase - end -endmodule - diff --git a/tests/hana/test_simulation_inc.v b/tests/hana/test_simulation_inc.v new file mode 100644 index 00000000..f8f54870 --- /dev/null +++ b/tests/hana/test_simulation_inc.v @@ -0,0 +1,42 @@ + +// test_simulation_inc_16_test.v +module f1_test(input [15:0] in, output [15:0] out); + +assign out = -in; + +endmodule + +// test_simulation_inc_1_test.v +module f2_test(input in, output out); + +assign out = -in; + +endmodule + +// test_simulation_inc_2_test.v +module f3_test(input [1:0] in, output [1:0] out); + +assign out = -in; + +endmodule + +// test_simulation_inc_32_test.v +module f4_test(input [31:0] in, output [31:0] out); + +assign out = -in; + +endmodule + +// test_simulation_inc_4_test.v +module f5_test(input [3:0] in, output [3:0] out); + +assign out = -in; + +endmodule + +// test_simulation_inc_8_test.v +module f6_test(input [7:0] in, output [7:0] out); + +assign out = -in; + +endmodule diff --git a/tests/hana/test_simulation_inc_16_test.v b/tests/hana/test_simulation_inc_16_test.v deleted file mode 100644 index 7ff42ff5..00000000 --- a/tests/hana/test_simulation_inc_16_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input [15:0] in, output [15:0] out); - -assign out = -in; - -endmodule diff --git a/tests/hana/test_simulation_inc_1_test.v b/tests/hana/test_simulation_inc_1_test.v deleted file mode 100644 index 02bec2c2..00000000 --- a/tests/hana/test_simulation_inc_1_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input in, output out); - -assign out = -in; - -endmodule diff --git a/tests/hana/test_simulation_inc_2_test.v b/tests/hana/test_simulation_inc_2_test.v deleted file mode 100644 index b96e05a2..00000000 --- a/tests/hana/test_simulation_inc_2_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input [1:0] in, output [1:0] out); - -assign out = -in; - -endmodule diff --git a/tests/hana/test_simulation_inc_32_test.v b/tests/hana/test_simulation_inc_32_test.v deleted file mode 100644 index 5700d0ce..00000000 --- a/tests/hana/test_simulation_inc_32_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input [31:0] in, output [31:0] out); - -assign out = -in; - -endmodule diff --git a/tests/hana/test_simulation_inc_4_test.v b/tests/hana/test_simulation_inc_4_test.v deleted file mode 100644 index 34940d63..00000000 --- a/tests/hana/test_simulation_inc_4_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input [3:0] in, output [3:0] out); - -assign out = -in; - -endmodule diff --git a/tests/hana/test_simulation_inc_8_test.v b/tests/hana/test_simulation_inc_8_test.v deleted file mode 100644 index c36d69f0..00000000 --- a/tests/hana/test_simulation_inc_8_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input [7:0] in, output [7:0] out); - -assign out = -in; - -endmodule diff --git a/tests/hana/test_simulation_mod_1_xx.v b/tests/hana/test_simulation_mod_1_xx.v deleted file mode 100644 index 75144a8e..00000000 --- a/tests/hana/test_simulation_mod_1_xx.v +++ /dev/null @@ -1,13 +0,0 @@ -module test(in1, in2, out); -input in1; -input in2; -output out; - -wire synth_net_0; -wire synth_net_1; -BUF synth_BUF_0(.in(synth_net_1), .out(out - )); -DIV1 synth_DIV(.in1(in1), .in2(in2), .rem(synth_net_0), .out(synth_net_1 - )); -endmodule - diff --git a/tests/hana/test_simulation_mux.v b/tests/hana/test_simulation_mux.v new file mode 100644 index 00000000..085387ef --- /dev/null +++ b/tests/hana/test_simulation_mux.v @@ -0,0 +1,176 @@ + +// test_simulation_mux_16_test.v +module f1_test(input [15:0] in, input [3:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + endcase +endmodule + +// test_simulation_mux_2_test.v +module f2_test(input [1:0] in, input select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + endcase +endmodule + +// test_simulation_mux_32_test.v +module f3_test(input [31:0] in, input [4:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + 16: out = in[16]; + 17: out = in[17]; + 18: out = in[18]; + 19: out = in[19]; + 20: out = in[20]; + 21: out = in[21]; + 22: out = in[22]; + 23: out = in[23]; + 24: out = in[24]; + 25: out = in[25]; + 26: out = in[26]; + 27: out = in[27]; + 28: out = in[28]; + 29: out = in[29]; + 30: out = in[30]; + 31: out = in[31]; + endcase +endmodule + + +// test_simulation_mux_4_test.v +module f4_test(input [3:0] in, input [1:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + endcase +endmodule + +// test_simulation_mux_64_test.v +module f5_test(input [63:0] in, input [5:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + 16: out = in[16]; + 17: out = in[17]; + 18: out = in[18]; + 19: out = in[19]; + 20: out = in[20]; + 21: out = in[21]; + 22: out = in[22]; + 23: out = in[23]; + 24: out = in[24]; + 25: out = in[25]; + 26: out = in[26]; + 27: out = in[27]; + 28: out = in[28]; + 29: out = in[29]; + 30: out = in[30]; + 31: out = in[31]; + 32: out = in[32]; + 33: out = in[33]; + 34: out = in[34]; + 35: out = in[35]; + 36: out = in[36]; + 37: out = in[37]; + 38: out = in[38]; + 39: out = in[39]; + 40: out = in[40]; + 41: out = in[41]; + 42: out = in[42]; + 43: out = in[43]; + 44: out = in[44]; + 45: out = in[45]; + 46: out = in[46]; + 47: out = in[47]; + 48: out = in[48]; + 49: out = in[49]; + 50: out = in[50]; + 51: out = in[51]; + 52: out = in[52]; + 53: out = in[53]; + 54: out = in[54]; + 55: out = in[55]; + 56: out = in[56]; + 57: out = in[57]; + 58: out = in[58]; + 59: out = in[59]; + 60: out = in[60]; + 61: out = in[61]; + 62: out = in[62]; + 63: out = in[63]; + endcase +endmodule + + +// test_simulation_mux_8_test.v +module f6_test(input [7:0] in, input [2:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + endcase +endmodule diff --git a/tests/hana/test_simulation_mux_16_test.v b/tests/hana/test_simulation_mux_16_test.v deleted file mode 100644 index de4b6f8e..00000000 --- a/tests/hana/test_simulation_mux_16_test.v +++ /dev/null @@ -1,22 +0,0 @@ -module test(input [15:0] in, input [3:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - 4: out = in[4]; - 5: out = in[5]; - 6: out = in[6]; - 7: out = in[7]; - 8: out = in[8]; - 9: out = in[9]; - 10: out = in[10]; - 11: out = in[11]; - 12: out = in[12]; - 13: out = in[13]; - 14: out = in[14]; - 15: out = in[15]; - endcase -endmodule diff --git a/tests/hana/test_simulation_mux_2_test.v b/tests/hana/test_simulation_mux_2_test.v deleted file mode 100644 index bc676c70..00000000 --- a/tests/hana/test_simulation_mux_2_test.v +++ /dev/null @@ -1,8 +0,0 @@ -module test(input [1:0] in, input select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - endcase -endmodule diff --git a/tests/hana/test_simulation_mux_32_test.v b/tests/hana/test_simulation_mux_32_test.v deleted file mode 100644 index 16de4d7f..00000000 --- a/tests/hana/test_simulation_mux_32_test.v +++ /dev/null @@ -1,39 +0,0 @@ -module test(input [31:0] in, input [4:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - 4: out = in[4]; - 5: out = in[5]; - 6: out = in[6]; - 7: out = in[7]; - 8: out = in[8]; - 9: out = in[9]; - 10: out = in[10]; - 11: out = in[11]; - 12: out = in[12]; - 13: out = in[13]; - 14: out = in[14]; - 15: out = in[15]; - 16: out = in[16]; - 17: out = in[17]; - 18: out = in[18]; - 19: out = in[19]; - 20: out = in[20]; - 21: out = in[21]; - 22: out = in[22]; - 23: out = in[23]; - 24: out = in[24]; - 25: out = in[25]; - 26: out = in[26]; - 27: out = in[27]; - 28: out = in[28]; - 29: out = in[29]; - 30: out = in[30]; - 31: out = in[31]; - endcase -endmodule - diff --git a/tests/hana/test_simulation_mux_4_test.v b/tests/hana/test_simulation_mux_4_test.v deleted file mode 100644 index 6a112c6a..00000000 --- a/tests/hana/test_simulation_mux_4_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(input [3:0] in, input [1:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - endcase -endmodule diff --git a/tests/hana/test_simulation_mux_64_test.v b/tests/hana/test_simulation_mux_64_test.v deleted file mode 100644 index 420239c6..00000000 --- a/tests/hana/test_simulation_mux_64_test.v +++ /dev/null @@ -1,71 +0,0 @@ -module test(input [63:0] in, input [5:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - 4: out = in[4]; - 5: out = in[5]; - 6: out = in[6]; - 7: out = in[7]; - 8: out = in[8]; - 9: out = in[9]; - 10: out = in[10]; - 11: out = in[11]; - 12: out = in[12]; - 13: out = in[13]; - 14: out = in[14]; - 15: out = in[15]; - 16: out = in[16]; - 17: out = in[17]; - 18: out = in[18]; - 19: out = in[19]; - 20: out = in[20]; - 21: out = in[21]; - 22: out = in[22]; - 23: out = in[23]; - 24: out = in[24]; - 25: out = in[25]; - 26: out = in[26]; - 27: out = in[27]; - 28: out = in[28]; - 29: out = in[29]; - 30: out = in[30]; - 31: out = in[31]; - 32: out = in[32]; - 33: out = in[33]; - 34: out = in[34]; - 35: out = in[35]; - 36: out = in[36]; - 37: out = in[37]; - 38: out = in[38]; - 39: out = in[39]; - 40: out = in[40]; - 41: out = in[41]; - 42: out = in[42]; - 43: out = in[43]; - 44: out = in[44]; - 45: out = in[45]; - 46: out = in[46]; - 47: out = in[47]; - 48: out = in[48]; - 49: out = in[49]; - 50: out = in[50]; - 51: out = in[51]; - 52: out = in[52]; - 53: out = in[53]; - 54: out = in[54]; - 55: out = in[55]; - 56: out = in[56]; - 57: out = in[57]; - 58: out = in[58]; - 59: out = in[59]; - 60: out = in[60]; - 61: out = in[61]; - 62: out = in[62]; - 63: out = in[63]; - endcase -endmodule - diff --git a/tests/hana/test_simulation_mux_8_test.v b/tests/hana/test_simulation_mux_8_test.v deleted file mode 100644 index f53a2c57..00000000 --- a/tests/hana/test_simulation_mux_8_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module test(input [7:0] in, input [2:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - 4: out = in[4]; - 5: out = in[5]; - 6: out = in[6]; - 7: out = in[7]; - endcase -endmodule diff --git a/tests/hana/test_simulation_nand.v b/tests/hana/test_simulation_nand.v new file mode 100644 index 00000000..5e6e0f1f --- /dev/null +++ b/tests/hana/test_simulation_nand.v @@ -0,0 +1,25 @@ + +// test_simulation_nand_1_test.v +module f1_test(input [1:0] in, output out); +assign out = ~(in[0] & in[1]); +endmodule + +// test_simulation_nand_3_test.v +module f2_test(input [2:0] in, output out); +assign out = !(in[0] & in[1] & in[2]); +endmodule + +// test_simulation_nand_4_test.v +module f3_test(input [2:0] in, output out); +assign out = ~(in[0] && in[1] && in[2]); +endmodule + +// test_simulation_nand_5_test.v +module f4_test(input [3:0] in, output out); +assign out = !(in[0] & in[1] & in[2] & in[3]); +endmodule + +// test_simulation_nand_6_test.v +module f5_test(input [3:0] in, output out); +assign out = !(in[0] && in[1] && in[2] && in[3]); +endmodule diff --git a/tests/hana/test_simulation_nand_1_test.v b/tests/hana/test_simulation_nand_1_test.v deleted file mode 100644 index d8f34ee1..00000000 --- a/tests/hana/test_simulation_nand_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = ~(in[0] & in[1]); -endmodule diff --git a/tests/hana/test_simulation_nand_3_test.v b/tests/hana/test_simulation_nand_3_test.v deleted file mode 100644 index 8926cebb..00000000 --- a/tests/hana/test_simulation_nand_3_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = !(in[0] & in[1] & in[2]); -endmodule diff --git a/tests/hana/test_simulation_nand_4_test.v b/tests/hana/test_simulation_nand_4_test.v deleted file mode 100644 index 703a2de4..00000000 --- a/tests/hana/test_simulation_nand_4_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = ~(in[0] && in[1] && in[2]); -endmodule diff --git a/tests/hana/test_simulation_nand_5_test.v b/tests/hana/test_simulation_nand_5_test.v deleted file mode 100644 index adef3c90..00000000 --- a/tests/hana/test_simulation_nand_5_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = !(in[0] & in[1] & in[2] & in[3]); -endmodule diff --git a/tests/hana/test_simulation_nand_6_test.v b/tests/hana/test_simulation_nand_6_test.v deleted file mode 100644 index a2136f21..00000000 --- a/tests/hana/test_simulation_nand_6_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = !(in[0] && in[1] && in[2] && in[3]); -endmodule diff --git a/tests/hana/test_simulation_nor.v b/tests/hana/test_simulation_nor.v new file mode 100644 index 00000000..d7d2bc0e --- /dev/null +++ b/tests/hana/test_simulation_nor.v @@ -0,0 +1,20 @@ + +// test_simulation_nor_1_test.v +module f1_test(input [1:0] in, output out); +assign out = ~(in[0] | in[1]); +endmodule + +// test_simulation_nor_2_test.v +module f2_test(input [2:0] in, output out); +assign out = ~(in[0] | in[1] | in[2]); +endmodule + +// test_simulation_nor_3_test.v +module f3_test(input [3:0] in, output out); +assign out = ~(in[0] | in[1] | in[2] | in[3]); +endmodule + +// test_simulation_nor_4_test.v +module f4_test(input [3:0] in, output out); +nor mynor(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/hana/test_simulation_nor_1_test.v b/tests/hana/test_simulation_nor_1_test.v deleted file mode 100644 index df4e8bfa..00000000 --- a/tests/hana/test_simulation_nor_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = ~(in[0] | in[1]); -endmodule diff --git a/tests/hana/test_simulation_nor_2_test.v b/tests/hana/test_simulation_nor_2_test.v deleted file mode 100644 index 2cfffc45..00000000 --- a/tests/hana/test_simulation_nor_2_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = ~(in[0] | in[1] | in[2]); -endmodule diff --git a/tests/hana/test_simulation_nor_3_test.v b/tests/hana/test_simulation_nor_3_test.v deleted file mode 100644 index 9f1ef8fe..00000000 --- a/tests/hana/test_simulation_nor_3_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = ~(in[0] | in[1] | in[2] | in[3]); -endmodule diff --git a/tests/hana/test_simulation_nor_4_test.v b/tests/hana/test_simulation_nor_4_test.v deleted file mode 100644 index d8e68504..00000000 --- a/tests/hana/test_simulation_nor_4_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -nor mynor(out, in[0], in[1], in[2], in[3]); -endmodule diff --git a/tests/hana/test_simulation_opt_constprop_contassign_1_test.v b/tests/hana/test_simulation_opt_constprop_contassign_1_test.v deleted file mode 100644 index a39b58b4..00000000 --- a/tests/hana/test_simulation_opt_constprop_contassign_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input in, output out); -assign out = 1'b1; -endmodule diff --git a/tests/hana/test_simulation_or.v b/tests/hana/test_simulation_or.v new file mode 100644 index 00000000..9217db80 --- /dev/null +++ b/tests/hana/test_simulation_or.v @@ -0,0 +1,30 @@ + +// test_simulation_or_1_test.v +module f1_test(input [1:0] in, output out); +assign out = in[0] | in[1]; +endmodule + +// test_simulation_or_2_test.v +module f2_test(input [1:0] in, output out); +assign out = in[0] || in[1]; +endmodule + +// test_simulation_or_3_test.v +module f3_test(input [2:0] in, output out); +assign out = in[0] | in[1] | in[2]; +endmodule + +// test_simulation_or_4_test.v +module f4_test(input [2:0] in, output out); +assign out = in[0] || in[1] || in[2]; +endmodule + +// test_simulation_or_5_test.v +module f5_test(input [3:0] in, output out); +assign out = in[0] | in[1] | in[2] | in[3]; +endmodule + +// test_simulation_or_6_test.v +module f6_test(input [3:0] in, output out); +assign out = in[0] || in[1] || in[2] || in[3]; +endmodule diff --git a/tests/hana/test_simulation_or_1_test.v b/tests/hana/test_simulation_or_1_test.v deleted file mode 100644 index bdfffd3d..00000000 --- a/tests/hana/test_simulation_or_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = in[0] | in[1]; -endmodule diff --git a/tests/hana/test_simulation_or_2_test.v b/tests/hana/test_simulation_or_2_test.v deleted file mode 100644 index 291c8c76..00000000 --- a/tests/hana/test_simulation_or_2_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = in[0] || in[1]; -endmodule diff --git a/tests/hana/test_simulation_or_3_test.v b/tests/hana/test_simulation_or_3_test.v deleted file mode 100644 index ad00c708..00000000 --- a/tests/hana/test_simulation_or_3_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = in[0] | in[1] | in[2]; -endmodule diff --git a/tests/hana/test_simulation_or_4_test.v b/tests/hana/test_simulation_or_4_test.v deleted file mode 100644 index 2ec57fa9..00000000 --- a/tests/hana/test_simulation_or_4_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = in[0] || in[1] || in[2]; -endmodule diff --git a/tests/hana/test_simulation_or_5_test.v b/tests/hana/test_simulation_or_5_test.v deleted file mode 100644 index f6a2d14d..00000000 --- a/tests/hana/test_simulation_or_5_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = in[0] | in[1] | in[2] | in[3]; -endmodule diff --git a/tests/hana/test_simulation_or_6_test.v b/tests/hana/test_simulation_or_6_test.v deleted file mode 100644 index ecd85c36..00000000 --- a/tests/hana/test_simulation_or_6_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = in[0] || in[1] || in[2] || in[3]; -endmodule diff --git a/tests/hana/test_simulation_seq.v b/tests/hana/test_simulation_seq.v new file mode 100644 index 00000000..eba4e88e --- /dev/null +++ b/tests/hana/test_simulation_seq.v @@ -0,0 +1,12 @@ + +// test_simulation_seq_ff_1_test.v +module f1_test(input in, input clk, output reg out); +always @(posedge clk) + out <= in; +endmodule + +// test_simulation_seq_ff_2_test.v +module f2_test(input in, input clk, output reg out); +always @(negedge clk) + out <= in; +endmodule diff --git a/tests/hana/test_simulation_seq_ff_1_test.v b/tests/hana/test_simulation_seq_ff_1_test.v deleted file mode 100644 index 5aac49c0..00000000 --- a/tests/hana/test_simulation_seq_ff_1_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input in, input clk, output reg out); -always @(posedge clk) - out <= in; -endmodule diff --git a/tests/hana/test_simulation_seq_ff_2_test.v b/tests/hana/test_simulation_seq_ff_2_test.v deleted file mode 100644 index f1d2b7b4..00000000 --- a/tests/hana/test_simulation_seq_ff_2_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input in, input clk, output reg out); -always @(negedge clk) - out <= in; -endmodule diff --git a/tests/hana/test_simulation_shifter.v b/tests/hana/test_simulation_shifter.v new file mode 100644 index 00000000..8864fb0e --- /dev/null +++ b/tests/hana/test_simulation_shifter.v @@ -0,0 +1,60 @@ + +// test_simulation_shifter_left_16_test.v +module f1_test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT); + +assign OUT = IN << SHIFT; +endmodule + +// test_simulation_shifter_left_32_test.v +module f2_test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT); + +assign OUT = IN << SHIFT; +endmodule + +// test_simulation_shifter_left_4_test.v +module f3_test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT); + +assign OUT = IN << SHIFT; +endmodule + +// test_simulation_shifter_left_64_test.v +module f4_test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT); + +assign OUT = IN << SHIFT; +endmodule + +// test_simulation_shifter_left_8_test.v +module f5_test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT); + +assign OUT = IN << SHIFT; +endmodule + +// test_simulation_shifter_right_16_test.v +module f6_test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule + +// test_simulation_shifter_right_32_test.v +module f7_test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule + +// test_simulation_shifter_right_4_test.v +module f8_test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule + +// test_simulation_shifter_right_64_test.v +module f9_test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule + +// test_simulation_shifter_right_8_test.v +module f10_test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_left_16_test.v b/tests/hana/test_simulation_shifter_left_16_test.v deleted file mode 100644 index a57dac49..00000000 --- a/tests/hana/test_simulation_shifter_left_16_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT); - -assign OUT = IN << SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_left_32_test.v b/tests/hana/test_simulation_shifter_left_32_test.v deleted file mode 100644 index 672938ac..00000000 --- a/tests/hana/test_simulation_shifter_left_32_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT); - -assign OUT = IN << SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_left_4_test.v b/tests/hana/test_simulation_shifter_left_4_test.v deleted file mode 100644 index c525401f..00000000 --- a/tests/hana/test_simulation_shifter_left_4_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT); - -assign OUT = IN << SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_left_64_test.v b/tests/hana/test_simulation_shifter_left_64_test.v deleted file mode 100644 index 276a7c5a..00000000 --- a/tests/hana/test_simulation_shifter_left_64_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT); - -assign OUT = IN << SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_left_8_test.v b/tests/hana/test_simulation_shifter_left_8_test.v deleted file mode 100644 index c1727700..00000000 --- a/tests/hana/test_simulation_shifter_left_8_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT); - -assign OUT = IN << SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_right_16_test.v b/tests/hana/test_simulation_shifter_right_16_test.v deleted file mode 100644 index 6152adc0..00000000 --- a/tests/hana/test_simulation_shifter_right_16_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT); - -assign OUT = IN >> SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_right_32_test.v b/tests/hana/test_simulation_shifter_right_32_test.v deleted file mode 100644 index e910cdd6..00000000 --- a/tests/hana/test_simulation_shifter_right_32_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT); - -assign OUT = IN >> SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_right_4_test.v b/tests/hana/test_simulation_shifter_right_4_test.v deleted file mode 100644 index 608c196d..00000000 --- a/tests/hana/test_simulation_shifter_right_4_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT); - -assign OUT = IN >> SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_right_64_test.v b/tests/hana/test_simulation_shifter_right_64_test.v deleted file mode 100644 index c26d5938..00000000 --- a/tests/hana/test_simulation_shifter_right_64_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT); - -assign OUT = IN >> SHIFT; -endmodule diff --git a/tests/hana/test_simulation_shifter_right_8_test.v b/tests/hana/test_simulation_shifter_right_8_test.v deleted file mode 100644 index a91c594e..00000000 --- a/tests/hana/test_simulation_shifter_right_8_test.v +++ /dev/null @@ -1,4 +0,0 @@ -module test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT); - -assign OUT = IN >> SHIFT; -endmodule diff --git a/tests/hana/test_simulation_sop.v b/tests/hana/test_simulation_sop.v new file mode 100644 index 00000000..79870cf0 --- /dev/null +++ b/tests/hana/test_simulation_sop.v @@ -0,0 +1,65 @@ + +// test_simulation_sop_basic_10_test.v +module f1_test(input [1:0] in, input select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + endcase +endmodule + +// test_simulation_sop_basic_11_test.v +module f2_test(input [3:0] in, input [1:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + endcase +endmodule + +// test_simulation_sop_basic_12_test.v +module f3_test(input [7:0] in, input [2:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + endcase +endmodule + +// test_simulation_sop_basic_18_test.v +module f4_test(input [7:0] in, output out); + +assign out = ~^in; + +endmodule + +// test_simulation_sop_basic_3_test.v +module f5_test(input in, output out); +assign out = ~in; +endmodule + +// test_simulation_sop_basic_7_test.v +module f6_test(input in, output out); +assign out = in; +endmodule + +// test_simulation_sop_basic_8_test.v +module f7_test(output out); +assign out = 1'b0; +endmodule + +// test_simulation_sop_basic_9_test.v +module f8_test(input in, output out); +assign out = ~in; +endmodule diff --git a/tests/hana/test_simulation_sop_basic_10_test.v b/tests/hana/test_simulation_sop_basic_10_test.v deleted file mode 100644 index bc676c70..00000000 --- a/tests/hana/test_simulation_sop_basic_10_test.v +++ /dev/null @@ -1,8 +0,0 @@ -module test(input [1:0] in, input select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - endcase -endmodule diff --git a/tests/hana/test_simulation_sop_basic_11_test.v b/tests/hana/test_simulation_sop_basic_11_test.v deleted file mode 100644 index 6a112c6a..00000000 --- a/tests/hana/test_simulation_sop_basic_11_test.v +++ /dev/null @@ -1,10 +0,0 @@ -module test(input [3:0] in, input [1:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - endcase -endmodule diff --git a/tests/hana/test_simulation_sop_basic_12_test.v b/tests/hana/test_simulation_sop_basic_12_test.v deleted file mode 100644 index f53a2c57..00000000 --- a/tests/hana/test_simulation_sop_basic_12_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module test(input [7:0] in, input [2:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - 4: out = in[4]; - 5: out = in[5]; - 6: out = in[6]; - 7: out = in[7]; - endcase -endmodule diff --git a/tests/hana/test_simulation_sop_basic_18_test.v b/tests/hana/test_simulation_sop_basic_18_test.v deleted file mode 100644 index 03fc35b3..00000000 --- a/tests/hana/test_simulation_sop_basic_18_test.v +++ /dev/null @@ -1,5 +0,0 @@ -module test(input [7:0] in, output out); - -assign out = ~^in; - -endmodule diff --git a/tests/hana/test_simulation_sop_basic_3_test.v b/tests/hana/test_simulation_sop_basic_3_test.v deleted file mode 100644 index 81759c25..00000000 --- a/tests/hana/test_simulation_sop_basic_3_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input in, output out); -assign out = ~in; -endmodule diff --git a/tests/hana/test_simulation_sop_basic_7_test.v b/tests/hana/test_simulation_sop_basic_7_test.v deleted file mode 100644 index e9bb7f61..00000000 --- a/tests/hana/test_simulation_sop_basic_7_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input in, output out); -assign out = in; -endmodule diff --git a/tests/hana/test_simulation_sop_basic_8_test.v b/tests/hana/test_simulation_sop_basic_8_test.v deleted file mode 100644 index a51ead0b..00000000 --- a/tests/hana/test_simulation_sop_basic_8_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(output out); -assign out = 1'b0; -endmodule diff --git a/tests/hana/test_simulation_sop_basic_9_test.v b/tests/hana/test_simulation_sop_basic_9_test.v deleted file mode 100644 index 81759c25..00000000 --- a/tests/hana/test_simulation_sop_basic_9_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input in, output out); -assign out = ~in; -endmodule diff --git a/tests/hana/test_simulation_techmap_mux_128_test.v b/tests/hana/test_simulation_techmap.v similarity index 77% rename from tests/hana/test_simulation_techmap_mux_128_test.v rename to tests/hana/test_simulation_techmap.v index 544c016a..88e24d0e 100644 --- a/tests/hana/test_simulation_techmap_mux_128_test.v +++ b/tests/hana/test_simulation_techmap.v @@ -1,4 +1,26 @@ -module test(input [127:0] in, input [6:0] select, output reg out); + +// test_simulation_techmap_buf_test.v +module f1_test(input in, output out); +assign out = in; +endmodule + +// test_simulation_techmap_inv_test.v +module f2_test(input in, output out); +assign out = ~in; +endmodule + +// test_simulation_techmap_mux_0_test.v +module f3_test(input [1:0] in, input select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + endcase +endmodule + +// test_simulation_techmap_mux_128_test.v +module f4_test(input [127:0] in, input [6:0] select, output reg out); always @( in or select) case (select) @@ -132,3 +154,19 @@ always @( in or select) 127: out = in[127]; endcase endmodule + +// test_simulation_techmap_mux_8_test.v +module f5_test(input [7:0] in, input [2:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + endcase +endmodule diff --git a/tests/hana/test_simulation_techmap_and_19_tech.v b/tests/hana/test_simulation_techmap_and_19_tech.v deleted file mode 100644 index 2491087c..00000000 --- a/tests/hana/test_simulation_techmap_and_19_tech.v +++ /dev/null @@ -1,7 +0,0 @@ -module TECH_AND18(input [17:0] in, output out); -assign out = ∈ -endmodule - -module TECH_AND4(input [3:0] in, output out); -assign out = ∈ -endmodule diff --git a/tests/hana/test_simulation_techmap_and_5_tech.v b/tests/hana/test_simulation_techmap_and_5_tech.v deleted file mode 100644 index 6ec6a61c..00000000 --- a/tests/hana/test_simulation_techmap_and_5_tech.v +++ /dev/null @@ -1,3 +0,0 @@ -module TECH_AND5(input [4:0] in, output out); -assign out = ∈ -endmodule diff --git a/tests/hana/test_simulation_techmap_buf_test.v b/tests/hana/test_simulation_techmap_buf_test.v deleted file mode 100644 index e9bb7f61..00000000 --- a/tests/hana/test_simulation_techmap_buf_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input in, output out); -assign out = in; -endmodule diff --git a/tests/hana/test_simulation_techmap_inv_test.v b/tests/hana/test_simulation_techmap_inv_test.v deleted file mode 100644 index 81759c25..00000000 --- a/tests/hana/test_simulation_techmap_inv_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input in, output out); -assign out = ~in; -endmodule diff --git a/tests/hana/test_simulation_techmap_mux_0_test.v b/tests/hana/test_simulation_techmap_mux_0_test.v deleted file mode 100644 index bc676c70..00000000 --- a/tests/hana/test_simulation_techmap_mux_0_test.v +++ /dev/null @@ -1,8 +0,0 @@ -module test(input [1:0] in, input select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - endcase -endmodule diff --git a/tests/hana/test_simulation_techmap_mux_8_test.v b/tests/hana/test_simulation_techmap_mux_8_test.v deleted file mode 100644 index f53a2c57..00000000 --- a/tests/hana/test_simulation_techmap_mux_8_test.v +++ /dev/null @@ -1,14 +0,0 @@ -module test(input [7:0] in, input [2:0] select, output reg out); - -always @( in or select) - case (select) - 0: out = in[0]; - 1: out = in[1]; - 2: out = in[2]; - 3: out = in[3]; - 4: out = in[4]; - 5: out = in[5]; - 6: out = in[6]; - 7: out = in[7]; - endcase -endmodule diff --git a/tests/hana/test_simulation_techmap_nand_19_tech.v b/tests/hana/test_simulation_techmap_nand_19_tech.v deleted file mode 100644 index 6a119e1e..00000000 --- a/tests/hana/test_simulation_techmap_nand_19_tech.v +++ /dev/null @@ -1,11 +0,0 @@ -module TECH_NAND18(input [17:0] in, output out); -assign out = ~(&in); -endmodule - -module TECH_NAND4(input [3:0] in, output out); -assign out = ~(&in); -endmodule - -module TECH_NAND2(input [1:0] in, output out); -assign out = ~(&in); -endmodule diff --git a/tests/hana/test_simulation_techmap_nand_2_tech.v b/tests/hana/test_simulation_techmap_nand_2_tech.v deleted file mode 100644 index 6a119e1e..00000000 --- a/tests/hana/test_simulation_techmap_nand_2_tech.v +++ /dev/null @@ -1,11 +0,0 @@ -module TECH_NAND18(input [17:0] in, output out); -assign out = ~(&in); -endmodule - -module TECH_NAND4(input [3:0] in, output out); -assign out = ~(&in); -endmodule - -module TECH_NAND2(input [1:0] in, output out); -assign out = ~(&in); -endmodule diff --git a/tests/hana/test_simulation_techmap_nand_5_tech.v b/tests/hana/test_simulation_techmap_nand_5_tech.v deleted file mode 100644 index 6a119e1e..00000000 --- a/tests/hana/test_simulation_techmap_nand_5_tech.v +++ /dev/null @@ -1,11 +0,0 @@ -module TECH_NAND18(input [17:0] in, output out); -assign out = ~(&in); -endmodule - -module TECH_NAND4(input [3:0] in, output out); -assign out = ~(&in); -endmodule - -module TECH_NAND2(input [1:0] in, output out); -assign out = ~(&in); -endmodule diff --git a/tests/hana/test_simulation_techmap_nor_19_tech.v b/tests/hana/test_simulation_techmap_nor_19_tech.v deleted file mode 100644 index 89fb2c7e..00000000 --- a/tests/hana/test_simulation_techmap_nor_19_tech.v +++ /dev/null @@ -1,11 +0,0 @@ -module TECH_NOR18(input [17:0] in, output out); -assign out = ~(|in); -endmodule - -module TECH_NOR4(input [3:0] in, output out); -assign out = ~(|in); -endmodule - -module TECH_NOR2(input [1:0] in, output out); -assign out = ~(|in); -endmodule diff --git a/tests/hana/test_simulation_techmap_nor_2_tech.v b/tests/hana/test_simulation_techmap_nor_2_tech.v deleted file mode 100644 index 89fb2c7e..00000000 --- a/tests/hana/test_simulation_techmap_nor_2_tech.v +++ /dev/null @@ -1,11 +0,0 @@ -module TECH_NOR18(input [17:0] in, output out); -assign out = ~(|in); -endmodule - -module TECH_NOR4(input [3:0] in, output out); -assign out = ~(|in); -endmodule - -module TECH_NOR2(input [1:0] in, output out); -assign out = ~(|in); -endmodule diff --git a/tests/hana/test_simulation_techmap_nor_5_tech.v b/tests/hana/test_simulation_techmap_nor_5_tech.v deleted file mode 100644 index 89fb2c7e..00000000 --- a/tests/hana/test_simulation_techmap_nor_5_tech.v +++ /dev/null @@ -1,11 +0,0 @@ -module TECH_NOR18(input [17:0] in, output out); -assign out = ~(|in); -endmodule - -module TECH_NOR4(input [3:0] in, output out); -assign out = ~(|in); -endmodule - -module TECH_NOR2(input [1:0] in, output out); -assign out = ~(|in); -endmodule diff --git a/tests/hana/test_simulation_techmap_or_19_tech.v b/tests/hana/test_simulation_techmap_or_19_tech.v deleted file mode 100644 index 745d7b71..00000000 --- a/tests/hana/test_simulation_techmap_or_19_tech.v +++ /dev/null @@ -1,7 +0,0 @@ -module TECH_OR18(input [17:0] in, output out); -assign out = |in; -endmodule - -module TECH_OR4(input [3:0] in, output out); -assign out = |in; -endmodule diff --git a/tests/hana/test_simulation_techmap_or_5_tech.v b/tests/hana/test_simulation_techmap_or_5_tech.v deleted file mode 100644 index 05c38b67..00000000 --- a/tests/hana/test_simulation_techmap_or_5_tech.v +++ /dev/null @@ -1,3 +0,0 @@ -module TECH_OR5(input [4:0] in, output out); -assign out = |in; -endmodule diff --git a/tests/hana/test_simulation_techmap_tech.v b/tests/hana/test_simulation_techmap_tech.v new file mode 100644 index 00000000..60aeca5c --- /dev/null +++ b/tests/hana/test_simulation_techmap_tech.v @@ -0,0 +1,143 @@ + +// test_simulation_techmap_and_19_tech.v +module f1_TECH_AND18(input [17:0] in, output out); +assign out = ∈ +endmodule + +module f1_TECH_AND4(input [3:0] in, output out); +assign out = ∈ +endmodule + +// test_simulation_techmap_and_5_tech.v +module f2_TECH_AND5(input [4:0] in, output out); +assign out = ∈ +endmodule + +// test_simulation_techmap_nand_19_tech.v +module f3_TECH_NAND18(input [17:0] in, output out); +assign out = ~(&in); +endmodule + +module f3_TECH_NAND4(input [3:0] in, output out); +assign out = ~(&in); +endmodule + +module f3_TECH_NAND2(input [1:0] in, output out); +assign out = ~(&in); +endmodule + +// test_simulation_techmap_nand_2_tech.v +module f4_TECH_NAND18(input [17:0] in, output out); +assign out = ~(&in); +endmodule + +module f4_TECH_NAND4(input [3:0] in, output out); +assign out = ~(&in); +endmodule + +module f4_TECH_NAND2(input [1:0] in, output out); +assign out = ~(&in); +endmodule + +// test_simulation_techmap_nand_5_tech.v +module f5_TECH_NAND18(input [17:0] in, output out); +assign out = ~(&in); +endmodule + +module f5_TECH_NAND4(input [3:0] in, output out); +assign out = ~(&in); +endmodule + +module f5_TECH_NAND2(input [1:0] in, output out); +assign out = ~(&in); +endmodule + +// test_simulation_techmap_nor_19_tech.v +module f6_TECH_NOR18(input [17:0] in, output out); +assign out = ~(|in); +endmodule + +module f6_TECH_NOR4(input [3:0] in, output out); +assign out = ~(|in); +endmodule + +module f6_TECH_NOR2(input [1:0] in, output out); +assign out = ~(|in); +endmodule + +// test_simulation_techmap_nor_2_tech.v +module f7_TECH_NOR18(input [17:0] in, output out); +assign out = ~(|in); +endmodule + +module f7_TECH_NOR4(input [3:0] in, output out); +assign out = ~(|in); +endmodule + +module f7_TECH_NOR2(input [1:0] in, output out); +assign out = ~(|in); +endmodule + +// test_simulation_techmap_nor_5_tech.v +module f8_TECH_NOR18(input [17:0] in, output out); +assign out = ~(|in); +endmodule + +module f8_TECH_NOR4(input [3:0] in, output out); +assign out = ~(|in); +endmodule + +module f8_TECH_NOR2(input [1:0] in, output out); +assign out = ~(|in); +endmodule + +// test_simulation_techmap_or_19_tech.v +module f9_TECH_OR18(input [17:0] in, output out); +assign out = |in; +endmodule + +module f9_TECH_OR4(input [3:0] in, output out); +assign out = |in; +endmodule + +// test_simulation_techmap_or_5_tech.v +module f10_TECH_OR5(input [4:0] in, output out); +assign out = |in; +endmodule + +// test_simulation_techmap_xnor_2_tech.v +module f11_TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module f11_TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule + +// test_simulation_techmap_xnor_5_tech.v +module f12_TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module f12_TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule + +// test_simulation_techmap_xor_19_tech.v +module f13_TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule + +// test_simulation_techmap_xor_2_tech.v +module f14_TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module f14_TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule + +// test_simulation_techmap_xor_5_tech.v +module f15_TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module f15_TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule diff --git a/tests/hana/test_simulation_techmap_xnor_2_tech.v b/tests/hana/test_simulation_techmap_xnor_2_tech.v deleted file mode 100644 index 4eb05683..00000000 --- a/tests/hana/test_simulation_techmap_xnor_2_tech.v +++ /dev/null @@ -1,6 +0,0 @@ -module TECH_XOR5(input [4:0] in, output out); -assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; -endmodule -module TECH_XOR2(input [1:0] in, output out); -assign out = in[0] ^ in[1]; -endmodule diff --git a/tests/hana/test_simulation_techmap_xnor_5_tech.v b/tests/hana/test_simulation_techmap_xnor_5_tech.v deleted file mode 100644 index 4eb05683..00000000 --- a/tests/hana/test_simulation_techmap_xnor_5_tech.v +++ /dev/null @@ -1,6 +0,0 @@ -module TECH_XOR5(input [4:0] in, output out); -assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; -endmodule -module TECH_XOR2(input [1:0] in, output out); -assign out = in[0] ^ in[1]; -endmodule diff --git a/tests/hana/test_simulation_techmap_xor_19_tech.v b/tests/hana/test_simulation_techmap_xor_19_tech.v deleted file mode 100644 index 2042a0ad..00000000 --- a/tests/hana/test_simulation_techmap_xor_19_tech.v +++ /dev/null @@ -1,3 +0,0 @@ -module TECH_XOR2(input [1:0] in, output out); -assign out = in[0] ^ in[1]; -endmodule diff --git a/tests/hana/test_simulation_techmap_xor_2_tech.v b/tests/hana/test_simulation_techmap_xor_2_tech.v deleted file mode 100644 index 4eb05683..00000000 --- a/tests/hana/test_simulation_techmap_xor_2_tech.v +++ /dev/null @@ -1,6 +0,0 @@ -module TECH_XOR5(input [4:0] in, output out); -assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; -endmodule -module TECH_XOR2(input [1:0] in, output out); -assign out = in[0] ^ in[1]; -endmodule diff --git a/tests/hana/test_simulation_techmap_xor_5_tech.v b/tests/hana/test_simulation_techmap_xor_5_tech.v deleted file mode 100644 index 4eb05683..00000000 --- a/tests/hana/test_simulation_techmap_xor_5_tech.v +++ /dev/null @@ -1,6 +0,0 @@ -module TECH_XOR5(input [4:0] in, output out); -assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; -endmodule -module TECH_XOR2(input [1:0] in, output out); -assign out = in[0] ^ in[1]; -endmodule diff --git a/tests/hana/test_simulation_tribuf_2_test.v b/tests/hana/test_simulation_tribuf_2_test.v deleted file mode 100644 index 1e82aaf0..00000000 --- a/tests/hana/test_simulation_tribuf_2_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, input enable, output [1:0] out); -assign out = enable ? in : 2'bzz; -endmodule diff --git a/tests/hana/test_simulation_always_31_tt.v b/tests/hana/test_simulation_vlib.v similarity index 77% rename from tests/hana/test_simulation_always_31_tt.v rename to tests/hana/test_simulation_vlib.v index 299c0ca4..7d3af09c 100644 --- a/tests/hana/test_simulation_always_31_tt.v +++ b/tests/hana/test_simulation_vlib.v @@ -1,4 +1,19 @@ -module test(clk, cond, data); +// test_simulation_mod_1_xx.v +module f1_test(in1, in2, out); +input in1; +input in2; +output out; + +wire synth_net_0; +wire synth_net_1; +BUF synth_BUF_0(.in(synth_net_1), .out(out + )); +DIV1 synth_DIV(.in1(in1), .in2(in2), .rem(synth_net_0), .out(synth_net_1 + )); +endmodule + +// test_simulation_always_31_tt.v +module f2_test(clk, cond, data); input cond; input clk; output data; diff --git a/tests/hana/test_simulation_xnor.v b/tests/hana/test_simulation_xnor.v new file mode 100644 index 00000000..7286d134 --- /dev/null +++ b/tests/hana/test_simulation_xnor.v @@ -0,0 +1,20 @@ + +// test_simulation_xnor_1_test.v +module f1_test(input [1:0] in, output out); +assign out = ~(in[0] ^ in[1]); +endmodule + +// test_simulation_xnor_2_test.v +module f2_test(input [2:0] in, output out); +assign out = ~(in[0] ^ in[1] ^ in[2]); +endmodule + +// test_simulation_xnor_3_test.v +module f3_test(input [3:0] in, output out); +assign out = ~(in[0] ^ in[1] ^ in[2] ^ in[3]); +endmodule + +// test_simulation_xnor_4_test.v +module f4_test(input [3:0] in, output out); +xnor myxnor(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/hana/test_simulation_xnor_1_test.v b/tests/hana/test_simulation_xnor_1_test.v deleted file mode 100644 index adc6ae5c..00000000 --- a/tests/hana/test_simulation_xnor_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = ~(in[0] ^ in[1]); -endmodule diff --git a/tests/hana/test_simulation_xnor_2_test.v b/tests/hana/test_simulation_xnor_2_test.v deleted file mode 100644 index 701bcc77..00000000 --- a/tests/hana/test_simulation_xnor_2_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = ~(in[0] ^ in[1] ^ in[2]); -endmodule diff --git a/tests/hana/test_simulation_xnor_3_test.v b/tests/hana/test_simulation_xnor_3_test.v deleted file mode 100644 index a8c87cc6..00000000 --- a/tests/hana/test_simulation_xnor_3_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = ~(in[0] ^ in[1] ^ in[2] ^ in[3]); -endmodule diff --git a/tests/hana/test_simulation_xnor_4_test.v b/tests/hana/test_simulation_xnor_4_test.v deleted file mode 100644 index fa671ff9..00000000 --- a/tests/hana/test_simulation_xnor_4_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -xnor myxnor(out, in[0], in[1], in[2], in[3]); -endmodule diff --git a/tests/hana/test_simulation_xor.v b/tests/hana/test_simulation_xor.v new file mode 100644 index 00000000..e181dd83 --- /dev/null +++ b/tests/hana/test_simulation_xor.v @@ -0,0 +1,20 @@ + +// test_simulation_xor_1_test.v +module f1_test(input [1:0] in, output out); +assign out = (in[0] ^ in[1]); +endmodule + +// test_simulation_xor_2_test.v +module f2_test(input [2:0] in, output out); +assign out = (in[0] ^ in[1] ^ in[2]); +endmodule + +// test_simulation_xor_3_test.v +module f3_test(input [3:0] in, output out); +assign out = (in[0] ^ in[1] ^ in[2] ^ in[3]); +endmodule + +// test_simulation_xor_4_test.v +module f4_test(input [3:0] in, output out); +xor myxor(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/hana/test_simulation_xor_1_test.v b/tests/hana/test_simulation_xor_1_test.v deleted file mode 100644 index f6447f81..00000000 --- a/tests/hana/test_simulation_xor_1_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [1:0] in, output out); -assign out = (in[0] ^ in[1]); -endmodule diff --git a/tests/hana/test_simulation_xor_2_test.v b/tests/hana/test_simulation_xor_2_test.v deleted file mode 100644 index d94081df..00000000 --- a/tests/hana/test_simulation_xor_2_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [2:0] in, output out); -assign out = (in[0] ^ in[1] ^ in[2]); -endmodule diff --git a/tests/hana/test_simulation_xor_3_test.v b/tests/hana/test_simulation_xor_3_test.v deleted file mode 100644 index cfa13187..00000000 --- a/tests/hana/test_simulation_xor_3_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -assign out = (in[0] ^ in[1] ^ in[2] ^ in[3]); -endmodule diff --git a/tests/hana/test_simulation_xor_4_test.v b/tests/hana/test_simulation_xor_4_test.v deleted file mode 100644 index be6cab63..00000000 --- a/tests/hana/test_simulation_xor_4_test.v +++ /dev/null @@ -1,3 +0,0 @@ -module test(input [3:0] in, output out); -xor myxor(out, in[0], in[1], in[2], in[3]); -endmodule From 97a17d39e2f0088e02ed8496d905528722115674 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 15:25:42 +0200 Subject: [PATCH 515/750] Packed SigBit::data and SigBit::offset in a union --- kernel/rtlil.cc | 4 +++- kernel/rtlil.h | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 01225314..79ddd2e0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1681,9 +1681,11 @@ RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width) RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit) { wire = bit.wire; + offset = 0; if (wire == NULL) data = RTLIL::Const(bit.data); - offset = bit.offset; + else + offset = bit.offset; width = 1; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 796d45df..43c7e105 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -707,15 +707,17 @@ struct RTLIL::SigChunk struct RTLIL::SigBit { RTLIL::Wire *wire; - RTLIL::State data; - int offset; + union { + RTLIL::State data; + int offset; + }; - SigBit() : wire(NULL), data(RTLIL::State::S0), offset(0) { } - SigBit(RTLIL::State bit) : wire(NULL), data(bit), offset(0) { } - SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { log_assert(wire && wire->width == 1); } - SigBit(RTLIL::Wire *wire, int offset) : wire(wire), data(RTLIL::State::S0), offset(offset) { log_assert(wire); } - SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[0]), offset(chunk.offset) { log_assert(chunk.width == 1); } - SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[index]), offset(chunk.wire ? chunk.offset + index : 0) { } + SigBit() : wire(NULL), data(RTLIL::State::S0) { } + SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } + SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0) { log_assert(wire && wire->width == 1); } + SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire); } + SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { if (wire) offset = chunk.offset; else data = chunk.data.bits[0]; log_assert(chunk.width == 1); } + SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data.bits[index]; } SigBit(const RTLIL::SigSpec &sig); bool operator <(const RTLIL::SigBit &other) const { From d13eb7e0999def2da03eb6ddef805145f7fd9c9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 16:53:15 +0200 Subject: [PATCH 516/750] Added ModIndex helper class, some changes to RTLIL::Monitor --- kernel/log.h | 5 -- kernel/modtools.h | 111 ++++++++++++++++++++++++++++++++++ kernel/rtlil.cc | 36 +++++++---- kernel/rtlil.h | 10 +-- kernel/sigtools.h | 13 ++++ kernel/yosys.cc | 5 ++ kernel/yosys.h | 9 ++- passes/cmds/trace.cc | 6 +- passes/memory/memory_share.cc | 5 +- 9 files changed, 170 insertions(+), 30 deletions(-) diff --git a/kernel/log.h b/kernel/log.h index 0109faf6..9fc83800 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -57,11 +57,6 @@ void log_pop(); void log_reset_stack(); void log_flush(); -namespace RTLIL { - struct SigSpec; - struct Cell; -} - const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); const char *log_id(std::string id); diff --git a/kernel/modtools.h b/kernel/modtools.h index 06e96246..09f2ae65 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -20,9 +20,118 @@ #ifndef MODTOOLS_H #define MODTOOLS_H +#include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +YOSYS_NAMESPACE_BEGIN + +struct ModIndex : public RTLIL::Monitor +{ + struct PortInfo { + const RTLIL::Cell* cell; + const RTLIL::IdString &port; + const int offset; + + PortInfo(RTLIL::Cell* _c, const RTLIL::IdString &_p, int _o) : cell(_c), port(_p), offset(_o) { } + + bool operator<(const PortInfo &other) const { + if (cell != other.cell) + return cell < other.cell; + if (offset != other.offset) + return offset < other.offset; + return port < other.port; + } + }; + + struct SigBitInfo + { + bool is_input, is_output; + std::set ports; + + SigBitInfo() : is_input(false), is_output(false) { } + }; + + SigMap sigmap; + RTLIL::Module *module; + std::map database; + bool auto_reload_module; + + void port_add(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &sig) + { + for (int i = 0; i < SIZE(sig); i++) + database[sigmap(sig[i])].ports.insert(PortInfo(cell, port, i)); + } + + void port_del(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &sig) + { + for (int i = 0; i < SIZE(sig); i++) + database[sigmap(sig[i])].ports.erase(PortInfo(cell, port, i)); + } + + const SigBitInfo &info(RTLIL::SigBit bit) + { + return database[sigmap(bit)]; + } + + void reload_module() + { + sigmap.clear(); + sigmap.set(module); + + database.clear(); + for (auto wire : module->wires()) + if (wire->port_input || wire->port_output) + for (int i = 0; i < SIZE(wire); i++) { + if (wire->port_input) + database[sigmap(RTLIL::SigBit(wire, i))].is_input = true; + if (wire->port_output) + database[sigmap(RTLIL::SigBit(wire, i))].is_output = true; + } + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + port_add(cell, conn.first, conn.second); + + auto_reload_module = false; + } + + virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) override + { + if (auto_reload_module) + reload_module(); + + port_del(cell, port, old_sig); + port_add(cell, port, sig); + } + + virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig&) + { + log_assert(module == mod); + auto_reload_module = true; + } + + virtual void notify_connect(RTLIL::Module *mod, const std::vector&) + { + log_assert(module == mod); + auto_reload_module = true; + } + + virtual void notify_blackout(RTLIL::Module *mod) + { + log_assert(module == mod); + auto_reload_module = true; + } + + ModIndex(RTLIL::Module *_m) : module(_m) { + auto_reload_module = true; + module->monitors.insert(this); + } + + ~ModIndex() { + module->monitors.erase(this); + } +}; + struct ModWalker { struct PortBit @@ -295,4 +404,6 @@ struct ModWalker } }; +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 79ddd2e0..13705852 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1092,11 +1092,11 @@ void RTLIL::Module::connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs void RTLIL::Module::new_connections(const std::vector &new_conn) { for (auto mon : monitors) - mon->notify_new_connections(this, new_conn); + mon->notify_connect(this, new_conn); if (design) for (auto mon : design->monitors) - mon->notify_new_connections(this, new_conn); + mon->notify_connect(this, new_conn); connections_ = new_conn; } @@ -1516,30 +1516,40 @@ bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const void RTLIL::Cell::unsetPort(RTLIL::IdString portname) { - std::pair new_conn(portname, RTLIL::SigSpec()); + RTLIL::SigSpec signal; + auto conn_it = connections_.find(portname); - for (auto mon : module->monitors) - mon->notify_cell_connect(this, new_conn); + if (conn_it != connections_.end()) + { + for (auto mon : module->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); - if (module->design) - for (auto mon : module->design->monitors) - mon->notify_cell_connect(this, new_conn); + if (module->design) + for (auto mon : module->design->monitors) + mon->notify_connect(this, conn_it->first, conn_it->second, signal); - connections_.erase(portname); + connections_.erase(conn_it); + } } void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal) { - std::pair new_conn(portname, signal); + auto conn_it = connections_.find(portname); + + if (conn_it == connections_.end()) { + connections_[portname] = RTLIL::SigSpec(); + conn_it = connections_.find(portname); + log_assert(conn_it != connections_.end()); + } for (auto mon : module->monitors) - mon->notify_cell_connect(this, new_conn); + mon->notify_connect(this, conn_it->first, conn_it->second, signal); if (module->design) for (auto mon : module->design->monitors) - mon->notify_cell_connect(this, new_conn); + mon->notify_connect(this, conn_it->first, conn_it->second, signal); - connections_[portname] = signal; + conn_it->second = signal; } const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 43c7e105..0685f1ea 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -334,9 +334,9 @@ struct RTLIL::Monitor virtual ~Monitor() { } virtual void notify_module_add(RTLIL::Module*) { } virtual void notify_module_del(RTLIL::Module*) { } - virtual void notify_cell_connect(RTLIL::Cell*, const std::pair&) { } + virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, RTLIL::SigSpec&) { } virtual void notify_connect(RTLIL::Module*, const RTLIL::SigSig&) { } - virtual void notify_new_connections(RTLIL::Module*, const std::vector&) { } + virtual void notify_connect(RTLIL::Module*, const std::vector&) { } virtual void notify_blackout(RTLIL::Module*) { } }; @@ -708,15 +708,15 @@ struct RTLIL::SigBit { RTLIL::Wire *wire; union { - RTLIL::State data; - int offset; + RTLIL::State data; // used if wire == NULL + int offset; // used if wire != NULL }; SigBit() : wire(NULL), data(RTLIL::State::S0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0) { log_assert(wire && wire->width == 1); } SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire); } - SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { if (wire) offset = chunk.offset; else data = chunk.data.bits[0]; log_assert(chunk.width == 1); } + SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data.bits[0]; } SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data.bits[index]; } SigBit(const RTLIL::SigSpec &sig); diff --git a/kernel/sigtools.h b/kernel/sigtools.h index b691749a..32ef444a 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -391,11 +391,24 @@ struct SigMap map_bit(bit); } + RTLIL::SigBit operator()(RTLIL::SigBit bit) const + { + apply(bit); + return bit; + } + RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const { apply(sig); return sig; } + + RTLIL::SigSpec operator()(RTLIL::Wire *wire) const + { + RTLIL::SigSpec sig(wire); + apply(sig); + return sig; + } }; YOSYS_NAMESPACE_END diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 34800ce8..67194563 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -53,6 +53,11 @@ std::string stringf(const char *fmt, ...) return string; } +int SIZE(RTLIL::Wire *wire) +{ + return wire->width; +} + void yosys_setup() { Pass::init_register(); diff --git a/kernel/yosys.h b/kernel/yosys.h index 119e7e8a..d9db57c5 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -61,8 +61,15 @@ YOSYS_NAMESPACE_BEGIN +namespace RTLIL { + struct SigSpec; + struct Wire; + struct Cell; +} + std::string stringf(const char *fmt, ...); -#define SIZE(__obj) int(__obj.size()) +template int SIZE(const T &obj) { return obj.size(); } +int SIZE(RTLIL::Wire *wire); YOSYS_NAMESPACE_END diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index b4bc45c2..6a5ea346 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -34,9 +34,9 @@ struct TraceMonitor : public RTLIL::Monitor log("#TRACE# Module delete: %s\n", log_id(module)); } - virtual void notify_cell_connect(RTLIL::Cell *cell, const std::pair &conn) override + virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) override { - log("#TRACE# Cell connect: %s.%s.%s = %s\n", log_id(cell->module), log_id(cell), log_id(conn.first), log_signal(conn.second)); + log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig)); } virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override @@ -44,7 +44,7 @@ struct TraceMonitor : public RTLIL::Monitor log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second)); } - virtual void notify_new_connections(RTLIL::Module *module, const std::vector &sigsig_vec) override + virtual void notify_connect(RTLIL::Module *module, const std::vector &sigsig_vec) override { log("#TRACE# New connections in module %s:\n", log_id(module)); for (auto &sigsig : sigsig_vec) diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index fde6ea00..ace6eeaf 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -735,9 +735,8 @@ struct MemorySharePass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing MEMORY_SHARE pass (consolidating $memrc/$memwr cells).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - MemoryShareWorker(design, mod_it.second); + for (auto module : design->selected_modules()) + MemoryShareWorker(design, module); } } MemorySharePass; From 1e224506be6d824ea9ed1855fa46d039e5ffefd5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 18:42:10 +0200 Subject: [PATCH 517/750] Added per-pass cpu usage statistics --- kernel/driver.cc | 42 +++++++++++++++++++++++++++++++++++++++--- kernel/log.h | 1 + kernel/register.cc | 42 +++++++++++++++++++++++++++++++++++------- kernel/register.h | 13 +++++++++++-- 4 files changed, 86 insertions(+), 12 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 01ade7d4..273be7ce 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -43,6 +43,7 @@ int main(int argc, char **argv) bool scriptfile_tcl = false; bool got_output_filename = false; bool print_banner = true; + bool print_stats = true; bool call_abort = false; int history_offset = 0; @@ -54,7 +55,7 @@ int main(int argc, char **argv) } int opt; - while ((opt = getopt(argc, argv, "AQVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) + while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) { switch (opt) { @@ -64,6 +65,9 @@ int main(int argc, char **argv) case 'Q': print_banner = false; break; + case 'T': + print_stats = false; + break; case 'V': printf("%s\n", yosys_version_str); exit(0); @@ -129,12 +133,15 @@ int main(int argc, char **argv) break; default: fprintf(stderr, "\n"); - fprintf(stderr, "Usage: %s [-V -S -Q -q] [-v [-t] [-l ] [-o ] [-f ] [-h cmd] \\\n", argv[0]); + fprintf(stderr, "Usage: %s [-V -S -Q -T -q] [-v [-t] [-l ] [-o ] [-f ] [-h cmd] \\\n", argv[0]); fprintf(stderr, " %*s[{-s|-c} ] [-p [-p ..]] [-b ] [-m ] [ [..]]\n", int(strlen(argv[0])+1), ""); fprintf(stderr, "\n"); fprintf(stderr, " -Q\n"); fprintf(stderr, " suppress printing of banner (copyright, disclaimer, version)\n"); fprintf(stderr, "\n"); + fprintf(stderr, " -T\n"); + fprintf(stderr, " suppress printing of footer (log hash, version, timing statistics)\n"); + fprintf(stderr, "\n"); fprintf(stderr, " -q\n"); fprintf(stderr, " quiet operation. only write error messages to console\n"); fprintf(stderr, "\n"); @@ -284,7 +291,36 @@ int main(int argc, char **argv) } #endif - log("\nEnd of script.\n"); + if (print_stats) + { + struct rusage ru_buffer; + getrusage(RUSAGE_SELF, &ru_buffer); + log("\nEnd of script. Logfile hash: xxxxxxxxxx, CPU: user %.2fs system %.2fs\n", + ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, + ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec); + log("%s\nTime spent:", yosys_version_str); + + int64_t total_ns = 0; + std::set> timedat; + + for (auto &it : pass_register) + if (it.second->call_counter) { + total_ns += it.second->runtime_ns + 1; + timedat.insert(make_tuple(it.second->runtime_ns + 1, it.second->call_counter, it.first)); + } + + int out_count = 0; + for (auto it = timedat.rbegin(); it != timedat.rend() && out_count < 4; it++, out_count++) { + if (out_count >= 2 && (std::get<0>(*it) < 1000000000 || int(100*std::get<0>(*it) / total_ns) < 20)) { + log(", ..."); + break; + } + log("%s %d%% %dx %s (%d sec)", out_count ? "," : "", int(100*std::get<0>(*it) / total_ns), + std::get<1>(*it), std::get<2>(*it).c_str(), int(std::get<0>(*it) / 1000000000)); + } + log("%s\n", out_count ? "" : " no commands executed"); + } + if (call_abort) abort(); diff --git a/kernel/log.h b/kernel/log.h index 9fc83800..8e46ad49 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -170,6 +170,7 @@ struct PerformanceTimer return total_ns * 1e-9; } #else + static int64_t query() { return 0; } void reset() { } void begin() { } void end() { } diff --git a/kernel/register.cc b/kernel/register.cc index 7469b3e8..4d204069 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -29,6 +29,7 @@ YOSYS_NAMESPACE_BEGIN bool echo_mode = false; Pass *first_queued_pass; +Pass *current_pass; std::map frontend_register; std::map pass_register; @@ -41,6 +42,7 @@ Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_he next_queued_pass = first_queued_pass; first_queued_pass = this; call_counter = 0; + runtime_ns = 0; } void Pass::run_register() @@ -69,6 +71,25 @@ Pass::~Pass() { } +Pass::pre_post_exec_state_t Pass::pre_execute() +{ + pre_post_exec_state_t state; + call_counter++; + state.begin_ns = PerformanceTimer::query(); + state.parent_pass = current_pass; + current_pass = this; + return state; +} + +void Pass::post_execute(Pass::pre_post_exec_state_t state) +{ + int64_t time_ns = PerformanceTimer::query() - state.begin_ns; + runtime_ns += time_ns; + current_pass = state.parent_pass; + if (current_pass) + current_pass->runtime_ns -= time_ns; +} + void Pass::help() { log("\n"); @@ -183,8 +204,9 @@ void Pass::call(RTLIL::Design *design, std::vector args) log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str()); size_t orig_sel_stack_pos = design->selection_stack.size(); - pass_register[args[0]]->call_counter++; + auto state = pass_register[args[0]]->pre_execute(); pass_register[args[0]]->execute(args, design); + pass_register[args[0]]->post_execute(state); while (design->selection_stack.size() > orig_sel_stack_pos) design->selection_stack.pop_back(); @@ -266,8 +288,9 @@ void Frontend::execute(std::vector args, RTLIL::Design *design) do { FILE *f = NULL; next_args.clear(); - call_counter++; + auto state = pre_execute(); execute(f, std::string(), args, design); + post_execute(state); args = next_args; fclose(f); } while (!args.empty()); @@ -359,12 +382,14 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam log_cmd_error("No such frontend: %s\n", args[0].c_str()); if (f != NULL) { - frontend_register[args[0]]->call_counter++; + auto state = frontend_register[args[0]]->pre_execute(); frontend_register[args[0]]->execute(f, filename, args, design); + frontend_register[args[0]]->post_execute(state); } else if (filename == "-") { FILE *f_stdin = stdin; // workaround for OpenBSD 'stdin' implementation - frontend_register[args[0]]->call_counter++; + auto state = frontend_register[args[0]]->pre_execute(); frontend_register[args[0]]->execute(f_stdin, "", args, design); + frontend_register[args[0]]->post_execute(state); } else { if (!filename.empty()) args.push_back(filename); @@ -396,8 +421,9 @@ Backend::~Backend() void Backend::execute(std::vector args, RTLIL::Design *design) { FILE *f = NULL; - call_counter++; + auto state = pre_execute(); execute(f, std::string(), args, design); + post_execute(state); if (f != stdout) fclose(f); } @@ -458,12 +484,14 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, size_t orig_sel_stack_pos = design->selection_stack.size(); if (f != NULL) { - backend_register[args[0]]->call_counter++; + auto state = backend_register[args[0]]->pre_execute(); backend_register[args[0]]->execute(f, filename, args, design); + backend_register[args[0]]->post_execute(state); } else if (filename == "-") { FILE *f_stdout = stdout; // workaround for OpenBSD 'stdout' implementation - backend_register[args[0]]->call_counter++; + auto state = backend_register[args[0]]->pre_execute(); backend_register[args[0]]->execute(f_stdout, "", args, design); + backend_register[args[0]]->post_execute(state); } else { if (!filename.empty()) args.push_back(filename); diff --git a/kernel/register.h b/kernel/register.h index 17942ca9..93a3308a 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -31,14 +31,23 @@ YOSYS_NAMESPACE_BEGIN struct Pass { std::string pass_name, short_help; - int call_counter; - Pass(std::string name, std::string short_help = "** document me **"); virtual ~Pass(); virtual void help(); virtual void execute(std::vector args, RTLIL::Design *design) = 0; + int call_counter; + int64_t runtime_ns; + + struct pre_post_exec_state_t { + Pass *parent_pass; + int64_t begin_ns; + }; + + pre_post_exec_state_t pre_execute(); + void post_execute(pre_post_exec_state_t state); + void cmd_log_args(const std::vector &args); void cmd_error(const std::vector &args, size_t argidx, std::string msg); void extra_args(std::vector args, size_t argidx, RTLIL::Design *design, bool select = true); From bd74ed7da467de11128c57c4c424febe4a7e2f39 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 19:01:10 +0200 Subject: [PATCH 518/750] Replaced sha1 implementation --- frontends/ast/ast.cc | 29 +-- libs/sha1/sha1.cpp | 455 ++++++++++++++++++++++--------------- libs/sha1/sha1.h | 106 +++++---- manual/CHAPTER_Auxlibs.tex | 6 +- manual/weblinks.bib | 6 - passes/opt/opt_reduce.cc | 1 - passes/opt/opt_share.cc | 7 +- passes/techmap/techmap.cc | 7 +- 8 files changed, 334 insertions(+), 283 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 46b717ce..85b67b65 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) + modname = "$paramod$" + sha1(para_info) + stripped_name; else - if (para_info.size() > 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 - { modname = "$paramod" + stripped_name + para_info; - } if (!design->has(modname)) { new_ast->str = modname; diff --git a/libs/sha1/sha1.cpp b/libs/sha1/sha1.cpp index fb7bfed6..dc86b2ce 100644 --- a/libs/sha1/sha1.cpp +++ b/libs/sha1/sha1.cpp @@ -1,185 +1,270 @@ -/* - Copyright (c) 2011, Micael Hildenborg - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Micael Hildenborg nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - Contributors: - Gustav - Several members in the gamedev.se forum. - Gregory Petrosyan - */ - -#include "sha1.h" - -namespace sha1 -{ - namespace // local - { - // Rotate an integer value to left. - inline unsigned int rol(const unsigned int value, - const unsigned int steps) - { - return ((value << steps) | (value >> (32 - steps))); - } - - // Sets the first 16 integers in the buffert to zero. - // Used for clearing the W buffert. - inline void clearWBuffert(unsigned int* buffert) - { - for (int pos = 16; --pos >= 0;) - { - buffert[pos] = 0; - } - } - - void innerHash(unsigned int* result, unsigned int* w) - { - unsigned int a = result[0]; - unsigned int b = result[1]; - unsigned int c = result[2]; - unsigned int d = result[3]; - unsigned int e = result[4]; - - int round = 0; - - #define sha1macro(func,val) \ - { \ - const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \ - e = d; \ - d = c; \ - c = rol(b, 30); \ - b = a; \ - a = t; \ - } - - while (round < 16) - { - sha1macro((b & c) | (~b & d), 0x5a827999) - ++round; - } - while (round < 20) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro((b & c) | (~b & d), 0x5a827999) - ++round; - } - while (round < 40) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro(b ^ c ^ d, 0x6ed9eba1) - ++round; - } - while (round < 60) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc) - ++round; - } - while (round < 80) - { - w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); - sha1macro(b ^ c ^ d, 0xca62c1d6) - ++round; - } - - #undef sha1macro - - result[0] += a; - result[1] += b; - result[2] += c; - result[3] += d; - result[4] += e; - } - } // namespace - - void calc(const void* src, const int bytelength, unsigned char* hash) - { - // Init the result array. - unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; - - // Cast the void src pointer to be the byte array we can work with. - const unsigned char* sarray = (const unsigned char*) src; - - // The reusable round buffer - unsigned int w[80]; - - // Loop through all complete 64byte blocks. - const int endOfFullBlocks = bytelength - 64; - int endCurrentBlock; - int currentBlock = 0; - - while (currentBlock <= endOfFullBlocks) - { - endCurrentBlock = currentBlock + 64; - - // Init the round buffer with the 64 byte block data. - for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4) - { - // This line will swap endian on big endian and keep endian on little endian. - w[roundPos++] = (unsigned int) sarray[currentBlock + 3] - | (((unsigned int) sarray[currentBlock + 2]) << 8) - | (((unsigned int) sarray[currentBlock + 1]) << 16) - | (((unsigned int) sarray[currentBlock]) << 24); - } - innerHash(result, w); - } - - // Handle the last and not full 64 byte block if existing. - endCurrentBlock = bytelength - currentBlock; - clearWBuffert(w); - int lastBlockBytes = 0; - for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) - { - w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3); - } - w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3); - if (endCurrentBlock >= 56) - { - innerHash(result, w); - clearWBuffert(w); - } - w[15] = bytelength << 3; - innerHash(result, w); - - // Store hash in result pointer, and make sure we get in in the correct order on both endian models. - for (int hashByte = 20; --hashByte >= 0;) - { - hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff; - } - } - - void toHexString(const unsigned char* hash, char* hexstring) - { - const char hexDigits[] = { "0123456789abcdef" }; - - for (int hashByte = 20; --hashByte >= 0;) - { - hexstring[hashByte << 1] = hexDigits[(hash[hashByte] >> 4) & 0xf]; - hexstring[(hashByte << 1) + 1] = hexDigits[hash[hashByte] & 0xf]; - } - hexstring[40] = 0; - } -} // namespace sha1 +/* + sha1.cpp - source code of + + ============ + SHA-1 in C++ + ============ + + 100% Public Domain. + + Original C Code + -- Steve Reid + Small changes to fit into bglibs + -- Bruce Guenter + Translation to simpler C++ Code + -- Volker Grabsch +*/ + +#include "sha1.h" +#include +#include +#include + +/* Help macros */ +#define SHA1_ROL(value, bits) (((value) << (bits)) | (((value) & 0xffffffff) >> (32 - (bits)))) +#define SHA1_BLK(i) (block[i&15] = SHA1_ROL(block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define SHA1_R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + block[i] + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); +#define SHA1_R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + SHA1_BLK(i) + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); +#define SHA1_R2(v,w,x,y,z,i) z += (w^x^y) + SHA1_BLK(i) + 0x6ed9eba1 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); +#define SHA1_R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + SHA1_BLK(i) + 0x8f1bbcdc + SHA1_ROL(v,5); w=SHA1_ROL(w,30); +#define SHA1_R4(v,w,x,y,z,i) z += (w^x^y) + SHA1_BLK(i) + 0xca62c1d6 + SHA1_ROL(v,5); w=SHA1_ROL(w,30); + +SHA1::SHA1() +{ + reset(); +} + + +void SHA1::update(const std::string &s) +{ + std::istringstream is(s); + update(is); +} + + +void SHA1::update(std::istream &is) +{ + std::string rest_of_buffer; + read(is, rest_of_buffer, BLOCK_BYTES - buffer.size()); + buffer += rest_of_buffer; + + while (is) + { + uint32 block[BLOCK_INTS]; + buffer_to_block(buffer, block); + transform(block); + read(is, buffer, BLOCK_BYTES); + } +} + + +/* + * Add padding and return the message digest. + */ + +std::string SHA1::final() +{ + /* Total number of hashed bits */ + uint64 total_bits = (transforms*BLOCK_BYTES + buffer.size()) * 8; + + /* Padding */ + buffer += 0x80; + unsigned int orig_size = buffer.size(); + while (buffer.size() < BLOCK_BYTES) + { + buffer += (char)0x00; + } + + uint32 block[BLOCK_INTS]; + buffer_to_block(buffer, block); + + if (orig_size > BLOCK_BYTES - 8) + { + transform(block); + for (unsigned int i = 0; i < BLOCK_INTS - 2; i++) + { + block[i] = 0; + } + } + + /* Append total_bits, split this uint64 into two uint32 */ + block[BLOCK_INTS - 1] = total_bits; + block[BLOCK_INTS - 2] = (total_bits >> 32); + transform(block); + + /* Hex std::string */ + std::ostringstream result; + for (unsigned int i = 0; i < DIGEST_INTS; i++) + { + result << std::hex << std::setfill('0') << std::setw(8); + result << (digest[i] & 0xffffffff); + } + + /* Reset for next run */ + reset(); + + return result.str(); +} + + +std::string SHA1::from_file(const std::string &filename) +{ + std::ifstream stream(filename.c_str(), std::ios::binary); + SHA1 checksum; + checksum.update(stream); + return checksum.final(); +} + + +void SHA1::reset() +{ + /* SHA1 initialization constants */ + digest[0] = 0x67452301; + digest[1] = 0xefcdab89; + digest[2] = 0x98badcfe; + digest[3] = 0x10325476; + digest[4] = 0xc3d2e1f0; + + /* Reset counters */ + transforms = 0; + buffer = ""; +} + + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ + +void SHA1::transform(uint32 block[BLOCK_BYTES]) +{ + /* Copy digest[] to working vars */ + uint32 a = digest[0]; + uint32 b = digest[1]; + uint32 c = digest[2]; + uint32 d = digest[3]; + uint32 e = digest[4]; + + + /* 4 rounds of 20 operations each. Loop unrolled. */ + SHA1_R0(a,b,c,d,e, 0); + SHA1_R0(e,a,b,c,d, 1); + SHA1_R0(d,e,a,b,c, 2); + SHA1_R0(c,d,e,a,b, 3); + SHA1_R0(b,c,d,e,a, 4); + SHA1_R0(a,b,c,d,e, 5); + SHA1_R0(e,a,b,c,d, 6); + SHA1_R0(d,e,a,b,c, 7); + SHA1_R0(c,d,e,a,b, 8); + SHA1_R0(b,c,d,e,a, 9); + SHA1_R0(a,b,c,d,e,10); + SHA1_R0(e,a,b,c,d,11); + SHA1_R0(d,e,a,b,c,12); + SHA1_R0(c,d,e,a,b,13); + SHA1_R0(b,c,d,e,a,14); + SHA1_R0(a,b,c,d,e,15); + SHA1_R1(e,a,b,c,d,16); + SHA1_R1(d,e,a,b,c,17); + SHA1_R1(c,d,e,a,b,18); + SHA1_R1(b,c,d,e,a,19); + SHA1_R2(a,b,c,d,e,20); + SHA1_R2(e,a,b,c,d,21); + SHA1_R2(d,e,a,b,c,22); + SHA1_R2(c,d,e,a,b,23); + SHA1_R2(b,c,d,e,a,24); + SHA1_R2(a,b,c,d,e,25); + SHA1_R2(e,a,b,c,d,26); + SHA1_R2(d,e,a,b,c,27); + SHA1_R2(c,d,e,a,b,28); + SHA1_R2(b,c,d,e,a,29); + SHA1_R2(a,b,c,d,e,30); + SHA1_R2(e,a,b,c,d,31); + SHA1_R2(d,e,a,b,c,32); + SHA1_R2(c,d,e,a,b,33); + SHA1_R2(b,c,d,e,a,34); + SHA1_R2(a,b,c,d,e,35); + SHA1_R2(e,a,b,c,d,36); + SHA1_R2(d,e,a,b,c,37); + SHA1_R2(c,d,e,a,b,38); + SHA1_R2(b,c,d,e,a,39); + SHA1_R3(a,b,c,d,e,40); + SHA1_R3(e,a,b,c,d,41); + SHA1_R3(d,e,a,b,c,42); + SHA1_R3(c,d,e,a,b,43); + SHA1_R3(b,c,d,e,a,44); + SHA1_R3(a,b,c,d,e,45); + SHA1_R3(e,a,b,c,d,46); + SHA1_R3(d,e,a,b,c,47); + SHA1_R3(c,d,e,a,b,48); + SHA1_R3(b,c,d,e,a,49); + SHA1_R3(a,b,c,d,e,50); + SHA1_R3(e,a,b,c,d,51); + SHA1_R3(d,e,a,b,c,52); + SHA1_R3(c,d,e,a,b,53); + SHA1_R3(b,c,d,e,a,54); + SHA1_R3(a,b,c,d,e,55); + SHA1_R3(e,a,b,c,d,56); + SHA1_R3(d,e,a,b,c,57); + SHA1_R3(c,d,e,a,b,58); + SHA1_R3(b,c,d,e,a,59); + SHA1_R4(a,b,c,d,e,60); + SHA1_R4(e,a,b,c,d,61); + SHA1_R4(d,e,a,b,c,62); + SHA1_R4(c,d,e,a,b,63); + SHA1_R4(b,c,d,e,a,64); + SHA1_R4(a,b,c,d,e,65); + SHA1_R4(e,a,b,c,d,66); + SHA1_R4(d,e,a,b,c,67); + SHA1_R4(c,d,e,a,b,68); + SHA1_R4(b,c,d,e,a,69); + SHA1_R4(a,b,c,d,e,70); + SHA1_R4(e,a,b,c,d,71); + SHA1_R4(d,e,a,b,c,72); + SHA1_R4(c,d,e,a,b,73); + SHA1_R4(b,c,d,e,a,74); + SHA1_R4(a,b,c,d,e,75); + SHA1_R4(e,a,b,c,d,76); + SHA1_R4(d,e,a,b,c,77); + SHA1_R4(c,d,e,a,b,78); + SHA1_R4(b,c,d,e,a,79); + + /* Add the working vars back into digest[] */ + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; + digest[4] += e; + + /* Count the number of transformations */ + transforms++; +} + + +void SHA1::buffer_to_block(const std::string &buffer, uint32 block[BLOCK_BYTES]) +{ + /* Convert the std::string (byte buffer) to a uint32 array (MSB) */ + for (unsigned int i = 0; i < BLOCK_INTS; i++) + { + block[i] = (buffer[4*i+3] & 0xff) + | (buffer[4*i+2] & 0xff)<<8 + | (buffer[4*i+1] & 0xff)<<16 + | (buffer[4*i+0] & 0xff)<<24; + } +} + + +void SHA1::read(std::istream &is, std::string &s, int max) +{ + char sbuf[max]; + is.read(sbuf, max); + s.assign(sbuf, is.gcount()); +} + + +std::string sha1(const std::string &string) +{ + SHA1 checksum; + checksum.update(string); + return checksum.final(); +} diff --git a/libs/sha1/sha1.h b/libs/sha1/sha1.h index 540c156d..15edee12 100644 --- a/libs/sha1/sha1.h +++ b/libs/sha1/sha1.h @@ -1,49 +1,57 @@ -/* - Copyright (c) 2011, Micael Hildenborg - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Micael Hildenborg nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SHA1_DEFINED -#define SHA1_DEFINED - -namespace sha1 -{ - - /** - @param src points to any kind of data to be hashed. - @param bytelength the number of bytes to hash from the src pointer. - @param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in. - */ - void calc(const void* src, const int bytelength, unsigned char* hash); - - /** - @param hash is 20 bytes of sha1 hash. This is the same data that is the result from the calc function. - @param hexstring should point to a buffer of at least 41 bytes of size for storing the hexadecimal representation of the hash. A zero will be written at position 40, so the buffer will be a valid zero ended string. - */ - void toHexString(const unsigned char* hash, char* hexstring); - -} // namespace sha1 - -#endif // SHA1_DEFINED +/* + sha1.h - header of + + ============ + SHA-1 in C++ + ============ + + 100% Public Domain. + + Original C Code + -- Steve Reid + Small changes to fit into bglibs + -- Bruce Guenter + Translation to simpler C++ Code + -- Volker Grabsch +*/ + +#ifndef SHA1_HPP +#define SHA1_HPP + + +#include +#include + +class SHA1 +{ +public: + SHA1(); + void update(const std::string &s); + void update(std::istream &is); + std::string final(); + static std::string from_file(const std::string &filename); + +private: + typedef unsigned long int uint32; /* just needs to be at least 32bit */ + typedef unsigned long long uint64; /* just needs to be at least 64bit */ + + static const unsigned int DIGEST_INTS = 5; /* number of 32bit integers per SHA1 digest */ + static const unsigned int BLOCK_INTS = 16; /* number of 32bit integers per SHA1 block */ + static const unsigned int BLOCK_BYTES = BLOCK_INTS * 4; + + uint32 digest[DIGEST_INTS]; + std::string buffer; + uint64 transforms; + + void reset(); + void transform(uint32 block[BLOCK_BYTES]); + + static void buffer_to_block(const std::string &buffer, uint32 block[BLOCK_BYTES]); + static void read(std::istream &is, std::string &s, int max); +}; + +std::string sha1(const std::string &string); + + + +#endif /* SHA1_HPP */ diff --git a/manual/CHAPTER_Auxlibs.tex b/manual/CHAPTER_Auxlibs.tex index 0726e031..8d3ed743 100644 --- a/manual/CHAPTER_Auxlibs.tex +++ b/manual/CHAPTER_Auxlibs.tex @@ -6,9 +6,9 @@ with Yosys. \section{SHA1} -The files in {\tt libs/sha1/} provide a SHA1 implementation written by Micael -Hildenborg \citeweblink{smallsha1}. It is used for generating unique names when -specializing parameterized modules. +The files in {\tt libs/sha1/} provide a public domain SHA1 implementation written +by Steve Reid, Bruce Guenter, and Volker Grabsch. It is used for generating +unique names when specializing parameterized modules. \section{BigInt} diff --git a/manual/weblinks.bib b/manual/weblinks.bib index 9b6032ed..5215a6ca 100644 --- a/manual/weblinks.bib +++ b/manual/weblinks.bib @@ -132,9 +132,3 @@ note = {\url{http://mattmccutchen.net/bigint/}} } -@misc{smallsha1, - author = {Micael Hildenborg}, - title = {{smallsha1}}, - note = {\url{https://code.google.com/p/smallsha1/}} -} - diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 80ec8974..f947e972 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -22,7 +22,6 @@ #include "kernel/sigtools.h" #include "kernel/log.h" #include "kernel/celltypes.h" -#include "libs/sha1/sha1.h" #include #include #include diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 26d19414..3532b124 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -107,12 +107,7 @@ struct OptShareWorker hash_string += "\n"; } - unsigned char hash[20]; - char hash_hex_string[41]; - sha1::calc(hash_string.c_str(), hash_string.size(), hash); - sha1::toHexString(hash, hash_hex_string); - cell_hash_cache[cell] = hash_hex_string; - + cell_hash_cache[cell] = sha1(hash_string); return cell_hash_cache[cell]; } #endif diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index c2e5960f..1f812e52 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -99,12 +99,7 @@ struct TechmapWorker connbits_map[bit] = std::pair(conn.first, i);stringf("%s %d", log_id(conn.first), i, bit.data); } - unsigned char hash[20]; - char hash_hex_string[41]; - sha1::calc(constmap_info.c_str(), constmap_info.size(), hash); - sha1::toHexString(hash, hash_hex_string); - - return stringf("$paramod$constmap$%s%s", hash_hex_string, tpl->name.c_str()); + return stringf("$paramod$constmap:%s%s", sha1(constmap_info).c_str(), tpl->name.c_str()); } TechmapWires techmap_find_special_wires(RTLIL::Module *module) From 75ffd1643c97321255bc591edf0c1a7097b8dce9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 19:43:28 +0200 Subject: [PATCH 519/750] Added logfile hash to statistics footer --- kernel/driver.cc | 70 ++++++++++++++++++++++++++---------------------- kernel/log.cc | 36 ++++++++++++++++--------- kernel/log.h | 2 ++ kernel/yosys.cc | 16 +++++++++-- kernel/yosys.h | 2 ++ 5 files changed, 80 insertions(+), 46 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 273be7ce..6f976423 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -18,6 +18,7 @@ */ #include "kernel/yosys.h" +#include "libs/sha1/sha1.h" #include #include @@ -233,6 +234,9 @@ int main(int argc, char **argv) log("\n"); } + if (print_stats) + log_hasher = new SHA1; + yosys_setup(); if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) { @@ -262,8 +266,40 @@ int main(int argc, char **argv) if (!backend_command.empty()) run_backend(output_filename, backend_command, yosys_design); - delete yosys_design; - yosys_design = NULL; + if (print_stats) + { + std::string hash = log_hasher->final().substr(0, 10); + delete log_hasher; + log_hasher = nullptr; + + struct rusage ru_buffer; + getrusage(RUSAGE_SELF, &ru_buffer); + log("\nEnd of script. Logfile hash: %s, CPU: user %.2fs system %.2fs\n", hash.c_str(), + ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, + ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec); + log("%s\n", yosys_version_str); + + int64_t total_ns = 0; + std::set> timedat; + + for (auto &it : pass_register) + if (it.second->call_counter) { + total_ns += it.second->runtime_ns + 1; + timedat.insert(make_tuple(it.second->runtime_ns + 1, it.second->call_counter, it.first)); + } + + int out_count = 0; + log("Time spent:"); + for (auto it = timedat.rbegin(); it != timedat.rend() && out_count < 4; it++, out_count++) { + if (out_count >= 2 && (std::get<0>(*it) < 1000000000 || int(100*std::get<0>(*it) / total_ns) < 20)) { + log(", ..."); + break; + } + log("%s %d%% %dx %s (%d sec)", out_count ? "," : "", int(100*std::get<0>(*it) / total_ns), + std::get<1>(*it), std::get<2>(*it).c_str(), int(std::get<0>(*it) / 1000000000)); + } + log("%s\n", out_count ? "" : " no commands executed"); + } #ifdef COVER_ACTIVE if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) @@ -291,36 +327,6 @@ int main(int argc, char **argv) } #endif - if (print_stats) - { - struct rusage ru_buffer; - getrusage(RUSAGE_SELF, &ru_buffer); - log("\nEnd of script. Logfile hash: xxxxxxxxxx, CPU: user %.2fs system %.2fs\n", - ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, - ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec); - log("%s\nTime spent:", yosys_version_str); - - int64_t total_ns = 0; - std::set> timedat; - - for (auto &it : pass_register) - if (it.second->call_counter) { - total_ns += it.second->runtime_ns + 1; - timedat.insert(make_tuple(it.second->runtime_ns + 1, it.second->call_counter, it.first)); - } - - int out_count = 0; - for (auto it = timedat.rbegin(); it != timedat.rend() && out_count < 4; it++, out_count++) { - if (out_count >= 2 && (std::get<0>(*it) < 1000000000 || int(100*std::get<0>(*it) / total_ns) < 20)) { - log(", ..."); - break; - } - log("%s %d%% %dx %s (%d sec)", out_count ? "," : "", int(100*std::get<0>(*it) / total_ns), - std::get<1>(*it), std::get<2>(*it).c_str(), int(std::get<0>(*it) / 1000000000)); - } - log("%s\n", out_count ? "" : " no commands executed"); - } - if (call_abort) abort(); diff --git a/kernel/log.cc b/kernel/log.cc index 64dd7a92..10eb2563 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -18,6 +18,7 @@ */ #include "kernel/yosys.h" +#include "libs/sha1/sha1.h" #include "backends/ilang/ilang_backend.h" #include @@ -32,6 +33,8 @@ YOSYS_NAMESPACE_BEGIN std::vector log_files; FILE *log_errfile = NULL; +SHA1 *log_hasher = NULL; + bool log_time = false; bool log_cmd_error_throw = false; int log_verbose_level; @@ -44,11 +47,20 @@ static bool next_print_log = false; void logv(const char *format, va_list ap) { - if (log_time) { - while (format[0] == '\n' && format[1] != 0) { - format++; - log("\n"); - } + while (format[0] == '\n' && format[1] != 0) { + log("\n"); + format++; + } + + std::string str = vstringf(format, ap); + + if (log_hasher) + log_hasher->update(str); + + if (log_time) + { + std::string time_str; + if (next_print_log || initial_tv.tv_sec == 0) { next_print_log = false; struct timeval tv; @@ -61,18 +73,18 @@ void logv(const char *format, va_list ap) } tv.tv_sec -= initial_tv.tv_sec; tv.tv_usec -= initial_tv.tv_usec; - log("[%05d.%06d] ", int(tv.tv_sec), int(tv.tv_usec)); + time_str += stringf("[%05d.%06d] ", int(tv.tv_sec), int(tv.tv_usec)); } + if (format[0] && format[strlen(format)-1] == '\n') next_print_log = true; + + for (auto f : log_files) + fputs(time_str.c_str(), f); } - for (auto f : log_files) { - va_list aq; - va_copy(aq, ap); - vfprintf(f, format, aq); - va_end(aq); - } + for (auto f : log_files) + fputs(str.c_str(), f); } void logv_header(const char *format, va_list ap) diff --git a/kernel/log.h b/kernel/log.h index 8e46ad49..2e968039 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -38,6 +38,8 @@ struct log_cmd_error_expection { }; extern std::vector log_files; extern FILE *log_errfile; +extern class SHA1 *log_hasher; + extern bool log_time; extern bool log_cmd_error_throw; extern int log_verbose_level; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 67194563..89a9cdf7 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -37,13 +37,22 @@ Tcl_Interp *yosys_tcl_interp = NULL; std::string stringf(const char *fmt, ...) { std::string string; - char *str = NULL; va_list ap; va_start(ap, fmt); + string = vstringf(fmt, ap); + va_end(ap); + + return string; +} + +std::string vstringf(const char *fmt, va_list ap) +{ + std::string string; + char *str = NULL; + if (vasprintf(&str, fmt, ap) < 0) str = NULL; - va_end(ap); if (str != NULL) { string = str; @@ -71,6 +80,9 @@ void yosys_shutdown() { log_pop(); + delete yosys_design; + yosys_design = NULL; + for (auto f : log_files) if (f != stderr) fclose(f); diff --git a/kernel/yosys.h b/kernel/yosys.h index d9db57c5..e90dcc46 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -43,6 +43,7 @@ #include #include #include +#include #define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_END } @@ -68,6 +69,7 @@ namespace RTLIL { } std::string stringf(const char *fmt, ...); +std::string vstringf(const char *fmt, va_list ap); template int SIZE(const T &obj) { return obj.size(); } int SIZE(RTLIL::Wire *wire); From 14412e6c957a34381c33740426b35f7b90a446be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 00:45:25 +0200 Subject: [PATCH 520/750] Preparations for RTLIL::IdString redesign: cleanup of existing code --- frontends/ast/ast.cc | 4 +-- frontends/ast/simplify.cc | 2 +- kernel/celltypes.h | 10 +++---- kernel/log.cc | 4 +-- kernel/log.h | 2 +- kernel/rtlil.h | 56 ++++++++++++++++++++++++++++++++------- kernel/yosys.cc | 10 +++---- kernel/yosys.h | 1 + passes/abc/abc.cc | 2 +- passes/cmds/delete.cc | 6 ++--- passes/cmds/design.cc | 2 +- passes/cmds/select.cc | 4 +-- 12 files changed, 71 insertions(+), 32 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 85b67b65..5815fb0d 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 c51692f1..4d71bb39 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); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index e1a1110d..99386382 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -29,7 +29,7 @@ struct CellTypes { - std::set cell_types; + std::set cell_types; std::vector designs; CellTypes() @@ -168,7 +168,7 @@ struct CellTypes designs.clear(); } - bool cell_known(std::string type) + bool cell_known(RTLIL::IdString type) { if (cell_types.count(type) > 0) return true; @@ -178,7 +178,7 @@ struct CellTypes return false; } - bool cell_output(std::string type, std::string port) + bool cell_output(RTLIL::IdString type, RTLIL::IdString port) { if (cell_types.count(type) == 0) { for (auto design : designs) @@ -201,7 +201,7 @@ struct CellTypes return false; } - bool cell_input(std::string type, std::string port) + bool cell_input(RTLIL::IdString type, RTLIL::IdString port) { if (cell_types.count(type) == 0) { for (auto design : designs) @@ -219,7 +219,7 @@ struct CellTypes return false; } - static RTLIL::Const eval(std::string type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) + static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { if (type == "$sshr" && !signed1) type = "$shr"; diff --git a/kernel/log.cc b/kernel/log.cc index 10eb2563..1595596a 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -203,12 +203,12 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) return string_buf.back().c_str(); } -const char *log_id(std::string str) +const char *log_id(RTLIL::IdString str) { if (str.size() > 1 && str[0] == '\\' && str[1] != '$') string_buf.push_back(str.substr(1)); else - string_buf.push_back(str); + string_buf.push_back(str.str()); return string_buf.back().c_str(); } diff --git a/kernel/log.h b/kernel/log.h index 2e968039..118ff69b 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -60,7 +60,7 @@ void log_reset_stack(); void log_flush(); const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true); -const char *log_id(std::string id); +const char *log_id(RTLIL::IdString id); template static inline const char *log_id(T *obj) { return log_id(obj->name); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0685f1ea..b423b1bc 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -72,9 +72,7 @@ namespace RTLIL typedef std::pair SigSig; -#ifdef NDEBUG - typedef std::string IdString; -#else +#if 1 struct IdString : public std::string { IdString() { } IdString(std::string str) : std::string(str) { @@ -100,30 +98,70 @@ namespace RTLIL void check() const { log_assert(empty() || (size() >= 2 && (at(0) == '$' || at(0) == '\\'))); } + const std::string& str() const { + return *this; + } }; +#else + struct IdString { + IdString(); + IdString(const char *str); + IdString(const IdString &str); + IdString(const std::string &str); + + void operator=(const char *rhs); + void operator=(const IdString &rhs); + void operator=(const std::string &rhs); + + operator const char*() const; + const std::string& str() const; + + bool operator<(const IdString &rhs) const; + bool operator==(const IdString &rhs) const; + bool operator!=(const IdString &rhs) const; + bool operator==(const char *rhs) const; + bool operator!=(const char *rhs) const; + std::string operator+(const char *other) const; + + std::string::const_iterator begin() const; + std::string::const_iterator end() const; + char at(int i) const; + const char*c_str() const; + size_t find(char c) const; + std::string substr(size_t pos = 0, size_t len = std::string::npos) const; + size_t size() const; + bool empty() const; + void clear(); + }; + #endif - static IdString escape_id(std::string str) __attribute__((unused)); - static IdString escape_id(std::string str) { + static inline std::string escape_id(std::string str) { if (str.size() > 0 && str[0] != '\\' && str[0] != '$') return "\\" + str; return str; } - static std::string unescape_id(std::string str) __attribute__((unused)); - static std::string unescape_id(std::string str) { + static inline std::string unescape_id(std::string str) { if (str.size() > 1 && str[0] == '\\' && str[1] != '$') return str.substr(1); return str; } - static const char *id2cstr(std::string str) __attribute__((unused)); - static const char *id2cstr(std::string str) { + static inline const char *id2cstr(std::string str) { if (str.size() > 1 && str[0] == '\\' && str[1] != '$') return str.c_str() + 1; return str.c_str(); } + static inline std::string unescape_id(RTLIL::IdString str) { + return unescape_id(str.str()); + } + + static inline const char *id2cstr(RTLIL::IdString str) { + return id2cstr(str.str()); + } + template struct sort_by_name { bool operator()(T *a, T *b) const { return a->name < b->name; diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 89a9cdf7..b5873d18 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -445,7 +445,7 @@ static char *readline_obj_generator(const char *text, int state) { for (auto &it : design->modules_) if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); } else if (design->modules_.count(design->selected_active_module) > 0) @@ -454,19 +454,19 @@ static char *readline_obj_generator(const char *text, int state) for (auto &it : module->wires_) if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); for (auto &it : module->memories) if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); for (auto &it : module->cells_) if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); for (auto &it : module->processes) if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + obj_names.push_back(strdup(RTLIL::id2cstr(it.first))); } std::sort(obj_names.begin(), obj_names.end()); diff --git a/kernel/yosys.h b/kernel/yosys.h index e90dcc46..f9c1848e 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -63,6 +63,7 @@ YOSYS_NAMESPACE_BEGIN namespace RTLIL { + struct IdString; struct SigSpec; struct Wire; struct Cell; diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 4b2e82ca..19664357 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -193,7 +193,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) } } -static std::string remap_name(std::string abc_name) +static std::string remap_name(RTLIL::IdString abc_name) { std::stringstream sstr; sstr << "$abc$" << map_autoidx << "$" << abc_name.substr(1); diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 67b4d939..2a91bc9e 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -64,7 +64,7 @@ struct DeletePass : public Pass { } extra_args(args, argidx, design); - std::vector delete_mods; + std::vector delete_mods; for (auto &mod_it : design->modules_) { @@ -92,8 +92,8 @@ struct DeletePass : public Pass { std::set delete_wires; std::set delete_cells; - std::set delete_procs; - std::set delete_mems; + std::set delete_procs; + std::set delete_mems; for (auto &it : module->wires_) if (design->selected(module, it.second)) diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 41548f62..260e7b5d 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -192,7 +192,7 @@ struct DesignPass : public Pass { for (auto mod : copy_src_modules) { - std::string trg_name = as_name.empty() ? mod->name : RTLIL::escape_id(as_name); + std::string trg_name = as_name.empty() ? std::string(mod->name) : RTLIL::escape_id(as_name); if (copy_to_design->modules_.count(trg_name)) delete copy_to_design->modules_.at(trg_name); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index bbfa396b..35ca2f47 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -547,7 +547,7 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se return; } - std::vector del_list; + std::vector del_list; for (auto mod_name : sel.selected_modules) if (mod_name != design->selected_active_module) del_list.push_back(mod_name); @@ -1322,7 +1322,7 @@ struct CdPass : public Pass { template static int log_matches(const char *title, std::string pattern, T list) { - std::vector matches; + std::vector matches; for (auto &it : list) if (pattern.empty() || match_ids(it.first, pattern)) From b9bd22b8c8d46284fba4d4c1cbd09092a9ccc5c3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 13:11:01 +0200 Subject: [PATCH 521/750] More cleanups related to RTLIL::IdString usage --- backends/blif/blif.cc | 2 +- backends/btor/btor.cc | 22 +++---- backends/edif/edif.cc | 2 +- backends/verilog/verilog_backend.cc | 12 ++-- frontends/ast/genrtlil.cc | 12 ++-- kernel/rtlil.cc | 2 +- kernel/rtlil.h | 97 +++++++++++------------------ passes/cmds/connwrappers.cc | 6 +- passes/cmds/show.cc | 24 +++---- passes/cmds/splice.cc | 8 +-- passes/cmds/splitnets.cc | 2 +- passes/fsm/fsm_detect.cc | 2 +- passes/fsm/fsm_export.cc | 2 +- passes/fsm/fsm_extract.cc | 4 +- passes/hierarchy/hierarchy.cc | 30 ++++----- passes/hierarchy/submod.cc | 10 +-- passes/memory/memory_collect.cc | 8 +-- passes/memory/memory_map.cc | 4 +- passes/memory/memory_unpack.cc | 6 +- passes/opt/opt_clean.cc | 7 ++- passes/opt/opt_const.cc | 42 ++++++------- passes/opt/opt_rmdff.cc | 2 +- passes/opt/opt_share.cc | 8 +-- passes/proc/proc_clean.cc | 2 +- passes/sat/eval.cc | 2 +- passes/sat/expose.cc | 50 +++++++-------- passes/sat/sat.cc | 6 +- passes/sat/share.cc | 4 +- passes/techmap/dfflibmap.cc | 4 +- passes/techmap/extract.cc | 30 ++++----- passes/techmap/simplemap.cc | 6 +- passes/techmap/techmap.cc | 36 +++++------ passes/tests/test_autotb.cc | 44 ++++++------- 33 files changed, 237 insertions(+), 261 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index b31d6ce6..ecde8b5a 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -209,7 +209,7 @@ struct BlifDumper continue; } - fprintf(f, ".%s %s", subckt_or_gate(cell->type), cstr(cell->type)); + fprintf(f, ".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type)); for (auto &conn : cell->connections()) for (int i = 0; i < conn.second.size(); i++) { if (conn.second.size() == 1) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index d8a54234..201be0cf 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -428,7 +428,7 @@ struct BtorDumper { cell_line = ++line_num; bool reduced = (cell->type == "$not" || cell->type == "$neg") ? false : true; - str = stringf ("%d %s %d %d", cell_line, cell_type_translation.at(cell->type).c_str(), reduced?output_width:w, l); + str = stringf ("%d %s %d %d", cell_line, cell_type_translation.at(cell->type.str()).c_str(), reduced?output_width:w, l); fprintf(f, "%s\n", str.c_str()); } if(output_width < w && (cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos")) @@ -487,13 +487,13 @@ struct BtorDumper int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width); ++line_num; - std::string op = cell_type_translation.at(cell->type); + std::string op = cell_type_translation.at(cell->type.str()); if(cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") { if(l1_signed) - op = s_cell_type_translation.at(cell->type); + op = s_cell_type_translation.at(cell->type.str()); } str = stringf ("%d %s %d %d %d", line_num, op.c_str(), output_width, l1, l2); @@ -521,9 +521,9 @@ struct BtorDumper int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width); ++line_num; - std::string op = cell_type_translation.at(cell->type); + std::string op = cell_type_translation.at(cell->type.str()); if(cell->type == "$div" && l1_signed) - op = s_cell_type_translation.at(cell->type); + op = s_cell_type_translation.at(cell->type.str()); else if(cell->type == "$mod") { if(l1_signed) @@ -555,7 +555,7 @@ struct BtorDumper int l1 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\A")), l1_width); int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); int cell_output = ++line_num; - str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), l1_width, l1, l2); + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), l1_width, l1, l2); fprintf(f, "%s\n", str.c_str()); if(l2_width > ceil(log(l1_width)/log(2))) @@ -635,7 +635,7 @@ struct BtorDumper int s = dump_sigspec(&cell->getPort(RTLIL::IdString("\\S")), 1); ++line_num; str = stringf ("%d %s %d %d %d %d", - line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell + line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell fprintf(f, "%s\n", str.c_str()); line_ref[cell->name]=line_num; } @@ -697,7 +697,7 @@ struct BtorDumper fprintf(f, "%s\n", str.c_str()); } ++line_num; - str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, reg, next); fprintf(f, "%s\n", str.c_str()); } @@ -768,7 +768,7 @@ struct BtorDumper log_assert(output->size() == output_width); int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); ++line_num; - str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, input_line, output_width+offset-1, offset); + str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, input_line, output_width+offset-1, offset); fprintf(f, "%s\n", str.c_str()); line_ref[cell->name]=line_num; } @@ -784,7 +784,7 @@ struct BtorDumper log_assert(input_b->size() == input_b_width); int input_b_line = dump_sigspec(input_b, input_b_width); ++line_num; - str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), input_a_width+input_b_width, + str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), input_a_width+input_b_width, input_a_line, input_b_line); fprintf(f, "%s\n", str.c_str()); line_ref[cell->name]=line_num; @@ -888,7 +888,7 @@ struct BtorDumper inputs[wire->port_id] = wire; if (wire->port_output) { outputs[wire->port_id] = wire; - if (wire->name.find("safety") != std::string::npos ) + if (wire->name.str().find("safety") != std::string::npos ) safety.push_back(wire); } } diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 49f719a4..bf1efc4a 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -108,7 +108,7 @@ struct EdifBackend : public Backend { log_header("Executing EDIF backend.\n"); std::string top_module_name; - std::map> lib_cell_ports; + std::map> lib_cell_ports; CellTypes ct(design); EdifNames edif_names; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 4bba32a6..e3c930c8 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -39,14 +39,14 @@ namespace { bool norename, noattr, attr2comment, noexpr; int auto_name_counter, auto_name_offset, auto_name_digits; -std::map auto_name_map; +std::map auto_name_map; -std::set reg_wires; +std::set reg_wires; CellTypes reg_ct; RTLIL::Module *active_module; -void reset_auto_counter_id(const std::string &id, bool may_rename) +void reset_auto_counter_id(RTLIL::IdString id, bool may_rename) { const char *str = id.c_str(); @@ -94,7 +94,7 @@ void reset_auto_counter(RTLIL::Module *module) log(" renaming `%s' to `_%0*d_'.\n", it->first.c_str(), auto_name_digits, auto_name_offset + it->second); } -std::string id(std::string internal_id, bool may_rename = true) +std::string id(RTLIL::IdString internal_id, bool may_rename = true) { const char *str = internal_id.c_str(); bool do_escape = false; @@ -324,7 +324,7 @@ std::string cellname(RTLIL::Cell *cell) if (wire->name[0] != '\\') goto no_special_reg_name; - std::string cell_name = wire->name; + std::string cell_name = wire->name.str(); size_t pos = cell_name.find('['); if (pos != std::string::npos) @@ -715,7 +715,7 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, " %s (", cell_name.c_str()); bool first_arg = true; - std::set numbered_ports; + std::set numbered_ports; for (int i = 1; true; i++) { char str[16]; snprintf(str, 16, "$%d", i); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index f4f82823..bea99d8d 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; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 13705852..af652a9d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1998,7 +1998,7 @@ void RTLIL::SigSpec::hash() const for (auto &v : c.data.bits) DJB2(that->hash_, v); } else { - for (auto &v : c.wire->name) + for (auto &v : c.wire->name.str()) DJB2(that->hash_, v); DJB2(that->hash_, c.offset); DJB2(that->hash_, c.width); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b423b1bc..70e01b72 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -72,69 +72,42 @@ namespace RTLIL typedef std::pair SigSig; -#if 1 - struct IdString : public std::string { - IdString() { } - IdString(std::string str) : std::string(str) { - check(); - } - IdString(const char *s) : std::string(s) { - check(); - } - IdString &operator=(const std::string &str) { - std::string::operator=(str); - check(); - return *this; - } - IdString &operator=(const char *s) { - std::string::operator=(s); - check(); - return *this; - } - bool operator<(const IdString &rhs) { - check(), rhs.check(); - return std::string(*this) < std::string(rhs); - } - void check() const { - log_assert(empty() || (size() >= 2 && (at(0) == '$' || at(0) == '\\'))); - } - const std::string& str() const { - return *this; - } + struct IdString + { + private: + std::string str_; + + public: + IdString() : str_() { } + IdString(const char *str) : str_(str) { } + IdString(const IdString &str) : str_(str.str_) { } + IdString(const std::string &str) : str_(str) { } + + void operator=(const char *rhs) { str_ = rhs; } + void operator=(const IdString &rhs) { str_ = rhs.str_; } + void operator=(const std::string &rhs) { str_ = rhs; } + + const std::string& str() const { return str_; } + + // The methods below are just convinience functions for better compatibility + // with std::string. Except clear() they all just deligate to std::string. + + operator const char*() const { return str().c_str(); } + + bool operator<(const IdString &rhs) const { return str() < rhs.str(); } + bool operator==(const IdString &rhs) const { return str() == rhs.str(); } + bool operator!=(const IdString &rhs) const { return str() != rhs.str(); } + + bool operator==(const char *rhs) const { return str() == rhs; } + bool operator!=(const char *rhs) const { return str() != rhs; } + + char at(size_t i) const { return str().at(i); } + const char*c_str() const { return str().c_str(); } + std::string substr(size_t pos = 0, size_t len = std::string::npos) const { return str().substr(pos, len); } + size_t size() const { return str().size(); } + bool empty() const { return str().empty(); } + void clear() { *this = IdString(); } }; -#else - struct IdString { - IdString(); - IdString(const char *str); - IdString(const IdString &str); - IdString(const std::string &str); - - void operator=(const char *rhs); - void operator=(const IdString &rhs); - void operator=(const std::string &rhs); - - operator const char*() const; - const std::string& str() const; - - bool operator<(const IdString &rhs) const; - bool operator==(const IdString &rhs) const; - bool operator!=(const IdString &rhs) const; - bool operator==(const char *rhs) const; - bool operator!=(const char *rhs) const; - std::string operator+(const char *other) const; - - std::string::const_iterator begin() const; - std::string::const_iterator end() const; - char at(int i) const; - const char*c_str() const; - size_t find(char c) const; - std::string substr(size_t pos = 0, size_t len = std::string::npos) const; - size_t size() const; - bool empty() const; - void clear(); - }; - -#endif static inline std::string escape_id(std::string str) { if (str.size() > 0 && str[0] != '\\' && str[0] != '$') diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 5125ff5e..aac11716 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -30,8 +30,8 @@ struct ConnwrappersWorker bool is_signed; }; - std::set decl_celltypes; - std::map, portdecl_t> decls; + std::set decl_celltypes; + std::map, portdecl_t> decls; void add_port(std::string celltype, std::string portname, std::string widthparam, std::string signparam) { @@ -76,7 +76,7 @@ struct ConnwrappersWorker for (auto &conn : cell->connections()) { - std::pair key(cell->type, conn.first); + std::pair key(cell->type, conn.first); if (!decls.count(key)) continue; diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index a2dd8051..bbc0ff44 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -111,7 +111,7 @@ struct ShowWorker return stringf("style=\"setlinewidth(3)\", label=\"<%d>\"", bits); } - const char *findColor(std::string member_name) + const char *findColor(RTLIL::IdString member_name) { for (auto &s : color_selections) if (s.second.selected_member(module->name, member_name)) { @@ -121,20 +121,22 @@ struct ShowWorker return ""; } - const char *findLabel(std::string member_name) + const char *findLabel(RTLIL::IdString member_name) { for (auto &s : label_selections) - if (s.second.selected_member(module->name, RTLIL::escape_id(member_name))) + if (s.second.selected_member(module->name, member_name)) return escape(s.first); return escape(member_name, true); } - const char *escape(std::string id, bool is_name = false) + const char *escape(RTLIL::IdString id, bool is_name = false) { - if (id.size() == 0) + std::string id_str = id.str(); + + if (id_str.size() == 0) return ""; - if (id[0] == '$' && is_name) { + if (id_str[0] == '$' && is_name) { if (enumerateIds) { if (autonames.count(id) == 0) { autonames[id] = autonames.size() + 1; @@ -142,17 +144,17 @@ struct ShowWorker } id = stringf("_%d_", autonames[id]); } else if (abbreviateIds) { - const char *p = id.c_str(); + const char *p = id_str.c_str(); const char *q = strrchr(p, '$'); - id = std::string(q); + id_str = std::string(q); } } - if (id[0] == '\\') - id = id.substr(1); + if (id_str[0] == '\\') + id_str = id_str.substr(1); std::string str; - for (char ch : id) { + for (char ch : id_str) { if (ch == '\\' || ch == '"') str += "\\"; str += ch; diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index 07c6150c..ca71f7d8 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -33,8 +33,8 @@ struct SpliceWorker bool sel_by_wire; bool sel_any_bit; bool no_outputs; - std::set ports; - std::set no_ports; + std::set ports; + std::set no_ports; CellTypes ct; SigMap sigmap; @@ -224,7 +224,7 @@ struct SpliceWorker for (auto &it : rework_wires) { - std::string orig_name = it.first->name; + RTLIL::IdString orig_name = it.first->name; module->rename(it.first, NEW_ID); RTLIL::Wire *new_port = module->addWire(orig_name, it.first); @@ -283,7 +283,7 @@ struct SplicePass : public Pass { bool sel_by_wire = false; bool sel_any_bit = false; bool no_outputs = false; - std::set ports, no_ports; + std::set ports, no_ports; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 6b1dbe13..a3daf239 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -28,7 +28,7 @@ struct SplitnetsWorker void append_wire(RTLIL::Module *module, RTLIL::Wire *wire, int offset, int width, std::string format) { - std::string new_wire_name = wire->name; + std::string new_wire_name = wire->name.str(); if (format.size() > 0) new_wire_name += format.substr(0, 1); diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 6025de15..5675dff5 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -26,7 +26,7 @@ static RTLIL::Module *module; static SigMap assign_map; -typedef std::pair sig2driver_entry_t; +typedef std::pair sig2driver_entry_t; static SigSet sig2driver, sig2user; static std::set muxtree_cells; static SigPool sig_at_port; diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index f6f9faa9..97ccf91e 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -62,7 +62,7 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st } else { kiss_name.assign(module->name); - kiss_name.append('-' + cell->name + ".kiss2"); + kiss_name.append('-' + cell->name.str() + ".kiss2"); } log("\n"); diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index cf2075fb..5e71c1f0 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -31,7 +31,7 @@ static RTLIL::Module *module; static SigMap assign_map; -typedef std::pair sig2driver_entry_t; +typedef std::pair sig2driver_entry_t; static SigSet sig2driver, sig2trigger; static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL::SigSpec &ctrl, std::map &states, RTLIL::Const *reset_state = NULL) @@ -277,7 +277,7 @@ static void extract_fsm(RTLIL::Wire *wire) fsm_cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity ? 1 : 0, 1); fsm_cell->setPort("\\CTRL_IN", ctrl_in); fsm_cell->setPort("\\CTRL_OUT", ctrl_out); - fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name); + fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str()); fsm_cell->attributes = wire->attributes; fsm_data.copy_to_cell(fsm_cell); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 67b57a94..28b4ad99 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -35,7 +35,7 @@ namespace { static void generate(RTLIL::Design *design, const std::vector &celltypes, const std::vector &portdecls) { - std::set found_celltypes; + std::set found_celltypes; for (auto i1 : design->modules_) for (auto i2 : i1.second->cells_) @@ -52,9 +52,9 @@ static void generate(RTLIL::Design *design, const std::vector &cell for (auto &celltype : found_celltypes) { - std::set portnames; - std::set parameters; - std::map portwidths; + std::set portnames; + std::set parameters; + std::map portwidths; log("Generate module for cell type %s:\n", celltype.c_str()); for (auto i1 : design->modules_) @@ -94,7 +94,7 @@ static void generate(RTLIL::Design *design, const std::vector &cell } while (portnames.size() > 0) { - std::string portname = *portnames.begin(); + RTLIL::IdString portname = *portnames.begin(); for (auto &decl : portdecls) if (decl.index == 0 && !fnmatch(decl.portname.c_str(), RTLIL::unescape_id(portname).c_str(), FNM_NOESCAPE)) { generate_port_decl_t d = decl; @@ -144,20 +144,20 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla RTLIL::Cell *cell = cell_it.second; if (cell->type.substr(0, 7) == "$array:") { - int pos_idx = cell->type.find_first_of(':'); - int pos_num = cell->type.find_first_of(':', pos_idx + 1); - int pos_type = cell->type.find_first_of(':', pos_num + 1); - int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str()); - int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str()); + int pos_idx = cell->type.str().find_first_of(':'); + int pos_num = cell->type.str().find_first_of(':', pos_idx + 1); + int pos_type = cell->type.str().find_first_of(':', pos_num + 1); + int idx = atoi(cell->type.str().substr(pos_idx + 1, pos_num).c_str()); + int num = atoi(cell->type.str().substr(pos_num + 1, pos_type).c_str()); array_cells[cell] = std::pair(idx, num); - cell->type = cell->type.substr(pos_type + 1); + cell->type = cell->type.str().substr(pos_type + 1); } if (design->modules_.count(cell->type) == 0) { - if (design->modules_.count("$abstract" + cell->type)) + if (design->modules_.count("$abstract" + cell->type.str())) { - cell->type = design->modules_.at("$abstract" + cell->type)->derive(design, cell->parameters); + cell->type = design->modules_.at("$abstract" + cell->type.str())->derive(design, cell->parameters); cell->parameters.clear(); did_something = true; continue; @@ -220,7 +220,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla for (auto &conn : cell->connections_) { int conn_size = conn.second.size(); - std::string portname = conn.first; + RTLIL::IdString portname = conn.first; if (portname.substr(0, 1) == "$") { int port_id = atoi(portname.substr(1).c_str()); for (auto &wire_it : mod->wires_) @@ -447,7 +447,7 @@ struct HierarchyPass : public Pass { bool did_something_once = false; while (did_something) { did_something = false; - std::vector modnames; + std::vector modnames; modnames.reserve(design->modules_.size()); for (auto &mod_it : design->modules_) modnames.push_back(mod_it.first); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 2a47002e..89f45e02 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -108,7 +108,7 @@ struct SubmodWorker design->add(new_mod); int port_counter = 1, auto_name_counter = 1; - std::set all_wire_names; + std::set all_wire_names; for (auto &it : wire_flags) { all_wire_names.insert(it.first->name); } @@ -134,7 +134,7 @@ struct SubmodWorker if (flags.is_int_driven && flags.is_ext_driven) new_wire_port_input = true, new_wire_port_output = true; - std::string new_wire_name = wire->name; + std::string new_wire_name = wire->name.str(); if (new_wire_port_input || new_wire_port_output) { while (new_wire_name[0] == '$') { std::string next_wire_name = stringf("\\n%d", auto_name_counter++); @@ -228,7 +228,7 @@ struct SubmodWorker if (submodules.count(submod_str) == 0) { submodules[submod_str].name = submod_str; - submodules[submod_str].full_name = module->name + "_" + submod_str; + submodules[submod_str].full_name = module->name.str() + "_" + submod_str; while (design->modules_.count(submodules[submod_str].full_name) != 0 || module->count_id(submodules[submod_str].full_name) != 0) submodules[submod_str].full_name += "_"; @@ -306,12 +306,12 @@ struct SubmodPass : public Pass { Pass::call(design, "opt_clean"); log_header("Continuing SUBMOD pass.\n"); - std::set handled_modules; + std::set handled_modules; bool did_something = true; while (did_something) { did_something = false; - std::vector queued_modules; + std::vector queued_modules; for (auto &mod_it : design->modules_) if (handled_modules.count(mod_it.first) == 0 && design->selected_whole_module(mod_it.first)) queued_modules.push_back(mod_it.first); diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 8887d195..471a7d53 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -62,7 +62,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - if ((cell->type == "$memwr" || cell->type == "$memrd") && cell->parameters["\\MEMID"].decode_string() == memory->name) + if ((cell->type == "$memwr" || cell->type == "$memrd") && memory->name == cell->parameters["\\MEMID"].decode_string()) memcells.push_back(cell); } @@ -70,7 +70,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) for (auto cell : memcells) { - if (cell->type == "$memwr" && cell->parameters["\\MEMID"].decode_string() == memory->name) + if (cell->type == "$memwr" && memory->name == cell->parameters["\\MEMID"].decode_string()) { wr_ports++; del_cells.push_back(cell); @@ -97,7 +97,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) sig_wr_en.append(en); } - if (cell->type == "$memrd" && cell->parameters["\\MEMID"].decode_string() == memory->name) + if (cell->type == "$memrd" && memory->name == cell->parameters["\\MEMID"].decode_string()) { rd_ports++; del_cells.push_back(cell); @@ -129,7 +129,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) sstr << "$mem$" << memory->name << "$" << (autoidx++); RTLIL::Cell *mem = module->addCell(sstr.str(), "$mem"); - mem->parameters["\\MEMID"] = RTLIL::Const(memory->name); + mem->parameters["\\MEMID"] = RTLIL::Const(memory->name.str()); mem->parameters["\\WIDTH"] = RTLIL::Const(memory->width); mem->parameters["\\OFFSET"] = RTLIL::Const(memory->start_offset); mem->parameters["\\SIZE"] = RTLIL::Const(memory->size); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index f1917b97..8dc66f2c 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -23,10 +23,10 @@ #include #include -static std::string genid(std::string name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "") +static std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "") { std::stringstream sstr; - sstr << "$memory" << name << token1; + sstr << "$memory" << name.str() << token1; if (i >= 0) sstr << "[" << i << "]"; diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index 68e9a969..5a4c4eac 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -31,7 +31,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at("\\MEMID").decode_string()); while (module->memories.count(mem_name) != 0) - mem_name += stringf("_%d", autoidx++); + mem_name = mem_name.str() + stringf("_%d", autoidx++); RTLIL::Memory *mem = new RTLIL::Memory; mem->name = mem_name; @@ -47,7 +47,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) for (int i = 0; i < num_rd_ports; i++) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$memrd"); - cell->parameters["\\MEMID"] = mem_name; + cell->parameters["\\MEMID"] = mem_name.str(); cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS"); cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH"); cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_ENABLE")).extract(i, 1).as_const(); @@ -61,7 +61,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) for (int i = 0; i < num_wr_ports; i++) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$memwr"); - cell->parameters["\\MEMID"] = mem_name; + cell->parameters["\\MEMID"] = mem_name.str(); cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS"); cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH"); cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_ENABLE")).extract(i, 1).as_const(); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 4182c6f5..c620531e 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -139,11 +139,12 @@ static bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool ®s, static bool check_public_name(RTLIL::IdString id) { - if (id[0] == '$') + const std::string &id_str = id.str(); + if (id_str[0] == '$') return false; - if (id.substr(0, 2) == "\\_" && (id[id.size()-1] == '_' || id.find("_[") != std::string::npos)) + if (id_str.substr(0, 2) == "\\_" && (id_str[id_str.size()-1] == '_' || id_str.find("_[") != std::string::npos)) return false; - if (id.find(".$") != std::string::npos) + if (id_str.find(".$") != std::string::npos) return false; return true; } diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 5dab5eca..a13bb09c 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -183,7 +183,7 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com log("\n"); } - cover_list("opt.opt_const.fine.group", "$not", "$pos", "$bu0", "$and", "$or", "$xor", "$xnor", cell->type); + cover_list("opt.opt_const.fine.group", "$not", "$pos", "$bu0", "$and", "$or", "$xor", "$xnor", cell->type.str()); module->remove(cell); OPT_DID_SOMETHING = true; @@ -288,7 +288,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a != RTLIL::State::Sm && RTLIL::SigSpec(new_a) != sig_a) { - cover_list("opt.opt_const.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type); + cover_list("opt.opt_const.fine.A", "$logic_not", "$logic_and", "$logic_or", "$reduce_or", "$reduce_bool", cell->type.str()); log("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); cell->setPort("\\A", sig_a = new_a); @@ -315,7 +315,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_b != RTLIL::State::Sm && RTLIL::SigSpec(new_b) != sig_b) { - cover_list("opt.opt_const.fine.B", "$logic_and", "$logic_or", cell->type); + cover_list("opt.opt_const.fine.B", "$logic_and", "$logic_or", cell->type.str()); log("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); cell->setPort("\\B", sig_b = new_b); @@ -361,7 +361,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (0) { found_the_x_bit: cover_list("opt.opt_const.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", - "$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); + "$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type.str()); if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); @@ -373,13 +373,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->getPort("\\Y").size() == 1 && invert_map.count(assign_map(cell->getPort("\\A"))) != 0) { - cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type); + cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type.str()); replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->getPort("\\A")))); goto next_cell; } if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->getPort("\\S"))) != 0) { - cover_list("opt.opt_const.invert.muxsel", "$_MUX_", "$mux", cell->type); + cover_list("opt.opt_const.invert.muxsel", "$_MUX_", "$mux", cell->type.str()); RTLIL::SigSpec tmp = cell->getPort("\\A"); cell->setPort("\\A", cell->getPort("\\B")); cell->setPort("\\B", tmp); @@ -497,7 +497,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo log_assert(SIZE(a) == SIZE(b)); for (int i = 0; i < SIZE(a); i++) { if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) { - cover_list("opt.opt_const.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type); + cover_list("opt.opt_const.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S0 : RTLIL::State::S1); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(assign_map, module, cell, "isneq", "\\Y", new_y); @@ -510,7 +510,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a.size() == 0) { - cover_list("opt.opt_const.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type); + cover_list("opt.opt_const.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); RTLIL::SigSpec new_y = RTLIL::SigSpec((cell->type == "$eq" || cell->type == "$eqx") ? RTLIL::State::S1 : RTLIL::State::S0); new_y.extend(cell->parameters["\\Y_WIDTH"].as_int(), false); replace_cell(assign_map, module, cell, "empty", "\\Y", new_y); @@ -518,7 +518,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (new_a.size() < a.size() || new_b.size() < b.size()) { - cover_list("opt.opt_const.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type); + cover_list("opt.opt_const.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type.str()); cell->setPort("\\A", new_a); cell->setPort("\\B", new_b); cell->parameters["\\A_WIDTH"] = new_a.size(); @@ -533,7 +533,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); if (a.is_fully_const()) { - cover_list("opt.opt_const.eqneq.swapconst", "$eq", "$ne", cell->type); + cover_list("opt.opt_const.eqneq.swapconst", "$eq", "$ne", cell->type.str()); RTLIL::SigSpec tmp = cell->getPort("\\A"); cell->setPort("\\A", cell->getPort("\\B")); cell->setPort("\\B", tmp); @@ -544,7 +544,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec input = b; ACTION_DO("\\Y", cell->getPort("\\A")); } else { - cover_list("opt.opt_const.eqneq.isnot", "$eq", "$ne", cell->type); + cover_list("opt.opt_const.eqneq.isnot", "$eq", "$ne", cell->type.str()); cell->type = "$not"; cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); @@ -603,9 +603,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (identity_wrt_a || identity_wrt_b) { if (identity_wrt_a) - cover_list("opt.opt_const.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type); + cover_list("opt.opt_const.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); if (identity_wrt_b) - cover_list("opt.opt_const.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type); + cover_list("opt.opt_const.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); log("Replacing %s cell `%s' in module `%s' with identity for port %c.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); @@ -630,14 +630,14 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(0, 1) && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { - cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type); + cover_list("opt.opt_const.mux_bool", "$mux", "$_MUX_", cell->type.str()); replace_cell(assign_map, module, cell, "mux_bool", "\\Y", cell->getPort("\\S")); goto next_cell; } if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(1, 1) && cell->getPort("\\B") == RTLIL::SigSpec(0, 1)) { - cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type); + cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type.str()); cell->setPort("\\A", cell->getPort("\\S")); cell->unsetPort("\\B"); cell->unsetPort("\\S"); @@ -655,7 +655,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(0, 1)) { - cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type); + cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type.str()); cell->setPort("\\A", cell->getPort("\\S")); cell->unsetPort("\\S"); if (cell->type == "$mux") { @@ -674,7 +674,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { - cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type); + cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type.str()); cell->setPort("\\B", cell->getPort("\\S")); cell->unsetPort("\\S"); if (cell->type == "$mux") { @@ -697,7 +697,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo int width = cell->getPort("\\A").size(); if ((cell->getPort("\\A").is_fully_undef() && cell->getPort("\\B").is_fully_undef()) || cell->getPort("\\S").is_fully_undef()) { - cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type); + cover_list("opt.opt_const.mux_undef", "$mux", "$pmux", cell->type.str()); replace_cell(assign_map, module, cell, "mux_undef", "\\Y", cell->getPort("\\A")); goto next_cell; } @@ -716,17 +716,17 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo new_s = new_s.extract(0, new_s.size()-1); } if (new_s.size() == 0) { - cover_list("opt.opt_const.mux_empty", "$mux", "$pmux", cell->type); + cover_list("opt.opt_const.mux_empty", "$mux", "$pmux", cell->type.str()); replace_cell(assign_map, module, cell, "mux_empty", "\\Y", new_a); goto next_cell; } if (new_a == RTLIL::SigSpec(RTLIL::State::S0) && new_b == RTLIL::SigSpec(RTLIL::State::S1)) { - cover_list("opt.opt_const.mux_sel01", "$mux", "$pmux", cell->type); + cover_list("opt.opt_const.mux_sel01", "$mux", "$pmux", cell->type.str()); replace_cell(assign_map, module, cell, "mux_sel01", "\\Y", new_s); goto next_cell; } if (cell->getPort("\\S").size() != new_s.size()) { - cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type); + cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type.str()); cell->setPort("\\A", new_a); cell->setPort("\\B", new_b); cell->setPort("\\S", new_s); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index c1e33caf..bbf94d3b 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -178,7 +178,7 @@ struct OptRmdffPass : public Pass { dff_init_map.add(it.second, it.second->attributes.at("\\init")); mux_drivers.clear(); - std::vector dff_list; + std::vector dff_list; for (auto &it : mod_it.second->cells_) { if (it.second->type == "$mux" || it.second->type == "$pmux") { if (it.second->getPort("\\A").size() == it.second->getPort("\\B").size()) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 3532b124..eb970329 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -60,10 +60,10 @@ struct OptShareWorker if (cell_hash_cache.count(cell) > 0) return cell_hash_cache[cell]; - std::string hash_string = cell->type + "\n"; + std::string hash_string = cell->type.str() + "\n"; for (auto &it : cell->parameters) - hash_string += "P " + it.first + "=" + it.second.as_string() + "\n"; + hash_string += "P " + it.first.str() + "=" + it.second.as_string() + "\n"; const std::map *conn = &cell->connections(); std::map alt_conn; @@ -95,10 +95,10 @@ struct OptShareWorker continue; RTLIL::SigSpec sig = it.second; assign_map.apply(sig); - hash_string += "C " + it.first + "="; + hash_string += "C " + it.first.str() + "="; for (auto &chunk : sig.chunks()) { if (chunk.wire) - hash_string += "{" + chunk.wire->name + " " + + hash_string += "{" + chunk.wire->name.str() + " " + int_to_hash_string(chunk.offset) + " " + int_to_hash_string(chunk.width) + "}"; else diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index e4c52663..13be0ddb 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -150,7 +150,7 @@ struct ProcCleanPass : public Pass { extra_args(args, 1, design); for (auto mod : design->modules()) { - std::vector delme; + std::vector delme; if (!design->selected(mod)) continue; for (auto &proc_it : mod->processes) { diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index 8a2dd929..f07ad943 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -471,7 +471,7 @@ struct EvalPass : public Pass { if (shows.size() == 0) { for (auto &it : module->wires_) if (it.second->port_output) - shows.push_back(it.second->name); + shows.push_back(it.second->name.str()); } if (tables.empty()) diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 25b9e1d1..affd685e 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -27,7 +27,7 @@ struct dff_map_info_t { RTLIL::SigSpec sig_d, sig_clk, sig_arst; bool clk_polarity, arst_polarity; RTLIL::Const arst_value; - std::vector cells; + std::vector cells; }; struct dff_map_bit_info_t { @@ -37,7 +37,7 @@ struct dff_map_bit_info_t { RTLIL::Cell *cell; }; -static bool consider_wire(RTLIL::Wire *wire, std::map &dff_dq_map) +static bool consider_wire(RTLIL::Wire *wire, std::map &dff_dq_map) { if (wire->name[0] == '$' || dff_dq_map.count(wire->name)) return false; @@ -46,7 +46,7 @@ static bool consider_wire(RTLIL::Wire *wire, std::map &dff_cells, RTLIL::Cell *cell) +static bool consider_cell(RTLIL::Design *design, std::set &dff_cells, RTLIL::Cell *cell) { if (cell->name[0] == '$' || dff_cells.count(cell->name)) return false; @@ -73,7 +73,7 @@ static bool compare_cells(RTLIL::Cell *cell1, RTLIL::Cell *cell2) return true; } -static void find_dff_wires(std::set &dff_wires, RTLIL::Module *module) +static void find_dff_wires(std::set &dff_wires, RTLIL::Module *module) { CellTypes ct; ct.setup_internals_mem(); @@ -93,7 +93,7 @@ static void find_dff_wires(std::set &dff_wires, RTLIL::Module *modu } } -static void create_dff_dq_map(std::map &map, RTLIL::Design *design, RTLIL::Module *module) +static void create_dff_dq_map(std::map &map, RTLIL::Design *design, RTLIL::Module *module) { std::map bit_info; SigMap sigmap(module); @@ -160,7 +160,7 @@ static void create_dff_dq_map(std::map &map, RTLIL: } } - std::map empty_dq_map; + std::map empty_dq_map; for (auto &it : module->wires_) { if (!consider_wire(it.second, empty_dq_map)) @@ -208,7 +208,7 @@ static void create_dff_dq_map(std::map &map, RTLIL: } } -static RTLIL::Wire *add_new_wire(RTLIL::Module *module, std::string name, int width = 1) +static RTLIL::Wire *add_new_wire(RTLIL::Module *module, RTLIL::IdString name, int width = 1) { if (module->count_id(name)) log_error("Attempting to create wire %s, but a wire of this name exists already! Hint: Try another value for -sep.\n", log_id(name)); @@ -294,13 +294,13 @@ struct ExposePass : public Pass { CellTypes ct(design); - std::map> dff_dq_maps; - std::map> dff_cells; + std::map> dff_dq_maps; + std::map> dff_cells; if (flag_evert_dff) { RTLIL::Module *first_module = NULL; - std::set shared_dff_wires; + std::set shared_dff_wires; for (auto &mod_it : design->modules_) { @@ -317,7 +317,7 @@ struct ExposePass : public Pass { shared_dff_wires.insert(it.first); first_module = mod_it.second; } else { - std::set new_shared_dff_wires; + std::set new_shared_dff_wires; for (auto &it : shared_dff_wires) { if (!dff_dq_maps[mod_it.second].count(it)) continue; @@ -332,7 +332,7 @@ struct ExposePass : public Pass { if (flag_shared) for (auto &map_it : dff_dq_maps) { - std::map new_map; + std::map new_map; for (auto &it : map_it.second) if (shared_dff_wires.count(it.first)) new_map[it.first] = it.second; @@ -345,8 +345,8 @@ struct ExposePass : public Pass { dff_cells[it1.first].insert(it3); } - std::set shared_wires, shared_cells; - std::set used_names; + std::set shared_wires, shared_cells; + std::set used_names; if (flag_shared) { @@ -359,7 +359,7 @@ struct ExposePass : public Pass { if (!design->selected(module)) continue; - std::set dff_wires; + std::set dff_wires; if (flag_dff) find_dff_wires(dff_wires, module); @@ -379,7 +379,7 @@ struct ExposePass : public Pass { } else { - std::vector delete_shared_wires, delete_shared_cells; + std::vector delete_shared_wires, delete_shared_cells; for (auto &it : shared_wires) { @@ -441,7 +441,7 @@ struct ExposePass : public Pass { if (!design->selected(module)) continue; - std::set dff_wires; + std::set dff_wires; if (flag_dff && !flag_shared) find_dff_wires(dff_wires, module); @@ -467,7 +467,7 @@ struct ExposePass : public Pass { } if (flag_cut) { - RTLIL::Wire *in_wire = add_new_wire(module, it.second->name + sep + "i", it.second->width); + RTLIL::Wire *in_wire = add_new_wire(module, it.second->name.str() + sep + "i", it.second->width); in_wire->port_input = true; out_to_in_map.add(sigmap(it.second), in_wire); } @@ -511,7 +511,7 @@ struct ExposePass : public Pass { cell->setPort("\\Q", cell_q_bits); } - RTLIL::Wire *wire_q = add_new_wire(module, wire->name + sep + "q", wire->width); + RTLIL::Wire *wire_q = add_new_wire(module, wire->name.str() + sep + "q", wire->width); wire_q->port_input = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_q->name)); @@ -525,12 +525,12 @@ struct ExposePass : public Pass { } module->connect(connect_q); - RTLIL::Wire *wire_d = add_new_wire(module, wire->name + sep + "d", wire->width); + RTLIL::Wire *wire_d = add_new_wire(module, wire->name.str() + sep + "d", wire->width); wire_d->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_d->name)); module->connect(RTLIL::SigSig(wire_d, info.sig_d)); - RTLIL::Wire *wire_c = add_new_wire(module, wire->name + sep + "c"); + RTLIL::Wire *wire_c = add_new_wire(module, wire->name.str() + sep + "c"); wire_c->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_c->name)); if (info.clk_polarity) { @@ -546,7 +546,7 @@ struct ExposePass : public Pass { if (info.sig_arst != RTLIL::State::Sm) { - RTLIL::Wire *wire_r = add_new_wire(module, wire->name + sep + "r"); + RTLIL::Wire *wire_r = add_new_wire(module, wire->name.str() + sep + "r"); wire_r->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_r->name)); if (info.arst_polarity) { @@ -560,7 +560,7 @@ struct ExposePass : public Pass { c->setPort("\\Y", wire_r); } - RTLIL::Wire *wire_v = add_new_wire(module, wire->name + sep + "v", wire->width); + RTLIL::Wire *wire_v = add_new_wire(module, wire->name.str() + sep + "v", wire->width); wire_v->port_output = true; log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire_v->name)); module->connect(RTLIL::SigSig(wire_v, info.arst_value)); @@ -593,7 +593,7 @@ struct ExposePass : public Pass { if (!p->port_input && !p->port_output) continue; - RTLIL::Wire *w = add_new_wire(module, cell->name + sep + RTLIL::unescape_id(p->name), p->width); + RTLIL::Wire *w = add_new_wire(module, cell->name.str() + sep + RTLIL::unescape_id(p->name), p->width); if (p->port_input) w->port_output = true; if (p->port_output) @@ -615,7 +615,7 @@ struct ExposePass : public Pass { { for (auto &it : cell->connections()) { - RTLIL::Wire *w = add_new_wire(module, cell->name + sep + RTLIL::unescape_id(it.first), it.second.size()); + RTLIL::Wire *w = add_new_wire(module, cell->name.str() + sep + RTLIL::unescape_id(it.first), it.second.size()); if (ct.cell_input(cell->type, it.first)) w->port_output = true; if (ct.cell_output(cell->type, it.first)) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 430628e4..fd3d405a 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -1160,19 +1160,19 @@ struct SatPass : public Pass { if (set_def_inputs) { for (auto &it : module->wires_) if (it.second->port_input) - sets_def.push_back(it.second->name); + sets_def.push_back(it.second->name.str()); } if (show_inputs) { for (auto &it : module->wires_) if (it.second->port_input) - shows.push_back(it.second->name); + shows.push_back(it.second->name.str()); } if (show_outputs) { for (auto &it : module->wires_) if (it.second->port_output) - shows.push_back(it.second->name); + shows.push_back(it.second->name.str()); } if (tempinduct) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index ea7a9f63..4484d677 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -29,13 +29,13 @@ struct ShareWorkerConfig bool opt_force; bool opt_aggressive; bool opt_fast; - std::set generic_uni_ops, generic_bin_ops, generic_cbin_ops; + std::set generic_uni_ops, generic_bin_ops, generic_cbin_ops; }; struct ShareWorker { ShareWorkerConfig config; - std::set generic_ops; + std::set generic_ops; RTLIL::Design *design; RTLIL::Module *module; diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 7712d18b..16518b7d 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -29,7 +29,7 @@ struct cell_mapping { std::string cell_name; std::map ports; }; -static std::map cell_mappings; +static std::map cell_mappings; static void logmap(std::string dff) { @@ -319,7 +319,7 @@ static bool expand_cellmap(std::string pattern, std::string inv) bool return_status = false; for (auto &it : cell_mappings) { - std::string from = it.first, to = it.first; + std::string from = it.first.str(), to = it.first.str(); if (from.size() != pattern.size()) continue; for (size_t i = 0; i < from.size(); i++) { diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 53bc00da..6ebac265 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -34,7 +34,7 @@ namespace { public: bool ignore_parameters; - std::set> ignored_parameters; + std::set> ignored_parameters; std::set cell_attr, wire_attr; SubCircuitSolver() : ignore_parameters(false) @@ -106,10 +106,10 @@ namespace if (!ignore_parameters) { std::map needle_param, haystack_param; for (auto &it : needleCell->parameters) - if (!ignored_parameters.count(std::pair(needleCell->type, it.first))) + if (!ignored_parameters.count(std::pair(needleCell->type, it.first))) needle_param[it.first] = unified_param(needleCell->type, it.first, it.second); for (auto &it : haystackCell->parameters) - if (!ignored_parameters.count(std::pair(haystackCell->type, it.first))) + if (!ignored_parameters.count(std::pair(haystackCell->type, it.first))) haystack_param[it.first] = unified_param(haystackCell->type, it.first, it.second); if (needle_param != haystack_param) return false; @@ -127,7 +127,7 @@ namespace for (auto &conn : needleCell->connections()) { RTLIL::SigSpec needleSig = conn.second; - RTLIL::SigSpec haystackSig = haystackCell->getPort(portMapping.at(conn.first)); + RTLIL::SigSpec haystackSig = haystackCell->getPort(portMapping.at(conn.first.str())); for (int i = 0; i < std::min(needleSig.size(), haystackSig.size()); i++) { RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire; @@ -201,14 +201,14 @@ namespace if (sel && !sel->selected(mod, cell)) continue; - std::string type = cell->type; + std::string type = cell->type.str(); if (sel == NULL && type.substr(0, 2) == "\\$") type = type.substr(1); - graph.createNode(cell->name, type, (void*)cell); + graph.createNode(cell->name.str(), type, (void*)cell); for (auto &conn : cell->connections()) { - graph.createPort(cell->name, conn.first, conn.second.size()); + graph.createPort(cell->name.str(), conn.first.str(), conn.second.size()); if (split && split->count(std::pair(cell->type, conn.first)) > 0) continue; @@ -226,9 +226,9 @@ namespace if (bit == RTLIL::State::S0) node = "$const$0"; if (bit == RTLIL::State::S1) node = "$const$1"; if (bit == RTLIL::State::Sz) node = "$const$z"; - graph.createConnection(cell->name, conn.first, i, node, "\\Y", 0); + graph.createConnection(cell->name.str(), conn.first.str(), i, node, "\\Y", 0); } else - graph.createConstant(cell->name, conn.first, i, int(bit.data)); + graph.createConstant(cell->name.str(), conn.first.str(), i, int(bit.data)); continue; } @@ -246,7 +246,7 @@ namespace } bit_ref_t &bit_ref = sig_bit_ref[bit]; - graph.createConnection(bit_ref.cell, bit_ref.port, bit_ref.bit, cell->name, conn.first, i); + graph.createConnection(bit_ref.cell, bit_ref.port, bit_ref.bit, cell->name.str(), conn.first.str(), i); } } } @@ -293,7 +293,7 @@ namespace RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit::Solver::Result &match) { SigMap sigmap(needle); - SigSet> sig2port; + SigSet> sig2port; // create new cell RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), autoidx++), needle->name); @@ -303,7 +303,7 @@ namespace RTLIL::Wire *wire = it.second; if (wire->port_id > 0) { for (int i = 0; i < wire->width; i++) - sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair(wire->name, i)); + sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair(wire->name, i)); cell->setPort(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width)); } } @@ -320,10 +320,10 @@ namespace for (auto &conn : needle_cell->connections()) { RTLIL::SigSpec sig = sigmap(conn.second); - if (mapping.portMapping.count(conn.first) > 0 && sig2port.has(sigmap(sig))) { + if (mapping.portMapping.count(conn.first.str()) > 0 && sig2port.has(sigmap(sig))) { for (int i = 0; i < sig.size(); i++) for (auto &port : sig2port.find(sig[i])) { - RTLIL::SigSpec bitsig = haystack_cell->getPort(mapping.portMapping[conn.first]).extract(i, 1); + RTLIL::SigSpec bitsig = haystack_cell->getPort(mapping.portMapping[conn.first.str()]).extract(i, 1); RTLIL::SigSpec new_sig = cell->getPort(port.first); new_sig.replace(port.second, bitsig); cell->setPort(port.first, new_sig); @@ -561,7 +561,7 @@ struct ExtractPass : public Pass { continue; } if (args[argidx] == "-ignore_param" && argidx+2 < args.size()) { - solver.ignored_parameters.insert(std::pair(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2]))); + solver.ignored_parameters.insert(std::pair(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2]))); argidx += 2; continue; } diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index f1f334f6..960578b0 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -24,7 +24,7 @@ #include #include -extern void simplemap_get_mappers(std::map &mappers); +extern void simplemap_get_mappers(std::map &mappers); static void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) { @@ -382,7 +382,7 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell) } } -void simplemap_get_mappers(std::map &mappers) +void simplemap_get_mappers(std::map &mappers) { mappers["$not"] = simplemap_not; mappers["$pos"] = simplemap_pos; @@ -431,7 +431,7 @@ struct SimplemapPass : public Pass { log_header("Executing SIMPLEMAP pass (map simple cells to gate primitives).\n"); extra_args(args, 1, design); - std::map mappers; + std::map mappers; simplemap_get_mappers(mappers); for (auto mod : design->modules()) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 1f812e52..2bcd3003 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -29,7 +29,7 @@ #include "passes/techmap/techmap.inc" // see simplemap.cc -extern void simplemap_get_mappers(std::map &mappers); +extern void simplemap_get_mappers(std::map &mappers); static void apply_prefix(std::string prefix, std::string &id) { @@ -44,7 +44,7 @@ static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module std::vector chunks = sig; for (auto &chunk : chunks) if (chunk.wire != NULL) { - std::string wire_name = chunk.wire->name; + std::string wire_name = chunk.wire->name.str(); apply_prefix(prefix, wire_name); log_assert(module->wires_.count(wire_name) > 0); chunk.wire = module->wires_[wire_name]; @@ -54,7 +54,7 @@ static void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module struct TechmapWorker { - std::map simplemap_mappers; + std::map simplemap_mappers; std::map>, RTLIL::Module*> techmap_cache; std::map techmap_do_cache; std::set module_queue; @@ -80,7 +80,7 @@ struct TechmapWorker std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose) { std::string constmap_info; - std::map> connbits_map; + std::map> connbits_map; for (auto conn : cell->connections()) for (int i = 0; i < SIZE(conn.second); i++) { @@ -96,7 +96,7 @@ struct TechmapWorker constmap_info += stringf("|%s %d %s %d", log_id(conn.first), i, log_id(connbits_map.at(bit).first), connbits_map.at(bit).second); } else - connbits_map[bit] = std::pair(conn.first, i);stringf("%s %d", log_id(conn.first), i, bit.data); + connbits_map[bit] = std::pair(conn.first, i);stringf("%s %d", log_id(conn.first), i, bit.data); } return stringf("$paramod$constmap:%s%s", sha1(constmap_info).c_str(), tpl->name.c_str()); @@ -156,7 +156,7 @@ struct TechmapWorker for (auto &it : tpl->cells_) if (it.first == "\\_TECHMAP_REPLACE_") { orig_cell_name = cell->name; - module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name); + module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str()); break; } @@ -165,8 +165,8 @@ struct TechmapWorker for (auto &it : tpl->wires_) { if (it.second->port_id > 0) positional_ports[stringf("$%d", it.second->port_id)] = it.first; - std::string w_name = it.second->name; - apply_prefix(cell->name, w_name); + std::string w_name = it.second->name.str(); + apply_prefix(cell->name.str(), w_name); RTLIL::Wire *w = module->addWire(w_name, it.second); w->port_input = false; w->port_output = false; @@ -192,11 +192,11 @@ struct TechmapWorker if (w->port_output) { c.first = it.second; c.second = RTLIL::SigSpec(w); - apply_prefix(cell->name, c.second, module); + apply_prefix(cell->name.str(), c.second, module); } else { c.first = RTLIL::SigSpec(w); c.second = it.second; - apply_prefix(cell->name, c.first, module); + apply_prefix(cell->name.str(), c.first, module); } if (c.second.size() > c.first.size()) c.second.remove(c.first.size(), c.second.size() - c.first.size()); @@ -219,12 +219,12 @@ struct TechmapWorker for (auto &it : tpl->cells_) { - RTLIL::IdString c_name = it.second->name; + std::string c_name = it.second->name.str(); if (!flatten_mode && c_name == "\\_TECHMAP_REPLACE_") c_name = orig_cell_name; else - apply_prefix(cell->name, c_name); + apply_prefix(cell->name.str(), c_name); RTLIL::Cell *c = module->addCell(c_name, it.second); design->select(module, c); @@ -233,15 +233,15 @@ struct TechmapWorker c->type = c->type.substr(1); for (auto &it2 : c->connections_) { - apply_prefix(cell->name, it2.second, module); + apply_prefix(cell->name.str(), it2.second, module); port_signal_map.apply(it2.second); } } for (auto &it : tpl->connections()) { RTLIL::SigSig c = it; - apply_prefix(cell->name, c.first, module); - apply_prefix(cell->name, c.second, module); + apply_prefix(cell->name.str(), c.first, module); + apply_prefix(cell->name.str(), c.second, module); port_signal_map.apply(c.first); port_signal_map.apply(c.second); module->connect(c); @@ -271,7 +271,7 @@ struct TechmapWorker continue; if (celltypeMap.count(cell->type) == 0) { - if (assert_mode && cell->type.back() != '_') + if (assert_mode && cell->type.str().back() != '_') log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell->type)); continue; } @@ -313,7 +313,7 @@ struct TechmapWorker for (auto &tpl_name : celltypeMap.at(cell->type)) { - std::string derived_name = tpl_name; + RTLIL::IdString derived_name = tpl_name; RTLIL::Module *tpl = map->modules_[tpl_name]; std::map parameters = cell->parameters; @@ -499,7 +499,7 @@ struct TechmapWorker if (!wire->port_input || wire->port_output) continue; - std::string port_name = wire->name; + RTLIL::IdString port_name = wire->name; tpl->rename(wire, NEW_ID); RTLIL::Wire *new_wire = tpl->addWire(port_name, wire); diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index 844bcbc9..d2600227 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -109,8 +109,8 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) RTLIL::Wire *wire = it2->second; if (wire->port_output) { count_ports++; - signal_out[idy("sig", mod->name, wire->name)] = wire->width; - fprintf(f, "wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name, wire->name).c_str()); + signal_out[idy("sig", mod->name.str(), wire->name.str())] = wire->width; + fprintf(f, "wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); } else if (wire->port_input) { count_ports++; bool is_clksignal = wire->get_bool_attribute("\\gentb_clock"); @@ -124,25 +124,25 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) is_clksignal = true; } if (is_clksignal && wire->attributes.count("\\gentb_constant") == 0) { - signal_clk[idy("sig", mod->name, wire->name)] = wire->width; + signal_clk[idy("sig", mod->name.str(), wire->name.str())] = wire->width; } else { - signal_in[idy("sig", mod->name, wire->name)] = wire->width; + signal_in[idy("sig", mod->name.str(), wire->name.str())] = wire->width; if (wire->attributes.count("\\gentb_constant") != 0) - signal_const[idy("sig", mod->name, wire->name)] = wire->attributes["\\gentb_constant"].as_string(); + signal_const[idy("sig", mod->name.str(), wire->name.str())] = wire->attributes["\\gentb_constant"].as_string(); } - fprintf(f, "reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name, wire->name).c_str()); + fprintf(f, "reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); } } - fprintf(f, "%s %s(\n", id(mod->name).c_str(), idy("uut", mod->name).c_str()); + fprintf(f, "%s %s(\n", id(mod->name.str()).c_str(), idy("uut", mod->name.str()).c_str()); for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); it2++) { RTLIL::Wire *wire = it2->second; if (wire->port_output || wire->port_input) - fprintf(f, "\t.%s(%s)%s\n", id(wire->name).c_str(), - idy("sig", mod->name, wire->name).c_str(), --count_ports ? "," : ""); + fprintf(f, "\t.%s(%s)%s\n", id(wire->name.str()).c_str(), + idy("sig", mod->name.str(), wire->name.str()).c_str(), --count_ports ? "," : ""); } fprintf(f, ");\n\n"); - fprintf(f, "task %s;\n", idy(mod->name, "reset").c_str()); + fprintf(f, "task %s;\n", idy(mod->name.str(), "reset").c_str()); fprintf(f, "begin\n"); int delay_counter = 0; for (auto it = signal_in.begin(); it != signal_in.end(); it++) @@ -169,7 +169,7 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) fprintf(f, "end\n"); fprintf(f, "endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name, "update_data").c_str()); + fprintf(f, "task %s;\n", idy(mod->name.str(), "update_data").c_str()); fprintf(f, "begin\n"); delay_counter = 0; for (auto it = signal_in.begin(); it != signal_in.end(); it++) { @@ -181,7 +181,7 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) fprintf(f, "end\n"); fprintf(f, "endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name, "update_clock").c_str()); + fprintf(f, "task %s;\n", idy(mod->name.str(), "update_clock").c_str()); fprintf(f, "begin\n"); if (signal_clk.size()) { fprintf(f, "\txorshift128;\n"); @@ -203,7 +203,7 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) std::vector header1; std::string header2 = ""; - fprintf(f, "task %s;\n", idy(mod->name, "print_status").c_str()); + fprintf(f, "task %s;\n", idy(mod->name.str(), "print_status").c_str()); fprintf(f, "begin\n"); fprintf(f, "\t$display(\"#OUT# %%b %%b %%b %%t %%d\", {"); if (signal_in.size()) @@ -265,7 +265,7 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) fprintf(f, "end\n"); fprintf(f, "endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name, "print_header").c_str()); + fprintf(f, "task %s;\n", idy(mod->name.str(), "print_header").c_str()); fprintf(f, "begin\n"); fprintf(f, "\t$display(\"#OUT#\");\n"); for (auto &hdr : header1) @@ -275,15 +275,15 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) fprintf(f, "end\n"); fprintf(f, "endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name, "test").c_str()); + fprintf(f, "task %s;\n", idy(mod->name.str(), "test").c_str()); fprintf(f, "begin\n"); - fprintf(f, "\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name).c_str()); - fprintf(f, "\t%s;\n", idy(mod->name, "reset").c_str()); + fprintf(f, "\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name.str()).c_str()); + fprintf(f, "\t%s;\n", idy(mod->name.str(), "reset").c_str()); fprintf(f, "\tfor (i=0; i<%d; i=i+1) begin\n", num_iter); - fprintf(f, "\t\tif (i %% 20 == 0) %s;\n", idy(mod->name, "print_header").c_str()); - fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "update_data").c_str()); - fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "update_clock").c_str()); - fprintf(f, "\t\t#100; %s;\n", idy(mod->name, "print_status").c_str()); + fprintf(f, "\t\tif (i %% 20 == 0) %s;\n", idy(mod->name.str(), "print_header").c_str()); + fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "update_data").c_str()); + fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "update_clock").c_str()); + fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "print_status").c_str()); fprintf(f, "\tend\n"); fprintf(f, "end\n"); fprintf(f, "endtask\n\n"); @@ -294,7 +294,7 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) fprintf(f, "\t// $dumpvars(0, testbench);\n"); for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) if (!it->second->get_bool_attribute("\\gentb_skip")) - fprintf(f, "\t%s;\n", idy(it->first, "test").c_str()); + fprintf(f, "\t%s;\n", idy(it->first.str(), "test").c_str()); fprintf(f, "\t$finish;\n"); fprintf(f, "end\n\n"); From 97ad0623dfd772e8bea0728b439a8cd1f7493b7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 13:34:07 +0200 Subject: [PATCH 522/750] Fixed memory corruption related to id2cstr() --- kernel/rtlil.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 70e01b72..daf888b7 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -121,7 +121,7 @@ namespace RTLIL return str; } - static inline const char *id2cstr(std::string str) { + static inline const char *id2cstr(const std::string &str) { if (str.size() > 1 && str[0] == '\\' && str[1] != '$') return str.c_str() + 1; return str.c_str(); @@ -131,7 +131,7 @@ namespace RTLIL return unescape_id(str.str()); } - static inline const char *id2cstr(RTLIL::IdString str) { + static inline const char *id2cstr(const RTLIL::IdString &str) { return id2cstr(str.str()); } From 60f3dc99237afc051560d18f38625337dc80ac80 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:11:35 +0200 Subject: [PATCH 523/750] Implemented new reference counting RTLIL::IdString --- kernel/rtlil.cc | 8 +++- kernel/rtlil.h | 97 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 15 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index af652a9d..80f63ce7 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -26,6 +26,11 @@ YOSYS_NAMESPACE_BEGIN +std::vector RTLIL::IdString::global_refcount_storage_; +std::vector RTLIL::IdString::global_id_storage_; +std::map RTLIL::IdString::global_id_index_; +std::vector RTLIL::IdString::global_free_idx_list_; + RTLIL::Const::Const() { flags = RTLIL::CONST_FLAG_NONE; @@ -1998,8 +2003,7 @@ void RTLIL::SigSpec::hash() const for (auto &v : c.data.bits) DJB2(that->hash_, v); } else { - for (auto &v : c.wire->name.str()) - DJB2(that->hash_, v); + DJB2(that->hash_, c.wire->name.index_); DJB2(that->hash_, c.offset); DJB2(that->hash_, c.width); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index daf888b7..d95cf11f 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -74,30 +74,101 @@ namespace RTLIL struct IdString { - private: - std::string str_; - - public: - IdString() : str_() { } - IdString(const char *str) : str_(str) { } - IdString(const IdString &str) : str_(str.str_) { } - IdString(const std::string &str) : str_(str) { } + // the global string cache - void operator=(const char *rhs) { str_ = rhs; } - void operator=(const IdString &rhs) { str_ = rhs.str_; } - void operator=(const std::string &rhs) { str_ = rhs; } + static std::vector global_refcount_storage_; + static std::vector global_id_storage_; + static std::map global_id_index_; + static std::vector global_free_idx_list_; - const std::string& str() const { return str_; } + static inline int get_reference(int idx) + { + global_refcount_storage_.at(idx)++; + return idx; + } + + static inline int get_reference(const std::string &str) + { + if (!str.empty()) { + log_assert(str.size() >= 2); + log_assert(str[0] == '$' || str[0] == '\\'); + } + + auto it = global_id_index_.find(str); + if (it != global_id_index_.end()) { + global_refcount_storage_.at(it->second)++; + return it->second; + } + + if (global_free_idx_list_.empty()) { + log_assert(global_id_storage_.size() < 0x40000000); + global_free_idx_list_.push_back(global_id_storage_.size()); + global_id_storage_.push_back(std::string()); + global_refcount_storage_.push_back(0); + } + + int idx = global_free_idx_list_.back(); + global_free_idx_list_.pop_back(); + global_id_storage_.at(idx) = str; + global_id_index_[global_id_storage_.at(idx)] = idx; + global_refcount_storage_.at(idx)++; + return idx; + } + + static inline void put_reference(int idx) + { + if (--global_refcount_storage_.at(idx) != 0) + return; + + global_id_index_.erase(global_id_storage_.at(idx)); + global_id_storage_.at(idx).clear(); + global_free_idx_list_.push_back(idx); + } + + // The actual IdString objects just is a single int + + int index_; + + IdString() : index_(get_reference("")) { } + IdString(const char *str) : index_(get_reference(str)) { } + IdString(const IdString &str) : index_(get_reference(str.index_)) { } + IdString(const std::string &str) : index_(get_reference(str)) { } + ~IdString() { put_reference(index_); } + + void operator=(const IdString &rhs) { + put_reference(index_); + index_ = get_reference(rhs.index_); + } + + void operator=(const char *rhs) { + IdString id(rhs); + *this = id; + } + + void operator=(const std::string &rhs) { + IdString id(rhs); + *this = id; + } + + const std::string& str() const { + return global_id_storage_.at(index_); + } + + bool operator<(const IdString &rhs) const { + return index_ < rhs.index_; + } // The methods below are just convinience functions for better compatibility // with std::string. Except clear() they all just deligate to std::string. operator const char*() const { return str().c_str(); } - bool operator<(const IdString &rhs) const { return str() < rhs.str(); } bool operator==(const IdString &rhs) const { return str() == rhs.str(); } bool operator!=(const IdString &rhs) const { return str() != rhs.str(); } + bool operator==(const std::string &rhs) const { return str() == rhs; } + bool operator!=(const std::string &rhs) const { return str() != rhs; } + bool operator==(const char *rhs) const { return str() == rhs; } bool operator!=(const char *rhs) const { return str() != rhs; } From 8fd1c269ac7322f21408c1f99e7e4c275789c056 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:12:16 +0200 Subject: [PATCH 524/750] Fixed a performance bug in opt_reduce --- passes/opt/opt_reduce.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index f947e972..5f3c4d29 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -368,8 +368,12 @@ struct OptReducePass : public Pass { for (auto &mod_it : design->modules_) { if (!design->selected(mod_it.second)) continue; - OptReduceWorker worker(design, mod_it.second, do_fine); - total_count += worker.total_count; + do { + OptReduceWorker worker(design, mod_it.second, do_fine); + total_count += worker.total_count; + if (worker.total_count == 0) + break; + } while (1); } log("Performed a total of %d changes.\n", total_count); From e590ffc84dac1cb1ea833c5e7a71e958b63f7352 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:44:10 +0200 Subject: [PATCH 525/750] Improvements in new RTLIL::IdString implementation --- kernel/log.cc | 10 +++---- kernel/log.h | 2 -- kernel/rtlil.cc | 4 +-- kernel/rtlil.h | 78 ++++++++++++++++++++++++++++++++++--------------- kernel/yosys.h | 4 +++ 5 files changed, 65 insertions(+), 33 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 1595596a..f67d64c2 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -205,11 +205,11 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) const char *log_id(RTLIL::IdString str) { - if (str.size() > 1 && str[0] == '\\' && str[1] != '$') - string_buf.push_back(str.substr(1)); - else - string_buf.push_back(str.str()); - return string_buf.back().c_str(); + const char *p = str; + log_assert(RTLIL::IdString::global_refcount_storage_[str.index_] > 1); + if (p[0] == '\\' && p[1] != '$' && p[1] != 0) + return p+1; + return p; } void log_cell(RTLIL::Cell *cell, std::string indent) diff --git a/kernel/log.h b/kernel/log.h index 118ff69b..037a62a3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -22,8 +22,6 @@ #ifndef LOG_H #define LOG_H -#include -#include #include #include #include diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 80f63ce7..9ee8123f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -27,8 +27,8 @@ YOSYS_NAMESPACE_BEGIN std::vector RTLIL::IdString::global_refcount_storage_; -std::vector RTLIL::IdString::global_id_storage_; -std::map RTLIL::IdString::global_id_index_; +std::vector RTLIL::IdString::global_id_storage_; +std::map RTLIL::IdString::global_id_index_; std::vector RTLIL::IdString::global_free_idx_list_; RTLIL::Const::Const() diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d95cf11f..9430da31 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -76,9 +76,18 @@ namespace RTLIL { // the global string cache + struct char_ptr_cmp { + bool operator()(const char *a, const char *b) { + for (int i = 0; a[i] || b[i]; i++) + if (a[i] != b[i]) + return a[i] < b[i]; + return false; + } + }; + static std::vector global_refcount_storage_; - static std::vector global_id_storage_; - static std::map global_id_index_; + static std::vector global_id_storage_; + static std::map global_id_index_; static std::vector global_free_idx_list_; static inline int get_reference(int idx) @@ -87,14 +96,14 @@ namespace RTLIL return idx; } - static inline int get_reference(const std::string &str) + static inline int get_reference(const char *p) { - if (!str.empty()) { - log_assert(str.size() >= 2); - log_assert(str[0] == '$' || str[0] == '\\'); + if (p[0]) { + log_assert(p[1] != 0); + log_assert(p[0] == '$' || p[0] == '\\'); } - auto it = global_id_index_.find(str); + auto it = global_id_index_.find((char*)p); if (it != global_id_index_.end()) { global_refcount_storage_.at(it->second)++; return it->second; @@ -103,13 +112,13 @@ namespace RTLIL if (global_free_idx_list_.empty()) { log_assert(global_id_storage_.size() < 0x40000000); global_free_idx_list_.push_back(global_id_storage_.size()); - global_id_storage_.push_back(std::string()); + global_id_storage_.push_back(nullptr); global_refcount_storage_.push_back(0); } int idx = global_free_idx_list_.back(); global_free_idx_list_.pop_back(); - global_id_storage_.at(idx) = str; + global_id_storage_.at(idx) = strdup(p); global_id_index_[global_id_storage_.at(idx)] = idx; global_refcount_storage_.at(idx)++; return idx; @@ -121,7 +130,7 @@ namespace RTLIL return; global_id_index_.erase(global_id_storage_.at(idx)); - global_id_storage_.at(idx).clear(); + free(global_id_storage_.at(idx)); global_free_idx_list_.push_back(idx); } @@ -132,7 +141,7 @@ namespace RTLIL IdString() : index_(get_reference("")) { } IdString(const char *str) : index_(get_reference(str)) { } IdString(const IdString &str) : index_(get_reference(str.index_)) { } - IdString(const std::string &str) : index_(get_reference(str)) { } + IdString(const std::string &str) : index_(get_reference(str.c_str())) { } ~IdString() { put_reference(index_); } void operator=(const IdString &rhs) { @@ -150,21 +159,26 @@ namespace RTLIL *this = id; } - const std::string& str() const { + const char*c_str() const { return global_id_storage_.at(index_); } + operator const char*() const { + return global_id_storage_.at(index_); + } + + std::string str() const { + return std::string(global_id_storage_.at(index_)); + } + bool operator<(const IdString &rhs) const { return index_ < rhs.index_; } - // The methods below are just convinience functions for better compatibility - // with std::string. Except clear() they all just deligate to std::string. + bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } + bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } - operator const char*() const { return str().c_str(); } - - bool operator==(const IdString &rhs) const { return str() == rhs.str(); } - bool operator!=(const IdString &rhs) const { return str() != rhs.str(); } + // The methods below are just convinience functions for better compatibility with std::string. bool operator==(const std::string &rhs) const { return str() == rhs; } bool operator!=(const std::string &rhs) const { return str() != rhs; } @@ -172,12 +186,28 @@ namespace RTLIL bool operator==(const char *rhs) const { return str() == rhs; } bool operator!=(const char *rhs) const { return str() != rhs; } - char at(size_t i) const { return str().at(i); } - const char*c_str() const { return str().c_str(); } - std::string substr(size_t pos = 0, size_t len = std::string::npos) const { return str().substr(pos, len); } - size_t size() const { return str().size(); } - bool empty() const { return str().empty(); } - void clear() { *this = IdString(); } + char at(size_t i) const { + return c_str()[i]; + } + + std::string substr(size_t pos = 0, size_t len = std::string::npos) const { + if (len == std::string::npos) + return std::string(c_str() + pos); + else + return std::string(c_str() + pos, len); + } + + size_t size() const { + return str().size(); + } + + bool empty() const { + return c_str()[0] == 0; + } + + void clear() { + *this = IdString(); + } }; static inline std::string escape_id(std::string str) { diff --git a/kernel/yosys.h b/kernel/yosys.h index f9c1848e..34777c9a 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -43,7 +43,11 @@ #include #include #include + #include +#include +#include +#include #define PRIVATE_NAMESPACE_BEGIN namespace { #define PRIVATE_NAMESPACE_END } From 08392aad8f8e7c5bbcfa010c19786b1f318028b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:52:21 +0200 Subject: [PATCH 526/750] Limit size of log_signal buffer to 100 elements --- kernel/log.cc | 7 +++++++ kernel/rtlil.h | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index f67d64c2..9cabc6a8 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -41,6 +41,7 @@ int log_verbose_level; std::vector header_count; std::list string_buf; +int string_buf_size = 0; static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; @@ -166,6 +167,7 @@ void log_pop() { header_count.pop_back(); string_buf.clear(); + string_buf_size = 0; log_flush(); } @@ -174,6 +176,7 @@ void log_reset_stack() while (header_count.size() > 1) header_count.pop_back(); string_buf.clear(); + string_buf_size = 0; log_flush(); } @@ -197,6 +200,10 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) fputc(0, f); fclose(f); + if (string_buf_size < 100) + string_buf_size++; + else + string_buf.pop_front(); string_buf.push_back(ptr); free(ptr); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9430da31..7b989385 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -74,7 +74,7 @@ namespace RTLIL struct IdString { - // the global string cache + // the global id string cache struct char_ptr_cmp { bool operator()(const char *a, const char *b) { @@ -134,7 +134,7 @@ namespace RTLIL global_free_idx_list_.push_back(idx); } - // The actual IdString objects just is a single int + // the actual IdString object is just is a single int int index_; From 768eb846c4473040dc07bf62ce631c8a21474ae8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 16:03:18 +0200 Subject: [PATCH 527/750] More bugfixes related to new RTLIL::IdString --- frontends/ast/simplify.cc | 14 +++++++------- frontends/liberty/liberty.cc | 18 +++++++++--------- kernel/log.cc | 17 ++++++++++------- kernel/rtlil.h | 29 ++++++++++++++++++++--------- kernel/yosys.cc | 2 +- passes/cmds/select.cc | 6 +++--- passes/hierarchy/hierarchy.cc | 2 +- passes/sat/miter.cc | 6 +++--- passes/techmap/extract.cc | 2 +- passes/techmap/techmap.cc | 8 +++++--- 10 files changed, 60 insertions(+), 44 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 4d71bb39..694f1d4d 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 72e370b9..504b8d1e 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; } diff --git a/kernel/log.cc b/kernel/log.cc index 9cabc6a8..01f6207e 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -90,22 +90,25 @@ void logv(const char *format, va_list ap) void logv_header(const char *format, va_list ap) { + bool pop_errfile = false; + log("\n"); if (header_count.size() > 0) header_count.back()++; + + if (int(header_count.size()) <= log_verbose_level && log_errfile != NULL) { + log_files.push_back(log_errfile); + pop_errfile = true; + } + for (int c : header_count) log("%d.", c); log(" "); logv(format, ap); log_flush(); - if (int(header_count.size()) <= log_verbose_level && log_errfile != NULL) { - for (int c : header_count) - fprintf(log_errfile, "%d.", c); - fprintf(log_errfile, " "); - vfprintf(log_errfile, format, ap); - fflush(log_errfile); - } + if (pop_errfile) + log_files.pop_back(); } void logv_error(const char *format, va_list ap) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7b989385..6529603e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -126,11 +126,14 @@ namespace RTLIL static inline void put_reference(int idx) { + log_assert(global_refcount_storage_.at(idx) > 0); + if (--global_refcount_storage_.at(idx) != 0) return; global_id_index_.erase(global_id_storage_.at(idx)); free(global_id_storage_.at(idx)); + global_id_storage_.at(idx) = nullptr; global_free_idx_list_.push_back(idx); } @@ -191,7 +194,7 @@ namespace RTLIL } std::string substr(size_t pos = 0, size_t len = std::string::npos) const { - if (len == std::string::npos) + if (len == std::string::npos || len >= strlen(c_str() + pos)) return std::string(c_str() + pos); else return std::string(c_str() + pos, len); @@ -208,6 +211,16 @@ namespace RTLIL void clear() { *this = IdString(); } + + // The following is a helper key_compare class. Instead of for example std::set + // use std::set> if the order of cells in the + // set has an influence on the algorithm. + + template struct compare_ptr_by_name { + bool operator()(const T *a, const T *b) { + return (a == nullptr || b == nullptr) ? (a < b) : (a->name < b->name); + } + }; }; static inline std::string escape_id(std::string str) { @@ -222,18 +235,12 @@ namespace RTLIL return str; } - static inline const char *id2cstr(const std::string &str) { - if (str.size() > 1 && str[0] == '\\' && str[1] != '$') - return str.c_str() + 1; - return str.c_str(); - } - static inline std::string unescape_id(RTLIL::IdString str) { return unescape_id(str.str()); } static inline const char *id2cstr(const RTLIL::IdString &str) { - return id2cstr(str.str()); + return log_id(str); } template struct sort_by_name { @@ -833,7 +840,11 @@ struct RTLIL::SigBit SigBit(const RTLIL::SigSpec &sig); bool operator <(const RTLIL::SigBit &other) const { - return (wire != other.wire) ? (wire < other.wire) : wire ? (offset < other.offset) : (data < other.data); + if (wire == other.wire) + return wire ? (offset < other.offset) : (data < other.data); + if (wire != nullptr && other.wire != nullptr) + return wire->name < other.wire->name; + return wire < other.wire; } bool operator ==(const RTLIL::SigBit &other) const { diff --git a/kernel/yosys.cc b/kernel/yosys.cc index b5873d18..dff31db0 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -122,7 +122,7 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) str += stringf("(%d) ", recursion_counter); str += "yosys"; if (!design->selected_active_module.empty()) - str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); + str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module).c_str()); if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { if (design->selected_active_module.empty()) str += "*"; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 35ca2f47..b4f4d26a 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -490,7 +490,7 @@ static void select_op_expand(RTLIL::Design *design, std::string arg, char mode) for (auto i2 : i1.second) limits.insert(i2); } else - log_cmd_error("Selection %s is not defined!\n", RTLIL::id2cstr(str)); + log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str).c_str()); } else limits.insert(RTLIL::escape_id(str)); } @@ -654,7 +654,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg) if (design->selection_vars.count(set_name) > 0) work_stack.push_back(design->selection_vars[set_name]); else - log_cmd_error("Selection @%s is not defined!\n", RTLIL::id2cstr(set_name)); + log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name).c_str()); select_filter_active_mod(design, work_stack.back()); return; } @@ -1315,7 +1315,7 @@ struct CdPass : public Pass { return; } - log_cmd_error("No such module `%s' found!\n", RTLIL::id2cstr(modname)); + log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname).c_str()); } } CdPass; diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 28b4ad99..50b4989d 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -28,7 +28,7 @@ namespace { struct generate_port_decl_t { bool input, output; - std::string portname; + RTLIL::IdString portname; int index; }; } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 1475b855..e51c92f9 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -59,9 +59,9 @@ static void create_miter_equiv(struct Pass *that, std::vector args, if (argidx+3 != args.size() || args[argidx].substr(0, 1) == "-") that->cmd_error(args, argidx, "command argument error"); - std::string gold_name = RTLIL::escape_id(args[argidx++]); - std::string gate_name = RTLIL::escape_id(args[argidx++]); - std::string miter_name = RTLIL::escape_id(args[argidx++]); + RTLIL::IdString gold_name = RTLIL::escape_id(args[argidx++]); + RTLIL::IdString gate_name = RTLIL::escape_id(args[argidx++]); + RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]); if (design->modules_.count(gold_name) == 0) log_cmd_error("Can't find gold module %s!\n", gold_name.c_str()); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 6ebac265..06af2923 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -700,7 +700,7 @@ struct ExtractPass : public Pass { log("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits); log(" primary match in %s:", id2cstr(haystack_map.at(result.graphId)->name)); for (auto &node : result.nodes) - log(" %s", id2cstr(node.nodeId)); + log(" %s", RTLIL::unescape_id(node.nodeId).c_str()); log("\n"); for (auto &it : result.matchesPerGraph) log(" matches in %s: %d\n", id2cstr(haystack_map.at(it.first)->name), it.second); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 2bcd3003..374fa9bf 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -57,7 +57,7 @@ struct TechmapWorker std::map simplemap_mappers; std::map>, RTLIL::Module*> techmap_cache; std::map techmap_do_cache; - std::set module_queue; + std::set> module_queue; struct TechmapWireData { RTLIL::Wire *wire; @@ -479,7 +479,7 @@ struct TechmapWorker cmd_string = cmd_string.substr(strlen("CONSTMAP; ")); log("Analyzing pattern of constant bits for this cell:\n"); - std::string new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true); + RTLIL::IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true); log("Creating constmapped module `%s'.\n", log_id(new_tpl_name)); log_assert(map->module(new_tpl_name) == nullptr); @@ -824,7 +824,9 @@ struct TechmapPass : public Pass { celltypeMap[it.first].insert(it.first); } - worker.module_queue = design->modules(); + for (auto module : design->modules()) + worker.module_queue.insert(module); + while (!worker.module_queue.empty()) { RTLIL::Module *module = *worker.module_queue.begin(); From 04727c7e0fb4c00b38999da192e4ada2a6f9474a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 18:58:40 +0200 Subject: [PATCH 528/750] No implicit conversion from IdString to anything else --- backends/blif/blif.cc | 2 +- backends/btor/btor.cc | 2 +- backends/edif/edif.cc | 4 ++-- backends/spice/spice.cc | 2 +- kernel/log.cc | 2 +- kernel/register.cc | 4 ++-- kernel/rtlil.cc | 28 ++++++++++++++-------------- kernel/rtlil.h | 10 +++++----- passes/abc/abc.cc | 2 +- passes/cmds/design.cc | 2 +- passes/cmds/select.cc | 4 ++-- passes/cmds/show.cc | 2 +- passes/fsm/fsm_export.cc | 2 +- passes/memory/memory_collect.cc | 2 +- passes/techmap/extract.cc | 4 ++-- passes/techmap/techmap.cc | 2 +- 16 files changed, 37 insertions(+), 37 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index ecde8b5a..5daab669 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -363,7 +363,7 @@ struct BlifBackend : public Backend { if (top_module_name.empty()) for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) - top_module_name = mod_it.first; + top_module_name = mod_it.first.str(); fprintf(f, "# Generated by %s\n", yosys_version_str); diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 201be0cf..a81d8f15 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -968,7 +968,7 @@ struct BtorBackend : public Backend { if (top_module_name.empty()) for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) - top_module_name = mod_it.first; + top_module_name = mod_it.first.str(); fprintf(f, "; Generated by %s\n", yosys_version_str); fprintf(f, "; %s developed and maintained by Clifford Wolf \n", yosys_version_str); diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index bf1efc4a..ecdfaabf 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -126,7 +126,7 @@ struct EdifBackend : public Backend { if (top_module_name.empty()) for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) - top_module_name = mod_it.first; + top_module_name = mod_it.first.str(); for (auto module_it : design->modules_) { @@ -135,7 +135,7 @@ struct EdifBackend : public Backend { continue; if (top_module_name.empty()) - top_module_name = module->name; + top_module_name = module->name.str(); if (module->processes.size() != 0) log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name)); diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index a445e9cc..be0086ff 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -172,7 +172,7 @@ struct SpiceBackend : public Backend { if (top_module_name.empty()) for (auto & mod_it:design->modules_) if (mod_it.second->get_bool_attribute("\\top")) - top_module_name = mod_it.first; + top_module_name = mod_it.first.str(); fprintf(f, "* SPICE netlist generated by %s\n", yosys_version_str); fprintf(f, "\n"); diff --git a/kernel/log.cc b/kernel/log.cc index 01f6207e..81cc26da 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -215,7 +215,7 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) const char *log_id(RTLIL::IdString str) { - const char *p = str; + const char *p = str.c_str(); log_assert(RTLIL::IdString::global_refcount_storage_[str.index_] > 1); if (p[0] == '\\' && p[1] != '$' && p[1] != 0) return p+1; diff --git a/kernel/register.cc b/kernel/register.cc index 4d204069..868dbb94 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -240,7 +240,7 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command) { std::string backup_selected_active_module = design->selected_active_module; - design->selected_active_module = module->name; + design->selected_active_module = module->name.str(); design->selection_stack.push_back(RTLIL::Selection(false)); design->selection_stack.back().select(module); @@ -253,7 +253,7 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::str void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vector args) { std::string backup_selected_active_module = design->selected_active_module; - design->selected_active_module = module->name; + design->selected_active_module = module->name.str(); design->selection_stack.push_back(RTLIL::Selection(false)); design->selection_stack.back().select(module); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9ee8123f..2838449b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -286,7 +286,7 @@ void RTLIL::Design::check() for (auto &it : modules_) { log_assert(this == it.second->design); log_assert(it.first == it.second->name); - log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(!it.first.empty()); it.second->check(); } #endif @@ -499,7 +499,7 @@ namespace { void check() { - if (cell->type[0] != '$' || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || + if (cell->type.substr(0, 1) != "$" || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:") return; @@ -818,38 +818,38 @@ void RTLIL::Module::check() for (auto &it : wires_) { log_assert(this == it.second->module); log_assert(it.first == it.second->name); - log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(!it.first.empty()); log_assert(it.second->width >= 0); log_assert(it.second->port_id >= 0); for (auto &it2 : it.second->attributes) { - log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(!it2.first.empty()); } } for (auto &it : memories) { log_assert(it.first == it.second->name); - log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(!it.first.empty()); log_assert(it.second->width >= 0); log_assert(it.second->size >= 0); for (auto &it2 : it.second->attributes) { - log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(!it2.first.empty()); } } for (auto &it : cells_) { log_assert(this == it.second->module); log_assert(it.first == it.second->name); - log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); - log_assert(it.second->type.size() > 0 && (it.second->type[0] == '\\' || it.second->type[0] == '$')); + log_assert(!it.first.empty()); + log_assert(!it.second->type.empty()); for (auto &it2 : it.second->connections()) { - log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(!it2.first.empty()); it2.second.check(); } for (auto &it2 : it.second->attributes) { - log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(!it2.first.empty()); } for (auto &it2 : it.second->parameters) { - log_assert(it2.first.size() > 0 && (it2.first[0] == '\\' || it2.first[0] == '$')); + log_assert(!it2.first.empty()); } InternalCellChecker checker(this, it.second); checker.check(); @@ -857,7 +857,7 @@ void RTLIL::Module::check() for (auto &it : processes) { log_assert(it.first == it.second->name); - log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(!it.first.empty()); // FIXME: More checks here.. } @@ -868,7 +868,7 @@ void RTLIL::Module::check() } for (auto &it : attributes) { - log_assert(it.first.size() > 0 && (it.first[0] == '\\' || it.first[0] == '$')); + log_assert(!it.first.empty()); } #endif } @@ -1597,7 +1597,7 @@ void RTLIL::Cell::check() void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) { - if (type[0] != '$' || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || + if (type.substr(0, 1) != "$" || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") return; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6529603e..502969a1 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -162,11 +162,7 @@ namespace RTLIL *this = id; } - const char*c_str() const { - return global_id_storage_.at(index_); - } - - operator const char*() const { + const char *c_str() const { return global_id_storage_.at(index_); } @@ -193,6 +189,10 @@ namespace RTLIL return c_str()[i]; } + char operator[](size_t i) const { + return c_str()[i]; + } + std::string substr(size_t pos = 0, size_t len = std::string::npos) const { if (len == std::string::npos || len >= strlen(c_str() + pos)) return std::string(c_str() + pos); diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 19664357..77419e61 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -303,7 +303,7 @@ static void handle_loops() id1 = id2; else if (edges[id1].size() > edges[id2].size()) continue; - else if (w1->name > w2->name) + else if (w2->name < w1->name) id1 = id2; } diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 260e7b5d..9f800c31 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -192,7 +192,7 @@ struct DesignPass : public Pass { for (auto mod : copy_src_modules) { - std::string trg_name = as_name.empty() ? std::string(mod->name) : RTLIL::escape_id(as_name); + std::string trg_name = as_name.empty() ? mod->name.str() : RTLIL::escape_id(as_name); if (copy_to_design->modules_.count(trg_name)) delete copy_to_design->modules_.at(trg_name); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index b4f4d26a..2d49e85e 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1080,7 +1080,7 @@ struct SelectPass : public Pass { RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]); if (design->modules_.count(mod_name) == 0) log_cmd_error("No such module: %s\n", id2cstr(mod_name)); - design->selected_active_module = mod_name; + design->selected_active_module = mod_name.str(); got_module = true; continue; } @@ -1304,7 +1304,7 @@ struct CdPass : public Pass { if (design->modules_.count(design->selected_active_module) > 0) module = design->modules_.at(design->selected_active_module); if (module != NULL && module->cells_.count(modname) > 0) - modname = module->cells_.at(modname)->type; + modname = module->cells_.at(modname)->type.str(); } if (design->modules_.count(modname) > 0) { diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index bbc0ff44..cbc4725f 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -322,7 +322,7 @@ struct ShowWorker else if (it.second->port_output) all_sinks.insert(stringf("n%d", id2num(it.first))); } else { - wires_on_demand[stringf("n%d", id2num(it.first))] = it.first; + wires_on_demand[stringf("n%d", id2num(it.first))] = it.first.str(); } } diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index 97ccf91e..cb762dc1 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -61,7 +61,7 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st kiss_name.assign(attr_it->second.decode_string()); } else { - kiss_name.assign(module->name); + kiss_name.assign(module->name.str()); kiss_name.append('-' + cell->name.str() + ".kiss2"); } diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 471a7d53..9c670f00 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -126,7 +126,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) } std::stringstream sstr; - sstr << "$mem$" << memory->name << "$" << (autoidx++); + sstr << "$mem$" << memory->name.str() << "$" << (autoidx++); RTLIL::Cell *mem = module->addCell(sstr.str(), "$mem"); mem->parameters["\\MEMID"] = RTLIL::Const(memory->name.str()); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 06af2923..985d51e5 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -240,8 +240,8 @@ namespace if (sig_bit_ref.count(bit) == 0) { bit_ref_t &bit_ref = sig_bit_ref[bit]; - bit_ref.cell = cell->name; - bit_ref.port = conn.first; + bit_ref.cell = cell->name.str(); + bit_ref.port = conn.first.str(); bit_ref.bit = i; } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 374fa9bf..c639cc48 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -155,7 +155,7 @@ struct TechmapWorker if (!flatten_mode) for (auto &it : tpl->cells_) if (it.first == "\\_TECHMAP_REPLACE_") { - orig_cell_name = cell->name; + orig_cell_name = cell->name.str(); module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str()); break; } From 8e7361f128ce00a742412931efcf7cbe5795a39a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 19:08:02 +0200 Subject: [PATCH 529/750] Removed at() method from RTLIL::IdString --- kernel/rtlil.cc | 4 ++-- kernel/rtlil.h | 9 ++++----- passes/sat/expose.cc | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2838449b..56c631f3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -490,9 +490,9 @@ namespace { } for (auto &conn : cell->connections()) { - if (conn.first.size() != 2 || conn.first.at(0) != '\\') + if (conn.first.size() != 2 || conn.first[0] != '\\') error(__LINE__); - if (strchr(ports, conn.first.at(1)) == NULL) + if (strchr(ports, conn.first[1]) == NULL) error(__LINE__); } } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 502969a1..ab15024e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -185,12 +185,11 @@ namespace RTLIL bool operator==(const char *rhs) const { return str() == rhs; } bool operator!=(const char *rhs) const { return str() != rhs; } - char at(size_t i) const { - return c_str()[i]; - } - char operator[](size_t i) const { - return c_str()[i]; + const char *p = c_str(); + for (; i != 0; i--, p++) + log_assert(*p != 0); + return *p; } std::string substr(size_t pos = 0, size_t len = std::string::npos) const { diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index affd685e..e856fdf7 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -50,7 +50,7 @@ static bool consider_cell(RTLIL::Design *design, std::set &dff_ { if (cell->name[0] == '$' || dff_cells.count(cell->name)) return false; - if (cell->type.at(0) == '\\' && !design->modules_.count(cell->type)) + if (cell->type[0] == '\\' && !design->modules_.count(cell->type)) return false; return true; } From b6acbc82e6a2954d453188a9997da2a30731ddac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 20:54:30 +0200 Subject: [PATCH 530/750] Bugfix in "techmap -extern" --- kernel/rtlil.cc | 26 ++++++++++++++++---------- passes/techmap/techmap.cc | 1 + 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 56c631f3..792474af 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -815,25 +815,34 @@ namespace { void RTLIL::Module::check() { #ifndef NDEBUG + std::vector ports_declared; for (auto &it : wires_) { log_assert(this == it.second->module); log_assert(it.first == it.second->name); log_assert(!it.first.empty()); log_assert(it.second->width >= 0); log_assert(it.second->port_id >= 0); - for (auto &it2 : it.second->attributes) { + for (auto &it2 : it.second->attributes) log_assert(!it2.first.empty()); - } + if (it.second->port_id) { + log_assert(it.second->port_input || it.second->port_output); + if (SIZE(ports_declared) < it.second->port_id) + ports_declared.resize(it.second->port_id); + log_assert(ports_declared[it.second->port_id-1] == false); + ports_declared[it.second->port_id-1] = true; + } else + log_assert(!it.second->port_input && !it.second->port_output); } + for (auto port_declared : ports_declared) + log_assert(port_declared == true); for (auto &it : memories) { log_assert(it.first == it.second->name); log_assert(!it.first.empty()); log_assert(it.second->width >= 0); log_assert(it.second->size >= 0); - for (auto &it2 : it.second->attributes) { + for (auto &it2 : it.second->attributes) log_assert(!it2.first.empty()); - } } for (auto &it : cells_) { @@ -845,12 +854,10 @@ void RTLIL::Module::check() log_assert(!it2.first.empty()); it2.second.check(); } - for (auto &it2 : it.second->attributes) { + for (auto &it2 : it.second->attributes) log_assert(!it2.first.empty()); - } - for (auto &it2 : it.second->parameters) { + for (auto &it2 : it.second->parameters) log_assert(!it2.first.empty()); - } InternalCellChecker checker(this, it.second); checker.check(); } @@ -867,9 +874,8 @@ void RTLIL::Module::check() it.second.check(); } - for (auto &it : attributes) { + for (auto &it : attributes) log_assert(!it.first.empty()); - } #endif } diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index c639cc48..74a51550 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -504,6 +504,7 @@ struct TechmapWorker RTLIL::Wire *new_wire = tpl->addWire(port_name, wire); wire->port_input = false; + wire->port_id = 0; for (int i = 0; i < wire->width; i++) { port_new2old_map[RTLIL::SigBit(new_wire, i)] = RTLIL::SigBit(wire, i); From ca1b5d50e0e577a88ae265b71679b81e71980db8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:10:08 +0200 Subject: [PATCH 531/750] Improved verilog output for ordinary $mux cells --- backends/verilog/verilog_backend.cc | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index e3c930c8..c691eae6 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -544,7 +544,22 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) #undef HANDLE_UNIOP #undef HANDLE_BINOP - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$pmux_safe") + if (cell->type == "$mux") + { + fprintf(f, "%s" "assign ", indent.c_str()); + dump_sigspec(f, cell->getPort("\\Y")); + fprintf(f, " = "); + dump_sigspec(f, cell->getPort("\\S")); + fprintf(f, " ? "); + dump_attributes(f, "", cell->attributes, ' '); + dump_sigspec(f, cell->getPort("\\B")); + fprintf(f, " : "); + dump_sigspec(f, cell->getPort("\\A")); + fprintf(f, ";\n"); + return true; + } + + if (cell->type == "$pmux" || cell->type == "$pmux_safe") { int width = cell->parameters["\\WIDTH"].as_int(); int s_width = cell->getPort("\\S").size(); @@ -556,10 +571,11 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) fprintf(f, "%s" " input [%d:0] s;\n", indent.c_str(), s_width-1); dump_attributes(f, indent + " ", cell->attributes); - if (!noattr) + if (cell->type != "$pmux_safe" && !noattr) fprintf(f, "%s" " (* parallel_case *)\n", indent.c_str()); fprintf(f, "%s" " casez (s)", indent.c_str()); - fprintf(f, noattr ? " // synopsys parallel_case\n" : "\n"); + if (cell->type != "$pmux_safe") + fprintf(f, noattr ? " // synopsys parallel_case\n" : "\n"); for (int i = 0; i < s_width; i++) { From 88cf00ce7874ec7951b09d85e959dd2c6ed261b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:54:02 +0200 Subject: [PATCH 532/750] Be more conservative with printing decimal numbers in verilog backend --- backends/verilog/verilog_backend.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index c691eae6..605616b3 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -163,11 +163,12 @@ void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = log_assert(i < (int)data.bits.size()); if (data.bits[i] != RTLIL::S0 && data.bits[i] != RTLIL::S1) goto dump_bits; + if (data.bits[i] == RTLIL::S1 && (i - offset) == 31) + goto dump_bits; if (data.bits[i] == RTLIL::S1) val |= 1 << (i - offset); } - // fprintf(f, "%s32'sd%u", val < 0 ? "-" : "", abs(val)); - fprintf(f, "%d", val); + fprintf(f, "32'%sd%d", set_signed ? "s" : "", val); } else { dump_bits: fprintf(f, "%d'%sb", width, set_signed ? "s" : ""); From bc947d4c7b9b7691e2aeab608c78c4658314cec2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:54:30 +0200 Subject: [PATCH 533/750] Fixed a va_list corruption in logv_error() --- kernel/log.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 81cc26da..09673dc2 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -113,12 +113,11 @@ void logv_header(const char *format, va_list ap) void logv_error(const char *format, va_list ap) { + if (log_errfile != NULL) + log_files.push_back(log_errfile); + log("ERROR: "); logv(format, ap); - if (log_errfile != NULL) { - fprintf(log_errfile, "ERROR: "); - vfprintf(log_errfile, format, ap); - } log_flush(); exit(1); } From 08ec33a5e573e0a59d2c1375e4e302a8485a6302 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:55:13 +0200 Subject: [PATCH 534/750] Implemented simplemap support for "techmap -extern" --- passes/techmap/techmap.cc | 45 ++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 74a51550..4a9a7891 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -326,8 +326,40 @@ struct TechmapWorker { if (extern_mode) { - log("WARNING: Mapping simplemap cell %s.%s (%s) in -extern mode is not supported yet.\n", log_id(module), log_id(cell), log_id(cell->type)); - break; + std::string m_name = stringf("$extern:simplemap:%s", log_id(cell->type)); + + for (auto &c : cell->parameters) + m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second)); + + RTLIL::Module *simplemap_module = design->module(m_name); + + if (simplemap_module == nullptr) + { + simplemap_module = design->addModule(m_name); + RTLIL::Cell *simplemap_cell = simplemap_module->addCell(cell->type, cell); + + int port_counter = 1; + for (auto &c : simplemap_cell->connections_) { + RTLIL::Wire *w = simplemap_module->addWire(c.first, SIZE(c.second)); + if (w->name == "\\Y" || w->name == "\\Q") + w->port_output = true; + else + w->port_input = true; + w->port_id = port_counter++; + c.second = w; + } + + simplemap_module->check(); + + log("Creating %s with simplemap.\n", log_id(simplemap_module)); + if (simplemap_mappers.count(simplemap_cell->type) == 0) + log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(simplemap_cell->type)); + simplemap_mappers.at(simplemap_cell->type)(simplemap_module, simplemap_cell); + simplemap_module->remove(simplemap_cell); + } + + cell->type = m_name; + cell->parameters.clear(); } else { @@ -337,10 +369,11 @@ struct TechmapWorker simplemap_mappers.at(cell->type)(module, cell); module->remove(cell); cell = NULL; - did_something = true; - mapped_cell = true; - break; } + + did_something = true; + mapped_cell = true; + break; } for (auto conn : cell->connections()) { @@ -538,6 +571,8 @@ struct TechmapWorker port_conn.second.append_bit(it.second); } tpl->connect(port_conn); + + tpl->check(); } Pass::call_on_module(map, tpl, cmd_string); From 9bb5298c104e83fef52d345772175be40301c7e3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 12:40:23 +0200 Subject: [PATCH 535/750] Fixes in show command (related to new IdString) --- passes/cmds/show.cc | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index cbc4725f..c15feb7b 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -111,7 +111,7 @@ struct ShowWorker return stringf("style=\"setlinewidth(3)\", label=\"<%d>\"", bits); } - const char *findColor(RTLIL::IdString member_name) + const char *findColor(std::string member_name) { for (auto &s : color_selections) if (s.second.selected_member(module->name, member_name)) { @@ -121,7 +121,7 @@ struct ShowWorker return ""; } - const char *findLabel(RTLIL::IdString member_name) + const char *findLabel(std::string member_name) { for (auto &s : label_selections) if (s.second.selected_member(module->name, member_name)) @@ -129,14 +129,12 @@ struct ShowWorker return escape(member_name, true); } - const char *escape(RTLIL::IdString id, bool is_name = false) + const char *escape(std::string id, bool is_name = false) { - std::string id_str = id.str(); - - if (id_str.size() == 0) + if (id.size() == 0) return ""; - if (id_str[0] == '$' && is_name) { + if (id[0] == '$' && is_name) { if (enumerateIds) { if (autonames.count(id) == 0) { autonames[id] = autonames.size() + 1; @@ -144,17 +142,17 @@ struct ShowWorker } id = stringf("_%d_", autonames[id]); } else if (abbreviateIds) { - const char *p = id_str.c_str(); + const char *p = id.c_str(); const char *q = strrchr(p, '$'); - id_str = std::string(q); + id = std::string(q); } } - if (id_str[0] == '\\') - id_str = id_str.substr(1); + if (id[0] == '\\') + id = id.substr(1); std::string str; - for (char ch : id_str) { + for (char ch : id) { if (ch == '\\' || ch == '"') str += "\\"; str += ch; @@ -298,9 +296,9 @@ struct ShowWorker dot_id2num_store.clear(); net_conn_map.clear(); - fprintf(f, "digraph \"%s\" {\n", escape(module->name)); + fprintf(f, "digraph \"%s\" {\n", escape(module->name.str())); if (!notitle) - fprintf(f, "label=\"%s\";\n", escape(module->name)); + fprintf(f, "label=\"%s\";\n", escape(module->name.str())); fprintf(f, "rankdir=\"LR\";\n"); fprintf(f, "remincross=true;\n"); @@ -315,7 +313,7 @@ struct ShowWorker shape = "octagon"; if (it.first[0] == '\\') { fprintf(f, "n%d [ shape=%s, label=\"%s\", %s, fontcolor=\"black\" ];\n", - id2num(it.first), shape, findLabel(it.first), + id2num(it.first), shape, findLabel(it.first.str()), nextColor(RTLIL::SigSpec(it.second), "color=\"black\"").c_str()); if (it.second->port_input) all_sources.insert(stringf("n%d", id2num(it.first))); @@ -356,14 +354,14 @@ struct ShowWorker std::string label_string = "{{"; for (auto &p : in_ports) - label_string += stringf(" %s|", id2num(p), escape(p)); + label_string += stringf(" %s|", id2num(p), escape(p.str())); if (label_string[label_string.size()-1] == '|') label_string = label_string.substr(0, label_string.size()-1); - label_string += stringf("}|%s\\n%s|{", findLabel(it.first), escape(it.second->type)); + label_string += stringf("}|%s\\n%s|{", findLabel(it.first.str()), escape(it.second->type.str())); for (auto &p : out_ports) - label_string += stringf(" %s|", id2num(p), escape(p)); + label_string += stringf(" %s|", id2num(p), escape(p.str())); if (label_string[label_string.size()-1] == '|') label_string = label_string.substr(0, label_string.size()-1); @@ -382,7 +380,7 @@ struct ShowWorker else #endif fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s", - id2num(it.first), label_string.c_str(), findColor(it.first), code.c_str()); + id2num(it.first), label_string.c_str(), findColor(it.first.str()), code.c_str()); } for (auto &it : module->processes) @@ -420,7 +418,7 @@ struct ShowWorker std::string proc_src = RTLIL::unescape_id(proc->name); if (proc->attributes.count("\\src") > 0) proc_src = proc->attributes.at("\\src").decode_string(); - fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name), proc_src.c_str()); + fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name.str()), proc_src.c_str()); } for (auto &conn : module->connections()) From 014a41fcf3463fae881413b4b366c2c2a6fb20de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 12:40:43 +0200 Subject: [PATCH 536/750] Implemented recursive techmap --- passes/techmap/techmap.cc | 78 +++++++++++++++++++++++++++++++-------- techlibs/common/techmap.v | 2 +- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 4a9a7891..29ce9676 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -69,12 +69,14 @@ struct TechmapWorker bool extern_mode; bool assert_mode; bool flatten_mode; + bool recursive_mode; TechmapWorker() { extern_mode = false; assert_mode = false; flatten_mode = false; + recursive_mode = false; } std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose) @@ -139,8 +141,6 @@ struct TechmapWorker void techmap_module_worker(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl) { - log("Mapping `%s.%s' using `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(tpl->name)); - if (tpl->memories.size() != 0) log_error("Technology map yielded memories -> this is not supported.\n"); @@ -251,8 +251,10 @@ struct TechmapWorker } bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, - const std::map> &celltypeMap) + const std::map> &celltypeMap, bool in_recursion) { + std::string mapmsg_prefix = in_recursion ? "Recursively mapping" : "Mapping"; + if (!design->selected(module)) return false; @@ -270,9 +272,13 @@ struct TechmapWorker if (!design->selected(module, cell) || handled_cells.count(cell) > 0) continue; - if (celltypeMap.count(cell->type) == 0) { - if (assert_mode && cell->type.str().back() != '_') - log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell->type)); + std::string cell_type = cell->type.str(); + if (in_recursion && cell_type.substr(0, 2) == "\\$") + cell_type = cell_type.substr(1); + + if (celltypeMap.count(cell_type) == 0) { + if (assert_mode && cell_type.back() != '_') + log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell_type)); continue; } @@ -284,7 +290,7 @@ struct TechmapWorker if (SIZE(sig) == 0) continue; - for (auto &tpl_name : celltypeMap.at(cell->type)) { + for (auto &tpl_name : celltypeMap.at(cell_type)) { RTLIL::Module *tpl = map->modules_[tpl_name]; RTLIL::Wire *port = tpl->wire(conn.first); if (port && port->port_input) @@ -311,7 +317,11 @@ struct TechmapWorker log_assert(cell == module->cell(cell->name)); bool mapped_cell = false; - for (auto &tpl_name : celltypeMap.at(cell->type)) + std::string cell_type = cell->type.str(); + if (in_recursion && cell_type.substr(0, 2) == "\\$") + cell_type = cell_type.substr(1); + + for (auto &tpl_name : celltypeMap.at(cell_type)) { RTLIL::IdString derived_name = tpl_name; RTLIL::Module *tpl = map->modules_[tpl_name]; @@ -324,7 +334,9 @@ struct TechmapWorker { if (tpl->get_bool_attribute("\\techmap_simplemap")) { - if (extern_mode) + cell->type = cell_type; + + if (extern_mode && !in_recursion) { std::string m_name = stringf("$extern:simplemap:%s", log_id(cell->type)); @@ -358,12 +370,13 @@ struct TechmapWorker simplemap_module->remove(simplemap_cell); } - cell->type = m_name; + log("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(simplemap_module)); + cell->type = simplemap_module->name; cell->parameters.clear(); } else { - log("Mapping %s.%s (%s) with simplemap.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + log("%s %s.%s (%s) with simplemap.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type)); if (simplemap_mappers.count(cell->type) == 0) log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); simplemap_mappers.at(cell->type)(module, cell); @@ -507,6 +520,7 @@ struct TechmapWorker std::string cmd_string = data.value.as_const().decode_string(); + restart_eval_cmd_string: if (cmd_string.rfind("CONSTMAP; ", 0) == 0) { cmd_string = cmd_string.substr(strlen("CONSTMAP; ")); @@ -573,6 +587,14 @@ struct TechmapWorker tpl->connect(port_conn); tpl->check(); + goto restart_eval_cmd_string; + } + + if (cmd_string.rfind("RECURSION; ", 0) == 0) + { + cmd_string = cmd_string.substr(strlen("RECURSION; ")); + while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) { } + goto restart_eval_cmd_string; } Pass::call_on_module(map, tpl, cmd_string); @@ -601,6 +623,14 @@ struct TechmapWorker for (auto &it : techmap_wire_names) log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", RTLIL::id2cstr(it)); + + if (recursive_mode) { + if (log_continue) { + log_header("Continuing TECHMAP pass.\n"); + log_continue = false; + } + while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) { } + } } if (techmap_do_cache.at(tpl) == false) @@ -611,7 +641,7 @@ struct TechmapWorker log_continue = false; } - if (extern_mode) + if (extern_mode && !in_recursion) { std::string m_name = stringf("$extern:%s", log_id(tpl)); @@ -628,12 +658,13 @@ struct TechmapWorker module_queue.insert(m); } - log("Mapping %s.%s to imported %s.\n", log_id(module), log_id(cell), log_id(m_name)); + log("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name)); cell->type = m_name; cell->parameters.clear(); } else { + log("%s %s.%s using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(tpl)); techmap_module_worker(design, module, cell, tpl); cell = NULL; } @@ -687,6 +718,11 @@ struct TechmapPass : public Pass { log(" -max_iter \n"); log(" only run the specified number of iterations.\n"); log("\n"); + log(" -recursive\n"); + log(" instead of the iterative breadth-first algorithm use a recursive\n"); + log(" depth-first algorithm. both methods should yield equivialent results,\n"); + log(" but may differ in performance.\n"); + log("\n"); log(" -assert\n"); log(" this option will cause techmap to exit with an error if it can't map\n"); log(" a selected cell. only cell types that end on an underscore are accepted\n"); @@ -736,6 +772,12 @@ struct TechmapPass : public Pass { log(" optimizied specializations of techmap modules without using the special\n"); log(" parameters described below.\n"); log("\n"); + log(" A _TECHMAP_DO_* command may start with the special token 'RECURSION; '.\n"); + log(" then techmap will recursively replace the cells in the module with their\n"); + log(" implementation. This is not affected by the -max_iter option.\n"); + log("\n"); + log(" It is possible to combine both prefixes to 'RECURSION; CONSTMAP; '.\n"); + log("\n"); log("In addition to this special wires, techmap also supports special parameters in\n"); log("modules in the map file:\n"); log("\n"); @@ -814,6 +856,10 @@ struct TechmapPass : public Pass { worker.extern_mode = true; continue; } + if (args[argidx] == "-recursive") { + worker.recursive_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -872,7 +918,7 @@ struct TechmapPass : public Pass { std::set handled_cells; while (did_something) { did_something = false; - if (worker.techmap_module(design, module, map, handled_cells, celltypeMap)) + if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false)) did_something = true; if (did_something) module->check(); @@ -926,11 +972,11 @@ struct FlattenPass : public Pass { while (did_something) { did_something = false; if (top_mod != NULL) { - if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap)) + if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, false)) did_something = true; } else { for (auto mod : design->modules()) - if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap)) + if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, false)) did_something = true; } } diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 54652868..7f3855ce 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -167,7 +167,7 @@ module shift_ops_shr_shl_sshl_sshr (A, B, Y); localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH); wire [1023:0] _TECHMAP_DO_00_ = "proc;;"; - wire [1023:0] _TECHMAP_DO_01_ = "CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_01_ = "RECURSION; CONSTMAP; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; integer i; reg [WIDTH-1:0] buffer; From 75423169c59022b3680aa3bf7de0877bc43a8082 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 14:59:13 +0200 Subject: [PATCH 537/750] Added ID() macro for static IdStrings --- kernel/yosys.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/yosys.h b/kernel/yosys.h index 34777c9a..f9bbc0e4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -103,6 +103,9 @@ RTLIL::IdString new_id(std::string file, int line, std::string func); #define NEW_ID \ YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) +#define ID(_str) \ + ([]() { static YOSYS_NAMESPACE_PREFIX RTLIL::IdString _id(_str); return _id; })() + RTLIL::Design *yosys_get_design(); std::string proc_self_dirname(); std::string proc_share_dirname(); From 653edd7a2f857d09bd8cecc48cc9ac76aea33098 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 15:00:38 +0200 Subject: [PATCH 538/750] Added query() API to ModIndex --- kernel/modtools.h | 54 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/kernel/modtools.h b/kernel/modtools.h index 09f2ae65..56bc1882 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -29,11 +29,11 @@ YOSYS_NAMESPACE_BEGIN struct ModIndex : public RTLIL::Monitor { struct PortInfo { - const RTLIL::Cell* cell; - const RTLIL::IdString &port; - const int offset; + RTLIL::Cell* cell; + RTLIL::IdString port; + int offset; - PortInfo(RTLIL::Cell* _c, const RTLIL::IdString &_p, int _o) : cell(_c), port(_p), offset(_o) { } + PortInfo(RTLIL::Cell* _c, RTLIL::IdString _p, int _o) : cell(_c), port(_p), offset(_o) { } bool operator<(const PortInfo &other) const { if (cell != other.cell) @@ -57,13 +57,13 @@ struct ModIndex : public RTLIL::Monitor std::map database; bool auto_reload_module; - void port_add(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &sig) + void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) { for (int i = 0; i < SIZE(sig); i++) database[sigmap(sig[i])].ports.insert(PortInfo(cell, port, i)); } - void port_del(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &sig) + void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) { for (int i = 0; i < SIZE(sig); i++) database[sigmap(sig[i])].ports.erase(PortInfo(cell, port, i)); @@ -122,14 +122,52 @@ struct ModIndex : public RTLIL::Monitor auto_reload_module = true; } - ModIndex(RTLIL::Module *_m) : module(_m) { + ModIndex(RTLIL::Module *_m) : module(_m) + { auto_reload_module = true; module->monitors.insert(this); } - ~ModIndex() { + ~ModIndex() + { module->monitors.erase(this); } + + SigBitInfo *query(RTLIL::SigBit bit) + { + if (auto_reload_module) + reload_module(); + auto it = database.find(sigmap(bit)); + if (it == database.end()) + return nullptr; + else + return &it->second; + } + + bool query_is_input(RTLIL::SigBit bit) + { + const SigBitInfo *info = query(bit); + if (info == nullptr) + return false; + return info->is_input; + } + + bool query_is_output(RTLIL::SigBit bit) + { + const SigBitInfo *info = query(bit); + if (info == nullptr) + return false; + return info->is_output; + } + + std::set &query_ports(RTLIL::SigBit bit) + { + static std::set empty_result_set; + SigBitInfo *info = query(bit); + if (info == nullptr) + return empty_result_set; + return info->ports; + } }; struct ModWalker From 0b02f6ca30a7bb5c3c8c34908aab8b8aa821c113 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 15:02:05 +0200 Subject: [PATCH 539/750] Added "wreduce" command (work in progress) --- passes/cmds/Makefile.inc | 1 + passes/cmds/wreduce.cc | 252 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 passes/cmds/wreduce.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index b55af995..d6e45f2d 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -20,4 +20,5 @@ OBJS += passes/cmds/write_file.o OBJS += passes/cmds/connwrappers.o OBJS += passes/cmds/cover.o OBJS += passes/cmds/trace.o +OBJS += passes/cmds/wreduce.o diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc new file mode 100644 index 00000000..39881a83 --- /dev/null +++ b/passes/cmds/wreduce.cc @@ -0,0 +1,252 @@ +/* + * 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/yosys.h" +#include "kernel/sigtools.h" +#include "kernel/modtools.h" + +#include + +USING_YOSYS_NAMESPACE +using namespace RTLIL; + +PRIVATE_NAMESPACE_BEGIN + +struct WreduceConfig +{ + std::set supported_cell_types; + + WreduceConfig() + { + supported_cell_types.insert("$not"); + supported_cell_types.insert("$pos"); + supported_cell_types.insert("$bu0"); + supported_cell_types.insert("$neg"); + + supported_cell_types.insert("$and"); + supported_cell_types.insert("$or"); + supported_cell_types.insert("$xor"); + supported_cell_types.insert("$xnor"); + + supported_cell_types.insert("$shl"); + supported_cell_types.insert("$shr"); + supported_cell_types.insert("$sshl"); + supported_cell_types.insert("$sshr"); + supported_cell_types.insert("$shift"); + supported_cell_types.insert("$shiftx"); + + supported_cell_types.insert("$lt"); + supported_cell_types.insert("$le"); + supported_cell_types.insert("$eq"); + supported_cell_types.insert("$ne"); + supported_cell_types.insert("$eqx"); + supported_cell_types.insert("$nex"); + supported_cell_types.insert("$ge"); + supported_cell_types.insert("$gt"); + + supported_cell_types.insert("$add"); + supported_cell_types.insert("$sub"); + // supported_cell_types.insert("$mul"); + // supported_cell_types.insert("$div"); + // supported_cell_types.insert("$mod"); + // supported_cell_types.insert("$pow"); + + // supported_cell_types.insert("$mux"); + // supported_cell_types.insert("$pmux"); + // supported_cell_types.insert("$safe_pmux"); + } +}; + +struct WreduceWorker +{ + WreduceConfig *config; + Module *module; + ModIndex mi; + + std::set> work_queue_cells; + std::set work_queue_bits; + SigMap constmap; + + WreduceWorker(WreduceConfig *config, Module *module) : + config(config), module(module), mi(module) { } + + void run_reduce_inport(Cell *cell, char port) + { + bool is_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); + SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port))); + + int bits_removed = 0; + if (is_signed) { + while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == constmap(sig[SIZE(sig)-2])) + work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; + } else { + while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == S0) + work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; + } + + if (bits_removed) { + log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n", + bits_removed, SIZE(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type)); + cell->setPort(stringf("\\%c", port), sig); + } + } + + void run_cell(Cell *cell) + { + if (config->supported_cell_types.count(cell->type) == 0) + return; + + if (cell->type == ID("$shl") || cell->type == ID("$shr") || cell->type == ID("$sshl") || cell->type == ID("$sshr")) + cell->setParam("\\B_SIGNED", false); + + if (cell->hasParam("\\A_SIGNED")) + run_reduce_inport(cell, 'A'); + + if (cell->hasParam("\\B_SIGNED")) + run_reduce_inport(cell, 'B'); + + SigSpec sig = mi.sigmap(cell->getPort("\\Y")); + + int bits_removed = 0; + while (SIZE(sig) > 0) { + auto info = mi.query(sig[SIZE(sig)-1]); + if (info->is_output || SIZE(info->ports) > 1) + break; + sig.remove(SIZE(sig)-1); + bits_removed++; + } + + if (cell->type == ID("$not") || cell->type == ID("$pos") || cell->type == ID("$bu0") || cell->type == ID("$neg") || + cell->type == ID("$and") || cell->type == ID("$or") || cell->type == ID("$xor") || cell->type == ID("$xnor") || + cell->type == ID("$add") || cell->type == ID("$sub") || cell->type == ID("$mul")) + { + bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + + int a_size = 0, b_size = 0; + if (cell->hasPort("\\A")) a_size = SIZE(cell->getPort("\\A")); + if (cell->hasPort("\\B")) b_size = SIZE(cell->getPort("\\B")); + + while (SIZE(sig) > 1 && SIZE(sig) > std::max(a_size, b_size)) { + module->connect(sig[SIZE(sig)-1], is_signed ? sig[SIZE(sig)-2] : S0); + sig.remove(SIZE(sig)-1); + bits_removed++; + } + } + + if (bits_removed) { + log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", + bits_removed, SIZE(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); + cell->setPort("\\Y", sig); + } + + cell->fixup_parameters(); + } + + void run() + { + for (auto c : module->selected_cells()) + work_queue_cells.insert(c); + + while (!work_queue_cells.empty()) + { + work_queue_bits.clear(); + for (auto c : work_queue_cells) + run_cell(c); + + work_queue_cells.clear(); + for (auto bit : work_queue_bits) + for (auto port : mi.query_ports(bit)) + work_queue_cells.insert(port.cell); + } + + std::set removed_wire_bits; + + for (auto w : module->selected_wires()) + { + int bits_removed = 0; + while (w->width > 0) { + SigBit bit(w, w->width-1); + auto info = mi.query(bit); + if (info == nullptr || (!info->is_output && !info->is_input && !SIZE(info->ports))) { + removed_wire_bits.insert(bit); + bits_removed++; + w->width--; + continue; + } + break; + } + if (bits_removed) + log("Removed top %d bits (of %d) from wire %s.%s.\n", + bits_removed, SIZE(w) + bits_removed, log_id(module), log_id(w)); + } + + if (!removed_wire_bits.empty()) { + std::vector new_conn = module->connections(); + for (auto &ss : new_conn) { + SigSig new_ss; + for (int i = 0; i < SIZE(ss.first); i++) + if (!removed_wire_bits.count(ss.first[i]) && !removed_wire_bits.count(ss.second[i])) { + new_ss.first.append_bit(ss.first[i]); + new_ss.second.append_bit(ss.second[i]); + } + ss = std::move(new_ss); + } + module->new_connections(new_conn); + } + } +}; + +struct WreducePass : public Pass { + WreducePass() : Pass("wreduce", "reduce the word size of operations is possible") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" wreduce [options] [selection]\n"); + log("\n"); + log("This command reduces the word size of operations.\n"); + log("\n"); + } + virtual void execute(std::vector args, Design *design) + { + WreduceConfig config; + + log_header("Executing WREDCUE pass (reducing word size of cells).\n"); + + log_error("FIXME: This command is under construction.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + break; + } + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) + { + if (module->has_processes_warn()) + continue; + + WreduceWorker worker(&config, module); + worker.run(); + } + } +} WreducePass; + +PRIVATE_NAMESPACE_END + From 027376515ac56251c82eedd961a9ffb2cc15a5a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 20:02:42 +0200 Subject: [PATCH 540/750] Progress in "wreduce" pass --- passes/cmds/wreduce.cc | 59 ++++++++++++------------------------------ 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index 39881a83..bd0b315e 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -124,17 +124,19 @@ struct WreduceWorker SigSpec sig = mi.sigmap(cell->getPort("\\Y")); int bits_removed = 0; - while (SIZE(sig) > 0) { + while (SIZE(sig) > 0) + { auto info = mi.query(sig[SIZE(sig)-1]); + if (info->is_output || SIZE(info->ports) > 1) break; + sig.remove(SIZE(sig)-1); bits_removed++; } - if (cell->type == ID("$not") || cell->type == ID("$pos") || cell->type == ID("$bu0") || cell->type == ID("$neg") || - cell->type == ID("$and") || cell->type == ID("$or") || cell->type == ID("$xor") || cell->type == ID("$xnor") || - cell->type == ID("$add") || cell->type == ID("$sub") || cell->type == ID("$mul")) + if (cell->type == ID("$pos") || cell->type == ID("$bu0") || cell->type == ID("$add") || cell->type == ID("$mul") || + cell->type == ID("$and") || cell->type == ID("$or") || cell->type == ID("$xor")) { bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); @@ -142,7 +144,15 @@ struct WreduceWorker if (cell->hasPort("\\A")) a_size = SIZE(cell->getPort("\\A")); if (cell->hasPort("\\B")) b_size = SIZE(cell->getPort("\\B")); - while (SIZE(sig) > 1 && SIZE(sig) > std::max(a_size, b_size)) { + int max_y_size = std::max(a_size, b_size); + + if (cell->type == "$add") + max_y_size++; + + if (cell->type == "$mul") + max_y_size = a_size + b_size; + + while (SIZE(sig) > 1 && SIZE(sig) > max_y_size) { module->connect(sig[SIZE(sig)-1], is_signed ? sig[SIZE(sig)-2] : S0); sig.remove(SIZE(sig)-1); bits_removed++; @@ -174,41 +184,6 @@ struct WreduceWorker for (auto port : mi.query_ports(bit)) work_queue_cells.insert(port.cell); } - - std::set removed_wire_bits; - - for (auto w : module->selected_wires()) - { - int bits_removed = 0; - while (w->width > 0) { - SigBit bit(w, w->width-1); - auto info = mi.query(bit); - if (info == nullptr || (!info->is_output && !info->is_input && !SIZE(info->ports))) { - removed_wire_bits.insert(bit); - bits_removed++; - w->width--; - continue; - } - break; - } - if (bits_removed) - log("Removed top %d bits (of %d) from wire %s.%s.\n", - bits_removed, SIZE(w) + bits_removed, log_id(module), log_id(w)); - } - - if (!removed_wire_bits.empty()) { - std::vector new_conn = module->connections(); - for (auto &ss : new_conn) { - SigSig new_ss; - for (int i = 0; i < SIZE(ss.first); i++) - if (!removed_wire_bits.count(ss.first[i]) && !removed_wire_bits.count(ss.second[i])) { - new_ss.first.append_bit(ss.first[i]); - new_ss.second.append_bit(ss.second[i]); - } - ss = std::move(new_ss); - } - module->new_connections(new_conn); - } } }; @@ -227,9 +202,7 @@ struct WreducePass : public Pass { { WreduceConfig config; - log_header("Executing WREDCUE pass (reducing word size of cells).\n"); - - log_error("FIXME: This command is under construction.\n"); + log_header("Executing WREDUCE pass (reducing word size of cells).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { From 358bf70a2111d476d9d209f216fdd087356ec0d9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 20:03:16 +0200 Subject: [PATCH 541/750] Added "wreduce" to some of the standard test benches --- tests/share/generate.py | 1 + tests/tools/autotest.sh | 2 +- tests/vloghtb/test_share.sh | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/share/generate.py b/tests/share/generate.py index e3b4bc96..a06a642d 100644 --- a/tests/share/generate.py +++ b/tests/share/generate.py @@ -66,6 +66,7 @@ for idx in range(100): print('rename uut_%05d gate' % idx) print('tee -a temp/all_share_log.txt log') print('tee -a temp/all_share_log.txt log #job# uut_%05d' % idx) + print('tee -a temp/all_share_log.txt wreduce') print('tee -a temp/all_share_log.txt share -aggressive gate') print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') print('sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter') diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 2d97e46f..9ae1c155 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -140,7 +140,7 @@ do elif [ "$frontend" = "verific_gates" ]; then test_passes -p "verific -vlog2k $fn; verific -import -gates -all; opt; memory;;" else - test_passes -f "$frontend" -p "hierarchy; proc; opt; memory -nomap; opt; fsm; opt" $fn + test_passes -f "$frontend" -p "hierarchy; proc; opt_const; opt_share;; wreduce;; share;; opt; memory -nomap;; fsm; opt" $fn test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt -fine; techmap; opt; abc -dff; opt" $fn fi touch ../${bn}.log diff --git a/tests/vloghtb/test_share.sh b/tests/vloghtb/test_share.sh index da221162..67cfe44e 100644 --- a/tests/vloghtb/test_share.sh +++ b/tests/vloghtb/test_share.sh @@ -6,6 +6,6 @@ source common.sh f=$1 n=$(basename ${f%.v}) -test_equiv share "share -aggressive" "-ignore_div_by_zero" $n $f +test_equiv share "wreduce; share -aggressive" "-ignore_div_by_zero" $n $f exit 0 From c7f99be3be828606cafc7d35b3612f5344065736 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 20:19:50 +0200 Subject: [PATCH 542/750] Fixed "share" for memory read ports --- passes/sat/share.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 4484d677..0c88b4d3 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -419,6 +419,13 @@ struct ShareWorker return supercell; } + if (c1->type == "$memrd") + { + RTLIL::Cell *supercell = module->addCell(NEW_ID, c1); + module->connect(c2->getPort("\\DATA"), supercell->getPort("\\DATA")); + return supercell; + } + log_abort(); } From ebbbe7fc8360ca0bd8f840d3df1b77ab2fb569b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:08:35 +0200 Subject: [PATCH 543/750] Added RTLIL::IdString::in(...) --- kernel/rtlil.h | 23 ++++++++++++++++++----- passes/cmds/wreduce.cc | 7 +++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ab15024e..8dfcbcaa 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -170,20 +170,20 @@ namespace RTLIL return std::string(global_id_storage_.at(index_)); } - bool operator<(const IdString &rhs) const { + bool operator<(IdString rhs) const { return index_ < rhs.index_; } - bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } - bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } + bool operator==(IdString rhs) const { return index_ == rhs.index_; } + bool operator!=(IdString rhs) const { return index_ != rhs.index_; } // The methods below are just convinience functions for better compatibility with std::string. bool operator==(const std::string &rhs) const { return str() == rhs; } bool operator!=(const std::string &rhs) const { return str() != rhs; } - bool operator==(const char *rhs) const { return str() == rhs; } - bool operator!=(const char *rhs) const { return str() != rhs; } + bool operator==(const char *rhs) const { return strcmp(c_str(), rhs) == 0; } + bool operator!=(const char *rhs) const { return strcmp(c_str(), rhs) != 0; } char operator[](size_t i) const { const char *p = c_str(); @@ -220,6 +220,19 @@ namespace RTLIL return (a == nullptr || b == nullptr) ? (a < b) : (a->name < b->name); } }; + + // often one needs to check if a given IdString is part of a list (for example a list + // of cell types). the following functions helps with that. + + template + bool in(T first, Args... rest) { + return in(first) || in(rest...); + } + + bool in(IdString rhs) { return *this == rhs; } + bool in(const char *rhs) { return *this == rhs; } + bool in(const std::string &rhs) { return *this == rhs; } + bool in(const std::set &rhs) { return rhs.count(*this) != 0; } }; static inline std::string escape_id(std::string str) { diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index bd0b315e..9cef14f4 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -109,10 +109,10 @@ struct WreduceWorker void run_cell(Cell *cell) { - if (config->supported_cell_types.count(cell->type) == 0) + if (!cell->type.in(config->supported_cell_types)) return; - if (cell->type == ID("$shl") || cell->type == ID("$shr") || cell->type == ID("$sshl") || cell->type == ID("$sshr")) + if (cell->type.in("$shl", "$shr", "$sshl", "$sshr")) cell->setParam("\\B_SIGNED", false); if (cell->hasParam("\\A_SIGNED")) @@ -135,8 +135,7 @@ struct WreduceWorker bits_removed++; } - if (cell->type == ID("$pos") || cell->type == ID("$bu0") || cell->type == ID("$add") || cell->type == ID("$mul") || - cell->type == ID("$and") || cell->type == ID("$or") || cell->type == ID("$xor")) + if (cell->type.in("$pos", "$bu0", "$add", "$mul", "$and", "$or", "$xor")) { bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); From b5a3419ac2c6f367b90f062c4e2252029910cdb9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:19:24 +0200 Subject: [PATCH 544/750] Added support for non-standard "module mod_name(...);" syntax --- README | 5 +++++ frontends/verilog/parser.y | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/README b/README index 1e0ade91..63d69229 100644 --- a/README +++ b/README @@ -276,6 +276,11 @@ Verilog Attributes and non-standard features for everything that comes after the {* ... *} statement. (Reset by adding an empty {* *} statement.) +- Modules can be declared with "module mod_name(...);" (with three dots + instead of a list of moudle ports). With this syntax it is sufficient + to simply declare a module port as 'input' or 'output' in the module + body. + - Sized constants (the syntax 's?[bodh]) support constant expressions as . If the expresion is not a simple identifier, it must be put in parentheses. Examples: WIDTH'd42, (4+2)'b101010 diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index c62e761e..1e0168a5 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()); From 0bb694221832f250977437f29365bc5e17c4cd09 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:33:51 +0200 Subject: [PATCH 545/750] Added "show -signed" --- passes/cmds/show.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index c15feb7b..4f6b811b 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -45,6 +45,7 @@ struct ShowWorker RTLIL::Module *module; uint32_t currentColor; bool genWidthLabels; + bool genSignedLabels; bool stretchIO; bool enumerateIds; bool abbreviateIds; @@ -354,7 +355,9 @@ struct ShowWorker std::string label_string = "{{"; for (auto &p : in_ports) - label_string += stringf(" %s|", id2num(p), escape(p.str())); + label_string += stringf(" %s%s|", id2num(p), escape(p.str()), + genSignedLabels && it.second->hasParam(p.str() + "_SIGNED") && + it.second->getParam(p.str() + "_SIGNED").as_bool() ? "*" : ""); if (label_string[label_string.size()-1] == '|') label_string = label_string.substr(0, label_string.size()-1); @@ -487,12 +490,12 @@ struct ShowWorker fprintf(f, "}\n"); } - ShowWorker(FILE *f, RTLIL::Design *design, std::vector &libs, uint32_t colorSeed, - bool genWidthLabels, bool stretchIO, bool enumerateIds, bool abbreviateIds, bool notitle, + ShowWorker(FILE *f, RTLIL::Design *design, std::vector &libs, uint32_t colorSeed, bool genWidthLabels, + bool genSignedLabels, bool stretchIO, bool enumerateIds, bool abbreviateIds, bool notitle, const std::vector> &color_selections, const std::vector> &label_selections) : f(f), design(design), currentColor(colorSeed), genWidthLabels(genWidthLabels), - stretchIO(stretchIO), enumerateIds(enumerateIds), abbreviateIds(abbreviateIds), + genSignedLabels(genSignedLabels), stretchIO(stretchIO), enumerateIds(enumerateIds), abbreviateIds(abbreviateIds), notitle(notitle), color_selections(color_selections), label_selections(label_selections) { ct.setup_internals(); @@ -572,6 +575,10 @@ struct ShowPass : public Pass { log(" -width\n"); log(" annotate busses with a label indicating the width of the bus.\n"); log("\n"); + log(" -signed\n"); + log(" mark ports (A, B) that are declarted as signed (using the [AB]_SIGNED\n"); + log(" cell parameter) with an asterisk next to the port name.\n"); + log("\n"); log(" -stretch\n"); log(" stretch the graph so all inputs are on the left side and all outputs\n"); log(" (including inout ports) are on the right side.\n"); @@ -610,6 +617,7 @@ struct ShowPass : public Pass { std::vector libs; uint32_t colorSeed = 0; bool flag_width = false; + bool flag_signed = false; bool flag_stretch = false; bool flag_pause = false; bool flag_enum = false; @@ -664,6 +672,10 @@ struct ShowPass : public Pass { flag_width= true; continue; } + if (arg == "-signed") { + flag_signed= true; + continue; + } if (arg == "-stretch") { flag_stretch= true; continue; @@ -727,7 +739,7 @@ struct ShowPass : public Pass { delete lib; log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str()); } - ShowWorker worker(f, design, libs, colorSeed, flag_width, flag_stretch, flag_enum, flag_abbeviate, flag_notitle, color_selections, label_selections); + ShowWorker worker(f, design, libs, colorSeed, flag_width, flag_signed, flag_stretch, flag_enum, flag_abbeviate, flag_notitle, color_selections, label_selections); fclose(f); for (auto lib : libs) From 0129d41efad623ee95878a673c1c1190261ba3ef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 08:35:51 +0200 Subject: [PATCH 546/750] Fixed AST handling of variables declared inside a functions main block --- frontends/ast/simplify.cc | 6 +++--- tests/simple/task_func.v | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 694f1d4d..20edc173 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) { diff --git a/tests/simple/task_func.v b/tests/simple/task_func.v index 8dbc90c5..51e31015 100644 --- a/tests/simple/task_func.v +++ b/tests/simple/task_func.v @@ -33,3 +33,16 @@ end endmodule + +module task_func_test02( input [7:0] din_a, input [7:0] din_b, output [7:0] dout_a); + assign dout_a = test(din_a,din_b); + function [7:0] test; + input [7:0] a; + input [7:0] b; + begin : TEST + integer i; + for (i = 0; i <= 7; i = i + 1) + test[i] = a[i] & b[i]; + end + endfunction +endmodule From 91dd87e60b120119ee34a9961a7b5f33f340282e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 12:15:53 +0200 Subject: [PATCH 547/750] 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 +- tests/simple/scopes.v | 63 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 tests/simple/scopes.v diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 83798edf..00b044bc 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 20edc173..29d00be9 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 1e0168a5..26e2ddc3 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; }; diff --git a/tests/simple/scopes.v b/tests/simple/scopes.v new file mode 100644 index 00000000..eecc1a0b --- /dev/null +++ b/tests/simple/scopes.v @@ -0,0 +1,63 @@ +module scopes_test_01(input [3:0] k, output reg [15:0] x, y); + function [15:0] func_01; + input [15:0] x, y; + begin + func_01 = x + y; + begin:blk + reg [15:0] x; + x = y; + func_01 = func_01 ^ x; + end + func_01 = func_01 ^ x; + end + endfunction + + function [15:0] func_02; + input [15:0] x, y; + begin + func_02 = x - y; + begin:blk + reg [15:0] func_02; + func_02 = 0; + end + end + endfunction + + task task_01; + input [3:0] a; + reg [15:0] y; + begin + y = a * 23; + x = x + y; + end + endtask + + task task_02; + input [3:0] a; + begin:foo + reg [15:0] x, z; + x = y; + begin:bar + reg [15:0] x; + x = 77 + a; + z = -x; + end + y = x ^ z; + end + endtask + + always @* begin + x = func_01(11, 22); + y = func_02(33, 44); + task_01(k); + task_02(k); + begin:foo + reg [15:0] y; + y = x; + y = y + k; + x = y; + end + x = func_01(y, x); + y = func_02(y, x); + end +endmodule From 1c182cedb7a42174d6eafbbc84951a27775da15d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 12:49:53 +0200 Subject: [PATCH 548/750] Added mux support to wreduce command --- passes/cmds/wreduce.cc | 118 ++++++++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 36 deletions(-) diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index 9cef14f4..b90843ef 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -28,48 +28,23 @@ using namespace RTLIL; PRIVATE_NAMESPACE_BEGIN +static inline std::set &operator<<(std::set &set, IdString id) { + set.insert(id); + return set; +} + struct WreduceConfig { std::set supported_cell_types; WreduceConfig() { - supported_cell_types.insert("$not"); - supported_cell_types.insert("$pos"); - supported_cell_types.insert("$bu0"); - supported_cell_types.insert("$neg"); - - supported_cell_types.insert("$and"); - supported_cell_types.insert("$or"); - supported_cell_types.insert("$xor"); - supported_cell_types.insert("$xnor"); - - supported_cell_types.insert("$shl"); - supported_cell_types.insert("$shr"); - supported_cell_types.insert("$sshl"); - supported_cell_types.insert("$sshr"); - supported_cell_types.insert("$shift"); - supported_cell_types.insert("$shiftx"); - - supported_cell_types.insert("$lt"); - supported_cell_types.insert("$le"); - supported_cell_types.insert("$eq"); - supported_cell_types.insert("$ne"); - supported_cell_types.insert("$eqx"); - supported_cell_types.insert("$nex"); - supported_cell_types.insert("$ge"); - supported_cell_types.insert("$gt"); - - supported_cell_types.insert("$add"); - supported_cell_types.insert("$sub"); - // supported_cell_types.insert("$mul"); - // supported_cell_types.insert("$div"); - // supported_cell_types.insert("$mod"); - // supported_cell_types.insert("$pow"); - - // supported_cell_types.insert("$mux"); - // supported_cell_types.insert("$pmux"); - // supported_cell_types.insert("$safe_pmux"); + supported_cell_types << "$not" << "$pos" << "$bu0" << "$neg"; + supported_cell_types << "$and" << "$or" << "$xor" << "$xnor"; + supported_cell_types << "$shl" << "$shr" << "$sshl" << "$sshr" << "$shift" << "$shiftx"; + supported_cell_types << "$lt" << "$le" << "$eq" << "$ne" << "$eqx" << "$nex" << "$ge" << "$gt"; + supported_cell_types << "$add" << "$sub"; // << "$mul" << "$div" << "$mod" << "$pow" + supported_cell_types << "$mux" << "$pmux" << "$safe_pmux"; } }; @@ -86,6 +61,72 @@ struct WreduceWorker WreduceWorker(WreduceConfig *config, Module *module) : config(config), module(module), mi(module) { } + void run_cell_mux(Cell *cell) + { + SigSpec sig_a = mi.sigmap(cell->getPort("\\A")); + SigSpec sig_b = mi.sigmap(cell->getPort("\\B")); + SigSpec sig_s = mi.sigmap(cell->getPort("\\S")); + SigSpec sig_y = mi.sigmap(cell->getPort("\\Y")); + std::vector bits_removed; + + for (int i = SIZE(sig_y)-1; i >= 0; i--) + { + auto info = mi.query(sig_y[i]); + if (!info->is_output && SIZE(info->ports) <= 1) { + bits_removed.push_back(Sx); + continue; + } + + SigBit ref = sig_a[i]; + for (int k = 0; k < SIZE(sig_s); k++) { + if (ref != Sx && sig_b[k*SIZE(sig_a) + i] != Sx && ref != sig_b[k*SIZE(sig_a) + i]) + goto no_match_ab; + if (sig_b[k*SIZE(sig_a) + i] != Sx) + ref = sig_b[k*SIZE(sig_a) + i]; + } + if (0) + no_match_ab: + break; + bits_removed.push_back(ref); + } + + if (!bits_removed.empty()) + { + SigSpec sig_removed; + for (int i = SIZE(bits_removed)-1; i >= 0; i--) + sig_removed.append_bit(bits_removed[i]); + + log("Removed top %d bits (of %d) from mux cell %s.%s (%s).\n", + SIZE(sig_removed), SIZE(sig_y), log_id(module), log_id(cell), log_id(cell->type)); + + int n_removed = SIZE(sig_removed); + int n_kept = SIZE(sig_y) - SIZE(sig_removed); + + SigSpec new_work_queue_bits; + new_work_queue_bits.append(sig_a.extract(n_kept, n_removed)); + new_work_queue_bits.append(sig_y.extract(n_kept, n_removed)); + + SigSpec new_sig_a = sig_a.extract(0, n_kept); + SigSpec new_sig_y = sig_y.extract(0, n_kept); + SigSpec new_sig_b; + + for (int k = 0; k < SIZE(sig_s); k++) { + new_sig_b.append(sig_b.extract(k*SIZE(sig_a), n_kept)); + new_work_queue_bits.append(sig_b.extract(k*SIZE(sig_a) + n_kept, n_removed)); + } + + for (auto bit : new_work_queue_bits) + work_queue_bits.insert(bit); + + cell->setPort("\\A", new_sig_a); + cell->setPort("\\B", new_sig_b); + cell->setPort("\\Y", new_sig_y); + cell->fixup_parameters(); + + module->connect(sig_y.extract(n_kept, n_removed), sig_removed); + } + } + void run_reduce_inport(Cell *cell, char port) { bool is_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); @@ -112,6 +153,11 @@ struct WreduceWorker if (!cell->type.in(config->supported_cell_types)) return; + if (cell->type.in("$mux", "$pmux", "$safe_pmux")) { + run_cell_mux(cell); + return; + } + if (cell->type.in("$shl", "$shr", "$sshl", "$sshr")) cell->setParam("\\B_SIGNED", false); From d3b1a29708fc9cfd793180763484125a5f978d1a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 13:11:04 +0200 Subject: [PATCH 549/750] Cleanups and improvements in wreduce pass --- passes/cmds/wreduce.cc | 128 +++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 49 deletions(-) diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index b90843ef..ce24e09b 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -61,8 +61,10 @@ struct WreduceWorker WreduceWorker(WreduceConfig *config, Module *module) : config(config), module(module), mi(module) { } - void run_cell_mux(Cell *cell) + bool run_cell_mux(Cell *cell) { + // Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused + SigSpec sig_a = mi.sigmap(cell->getPort("\\A")); SigSpec sig_b = mi.sigmap(cell->getPort("\\B")); SigSpec sig_s = mi.sigmap(cell->getPort("\\S")); @@ -90,49 +92,60 @@ struct WreduceWorker bits_removed.push_back(ref); } - if (!bits_removed.empty()) - { - SigSpec sig_removed; - for (int i = SIZE(bits_removed)-1; i >= 0; i--) - sig_removed.append_bit(bits_removed[i]); + if (bits_removed.empty()) + return false; - log("Removed top %d bits (of %d) from mux cell %s.%s (%s).\n", - SIZE(sig_removed), SIZE(sig_y), log_id(module), log_id(cell), log_id(cell->type)); + SigSpec sig_removed; + for (int i = SIZE(bits_removed)-1; i >= 0; i--) + sig_removed.append_bit(bits_removed[i]); - int n_removed = SIZE(sig_removed); - int n_kept = SIZE(sig_y) - SIZE(sig_removed); + log("Removed top %d bits (of %d) from mux cell %s.%s (%s).\n", + SIZE(sig_removed), SIZE(sig_y), log_id(module), log_id(cell), log_id(cell->type)); - SigSpec new_work_queue_bits; - new_work_queue_bits.append(sig_a.extract(n_kept, n_removed)); - new_work_queue_bits.append(sig_y.extract(n_kept, n_removed)); + int n_removed = SIZE(sig_removed); + int n_kept = SIZE(sig_y) - SIZE(sig_removed); - SigSpec new_sig_a = sig_a.extract(0, n_kept); - SigSpec new_sig_y = sig_y.extract(0, n_kept); - SigSpec new_sig_b; + SigSpec new_work_queue_bits; + new_work_queue_bits.append(sig_a.extract(n_kept, n_removed)); + new_work_queue_bits.append(sig_y.extract(n_kept, n_removed)); - for (int k = 0; k < SIZE(sig_s); k++) { - new_sig_b.append(sig_b.extract(k*SIZE(sig_a), n_kept)); - new_work_queue_bits.append(sig_b.extract(k*SIZE(sig_a) + n_kept, n_removed)); - } + SigSpec new_sig_a = sig_a.extract(0, n_kept); + SigSpec new_sig_y = sig_y.extract(0, n_kept); + SigSpec new_sig_b; - for (auto bit : new_work_queue_bits) - work_queue_bits.insert(bit); - - cell->setPort("\\A", new_sig_a); - cell->setPort("\\B", new_sig_b); - cell->setPort("\\Y", new_sig_y); - cell->fixup_parameters(); - - module->connect(sig_y.extract(n_kept, n_removed), sig_removed); + for (int k = 0; k < SIZE(sig_s); k++) { + new_sig_b.append(sig_b.extract(k*SIZE(sig_a), n_kept)); + new_work_queue_bits.append(sig_b.extract(k*SIZE(sig_a) + n_kept, n_removed)); } + + for (auto bit : new_work_queue_bits) + work_queue_bits.insert(bit); + + cell->setPort("\\A", new_sig_a); + cell->setPort("\\B", new_sig_b); + cell->setPort("\\Y", new_sig_y); + cell->fixup_parameters(); + + module->connect(sig_y.extract(n_kept, n_removed), sig_removed); + return true; } - void run_reduce_inport(Cell *cell, char port) + bool run_reduce_inport(Cell *cell, char port, int max_port_size) { bool is_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port))); + if (port == 'B' && cell->type.in("$shl", "$shr", "$sshl", "$sshr")) + is_signed = false; + int bits_removed = 0; + if (SIZE(sig) > max_port_size) { + bits_removed = SIZE(sig) - max_port_size; + for (auto bit : sig.extract(max_port_size, bits_removed)) + work_queue_bits.insert(bit); + sig = sig.extract(0, max_port_size); + } + if (is_signed) { while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == constmap(sig[SIZE(sig)-2])) work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; @@ -141,31 +154,44 @@ struct WreduceWorker work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; } - if (bits_removed) { - log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n", - bits_removed, SIZE(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type)); - cell->setPort(stringf("\\%c", port), sig); - } + if (bits_removed == 0) + return false; + + log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n", + bits_removed, SIZE(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type)); + cell->setPort(stringf("\\%c", port), sig); + return true; } - void run_cell(Cell *cell) + bool run_cell(Cell *cell) { - if (!cell->type.in(config->supported_cell_types)) - return; + bool did_something = false; - if (cell->type.in("$mux", "$pmux", "$safe_pmux")) { - run_cell_mux(cell); - return; + if (!cell->type.in(config->supported_cell_types)) + return false; + + if (cell->type.in("$mux", "$pmux", "$safe_pmux")) + return run_cell_mux(cell); + + + // Reduce size of ports A and B based on constant input bits and size of output port + + int max_port_a_size = cell->hasPort("\\A") ? SIZE(cell->getPort("\\A")) : -1; + int max_port_b_size = cell->hasPort("\\B") ? SIZE(cell->getPort("\\B")) : -1; + + if (cell->type.in("$not", "$pos", "$bu0", "$neg", "$and", "$or", "$xor", "$add", "$sub")) { + max_port_a_size = std::min(max_port_a_size, SIZE(cell->getPort("\\Y"))); + max_port_b_size = std::min(max_port_b_size, SIZE(cell->getPort("\\Y"))); } - if (cell->type.in("$shl", "$shr", "$sshl", "$sshr")) - cell->setParam("\\B_SIGNED", false); + if (max_port_a_size >= 0) + did_something = run_reduce_inport(cell, 'A', max_port_a_size) || did_something; - if (cell->hasParam("\\A_SIGNED")) - run_reduce_inport(cell, 'A'); + if (max_port_b_size >= 0) + did_something = run_reduce_inport(cell, 'B', max_port_b_size) || did_something; - if (cell->hasParam("\\B_SIGNED")) - run_reduce_inport(cell, 'B'); + + // Reduce size of port Y based on sizes for A and B and unused bits in Y SigSpec sig = mi.sigmap(cell->getPort("\\Y")); @@ -208,9 +234,13 @@ struct WreduceWorker log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", bits_removed, SIZE(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); cell->setPort("\\Y", sig); + did_something = true; } - cell->fixup_parameters(); + if (did_something) + cell->fixup_parameters(); + + return did_something; } void run() @@ -222,7 +252,7 @@ struct WreduceWorker { work_queue_bits.clear(); for (auto c : work_queue_cells) - run_cell(c); + while (run_cell(c)) { } work_queue_cells.clear(); for (auto bit : work_queue_bits) From 523df7314502e2674df5287289dcf8eb204c17ac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 14:47:03 +0200 Subject: [PATCH 550/750] Added support for truncating of wires to wreduce pass --- kernel/modtools.h | 24 +++++++++++++++-------- kernel/rtlil.cc | 30 ++++++++++++++++++++++++++++ kernel/rtlil.h | 7 +++++++ passes/cmds/wreduce.cc | 44 ++++++++++++++++++++++++++++++++++++++---- 4 files changed, 93 insertions(+), 12 deletions(-) diff --git a/kernel/modtools.h b/kernel/modtools.h index 56bc1882..fde59d14 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -59,14 +59,20 @@ struct ModIndex : public RTLIL::Monitor void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) { - for (int i = 0; i < SIZE(sig); i++) - database[sigmap(sig[i])].ports.insert(PortInfo(cell, port, i)); + for (int i = 0; i < SIZE(sig); i++) { + RTLIL::SigBit bit = sigmap(sig[i]); + if (bit.wire) + database[bit].ports.insert(PortInfo(cell, port, i)); + } } void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig) { - for (int i = 0; i < SIZE(sig); i++) - database[sigmap(sig[i])].ports.erase(PortInfo(cell, port, i)); + for (int i = 0; i < SIZE(sig); i++) { + RTLIL::SigBit bit = sigmap(sig[i]); + if (bit.wire) + database[bit].ports.erase(PortInfo(cell, port, i)); + } } const SigBitInfo &info(RTLIL::SigBit bit) @@ -83,10 +89,11 @@ struct ModIndex : public RTLIL::Monitor for (auto wire : module->wires()) if (wire->port_input || wire->port_output) for (int i = 0; i < SIZE(wire); i++) { - if (wire->port_input) - database[sigmap(RTLIL::SigBit(wire, i))].is_input = true; - if (wire->port_output) - database[sigmap(RTLIL::SigBit(wire, i))].is_output = true; + RTLIL::SigBit bit = sigmap(RTLIL::SigBit(wire, i)); + if (bit.wire && wire->port_input) + database[bit].is_input = true; + if (bit.wire && wire->port_output) + database[bit].is_output = true; } for (auto cell : module->cells()) for (auto &conn : cell->connections()) @@ -137,6 +144,7 @@ struct ModIndex : public RTLIL::Monitor { if (auto_reload_module) reload_module(); + auto it = database.find(sigmap(bit)); if (it == database.end()) return nullptr; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 792474af..8ff56451 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1071,6 +1071,36 @@ void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name) log_abort(); } +void RTLIL::Module::swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2) +{ + log_assert(wires_[w1->name] == w1); + log_assert(wires_[w2->name] == w2); + log_assert(refcount_wires_ == 0); + + wires_.erase(w1->name); + wires_.erase(w2->name); + + std::swap(w1->name, w2->name); + + wires_[w1->name] = w1; + wires_[w2->name] = w2; +} + +void RTLIL::Module::swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2) +{ + log_assert(cells_[c1->name] == c1); + log_assert(cells_[c2->name] == c2); + log_assert(refcount_cells_ == 0); + + cells_.erase(c1->name); + cells_.erase(c2->name); + + std::swap(c1->name, c2->name); + + cells_[c1->name] = c1; + cells_[c2->name] = c2; +} + static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) { if (a->port_id && !b->port_id) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8dfcbcaa..8ec59941 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -590,6 +590,10 @@ public: std::vector selected_wires() const; std::vector selected_cells() const; + template bool selected(T *member) const { + return design->selected_member(name, member->name); + } + RTLIL::Wire* wire(RTLIL::IdString id) { return wires_.count(id) ? wires_.at(id) : nullptr; } RTLIL::Cell* cell(RTLIL::IdString id) { return cells_.count(id) ? cells_.at(id) : nullptr; } @@ -604,6 +608,9 @@ public: void rename(RTLIL::Cell *cell, RTLIL::IdString new_name); void rename(RTLIL::IdString old_name, RTLIL::IdString new_name); + void swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2); + void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2); + RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other); diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index ce24e09b..27571eb0 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -21,8 +21,6 @@ #include "kernel/sigtools.h" #include "kernel/modtools.h" -#include - USING_YOSYS_NAMESPACE using namespace RTLIL; @@ -243,6 +241,14 @@ struct WreduceWorker return did_something; } + static int count_nontrivial_wire_attrs(RTLIL::Wire *w) + { + int count = w->attributes.size(); + count -= w->attributes.count("\\src"); + count -= w->attributes.count("\\unused_bits"); + return count; + } + void run() { for (auto c : module->selected_cells()) @@ -257,7 +263,32 @@ struct WreduceWorker work_queue_cells.clear(); for (auto bit : work_queue_bits) for (auto port : mi.query_ports(bit)) - work_queue_cells.insert(port.cell); + if (module->selected(port.cell)) + work_queue_cells.insert(port.cell); + } + + for (auto w : module->selected_wires()) + { + int unused_top_bits = 0; + + if (w->port_id > 0 || count_nontrivial_wire_attrs(w) > 0) + continue; + + for (int i = SIZE(w)-1; i >= 0; i--) { + SigBit bit(w, i); + auto info = mi.query(bit); + if (info && (info->is_input || info->is_output || SIZE(info->ports) > 0)) + break; + unused_top_bits++; + } + + if (0 < unused_top_bits && unused_top_bits < SIZE(w)) { + log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, SIZE(w), log_id(module), log_id(w)); + Wire *nw = module->addWire(NEW_ID, w); + nw->width = SIZE(w) - unused_top_bits; + module->connect(nw, SigSpec(w).extract(0, SIZE(nw))); + module->swap_names(w, nw); + } } } }; @@ -270,7 +301,12 @@ struct WreducePass : public Pass { log("\n"); log(" wreduce [options] [selection]\n"); log("\n"); - log("This command reduces the word size of operations.\n"); + log("This command reduces the word size of operations. For example it will replace\n"); + log("the 32 bit adders in the following code with adders of more appropriate widths:\n"); + log("\n"); + log(" module test(input [3:0] a, b, c, output [7:0] y);\n"); + log(" assign y = a + b + c + 1;\n"); + log(" endmodule\n"); log("\n"); } virtual void execute(std::vector args, Design *design) From 5b3dc07b9a571771afbe356e30046633037b9814 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 16:53:53 +0200 Subject: [PATCH 551/750] Removed old "constmap" from wreduce code --- passes/cmds/wreduce.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index 27571eb0..1d296da5 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -54,7 +54,6 @@ struct WreduceWorker std::set> work_queue_cells; std::set work_queue_bits; - SigMap constmap; WreduceWorker(WreduceConfig *config, Module *module) : config(config), module(module), mi(module) { } @@ -145,10 +144,10 @@ struct WreduceWorker } if (is_signed) { - while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == constmap(sig[SIZE(sig)-2])) + while (SIZE(sig) > 1 && sig[SIZE(sig)-1] == sig[SIZE(sig)-2]) work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; } else { - while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == S0) + while (SIZE(sig) > 1 && sig[SIZE(sig)-1] == S0) work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; } From 2501abe1ee47610e5fb2b541c1fc0c648617da20 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 19:01:41 +0200 Subject: [PATCH 552/750] Various fixes and improvements in wreduce pass --- passes/cmds/wreduce.cc | 76 ++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index 1d296da5..6723a57f 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -58,7 +58,7 @@ struct WreduceWorker WreduceWorker(WreduceConfig *config, Module *module) : config(config), module(module), mi(module) { } - bool run_cell_mux(Cell *cell) + void run_cell_mux(Cell *cell) { // Reduce size of MUX if inputs agree on a value for a bit or a output bit is unused @@ -90,12 +90,19 @@ struct WreduceWorker } if (bits_removed.empty()) - return false; + return; SigSpec sig_removed; for (int i = SIZE(bits_removed)-1; i >= 0; i--) sig_removed.append_bit(bits_removed[i]); + if (SIZE(bits_removed) == SIZE(sig_y)) { + log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + module->connect(sig_y, sig_removed); + module->remove(cell); + return; + } + log("Removed top %d bits (of %d) from mux cell %s.%s (%s).\n", SIZE(sig_removed), SIZE(sig_y), log_id(module), log_id(cell), log_id(cell->type)); @@ -124,16 +131,15 @@ struct WreduceWorker cell->fixup_parameters(); module->connect(sig_y.extract(n_kept, n_removed), sig_removed); - return true; } - bool run_reduce_inport(Cell *cell, char port, int max_port_size) + void run_reduce_inport(Cell *cell, char port, int max_port_size, bool &port_signed, bool &did_something) { - bool is_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); + port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port))); if (port == 'B' && cell->type.in("$shl", "$shr", "$sshl", "$sshr")) - is_signed = false; + port_signed = false; int bits_removed = 0; if (SIZE(sig) > max_port_size) { @@ -143,7 +149,7 @@ struct WreduceWorker sig = sig.extract(0, max_port_size); } - if (is_signed) { + if (port_signed) { while (SIZE(sig) > 1 && sig[SIZE(sig)-1] == sig[SIZE(sig)-2]) work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; } else { @@ -151,21 +157,20 @@ struct WreduceWorker work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++; } - if (bits_removed == 0) - return false; - - log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n", - bits_removed, SIZE(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type)); - cell->setPort(stringf("\\%c", port), sig); - return true; + if (bits_removed) { + log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n", + bits_removed, SIZE(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type)); + cell->setPort(stringf("\\%c", port), sig); + did_something = true; + } } - bool run_cell(Cell *cell) + void run_cell(Cell *cell) { bool did_something = false; if (!cell->type.in(config->supported_cell_types)) - return false; + return; if (cell->type.in("$mux", "$pmux", "$safe_pmux")) return run_cell_mux(cell); @@ -181,11 +186,14 @@ struct WreduceWorker max_port_b_size = std::min(max_port_b_size, SIZE(cell->getPort("\\Y"))); } + bool port_a_signed = false; + bool port_b_signed = false; + if (max_port_a_size >= 0) - did_something = run_reduce_inport(cell, 'A', max_port_a_size) || did_something; + run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something); if (max_port_b_size >= 0) - did_something = run_reduce_inport(cell, 'B', max_port_b_size) || did_something; + run_reduce_inport(cell, 'B', max_port_b_size, port_b_signed, did_something); // Reduce size of port Y based on sizes for A and B and unused bits in Y @@ -193,15 +201,19 @@ struct WreduceWorker SigSpec sig = mi.sigmap(cell->getPort("\\Y")); int bits_removed = 0; - while (SIZE(sig) > 0) - { - auto info = mi.query(sig[SIZE(sig)-1]); + if (port_a_signed && cell->type == "$shr") { + // do not reduce size of output on $shr cells with signed A inputs + } else { + while (SIZE(sig) > 0) + { + auto info = mi.query(sig[SIZE(sig)-1]); - if (info->is_output || SIZE(info->ports) > 1) - break; + if (info->is_output || SIZE(info->ports) > 1) + break; - sig.remove(SIZE(sig)-1); - bits_removed++; + sig.remove(SIZE(sig)-1); + bits_removed++; + } } if (cell->type.in("$pos", "$bu0", "$add", "$mul", "$and", "$or", "$xor")) @@ -227,6 +239,12 @@ struct WreduceWorker } } + if (SIZE(sig) == 0) { + log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); + module->remove(cell); + return; + } + if (bits_removed) { log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n", bits_removed, SIZE(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type)); @@ -234,10 +252,10 @@ struct WreduceWorker did_something = true; } - if (did_something) + if (did_something) { cell->fixup_parameters(); - - return did_something; + run_cell(cell); + } } static int count_nontrivial_wire_attrs(RTLIL::Wire *w) @@ -257,7 +275,7 @@ struct WreduceWorker { work_queue_bits.clear(); for (auto c : work_queue_cells) - while (run_cell(c)) { } + run_cell(c); work_queue_cells.clear(); for (auto bit : work_queue_bits) From b4f10e342cf400bd2f392a588f28de069ba0f9d8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Aug 2014 14:31:38 +0200 Subject: [PATCH 553/750] Various improvements in memory_dff pass --- passes/memory/memory_dff.cc | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index e92d726c..cdd0b85e2 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -28,7 +28,7 @@ static void normalize_sig(RTLIL::Module *module, RTLIL::SigSpec &sig) sig.replace(conn.first, conn.second); } -static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, bool after = false) +static bool find_sig_before_dff(RTLIL::Module *module, std::vector &dff_cells, RTLIL::SigSpec &sig, RTLIL::SigSpec &clk, bool &clk_polarity, bool after = false) { normalize_sig(module, sig); @@ -37,11 +37,8 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI if (bit.wire == NULL) continue; - for (auto cell : module->cells()) + for (auto cell : dff_cells) { - if (cell->type != "$dff") - continue; - if (clk != RTLIL::SigSpec(RTLIL::State::Sx)) { if (cell->getPort("\\CLK") != clk) continue; @@ -69,7 +66,7 @@ static bool find_sig_before_dff(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLI return true; } -static void handle_wr_cell(RTLIL::Module *module, RTLIL::Cell *cell) +static void handle_wr_cell(RTLIL::Module *module, std::vector &dff_cells, RTLIL::Cell *cell) { log("Checking cell `%s' in module `%s': ", cell->name.c_str(), module->name.c_str()); @@ -77,19 +74,19 @@ static void handle_wr_cell(RTLIL::Module *module, RTLIL::Cell *cell) bool clk_polarity = 0; RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR"); - if (!find_sig_before_dff(module, sig_addr, clk, clk_polarity)) { + if (!find_sig_before_dff(module, dff_cells, sig_addr, clk, clk_polarity)) { log("no (compatible) $dff for address input found.\n"); return; } RTLIL::SigSpec sig_data = cell->getPort("\\DATA"); - if (!find_sig_before_dff(module, sig_data, clk, clk_polarity)) { + if (!find_sig_before_dff(module, dff_cells, sig_data, clk, clk_polarity)) { log("no (compatible) $dff for data input found.\n"); return; } RTLIL::SigSpec sig_en = cell->getPort("\\EN"); - if (!find_sig_before_dff(module, sig_en, clk, clk_polarity)) { + if (!find_sig_before_dff(module, dff_cells, sig_en, clk, clk_polarity)) { log("no (compatible) $dff for enable input found.\n"); return; } @@ -102,6 +99,7 @@ static void handle_wr_cell(RTLIL::Module *module, RTLIL::Cell *cell) cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity); log("merged $dff to cell.\n"); + return; } log("no (compatible) $dff found.\n"); @@ -125,7 +123,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) } } -static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) +static void handle_rd_cell(RTLIL::Module *module, std::vector &dff_cells, RTLIL::Cell *cell) { log("Checking cell `%s' in module `%s': ", cell->name.c_str(), module->name.c_str()); @@ -133,7 +131,7 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx); RTLIL::SigSpec sig_data = cell->getPort("\\DATA"); - if (find_sig_before_dff(module, sig_data, clk_data, clk_polarity, true) && + if (find_sig_before_dff(module, dff_cells, sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx)) { disconnect_dff(module, sig_data); @@ -148,7 +146,7 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx); RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR"); - if (find_sig_before_dff(module, sig_addr, clk_addr, clk_polarity) && + if (find_sig_before_dff(module, dff_cells, sig_addr, clk_addr, clk_polarity) && clk_addr != RTLIL::SigSpec(RTLIL::State::Sx)) { cell->setPort("\\CLK", clk_addr); @@ -163,15 +161,19 @@ static void handle_rd_cell(RTLIL::Module *module, RTLIL::Cell *cell) log("no (compatible) $dff found.\n"); } -static void handle_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_wr_only) +static void handle_module(RTLIL::Module *module, bool flag_wr_only) { - for (auto cell : module->cells()) { - if (!design->selected(module, cell)) - continue; + std::vector dff_cells; + + for (auto cell : module->cells()) + if (cell->type == "$dff") + dff_cells.push_back(cell); + + for (auto cell : module->selected_cells()) { if (cell->type == "$memwr" && !cell->parameters["\\CLK_ENABLE"].as_bool()) - handle_wr_cell(module, cell); + handle_wr_cell(module, dff_cells, cell); if (!flag_wr_only && cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool()) - handle_rd_cell(module, cell); + handle_rd_cell(module, dff_cells, cell); } } @@ -207,9 +209,8 @@ struct MemoryDffPass : public Pass { } extra_args(args, argidx, design); - for (auto mod : design->modules()) - if (design->selected(mod)) - handle_module(design, mod, flag_wr_only); + for (auto mod : design->selected_modules()) + handle_module(mod, flag_wr_only); } } MemoryDffPass; From d259abbda2b9d568228dc8d0bed2d0b0d88d7b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Aug 2014 15:43:46 +0200 Subject: [PATCH 554/750] Added AST_MULTIRANGE (arrays with more than 1 dimension) --- README | 1 - frontends/ast/ast.cc | 7 +++++ frontends/ast/ast.h | 4 +++ frontends/ast/simplify.cc | 52 +++++++++++++++++++++++++++++++++++++- frontends/verilog/parser.y | 22 +++++++++++++--- 5 files changed, 80 insertions(+), 6 deletions(-) diff --git a/README b/README index 63d69229..0c8425f3 100644 --- a/README +++ b/README @@ -326,7 +326,6 @@ Other Unsorted TODOs - Implement missing Verilog 2005 features: - - Multi-dimensional arrays - Support for real (float) const. expressions and parameters - ROM modeling using $readmemh/$readmemb in "initial" blocks - Ignore what needs to be ignored (e.g. drive and charge strengths) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5815fb0d..f18124e2 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 00b044bc..5fb1f0a7 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 29d00be9..39c47262 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 26e2ddc3..95d7f393 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; }; From 312ee00c9e279a91f336acef26dd064c25f42ed5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:14:38 +0200 Subject: [PATCH 555/750] Added adff2dff.v (for techmap -share_map) --- techlibs/common/Makefile.inc | 6 +++++- techlibs/common/adff2dff.v | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 techlibs/common/adff2dff.v diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 2be27b92..461c1cb4 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -5,7 +5,7 @@ techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib. $(P) cat techlibs/common/simlib.v techlibs/common/simcells.v | $(SED) -rf techlibs/common/blackbox.sed > techlibs/common/blackbox.v.new $(Q) mv techlibs/common/blackbox.v.new techlibs/common/blackbox.v -EXTRA_TARGETS += share/simlib.v share/simcells.v share/techmap.v share/blackbox.v share/pmux2mux.v +EXTRA_TARGETS += share/simlib.v share/simcells.v share/techmap.v share/blackbox.v share/pmux2mux.v share/adff2dff.v share/simlib.v: techlibs/common/simlib.v $(P) mkdir -p share @@ -27,3 +27,7 @@ share/pmux2mux.v: techlibs/common/pmux2mux.v $(P) mkdir -p share $(Q) cp techlibs/common/pmux2mux.v share/pmux2mux.v +share/adff2dff.v: techlibs/common/adff2dff.v + $(P) mkdir -p share + $(Q) cp techlibs/common/adff2dff.v share/adff2dff.v + diff --git a/techlibs/common/adff2dff.v b/techlibs/common/adff2dff.v new file mode 100644 index 00000000..86744d41 --- /dev/null +++ b/techlibs/common/adff2dff.v @@ -0,0 +1,27 @@ +(* techmap_celltype = "$adff" *) +module adff2dff (CLK, ARST, D, Q); + parameter WIDTH = 1; + parameter CLK_POLARITY = 1; + parameter ARST_POLARITY = 1; + parameter ARST_VALUE = 0; + + input CLK, ARST; + input [WIDTH-1:0] D; + output reg [WIDTH-1:0] Q; + wire reg [WIDTH-1:0] NEXT_Q; + + wire [1023:0] _TECHMAP_DO_ = "proc;;"; + + always @* + if (ARST == ARST_POLARITY) + NEXT_Q <= ARST_VALUE; + else + NEXT_Q <= D; + + if (CLK_POLARITY) + always @(posedge CLK) + Q <= NEXT_Q; + else + always @(negedge CLK) + Q <= NEXT_Q; +endmodule From 2dc33337346ea53a654af3d80bdf056c7ccfa43c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:41:27 +0200 Subject: [PATCH 556/750] Also allow "module foobar(input foo, output bar, ...);" syntax --- frontends/verilog/parser.y | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 95d7f393..f619d3c2 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: { From c55eb8f8a6c83514c5d46c6992c6c6fa1069a889 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:42:35 +0200 Subject: [PATCH 557/750] Use "-keepdc" in "miter -equiv -flatten" --- passes/sat/miter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index e51c92f9..b3adefb9 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -251,7 +251,7 @@ static void create_miter_equiv(struct Pass *that, std::vector args, if (flag_flatten) { log_push(); - Pass::call_on_module(design, miter_module, "flatten; opt_const -undriven;;"); + Pass::call_on_module(design, miter_module, "flatten; opt_const -keepdc -undriven;;"); log_pop(); } } @@ -285,7 +285,7 @@ struct MiterPass : public Pass { log(" also create an 'assert' cell that checks if trigger is always low.\n"); log("\n"); log(" -flatten\n"); - log(" call 'flatten; opt_const -undriven;;' on the miter circuit.\n"); + log(" call 'flatten; opt_const -keepdc -undriven;;' on the miter circuit.\n"); log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) From 0b8b8d41eb07fd048cbe68acfe4b724e314bbb41 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 22:37:01 +0200 Subject: [PATCH 558/750] Fixed build with gcc-4.6 --- CHECKLISTS | 2 +- Makefile | 12 ++++++------ kernel/modtools.h | 2 +- kernel/register.h | 4 ++-- kernel/yosys.h | 8 ++++++++ passes/cmds/trace.cc | 12 ++++++------ 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/CHECKLISTS b/CHECKLISTS index 3a06e61e..4a421651 100644 --- a/CHECKLISTS +++ b/CHECKLISTS @@ -20,7 +20,7 @@ Update the CHANGELOG file: vi CHANGELOG -Run all tests with "make config-{clang-debug,gcc-debug,gcc-4.7,release}": +Run all tests with "make config-{clang-debug,gcc-debug,gcc-4.6,release}": cd ~yosys make clean diff --git a/Makefile b/Makefile index 41569f6c..cd43e53b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CONFIG := clang # CONFIG := gcc -# CONFIG := gcc-4.7 +# CONFIG := gcc-4.6 # features (the more the better) ENABLE_TCL := 1 @@ -67,8 +67,8 @@ CXX = gcc CXXFLAGS += -std=gnu++0x -Os endif -ifeq ($(CONFIG),gcc-4.7) -CXX = gcc-4.7 +ifeq ($(CONFIG),gcc-4.6) +CXX = gcc-4.6 CXXFLAGS += -std=gnu++0x -Os endif @@ -282,8 +282,8 @@ config-clang: clean config-gcc: clean echo 'CONFIG := gcc' > Makefile.conf -config-gcc-4.7: clean - echo 'CONFIG := gcc-4.7' > Makefile.conf +config-gcc-4.6: clean + echo 'CONFIG := gcc-4.6' > Makefile.conf config-gprof: clean echo 'CONFIG := gcc' > Makefile.conf @@ -300,5 +300,5 @@ config-sudo: -include techlibs/*/*.d .PHONY: all top-all abc test install install-abc manual clean mrproper qtcreator -.PHONY: config-clean config-clang config-gcc config-gcc-4.7 config-gprof config-sudo +.PHONY: config-clean config-clang config-gcc config-gcc-4.6 config-gprof config-sudo diff --git a/kernel/modtools.h b/kernel/modtools.h index fde59d14..58cdd5b0 100644 --- a/kernel/modtools.h +++ b/kernel/modtools.h @@ -102,7 +102,7 @@ struct ModIndex : public RTLIL::Monitor auto_reload_module = false; } - virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) override + virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) OVERRIDE { if (auto_reload_module) reload_module(); diff --git a/kernel/register.h b/kernel/register.h index 93a3308a..d7e4281c 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -77,7 +77,7 @@ struct Frontend : Pass Frontend(std::string name, std::string short_help = "** document me **"); virtual void run_register(); virtual ~Frontend(); - virtual void execute(std::vector args, RTLIL::Design *design) override final; + virtual void execute(std::vector args, RTLIL::Design *design) OVERRIDE FINAL; virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; static std::vector next_args; @@ -93,7 +93,7 @@ struct Backend : Pass Backend(std::string name, std::string short_help = "** document me **"); virtual void run_register(); virtual ~Backend(); - virtual void execute(std::vector args, RTLIL::Design *design) override final; + virtual void execute(std::vector args, RTLIL::Design *design) OVERRIDE FINAL; virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; void extra_args(FILE *&f, std::string &filename, std::vector args, size_t argidx); diff --git a/kernel/yosys.h b/kernel/yosys.h index f9bbc0e4..e12069b4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -64,6 +64,14 @@ # define USING_YOSYS_NAMESPACE #endif +#if __cplusplus >= 201103L +# define OVERRIDE override +# define FINAL final +#else +# define OVERRIDE +# define FINAL +#endif + YOSYS_NAMESPACE_BEGIN namespace RTLIL { diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index 6a5ea346..09293a86 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -24,34 +24,34 @@ PRIVATE_NAMESPACE_BEGIN struct TraceMonitor : public RTLIL::Monitor { - virtual void notify_module_add(RTLIL::Module *module) override + virtual void notify_module_add(RTLIL::Module *module) OVERRIDE { log("#TRACE# Module add: %s\n", log_id(module)); } - virtual void notify_module_del(RTLIL::Module *module) override + virtual void notify_module_del(RTLIL::Module *module) OVERRIDE { log("#TRACE# Module delete: %s\n", log_id(module)); } - virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) override + virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) OVERRIDE { log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig)); } - virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) override + virtual void notify_connect(RTLIL::Module *module, const RTLIL::SigSig &sigsig) OVERRIDE { log("#TRACE# Connection in module %s: %s = %s\n", log_id(module), log_signal(sigsig.first), log_signal(sigsig.second)); } - virtual void notify_connect(RTLIL::Module *module, const std::vector &sigsig_vec) override + virtual void notify_connect(RTLIL::Module *module, const std::vector &sigsig_vec) OVERRIDE { log("#TRACE# New connections in module %s:\n", log_id(module)); for (auto &sigsig : sigsig_vec) log("## %s = %s\n", log_signal(sigsig.first), log_signal(sigsig.second)); } - virtual void notify_blackout(RTLIL::Module *module) override + virtual void notify_blackout(RTLIL::Module *module) OVERRIDE { log("#TRACE# Blackout in module %s:\n", log_id(module)); } From 622ebab6710815324fa7250554b56f673862b479 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 13:11:54 +0200 Subject: [PATCH 559/750] Added "sat -prove-skip" --- passes/sat/sat.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index fd3d405a..c6da4bb4 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -917,6 +917,9 @@ struct SatPass : public Pass { log(" -prove-asserts\n"); log(" Prove that all asserts in the design hold.\n"); log("\n"); + log(" -prove-skip \n"); + log(" Do not enforce the prove-condition for the first time steps.\n"); + log("\n"); log(" -maxsteps \n"); log(" Set a maximum length for the induction.\n"); log("\n"); @@ -945,7 +948,7 @@ struct SatPass : public Pass { std::map>> sets_at; std::map> unsets_at, sets_def_at, sets_any_undef_at, sets_all_undef_at; std::vector shows, sets_def, sets_any_undef, sets_all_undef; - int loopcount = 0, seq_len = 0, maxsteps = 0, initsteps = 0, timeout = 0; + int loopcount = 0, seq_len = 0, maxsteps = 0, initsteps = 0, timeout = 0, prove_skip = 0; bool verify = false, fail_on_timeout = false, enable_undef = false, set_def_inputs = false; bool ignore_div_by_zero = false, set_init_undef = false, set_init_zero = false, max_undef = false; bool tempinduct = false, prove_asserts = false, show_inputs = false, show_outputs = false; @@ -1059,6 +1062,10 @@ struct SatPass : public Pass { prove_asserts = true; continue; } + if (args[argidx] == "-prove-skip" && argidx+1 < args.size()) { + prove_skip = atoi(args[++argidx].c_str()); + continue; + } if (args[argidx] == "-seq" && argidx+1 < args.size()) { seq_len = atoi(args[++argidx].c_str()); continue; @@ -1154,6 +1161,12 @@ struct SatPass : public Pass { if (!prove.size() && !prove_x.size() && !prove_asserts && tempinduct) log_cmd_error("Got -tempinduct but nothing to prove!\n"); + if (prove_skip && tempinduct) + log_cmd_error("Options -prove-skip and -tempinduct don't work with each other.\n"); + + if (prove_skip >= seq_len && prove_skip > 0) + log_cmd_error("The value of -prove-skip must be smaller than the one of -seq.\n"); + if (set_init_undef + set_init_zero + set_init_def > 1) log_cmd_error("The options -set-init-undef, -set-init-def, and -set-init-zero are exclusive!\n"); @@ -1359,7 +1372,8 @@ struct SatPass : public Pass { for (int timestep = 1; timestep <= seq_len; timestep++) { sathelper.setup(timestep); if (sathelper.prove.size() || sathelper.prove_x.size() || sathelper.prove_asserts) - prove_bits.push_back(sathelper.setup_proof(timestep)); + if (timestep > prove_skip) + prove_bits.push_back(sathelper.setup_proof(timestep)); } if (sathelper.prove.size() || sathelper.prove_x.size() || sathelper.prove_asserts) sathelper.ez.assume(sathelper.ez.NOT(sathelper.ez.expression(ezSAT::OpAnd, prove_bits))); From c07774b0b674805014b3ea16b28a01d40ba83d11 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 13:12:18 +0200 Subject: [PATCH 560/750] Added FSM test bench --- tests/fsm/generate.py | 83 +++++++++++++++++++++++++++++++++++++++++++ tests/fsm/run-test.sh | 30 ++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 tests/fsm/generate.py create mode 100755 tests/fsm/run-test.sh diff --git a/tests/fsm/generate.py b/tests/fsm/generate.py new file mode 100644 index 00000000..0d000f04 --- /dev/null +++ b/tests/fsm/generate.py @@ -0,0 +1,83 @@ +#!/usr/bin/python + +from __future__ import division +from __future__ import print_function + +import sys +import random +from contextlib import contextmanager + +@contextmanager +def redirect_stdout(new_target): + old_target, sys.stdout = sys.stdout, new_target + try: + yield new_target + finally: + sys.stdout = old_target + +def random_expr(variables): + c = random.choice(['bin', 'uni', 'var', 'const']) + if c == 'bin': + op = random.choice(['+', '-', '*', '<', '<=', '==', '!=', '>=', '>', '<<', '>>', '<<<', '>>>', '|', '&', '^', '~^', '||', '&&']) + return "(%s %s %s)" % (random_expr(variables), op, random_expr(variables)) + if c == 'uni': + op = random.choice(['+', '-', '~', '|', '&', '^', '~^', '!', '$signed', '$unsigned']) + return "%s(%s)" % (op, random_expr(variables)) + if c == 'var': + return random.choice(variables) + if c == 'const': + bits = random.randint(1, 32) + return "%d'd%s" % (bits, random.randint(0, 2**bits-1)) + raise AssertionError + +for idx in range(100): + with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): + print('module uut_%05d(clk, rst, a, b, c, x, y, z);' % (idx)) + print(' input clk, rst;') + variables=['a', 'b', 'c', 'x', 'y', 'z'] + print(' input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 31))) + print(' input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 31))) + print(' input%s [%d:0] c;' % (random.choice(['', ' signed']), random.randint(0, 31))) + print(' output reg%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 31))) + print(' output reg%s [%d:0] y;' % (random.choice(['', ' signed']), random.randint(0, 31))) + print(' output reg%s [%d:0] z;' % (random.choice(['', ' signed']), random.randint(0, 31))) + print(' reg [15:0] state;') + states=[] + for i in range(random.randint(2, 10)): + n = random.randint(0, 2**16-1) + if n not in states: + states.append(n) + print(' always @(posedge clk) begin') + print(' if (rst) begin') + print(' x <= %d;' % random.randint(0, 2**31-1)) + print(' y <= %d;' % random.randint(0, 2**31-1)) + print(' z <= %d;' % random.randint(0, 2**31-1)) + print(' state <= %d;' % random.choice(states)) + print(' end else begin') + print(' case (state)') + for state in states: + print(' %d: begin' % state) + for var in ('x', 'y', 'z'): + print(' %s <= %s;' % (var, random_expr(variables))) + next_states = states[:] + for i in range(random.randint(0, len(states))): + next_state = random.choice(next_states) + next_states.remove(next_state) + print(' if ((%s) %s (%s)) state <= %s;' % (random_expr(variables), + random.choice(['<', '<=', '>=', '>']), random_expr(variables), next_state)) + print(' end') + print(' endcase') + print(' end') + print(' end') + print('endmodule') + with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): + print('read_verilog temp/uut_%05d.v' % idx) + print('proc;;') + print('copy uut_%05d gold' % idx) + print('rename uut_%05d gate' % idx) + print('cd gate') + print('opt; wreduce; share; opt; fsm;;') + print('cd ..') + print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') + print('sat -verify -seq 5 -set-at 1 in_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter') + diff --git a/tests/fsm/run-test.sh b/tests/fsm/run-test.sh new file mode 100755 index 00000000..697ed935 --- /dev/null +++ b/tests/fsm/run-test.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# run this test many times: +# time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' + +set -e + +rm -rf temp +mkdir -p temp +echo "generating tests.." +python generate.py + +{ + all_targets="all_targets:" + echo "all: all_targets" + for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do + idx=$( printf "%05d" $i ) + echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v" + echo " @echo -n '[$i]'" + echo " @../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys" + all_targets="$all_targets temp/uut_${idx}.log" + done + echo "$all_targets" +} > temp/makefile + +echo "running tests.." +${MAKE:-make} -f temp/makefile +echo + +exit 0 From 7c94024fc32778cb6c789fc46a7bfbbcc7109e89 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 13:47:20 +0200 Subject: [PATCH 561/750] Fixed fsm_extract for wreduced muxes --- passes/fsm/fsm_extract.cc | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 5e71c1f0..7533b4a3 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -52,33 +52,50 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL std::set cellport_list; sig2driver.find(sig, cellport_list); - for (auto &cellport : cellport_list) { + for (auto &cellport : cellport_list) + { RTLIL::Cell *cell = module->cells_.at(cellport.first); if ((cell->type != "$mux" && cell->type != "$pmux" && cell->type != "$safe_pmux") || cellport.second != "\\Y") { log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); return false; } + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B")); RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S")); + RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y")); + + RTLIL::SigSpec sig_aa = sig; + sig_aa.replace(sig_y, sig_a); + + RTLIL::SigSpec sig_bb; + for (int i = 0; i < SIZE(sig_b)/SIZE(sig_a); i++) { + RTLIL::SigSpec s = sig; + s.replace(sig_y, sig_b.extract(i*SIZE(sig_a), SIZE(sig_a))); + sig_bb.append(s); + } + if (reset_state && RTLIL::SigSpec(*reset_state).is_fully_undef()) do { - if (sig_a.is_fully_def()) - *reset_state = sig_a.as_const(); - else if (sig_b.is_fully_def()) - *reset_state = sig_b.as_const(); + if (sig_aa.is_fully_def()) + *reset_state = sig_aa.as_const(); + else if (sig_bb.is_fully_def()) + *reset_state = sig_bb.as_const(); else break; log(" found reset state: %s (guessed from mux tree)\n", log_signal(*reset_state)); } while (0); + if (ctrl.extract(sig_s).size() == 0) { log(" found ctrl input: %s\n", log_signal(sig_s)); ctrl.append(sig_s); } - if (!find_states(sig_a, dff_out, ctrl, states)) + + if (!find_states(sig_aa, dff_out, ctrl, states)) return false; - for (int i = 0; i < sig_b.size()/sig_a.size(); i++) { - if (!find_states(sig_b.extract(i*sig_a.size(), sig_a.size()), dff_out, ctrl, states)) + + for (int i = 0; i < SIZE(sig_bb)/SIZE(sig_aa); i++) { + if (!find_states(sig_bb.extract(i*SIZE(sig_aa), SIZE(sig_aa)), dff_out, ctrl, states)) return false; } } From cb6ca08a53bfaa1b76798e6220bb1b267d49b235 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:24:09 +0200 Subject: [PATCH 562/750] Fixed sharing of reduce operator --- passes/sat/share.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 0c88b4d3..7141cea2 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -252,6 +252,19 @@ struct ShareWorker if (config.generic_uni_ops.count(c1->type)) { + if (c1->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool") && c1->getParam("\\A_WIDTH").as_int() != c2->getParam("\\A_WIDTH").as_int()) + { + RTLIL::SigBit extbit = c1->type == "$reduce_and" ? RTLIL::State::S1 : RTLIL::State::S0; + while (c1->getParam("\\A_WIDTH").as_int() < c2->getParam("\\A_WIDTH").as_int()) { + c1->setParam("\\A_WIDTH", c1->getParam("\\A_WIDTH").as_int() + 1); + c1->setPort("\\A", {extbit, c1->getPort("\\A")}); + } + while (c2->getParam("\\A_WIDTH").as_int() < c1->getParam("\\A_WIDTH").as_int()) { + c2->setParam("\\A_WIDTH", c2->getParam("\\A_WIDTH").as_int() + 1); + c2->setPort("\\A", {extbit, c2->getPort("\\A")}); + } + } + if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; From 7067c43ec09cca176ad72378aa9ad868171c2471 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:49:06 +0200 Subject: [PATCH 563/750] Fixed "fsm -export" --- passes/fsm/fsm.cc | 6 +++--- passes/fsm/fsm_export.cc | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/passes/fsm/fsm.cc b/passes/fsm/fsm.cc index 13e90910..2fae7609 100644 --- a/passes/fsm/fsm.cc +++ b/passes/fsm/fsm.cc @@ -127,12 +127,12 @@ struct FsmPass : public Pass { Pass::call(design, "fsm_recode" + fm_set_fsm_file_opt + encoding_opt); Pass::call(design, "fsm_info"); - if (!flag_nomap) - Pass::call(design, "fsm_map"); - if (flag_export) Pass::call(design, "fsm_export"); + if (!flag_nomap) + Pass::call(design, "fsm_map"); + log_pop(); } } FsmPass; diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc index cb762dc1..b4a6b3f7 100644 --- a/passes/fsm/fsm_export.cc +++ b/passes/fsm/fsm_export.cc @@ -56,13 +56,12 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st attr_it = cell->attributes.find("\\fsm_export"); if (!filename.empty()) { - kiss_name.assign(filename); + kiss_name.assign(filename); } else if (attr_it != cell->attributes.end() && attr_it->second.decode_string() != "") { kiss_name.assign(attr_it->second.decode_string()); } else { - kiss_name.assign(module->name.str()); - kiss_name.append('-' + cell->name.str() + ".kiss2"); + kiss_name.assign(log_id(module) + std::string("-") + log_id(cell) + ".kiss2"); } log("\n"); From 58ac605470aed3b2a537b4f99ac17a199f8b5233 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:55:11 +0200 Subject: [PATCH 564/750] Another fsm_extract bugfix --- passes/fsm/fsm_extract.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 7533b4a3..ebe3073d 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -231,6 +231,10 @@ static void extract_fsm(RTLIL::Wire *wire) log(" fsm extraction failed: state selection tree is not closed.\n"); return; } + if (SIZE(states) <= 1) { + log(" fsm extraction failed: at least two states are required.\n"); + return; + } // find control outputs // (add the state signals to the list of control outputs. if everything goes right, this signals From 51aa5544fbda97c6b49bfba55696083ba47d4cef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:30:45 +0200 Subject: [PATCH 565/750] Improved FSM tests --- Makefile | 1 + tests/fsm/.gitignore | 1 + tests/fsm/generate.py | 4 ++-- tests/fsm/run-test.sh | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 tests/fsm/.gitignore diff --git a/Makefile b/Makefile index cd43e53b..0e3a88a7 100644 --- a/Makefile +++ b/Makefile @@ -218,6 +218,7 @@ test: $(TARGETS) $(EXTRA_TARGETS) +cd tests/asicworld && bash run-test.sh +cd tests/realmath && bash run-test.sh +cd tests/share && bash run-test.sh + +cd tests/fsm && bash run-test.sh +cd tests/techmap && bash run-test.sh +cd tests/memories && bash run-test.sh +cd tests/various && bash run-test.sh diff --git a/tests/fsm/.gitignore b/tests/fsm/.gitignore new file mode 100644 index 00000000..9c595a6f --- /dev/null +++ b/tests/fsm/.gitignore @@ -0,0 +1 @@ +temp diff --git a/tests/fsm/generate.py b/tests/fsm/generate.py index 0d000f04..722bd62a 100644 --- a/tests/fsm/generate.py +++ b/tests/fsm/generate.py @@ -30,7 +30,7 @@ def random_expr(variables): return "%d'd%s" % (bits, random.randint(0, 2**bits-1)) raise AssertionError -for idx in range(100): +for idx in range(50): with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): print('module uut_%05d(clk, rst, a, b, c, x, y, z);' % (idx)) print(' input clk, rst;') @@ -79,5 +79,5 @@ for idx in range(100): print('opt; wreduce; share; opt; fsm;;') print('cd ..') print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') - print('sat -verify -seq 5 -set-at 1 in_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter') + print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 in_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter') diff --git a/tests/fsm/run-test.sh b/tests/fsm/run-test.sh index 697ed935..f5299c09 100755 --- a/tests/fsm/run-test.sh +++ b/tests/fsm/run-test.sh @@ -18,6 +18,7 @@ python generate.py echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v" echo " @echo -n '[$i]'" echo " @../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys" + echo " @grep -q 'SAT proof finished' temp/uut_${idx}.log && echo -n K || echo -n T" all_targets="$all_targets temp/uut_${idx}.log" done echo "$all_targets" From 2faef8973830e553b1730c07d327c8d76d412e1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 9 Aug 2014 14:49:51 +0200 Subject: [PATCH 566/750] Some improvements in fsm_opt and fsm_map for FSM with unreachable states --- passes/fsm/fsm_map.cc | 109 ++++++++++++++++++++++-------------------- passes/fsm/fsm_opt.cc | 44 +++++++++++++++++ tests/fsm/run-test.sh | 3 +- 3 files changed, 104 insertions(+), 52 deletions(-) diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 99b736c1..b3750de0 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -207,65 +207,72 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) // generate next_state signal - RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size()); - - for (size_t i = 0; i < fsm_data.state_table.size(); i++) + if (SIZE(fsm_data.state_table) == 1) { - std::map> pattern_cache; - std::set fullstate_cache; - - for (size_t j = 0; j < fsm_data.state_table.size(); j++) - fullstate_cache.insert(j); - - for (auto &tr : fsm_data.transition_table) { - if (tr.state_out == int(i)) - pattern_cache[tr.ctrl_in].insert(tr.state_in); - else - fullstate_cache.erase(tr.state_in); - } - - implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec(next_state_onehot, i)); - } - - if (encoding_is_onehot) - { - RTLIL::SigSpec next_state_sig(RTLIL::State::Sm, next_state_wire->width); - for (size_t i = 0; i < fsm_data.state_table.size(); i++) { - RTLIL::Const state = fsm_data.state_table[i]; - int bit_idx = -1; - for (size_t j = 0; j < state.bits.size(); j++) - if (state.bits[j] == RTLIL::State::S1) - bit_idx = j; - if (bit_idx >= 0) - next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, i)); - } - log_assert(!next_state_sig.has_marked_bits()); - module->connect(RTLIL::SigSig(next_state_wire, next_state_sig)); + module->connect(next_state_wire, fsm_data.state_table.front()); } else { - RTLIL::SigSpec sig_a, sig_b, sig_s; - int reset_state = fsm_data.reset_state; - if (reset_state < 0) - reset_state = 0; + RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size()); - for (size_t i = 0; i < fsm_data.state_table.size(); i++) { - RTLIL::Const state = fsm_data.state_table[i]; - if (int(i) == fsm_data.reset_state) { - sig_a = RTLIL::SigSpec(state); - } else { - sig_b.append(RTLIL::SigSpec(state)); - sig_s.append(RTLIL::SigSpec(next_state_onehot, i)); + for (size_t i = 0; i < fsm_data.state_table.size(); i++) + { + std::map> pattern_cache; + std::set fullstate_cache; + + for (size_t j = 0; j < fsm_data.state_table.size(); j++) + fullstate_cache.insert(j); + + for (auto &tr : fsm_data.transition_table) { + if (tr.state_out == int(i)) + pattern_cache[tr.ctrl_in].insert(tr.state_in); + else + fullstate_cache.erase(tr.state_in); } + + implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec(next_state_onehot, i)); } - RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux"); - mux_cell->setPort("\\A", sig_a); - mux_cell->setPort("\\B", sig_b); - mux_cell->setPort("\\S", sig_s); - mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire)); - mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); - mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); + if (encoding_is_onehot) + { + RTLIL::SigSpec next_state_sig(RTLIL::State::Sm, next_state_wire->width); + for (size_t i = 0; i < fsm_data.state_table.size(); i++) { + RTLIL::Const state = fsm_data.state_table[i]; + int bit_idx = -1; + for (size_t j = 0; j < state.bits.size(); j++) + if (state.bits[j] == RTLIL::State::S1) + bit_idx = j; + if (bit_idx >= 0) + next_state_sig.replace(bit_idx, RTLIL::SigSpec(next_state_onehot, i)); + } + log_assert(!next_state_sig.has_marked_bits()); + module->connect(RTLIL::SigSig(next_state_wire, next_state_sig)); + } + else + { + RTLIL::SigSpec sig_a, sig_b, sig_s; + int reset_state = fsm_data.reset_state; + if (reset_state < 0) + reset_state = 0; + + for (size_t i = 0; i < fsm_data.state_table.size(); i++) { + RTLIL::Const state = fsm_data.state_table[i]; + if (int(i) == fsm_data.reset_state) { + sig_a = RTLIL::SigSpec(state); + } else { + sig_b.append(RTLIL::SigSpec(state)); + sig_s.append(RTLIL::SigSpec(next_state_onehot, i)); + } + } + + RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux"); + mux_cell->setPort("\\A", sig_a); + mux_cell->setPort("\\B", sig_b); + mux_cell->setPort("\\S", sig_s); + mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire)); + mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); + mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); + } } // Generate ctrl_out signal diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc index bcaa89bf..a0e1885e 100644 --- a/passes/fsm/fsm_opt.cc +++ b/passes/fsm/fsm_opt.cc @@ -30,6 +30,48 @@ struct FsmOpt FsmData fsm_data; RTLIL::Cell *cell; RTLIL::Module *module; + + void opt_unreachable_states() + { + while (1) + { + std::set unreachable_states; + std::vector new_transition_table; + std::vector new_state_table; + std::map old_to_new_state; + + for (int i = 0; i < SIZE(fsm_data.state_table); i++) + if (i != fsm_data.reset_state) + unreachable_states.insert(i); + + for (auto &trans : fsm_data.transition_table) + unreachable_states.erase(trans.state_out); + + if (unreachable_states.empty()) + break; + + for (int i = 0; i < SIZE(fsm_data.state_table); i++) { + if (unreachable_states.count(i)) { + log(" Removing unreachable state %s.\n", log_signal(fsm_data.state_table[i])); + continue; + } + old_to_new_state[i] = SIZE(new_state_table); + new_state_table.push_back(fsm_data.state_table[i]); + } + + for (auto trans : fsm_data.transition_table) { + if (unreachable_states.count(trans.state_in)) + continue; + trans.state_in = old_to_new_state.at(trans.state_in); + trans.state_out = old_to_new_state.at(trans.state_out); + new_transition_table.push_back(trans); + } + + new_transition_table.swap(fsm_data.transition_table); + new_state_table.swap(fsm_data.state_table); + fsm_data.reset_state = old_to_new_state.at(fsm_data.reset_state); + } + } bool signal_is_unused(RTLIL::SigSpec sig) { @@ -253,6 +295,8 @@ struct FsmOpt this->cell = cell; this->module = module; + opt_unreachable_states(); + opt_unused_outputs(); opt_alias_inputs(); diff --git a/tests/fsm/run-test.sh b/tests/fsm/run-test.sh index f5299c09..3d0ff757 100755 --- a/tests/fsm/run-test.sh +++ b/tests/fsm/run-test.sh @@ -17,7 +17,8 @@ python generate.py idx=$( printf "%05d" $i ) echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v" echo " @echo -n '[$i]'" - echo " @../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys" + echo " @../../yosys -ql temp/uut_${idx}.out temp/uut_${idx}.ys" + echo " @mv temp/uut_${idx}.out temp/uut_${idx}.log" echo " @grep -q 'SAT proof finished' temp/uut_${idx}.log && echo -n K || echo -n T" all_targets="$all_targets temp/uut_${idx}.log" done From b9811d5aff7ca31daa214386a041af0865813813 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 9 Aug 2014 15:17:54 +0200 Subject: [PATCH 567/750] Do not share any $reduce_* cells (its complicated and not worth it anyways) --- passes/sat/share.cc | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 7141cea2..065b90d3 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -252,19 +252,6 @@ struct ShareWorker if (config.generic_uni_ops.count(c1->type)) { - if (c1->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool") && c1->getParam("\\A_WIDTH").as_int() != c2->getParam("\\A_WIDTH").as_int()) - { - RTLIL::SigBit extbit = c1->type == "$reduce_and" ? RTLIL::State::S1 : RTLIL::State::S0; - while (c1->getParam("\\A_WIDTH").as_int() < c2->getParam("\\A_WIDTH").as_int()) { - c1->setParam("\\A_WIDTH", c1->getParam("\\A_WIDTH").as_int() + 1); - c1->setPort("\\A", {extbit, c1->getPort("\\A")}); - } - while (c2->getParam("\\A_WIDTH").as_int() < c1->getParam("\\A_WIDTH").as_int()) { - c2->setParam("\\A_WIDTH", c2->getParam("\\A_WIDTH").as_int() + 1); - c2->setPort("\\A", {extbit, c2->getPort("\\A")}); - } - } - if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) { RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; @@ -923,12 +910,6 @@ struct SharePass : public Pass { // config.generic_uni_ops.insert("$bu0"); config.generic_uni_ops.insert("$neg"); - config.generic_uni_ops.insert("$reduce_and"); - config.generic_uni_ops.insert("$reduce_or"); - config.generic_uni_ops.insert("$reduce_xor"); - config.generic_uni_ops.insert("$reduce_xnor"); - config.generic_uni_ops.insert("$reduce_bool"); - config.generic_cbin_ops.insert("$and"); config.generic_cbin_ops.insert("$or"); config.generic_cbin_ops.insert("$xor"); From 9d4362990f514ffd2aad3170ec7382f21b8bca67 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 9 Aug 2014 17:07:20 +0200 Subject: [PATCH 568/750] Fixed "share" for complex scenarios with never-active cells --- passes/sat/share.cc | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 065b90d3..5f3cf421 100644 --- a/passes/sat/share.cc +++ b/passes/sat/share.cc @@ -685,12 +685,13 @@ struct ShareWorker RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns); if (cell_activation_patterns.empty()) { - log (" Cell is never active. Sharing is pointless, we simply remove it.\n"); + log(" Cell is never active. Sharing is pointless, we simply remove it.\n"); + cells_to_remove.insert(cell); continue; } if (cell_activation_patterns.count(std::pair())) { - log (" Cell is always active. Therefore no sharing is possible.\n"); + log(" Cell is always active. Therefore no sharing is possible.\n"); continue; } @@ -717,13 +718,15 @@ struct ShareWorker RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns); if (other_cell_activation_patterns.empty()) { - log (" Cell is never active. Sharing is pointless, we simply remove it.\n"); + log(" Cell is never active. Sharing is pointless, we simply remove it.\n"); shareable_cells.erase(other_cell); + cells_to_remove.insert(other_cell); continue; } if (other_cell_activation_patterns.count(std::pair())) { - log (" Cell is always active. Therefore no sharing is possible.\n"); + log(" Cell is always active. Therefore no sharing is possible.\n"); + shareable_cells.erase(other_cell); continue; } @@ -750,8 +753,6 @@ struct ShareWorker optimize_activation_patterns(filtered_other_cell_activation_patterns); ezDefaultSAT ez; - ez.non_incremental(); - SatGen satgen(&ez, &modwalker.sigmap); std::set sat_cells; @@ -798,6 +799,21 @@ struct ShareWorker break; } + if (!ez.solve(ez.expression(ez.OpOr, cell_active))) { + log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(cell)); + cells_to_remove.insert(cell); + break; + } + + if (!ez.solve(ez.expression(ez.OpOr, other_cell_active))) { + log(" According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(other_cell)); + cells_to_remove.insert(other_cell); + shareable_cells.erase(other_cell); + continue; + } + + ez.non_incremental(); + all_ctrl_signals.sort_and_unify(); std::vector sat_model = satgen.importSigSpec(all_ctrl_signals); std::vector sat_model_values; From 788bd02f970859bb67c5dbb7b503f23904257f7b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 10 Aug 2014 12:04:02 +0200 Subject: [PATCH 569/750] Fixed FSM mapping for multiple reset-like signals --- passes/fsm/fsm_map.cc | 22 +++++++++++++++++++++- tests/fsm/generate.py | 29 ++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index b3750de0..048cf7e5 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -25,6 +25,20 @@ #include "fsmdata.h" #include +static bool pattern_is_subset(const RTLIL::Const &super_pattern, const RTLIL::Const &sub_pattern) +{ + log_assert(SIZE(super_pattern.bits) == SIZE(sub_pattern.bits)); + for (int i = 0; i < SIZE(super_pattern.bits); i++) + if (sub_pattern.bits[i] == RTLIL::State::S0 || sub_pattern.bits[i] == RTLIL::State::S1) { + if (super_pattern.bits[i] == RTLIL::State::S0 || super_pattern.bits[i] == RTLIL::State::S1) { + if (super_pattern.bits[i] != sub_pattern.bits[i]) + return false; + } else + return false; + } + return true; +} + static void implement_pattern_cache(RTLIL::Module *module, std::map> &pattern_cache, std::set &fullstate_cache, int num_states, RTLIL::Wire *state_onehot, RTLIL::SigSpec &ctrl_in, RTLIL::SigSpec output) { RTLIL::SigSpec cases_vector; @@ -68,7 +82,13 @@ static void implement_pattern_cache(RTLIL::Module *module, std::mapparameters["\\Y_WIDTH"] = RTLIL::Const(1); } - if (or_sig.size() < num_states-int(fullstate_cache.size())) + std::set complete_in_state_cache = it.second; + + for (auto &it2 : pattern_cache) + if (pattern_is_subset(pattern, it2.first)) + complete_in_state_cache.insert(it2.second.begin(), it2.second.end()); + + if (SIZE(complete_in_state_cache) < num_states) { if (or_sig.size() == 1) { diff --git a/tests/fsm/generate.py b/tests/fsm/generate.py index 722bd62a..ca0718b2 100644 --- a/tests/fsm/generate.py +++ b/tests/fsm/generate.py @@ -32,8 +32,15 @@ def random_expr(variables): for idx in range(50): with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): - print('module uut_%05d(clk, rst, a, b, c, x, y, z);' % (idx)) - print(' input clk, rst;') + rst2 = random.choice([False, True]) + if rst2: + print('module uut_%05d(clk, rst1, rst2, rst, a, b, c, x, y, z);' % (idx)) + print(' input clk, rst1, rst2;') + print(' output rst;') + print(' assign rst = rst1 || rst2;') + else: + print('module uut_%05d(clk, rst, a, b, c, x, y, z);' % (idx)) + print(' input clk, rst;') variables=['a', 'b', 'c', 'x', 'y', 'z'] print(' input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 31))) print(' input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 31))) @@ -41,14 +48,15 @@ for idx in range(50): print(' output reg%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 31))) print(' output reg%s [%d:0] y;' % (random.choice(['', ' signed']), random.randint(0, 31))) print(' output reg%s [%d:0] z;' % (random.choice(['', ' signed']), random.randint(0, 31))) - print(' reg [15:0] state;') + state_bits = random.randint(5, 16); + print(' reg [%d:0] state;' % (state_bits-1)) states=[] for i in range(random.randint(2, 10)): - n = random.randint(0, 2**16-1) + n = random.randint(0, 2**state_bits-1) if n not in states: states.append(n) print(' always @(posedge clk) begin') - print(' if (rst) begin') + print(' if (%s) begin' % ('rst1' if rst2 else 'rst')) print(' x <= %d;' % random.randint(0, 2**31-1)) print(' y <= %d;' % random.randint(0, 2**31-1)) print(' z <= %d;' % random.randint(0, 2**31-1)) @@ -67,6 +75,13 @@ for idx in range(50): random.choice(['<', '<=', '>=', '>']), random_expr(variables), next_state)) print(' end') print(' endcase') + if rst2: + print(' if (rst2) begin') + print(' x <= a;') + print(' y <= b;') + print(' z <= c;') + print(' state <= %d;' % random.choice(states)) + print(' end') print(' end') print(' end') print('endmodule') @@ -76,8 +91,8 @@ for idx in range(50): print('copy uut_%05d gold' % idx) print('rename uut_%05d gate' % idx) print('cd gate') - print('opt; wreduce; share; opt; fsm;;') + print('opt; wreduce; share%s; opt; fsm;;' % random.choice(['', ' -aggressive'])) print('cd ..') print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') - print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 in_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter') + print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 %s_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter' % ('gold' if rst2 else 'in')) From 5215723c64037ba1ee7884423aee1b9c307b5850 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 11 Aug 2014 15:55:41 +0200 Subject: [PATCH 570/750] Another build fix by americanrouter (via reddit) --- kernel/log.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/log.cc b/kernel/log.cc index 09673dc2..1f082603 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -238,6 +238,7 @@ void log_cell(RTLIL::Cell *cell, std::string indent) // --------------------------------------------------- // This is the magic behind the code coverage counters // --------------------------------------------------- +#ifdef COVER_ACTIVE std::map> extra_coverage_data; @@ -283,5 +284,7 @@ std::map> get_coverage_data() return coverage_data; } +#endif + YOSYS_NAMESPACE_END From cad98bcd89cd9747f3ea9e35eed8d9bbedd64d7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 10:37:47 +0200 Subject: [PATCH 571/750] Added multi-dim memory test (requires iverilog git head) --- tests/simple/memory.v | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/simple/memory.v b/tests/simple/memory.v index 9fed1bf3..db06c56d 100644 --- a/tests/simple/memory.v +++ b/tests/simple/memory.v @@ -194,3 +194,14 @@ always @(posedge clk) begin end endmodule + +// ---------------------------------------------------------- + +module memtest08(input clk, input [3:0] a, b, c, output reg [3:0] y); + reg [3:0] mem [0:15] [0:15]; + always @(posedge clk) begin + y <= mem[a][b]; + mem[a][b] <= c; + end +endmodule + From 593264e9edce8b1df1d5b691353fa592261d4f3b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 15:21:06 +0200 Subject: [PATCH 572/750] Fixed building verific bindings --- frontends/verific/build_amd64.txt | 2 +- frontends/verific/verific.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 2f325e51..2c3ba7b4 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 30f45218..1ffcc422 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; From e5ac8fdf2bf9d4bed41daf420aa8a94018c0ded4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 15:39:48 +0200 Subject: [PATCH 573/750] Fixed SigBit(RTLIL::Wire *wire) constructor --- kernel/rtlil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8ec59941..1e967f26 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -852,7 +852,7 @@ struct RTLIL::SigBit SigBit() : wire(NULL), data(RTLIL::State::S0) { } SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } - SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0) { log_assert(wire && wire->width == 1); } + SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire); } SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data.bits[0]; } SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data.bits[index]; } From 1dd8252169654c2bc8cb96a90141a333d3ccd4f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 15:43:30 +0200 Subject: [PATCH 574/750] Added test_verific mode to tests/fsm/generate.py --- tests/fsm/generate.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/fsm/generate.py b/tests/fsm/generate.py index ca0718b2..66ca2af5 100644 --- a/tests/fsm/generate.py +++ b/tests/fsm/generate.py @@ -7,6 +7,9 @@ import sys import random from contextlib import contextmanager +# set to 'True' to compare verific with yosys +test_verific = False + @contextmanager def redirect_stdout(new_target): old_target, sys.stdout = sys.stdout, new_target @@ -86,13 +89,20 @@ for idx in range(50): print(' end') print('endmodule') with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): - print('read_verilog temp/uut_%05d.v' % idx) - print('proc;;') - print('copy uut_%05d gold' % idx) - print('rename uut_%05d gate' % idx) - print('cd gate') - print('opt; wreduce; share%s; opt; fsm;;' % random.choice(['', ' -aggressive'])) - print('cd ..') + if test_verific: + print('read_verilog temp/uut_%05d.v' % idx) + print('proc;; rename uut_%05d gold' % idx) + print('verific -vlog2k temp/uut_%05d.v' % idx) + print('verific -import uut_%05d' % idx) + print('rename uut_%05d gate' % idx) + else: + print('read_verilog temp/uut_%05d.v' % idx) + print('proc;;') + print('copy uut_%05d gold' % idx) + print('rename uut_%05d gate' % idx) + print('cd gate') + print('opt; wreduce; share%s; opt; fsm;;' % random.choice(['', ' -aggressive'])) + print('cd ..') print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 %s_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter' % ('gold' if rst2 else 'in')) From 9d353fc543295db7d6f4b4ba60c2b66a509b3ee2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 17:35:22 +0200 Subject: [PATCH 575/750] Fixed handling of constant-true branches in proc_clean --- passes/proc/proc_clean.cc | 3 ++- passes/proc/proc_rmdead.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 13be0ddb..1e3dd9ce 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -59,7 +59,8 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did sw->signal = RTLIL::SigSpec(); } - if (sw->cases.size() == 1 && (sw->signal.size() == 0 || sw->cases[0]->compare.empty())) + if (parent->switches.front() == sw && sw->cases.size() == 1 && + (sw->signal.size() == 0 || sw->cases[0]->compare.empty())) { did_something = true; for (auto &action : sw->cases[0]->actions) diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc index 61844d5e..fe3532da 100644 --- a/passes/proc/proc_rmdead.cc +++ b/passes/proc/proc_rmdead.cc @@ -31,7 +31,7 @@ static void proc_rmdead(RTLIL::SwitchRule *sw, int &counter) for (size_t i = 0; i < sw->cases.size(); i++) { - bool is_default = sw->cases[i]->compare.size() == 0 && !pool.empty(); + bool is_default = SIZE(sw->cases[i]->compare) == 0 && (!pool.empty() || SIZE(sw->signal) == 0); for (size_t j = 0; j < sw->cases[i]->compare.size(); j++) { RTLIL::SigSpec sig = sw->cases[i]->compare[j]; From f53984795d38946ee71684d88883cafd9f58f603 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:03:38 +0200 Subject: [PATCH 576/750] Added support for non-standard """ macro bodies --- README | 9 +++++++++ frontends/verilog/preproc.cc | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README b/README index 0c8425f3..1ecaa07d 100644 --- a/README +++ b/README @@ -281,6 +281,15 @@ Verilog Attributes and non-standard features to simply declare a module port as 'input' or 'output' in the module body. +- When defining a macro with `define, all text between tripple double quotes + is interpreted as macro body, even if it contains unescaped newlines. The + tripple double quotes are removed from the macro body. For example: + + `define MY_MACRO(a, b) """ + assign a = 23; + assign b = 42; + """ + - Sized constants (the syntax 's?[bodh]) support constant expressions as . If the expresion is not a simple identifier, it must be put in parentheses. Examples: WIDTH'd42, (4+2)'b101010 diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 8efd4d7c..7935fbc3 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; } From c27120fcbc69f7b942788d72677f34e4a96ab48a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:04:28 +0200 Subject: [PATCH 577/750] New interface for $__alu in techmap.v --- techlibs/common/techmap.v | 215 +++++++++++++------------------------- 1 file changed, 74 insertions(+), 141 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 7f3855ce..a03ff8eb 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -266,26 +266,36 @@ module \$__fulladd (A, B, C, X, Y); \$_OR_ gate5 ( .A(t1), .B(t3), .Y(X) ); endmodule -module \$__alu (A, B, Cin, Y, Cout, Csign); - parameter WIDTH = 1; +module \$__alu (A, B, CI, S, Y, CO, CS); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; - input [WIDTH-1:0] A, B; - input Cin; + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; - output [WIDTH-1:0] Y; - output Cout, Csign; + // carry in, sub, carry out, carry sign + input CI, S; + output CO, CS; - wire [WIDTH:0] carry; - assign carry[0] = Cin; - assign Cout = carry[WIDTH]; - assign Csign = carry[WIDTH-1]; + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + wire [Y_WIDTH:0] carry; + assign carry[0] = CI; + assign CO = carry[Y_WIDTH]; + assign CS = carry[Y_WIDTH-1]; genvar i; generate - for (i = 0; i < WIDTH; i = i + 1) begin:V + for (i = 0; i < Y_WIDTH; i = i + 1) begin:V \$__fulladd adder ( - .A(A[i]), - .B(B[i]), + .A(A_buf[i]), + .B(S ? !B_buf[i] : B_buf[i]), .C(carry[i]), .X(carry[i+1]), .Y(Y[i]) @@ -294,99 +304,60 @@ module \$__alu (A, B, Cin, Y, Cout, Csign); endgenerate endmodule +`define ALU_COMMONS(_width, _ci, _s) """ + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + localparam WIDTH = _width; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + wire alu_co, alu_cs; + wire [WIDTH-1:0] alu_y; + + \$__alu #( + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(WIDTH) + ) alu ( + .A(A), + .B(B), + .CI(_ci), + .S(_s), + .Y(alu_y), + .CO(alu_co), + .CS(alu_cs) + ); + + wire cf, of, zf, sf; + assign cf = !alu_co; + assign of = alu_co ^ alu_cs; + assign zf = ~|alu_y; + assign sf = alu_y[WIDTH-1]; +""" + // -------------------------------------------------------- // Compare cells // -------------------------------------------------------- module \$lt (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire carry, carry_sign; - wire [WIDTH-1:0] A_buf, B_buf, Y_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - - \$__alu #( - .WIDTH(WIDTH) - ) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign) - ); - - // ALU flags - wire cf, of, zf, sf; - assign cf = !carry; - assign of = carry ^ carry_sign; - assign zf = ~|Y_buf; - assign sf = Y_buf[WIDTH-1]; - - generate - if (A_SIGNED && B_SIGNED) begin - assign Y = of != sf; - end else begin - assign Y = cf; - end - endgenerate + wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1, 1) + assign Y = A_SIGNED && B_SIGNED ? of != sf : cf; endmodule module \$le (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire carry, carry_sign; - wire [WIDTH-1:0] A_buf, B_buf, Y_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - - \$__alu #( - .WIDTH(WIDTH) - ) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign) - ); - - // ALU flags - wire cf, of, zf, sf; - assign cf = !carry; - assign of = carry ^ carry_sign; - assign zf = ~|Y_buf; - assign sf = Y_buf[WIDTH-1]; - - generate - if (A_SIGNED && B_SIGNED) begin - assign Y = zf || (of != sf); - end else begin - assign Y = zf || cf; - end - endgenerate + wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1, 1) + assign Y = zf || (A_SIGNED && B_SIGNED ? of != sf : cf); endmodule @@ -395,53 +366,15 @@ endmodule // -------------------------------------------------------- module \$add (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire [Y_WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - - \$__alu #( - .WIDTH(Y_WIDTH) - ) alu ( - .A(A_buf), - .B(B_buf), - .Cin(1'b0), - .Y(Y) - ); + wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + `ALU_COMMONS(Y_WIDTH, 0, 0) + assign Y = alu_y; endmodule module \$sub (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire [Y_WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - - \$__alu #( - .WIDTH(Y_WIDTH) - ) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y) - ); + wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + `ALU_COMMONS(Y_WIDTH, 1, 1) + assign Y = alu_y; endmodule From 28bc7aeb9345377d7815ad5ae9a941e55409bc4b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:40:29 +0200 Subject: [PATCH 578/750] Filter ANSI escape sequences from ABC output --- passes/abc/abc.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 77419e61..b9baea38 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -639,10 +639,25 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std log("ABC: %s", logbuf); #else bool got_cr = false; + int escape_seq_state = 0; std::string linebuf; char logbuf[1024]; while (fgets(logbuf, 1024, f) != NULL) for (char *p = logbuf; *p; p++) { + if (escape_seq_state == 0 && *p == '\033') { + escape_seq_state = 1; + continue; + } + if (escape_seq_state == 1) { + escape_seq_state = *p == '[' ? 2 : 0; + continue; + } + if (escape_seq_state == 2) { + if ((*p < '0' || '9' < *p) && *p != ';') + escape_seq_state = 0; + continue; + } + escape_seq_state = 0; if (*p == '\r') { got_cr = true; continue; From 9a065509acd53d4fdbfe2e98ab0aba5e6851d8e8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 16:36:30 +0200 Subject: [PATCH 579/750] Preparations for lookahead ALU support in techmap.v --- techlibs/common/techmap.v | 120 +++++++++++++++++++++++++++++--------- 1 file changed, 92 insertions(+), 28 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index a03ff8eb..59f91bc5 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -251,19 +251,91 @@ endmodule // ALU Infrastructure // -------------------------------------------------------- -module \$__fulladd (A, B, C, X, Y); - // {X, Y} = A + B + C - input A, B, C; - output X, Y; +module \$__alu_ripple (A, B, CI, Y, CO, CS); + parameter WIDTH = 1; - // {t1, t2} = A + B - wire t1, t2, t3; + input [WIDTH-1:0] A, B; + output [WIDTH-1:0] Y; - \$_AND_ gate1 ( .A(A), .B(B), .Y(t1) ); - \$_XOR_ gate2 ( .A(A), .B(B), .Y(t2) ); - \$_AND_ gate3 ( .A(t2), .B(C), .Y(t3) ); - \$_XOR_ gate4 ( .A(t2), .B(C), .Y(Y) ); - \$_OR_ gate5 ( .A(t1), .B(t3), .Y(X) ); + input CI; + output CO, CS; + + wire [WIDTH:0] carry; + assign carry[0] = CI; + assign CO = carry[WIDTH]; + assign CS = carry[WIDTH-1]; + + genvar i; + generate + for (i = 0; i < WIDTH; i = i + 1) + begin:V + // {x, y} = a + b + c + wire a, b, c, x, y; + wire t1, t2, t3; + + \$_AND_ gate1 ( .A(a), .B(b), .Y(t1) ); + \$_XOR_ gate2 ( .A(a), .B(b), .Y(t2) ); + \$_AND_ gate3 ( .A(t2), .B(c), .Y(t3) ); + \$_XOR_ gate4 ( .A(t2), .B(c), .Y(y) ); + \$_OR_ gate5 ( .A(t1), .B(t3), .Y(x) ); + + assign a = A[i], b = B[i], c = carry[i]; + assign carry[i+1] = x, Y[i] = y; + end + endgenerate +endmodule + +module \$__lcu (P, G, CI, CO, PG, GG); + parameter WIDTH = 1; + + input [WIDTH-1:0] P, G; + input CI; + + output [WIDTH:0] CO; + output PG, GG; + + assign CO[0] = CI; + assign PG = 'bx, GG = 'bx; + + genvar i; + generate + // TBD: Actually implement a LCU topology + for (i = 0; i < WIDTH; i = i + 1) + assign CO[i+1] = G[i] | (P[i] & CO[i]); + endgenerate +endmodule + +module \$__alu_lookahead (A, B, CI, Y, CO, CS); + parameter WIDTH = 1; + + input [WIDTH-1:0] A, B; + output [WIDTH-1:0] Y; + + input CI; + output CO, CS; + + wire [WIDTH-1:0] P, G; + wire [WIDTH:0] C; + + assign CO = C[WIDTH]; + assign CS = C[WIDTH-1]; + + genvar i; + generate + for (i = 0; i < WIDTH; i = i + 1) + begin:V + wire a, b, c, p, g, y; + + \$_AND_ gate1 ( .A(a), .B(b), .Y(g) ); + \$_XOR_ gate2 ( .A(a), .B(b), .Y(p) ); + \$_XOR_ gate3 ( .A(p), .B(c), .Y(y) ); + + assign a = A[i], b = B[i], c = C[i]; + assign P[i] = p, G[i] = g, Y[i] = y; + end + endgenerate + + \$__lcu #(.WIDTH(WIDTH)) lcu (.P(P), .G(G), .CI(CI), .CO(C)); endmodule module \$__alu (A, B, CI, S, Y, CO, CS); @@ -285,23 +357,15 @@ module \$__alu (A, B, CI, S, Y, CO, CS); \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - wire [Y_WIDTH:0] carry; - assign carry[0] = CI; - assign CO = carry[Y_WIDTH]; - assign CS = carry[Y_WIDTH-1]; - - genvar i; - generate - for (i = 0; i < Y_WIDTH; i = i + 1) begin:V - \$__fulladd adder ( - .A(A_buf[i]), - .B(S ? !B_buf[i] : B_buf[i]), - .C(carry[i]), - .X(carry[i+1]), - .Y(Y[i]) - ); - end - endgenerate +`ifdef ALU_RIPPLE + \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(S ? ~B_buf : B_buf), .CI(CI), .Y(Y), .CO(CO), .CS(CS)); +`else + if (Y_WIDTH <= 4) begin + \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(S ? ~B_buf : B_buf), .CI(CI), .Y(Y), .CO(CO), .CS(CS)); + end else begin + \$__alu_lookahead #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(S ? ~B_buf : B_buf), .CI(CI), .Y(Y), .CO(CO), .CS(CS)); + end +`endif endmodule `define ALU_COMMONS(_width, _ci, _s) """ From 7e758d5fbba4769ba268229bece7b5c486c61223 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 18:40:57 +0200 Subject: [PATCH 580/750] Added techmap support for actual lookahead carry unit --- techlibs/common/techmap.v | 95 ++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 59f91bc5..3670bd69 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -267,7 +267,7 @@ module \$__alu_ripple (A, B, CI, Y, CO, CS); genvar i; generate - for (i = 0; i < WIDTH; i = i + 1) + for (i = 0; i < WIDTH; i = i+1) begin:V // {x, y} = a + b + c wire a, b, c, x, y; @@ -285,23 +285,79 @@ module \$__alu_ripple (A, B, CI, Y, CO, CS); endgenerate endmodule +module \$__lcu_simple (P, G, CI, CO, PG, GG); + parameter WIDTH = 1; + + input [WIDTH-1:0] P, G; + input CI; + + output reg [WIDTH:0] CO; + output reg PG, GG; + + wire [1023:0] _TECHMAP_DO_ = "proc;;"; + + integer i, j; + reg [WIDTH-1:0] tmp; + + always @* begin + PG = &P; + GG = 0; + for (i = 0; i < WIDTH; i = i+1) begin + tmp = ~0; + tmp[i] = G[i]; + for (j = i+1; j < WIDTH; j = j+1) + tmp[j] = P[j]; + GG = GG || &tmp[WIDTH-1:i]; + end + + CO[0] = CI; + for (i = 0; i < WIDTH; i = i+1) + CO[i+1] = G[i] | (P[i] & CO[i]); + end +endmodule + module \$__lcu (P, G, CI, CO, PG, GG); parameter WIDTH = 1; + function integer get_group_size; + begin + get_group_size = 4; + while (4 * get_group_size < WIDTH) + get_group_size = 4 * get_group_size; + end + endfunction + input [WIDTH-1:0] P, G; input CI; output [WIDTH:0] CO; output PG, GG; - assign CO[0] = CI; - assign PG = 'bx, GG = 'bx; - genvar i; generate - // TBD: Actually implement a LCU topology - for (i = 0; i < WIDTH; i = i + 1) - assign CO[i+1] = G[i] | (P[i] & CO[i]); + if (WIDTH <= 4) begin + \$__lcu_simple #(.WIDTH(WIDTH)) _TECHMAP_REPLACE_ (.P(P), .G(G), .CI(CI), .CO(CO), .PG(PG), .GG(GG)); + end else begin + localparam GROUP_SIZE = get_group_size(); + localparam GROUPS_NUM = (WIDTH + GROUP_SIZE - 1) / GROUP_SIZE; + + wire [GROUPS_NUM-1:0] groups_p, groups_g; + wire [GROUPS_NUM:0] groups_ci; + + for (i = 0; i < GROUPS_NUM; i = i+1) begin:V + localparam g_size = `MIN(GROUP_SIZE, WIDTH - i*GROUP_SIZE); + localparam g_offset = i*GROUP_SIZE; + wire [g_size:0] g_co; + + \$__lcu #(.WIDTH(g_size)) g (.P(P[g_offset +: g_size]), .G(G[g_offset +: g_size]), + .CI(groups_ci[i]), .CO(g_co), .PG(groups_p[i]), .GG(groups_g[i])); + assign CO[g_offset+1 +: g_size] = g_co[1 +: g_size]; + end + + \$__lcu_simple #(.WIDTH(GROUPS_NUM)) super_lcu (.P(groups_p), .G(groups_g), .CI(CI), .CO(groups_ci), .PG(PG), .GG(GG)); + + assign CO[0] = CI; + end endgenerate endmodule @@ -322,7 +378,7 @@ module \$__alu_lookahead (A, B, CI, Y, CO, CS); genvar i; generate - for (i = 0; i < WIDTH; i = i + 1) + for (i = 0; i < WIDTH; i = i+1) begin:V wire a, b, c, p, g, y; @@ -368,6 +424,11 @@ module \$__alu (A, B, CI, S, Y, CO, CS); `endif endmodule + +// -------------------------------------------------------- +// ALU Cell Types: Compare, Add, Subtract +// -------------------------------------------------------- + `define ALU_COMMONS(_width, _ci, _s) """ parameter A_SIGNED = 0; parameter B_SIGNED = 0; @@ -407,36 +468,26 @@ endmodule assign sf = alu_y[WIDTH-1]; """ - -// -------------------------------------------------------- -// Compare cells -// -------------------------------------------------------- - module \$lt (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1, 1) assign Y = A_SIGNED && B_SIGNED ? of != sf : cf; endmodule module \$le (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1, 1) assign Y = zf || (A_SIGNED && B_SIGNED ? of != sf : cf); endmodule - -// -------------------------------------------------------- -// Add and Subtract -// -------------------------------------------------------- - module \$add (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; `ALU_COMMONS(Y_WIDTH, 0, 0) assign Y = alu_y; endmodule module \$sub (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt_const -mux_undef -mux_bool -fine;;;"; + wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; `ALU_COMMONS(Y_WIDTH, 1, 1) assign Y = alu_y; endmodule From a878095b465d73df7b347dddb25c3627024b3d7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 10:19:12 +0200 Subject: [PATCH 581/750] Updated ABC to 4935c2b946de --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0e3a88a7..cf176fde 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = b1e63d18768d +ABCREV = 4935c2b946de ABCPULL = 1 -include Makefile.conf From 996c06f64dcb1619584c88d101c5ba258b2b26af Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 11:05:25 +0200 Subject: [PATCH 582/750] Added "abc -D" for setting delay target --- passes/abc/abc.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index b9baea38..e7da6ed4 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -29,8 +29,8 @@ // Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558–562, doi:10.1145/368996.369025 // http://en.wikipedia.org/wiki/Topological_sorting -#define ABC_COMMAND_LIB "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v" -#define ABC_COMMAND_CTR "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v; buffer -v; upsize -v; dnsize -v; stime -p" +#define ABC_COMMAND_LIB "strash; scorr -v; ifraig -v; retime -v {D}; strash; dch -vf; map -v {D}" +#define ABC_COMMAND_CTR "strash; scorr -v; ifraig -v; retime -v {D}; strash; dch -vf; map -v {D}; buffer -v; upsize -v {D}; dnsize -v {D}; stime -p" #define ABC_COMMAND_LUT "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; if -v" #define ABC_COMMAND_DFL "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v" @@ -397,7 +397,8 @@ static std::string fold_abc_cmd(std::string str) } static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, - std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str, bool keepff) + std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str, + bool keepff, std::string delay_target) { module = current_module; map_autoidx = autoidx++; @@ -435,6 +436,10 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std abc_command = constr_file.empty() ? ABC_COMMAND_LIB : ABC_COMMAND_CTR; else abc_command = ABC_COMMAND_DFL; + + for (size_t pos = abc_command.find("{D}"); pos != std::string::npos; pos = abc_command.find("{D}", pos)) + abc_command = abc_command.substr(0, pos) + delay_target + abc_command.substr(pos+3); + abc_command = add_echos_to_abc_cmd(abc_command); if (abc_command.size() > 128) { @@ -915,6 +920,10 @@ struct AbcPass : public Pass { log(" drive the primary inputs and the set_load statement sets the load in\n"); log(" femtofarads for each primary output.\n"); log("\n"); + log(" -D \n"); + log(" set delay target. the string {D} in the default scripts above is\n"); + log(" replaced by this option when used, and an empty string otherwise.\n"); + log("\n"); log(" -lut \n"); log(" generate netlist using luts of (max) the specified width.\n"); log("\n"); @@ -951,7 +960,7 @@ struct AbcPass : public Pass { log_push(); std::string exe_file = proc_self_dirname() + "yosys-abc"; - std::string script_file, liberty_file, constr_file, clk_str; + std::string script_file, liberty_file, constr_file, clk_str, delay_target; bool dff_mode = false, keepff = false, cleanup = true; int lut_mode = 0; @@ -985,6 +994,10 @@ struct AbcPass : public Pass { constr_file = std::string(pwd) + "/" + constr_file; continue; } + if (arg == "-D" && argidx+1 < args.size()) { + delay_target = "-D " + args[++argidx]; + continue; + } if (arg == "-lut" && argidx+1 < args.size()) { lut_mode = atoi(args[++argidx].c_str()); continue; @@ -1019,7 +1032,7 @@ struct AbcPass : public Pass { if (mod_it.second->processes.size() > 0) log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str()); else - abc_module(design, mod_it.second, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, dff_mode, clk_str, keepff); + abc_module(design, mod_it.second, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, dff_mode, clk_str, keepff, delay_target); } assign_map.clear(); From 28cf48e31f049f8343023de46cd916ac47fcfc5d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 11:22:45 +0200 Subject: [PATCH 583/750] Some improvements in FSM mapping and recoding --- passes/fsm/fsm_map.cc | 2 +- passes/fsm/fsm_recode.cc | 22 +++++++++++++++------- tests/fsm/generate.py | 3 ++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 048cf7e5..60580eb4 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -285,7 +285,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) } } - RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$safe_pmux"); + RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$pmux"); mux_cell->setPort("\\A", sig_a); mux_cell->setPort("\\B", sig_b); mux_cell->setPort("\\S", sig_s); diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 40fed130..9c0da0a3 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -53,10 +53,10 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs std::string encoding = cell->attributes.count("\\fsm_encoding") ? cell->attributes.at("\\fsm_encoding").decode_string() : "auto"; log("Recoding FSM `%s' from module `%s' using `%s' encoding:\n", cell->name.c_str(), module->name.c_str(), encoding.c_str()); - if (encoding != "none" && encoding != "one-hot" && encoding != "binary") { - if (encoding != "auto") - log(" unkown encoding `%s': using auto (%s) instead.\n", encoding.c_str(), default_encoding.c_str()); - encoding = default_encoding; + + if (encoding != "none" && encoding != "one-hot" && encoding != "binary" && encoding != "auto") { + log(" unkown encoding `%s': using auto instead.\n", encoding.c_str()); + encoding = "auto"; } if (encoding == "none") { @@ -70,10 +70,18 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs if (fm_set_fsm_file != NULL) fm_set_fsm_print(cell, module, fsm_data, "r", fm_set_fsm_file); + if (encoding == "auto") { + if (!default_encoding.empty()) + encoding = default_encoding; + else + encoding = SIZE(fsm_data.state_table) < 32 ? "one-hot" : "binary"; + log(" mapping auto encoding to `%s` for this FSM.\n", encoding.c_str()); + } + if (encoding == "one-hot") { fsm_data.state_bits = fsm_data.state_table.size(); } else - if (encoding == "auto" || encoding == "binary") { + if (encoding == "binary") { fsm_data.state_bits = ceil(log2(fsm_data.state_table.size())); } else log_error("FSM encoding `%s' is not supported!\n", encoding.c_str()); @@ -88,7 +96,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs new_code = RTLIL::Const(RTLIL::State::Sa, fsm_data.state_bits); new_code.bits[state_idx] = RTLIL::State::S1; } else - if (encoding == "auto" || encoding == "binary") { + if (encoding == "binary") { new_code = RTLIL::Const(state_idx, fsm_data.state_bits); } else log_abort(); @@ -124,7 +132,7 @@ struct FsmRecodePass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { FILE *fm_set_fsm_file = NULL; - std::string default_encoding = "one-hot"; + std::string default_encoding; log_header("Executing FSM_RECODE pass (re-assigning FSM state encoding).\n"); size_t argidx; diff --git a/tests/fsm/generate.py b/tests/fsm/generate.py index 66ca2af5..b5b4626d 100644 --- a/tests/fsm/generate.py +++ b/tests/fsm/generate.py @@ -52,7 +52,8 @@ for idx in range(50): print(' output reg%s [%d:0] y;' % (random.choice(['', ' signed']), random.randint(0, 31))) print(' output reg%s [%d:0] z;' % (random.choice(['', ' signed']), random.randint(0, 31))) state_bits = random.randint(5, 16); - print(' reg [%d:0] state;' % (state_bits-1)) + print(' %sreg [%d:0] state;' % (random.choice(['', '(* fsm_encoding = "one-hot" *)', + '(* fsm_encoding = "binary" *)']), state_bits-1)) states=[] for i in range(random.randint(2, 10)): n = random.randint(0, 2**state_bits-1) From 13f2f36884fa3e4a8329dab2556af7000cb085df Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 11:39:46 +0200 Subject: [PATCH 584/750] RIP $safe_pmux --- kernel/celltypes.h | 3 +-- kernel/consteval.h | 7 ++----- kernel/rtlil.cc | 7 +++---- kernel/rtlil.h | 6 ++---- kernel/satgen.h | 10 +--------- manual/PRESENTATION_Prog.tex | 2 +- passes/cmds/wreduce.cc | 4 ++-- passes/fsm/fsm_detect.cc | 2 +- passes/fsm/fsm_expand.cc | 2 +- passes/fsm/fsm_extract.cc | 2 +- passes/opt/opt_muxtree.cc | 2 +- passes/opt/opt_reduce.cc | 2 +- passes/opt/opt_share.cc | 1 - passes/tests/test_cell.cc | 1 - techlibs/common/simlib.v | 31 ++++-------------------------- techlibs/common/techmap.v | 37 ------------------------------------ 16 files changed, 21 insertions(+), 98 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 99386382..23d06f82 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -98,7 +98,6 @@ struct CellTypes cell_types.insert("$pmux"); cell_types.insert("$slice"); cell_types.insert("$concat"); - cell_types.insert("$safe_pmux"); cell_types.insert("$lut"); cell_types.insert("$assert"); } @@ -307,7 +306,7 @@ struct CellTypes static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &sel) { - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") { + if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") { RTLIL::Const ret = arg1; for (size_t i = 0; i < sel.bits.size(); i++) if (sel.bits[i] == RTLIL::State::S1) { diff --git a/kernel/consteval.h b/kernel/consteval.h index 529d8962..dbe13ea7 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -104,7 +104,7 @@ struct ConstEval if (cell->hasPort("\\B")) sig_b = cell->getPort("\\B"); - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") + if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") { std::vector y_candidates; int count_maybe_set_s_bits = 0; @@ -125,10 +125,7 @@ struct ConstEval count_set_s_bits++; } - if (cell->type == "$safe_pmux" && count_set_s_bits > 1) - y_candidates.clear(); - - if ((cell->type == "$safe_pmux" && count_maybe_set_s_bits > 1) || count_set_s_bits == 0) + if (count_set_s_bits == 0) y_candidates.push_back(sig_a); std::vector y_values; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8ff56451..201c717e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -608,7 +608,7 @@ namespace { return; } - if (cell->type == "$pmux" || cell->type == "$safe_pmux") { + if (cell->type == "$pmux") { port("\\A", param("\\WIDTH")); port("\\B", param("\\WIDTH") * param("\\S_WIDTH")); port("\\S", param("\\S_WIDTH")); @@ -1293,7 +1293,6 @@ DEF_METHOD(LogicOr, 1, "$logic_or") } DEF_METHOD(Mux, "$mux", 0) DEF_METHOD(Pmux, "$pmux", 1) -DEF_METHOD(SafePmux, "$safe_pmux", 1) #undef DEF_METHOD #define DEF_METHOD_2(_func, _type, _P1, _P2) \ @@ -1637,10 +1636,10 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") return; - if (type == "$mux" || type == "$pmux" || type == "$safe_pmux") + if (type == "$mux" || type == "$pmux") { parameters["\\WIDTH"] = SIZE(connections_["\\Y"]); - if (type == "$pmux" || type == "$safe_pmux") + if (type == "$pmux") parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]); check(); return; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1e967f26..10da7463 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -662,9 +662,8 @@ public: RTLIL::Cell* addLogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addLogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); - RTLIL::Cell* addMux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); - RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); - RTLIL::Cell* addSafePmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); + RTLIL::Cell* addMux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); + RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); RTLIL::Cell* addSlice (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset); RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); @@ -743,7 +742,6 @@ public: RTLIL::SigSpec Mux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); RTLIL::SigSpec Pmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); - RTLIL::SigSpec SafePmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); RTLIL::SigSpec InvGate (RTLIL::IdString name, RTLIL::SigSpec sig_a); RTLIL::SigSpec AndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); diff --git a/kernel/satgen.h b/kernel/satgen.h index 1ada1e16..8284cdeb 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -316,7 +316,7 @@ struct SatGen return true; } - if (cell->type == "$pmux" || cell->type == "$safe_pmux") + if (cell->type == "$pmux") { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); @@ -330,8 +330,6 @@ struct SatGen std::vector part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size()); tmp = ez->vec_ite(s.at(i), part_of_b, tmp); } - if (cell->type == "$safe_pmux") - tmp = ez->vec_ite(ez->onehot(s, true), tmp, a); ez->assume(ez->vec_eq(tmp, yy)); if (model_undef) @@ -370,12 +368,6 @@ struct SatGen int maybe_a = ez->NOT(maybe_one_hot); - if (cell->type == "$safe_pmux") { - maybe_a = ez->OR(maybe_a, maybe_many_hot); - bits_set = ez->vec_ite(sure_many_hot, ez->vec_or(a, undef_a), bits_set); - bits_clr = ez->vec_ite(sure_many_hot, ez->vec_or(ez->vec_not(a), undef_a), bits_clr); - } - bits_set = ez->vec_ite(maybe_a, ez->vec_or(bits_set, ez->vec_or(bits_set, ez->vec_or(a, undef_a))), bits_set); bits_clr = ez->vec_ite(maybe_a, ez->vec_or(bits_clr, ez->vec_or(bits_clr, ez->vec_or(ez->vec_not(a), undef_a))), bits_clr); diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index 21a93d55..3b214544 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -302,7 +302,7 @@ cell name from the internal cell library: \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont] $not $pos $bu0 $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor $reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod -$pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $safe_pmux $lut $assert $sr $dff +$pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff $dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_INV_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ $_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_ $_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_ diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index 6723a57f..2269859d 100644 --- a/passes/cmds/wreduce.cc +++ b/passes/cmds/wreduce.cc @@ -42,7 +42,7 @@ struct WreduceConfig supported_cell_types << "$shl" << "$shr" << "$sshl" << "$sshr" << "$shift" << "$shiftx"; supported_cell_types << "$lt" << "$le" << "$eq" << "$ne" << "$eqx" << "$nex" << "$ge" << "$gt"; supported_cell_types << "$add" << "$sub"; // << "$mul" << "$div" << "$mod" << "$pow" - supported_cell_types << "$mux" << "$pmux" << "$safe_pmux"; + supported_cell_types << "$mux" << "$pmux"; } }; @@ -172,7 +172,7 @@ struct WreduceWorker if (!cell->type.in(config->supported_cell_types)) return; - if (cell->type.in("$mux", "$pmux", "$safe_pmux")) + if (cell->type.in("$mux", "$pmux")) return run_cell_mux(cell); diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 5675dff5..2c846a4c 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -50,7 +50,7 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig std::set cellport_list; sig2driver.find(sig, cellport_list); for (auto &cellport : cellport_list) { - if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux" && cellport.first->type != "$safe_pmux") || cellport.second != "\\Y") + if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux") || cellport.second != "\\Y") return false; RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A")); RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B")); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 670fae1d..77821326 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -42,7 +42,7 @@ struct FsmExpand bool is_cell_merge_candidate(RTLIL::Cell *cell) { - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") + if (cell->type == "$mux" || cell->type == "$pmux") if (cell->getPort("\\A").size() < 2) return true; diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index ebe3073d..871478de 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -55,7 +55,7 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL for (auto &cellport : cellport_list) { RTLIL::Cell *cell = module->cells_.at(cellport.first); - if ((cell->type != "$mux" && cell->type != "$pmux" && cell->type != "$safe_pmux") || cellport.second != "\\Y") { + if ((cell->type != "$mux" && cell->type != "$pmux") || cellport.second != "\\Y") { log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); return false; } diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 2660b33d..daa06381 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -84,7 +84,7 @@ struct OptMuxtreeWorker // .const_activated for (auto cell : module->cells()) { - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") + if (cell->type == "$mux" || cell->type == "$pmux") { RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_b = cell->getPort("\\B"); diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 5f3c4d29..e2b4243d 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -312,7 +312,7 @@ struct OptReduceWorker std::vector cells; for (auto &it : module->cells_) - if ((it.second->type == "$mux" || it.second->type == "$pmux" || it.second->type == "$safe_pmux") && design->selected(module, it.second)) + if ((it.second->type == "$mux" || it.second->type == "$pmux") && design->selected(module, it.second)) cells.push_back(it.second); for (auto cell : cells) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index eb970329..e9a5e7fd 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -224,7 +224,6 @@ struct OptShareWorker if (mode_nomux) { ct.cell_types.erase("$mux"); ct.cell_types.erase("$pmux"); - ct.cell_types.erase("$safe_pmux"); } log("Finding identical cells in module `%s'.\n", module->name.c_str()); diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 94649013..94d5d27b 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -176,7 +176,6 @@ struct TestCellPass : public Pass { // cell_types["$pmux"] = "A"; // cell_types["$slice"] = "A"; // cell_types["$concat"] = "A"; - // cell_types["$safe_pmux"] = "A"; // cell_types["$lut"] = "A"; // cell_types["$assert"] = "A"; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index c2f6cb27..4b3317a7 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -938,39 +938,16 @@ input [S_WIDTH-1:0] S; output reg [WIDTH-1:0] Y; integer i; +reg found_active_sel_bit; always @* begin Y = A; - for (i = 0; i < S_WIDTH; i = i+1) - if (S[i]) - Y = B >> (WIDTH*i); -end - -endmodule - -// -------------------------------------------------------- - -module \$safe_pmux (A, B, S, Y); - -parameter WIDTH = 0; -parameter S_WIDTH = 0; - -input [WIDTH-1:0] A; -input [WIDTH*S_WIDTH-1:0] B; -input [S_WIDTH-1:0] S; -output reg [WIDTH-1:0] Y; - -integer i, j; - -always @* begin - j = 0; + found_active_sel_bit = 0; for (i = 0; i < S_WIDTH; i = i+1) if (S[i]) begin - Y = B >> (WIDTH*i); - j = j + 1; + Y = found_active_sel_bit ? 'bx : B >> (WIDTH*i); + found_active_sel_bit = 1; end - if (j != 1) - Y = A; end endmodule diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 3670bd69..e1d5bd82 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -794,40 +794,3 @@ module \$pmux (A, B, S, Y); assign Y = |S ? Y_B : A; endmodule -module \$safe_pmux (A, B, S, Y); - parameter WIDTH = 1; - parameter S_WIDTH = 1; - - input [WIDTH-1:0] A; - input [WIDTH*S_WIDTH-1:0] B; - input [S_WIDTH-1:0] S; - output [WIDTH-1:0] Y; - - wire [S_WIDTH-1:0] status_found_first; - wire [S_WIDTH-1:0] status_found_second; - - genvar i; - generate - for (i = 0; i < S_WIDTH; i = i + 1) begin:GEN1 - wire pre_first; - if (i > 0) begin:GEN2 - assign pre_first = status_found_first[i-1]; - end:GEN2 else begin:GEN3 - assign pre_first = 0; - end:GEN3 - assign status_found_first[i] = pre_first | S[i]; - assign status_found_second[i] = pre_first & S[i]; - end:GEN1 - endgenerate - - \$pmux #( - .WIDTH(WIDTH), - .S_WIDTH(S_WIDTH) - ) pmux_cell ( - .A(A), - .B(B), - .S(S & {S_WIDTH{~|status_found_second}}), - .Y(Y) - ); -endmodule - From 746aac540b815099c6a63077010555369d7fdd5a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 15:46:51 +0200 Subject: [PATCH 585/750] Refactoring of CellType class --- backends/verilog/verilog_backend.cc | 38 +++-- kernel/celltypes.h | 240 ++++++++++++---------------- kernel/rtlil.cc | 16 +- 3 files changed, 139 insertions(+), 155 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 605616b3..cafc1f3f 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -40,10 +40,8 @@ namespace { bool norename, noattr, attr2comment, noexpr; int auto_name_counter, auto_name_offset, auto_name_digits; std::map auto_name_map; +std::set reg_wires, reg_ct; -std::set reg_wires; - -CellTypes reg_ct; RTLIL::Module *active_module; void reset_auto_counter_id(RTLIL::IdString id, bool may_rename) @@ -314,7 +312,7 @@ void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_ std::string cellname(RTLIL::Cell *cell) { - if (!norename && cell->name[0] == '$' && reg_ct.cell_known(cell->type) && cell->hasPort("\\Q")) + if (!norename && cell->name[0] == '$' && reg_ct.count(cell->type) && cell->hasPort("\\Q")) { RTLIL::SigSpec sig = cell->getPort("\\Q"); if (SIZE(sig) != 1 || sig.is_fully_const()) @@ -696,7 +694,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) return true; } - // FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_ + // FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_, $_DLATCHSR_[PN][PN][PN]_ // FIXME: $sr, $dffsr, $dlatch, $memrd, $memwr, $mem, $fsm return false; @@ -937,7 +935,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; - if (!reg_ct.cell_known(cell->type) || !cell->hasPort("\\Q")) + if (!reg_ct.count(cell->type) || !cell->hasPort("\\Q")) continue; RTLIL::SigSpec sig = cell->getPort("\\Q"); @@ -1047,10 +1045,30 @@ struct VerilogBackend : public Backend { bool selected = false; reg_ct.clear(); - reg_ct.setup_stdcells_mem(); - reg_ct.cell_types.insert("$sr"); - reg_ct.cell_types.insert("$dff"); - reg_ct.cell_types.insert("$adff"); + + reg_ct.insert("$dff"); + reg_ct.insert("$adff"); + + reg_ct.insert("$_DFF_N_"); + reg_ct.insert("$_DFF_P_"); + + reg_ct.insert("$_DFF_NN0_"); + reg_ct.insert("$_DFF_NN1_"); + reg_ct.insert("$_DFF_NP0_"); + reg_ct.insert("$_DFF_NP1_"); + reg_ct.insert("$_DFF_PN0_"); + reg_ct.insert("$_DFF_PN1_"); + reg_ct.insert("$_DFF_PP0_"); + reg_ct.insert("$_DFF_PP1_"); + + reg_ct.insert("$_DFFSR_NNN_"); + reg_ct.insert("$_DFFSR_NNP_"); + reg_ct.insert("$_DFFSR_NPN_"); + reg_ct.insert("$_DFFSR_NPP_"); + reg_ct.insert("$_DFFSR_PNN_"); + reg_ct.insert("$_DFFSR_PNP_"); + reg_ct.insert("$_DFFSR_PPN_"); + reg_ct.insert("$_DFFSR_PPP_"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 23d06f82..6beaa3fe 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -27,195 +27,165 @@ #include #include +struct CellType +{ + RTLIL::IdString type; + std::set inputs, outputs; + bool maybe_has_internal_state; +}; + struct CellTypes { - std::set cell_types; - std::vector designs; + std::map cell_types; CellTypes() { } - CellTypes(const RTLIL::Design *design) + CellTypes(RTLIL::Design *design) { setup(design); } - void setup(const RTLIL::Design *design = NULL) + void setup(RTLIL::Design *design = NULL) { if (design) setup_design(design); + setup_internals(); setup_internals_mem(); setup_stdcells(); setup_stdcells_mem(); } - void setup_design(const RTLIL::Design *design) + void setup_type(RTLIL::IdString type, const std::set &inputs, const std::set &outputs, bool maybe_has_internal_state) { - designs.push_back(design); + CellType ct = {type, inputs, outputs, maybe_has_internal_state}; + cell_types[ct.type] = ct; + } + + void setup_module(RTLIL::Module *module) + { + std::set inputs, outputs; + for (auto wire : module->wires()) { + if (wire->port_input) + inputs.insert(wire->name); + if (wire->port_output) + outputs.insert(wire->name); + } + setup_type(module->name, inputs, outputs, true); + } + + void setup_design(RTLIL::Design *design) + { + for (auto module : design->modules()) + setup_module(module); } void setup_internals() { - cell_types.insert("$not"); - cell_types.insert("$pos"); - cell_types.insert("$bu0"); - cell_types.insert("$neg"); - cell_types.insert("$and"); - cell_types.insert("$or"); - cell_types.insert("$xor"); - cell_types.insert("$xnor"); - cell_types.insert("$reduce_and"); - cell_types.insert("$reduce_or"); - cell_types.insert("$reduce_xor"); - cell_types.insert("$reduce_xnor"); - cell_types.insert("$reduce_bool"); - cell_types.insert("$shl"); - cell_types.insert("$shr"); - cell_types.insert("$sshl"); - cell_types.insert("$sshr"); - cell_types.insert("$shift"); - cell_types.insert("$shiftx"); - cell_types.insert("$lt"); - cell_types.insert("$le"); - cell_types.insert("$eq"); - cell_types.insert("$ne"); - cell_types.insert("$eqx"); - cell_types.insert("$nex"); - cell_types.insert("$ge"); - cell_types.insert("$gt"); - cell_types.insert("$add"); - cell_types.insert("$sub"); - cell_types.insert("$mul"); - cell_types.insert("$div"); - cell_types.insert("$mod"); - cell_types.insert("$pow"); - cell_types.insert("$logic_not"); - cell_types.insert("$logic_and"); - cell_types.insert("$logic_or"); - cell_types.insert("$mux"); - cell_types.insert("$pmux"); - cell_types.insert("$slice"); - cell_types.insert("$concat"); - cell_types.insert("$lut"); - cell_types.insert("$assert"); + std::vector unary_ops = { + "$not", "$pos", "$bu0", "$neg", + "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", + "$logic_not", "$slice" + }; + + std::vector binary_ops = { + "$and", "$or", "$xor", "$xnor", + "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", + "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", + "$add", "$sub", "$mul", "$div", "$mod", "$pow", + "$logic_and", "$logic_or", "$concat" + }; + + for (auto type : unary_ops) + setup_type(type, {"\\A"}, {"\\Y"}, false); + + for (auto type : binary_ops) + setup_type(type, {"\\A", "\\B"}, {"\\Y"}, false); + + for (auto type : std::vector({"$mux", "$pmux"})) + setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, false); + + setup_type("$lut", {"\\I"}, {"\\O"}, false); + setup_type("$assert", {"\\A", "\\EN"}, {}, false); } void setup_internals_mem() { - cell_types.insert("$sr"); - cell_types.insert("$dff"); - cell_types.insert("$dffsr"); - cell_types.insert("$adff"); - cell_types.insert("$dlatch"); - cell_types.insert("$dlatchsr"); - cell_types.insert("$memrd"); - cell_types.insert("$memwr"); - cell_types.insert("$mem"); - cell_types.insert("$fsm"); + setup_type("$sr", {"\\SET", "\\CLR"}, {"\\Q"}, true); + setup_type("$dff", {"\\CLK", "\\D"}, {"\\Q"}, true); + setup_type("$dffsr", {"\\CLK", "\\SET", "\\CLR", "\\D"}, {"\\Q"}, true); + setup_type("$adff", {"\\CLK", "\\ARST", "\\D"}, {"\\Q"}, true); + setup_type("$dlatch", {"\\EN", "\\D"}, {"\\Q"}, true); + setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}, true); + + setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}, true); + setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, {}, true); + setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"}, true); + + setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"}, true); } void setup_stdcells() { - cell_types.insert("$_INV_"); - cell_types.insert("$_AND_"); - cell_types.insert("$_OR_"); - cell_types.insert("$_XOR_"); - cell_types.insert("$_MUX_"); + setup_type("$_INV_", {"\\A"}, {"\\Y"}, false); + setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, false); + setup_type("$_OR_", {"\\A", "\\B"}, {"\\Y"}, false); + setup_type("$_XOR_", {"\\A", "\\B"}, {"\\Y"}, false); + setup_type("$_MUX_", {"\\A", "\\B", "\\S"}, {"\\Y"}, false); } void setup_stdcells_mem() { - cell_types.insert("$_SR_NN_"); - cell_types.insert("$_SR_NP_"); - cell_types.insert("$_SR_PN_"); - cell_types.insert("$_SR_PP_"); - cell_types.insert("$_DFF_N_"); - cell_types.insert("$_DFF_P_"); - cell_types.insert("$_DFF_NN0_"); - cell_types.insert("$_DFF_NN1_"); - cell_types.insert("$_DFF_NP0_"); - cell_types.insert("$_DFF_NP1_"); - cell_types.insert("$_DFF_PN0_"); - cell_types.insert("$_DFF_PN1_"); - cell_types.insert("$_DFF_PP0_"); - cell_types.insert("$_DFF_PP1_"); - cell_types.insert("$_DFFSR_NNN_"); - cell_types.insert("$_DFFSR_NNP_"); - cell_types.insert("$_DFFSR_NPN_"); - cell_types.insert("$_DFFSR_NPP_"); - cell_types.insert("$_DFFSR_PNN_"); - cell_types.insert("$_DFFSR_PNP_"); - cell_types.insert("$_DFFSR_PPN_"); - cell_types.insert("$_DFFSR_PPP_"); - cell_types.insert("$_DLATCH_N_"); - cell_types.insert("$_DLATCH_P_"); - cell_types.insert("$_DLATCHSR_NNN_"); - cell_types.insert("$_DLATCHSR_NNP_"); - cell_types.insert("$_DLATCHSR_NPN_"); - cell_types.insert("$_DLATCHSR_NPP_"); - cell_types.insert("$_DLATCHSR_PNN_"); - cell_types.insert("$_DLATCHSR_PNP_"); - cell_types.insert("$_DLATCHSR_PPN_"); - cell_types.insert("$_DLATCHSR_PPP_"); + std::vector list_np = {'N', 'P'}, list_01 = {'0', '1'}; + + for (auto c1 : list_np) + for (auto c2 : list_np) + setup_type(stringf("$_SR_%c%c_", c1, c2), {"\\S", "\\R"}, {"\\Q"}, true); + + for (auto c1 : list_np) + setup_type(stringf("$_DFF_%c_", c1), {"\\C", "\\D"}, {"\\Q"}, true); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_01) + setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {"\\C", "\\R", "\\D"}, {"\\Q"}, true); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_np) + setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {"\\C", "\\S", "\\R", "\\D"}, {"\\Q"}, true); + + for (auto c1 : list_np) + setup_type(stringf("$_DLATCH_%c_", c1), {"\\E", "\\D"}, {"\\Q"}, true); + + for (auto c1 : list_np) + for (auto c2 : list_np) + for (auto c3 : list_np) + setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {"\\E", "\\S", "\\R", "\\D"}, {"\\Q"}, true); } void clear() { cell_types.clear(); - designs.clear(); } bool cell_known(RTLIL::IdString type) { - if (cell_types.count(type) > 0) - return true; - for (auto design : designs) - if (design->modules_.count(type) > 0) - return true; - return false; + return cell_types.count(type) != 0; } bool cell_output(RTLIL::IdString type, RTLIL::IdString port) { - if (cell_types.count(type) == 0) { - for (auto design : designs) - if (design->modules_.count(type) > 0) { - if (design->modules_.at(type)->wires_.count(port)) - return design->modules_.at(type)->wires_.at(port)->port_output; - return false; - } - return false; - } - - if (port == "\\Y" || port == "\\Q" || port == "\\RD_DATA") - return true; - if (type == "$memrd" && port == "\\DATA") - return true; - if (type == "$fsm" && port == "\\CTRL_OUT") - return true; - if (type == "$lut" && port == "\\O") - return true; - return false; + auto it = cell_types.find(type); + return it != cell_types.end() && it->second.outputs.count(port) != 0; } bool cell_input(RTLIL::IdString type, RTLIL::IdString port) { - if (cell_types.count(type) == 0) { - for (auto design : designs) - if (design->modules_.count(type) > 0) { - if (design->modules_.at(type)->wires_.count(port)) - return design->modules_.at(type)->wires_.at(port)->port_input; - return false; - } - return false; - } - - if (cell_types.count(type) > 0) - return !cell_output(type, port); - - return false; + auto it = cell_types.find(type); + return it != cell_types.end() && it->second.inputs.count(port) != 0; } static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 201c717e..fdb33ed8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -503,7 +503,7 @@ namespace { cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:") return; - if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") { + if (cell->type.in("$not", "$pos", "$bu0", "$neg")) { param_bool("\\A_SIGNED"); port("\\A", param("\\A_WIDTH")); port("\\Y", param("\\Y_WIDTH")); @@ -511,7 +511,7 @@ namespace { return; } - if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") { + if (cell->type.in("$and", "$or", "$xor", "$xnor")) { param_bool("\\A_SIGNED"); param_bool("\\B_SIGNED"); port("\\A", param("\\A_WIDTH")); @@ -521,8 +521,7 @@ namespace { return; } - if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" || - cell->type == "$reduce_xnor" || cell->type == "$reduce_bool") { + if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool")) { param_bool("\\A_SIGNED"); port("\\A", param("\\A_WIDTH")); port("\\Y", param("\\Y_WIDTH")); @@ -530,8 +529,7 @@ namespace { return; } - if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || - cell->type == "$shift" || cell->type == "$shiftx") { + if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) { param_bool("\\A_SIGNED"); param_bool("\\B_SIGNED"); port("\\A", param("\\A_WIDTH")); @@ -541,8 +539,7 @@ namespace { return; } - if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || - cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") { + if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) { param_bool("\\A_SIGNED"); param_bool("\\B_SIGNED"); port("\\A", param("\\A_WIDTH")); @@ -552,8 +549,7 @@ namespace { return; } - if (cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || - cell->type == "$mod" || cell->type == "$pow") { + if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$pow")) { param_bool("\\A_SIGNED"); param_bool("\\B_SIGNED"); port("\\A", param("\\A_WIDTH")); From 1bf7a18fec76cf46a5b8710a75371e23b68d147d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 16:13:42 +0200 Subject: [PATCH 586/750] Added module->ports --- frontends/ast/ast.cc | 1 + frontends/ilang/parser.y | 1 + kernel/celltypes.h | 3 ++- kernel/rtlil.cc | 10 +++++++++- kernel/rtlil.h | 2 ++ passes/abc/blifparse.cc | 3 +-- passes/hierarchy/hierarchy.cc | 2 ++ passes/hierarchy/submod.cc | 7 +++---- passes/techmap/extract.cc | 4 ++-- 9 files changed, 23 insertions(+), 10 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f18124e2..9f17f3bf 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 f696140e..e1ef39a5 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: diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 6beaa3fe..5486f6ac 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -67,7 +67,8 @@ struct CellTypes void setup_module(RTLIL::Module *module) { std::set inputs, outputs; - for (auto wire : module->wires()) { + for (RTLIL::IdString wire_name : module->ports) { + RTLIL::Wire *wire = module->wire(wire_name); if (wire->port_input) inputs.insert(wire->name); if (wire->port_output) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index fdb33ed8..96ae0f97 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -821,6 +821,8 @@ void RTLIL::Module::check() for (auto &it2 : it.second->attributes) log_assert(!it2.first.empty()); if (it.second->port_id) { + log_assert(SIZE(ports) >= it.second->port_id); + log_assert(ports.at(it.second->port_id-1) == it.first); log_assert(it.second->port_input || it.second->port_output); if (SIZE(ports_declared) < it.second->port_id) ports_declared.resize(it.second->port_id); @@ -831,6 +833,7 @@ void RTLIL::Module::check() } for (auto port_declared : ports_declared) log_assert(port_declared == true); + log_assert(SIZE(ports) == SIZE(ports_declared)); for (auto &it : memories) { log_assert(it.first == it.second->name); @@ -915,6 +918,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const RewriteSigSpecWorker rewriteSigSpecWorker; rewriteSigSpecWorker.mod = new_mod; new_mod->rewrite_sigspecs(rewriteSigSpecWorker); + new_mod->fixup_ports(); } RTLIL::Module *RTLIL::Module::clone() const @@ -1154,8 +1158,12 @@ void RTLIL::Module::fixup_ports() w.second->port_id = 0; std::sort(all_ports.begin(), all_ports.end(), fixup_ports_compare); - for (size_t i = 0; i < all_ports.size(); i++) + + ports.clear(); + for (size_t i = 0; i < all_ports.size(); i++) { + ports.push_back(all_ports[i]->name); all_ports[i]->port_id = i+1; + } } RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 10da7463..0093b8a1 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -575,6 +575,8 @@ public: void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); void new_connections(const std::vector &new_conn); const std::vector &connections() const; + + std::vector ports; void fixup_ports(); template void rewrite_sigspecs(T functor); diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index 1891a745..bc8f343a 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -58,7 +58,6 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) RTLIL::Const *lutptr = NULL; RTLIL::State lut_default_state = RTLIL::State::Sx; - int port_count = 0; module->name = "\\netlist"; design->add(module); @@ -91,6 +90,7 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) continue; if (!strcmp(cmd, ".end")) { + module->fixup_ports(); free(buffer); return design; } @@ -99,7 +99,6 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) char *p; while ((p = strtok(NULL, " \t\r\n")) != NULL) { RTLIL::Wire *wire = module->addWire(stringf("\\%s", p)); - wire->port_id = ++port_count; if (!strcmp(cmd, ".inputs")) wire->port_input = true; else diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 50b4989d..2f28afb2 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -126,6 +126,8 @@ static void generate(RTLIL::Design *design, const std::vector &cell wire->port_output = decl.output; } + mod->fixup_ports(); + for (auto ¶ : parameters) log(" ignoring parameter %s.\n", RTLIL::id2cstr(para)); diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 89f45e02..1b03ab55 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -106,7 +106,7 @@ struct SubmodWorker RTLIL::Module *new_mod = new RTLIL::Module; new_mod->name = submod.full_name; design->add(new_mod); - int port_counter = 1, auto_name_counter = 1; + int auto_name_counter = 1; std::set all_wire_names; for (auto &it : wire_flags) { @@ -151,9 +151,6 @@ struct SubmodWorker new_wire->start_offset = wire->start_offset; new_wire->attributes = wire->attributes; - if (new_wire->port_input || new_wire->port_output) - new_wire->port_id = port_counter++; - if (new_wire->port_input && new_wire->port_output) log(" signal %s: inout %s\n", wire->name.c_str(), new_wire->name.c_str()); else if (new_wire->port_input) @@ -166,6 +163,8 @@ struct SubmodWorker flags.new_wire = new_wire; } + new_mod->fixup_ports(); + for (RTLIL::Cell *cell : submod.cells) { RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell); for (auto &conn : new_cell->connections_) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 985d51e5..ebf4d77f 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -726,14 +726,14 @@ struct ExtractPass : public Pass { newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, id2cstr(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits); map->add(newMod); - int portCounter = 1; for (auto wire : wires) { RTLIL::Wire *newWire = newMod->addWire(wire->name, wire->width); - newWire->port_id = portCounter++; newWire->port_input = true; newWire->port_output = true; } + newMod->fixup_ports(); + for (auto cell : cells) { RTLIL::Cell *newCell = newMod->addCell(cell->name, cell->type); newCell->parameters = cell->parameters; From 5602cbde9f9f86197511036d8873c0f8fb1ca5d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 20:53:21 +0200 Subject: [PATCH 587/750] Simplified $__arraymul techmap rule --- techlibs/common/techmap.v | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index e1d5bd82..7a4f6b27 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -502,15 +502,21 @@ module \$__arraymul (A, B, Y); input [WIDTH-1:0] A, B; output [WIDTH-1:0] Y; - wire [WIDTH*WIDTH-1:0] partials; + wire [1023:0] _TECHMAP_DO_ = "proc;;"; - genvar i; - assign partials[WIDTH-1 : 0] = A[0] ? B : 0; - generate for (i = 1; i < WIDTH; i = i+1) begin:gen - assign partials[WIDTH*(i+1)-1 : WIDTH*i] = (A[i] ? B << i : 0) + partials[WIDTH*i-1 : WIDTH*(i-1)]; - end endgenerate + integer i; + reg [WIDTH-1:0] x, y; - assign Y = partials[WIDTH*WIDTH-1 : WIDTH*(WIDTH-1)]; + always @* begin + x = B; + y = A[0] ? x : 0; + for (i = 1; i < WIDTH; i = i+1) begin + x = {x[WIDTH-2:0], 1'b0}; + y = y + (A[i] ? x : 0); + end + end + + assign Y = y; endmodule module \$mul (A, B, Y); From 85e3cc12ac44c44178185b918aa2a7fe9ca89918 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:26:10 +0200 Subject: [PATCH 588/750] Fixed handling of task outputs --- frontends/ast/simplify.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 39c47262..76d1f827 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) From 6d56172c0d16f80742c1c4588929d1805e3dd650 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:26:30 +0200 Subject: [PATCH 589/750] Fixed line numbers when using here-doc macros --- frontends/verilog/preproc.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 7935fbc3..ae139741 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') { From 2f44d8ccf853870a661b5e528c7e3ad3e17ca21e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:32:18 +0200 Subject: [PATCH 590/750] Added sig.{replace,remove,extract} variants for std::{map,set} pattern --- kernel/rtlil.cc | 77 ++++++++++++++++++++++++++++++++++--------------- kernel/rtlil.h | 12 +++++++- 2 files changed, 64 insertions(+), 25 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 96ae0f97..297537f0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2071,26 +2071,40 @@ void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const { - cover("kernel.rtlil.sigspec.replace"); + log_assert(pattern.width_ == with.width_); - unpack(); pattern.unpack(); with.unpack(); - log_assert(other != NULL); - log_assert(width_ == other->width_); - other->unpack(); + std::map rules; - log_assert(pattern.width_ == with.width_); - - std::map pattern_map; for (int i = 0; i < SIZE(pattern.bits_); i++) if (pattern.bits_[i].wire != NULL) - pattern_map[pattern.bits_[i]] = with.bits_[i]; + rules[pattern.bits_[i]] = with.bits_[i]; - for (int i = 0; i < SIZE(bits_); i++) - if (pattern_map.count(bits_[i])) - other->bits_[i] = pattern_map.at(bits_[i]); + replace(rules, other); +} + +void RTLIL::SigSpec::replace(const std::map &rules) +{ + replace(rules, this); +} + +void RTLIL::SigSpec::replace(const std::map &rules, RTLIL::SigSpec *other) const +{ + cover("kernel.rtlil.sigspec.replace"); + + log_assert(other != NULL); + log_assert(width_ == other->width_); + + unpack(); + other->unpack(); + + for (int i = 0; i < SIZE(bits_); i++) { + auto it = rules.find(bits_[i]); + if (it != rules.end()) + other->bits_[i] = it->second; + } other->check(); } @@ -2107,6 +2121,23 @@ void RTLIL::SigSpec::remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other } void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) +{ + std::set pattern_bits = pattern.to_sigbit_set(); + remove2(pattern_bits, other); +} + +void RTLIL::SigSpec::remove(const std::set &pattern) +{ + remove2(pattern, NULL); +} + +void RTLIL::SigSpec::remove(const std::set &pattern, RTLIL::SigSpec *other) const +{ + RTLIL::SigSpec tmp = *this; + tmp.remove2(pattern, other); +} + +void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigSpec *other) { if (other) cover("kernel.rtlil.sigspec.remove_other"); @@ -2120,11 +2151,10 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe other->unpack(); } - std::set pattern_bits = pattern.to_sigbit_set(); std::vector new_bits, new_other_bits; for (int i = 0; i < SIZE(bits_); i++) { - if (bits_[i].wire != NULL && pattern_bits.count(bits_[i])) + if (bits_[i].wire != NULL && pattern.count(bits_[i])) continue; if (other != NULL) new_other_bits.push_back(other->bits_[i]); @@ -2142,33 +2172,32 @@ void RTLIL::SigSpec::remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *othe check(); } -RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other) const +RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const +{ + std::set pattern_bits = pattern.to_sigbit_set(); + return extract(pattern_bits, other); +} + +RTLIL::SigSpec RTLIL::SigSpec::extract(const std::set &pattern, const RTLIL::SigSpec *other) const { if (other) cover("kernel.rtlil.sigspec.extract_other"); else cover("kernel.rtlil.sigspec.extract"); - pack(); - pattern.pack(); - - if (other != NULL) - other->pack(); - log_assert(other == NULL || width_ == other->width_); - std::set pat = pattern.to_sigbit_set(); std::vector bits_match = to_sigbit_vector(); RTLIL::SigSpec ret; if (other) { std::vector bits_other = other->to_sigbit_vector(); for (int i = 0; i < width_; i++) - if (bits_match[i].wire && pat.count(bits_match[i])) + if (bits_match[i].wire && pattern.count(bits_match[i])) ret.append_bit(bits_other[i]); } else { for (int i = 0; i < width_; i++) - if (bits_match[i].wire && pat.count(bits_match[i])) + if (bits_match[i].wire && pattern.count(bits_match[i])) ret.append_bit(bits_match[i]); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 0093b8a1..8f780c82 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -968,15 +968,25 @@ public: void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with); void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with, RTLIL::SigSpec *other) const; + + void replace(const std::map &rules); + void replace(const std::map &rules, RTLIL::SigSpec *other) const; + void replace(int offset, const RTLIL::SigSpec &with); void remove(const RTLIL::SigSpec &pattern); void remove(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other) const; void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other); + + void remove(const std::set &pattern); + void remove(const std::set &pattern, RTLIL::SigSpec *other) const; + void remove2(const std::set &pattern, RTLIL::SigSpec *other); + void remove(int offset, int length = 1); void remove_const(); - RTLIL::SigSpec extract(RTLIL::SigSpec pattern, const RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const; + RTLIL::SigSpec extract(const std::set &pattern, const RTLIL::SigSpec *other = NULL) const; RTLIL::SigSpec extract(int offset, int length = 1) const; void append(const RTLIL::SigSpec &signal); From c83b9904582b81e71c4c510ffdc26f9796f5da21 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 23:02:07 +0200 Subject: [PATCH 591/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 9f17f3bf..551859eb 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 5fb1f0a7..e7b07548 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 bea99d8d..24251486 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); From 978a933b6af8863200096bd3a56780e3378e4848 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 23:14:47 +0200 Subject: [PATCH 592/750] Added RTLIL::SigSpec::to_sigbit_map() --- frontends/ast/genrtlil.cc | 14 +++----------- kernel/rtlil.cc | 16 ++++++++++++++++ kernel/rtlil.h | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 24251486..3c8f1fa1 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)); } } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 297537f0..f4f32f60 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2687,6 +2687,22 @@ std::vector RTLIL::SigSpec::to_sigbit_vector() const return bits_; } +std::map RTLIL::SigSpec::to_sigbit_map(const RTLIL::SigSpec &other) const +{ + cover("kernel.rtlil.sigspec.to_sigbit_map"); + + unpack(); + other.unpack(); + + log_assert(width_ == other.width_); + + std::map new_map; + for (int i = 0; i < width_; i++) + new_map[bits_[i]] = other.bits_[i]; + + return new_map; +} + RTLIL::SigBit RTLIL::SigSpec::to_single_sigbit() const { cover("kernel.rtlil.sigspec.to_single_sigbit"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8f780c82..3a0f0ff8 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1020,6 +1020,7 @@ public: std::set to_sigbit_set() const; std::vector to_sigbit_vector() const; + std::map to_sigbit_map(const RTLIL::SigSpec &other) const; RTLIL::SigBit to_single_sigbit() const; static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str); From c7afbd9d8efcf3045d9e4244600ce8d8e0d40b6d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 01:53:22 +0200 Subject: [PATCH 593/750] Fixed bug in "read_verilog -ignore_redef" --- frontends/ast/ast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 551859eb..ec9616be 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; } From d320e750877a6cf8d5993da6d2cd121fe5b4d78e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 02:00:53 +0200 Subject: [PATCH 594/750] document "techmap -map %" --- passes/techmap/techmap.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 29ce9676..a7f91e86 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -706,6 +706,9 @@ struct TechmapPass : public Pass { log(" transforms the internal RTL cells to the internal gate\n"); log(" library.\n"); log("\n"); + log(" -map %%\n"); + log(" like -map above, but with an in-memory design instead of a file.\n"); + log("\n"); log(" -share_map filename\n"); log(" like -map, but look for the file in the share directory (where the\n"); log(" yosys data files are). this is mainly used internally when techmap\n"); From 8ff71b5ae506306d7981eb118874cd4f407b2bf8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 02:08:02 +0200 Subject: [PATCH 595/750] Added Frontend "+/" filename syntax for files from proc_share_dir --- kernel/register.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/register.cc b/kernel/register.cc index 868dbb94..a9e21e6d 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -339,8 +339,11 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vector Date: Fri, 15 Aug 2014 02:40:46 +0200 Subject: [PATCH 596/750] More idstring sort_by_* helpers and fixed tpl ordering in techmap --- kernel/rtlil.h | 14 +++++++++++++- passes/fsm/fsm_expand.cc | 8 ++++---- passes/opt/opt_clean.cc | 4 ++-- passes/techmap/techmap.cc | 6 +++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 3a0f0ff8..2c4b26f5 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -255,12 +255,24 @@ namespace RTLIL return log_id(str); } - template struct sort_by_name { + template struct sort_by_name_id { bool operator()(T *a, T *b) const { return a->name < b->name; } }; + template struct sort_by_name_str { + bool operator()(T *a, T *b) const { + return strcmp(a->name.c_str(), b->name.c_str()) < 0; + } + }; + + struct sort_by_id_str { + bool operator()(RTLIL::IdString a, RTLIL::IdString b) const { + return strcmp(a.c_str(), b.c_str()) < 0; + } + }; + // see calc.cc for the implementation of this functions RTLIL::Const const_not (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_and (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc index 77821326..d1364391 100644 --- a/passes/fsm/fsm_expand.cc +++ b/passes/fsm/fsm_expand.cc @@ -30,12 +30,12 @@ struct FsmExpand RTLIL::Module *module; RTLIL::Cell *fsm_cell; SigMap assign_map; - SigSet> sig2driver, sig2user; + SigSet> sig2driver, sig2user; CellTypes ct; - std::set> merged_set; - std::set> current_set; - std::set> no_candidate_set; + std::set> merged_set; + std::set> current_set; + std::set> no_candidate_set; bool already_optimized; int limit_transitions; diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index c620531e..d47e4513 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -34,7 +34,7 @@ static int count_rm_cells, count_rm_wires; static void rmunused_module_cells(RTLIL::Module *module, bool verbose) { SigMap assign_map(module); - std::set> queue, unused; + std::set> queue, unused; SigSet wire2driver; for (auto &it : module->cells_) { @@ -65,7 +65,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) while (queue.size() > 0) { - std::set> new_queue; + std::set> new_queue; for (auto cell : queue) unused.erase(cell); for (auto cell : queue) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index a7f91e86..59173393 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -251,7 +251,7 @@ struct TechmapWorker } bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set &handled_cells, - const std::map> &celltypeMap, bool in_recursion) + const std::map> &celltypeMap, bool in_recursion) { std::string mapmsg_prefix = in_recursion ? "Recursively mapping" : "Mapping"; @@ -898,7 +898,7 @@ struct TechmapPass : public Pass { } map->modules_.swap(modules_new); - std::map> celltypeMap; + std::map> celltypeMap; for (auto &it : map->modules_) { if (it.second->attributes.count("\\techmap_celltype") && !it.second->attributes.at("\\techmap_celltype").bits.empty()) { char *p = strdup(it.second->attributes.at("\\techmap_celltype").decode_string().c_str()); @@ -960,7 +960,7 @@ struct FlattenPass : public Pass { TechmapWorker worker; worker.flatten_mode = true; - std::map> celltypeMap; + std::map> celltypeMap; for (auto &it : design->modules_) celltypeMap[it.first].insert(it.first); From bf486002d9a6d976b3d086700ccdcfb0fb70ba0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:04:35 +0200 Subject: [PATCH 597/750] Removed old doc references to $safe_pmux --- manual/CHAPTER_CellLib.tex | 4 ---- manual/CHAPTER_Optimize.tex | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index f09c4929..f05c1b7a 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -125,10 +125,6 @@ than one bit from \B{S} is set the output is undefined. Cells of this type are u ``parallel cases'' (defined by using the {\tt parallel\_case} attribute or detected by an optimization). -The {\tt \$safe\_pmux} behaves similarly to the {\tt \$pmux} cell type. But when more than one bit -of \B{S} is set, it is guaranteed that this cell type will output the value of the \B{A} input instead of -an undefined value. - Behavioural code with cascaded {\tt if-then-else}- and {\tt case}-statements usually results in trees of multiplexer cells. Many passes (from various optimizations to FSM extraction) heavily depend on these multiplexer trees to diff --git a/manual/CHAPTER_Optimize.tex b/manual/CHAPTER_Optimize.tex index c562650b..af8e2249 100644 --- a/manual/CHAPTER_Optimize.tex +++ b/manual/CHAPTER_Optimize.tex @@ -136,7 +136,7 @@ This pass performs trivial resource sharing. This means that this pass identifie with identical inputs and replaces them with a single instance of the cell. The option {\tt -nomux} can be used to disable resource sharing for multiplexer -cells ({\tt \$mux}, {\tt \$pmux}, and {\tt \$safe\_pmux}). This can be useful as +cells ({\tt \$mux} and {\tt \$pmux}. This can be useful as it prevents multiplexer trees to be merged, which might prevent {\tt opt\_muxtree} to identify possible optimizations. From f092b5014895dc5dc62b8103fcedf94cfa9f85a8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:11:40 +0200 Subject: [PATCH 598/750] Renamed $_INV_ cell type to $_NOT_ --- backends/blif/blif.cc | 2 +- backends/verilog/verilog_backend.cc | 2 +- frontends/liberty/liberty.cc | 22 ++++++++++----------- frontends/verific/verific.cc | 6 +++--- kernel/celltypes.h | 4 ++-- kernel/rtlil.cc | 4 ++-- kernel/rtlil.h | 4 ++-- kernel/satgen.h | 2 +- manual/CHAPTER_CellLib.tex | 4 ++-- manual/CHAPTER_StateOfTheArt/simlib_yosys.v | 4 ++-- manual/PRESENTATION_ExSyn.tex | 2 +- manual/PRESENTATION_Prog.tex | 2 +- passes/abc/abc.cc | 4 ++-- passes/opt/opt_const.cc | 12 +++++------ passes/sat/freduce.cc | 4 ++-- passes/techmap/dfflibmap.cc | 2 +- passes/techmap/simplemap.cc | 8 ++++---- techlibs/common/simcells.v | 4 ++-- techlibs/common/techmap.v | 2 +- 19 files changed, 47 insertions(+), 47 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 5daab669..386d68d8 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -143,7 +143,7 @@ struct BlifDumper { RTLIL::Cell *cell = cell_it.second; - if (!config->icells_mode && cell->type == "$_INV_") { + if (!config->icells_mode && cell->type == "$_NOT_") { fprintf(f, ".names %s %s\n0 1\n", cstr(cell->getPort("\\A")), cstr(cell->getPort("\\Y"))); continue; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index cafc1f3f..81c938bd 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -370,7 +370,7 @@ void dump_cell_expr_binop(FILE *f, std::string indent, RTLIL::Cell *cell, std::s bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) { - if (cell->type == "$_INV_") { + if (cell->type == "$_NOT_") { fprintf(f, "%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = "); diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 504b8d1e..83bfce37 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 1ffcc422..95b3c407 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; } diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 5486f6ac..e30ceb8b 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -130,7 +130,7 @@ struct CellTypes void setup_stdcells() { - setup_type("$_INV_", {"\\A"}, {"\\Y"}, false); + setup_type("$_NOT_", {"\\A"}, {"\\Y"}, false); setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, false); setup_type("$_OR_", {"\\A", "\\B"}, {"\\Y"}, false); setup_type("$_XOR_", {"\\A", "\\B"}, {"\\Y"}, false); @@ -241,7 +241,7 @@ struct CellTypes HANDLE_CELL_TYPE(neg) #undef HANDLE_CELL_TYPE - if (type == "$_INV_") + if (type == "$_NOT_") return const_not(arg1, arg2, false, false, 1); if (type == "$_AND_") return const_and(arg1, arg2, false, false, 1); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f4f32f60..614ea770 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -758,7 +758,7 @@ namespace { return; } - if (cell->type == "$_INV_") { check_gate("AY"); return; } + if (cell->type == "$_NOT_") { check_gate("AY"); return; } if (cell->type == "$_AND_") { check_gate("ABY"); return; } if (cell->type == "$_OR_") { check_gate("ABY"); return; } if (cell->type == "$_XOR_") { check_gate("ABY"); return; } @@ -1338,7 +1338,7 @@ DEF_METHOD(Pmux, "$pmux", 1) add ## _func(name, sig1, sig2, sig3, sig4); \ return sig4; \ } -DEF_METHOD_2(InvGate, "$_INV_", A, Y) +DEF_METHOD_2(NotGate, "$_NOT_", A, Y) DEF_METHOD_3(AndGate, "$_AND_", A, B, Y) DEF_METHOD_3(OrGate, "$_OR_", A, B, Y) DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 2c4b26f5..43e36cbd 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -694,7 +694,7 @@ public: RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true); - RTLIL::Cell* addInvGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y); + RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y); RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); @@ -757,7 +757,7 @@ public: RTLIL::SigSpec Mux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); RTLIL::SigSpec Pmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); - RTLIL::SigSpec InvGate (RTLIL::IdString name, RTLIL::SigSpec sig_a); + RTLIL::SigSpec NotGate (RTLIL::IdString name, RTLIL::SigSpec sig_a); RTLIL::SigSpec AndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); RTLIL::SigSpec OrGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); RTLIL::SigSpec XorGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); diff --git a/kernel/satgen.h b/kernel/satgen.h index 8284cdeb..b57edd9f 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -271,7 +271,7 @@ struct SatGen return true; } - if (cell->type == "$_INV_" || cell->type == "$not") + if (cell->type == "$_NOT_" || cell->type == "$not") { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index f05c1b7a..ea4ae8d4 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -371,7 +371,7 @@ source tree. \begin{tabular}[t]{ll} Verilog & Cell Type \\ \hline -\lstinline[language=Verilog]; Y = ~A; & {\tt \$\_INV\_} \\ +\lstinline[language=Verilog]; Y = ~A; & {\tt \$\_NOT\_} \\ \lstinline[language=Verilog]; Y = A & B; & {\tt \$\_AND\_} \\ \lstinline[language=Verilog]; Y = A | B; & {\tt \$\_OR\_} \\ \lstinline[language=Verilog]; Y = A ^ B; & {\tt \$\_XOR\_} \\ @@ -398,7 +398,7 @@ $ClkEdge$ & $RstLvl$ & $RstVal$ & Cell Type \\ \end{table} Table~\ref{tab:CellLib_gates} lists all cell types used for gate level logic. The cell types -{\tt \$\_INV\_}, {\tt \$\_AND\_}, {\tt \$\_OR\_}, {\tt \$\_XOR\_} and {\tt \$\_MUX\_} +{\tt \$\_NOT\_}, {\tt \$\_AND\_}, {\tt \$\_OR\_}, {\tt \$\_XOR\_} and {\tt \$\_MUX\_} are used to model combinatorial logic. The cell types {\tt \$\_DFF\_N\_} and {\tt \$\_DFF\_P\_} represent d-type flip-flops. diff --git a/manual/CHAPTER_StateOfTheArt/simlib_yosys.v b/manual/CHAPTER_StateOfTheArt/simlib_yosys.v index a2df8f64..54c07661 100644 --- a/manual/CHAPTER_StateOfTheArt/simlib_yosys.v +++ b/manual/CHAPTER_StateOfTheArt/simlib_yosys.v @@ -20,12 +20,12 @@ * The internal logic cell simulation library. * * This verilog library contains simple simulation models for the internal - * logic cells (_INV_, _AND_, ...) that are generated by the default technology + * logic cells (_NOT_, _AND_, ...) that are generated by the default technology * mapper (see "stdcells.v" in this directory) and expected by the "abc" pass. * */ -module _INV_(A, Y); +module _NOT_(A, Y); input A; output Y; assign Y = ~A; diff --git a/manual/PRESENTATION_ExSyn.tex b/manual/PRESENTATION_ExSyn.tex index f68b6f98..80398229 100644 --- a/manual/PRESENTATION_ExSyn.tex +++ b/manual/PRESENTATION_ExSyn.tex @@ -367,7 +367,7 @@ to map all RTL cell types to a generic library of built-in logic gates and regis \bigskip \begin{block}{The built-in logic gate types are:} -{\tt \$\_INV\_ \$\_AND\_ \$\_OR\_ \$\_XOR\_ \$\_MUX\_} +{\tt \$\_NOT\_ \$\_AND\_ \$\_OR\_ \$\_XOR\_ \$\_MUX\_} \end{block} \bigskip diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index 3b214544..4e9f4b21 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -303,7 +303,7 @@ cell name from the internal cell library: $not $pos $bu0 $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor $reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff -$dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_INV_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ +$dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_NOT_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ $_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_ $_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_ $_DFFSR_PNP_ $_DFFSR_PPN_ $_DFFSR_PPP_ $_DLATCH_N_ $_DLATCH_P_ $_DLATCHSR_NNN_ $_DLATCHSR_NNP_ diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index e7da6ed4..2b1d4981 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -130,7 +130,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) return; } - if (cell->type == "$_INV_") + if (cell->type == "$_NOT_") { RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_y = cell->getPort("\\Y"); @@ -733,7 +733,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std continue; } if (c->type == "\\INV") { - RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_INV_"); + RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_NOT_"); cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); design->select(module, cell); diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index a13bb09c..9af1e6bd 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -209,7 +209,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo for (auto cell : module->cells()) if (design->selected(module, cell) && cell->type[0] == '$') { - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && + if ((cell->type == "$_NOT_" || cell->type == "$not" || cell->type == "$logic_not") && cell->getPort("\\A").size() == 1 && cell->getPort("\\Y").size() == 1) invert_map[assign_map(cell->getPort("\\Y"))] = assign_map(cell->getPort("\\A")); if (ct_combinational.cell_known(cell->type)) @@ -371,9 +371,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } } - if ((cell->type == "$_INV_" || cell->type == "$not" || cell->type == "$logic_not") && cell->getPort("\\Y").size() == 1 && + if ((cell->type == "$_NOT_" || cell->type == "$not" || cell->type == "$logic_not") && cell->getPort("\\Y").size() == 1 && invert_map.count(assign_map(cell->getPort("\\A"))) != 0) { - cover_list("opt.opt_const.invert.double", "$_INV_", "$not", "$logic_not", cell->type.str()); + cover_list("opt.opt_const.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); replace_cell(assign_map, module, cell, "double_invert", "\\Y", invert_map.at(assign_map(cell->getPort("\\A")))); goto next_cell; } @@ -389,7 +389,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo goto next_cell; } - if (cell->type == "$_INV_") { + if (cell->type == "$_NOT_") { RTLIL::SigSpec input = cell->getPort("\\A"); assign_map.apply(input); if (input.match("1")) ACTION_DO_Y(0); @@ -463,7 +463,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (input.match("01 ")) ACTION_DO("\\Y", input.extract(0, 1)); if (input.match("10 ")) { cover("opt.opt_const.mux_to_inv"); - cell->type = "$_INV_"; + cell->type = "$_NOT_"; cell->setPort("\\A", input.extract(0, 1)); cell->unsetPort("\\B"); cell->unsetPort("\\S"); @@ -648,7 +648,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->parameters.erase("\\WIDTH"); cell->type = "$not"; } else - cell->type = "$_INV_"; + cell->type = "$_NOT_"; OPT_DID_SOMETHING = true; did_something = true; goto next_cell; diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 7b9fb207..bfed0005 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -623,7 +623,7 @@ struct FreduceWorker batches.push_back(outputs); bits_full_total += outputs.size(); } - if (inv_mode && it.second->type == "$_INV_") + if (inv_mode && it.second->type == "$_NOT_") inv_pairs.insert(std::pair(sigmap(it.second->getPort("\\A")), sigmap(it.second->getPort("\\Y")))); } @@ -718,7 +718,7 @@ struct FreduceWorker { inv_sig = module->addWire(NEW_ID); - RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_NOT_"); inv_cell->setPort("\\A", grp[0].bit); inv_cell->setPort("\\Y", inv_sig); } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 16518b7d..6ce771ac 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -411,7 +411,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } else if ('a' <= port.second && port.second <= 'z') { sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))]; - sig = module->InvGate(NEW_ID, sig); + sig = module->NotGate(NEW_ID, sig); } else if (port.second == '0' || port.second == '1') { sig = RTLIL::SigSpec(port.second == '0' ? 0 : 1, 1); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 960578b0..f5d9bbee 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -34,7 +34,7 @@ static void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); for (int i = 0; i < SIZE(sig_y); i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); gate->setPort("\\A", sig_a[i]); gate->setPort("\\Y", sig_y[i]); } @@ -74,7 +74,7 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_t = module->addWire(NEW_ID, SIZE(sig_y)); for (int i = 0; i < SIZE(sig_y); i++) { - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); gate->setPort("\\A", sig_t[i]); gate->setPort("\\Y", sig_y[i]); } @@ -152,7 +152,7 @@ static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) if (cell->type == "$reduce_xnor") { RTLIL::SigSpec sig_t = module->addWire(NEW_ID); - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); gate->setPort("\\A", sig_a); gate->setPort("\\Y", sig_t); last_output_cell = gate; @@ -207,7 +207,7 @@ static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) sig_y = sig_y.extract(0, 1); } - RTLIL::Cell *gate = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *gate = module->addCell(NEW_ID, "$_NOT_"); gate->setPort("\\A", sig_a); gate->setPort("\\Y", sig_y); } diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index d492c2f1..7c8a47dd 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -20,12 +20,12 @@ * The internal logic cell simulation library. * * This verilog library contains simple simulation models for the internal - * logic cells ($_INV_ , $_AND_ , ...) that are generated by the default technology + * logic cells ($_NOT_ , $_AND_ , ...) that are generated by the default technology * mapper (see "techmap.v" in this directory) and expected by the "abc" pass. * */ -module \$_INV_ (A, Y); +module \$_NOT_ (A, Y); input A; output Y; assign Y = ~A; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 7a4f6b27..190002c0 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -20,7 +20,7 @@ * The internal logic cell technology mapper. * * This verilog library contains the mapping of internal cells (e.g. $not with - * variable bit width) to the internal logic cells (such as the single bit $_INV_ + * variable bit width) to the internal logic cells (such as the single bit $_NOT_ * gate). Usually this logic network is then mapped to the actual technology * using e.g. the "abc" pass. * From b64b38eea2e9a7de30d6045f069c86bf4446134f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:18:40 +0200 Subject: [PATCH 599/750] Renamed $lut ports to follow A-Y naming scheme --- backends/blif/blif.cc | 4 ++-- kernel/celltypes.h | 3 +-- kernel/rtlil.cc | 8 ++++---- passes/abc/blifparse.cc | 4 ++-- techlibs/common/simlib.v | 22 +++++++++++----------- techlibs/xilinx/cells.v | 36 ++++++++++++++++++------------------ 6 files changed, 38 insertions(+), 39 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 386d68d8..b9b68b97 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -188,13 +188,13 @@ struct BlifDumper if (!config->icells_mode && cell->type == "$lut") { fprintf(f, ".names"); - auto &inputs = cell->getPort("\\I"); + auto &inputs = cell->getPort("\\A"); auto width = cell->parameters.at("\\WIDTH").as_int(); log_assert(inputs.size() == width); for (int i = 0; i < inputs.size(); i++) { fprintf(f, " %s", cstr(inputs.extract(i, 1))); } - auto &output = cell->getPort("\\O"); + auto &output = cell->getPort("\\Y"); log_assert(output.size() == 1); fprintf(f, " %s", cstr(output)); fprintf(f, "\n"); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index e30ceb8b..402d6ea7 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -88,7 +88,7 @@ struct CellTypes std::vector unary_ops = { "$not", "$pos", "$bu0", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", - "$logic_not", "$slice" + "$logic_not", "$slice", "$lut" }; std::vector binary_ops = { @@ -108,7 +108,6 @@ struct CellTypes for (auto type : std::vector({"$mux", "$pmux"})) setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, false); - setup_type("$lut", {"\\I"}, {"\\O"}, false); setup_type("$assert", {"\\A", "\\EN"}, {}, false); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 614ea770..d118b625 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -615,8 +615,8 @@ namespace { if (cell->type == "$lut") { param("\\LUT"); - port("\\I", param("\\WIDTH")); - port("\\O", 1); + port("\\A", param("\\WIDTH")); + port("\\Y", 1); check_expected(); return; } @@ -1388,8 +1388,8 @@ RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_i, R RTLIL::Cell *cell = addCell(name, "$lut"); cell->parameters["\\LUT"] = lut; cell->parameters["\\WIDTH"] = sig_i.size(); - cell->setPort("\\I", sig_i); - cell->setPort("\\O", sig_o); + cell->setPort("\\A", sig_i); + cell->setPort("\\Y", sig_o); return cell; } diff --git a/passes/abc/blifparse.cc b/passes/abc/blifparse.cc index bc8f343a..1fbb5720 100644 --- a/passes/abc/blifparse.cc +++ b/passes/abc/blifparse.cc @@ -195,8 +195,8 @@ RTLIL::Design *abc_parse_blif(FILE *f, std::string dff_name) RTLIL::Cell *cell = module->addCell(NEW_ID, "$lut"); cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size()); cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size()); - cell->setPort("\\I", input_sig); - cell->setPort("\\O", output_sig); + cell->setPort("\\A", input_sig); + cell->setPort("\\Y", output_sig); lutptr = &cell->parameters.at("\\LUT"); lut_default_state = RTLIL::State::Sx; continue; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 4b3317a7..8c0a54e4 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -955,13 +955,13 @@ endmodule // -------------------------------------------------------- `ifndef SIMLIB_NOLUT -module \$lut (I, O); +module \$lut (A, Y); parameter WIDTH = 0; parameter LUT = 0; -input [WIDTH-1:0] I; -output reg O; +input [WIDTH-1:0] A; +output reg Y; wire lut0_out, lut1_out; @@ -969,18 +969,18 @@ generate if (WIDTH <= 1) begin:simple assign {lut1_out, lut0_out} = LUT; end else begin:complex - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .I(I[WIDTH-2:0]), .O(lut0_out) ); - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .I(I[WIDTH-2:0]), .O(lut1_out) ); + \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .A(A[WIDTH-2:0]), .Y(lut0_out) ); + \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .A(A[WIDTH-2:0]), .Y(lut1_out) ); end if (WIDTH > 0) begin:lutlogic always @* begin - casez ({I[WIDTH-1], lut0_out, lut1_out}) - 3'b?11: O = 1'b1; - 3'b?00: O = 1'b0; - 3'b0??: O = lut0_out; - 3'b1??: O = lut1_out; - default: O = 1'bx; + casez ({A[WIDTH-1], lut0_out, lut1_out}) + 3'b?11: Y = 1'b1; + 3'b?00: Y = 1'b0; + 3'b0??: Y = lut0_out; + 3'b1??: Y = lut1_out; + default: Y = 1'bx; endcase end end diff --git a/techlibs/xilinx/cells.v b/techlibs/xilinx/cells.v index 5bf8ccd8..d19be0db 100644 --- a/techlibs/xilinx/cells.v +++ b/techlibs/xilinx/cells.v @@ -10,41 +10,41 @@ module \$_DFF_P_ (D, C, Q); endmodule -module \$lut (I, O); +module \$lut (A, Y); parameter WIDTH = 0; parameter LUT = 0; - input [WIDTH-1:0] I; - output O; + input [WIDTH-1:0] A; + output Y; generate if (WIDTH == 1) begin:lut1 - LUT1 #(.INIT(LUT)) fpga_lut (.O(O), - .I0(I[0])); + LUT1 #(.INIT(LUT)) fpga_lut (.O(Y), + .I0(A[0])); end else if (WIDTH == 2) begin:lut2 - LUT2 #(.INIT(LUT)) fpga_lut (.O(O), - .I0(I[0]), .I1(I[1])); + LUT2 #(.INIT(LUT)) fpga_lut (.O(Y), + .I0(A[0]), .I1(A[1])); end else if (WIDTH == 3) begin:lut3 - LUT3 #(.INIT(LUT)) fpga_lut (.O(O), - .I0(I[0]), .I1(I[1]), .I2(I[2])); + LUT3 #(.INIT(LUT)) fpga_lut (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2])); end else if (WIDTH == 4) begin:lut4 - LUT4 #(.INIT(LUT)) fpga_lut (.O(O), - .I0(I[0]), .I1(I[1]), .I2(I[2]), - .I3(I[3])); + LUT4 #(.INIT(LUT)) fpga_lut (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3])); end else if (WIDTH == 5) begin:lut5 - LUT5 #(.INIT(LUT)) fpga_lut (.O(O), - .I0(I[0]), .I1(I[1]), .I2(I[2]), - .I3(I[3]), .I4(I[4])); + LUT5 #(.INIT(LUT)) fpga_lut (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4])); end else if (WIDTH == 6) begin:lut6 - LUT6 #(.INIT(LUT)) fpga_lut (.O(O), - .I0(I[0]), .I1(I[1]), .I2(I[2]), - .I3(I[3]), .I4(I[4]), .I5(I[5])); + LUT6 #(.INIT(LUT)) fpga_lut (.O(Y), + .I0(A[0]), .I1(A[1]), .I2(A[2]), + .I3(A[3]), .I4(A[4]), .I5(A[5])); end else begin:error wire _TECHMAP_FAIL_ = 1; end From 674f421b476295d3376ec00644181fc9be02ccaf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:29:42 +0200 Subject: [PATCH 600/750] Bugfix in iopadmap --- passes/techmap/iopadmap.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index 194e06a4..9cd23ce6 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -164,8 +164,10 @@ struct IopadmapPass : public Pass { log("Mapping port %s.%s using %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name), celltype.c_str()); RTLIL::Wire *new_wire = NULL; - if (!portname2.empty()) + if (!portname2.empty()) { new_wire = module->addWire(NEW_ID, wire); + module->swap_names(new_wire, wire); + } if (flag_bits) { From dbdf89c7054a3f249d7579cb50d10b72b1ac592d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 15:34:00 +0200 Subject: [PATCH 601/750] Added log_spacer() --- kernel/driver.cc | 3 ++- kernel/log.cc | 18 +++++++++++++++++- kernel/log.h | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 6f976423..d59e68a5 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -274,7 +274,8 @@ int main(int argc, char **argv) struct rusage ru_buffer; getrusage(RUSAGE_SELF, &ru_buffer); - log("\nEnd of script. Logfile hash: %s, CPU: user %.2fs system %.2fs\n", hash.c_str(), + log_spacer(); + log("End of script. Logfile hash: %s, CPU: user %.2fs system %.2fs\n", hash.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec, ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec); log("%s\n", yosys_version_str); diff --git a/kernel/log.cc b/kernel/log.cc index 1f082603..b742a549 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -45,6 +45,7 @@ int string_buf_size = 0; static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; +static int log_newline_count = 0; void logv(const char *format, va_list ap) { @@ -55,6 +56,15 @@ void logv(const char *format, va_list ap) std::string str = vstringf(format, ap); + if (str.empty()) + return; + + size_t nnl_pos = str.find_last_not_of('\n'); + if (nnl_pos == std::string::npos) + log_newline_count += SIZE(str); + else + log_newline_count = SIZE(str) - nnl_pos - 1; + if (log_hasher) log_hasher->update(str); @@ -92,7 +102,7 @@ void logv_header(const char *format, va_list ap) { bool pop_errfile = false; - log("\n"); + log_spacer(); if (header_count.size() > 0) header_count.back()++; @@ -160,6 +170,12 @@ void log_cmd_error(const char *format, ...) logv_error(format, ap); } +void log_spacer() +{ + while (log_newline_count < 2) + log("\n"); +} + void log_push() { header_count.push_back(0); diff --git a/kernel/log.h b/kernel/log.h index 037a62a3..b1c44b46 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -51,6 +51,7 @@ void log_header(const char *format, ...) __attribute__ ((format (printf, 1, 2))) void log_error(const char *format, ...) __attribute__ ((format (printf, 1, 2))) __attribute__ ((noreturn)); void log_cmd_error(const char *format, ...) __attribute__ ((format (printf, 1, 2))) __attribute__ ((noreturn)); +void log_spacer(); void log_push(); void log_pop(); From eb17fbade5ef89983993d1e9d47da5f8a2fb32c3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 15:34:15 +0200 Subject: [PATCH 602/750] Added "opt -fast" --- passes/opt/opt.cc | 64 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index 33e1507b..b6d36f0e 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -37,7 +37,7 @@ struct OptPass : public Pass { log("a series of trivial optimizations and cleanups. This pass executes the other\n"); log("passes in the following order:\n"); log("\n"); - log(" opt_const\n"); + log(" opt_const [-mux_undef] [-mux_bool] [-undriven] [-fine] [-keepdc]\n"); log(" opt_share -nomux\n"); log("\n"); log(" do\n"); @@ -49,15 +49,26 @@ struct OptPass : public Pass { log(" opt_const [-mux_undef] [-mux_bool] [-undriven] [-fine] [-keepdc]\n"); log(" while \n"); log("\n"); + log("When called with -fast the following script is used instead:\n"); + log("\n"); + log(" do\n"); + log(" opt_const [-mux_undef] [-mux_bool] [-undriven] [-fine] [-keepdc]\n"); + log(" opt_share\n"); + log(" opt_rmdff\n"); + log(" opt_clean [-purge]\n"); + log(" while \n"); + log("\n"); log("Note: Options in square brackets (such as [-keepdc]) are passed through to\n"); log("the opt_* commands when given to 'opt'.\n"); log("\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { std::string opt_clean_args; std::string opt_const_args; std::string opt_reduce_args; + bool fast_mode = false; log_header("Executing OPT pass (performing simple optimizations).\n"); log_push(); @@ -89,32 +100,47 @@ struct OptPass : public Pass { opt_const_args += " -keepdc"; continue; } + if (args[argidx] == "-fast") { + fast_mode = true; + continue; + } break; } extra_args(args, argidx, design); - log_header("Optimizing in-memory representation of design.\n"); - design->optimize(); - - Pass::call(design, "opt_const"); - Pass::call(design, "opt_share -nomux"); - while (1) { - OPT_DID_SOMETHING = false; - Pass::call(design, "opt_muxtree"); - Pass::call(design, "opt_reduce" + opt_reduce_args); - Pass::call(design, "opt_share"); - Pass::call(design, "opt_rmdff"); + if (fast_mode) + { + while (1) { + Pass::call(design, "opt_const" + opt_const_args); + Pass::call(design, "opt_share"); + OPT_DID_SOMETHING = false; + Pass::call(design, "opt_rmdff"); + if (OPT_DID_SOMETHING == false) + break; + Pass::call(design, "opt_clean" + opt_clean_args); + log_header("Rerunning OPT passes. (Removed registers in this run.)\n"); + } Pass::call(design, "opt_clean" + opt_clean_args); + } + else + { Pass::call(design, "opt_const" + opt_const_args); - if (OPT_DID_SOMETHING == false) - break; - log_header("Rerunning OPT passes. (Maybe there is more to do..)\n"); + Pass::call(design, "opt_share -nomux"); + while (1) { + OPT_DID_SOMETHING = false; + Pass::call(design, "opt_muxtree"); + Pass::call(design, "opt_reduce" + opt_reduce_args); + Pass::call(design, "opt_share"); + Pass::call(design, "opt_rmdff"); + Pass::call(design, "opt_clean" + opt_clean_args); + Pass::call(design, "opt_const" + opt_const_args); + if (OPT_DID_SOMETHING == false) + break; + log_header("Rerunning OPT passes. (Maybe there is more to do..)\n"); + } } - log_header("Optimizing in-memory representation of design.\n"); - design->optimize(); - - log_header("Finished OPT passes. (There is nothing left to do.)\n"); + log_header(fast_mode ? "Finished fast OPT passes." : "Finished OPT passes. (There is nothing left to do.)\n"); log_pop(); } } OptPass; From 1ddf150c35aa32f2f6eb35d678feb76b612d7c47 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 16:01:58 +0200 Subject: [PATCH 603/750] Changes in techmap $__alu interface --- techlibs/common/techmap.v | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 190002c0..9b733c6f 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -251,11 +251,11 @@ endmodule // ALU Infrastructure // -------------------------------------------------------- -module \$__alu_ripple (A, B, CI, Y, CO, CS); +module \$__alu_ripple (A, B, CI, X, Y, CO, CS); parameter WIDTH = 1; input [WIDTH-1:0] A, B; - output [WIDTH-1:0] Y; + output [WIDTH-1:0] X, Y; input CI; output CO, CS; @@ -280,7 +280,7 @@ module \$__alu_ripple (A, B, CI, Y, CO, CS); \$_OR_ gate5 ( .A(t1), .B(t3), .Y(x) ); assign a = A[i], b = B[i], c = carry[i]; - assign carry[i+1] = x, Y[i] = y; + assign carry[i+1] = x, X[i] = t2, Y[i] = y; end endgenerate endmodule @@ -361,11 +361,11 @@ module \$__lcu (P, G, CI, CO, PG, GG); endgenerate endmodule -module \$__alu_lookahead (A, B, CI, Y, CO, CS); +module \$__alu_lookahead (A, B, CI, X, Y, CO, CS); parameter WIDTH = 1; input [WIDTH-1:0] A, B; - output [WIDTH-1:0] Y; + output [WIDTH-1:0] X, Y; input CI; output CO, CS; @@ -387,14 +387,14 @@ module \$__alu_lookahead (A, B, CI, Y, CO, CS); \$_XOR_ gate3 ( .A(p), .B(c), .Y(y) ); assign a = A[i], b = B[i], c = C[i]; - assign P[i] = p, G[i] = g, Y[i] = y; + assign P[i] = p, G[i] = g, X[i] = p, Y[i] = y; end endgenerate \$__lcu #(.WIDTH(WIDTH)) lcu (.P(P), .G(G), .CI(CI), .CO(C)); endmodule -module \$__alu (A, B, CI, S, Y, CO, CS); +module \$__alu (A, B, CI, BI, X, Y, CO, CS); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -403,10 +403,10 @@ module \$__alu (A, B, CI, S, Y, CO, CS); input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; + output [Y_WIDTH-1:0] X, Y; // carry in, sub, carry out, carry sign - input CI, S; + input CI, BI; output CO, CS; wire [Y_WIDTH-1:0] A_buf, B_buf; @@ -414,12 +414,12 @@ module \$__alu (A, B, CI, S, Y, CO, CS); \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); `ifdef ALU_RIPPLE - \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(S ? ~B_buf : B_buf), .CI(CI), .Y(Y), .CO(CO), .CS(CS)); + \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO), .CS(CS)); `else if (Y_WIDTH <= 4) begin - \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(S ? ~B_buf : B_buf), .CI(CI), .Y(Y), .CO(CO), .CS(CS)); + \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO), .CS(CS)); end else begin - \$__alu_lookahead #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(S ? ~B_buf : B_buf), .CI(CI), .Y(Y), .CO(CO), .CS(CS)); + \$__alu_lookahead #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO), .CS(CS)); end `endif endmodule @@ -429,7 +429,7 @@ endmodule // ALU Cell Types: Compare, Add, Subtract // -------------------------------------------------------- -`define ALU_COMMONS(_width, _ci, _s) """ +`define ALU_COMMONS(_width, _ci, _bi) """ parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -443,7 +443,7 @@ endmodule output [Y_WIDTH-1:0] Y; wire alu_co, alu_cs; - wire [WIDTH-1:0] alu_y; + wire [WIDTH-1:0] alu_x, alu_y; \$__alu #( .A_SIGNED(A_SIGNED), @@ -455,7 +455,8 @@ endmodule .A(A), .B(B), .CI(_ci), - .S(_s), + .BI(_bi), + .X(alu_x), .Y(alu_y), .CO(alu_co), .CS(alu_cs) @@ -464,7 +465,6 @@ endmodule wire cf, of, zf, sf; assign cf = !alu_co; assign of = alu_co ^ alu_cs; - assign zf = ~|alu_y; assign sf = alu_y[WIDTH-1]; """ @@ -477,7 +477,7 @@ endmodule module \$le (A, B, Y); wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1, 1) - assign Y = zf || (A_SIGNED && B_SIGNED ? of != sf : cf); + assign Y = &alu_x || (A_SIGNED && B_SIGNED ? of != sf : cf); endmodule module \$add (A, B, Y); From 56a30cf42c6a40f265a67df6e2c5fa74657fbf5b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 16:12:14 +0200 Subject: [PATCH 604/750] Added CellTypes::cell_evaluable() --- kernel/celltypes.h | 64 +++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 402d6ea7..ad5eae2e 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -31,7 +31,7 @@ struct CellType { RTLIL::IdString type; std::set inputs, outputs; - bool maybe_has_internal_state; + bool is_evaluable; }; struct CellTypes @@ -58,9 +58,9 @@ struct CellTypes setup_stdcells_mem(); } - void setup_type(RTLIL::IdString type, const std::set &inputs, const std::set &outputs, bool maybe_has_internal_state) + void setup_type(RTLIL::IdString type, const std::set &inputs, const std::set &outputs, bool is_evaluable = false) { - CellType ct = {type, inputs, outputs, maybe_has_internal_state}; + CellType ct = {type, inputs, outputs, is_evaluable}; cell_types[ct.type] = ct; } @@ -74,7 +74,7 @@ struct CellTypes if (wire->port_output) outputs.insert(wire->name); } - setup_type(module->name, inputs, outputs, true); + setup_type(module->name, inputs, outputs); } void setup_design(RTLIL::Design *design) @@ -100,40 +100,40 @@ struct CellTypes }; for (auto type : unary_ops) - setup_type(type, {"\\A"}, {"\\Y"}, false); + setup_type(type, {"\\A"}, {"\\Y"}, true); for (auto type : binary_ops) - setup_type(type, {"\\A", "\\B"}, {"\\Y"}, false); + setup_type(type, {"\\A", "\\B"}, {"\\Y"}, true); for (auto type : std::vector({"$mux", "$pmux"})) - setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, false); + setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); - setup_type("$assert", {"\\A", "\\EN"}, {}, false); + setup_type("$assert", {"\\A", "\\EN"}, {}, true); } void setup_internals_mem() { - setup_type("$sr", {"\\SET", "\\CLR"}, {"\\Q"}, true); - setup_type("$dff", {"\\CLK", "\\D"}, {"\\Q"}, true); - setup_type("$dffsr", {"\\CLK", "\\SET", "\\CLR", "\\D"}, {"\\Q"}, true); - setup_type("$adff", {"\\CLK", "\\ARST", "\\D"}, {"\\Q"}, true); - setup_type("$dlatch", {"\\EN", "\\D"}, {"\\Q"}, true); - setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}, true); + setup_type("$sr", {"\\SET", "\\CLR"}, {"\\Q"}); + setup_type("$dff", {"\\CLK", "\\D"}, {"\\Q"}); + setup_type("$dffsr", {"\\CLK", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); + setup_type("$adff", {"\\CLK", "\\ARST", "\\D"}, {"\\Q"}); + setup_type("$dlatch", {"\\EN", "\\D"}, {"\\Q"}); + setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); - setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}, true); - setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, {}, true); - setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"}, true); + setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}); + setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, {}); + setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"}); - setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"}, true); + setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"}); } void setup_stdcells() { - setup_type("$_NOT_", {"\\A"}, {"\\Y"}, false); - setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, false); - setup_type("$_OR_", {"\\A", "\\B"}, {"\\Y"}, false); - setup_type("$_XOR_", {"\\A", "\\B"}, {"\\Y"}, false); - setup_type("$_MUX_", {"\\A", "\\B", "\\S"}, {"\\Y"}, false); + setup_type("$_NOT_", {"\\A"}, {"\\Y"}, true); + setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, true); + setup_type("$_OR_", {"\\A", "\\B"}, {"\\Y"}, true); + setup_type("$_XOR_", {"\\A", "\\B"}, {"\\Y"}, true); + setup_type("$_MUX_", {"\\A", "\\B", "\\S"}, {"\\Y"}, true); } void setup_stdcells_mem() @@ -142,28 +142,28 @@ struct CellTypes for (auto c1 : list_np) for (auto c2 : list_np) - setup_type(stringf("$_SR_%c%c_", c1, c2), {"\\S", "\\R"}, {"\\Q"}, true); + setup_type(stringf("$_SR_%c%c_", c1, c2), {"\\S", "\\R"}, {"\\Q"}); for (auto c1 : list_np) - setup_type(stringf("$_DFF_%c_", c1), {"\\C", "\\D"}, {"\\Q"}, true); + setup_type(stringf("$_DFF_%c_", c1), {"\\C", "\\D"}, {"\\Q"}); for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_01) - setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {"\\C", "\\R", "\\D"}, {"\\Q"}, true); + setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {"\\C", "\\R", "\\D"}, {"\\Q"}); for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_np) - setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {"\\C", "\\S", "\\R", "\\D"}, {"\\Q"}, true); + setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {"\\C", "\\S", "\\R", "\\D"}, {"\\Q"}); for (auto c1 : list_np) - setup_type(stringf("$_DLATCH_%c_", c1), {"\\E", "\\D"}, {"\\Q"}, true); + setup_type(stringf("$_DLATCH_%c_", c1), {"\\E", "\\D"}, {"\\Q"}); for (auto c1 : list_np) for (auto c2 : list_np) for (auto c3 : list_np) - setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {"\\E", "\\S", "\\R", "\\D"}, {"\\Q"}, true); + setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {"\\E", "\\S", "\\R", "\\D"}, {"\\Q"}); } void clear() @@ -188,6 +188,12 @@ struct CellTypes return it != cell_types.end() && it->second.inputs.count(port) != 0; } + bool cell_evaluable(RTLIL::IdString type) + { + auto it = cell_types.find(type); + return it != cell_types.end() && it->second.is_evaluable; + } + static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { if (type == "$sshr" && !signed1) From 47c2637a961839f1eb1a0386f7e54d94be50bc10 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 18:18:30 +0200 Subject: [PATCH 605/750] Added additional gate types: $_NAND_ $_NOR_ $_XNOR_ $_AOI3_ $_OAI3_ $_AOI4_ $_OAI4_ --- backends/verilog/verilog_backend.cc | 44 ++++++- kernel/celltypes.h | 49 +++++++- kernel/consteval.h | 17 ++- kernel/rtlil.cc | 17 ++- kernel/satgen.h | 88 +++++++++++-- manual/CHAPTER_CellLib.tex | 4 + passes/abc/abc.cc | 186 ++++++++++++++++++++++++---- techlibs/common/simcells.v | 42 +++++++ 8 files changed, 399 insertions(+), 48 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 81c938bd..0fcd60cd 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -381,21 +381,25 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") { + if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_")) { fprintf(f, "%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); fprintf(f, " = "); + if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_")) + fprintf(f, "~("); dump_cell_expr_port(f, cell, "A", false); fprintf(f, " "); - if (cell->type == "$_AND_") + if (cell->type.in("$_AND_", "$_NAND_")) fprintf(f, "&"); - if (cell->type == "$_OR_") + if (cell->type.in("$_OR_", "$_NOR_")) fprintf(f, "|"); - if (cell->type == "$_XOR_") + if (cell->type.in("$_XOR_", "$_XNOR_")) fprintf(f, "^"); dump_attributes(f, "", cell->attributes, ' '); fprintf(f, " "); dump_cell_expr_port(f, cell, "B", false); + if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_")) + fprintf(f, ")"); fprintf(f, ";\n"); return true; } @@ -414,6 +418,38 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) return true; } + if (cell->type.in("$_AOI3_", "$_OAI3_")) { + fprintf(f, "%s" "assign ", indent.c_str()); + dump_sigspec(f, cell->getPort("\\Y")); + fprintf(f, " = ("); + dump_cell_expr_port(f, cell, "A", false); + fprintf(f, cell->type == "$_AOI3_" ? " & " : " | "); + dump_cell_expr_port(f, cell, "B", false); + fprintf(f, cell->type == "$_AOI3_" ? ") |" : ") &"); + dump_attributes(f, "", cell->attributes, ' '); + fprintf(f, " "); + dump_cell_expr_port(f, cell, "C", false); + fprintf(f, ";\n"); + return true; + } + + if (cell->type.in("$_AOI4_", "$_OAI4_")) { + fprintf(f, "%s" "assign ", indent.c_str()); + dump_sigspec(f, cell->getPort("\\Y")); + fprintf(f, " = ("); + dump_cell_expr_port(f, cell, "A", false); + fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); + dump_cell_expr_port(f, cell, "B", false); + fprintf(f, cell->type == "$_AOI4_" ? ") |" : ") &"); + dump_attributes(f, "", cell->attributes, ' '); + fprintf(f, " ("); + dump_cell_expr_port(f, cell, "C", false); + fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); + dump_cell_expr_port(f, cell, "D", false); + fprintf(f, ");\n"); + return true; + } + if (cell->type.substr(0, 6) == "$_DFF_") { std::string reg_name = cellname(cell); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index ad5eae2e..8c2e9a48 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -131,9 +131,16 @@ struct CellTypes { setup_type("$_NOT_", {"\\A"}, {"\\Y"}, true); setup_type("$_AND_", {"\\A", "\\B"}, {"\\Y"}, true); + setup_type("$_NAND_", {"\\A", "\\B"}, {"\\Y"}, true); setup_type("$_OR_", {"\\A", "\\B"}, {"\\Y"}, true); + setup_type("$_NOR_", {"\\A", "\\B"}, {"\\Y"}, true); setup_type("$_XOR_", {"\\A", "\\B"}, {"\\Y"}, true); + setup_type("$_XNOR_", {"\\A", "\\B"}, {"\\Y"}, true); setup_type("$_MUX_", {"\\A", "\\B", "\\S"}, {"\\Y"}, true); + setup_type("$_AOI3_", {"\\A", "\\B", "\\C"}, {"\\Y"}, true); + setup_type("$_OAI3_", {"\\A", "\\B", "\\C"}, {"\\Y"}, true); + setup_type("$_AOI4_", {"\\A", "\\B", "\\C", "\\D"}, {"\\Y"}, true); + setup_type("$_OAI4_", {"\\A", "\\B", "\\C", "\\D"}, {"\\Y"}, true); } void setup_stdcells_mem() @@ -194,6 +201,14 @@ struct CellTypes return it != cell_types.end() && it->second.is_evaluable; } + static RTLIL::Const eval_not(RTLIL::Const v) + { + for (auto &bit : v.bits) + if (bit == RTLIL::S0) bit = RTLIL::S1; + else if (bit == RTLIL::S1) bit = RTLIL::S0; + return v; + } + static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len) { if (type == "$sshr" && !signed1) @@ -247,13 +262,19 @@ struct CellTypes #undef HANDLE_CELL_TYPE if (type == "$_NOT_") - return const_not(arg1, arg2, false, false, 1); + return eval_not(arg1); if (type == "$_AND_") return const_and(arg1, arg2, false, false, 1); + if (type == "$_NAND_") + return eval_not(const_and(arg1, arg2, false, false, 1)); if (type == "$_OR_") return const_or(arg1, arg2, false, false, 1); + if (type == "$_NOR_") + return eval_not(const_and(arg1, arg2, false, false, 1)); if (type == "$_XOR_") return const_xor(arg1, arg2, false, false, 1); + if (type == "$_XNOR_") + return const_xnor(arg1, arg2, false, false, 1); log_abort(); } @@ -280,21 +301,37 @@ struct CellTypes return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len); } - static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &sel) + static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3) { - if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") { + if (cell->type.in("$mux", "$pmux", "$_MUX_")) { RTLIL::Const ret = arg1; - for (size_t i = 0; i < sel.bits.size(); i++) - if (sel.bits[i] == RTLIL::State::S1) { + for (size_t i = 0; i < arg3.bits.size(); i++) + if (arg3.bits[i] == RTLIL::State::S1) { std::vector bits(arg2.bits.begin() + i*arg1.bits.size(), arg2.bits.begin() + (i+1)*arg1.bits.size()); ret = RTLIL::Const(bits); } return ret; } - log_assert(sel.bits.size() == 0); + if (cell->type == "$_AOI3_") + return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1)); + if (cell->type == "$_OAI3_") + return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1)); + + log_assert(arg3.bits.size() == 0); return eval(cell, arg1, arg2); } + + static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4) + { + if (cell->type == "$_AOI4_") + return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1)); + if (cell->type == "$_OAI4_") + return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1)); + + log_assert(arg4.bits.size() == 0); + return eval(cell, arg1, arg2, arg3); + } }; #endif diff --git a/kernel/consteval.h b/kernel/consteval.h index dbe13ea7..d42c2b0f 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -156,11 +156,26 @@ struct ConstEval } else { + RTLIL::SigSpec sig_c, sig_d; + + if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) { + if (cell->hasPort("\\C")) + sig_c = cell->getPort("\\C"); + if (cell->hasPort("\\D")) + sig_d = cell->getPort("\\D"); + } + if (sig_a.size() > 0 && !eval(sig_a, undef, cell)) return false; if (sig_b.size() > 0 && !eval(sig_b, undef, cell)) return false; - set(sig_y, CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const())); + if (sig_c.size() > 0 && !eval(sig_c, undef, cell)) + return false; + if (sig_d.size() > 0 && !eval(sig_d, undef, cell)) + return false; + + set(sig_y, CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), + sig_c.as_const(), sig_d.as_const())); } return true; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d118b625..3df7d83c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -758,11 +758,18 @@ namespace { return; } - if (cell->type == "$_NOT_") { check_gate("AY"); return; } - if (cell->type == "$_AND_") { check_gate("ABY"); return; } - if (cell->type == "$_OR_") { check_gate("ABY"); return; } - if (cell->type == "$_XOR_") { check_gate("ABY"); return; } - if (cell->type == "$_MUX_") { check_gate("ABSY"); return; } + if (cell->type == "$_NOT_") { check_gate("AY"); return; } + if (cell->type == "$_AND_") { check_gate("ABY"); return; } + if (cell->type == "$_NAND_") { check_gate("ABY"); return; } + if (cell->type == "$_OR_") { check_gate("ABY"); return; } + if (cell->type == "$_NOR_") { check_gate("ABY"); return; } + if (cell->type == "$_XOR_") { check_gate("ABY"); return; } + if (cell->type == "$_XNOR_") { check_gate("ABY"); return; } + if (cell->type == "$_MUX_") { check_gate("ABSY"); return; } + if (cell->type == "$_AOI3_") { check_gate("ABCY"); return; } + if (cell->type == "$_OAI3_") { check_gate("ABCY"); return; } + if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; } + if (cell->type == "$_OAI4_") { check_gate("ABCDY"); return; } if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; } if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; } diff --git a/kernel/satgen.h b/kernel/satgen.h index b57edd9f..c02900a6 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -175,6 +175,11 @@ struct SatGen } } + void undefGating(int y, int yy, int undef) + { + ez->assume(ez->OR(undef, ez->IFF(y, yy))); + } + bool importCell(RTLIL::Cell *cell, int timestep = -1) { bool arith_undef_handled = false; @@ -211,9 +216,8 @@ struct SatGen arith_undef_handled = true; } - if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_" || - cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || - cell->type == "$add" || cell->type == "$sub") + if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", + "$and", "$or", "$xor", "$xnor", "$add", "$sub")) { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); @@ -224,11 +228,15 @@ struct SatGen if (cell->type == "$and" || cell->type == "$_AND_") ez->assume(ez->vec_eq(ez->vec_and(a, b), yy)); + if (cell->type == "$_NAND_") + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy)); if (cell->type == "$or" || cell->type == "$_OR_") ez->assume(ez->vec_eq(ez->vec_or(a, b), yy)); + if (cell->type == "$_NOR_") + ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy)); if (cell->type == "$xor" || cell->type == "$_XOR_") ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy)); - if (cell->type == "$xnor") + if (cell->type == "$xnor" || cell->type == "$_XNOR_") ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy)); if (cell->type == "$add") ez->assume(ez->vec_eq(ez->vec_add(a, b), yy)); @@ -242,19 +250,19 @@ struct SatGen std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidth(undef_a, undef_b, undef_y, cell, false); - if (cell->type == "$and" || cell->type == "$_AND_") { + if (cell->type.in("$and", "$_AND_", "$_NAND_")) { std::vector a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); std::vector b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); std::vector yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0))); ez->assume(ez->vec_eq(yX, undef_y)); } - else if (cell->type == "$or" || cell->type == "$_OR_") { + else if (cell->type.in("$or", "$_OR_", "$_NOR_")) { std::vector a1 = ez->vec_and(a, ez->vec_not(undef_a)); std::vector b1 = ez->vec_and(b, ez->vec_not(undef_b)); std::vector yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1))); ez->assume(ez->vec_eq(yX, undef_y)); } - else if (cell->type == "$xor" || cell->type == "$_XOR_" || cell->type == "$xnor") { + else if (cell->type.in("$xor", "$xnor", "$_XOR_", "$_XNOR_")) { std::vector yX = ez->vec_or(undef_a, undef_b); ez->assume(ez->vec_eq(yX, undef_y)); } @@ -271,6 +279,72 @@ struct SatGen return true; } + if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) + { + bool aoi_mode = cell->type.in("$_AOI3_", "$_AOI4_"); + bool three_mode = cell->type.in("$_AOI3_", "$_OAI3_"); + + int a = importDefSigSpec(cell->getPort("\\A"), timestep).at(0); + int b = importDefSigSpec(cell->getPort("\\B"), timestep).at(0); + int c = importDefSigSpec(cell->getPort("\\C"), timestep).at(0); + int d = three_mode ? (aoi_mode ? ez->TRUE : ez->FALSE) : importDefSigSpec(cell->getPort("\\D"), timestep).at(0); + int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0); + int yy = model_undef ? ez->literal() : y; + + if (cell->type.in("$_AOI3_", "$_AOI4_")) + ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy)); + else + ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy)); + + if (model_undef) + { + int undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep).at(0); + int undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep).at(0); + int undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep).at(0); + int undef_d = three_mode ? ez->FALSE : importUndefSigSpec(cell->getPort("\\D"), timestep).at(0); + int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0); + + if (aoi_mode) + { + int a0 = ez->AND(ez->NOT(a), ez->NOT(undef_a)); + int b0 = ez->AND(ez->NOT(b), ez->NOT(undef_b)); + int c0 = ez->AND(ez->NOT(c), ez->NOT(undef_c)); + int d0 = ez->AND(ez->NOT(d), ez->NOT(undef_d)); + + int ab = ez->AND(a, b), cd = ez->AND(c, d); + int undef_ab = ez->AND(ez->OR(undef_a, undef_b), ez->NOT(ez->OR(a0, b0))); + int undef_cd = ez->AND(ez->OR(undef_c, undef_d), ez->NOT(ez->OR(c0, d0))); + + int ab1 = ez->AND(ab, ez->NOT(undef_ab)); + int cd1 = ez->AND(cd, ez->NOT(undef_cd)); + int yX = ez->AND(ez->OR(undef_ab, undef_cd), ez->NOT(ez->OR(ab1, cd1))); + + ez->assume(ez->IFF(yX, undef_y)); + } + else + { + int a1 = ez->AND(a, ez->NOT(undef_a)); + int b1 = ez->AND(b, ez->NOT(undef_b)); + int c1 = ez->AND(c, ez->NOT(undef_c)); + int d1 = ez->AND(d, ez->NOT(undef_d)); + + int ab = ez->OR(a, b), cd = ez->OR(c, d); + int undef_ab = ez->AND(ez->OR(undef_a, undef_b), ez->NOT(ez->OR(a1, b1))); + int undef_cd = ez->AND(ez->OR(undef_c, undef_d), ez->NOT(ez->OR(c1, d1))); + + int ab0 = ez->AND(ez->NOT(ab), ez->NOT(undef_ab)); + int cd0 = ez->AND(ez->NOT(cd), ez->NOT(undef_cd)); + int yX = ez->AND(ez->OR(undef_ab, undef_cd), ez->NOT(ez->OR(ab0, cd0))); + + ez->assume(ez->IFF(yX, undef_y)); + } + + undefGating(y, yy, undef_y); + } + + return true; + } + if (cell->type == "$_NOT_" || cell->type == "$not") { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index ea4ae8d4..3eb2f946 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -430,3 +430,7 @@ Add information about {\tt \$assert} cells. Add information about {\tt \$slice} and {\tt \$concat} cells. \end{fixme} +\begin{fixme} +Add information about {\tt \$\_NAND\_}, {\tt \$\_NOR\_}, {\tt \$\_XNOR\_}, {\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, and {\tt \$\_OAI4\_} cells. +\end{fixme} + diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 2b1d4981..fd56668c 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -48,11 +48,30 @@ #include "blifparse.h" +enum class gate_type_t { + G_NONE, + G_FF, + G_NOT, + G_AND, + G_NAND, + G_OR, + G_NOR, + G_XOR, + G_XNOR, + G_MUX, + G_AOI3, + G_OAI3, + G_AOI4, + G_OAI4 +}; + +#define G(_name) gate_type_t::G_ ## _name + struct gate_t { int id; - char type; - int in1, in2, in3; + gate_type_t type; + int in1, in2, in3, in4; bool is_port; RTLIL::SigBit bit; }; @@ -66,17 +85,18 @@ static std::map signal_map; static bool clk_polarity; static RTLIL::SigSpec clk_sig; -static int map_signal(RTLIL::SigBit bit, char gate_type = -1, int in1 = -1, int in2 = -1, int in3 = -1) +static int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1) { assign_map.apply(bit); if (signal_map.count(bit) == 0) { gate_t gate; gate.id = signal_list.size(); - gate.type = -1; + gate.type = G(NONE); gate.in1 = -1; gate.in2 = -1; gate.in3 = -1; + gate.in4 = -1; gate.is_port = false; gate.bit = bit; signal_list.push_back(gate); @@ -85,7 +105,7 @@ static int map_signal(RTLIL::SigBit bit, char gate_type = -1, int in1 = -1, int gate_t &gate = signal_list[signal_map[bit]]; - if (gate_type >= 0) + if (gate_type != G(NONE)) gate.type = gate_type; if (in1 >= 0) gate.in1 = in1; @@ -93,6 +113,8 @@ static int map_signal(RTLIL::SigBit bit, char gate_type = -1, int in1 = -1, int gate.in2 = in2; if (in3 >= 0) gate.in3 = in3; + if (in4 >= 0) + gate.in4 = in4; return gate.id; } @@ -124,7 +146,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) assign_map.apply(sig_d); assign_map.apply(sig_q); - map_signal(sig_q, 'f', map_signal(sig_d)); + map_signal(sig_q, G(FF), map_signal(sig_d)); module->remove(cell); return; @@ -138,13 +160,13 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) assign_map.apply(sig_a); assign_map.apply(sig_y); - map_signal(sig_y, 'n', map_signal(sig_a)); + map_signal(sig_y, G(NOT), map_signal(sig_a)); module->remove(cell); return; } - if (cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") + if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR", "$_XOR_", "$_XNOR_")) { RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_b = cell->getPort("\\B"); @@ -158,11 +180,17 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) int mapped_b = map_signal(sig_b); if (cell->type == "$_AND_") - map_signal(sig_y, 'a', mapped_a, mapped_b); + map_signal(sig_y, G(AND), mapped_a, mapped_b); + else if (cell->type == "$_NAND_") + map_signal(sig_y, G(NAND), mapped_a, mapped_b); else if (cell->type == "$_OR_") - map_signal(sig_y, 'o', mapped_a, mapped_b); + map_signal(sig_y, G(OR), mapped_a, mapped_b); + else if (cell->type == "$_NOR_") + map_signal(sig_y, G(NOR), mapped_a, mapped_b); else if (cell->type == "$_XOR_") - map_signal(sig_y, 'x', mapped_a, mapped_b); + map_signal(sig_y, G(XOR), mapped_a, mapped_b); + else if (cell->type == "$_XNOR_") + map_signal(sig_y, G(XNOR), mapped_a, mapped_b); else log_abort(); @@ -186,7 +214,54 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) int mapped_b = map_signal(sig_b); int mapped_s = map_signal(sig_s); - map_signal(sig_y, 'm', mapped_a, mapped_b, mapped_s); + map_signal(sig_y, G(MUX), mapped_a, mapped_b, mapped_s); + + module->remove(cell); + return; + } + + if (cell->type.in("$_AOI3_", "$_OAI3_")) + { + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_c = cell->getPort("\\C"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + + assign_map.apply(sig_a); + assign_map.apply(sig_b); + assign_map.apply(sig_c); + assign_map.apply(sig_y); + + int mapped_a = map_signal(sig_a); + int mapped_b = map_signal(sig_b); + int mapped_c = map_signal(sig_c); + + map_signal(sig_y, cell->type == "$_AOI3_" ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c); + + module->remove(cell); + return; + } + + if (cell->type.in("$_AOI4_", "$_OAI4_")) + { + RTLIL::SigSpec sig_a = cell->getPort("\\A"); + RTLIL::SigSpec sig_b = cell->getPort("\\B"); + RTLIL::SigSpec sig_c = cell->getPort("\\C"); + RTLIL::SigSpec sig_d = cell->getPort("\\D"); + RTLIL::SigSpec sig_y = cell->getPort("\\Y"); + + assign_map.apply(sig_a); + assign_map.apply(sig_b); + assign_map.apply(sig_c); + assign_map.apply(sig_d); + assign_map.apply(sig_y); + + int mapped_a = map_signal(sig_a); + int mapped_b = map_signal(sig_b); + int mapped_c = map_signal(sig_c); + int mapped_d = map_signal(sig_d); + + map_signal(sig_y, cell->type == "$_AOI4_" ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d); module->remove(cell); return; @@ -244,7 +319,7 @@ static void handle_loops() // dot_f = fopen("test.dot", "w"); for (auto &g : signal_list) { - if (g.type == -1 || g.type == 'f') { + if (g.type == G(NONE) || g.type == G(FF)) { workpool.insert(g.id); } else { if (g.in1 >= 0) { @@ -259,6 +334,10 @@ static void handle_loops() edges[g.in3].insert(g.id); in_edges_count[g.id]++; } + if (g.in4 >= 0 && g.in4 != g.in3 && g.in4 != g.in2 && g.in4 != g.in1) { + edges[g.in4].insert(g.id); + in_edges_count[g.id]++; + } } } @@ -341,6 +420,8 @@ static void handle_loops() signal_list[id2].in2 = id3; if (signal_list[id2].in3 == id1) signal_list[id2].in3 = id3; + if (signal_list[id2].in4 == id1) + signal_list[id2].in4 = id3; } edges[id1].swap(edges[id3]); @@ -521,7 +602,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std int count_input = 0; fprintf(f, ".inputs"); for (auto &si : signal_list) { - if (!si.is_port || si.type >= 0) + if (!si.is_port || si.type != G(NONE)) continue; fprintf(f, " n%d", si.id); count_input++; @@ -533,7 +614,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std int count_output = 0; fprintf(f, ".outputs"); for (auto &si : signal_list) { - if (!si.is_port || si.type < 0) + if (!si.is_port || si.type == G(NONE)) continue; fprintf(f, " n%d", si.id); count_output++; @@ -553,29 +634,58 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std int count_gates = 0; for (auto &si : signal_list) { - if (si.type == 'n') { + if (si.type == G(NOT)) { fprintf(f, ".names n%d n%d\n", si.in1, si.id); fprintf(f, "0 1\n"); - } else if (si.type == 'a') { + } else if (si.type == G(AND)) { fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id); fprintf(f, "11 1\n"); - } else if (si.type == 'o') { + } else if (si.type == G(NAND)) { + fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id); + fprintf(f, "0- 1\n"); + fprintf(f, "-0 1\n"); + } else if (si.type == G(OR)) { fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id); fprintf(f, "-1 1\n"); fprintf(f, "1- 1\n"); - } else if (si.type == 'x') { + } else if (si.type == G(NOR)) { + fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id); + fprintf(f, "00 1\n"); + } else if (si.type == G(XOR)) { fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id); fprintf(f, "01 1\n"); fprintf(f, "10 1\n"); - } else if (si.type == 'm') { + } else if (si.type == G(XNOR)) { + fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id); + fprintf(f, "00 1\n"); + fprintf(f, "11 1\n"); + } else if (si.type == G(MUX)) { fprintf(f, ".names n%d n%d n%d n%d\n", si.in1, si.in2, si.in3, si.id); fprintf(f, "1-0 1\n"); fprintf(f, "-11 1\n"); - } else if (si.type == 'f') { + } else if (si.type == G(AOI3)) { + fprintf(f, ".names n%d n%d n%d n%d\n", si.in1, si.in2, si.in3, si.id); + fprintf(f, "-00 1\n"); + fprintf(f, "0-0 1\n"); + } else if (si.type == G(OAI3)) { + fprintf(f, ".names n%d n%d n%d n%d\n", si.in1, si.in2, si.in3, si.id); + fprintf(f, "00- 1\n"); + fprintf(f, "--0 1\n"); + } else if (si.type == G(AOI4)) { + fprintf(f, ".names n%d n%d n%d n%d n%d\n", si.in1, si.in2, si.in3, si.in4, si.id); + fprintf(f, "-0-0 1\n"); + fprintf(f, "-00- 1\n"); + fprintf(f, "0--0 1\n"); + fprintf(f, "0-0- 1\n"); + } else if (si.type == G(OAI4)) { + fprintf(f, ".names n%d n%d n%d n%d n%d\n", si.in1, si.in2, si.in3, si.in4, si.id); + fprintf(f, "00-- 1\n"); + fprintf(f, "--00 1\n"); + } else if (si.type == G(FF)) { fprintf(f, ".latch n%d n%d\n", si.in1, si.id); - } else if (si.type >= 0) + } else if (si.type != G(NONE)) log_abort(); - if (si.type >= 0) + if (si.type != G(NONE)) count_gates++; } @@ -599,9 +709,16 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std fprintf(f, "GATE BUF 1 Y=A; PIN * NONINV 1 999 1 0 1 0\n"); fprintf(f, "GATE INV 1 Y=!A; PIN * INV 1 999 1 0 1 0\n"); fprintf(f, "GATE AND 1 Y=A*B; PIN * NONINV 1 999 1 0 1 0\n"); + fprintf(f, "GATE NAND 1 Y=!(A*B); PIN * INV 1 999 1 0 1 0\n"); fprintf(f, "GATE OR 1 Y=A+B; PIN * NONINV 1 999 1 0 1 0\n"); + fprintf(f, "GATE NOR 1 Y=!(A+B); PIN * INV 1 999 1 0 1 0\n"); fprintf(f, "GATE XOR 1 Y=(A*!B)+(!A*B); PIN * UNKNOWN 1 999 1 0 1 0\n"); + fprintf(f, "GATE XNOR 1 Y=(A*B)+(!A*!B); PIN * UNKNOWN 1 999 1 0 1 0\n"); fprintf(f, "GATE MUX 1 Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n"); + fprintf(f, "GATE AOI3 1 Y=!((A*B)+C); PIN * INV 1 999 1 0 1 0\n"); + fprintf(f, "GATE OAI3 1 Y=!((A+B)*C); PIN * INV 1 999 1 0 1 0\n"); + fprintf(f, "GATE AOI4 1 Y=!((A*B)+(C*D)); PIN * INV 1 999 1 0 1 0\n"); + fprintf(f, "GATE OAI4 1 Y=!((A+B)*(C+D)); PIN * INV 1 999 1 0 1 0\n"); fclose(f); free(p); @@ -739,7 +856,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std design->select(module, cell); continue; } - if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR") { + if (c->type == "\\AND" || c->type == "\\OR" || c->type == "\\XOR" || c->type == "\\NAND" || c->type == "\\NOR" || c->type == "\\XNOR") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); @@ -756,6 +873,25 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std design->select(module, cell); continue; } + if (c->type == "\\AOI3" || c->type == "\\OAI3") { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); + cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); + cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); + cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); + cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + design->select(module, cell); + continue; + } + if (c->type == "\\AOI4" || c->type == "\\OAI4") { + RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); + cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); + cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); + cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); + cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); + cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); + design->select(module, cell); + continue; + } if (c->type == "\\DFF") { log_assert(clk_sig.size() == 1); RTLIL::Cell *cell = module->addCell(remap_name(c->name), clk_polarity ? "$_DFF_P_" : "$_DFF_N_"); @@ -822,7 +958,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std char buffer[100]; snprintf(buffer, 100, "\\n%d", si.id); RTLIL::SigSig conn; - if (si.type >= 0) { + if (si.type != G(NONE)) { conn.first = si.bit; conn.second = RTLIL::SigSpec(module->wires_[remap_name(buffer)]); out_wires++; diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v index 7c8a47dd..a2a37735 100644 --- a/techlibs/common/simcells.v +++ b/techlibs/common/simcells.v @@ -37,24 +37,66 @@ output Y; assign Y = A & B; endmodule +module \$_NAND_ (A, B, Y); +input A, B; +output Y; +assign Y = ~(A & B); +endmodule + module \$_OR_ (A, B, Y); input A, B; output Y; assign Y = A | B; endmodule +module \$_NOR_ (A, B, Y); +input A, B; +output Y; +assign Y = ~(A | B); +endmodule + module \$_XOR_ (A, B, Y); input A, B; output Y; assign Y = A ^ B; endmodule +module \$_XNOR_ (A, B, Y); +input A, B; +output Y; +assign Y = ~(A ^ B); +endmodule + module \$_MUX_ (A, B, S, Y); input A, B, S; output Y; assign Y = S ? B : A; endmodule +module \$_AOI3_ (A, B, C, Y); +input A, B, C; +output Y; +assign Y = ~((A & B) | C); +endmodule + +module \$_OAI3_ (A, B, C, Y); +input A, B, C; +output Y; +assign Y = ~((A | B) & C); +endmodule + +module \$_AOI4_ (A, B, C, D, Y); +input A, B, C, D; +output Y; +assign Y = ~((A & B) | (C & D)); +endmodule + +module \$_OAI4_ (A, B, C, D, Y); +input A, B, C, D; +output Y; +assign Y = ~((A | B) & (C | D)); +endmodule + module \$_SR_NN_ (S, R, Q); input S, R; output reg Q; From 83e2698e10065a27afcc0f0db3818ed3b4a5942e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 19:31:59 +0200 Subject: [PATCH 606/750] AST ProcessGenerator: replaced subst_*_{from,to} with subst_*_map --- frontends/ast/genrtlil.cc | 67 +++++++++++++++------------------------ 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3c8f1fa1..b519f9c5 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_lvalue_map = backup_subst_lvalue_map; + subst_rvalue_map = backup_subst_rvalue_map; - subst_rvalue_from = backup_subst_rvalue_from; - subst_rvalue_to = backup_subst_rvalue_to; - - 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_lvalue_map = backup_subst_lvalue_map; + subst_rvalue_map = backup_subst_rvalue_map; - subst_rvalue_from = backup_subst_rvalue_from; - subst_rvalue_to = backup_subst_rvalue_to; + 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_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); - - 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); } From 3b9157f9a605b5ae2f535c4da932891e504dc57e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 19:44:31 +0200 Subject: [PATCH 607/750] Added "test_cell -s " --- passes/tests/test_cell.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 94d5d27b..a4b8be0c 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -21,12 +21,13 @@ #include "kernel/yosys.h" #include +static uint32_t xorshift32_state = 123456789; + static uint32_t xorshift32(uint32_t limit) { - static uint32_t x = 123456789; - x ^= x << 13; - x ^= x >> 17; - x ^= x << 5; - return x % limit; + xorshift32_state ^= xorshift32_state << 13; + xorshift32_state ^= xorshift32_state >> 17; + xorshift32_state ^= xorshift32_state << 5; + return xorshift32_state % limit; } static void create_gold_module(RTLIL::Design *design, std::string cell_type, std::string cell_type_flags) @@ -94,6 +95,9 @@ struct TestCellPass : public Pass { log(" -n {integer}\n"); log(" create this number of cell instances and test them (default = 100).\n"); log("\n"); + log(" -s {positive_integer}\n"); + log(" use this value as rng seed value (default = unix time).\n"); + log("\n"); log(" -f {ilang_file}\n"); log(" don't generate circuits. instead load the specified ilang file.\n"); log("\n"); @@ -106,6 +110,7 @@ struct TestCellPass : public Pass { int num_iter = 100; std::string techmap_cmd = "techmap -assert"; std::string ilang_file; + xorshift32_state = 0; int argidx; for (argidx = 1; argidx < SIZE(args); argidx++) @@ -114,6 +119,10 @@ struct TestCellPass : public Pass { num_iter = atoi(args[++argidx].c_str()); continue; } + if (args[argidx] == "-s" && argidx+1 < SIZE(args)) { + xorshift32_state = atoi(args[++argidx].c_str()); + continue; + } if (args[argidx] == "-map" && argidx+1 < SIZE(args)) { techmap_cmd += " -map " + args[++argidx]; continue; @@ -126,6 +135,9 @@ struct TestCellPass : public Pass { break; } + if (xorshift32_state == 0) + xorshift32_state = time(NULL); + std::map cell_types; std::vector selected_cell_types; From 976bda71029b9d25ffad9ec8fbf3ceed2d1287e1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 21:07:29 +0200 Subject: [PATCH 608/750] Multiply using a carry-save accumulator --- techlibs/common/techmap.v | 50 +++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 9b733c6f..9bdff4f3 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -502,21 +502,61 @@ module \$__arraymul (A, B, Y); input [WIDTH-1:0] A, B; output [WIDTH-1:0] Y; - wire [1023:0] _TECHMAP_DO_ = "proc;;"; + wire [1023:0] _TECHMAP_DO_ = "proc;; opt"; integer i; - reg [WIDTH-1:0] x, y; + reg [WIDTH-1:0] x; + reg [2*WIDTH-1:0] y; + + function [2*WIDTH-1:0] acc_set; + input [WIDTH-1:0] value; + integer k; + begin + for (k = 0; k < WIDTH; k = k+1) begin + acc_set[2*k +: 2] = value[k]; + end + end + endfunction + + function [2*WIDTH-1:0] acc_add; + input [2*WIDTH-1:0] old_acc; + input [WIDTH-1:0] value; + integer k; + reg a, b, c; + begin + for (k = 0; k < WIDTH; k = k+1) begin + a = old_acc[2*k]; + b = k ? old_acc[2*k-1] : 1'b0; + c = value[k]; + acc_add[2*k] = (a ^ b) ^ c; + acc_add[2*k+1] = (a & b) | ((a ^ b) & c); + end + end + endfunction + + function [WIDTH-1:0] acc_get; + input [2*WIDTH-1:0] acc; + integer k; + begin + // at the end of the multiplier chain the carry-save accumulator + // should also have propagated all carries. thus we just need to + // copy the even bits from the carry accumulator to the output. + for (k = 0; k < WIDTH; k = k+1) begin + acc_get[k] = acc[2*k]; + end + end + endfunction always @* begin x = B; - y = A[0] ? x : 0; + y = acc_set(A[0] ? x : 0); for (i = 1; i < WIDTH; i = i+1) begin x = {x[WIDTH-2:0], 1'b0}; - y = y + (A[i] ? x : 0); + y = acc_add(y, A[i] ? x : 0); end end - assign Y = y; + assign Y = acc_get(y); endmodule module \$mul (A, B, Y); From f82c978e08604c596b034fb6e74ac34c78b9364b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 22:05:09 +0200 Subject: [PATCH 609/750] Fixed AOI/OAI expr handling in verilog backend --- backends/verilog/verilog_backend.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 0fcd60cd..f6095a5a 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -421,7 +421,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type.in("$_AOI3_", "$_OAI3_")) { fprintf(f, "%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = ("); + fprintf(f, " = ~(("); dump_cell_expr_port(f, cell, "A", false); fprintf(f, cell->type == "$_AOI3_" ? " & " : " | "); dump_cell_expr_port(f, cell, "B", false); @@ -429,14 +429,14 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) dump_attributes(f, "", cell->attributes, ' '); fprintf(f, " "); dump_cell_expr_port(f, cell, "C", false); - fprintf(f, ";\n"); + fprintf(f, ");\n"); return true; } if (cell->type.in("$_AOI4_", "$_OAI4_")) { fprintf(f, "%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = ("); + fprintf(f, " = ~(("); dump_cell_expr_port(f, cell, "A", false); fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); dump_cell_expr_port(f, cell, "B", false); @@ -446,7 +446,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) dump_cell_expr_port(f, cell, "C", false); fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); dump_cell_expr_port(f, cell, "D", false); - fprintf(f, ");\n"); + fprintf(f, "));\n"); return true; } From 7f734ecc098a2a113ced835cefc9d4e1982f08d0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 23:50:36 +0200 Subject: [PATCH 610/750] Added module->uniquify() --- frontends/verific/verific.cc | 8 ++------ kernel/rtlil.cc | 22 ++++++++++++++++++++++ kernel/rtlil.h | 3 +++ passes/cmds/splitnets.cc | 5 +---- passes/fsm/fsm_map.cc | 6 +----- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 95b3c407..0440f88e 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); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3df7d83c..60c514d1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1108,6 +1108,28 @@ void RTLIL::Module::swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2) cells_[c2->name] = c2; } +RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name) +{ + int index = 0; + return uniquify(name, index); +} + +RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name, int &index) +{ + if (index == 0) { + if (count_id(name) == 0) + return name; + index++; + } + + while (1) { + RTLIL::IdString new_name = stringf("%s_%d", name.c_str(), index); + if (count_id(new_name) == 0) + return new_name; + index++; + } +} + static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b) { if (a->port_id && !b->port_id) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 43e36cbd..7e052b09 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -625,6 +625,9 @@ public: void swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2); void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2); + RTLIL::IdString uniquify(RTLIL::IdString name); + RTLIL::IdString uniquify(RTLIL::IdString name, int &index); + RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other); diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index a3daf239..cef0a272 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -46,10 +46,7 @@ struct SplitnetsWorker if (format.size() > 1) new_wire_name += format.substr(1, 1); - while (module->count_id(new_wire_name) > 0) - new_wire_name += "_"; - - RTLIL::Wire *new_wire = module->addWire(new_wire_name, width); + RTLIL::Wire *new_wire = module->addWire(module->uniquify(new_wire_name), width); new_wire->port_id = wire->port_id; new_wire->port_input = wire->port_input; new_wire->port_output = wire->port_output; diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 60580eb4..ab6d5671 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -163,11 +163,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) // create state register - std::string state_wire_name = fsm_cell->parameters["\\NAME"].decode_string(); - while (module->count_id(state_wire_name) > 0) - state_wire_name += "_"; - - RTLIL::Wire *state_wire = module->addWire(state_wire_name, fsm_data.state_bits); + RTLIL::Wire *state_wire = module->addWire(module->uniquify(fsm_cell->parameters["\\NAME"].decode_string()), fsm_data.state_bits); RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits); RTLIL::Cell *state_dff = module->addCell(NEW_ID, ""); From 410d043dd86a2ca1f6c56a3e2a4d175dc0af8739 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 00:55:35 +0200 Subject: [PATCH 611/750] Renamed toposort.h to utils.h --- kernel/{toposort.h => utils.h} | 0 passes/opt/opt_const.cc | 2 +- passes/techmap/techmap.cc | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename kernel/{toposort.h => utils.h} (100%) diff --git a/kernel/toposort.h b/kernel/utils.h similarity index 100% rename from kernel/toposort.h rename to kernel/utils.h diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 9af1e6bd..58a7f7df 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -21,7 +21,7 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" -#include "kernel/toposort.h" +#include "kernel/utils.h" #include "kernel/log.h" #include #include diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 59173393..d9d8ddd6 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -18,7 +18,7 @@ */ #include "kernel/yosys.h" -#include "kernel/toposort.h" +#include "kernel/utils.h" #include "kernel/sigtools.h" #include "libs/sha1/sha1.h" From 9bacc0b54c0901dfd34c2230d3295720653c0a7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 00:56:47 +0200 Subject: [PATCH 612/750] Added stackmap<> container --- kernel/utils.h | 110 ++++++++++++++++++++++++++++++++++++++++++++++++- kernel/yosys.h | 1 + 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/kernel/utils.h b/kernel/utils.h index 4226e270..7f10619b 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -17,8 +17,114 @@ * */ -#ifndef TOPOSORT_H -#define TOPOSORT_H +// This file contains various c++ utility routines and helper classes that +// do not depend on any other components of yosys (except stuff like log_*). + +#include "kernel/yosys.h" + +#ifndef UTILS_H +#define UTILS_H + +// ------------------------------------------------ +// A map-like container, but you can save and restore the state +// ------------------------------------------------ + +template> +struct stackmap +{ +private: + std::vector> backup_state; + std::map current_state; + static T empty_tuple; + +public: + stackmap() { } + stackmap(const std::map &other) : current_state(other) { } + + template + void operator=(const Other &other) + { + for (auto &it : current_state) + if (!backup_state.empty() && backup_state.back().count(it.first) == 0) + backup_state.back()[it.first] = new T(it.second); + current_state.clear(); + + for (auto &it : other) + set(it.first, it.second); + } + + bool has(const Key &k) + { + return current_state.count(k) != 0; + } + + void set(const Key &k, const T &v) + { + if (!backup_state.empty() && backup_state.back().count(k) == 0) + backup_state.back()[k] = current_state.count(k) ? new T(current_state.at(k)) : nullptr; + current_state[k] = v; + } + + void unset(const Key &k) + { + if (!backup_state.empty() && backup_state.back().count(k) == 0) + backup_state.back()[k] = current_state.count(k) ? new T(current_state.at(k)) : nullptr; + current_state.erase(k); + } + + const T &get(const Key &k) + { + if (current_state.count(k) == 0) + return empty_tuple; + return current_state.at(k); + } + + void reset(const Key &k) + { + for (int i = SIZE(backup_state)-1; i >= 0; i--) + if (backup_state[i].count(k) != 0) { + if (backup_state[i].at(k) == nullptr) + current_state.erase(k); + else + current_state[k] = *backup_state[i].at(k); + return; + } + current_state.erase(k); + } + + const std::map &stdmap() + { + return current_state; + } + + void save() + { + backup_state.resize(backup_state.size()+1); + } + + void restore() + { + log_assert(!backup_state.empty()); + for (auto &it : backup_state.back()) + if (it.second != nullptr) { + current_state[it.first] = *it.second; + delete it.second; + } else + current_state.erase(it.first); + backup_state.pop_back(); + } + + ~stackmap() + { + while (!backup_state.empty()) + restore(); + } +}; + + +// ------------------------------------------------ +// A simple class for topological sorting +// ------------------------------------------------ template struct TopoSort diff --git a/kernel/yosys.h b/kernel/yosys.h index e12069b4..79c90628 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include From d491fd8c19cddb49d2feed2a873a328825c7b8f4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 00:57:24 +0200 Subject: [PATCH 613/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index ec9616be..6ac77144 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 e7b07548..6ea241fa 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 b519f9c5..4eb4f6c4 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; From f3326a642178b66ba98b6371245077ff93ffe215 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:16:56 +0200 Subject: [PATCH 614/750] Improved sig.remove2() performance --- kernel/rtlil.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 60c514d1..e4bf4f9f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2182,14 +2182,23 @@ void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigS std::vector new_bits, new_other_bits; + new_bits.resize(SIZE(bits_)); + if (other != NULL) + new_other_bits.resize(SIZE(bits_)); + + int k = 0; for (int i = 0; i < SIZE(bits_); i++) { if (bits_[i].wire != NULL && pattern.count(bits_[i])) continue; if (other != NULL) - new_other_bits.push_back(other->bits_[i]); - new_bits.push_back(bits_[i]); + new_other_bits[k] = other->bits_[i]; + new_bits[k++] = bits_[i]; } + new_bits.resize(k); + if (other != NULL) + new_other_bits.resize(k); + bits_.swap(new_bits); width_ = SIZE(bits_); From 64713647a966e8a14dff39f9ac18aafe9c882f46 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:17:49 +0200 Subject: [PATCH 615/750] Improved AST ProcessGenerator performance --- frontends/ast/genrtlil.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 4eb4f6c4..1936146b 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; From aa3a6663e2e9a63b88cfb1d008e3e246dc9fa677 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:24:53 +0200 Subject: [PATCH 616/750] Makefile fixes --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cf176fde..4d86a8c9 100644 --- a/Makefile +++ b/Makefile @@ -80,7 +80,7 @@ LDLIBS += -l$(TCL_VERSION) endif ifeq ($(ENABLE_GPROF),1) -CXXFLAGS += -pg -fno-inline +CXXFLAGS += -pg LDFLAGS += -pg endif @@ -150,6 +150,7 @@ OBJS += passes/cmds/select.o OBJS += passes/cmds/show.o OBJS += passes/cmds/stat.o OBJS += passes/cmds/cover.o +OBJS += passes/cmds/design.o include passes/proc/Makefile.inc include passes/opt/Makefile.inc @@ -159,6 +160,8 @@ include passes/abc/Makefile.inc include backends/verilog/Makefile.inc include backends/ilang/Makefile.inc +include techlibs/common/Makefile.inc + endif top-all: $(TARGETS) $(EXTRA_TARGETS) From aa7a3ed83f0972bd6da3b272e7bbc9efb1409067 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:25:59 +0200 Subject: [PATCH 617/750] Fixed proc_{self,share}_dirname error handling --- kernel/yosys.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/yosys.cc b/kernel/yosys.cc index dff31db0..599c92d5 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -207,8 +207,7 @@ std::string proc_self_dirname () char path [PATH_MAX]; ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); if (buflen < 0) { - log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); - log_abort(); + log_error("readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno)); } while (buflen > 0 && path[buflen-1] != '/') buflen--; @@ -239,8 +238,7 @@ std::string proc_share_dirname () proc_share_path = proc_self_path + "../share/yosys/"; if (access(proc_share_path.c_str(), X_OK) == 0) return proc_share_path; - log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); - log_abort(); + log_error("proc_share_dirname: unable to determine share/ directory!\n"); } bool fgetline(FILE *f, std::string &buffer) From acb435b6cf583b6c18f405a9c92566c4e9fb85e5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:02:30 +0200 Subject: [PATCH 618/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 6ac77144..0ea38b50 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 6ea241fa..ef54d76f 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 76d1f827..85671213 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()) { From 4b3834e0cc3c34b6845ab50ffd7e9fe396173e8d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:03:33 +0200 Subject: [PATCH 619/750] Replaced recursive lcu scheme with bk adder --- techlibs/common/techmap.v | 90 +++++++++++++-------------------------- 1 file changed, 30 insertions(+), 60 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 9bdff4f3..5bbe883e 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -285,80 +285,50 @@ module \$__alu_ripple (A, B, CI, X, Y, CO, CS); endgenerate endmodule -module \$__lcu_simple (P, G, CI, CO, PG, GG); - parameter WIDTH = 1; +module \$__lcu (P, G, CI, CO); + parameter WIDTH = 2; input [WIDTH-1:0] P, G; input CI; output reg [WIDTH:0] CO; - output reg PG, GG; - wire [1023:0] _TECHMAP_DO_ = "proc;;"; + integer i, j, k; + reg [WIDTH-1:0] p, g; - integer i, j; - reg [WIDTH-1:0] tmp; + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; always @* begin - PG = &P; - GG = 0; - for (i = 0; i < WIDTH; i = i+1) begin - tmp = ~0; - tmp[i] = G[i]; - for (j = i+1; j < WIDTH; j = j+1) - tmp[j] = P[j]; - GG = GG || &tmp[WIDTH-1:i]; - end + p = P; + g = G; - CO[0] = CI; - for (i = 0; i < WIDTH; i = i+1) - CO[i+1] = G[i] | (P[i] & CO[i]); - end -endmodule + // in almost all cases CI will be constant zero + g[0] = g[0] | (p[0] & CI); -module \$__lcu (P, G, CI, CO, PG, GG); - parameter WIDTH = 1; + // [[CITE]] Brent Kung Adder + // R. P. Brent and H. T. Kung, “A Regular Layout for Parallel Adders”, + // IEEE Transaction on Computers, Vol. C-31, No. 3, p. 260-264, March, 1982 - function integer get_group_size; - begin - get_group_size = 4; - while (4 * get_group_size < WIDTH) - get_group_size = 4 * get_group_size; - end - endfunction - - input [WIDTH-1:0] P, G; - input CI; - - output [WIDTH:0] CO; - output PG, GG; - - genvar i; - generate - if (WIDTH <= 4) begin - \$__lcu_simple #(.WIDTH(WIDTH)) _TECHMAP_REPLACE_ (.P(P), .G(G), .CI(CI), .CO(CO), .PG(PG), .GG(GG)); - end else begin - localparam GROUP_SIZE = get_group_size(); - localparam GROUPS_NUM = (WIDTH + GROUP_SIZE - 1) / GROUP_SIZE; - - wire [GROUPS_NUM-1:0] groups_p, groups_g; - wire [GROUPS_NUM:0] groups_ci; - - for (i = 0; i < GROUPS_NUM; i = i+1) begin:V - localparam g_size = `MIN(GROUP_SIZE, WIDTH - i*GROUP_SIZE); - localparam g_offset = i*GROUP_SIZE; - wire [g_size:0] g_co; - - \$__lcu #(.WIDTH(g_size)) g (.P(P[g_offset +: g_size]), .G(G[g_offset +: g_size]), - .CI(groups_ci[i]), .CO(g_co), .PG(groups_p[i]), .GG(groups_g[i])); - assign CO[g_offset+1 +: g_size] = g_co[1 +: g_size]; + // Main tree + for (i = 1; i <= $clog2(WIDTH); i = i+1) begin + for (j = 2**i - 1; j < WIDTH; j = j + 2**i) begin + k = j - 2**(i-1); + g[j] = g[j] | p[j] & g[k]; + p[j] = p[j] & p[k]; end - - \$__lcu_simple #(.WIDTH(GROUPS_NUM)) super_lcu (.P(groups_p), .G(groups_g), .CI(CI), .CO(groups_ci), .PG(PG), .GG(GG)); - - assign CO[0] = CI; end - endgenerate + + // Inverse tree + for (i = $clog2(WIDTH); i > 0; i = i-1) begin + for (j = 2**i + 2**(i-1) - 1; j < WIDTH; j = j + 2**i) begin + k = j - 2**(i-1); + g[j] = g[j] | p[j] & g[k]; + p[j] = p[j] & p[k]; + end + end + end + + assign CO = {g, CI}; endmodule module \$__alu_lookahead (A, B, CI, X, Y, CO, CS); From 6f33fc3e87f5d0429f2236662eb31954e51a71ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:27:54 +0200 Subject: [PATCH 620/750] Performance fix for new $__lcu techmap rule --- techlibs/common/techmap.v | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 5bbe883e..366351ec 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -293,7 +293,7 @@ module \$__lcu (P, G, CI, CO); output reg [WIDTH:0] CO; - integer i, j, k; + integer i, j; reg [WIDTH-1:0] p, g; wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; @@ -312,18 +312,16 @@ module \$__lcu (P, G, CI, CO); // Main tree for (i = 1; i <= $clog2(WIDTH); i = i+1) begin for (j = 2**i - 1; j < WIDTH; j = j + 2**i) begin - k = j - 2**(i-1); - g[j] = g[j] | p[j] & g[k]; - p[j] = p[j] & p[k]; + g[j] = g[j] | p[j] & g[j - 2**(i-1)]; + p[j] = p[j] & p[j - 2**(i-1)]; end end // Inverse tree for (i = $clog2(WIDTH); i > 0; i = i-1) begin for (j = 2**i + 2**(i-1) - 1; j < WIDTH; j = j + 2**i) begin - k = j - 2**(i-1); - g[j] = g[j] | p[j] & g[k]; - p[j] = p[j] & p[k]; + g[j] = g[j] | p[j] & g[j - 2**(i-1)]; + p[j] = p[j] & p[j - 2**(i-1)]; end end end From 640d9fc551c546b511f8d64c0ccfc438937164a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 14:29:30 +0200 Subject: [PATCH 621/750] Added "via_celltype" attribute on task/func --- README | 27 ++++++++++++++ frontends/ast/simplify.cc | 75 +++++++++++++++++++++++++++++++++++--- frontends/verilog/parser.y | 26 +++++++------ 3 files changed, 110 insertions(+), 18 deletions(-) diff --git a/README b/README index 1ecaa07d..a0e67e8a 100644 --- a/README +++ b/README @@ -290,6 +290,33 @@ Verilog Attributes and non-standard features assign b = 42; """ +- The attribute "via_celltype" can be used to implement a verilog task or + function by instantiating the specified cell type. The value is the name + of the cell type to use. For functions the name of the output port can + be specified by appending it to the cell type separated by a whitespace. + The body of the task or function is unused in this case and can be used + to specify a behavioral model of the cell type for simulation. For example: + + module my_add3(A, B, C, Y); + parameter WIDTH = 8; + input [WIDTH-1:0] A, B, C; + output [WIDTH-1:0] Y; + ... + endmodule + + module top; + ... + (* via_celltype = "my_add3 Y" *) + (* via_celltype_defparam_WIDTH = 32 *) + function [31:0] add3; + input [31:0] A, B, C; + begin + add3 = A + B + C; + end + endfunction + ... + endmodule + - Sized constants (the syntax 's?[bodh]) support constant expressions as . If the expresion is not a simple identifier, it must be put in parentheses. Examples: WIDTH'd42, (4+2)'b101010 diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 85671213..2572fa4a 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 f619d3c2..bf9b21bb 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(); From a92a68ce521c1e86c0666b9add0c88d59154325e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 14:30:20 +0200 Subject: [PATCH 622/750] Using "via_celltype" in $mul carry-save-acc implementation --- techlibs/common/techmap.v | 106 ++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 34 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 366351ec..1486b801 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -465,62 +465,98 @@ endmodule // Multiply // -------------------------------------------------------- -module \$__arraymul (A, B, Y); - parameter WIDTH = 8; +module \$__acc_set (acc_new, value); + parameter WIDTH = 1; + output reg [2*WIDTH-1:0] acc_new; + input [WIDTH-1:0] value; + + wire [1023:0] _TECHMAP_DO_ = "proc;;;"; + + integer k; + always @* begin + for (k = 0; k < WIDTH; k = k+1) begin + acc_new[2*k +: 2] = value[k]; + end + end +endmodule + +module \$__acc_add (acc_new, acc_old, value); + parameter WIDTH = 1; + output reg [2*WIDTH-1:0] acc_new; + input [2*WIDTH-1:0] acc_old; + input [WIDTH-1:0] value; + + wire [1023:0] _TECHMAP_DO_ = "proc; simplemap; opt -purge"; + + integer k; + reg a, b, c; + + always @* begin + for (k = 0; k < WIDTH; k = k+1) begin + a = acc_old[2*k]; + b = k ? acc_old[2*k-1] : 1'b0; + c = value[k]; + acc_new[2*k] = (a ^ b) ^ c; + acc_new[2*k+1] = (a & b) | ((a ^ b) & c); + end + end +endmodule + +module \$__acc_get (value, acc); + parameter WIDTH = 1; + output reg [WIDTH-1:0] value; + input [2*WIDTH-1:0] acc; + + wire [1023:0] _TECHMAP_DO_ = "proc;;;"; + + integer k; + + always @* begin + // at the end of the multiplier chain the carry-save accumulator + // should also have propagated all carries. thus we just need to + // copy the even bits from the carry accumulator to the output. + for (k = 0; k < WIDTH; k = k+1) begin + value[k] = acc[2*k]; + end + end +endmodule + +module \$__acc_mul (A, B, Y); + parameter WIDTH = 1; input [WIDTH-1:0] A, B; output [WIDTH-1:0] Y; - wire [1023:0] _TECHMAP_DO_ = "proc;; opt"; + wire [1023:0] _TECHMAP_DO_ = "proc;;"; integer i; reg [WIDTH-1:0] x; reg [2*WIDTH-1:0] y; + (* via_celltype = "\\$__acc_set acc_new" *) + (* via_celltype_defparam_WIDTH = WIDTH *) function [2*WIDTH-1:0] acc_set; input [WIDTH-1:0] value; - integer k; - begin - for (k = 0; k < WIDTH; k = k+1) begin - acc_set[2*k +: 2] = value[k]; - end - end endfunction + (* via_celltype = "\\$__acc_add acc_new" *) + (* via_celltype_defparam_WIDTH = WIDTH *) function [2*WIDTH-1:0] acc_add; - input [2*WIDTH-1:0] old_acc; + input [2*WIDTH-1:0] acc_old; input [WIDTH-1:0] value; - integer k; - reg a, b, c; - begin - for (k = 0; k < WIDTH; k = k+1) begin - a = old_acc[2*k]; - b = k ? old_acc[2*k-1] : 1'b0; - c = value[k]; - acc_add[2*k] = (a ^ b) ^ c; - acc_add[2*k+1] = (a & b) | ((a ^ b) & c); - end - end endfunction + (* via_celltype = "\\$__acc_get value" *) + (* via_celltype_defparam_WIDTH = WIDTH *) function [WIDTH-1:0] acc_get; input [2*WIDTH-1:0] acc; - integer k; - begin - // at the end of the multiplier chain the carry-save accumulator - // should also have propagated all carries. thus we just need to - // copy the even bits from the carry accumulator to the output. - for (k = 0; k < WIDTH; k = k+1) begin - acc_get[k] = acc[2*k]; - end - end endfunction always @* begin x = B; - y = acc_set(A[0] ? x : 0); + y = acc_set(A[0] ? x : 1'b0); for (i = 1; i < WIDTH; i = i+1) begin x = {x[WIDTH-2:0], 1'b0}; - y = acc_add(y, A[i] ? x : 0); + y = acc_add(y, A[i] ? x : 1'b0); end end @@ -538,13 +574,15 @@ module \$mul (A, B, Y); input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; + wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt -purge"; + wire [Y_WIDTH-1:0] A_buf, B_buf; \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - \$__arraymul #( + \$__acc_mul #( .WIDTH(Y_WIDTH) - ) arraymul ( + ) _TECHMAP_REPLACE_ ( .A(A_buf), .B(B_buf), .Y(Y) From b37d70dfd7fbc7cacc2b5fc9f3915e27da5eec07 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 19 Aug 2014 13:44:56 +0200 Subject: [PATCH 623/750] Added mod->addGate() methods for new gate types --- kernel/rtlil.cc | 129 ++++++++++++++++++++++++++++-------------------- kernel/rtlil.h | 34 +++++++++---- 2 files changed, 100 insertions(+), 63 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index e4bf4f9f..24cce6b8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1239,10 +1239,10 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters["\\A_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.size(); \ - cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->setPort("\\A", sig_a); \ - cell->setPort("\\Y", sig_y); \ + cell->parameters["\\A_WIDTH"] = sig_a.size(); \ + cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ + cell->setPort("\\A", sig_a); \ + cell->setPort("\\Y", sig_y); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed) { \ @@ -1267,12 +1267,12 @@ DEF_METHOD(LogicNot, 1, "$logic_not") RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters["\\A_SIGNED"] = is_signed; \ cell->parameters["\\B_SIGNED"] = is_signed; \ - cell->parameters["\\A_WIDTH"] = sig_a.size(); \ - cell->parameters["\\B_WIDTH"] = sig_b.size(); \ - cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ - cell->setPort("\\A", sig_a); \ - cell->setPort("\\B", sig_b); \ - cell->setPort("\\Y", sig_y); \ + cell->parameters["\\A_WIDTH"] = sig_a.size(); \ + cell->parameters["\\B_WIDTH"] = sig_b.size(); \ + cell->parameters["\\Y_WIDTH"] = sig_y.size(); \ + cell->setPort("\\A", sig_a); \ + cell->setPort("\\B", sig_b); \ + cell->setPort("\\Y", sig_y); \ return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed) { \ @@ -1309,72 +1309,95 @@ DEF_METHOD(LogicOr, 1, "$logic_or") #define DEF_METHOD(_func, _type, _pmux) \ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y) { \ - RTLIL::Cell *cell = addCell(name, _type); \ + RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters["\\WIDTH"] = sig_a.size(); \ cell->parameters["\\WIDTH"] = sig_b.size(); \ if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ - cell->setPort("\\A", sig_a); \ - cell->setPort("\\B", sig_b); \ - cell->setPort("\\S", sig_s); \ - cell->setPort("\\Y", sig_y); \ - return cell; \ + cell->setPort("\\A", sig_a); \ + cell->setPort("\\B", sig_b); \ + cell->setPort("\\S", sig_s); \ + cell->setPort("\\Y", sig_y); \ + return cell; \ } \ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s) { \ RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \ - add ## _func(name, sig_a, sig_b, sig_s, sig_y); \ - return sig_y; \ + add ## _func(name, sig_a, sig_b, sig_s, sig_y); \ + return sig_y; \ } DEF_METHOD(Mux, "$mux", 0) DEF_METHOD(Pmux, "$pmux", 1) #undef DEF_METHOD #define DEF_METHOD_2(_func, _type, _P1, _P2) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->setPort("\\" #_P1, sig1); \ - cell->setPort("\\" #_P2, sig2); \ - return cell; \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2) { \ + RTLIL::Cell *cell = addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + return cell; \ } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1) { \ - RTLIL::SigSpec sig2 = addWire(NEW_ID); \ - add ## _func(name, sig1, sig2); \ - return sig2; \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1) { \ + RTLIL::SigBit sig2 = addWire(NEW_ID); \ + add ## _func(name, sig1, sig2); \ + return sig2; \ } #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->setPort("\\" #_P1, sig1); \ - cell->setPort("\\" #_P2, sig2); \ - cell->setPort("\\" #_P3, sig3); \ - return cell; \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3) { \ + RTLIL::Cell *cell = addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ + return cell; \ } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2) { \ - RTLIL::SigSpec sig3 = addWire(NEW_ID); \ - add ## _func(name, sig1, sig2, sig3); \ - return sig3; \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2) { \ + RTLIL::SigBit sig3 = addWire(NEW_ID); \ + add ## _func(name, sig1, sig2, sig3); \ + return sig3; \ } #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ - RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3, RTLIL::SigSpec sig4) { \ - RTLIL::Cell *cell = addCell(name, _type); \ - cell->setPort("\\" #_P1, sig1); \ - cell->setPort("\\" #_P2, sig2); \ - cell->setPort("\\" #_P3, sig3); \ - cell->setPort("\\" #_P4, sig4); \ - return cell; \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4) { \ + RTLIL::Cell *cell = addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ + cell->setPort("\\" #_P4, sig4); \ + return cell; \ } \ - RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig1, RTLIL::SigSpec sig2, RTLIL::SigSpec sig3) { \ - RTLIL::SigSpec sig4 = addWire(NEW_ID); \ - add ## _func(name, sig1, sig2, sig3, sig4); \ - return sig4; \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3) { \ + RTLIL::SigBit sig4 = addWire(NEW_ID); \ + add ## _func(name, sig1, sig2, sig3, sig4); \ + return sig4; \ } -DEF_METHOD_2(NotGate, "$_NOT_", A, Y) -DEF_METHOD_3(AndGate, "$_AND_", A, B, Y) -DEF_METHOD_3(OrGate, "$_OR_", A, B, Y) -DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y) -DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y) +#define DEF_METHOD_5(_func, _type, _P1, _P2, _P3, _P4, _P5) \ + RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, RTLIL::SigBit sig5) { \ + RTLIL::Cell *cell = addCell(name, _type); \ + cell->setPort("\\" #_P1, sig1); \ + cell->setPort("\\" #_P2, sig2); \ + cell->setPort("\\" #_P3, sig3); \ + cell->setPort("\\" #_P4, sig4); \ + cell->setPort("\\" #_P5, sig5); \ + return cell; \ + } \ + RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4) { \ + RTLIL::SigBit sig5 = addWire(NEW_ID); \ + add ## _func(name, sig1, sig2, sig3, sig4, sig5); \ + return sig5; \ + } +DEF_METHOD_2(NotGate, "$_NOT_", A, Y) +DEF_METHOD_3(AndGate, "$_AND_", A, B, Y) +DEF_METHOD_3(NandGate, "$_NAND_", A, B, Y) +DEF_METHOD_3(OrGate, "$_OR_", A, B, Y) +DEF_METHOD_3(NorGate, "$_NOR_", A, B, Y) +DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y) +DEF_METHOD_3(XnorGate, "$_XNOR_", A, B, Y) +DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y) +DEF_METHOD_4(Aoi3Gate, "$_AOI3_", A, B, C, Y) +DEF_METHOD_4(Oai3Gate, "$_OAI3_", A, B, C, Y) +DEF_METHOD_5(Aoi4Gate, "$_AOI4_", A, B, C, D, Y) +DEF_METHOD_5(Oai4Gate, "$_OAI4_", A, B, C, D, Y) #undef DEF_METHOD_2 #undef DEF_METHOD_3 #undef DEF_METHOD_4 +#undef DEF_METHOD_5 RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7e052b09..8b3306f6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -697,11 +697,18 @@ public: RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true); - RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y); - RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); - RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); - RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); - RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); + RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y); + RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y); + RTLIL::Cell* addNandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y); + RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y); + RTLIL::Cell* addNorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y); + RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y); + RTLIL::Cell* addXnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y); + RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y); + RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y); + RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y); + RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y); + RTLIL::Cell* addOai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y); RTLIL::Cell* addDffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true); RTLIL::Cell* addDffsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, @@ -760,11 +767,18 @@ public: RTLIL::SigSpec Mux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); RTLIL::SigSpec Pmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); - RTLIL::SigSpec NotGate (RTLIL::IdString name, RTLIL::SigSpec sig_a); - RTLIL::SigSpec AndGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); - RTLIL::SigSpec OrGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); - RTLIL::SigSpec XorGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); - RTLIL::SigSpec MuxGate (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); + RTLIL::SigBit NotGate (RTLIL::IdString name, RTLIL::SigBit sig_a); + RTLIL::SigBit AndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b); + RTLIL::SigBit NandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b); + RTLIL::SigBit OrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b); + RTLIL::SigBit NorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b); + RTLIL::SigBit XorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b); + RTLIL::SigBit XnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b); + RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s); + RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c); + RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c); + RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d); + RTLIL::SigBit Oai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d); }; struct RTLIL::Wire From 38addd4c67905e3d1514ba839f07d94058e42560 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:42:28 +0200 Subject: [PATCH 624/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0ea38b50..d59ff1bb 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 bf9b21bb..acd904e5 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 4466e1cb..19578908 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); From 7bfc4ae12030648cd73686d3779c6d412a3c33c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:43:51 +0200 Subject: [PATCH 625/750] 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 diff --git a/frontends/ast/Makefile.inc b/frontends/ast/Makefile.inc index 993ead92..91d917c9 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 d59ff1bb..de38eff6 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 ef54d76f..88917c64 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 00000000..a1954dab --- /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 1936146b..506c2bb2 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 2572fa4a..19f1d055 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 fdb9bb02..cf51aac8 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 acd904e5..1d62bc3b 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; From 490d7a5bf2062481dfda656de86bfbeca83c080d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 13:09:47 +0200 Subject: [PATCH 626/750] Fixed memory leak in DPI function calls --- frontends/ast/simplify.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 19f1d055..5cf64310 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; } From 085c8e873d4d90129a952eba85836891635a7f8c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:11:51 +0200 Subject: [PATCH 627/750] 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(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index de38eff6..2fc8f983 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 88917c64..0a401673 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 a1954dab..965645cd 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); From 6c5cafcd8bf4d6b12b4d510480a0ccc1adee7212 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:22:04 +0200 Subject: [PATCH 628/750] 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(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5cf64310..859058cb 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 cf51aac8..f79f81a9 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 1d62bc3b..22312c6d 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; From ad146c25823505e8f9b3cb2b67ba00821a755375 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:33:40 +0200 Subject: [PATCH 629/750] Fixed small memory leak in ast simplify --- frontends/ast/simplify.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 859058cb..68c17271 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); } From c2df5b9175fb11e054ffb8426287b82f2bb2582b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:40:49 +0200 Subject: [PATCH 630/750] Cosmetic changes to FSM tests --- tests/fsm/run-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fsm/run-test.sh b/tests/fsm/run-test.sh index 3d0ff757..57c2a5b1 100755 --- a/tests/fsm/run-test.sh +++ b/tests/fsm/run-test.sh @@ -13,6 +13,7 @@ python generate.py { all_targets="all_targets:" echo "all: all_targets" + echo " @echo" for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do idx=$( printf "%05d" $i ) echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v" @@ -27,6 +28,5 @@ python generate.py echo "running tests.." ${MAKE:-make} -f temp/makefile -echo exit 0 From 752650a062cb262b37f1c5ea62663e5c8c9c7928 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 12:20:23 +0200 Subject: [PATCH 631/750] Updated ABC to 4d547a5e065b --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4d86a8c9..a64c628e 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ OBJS = kernel/version_$(GIT_REV).o # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 4935c2b946de +ABCREV = 4d547a5e065b ABCPULL = 1 -include Makefile.conf From a3494fa9ed32d7ff2b826dfc921e3a0139158880 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 13:58:36 +0200 Subject: [PATCH 632/750] Added "plugin" command --- Makefile | 1 + kernel/driver.cc | 15 ++--- kernel/yosys.cc | 7 +++ kernel/yosys.h | 5 ++ passes/cmds/Makefile.inc | 1 + passes/cmds/plugin.cc | 117 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 passes/cmds/plugin.cc diff --git a/Makefile b/Makefile index a64c628e..e7417539 100644 --- a/Makefile +++ b/Makefile @@ -151,6 +151,7 @@ OBJS += passes/cmds/show.o OBJS += passes/cmds/stat.o OBJS += passes/cmds/cover.o OBJS += passes/cmds/design.o +OBJS += passes/cmds/plugin.o include passes/proc/Makefile.inc include passes/opt/Makefile.inc diff --git a/kernel/driver.cc b/kernel/driver.cc index d59e68a5..6bd60d7b 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -38,7 +37,7 @@ int main(int argc, char **argv) std::string frontend_command = "auto"; std::string backend_command = "auto"; std::vector passes_commands; - std::vector loaded_modules; + std::vector plugin_filenames; std::string output_filename = ""; std::string scriptfile = ""; bool scriptfile_tcl = false; @@ -82,11 +81,7 @@ int main(int argc, char **argv) passes_commands.push_back("opt"); break; case 'm': - loaded_modules.push_back(dlopen(optarg, RTLD_LAZY|RTLD_GLOBAL)); - if (loaded_modules.back() == NULL) { - fprintf(stderr, "Can't load module `%s': %s\n", optarg, dlerror()); - exit(1); - } + plugin_filenames.push_back(optarg); break; case 'f': frontend_command = optarg; @@ -239,6 +234,9 @@ int main(int argc, char **argv) yosys_setup(); + for (auto &fn : plugin_filenames) + load_plugin(fn, {}); + if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) { if (!got_output_filename) backend_command = ""; @@ -346,9 +344,6 @@ int main(int argc, char **argv) yosys_shutdown(); - for (auto mod : loaded_modules) - dlclose(mod); - return 0; } diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 599c92d5..ce248731 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -98,6 +99,12 @@ void yosys_shutdown() yosys_tcl_interp = NULL; } #endif + + for (auto &it : loaded_plugins) + dlclose(it.second); + + loaded_plugins.clear(); + loaded_plugin_aliases.clear(); } RTLIL::IdString new_id(std::string file, int line, std::string func) diff --git a/kernel/yosys.h b/kernel/yosys.h index 79c90628..c6cbcabc 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -132,6 +132,11 @@ extern const char *yosys_version_str; extern std::map saved_designs; extern std::vector pushed_designs; +// from passes/cmds/pluginc.cc +extern std::map loaded_plugins; +extern std::map loaded_plugin_aliases; +void load_plugin(std::string filename, std::vector aliases); + YOSYS_NAMESPACE_END #endif diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index d6e45f2d..4cf61150 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -21,4 +21,5 @@ OBJS += passes/cmds/connwrappers.o OBJS += passes/cmds/cover.o OBJS += passes/cmds/trace.o OBJS += passes/cmds/wreduce.o +OBJS += passes/cmds/plugin.o diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc new file mode 100644 index 00000000..c73684f1 --- /dev/null +++ b/passes/cmds/plugin.cc @@ -0,0 +1,117 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 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/yosys.h" +#include + +YOSYS_NAMESPACE_BEGIN + +std::map loaded_plugins; +std::map loaded_plugin_aliases; + +void load_plugin(std::string filename, std::vector aliases) +{ + if (filename.find('/') == std::string::npos) + filename = "./" + filename; + + if (!loaded_plugins.count(filename)) { + void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL); + if (hdl == NULL) + log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror()); + loaded_plugins[filename] = hdl; + Pass::init_register(); + } + + for (auto &alias : aliases) + loaded_plugin_aliases[alias] = filename; +} + +struct PluginPass : public Pass { + PluginPass() : Pass("plugin", "load and list loaded plugins") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" plugin [options]\n"); + log("\n"); + log("Load and list loaded plugins.\n"); + log("\n"); + log(" -i \n"); + log(" Load (install) the specified plugin.\n"); + log("\n"); + log(" -a \n"); + log(" Register the specified alias name for the loaded plugin\n"); + log("\n"); + log(" -l\n"); + log(" List loaded plugins\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + std::string plugin_filename; + std::vector plugin_aliases; + bool list_mode = false; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if ((args[argidx] == "-i") && argidx+1 < args.size() && plugin_filename.empty()) { + plugin_filename = args[++argidx]; + continue; + } + if ((args[argidx] == "-a") && argidx+1 < args.size()) { + plugin_aliases.push_back(args[++argidx]); + continue; + } + if (args[argidx] == "-l") { + list_mode = true; + continue; + } + break; + } + extra_args(args, argidx, design, false); + + if (!plugin_filename.empty()) + load_plugin(plugin_filename, plugin_aliases); + + if (list_mode) + { + log("\n"); + if (loaded_plugins.empty()) + log("No plugins loaded.\n"); + else + log("Loaded plugins:\n"); + + for (auto &it : loaded_plugins) + log(" %s\n", it.first.c_str()); + + if (!loaded_plugin_aliases.empty()) { + log("\n"); + int max_alias_len = 1; + for (auto &it : loaded_plugin_aliases) + max_alias_len = std::max(max_alias_len, SIZE(it.first)); + for (auto &it : loaded_plugin_aliases) + log("Alias: %-*s %s\n", max_alias_len, it.first.c_str(), it.second.c_str()); + } + } + } +} PluginPass; + +YOSYS_NAMESPACE_END + From 74af3a2b7086acad45d15b590a0d23572e8c8734 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:22:09 +0200 Subject: [PATCH 633/750] Archibald Rust and Clifford Wolf: ffi-based dpi_call() --- Makefile | 2 +- README | 4 +- frontends/ast/dpicall.cc | 96 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index e7417539..8d7f2f8d 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -DYOSYS_SRC='"$(shell pwd)"' -D_YOSYS_ -fPIC -I${DESTDIR}/include LDFLAGS = -L${DESTDIR}/lib -LDLIBS = -lstdc++ -lreadline -lm -ldl +LDLIBS = -lstdc++ -lreadline -lm -lffi -ldl QMAKE = qmake-qt4 SED = sed diff --git a/README b/README index a0e67e8a..5c3286c2 100644 --- a/README +++ b/README @@ -57,8 +57,8 @@ Icarus Verilog. For example on Ubuntu Linux 12.04 LTS the following commands will install all prerequisites for building yosys: $ yosys_deps="git g++ clang make bison flex libreadline-dev - tcl8.5-dev zlib1g-dev libqt4-dev mercurial - iverilog graphviz" + tcl8.5-dev zlib1g-dev libqt4-dev libffi-dev + mercurial iverilog graphviz" $ sudo apt-get install $yosys_deps There are also pre-compiled packages for Yosys on Ubuntu. Visit the Yosys diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index 965645cd..b79bd59e 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)); - else + 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)); + 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 == "real" || rtype == "shortreal") { + 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); + + ffi_call(&cif, resolve_fn(fname.c_str()), values[args.size()], values); + + if (rtype == "real") { newNode = new AstNode(AST_REALVALUE); - newNode->realvalue = 1234; + 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 = 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; From e218f0eacf7cbcfa0736cb2d66bba0010e8e6799 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:30:29 +0200 Subject: [PATCH 634/750] Added support for non-standard : DPI syntax --- frontends/verilog/parser.y | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 22312c6d..3512538c 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; From ba83a7bdc641c68344b41f407323c76b8c62c674 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:37:14 +0200 Subject: [PATCH 635/750] Added DPI-C documentation to README file --- README | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README b/README index 5c3286c2..2e713ffe 100644 --- a/README +++ b/README @@ -317,6 +317,18 @@ Verilog Attributes and non-standard features ... endmodule +- A limited subset of DPI-C functions is supported. The plugin mechanism + (see "help plugin") can be used load .so files with implementations of + DPI-C routines. As a non-standard extension it is possible to specify + a plugin alias using the ":" syntax. for example: + + module dpitest; + import "DPI-C" function foo:round = real my_round (real); + parameter real r = my_round(12.345); + endmodule + + $ yosys -p 'plugin -a foo -i /lib/libm.so; read_verilog dpitest.v' + - Sized constants (the syntax 's?[bodh]) support constant expressions as . If the expresion is not a simple identifier, it must be put in parentheses. Examples: WIDTH'd42, (4+2)'b101010 From 98442e019d745f1d61983c071decfa3ebc1ff0cf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 16:09:13 +0200 Subject: [PATCH 636/750] Added emscripten (emcc) support to build system and some build fixes --- Makefile | 29 ++++++++++++++++++++++++++++- frontends/ast/ast.cc | 4 ++++ frontends/ast/dpicall.cc | 14 +++++++++++++- kernel/celltypes.h | 4 ++-- kernel/compatibility.cc | 2 +- kernel/driver.cc | 10 ++++++++-- kernel/rtlil.cc | 4 ++++ kernel/rtlil.h | 5 ++--- kernel/yosys.cc | 25 +++++++++++++++++++++++-- passes/cmds/plugin.cc | 9 ++++++++- passes/cmds/show.cc | 9 ++++++++- 11 files changed, 101 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 8d7f2f8d..ca595d9c 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,14 @@ CONFIG := clang # CONFIG := gcc # CONFIG := gcc-4.6 +# CONFIG := emcc # features (the more the better) ENABLE_TCL := 1 ENABLE_QT4 := 1 ENABLE_ABC := 1 +ENABLE_PLUGINS := 1 +ENABLE_READLINE := 1 ENABLE_VERIFIC := 0 # other configuration flags @@ -27,7 +30,7 @@ all: top-all CXXFLAGS = -Wall -Wextra -ggdb -I"$(shell pwd)" -MD -DYOSYS_SRC='"$(shell pwd)"' -D_YOSYS_ -fPIC -I${DESTDIR}/include LDFLAGS = -L${DESTDIR}/lib -LDLIBS = -lstdc++ -lreadline -lm -lffi -ldl +LDLIBS = -lstdc++ -lm QMAKE = qmake-qt4 SED = sed @@ -72,6 +75,22 @@ CXX = gcc-4.6 CXXFLAGS += -std=gnu++0x -Os endif +ifeq ($(CONFIG),emcc) +CXX = emcc +CXXFLAGS += -std=c++11 -Os -Wno-warn-absolute-paths +CXXFLAGS := $(filter-out -ggdb,$(CXXFLAGS)) +endif + +ifeq ($(ENABLE_READLINE),1) +CXXFLAGS += -DYOSYS_ENABLE_READLINE +LDLIBS += -lreadline +endif + +ifeq ($(ENABLE_PLUGINS),1) +CXXFLAGS += -DYOSYS_ENABLE_PLUGINS +LDLIBS += -lffi -ldl +endif + ifeq ($(ENABLE_TCL),1) TCL_VERSION ?= tcl8.5 TCL_INCLUDE ?= /usr/include/$(TCL_VERSION) @@ -290,6 +309,14 @@ config-gcc: clean config-gcc-4.6: clean echo 'CONFIG := gcc-4.6' > Makefile.conf +config-emcc: clean + echo 'CONFIG := emcc' > Makefile.conf + echo 'ENABLE_TCL := 0' >> Makefile.conf + echo 'ENABLE_QT4 := 0' >> Makefile.conf + echo 'ENABLE_ABC := 0' >> Makefile.conf + echo 'ENABLE_PLUGINS := 0' >> Makefile.conf + echo 'ENABLE_READLINE := 0' >> Makefile.conf + config-gprof: clean echo 'CONFIG := gcc' > Makefile.conf echo 'ENABLE_GPROF := 1' >> Makefile.conf diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 2fc8f983..1e43875a 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 b79bd59e..2eb104fa 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 */ + diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 8c2e9a48..515da25c 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -108,7 +108,7 @@ struct CellTypes for (auto type : std::vector({"$mux", "$pmux"})) setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); - setup_type("$assert", {"\\A", "\\EN"}, {}, true); + setup_type("$assert", {"\\A", "\\EN"}, std::set(), true); } void setup_internals_mem() @@ -121,7 +121,7 @@ struct CellTypes setup_type("$dlatchsr", {"\\EN", "\\SET", "\\CLR", "\\D"}, {"\\Q"}); setup_type("$memrd", {"\\CLK", "\\ADDR"}, {"\\DATA"}); - setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, {}); + setup_type("$memwr", {"\\CLK", "\\EN", "\\ADDR", "\\DATA"}, std::set()); setup_type("$mem", {"\\RD_CLK", "\\RD_ADDR", "\\WR_CLK", "\\WR_EN", "\\WR_ADDR", "\\WR_DATA"}, {"\\RD_DATA"}); setup_type("$fsm", {"\\CLK", "\\ARST", "\\CTRL_IN"}, {"\\CTRL_OUT"}); diff --git a/kernel/compatibility.cc b/kernel/compatibility.cc index 2ef023eb..4c4cbd6d 100644 --- a/kernel/compatibility.cc +++ b/kernel/compatibility.cc @@ -26,7 +26,7 @@ #include #include -#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) +#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L || defined(EMSCRIPTEN)) typedef struct memstream { off_t pos; diff --git a/kernel/driver.cc b/kernel/driver.cc index 6bd60d7b..e778e138 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -20,8 +20,10 @@ #include "kernel/yosys.h" #include "libs/sha1/sha1.h" -#include -#include +#ifdef YOSYS_ENABLE_READLINE +# include +# include +#endif #include #include @@ -46,6 +48,7 @@ int main(int argc, char **argv) bool print_stats = true; bool call_abort = false; +#ifdef YOSYS_ENABLE_READLINE int history_offset = 0; std::string history_file; if (getenv("HOME") != NULL) { @@ -53,6 +56,7 @@ int main(int argc, char **argv) read_history(history_file.c_str()); history_offset = where_history(); } +#endif int opt; while ((opt = getopt(argc, argv, "AQTVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1) @@ -329,6 +333,7 @@ int main(int argc, char **argv) if (call_abort) abort(); +#ifdef YOSYS_ENABLE_READLINE if (!history_file.empty()) { if (history_offset > 0) { history_truncate_file(history_file.c_str(), 100); @@ -341,6 +346,7 @@ int main(int argc, char **argv) HIST_ENTRY **hist_list = history_list(); if (hist_list != NULL) free(hist_list); +#endif yosys_shutdown(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 24cce6b8..22bff7bd 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1605,6 +1605,10 @@ RTLIL::Memory::Memory() size = 0; } +RTLIL::Cell::Cell() : module(nullptr) +{ +} + bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const { return connections_.count(portname) != 0; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 8b3306f6..ebfe4ca2 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -77,7 +77,7 @@ namespace RTLIL // the global id string cache struct char_ptr_cmp { - bool operator()(const char *a, const char *b) { + bool operator()(const char *a, const char *b) const { for (int i = 0; a[i] || b[i]; i++) if (a[i] != b[i]) return a[i] < b[i]; @@ -815,8 +815,7 @@ struct RTLIL::Cell protected: // use module->addCell() and module->remove() to create or destroy cells friend struct RTLIL::Module; - Cell() : module(nullptr) { }; - ~Cell() { }; + Cell(); public: // do not simply copy cells diff --git a/kernel/yosys.cc b/kernel/yosys.cc index ce248731..7b8173b6 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -19,12 +19,15 @@ #include "kernel/yosys.h" -#include -#include +#ifdef YOSYS_ENABLE_READLINE +# include +# include +#endif #include #include #include +#include YOSYS_NAMESPACE_BEGIN @@ -232,6 +235,11 @@ std::string proc_self_dirname () buflen--; return std::string(path, buflen); } +#elif defined(EMSCRIPTEN) +std::string proc_self_dirname () +{ + return "/"; +} #else #error Dont know how to determine process executable base path! #endif @@ -416,6 +424,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig Backend::backend_call(design, NULL, filename, command); } +#ifdef YOSYS_ENABLE_READLINE static char *readline_cmd_generator(const char *text, int state) { static std::map::iterator it; @@ -493,6 +502,7 @@ static char **readline_completion(const char *text, int start, int) return rl_completion_matches(text, readline_obj_generator); return NULL; } +#endif void shell(RTLIL::Design *design) { @@ -501,16 +511,25 @@ void shell(RTLIL::Design *design) recursion_counter++; log_cmd_error_throw = true; +#ifdef YOSYS_ENABLE_READLINE rl_readline_name = "yosys"; rl_attempted_completion_function = readline_completion; rl_basic_word_break_characters = " \t\n"; +#endif char *command = NULL; +#ifdef YOSYS_ENABLE_READLINE while ((command = readline(create_prompt(design, recursion_counter))) != NULL) +#else + char command_buffer[4096]; + while ((command = fgets(command_buffer, 4096, stdin)) != NULL) +#endif { if (command[strspn(command, " \t\r\n")] == 0) continue; +#ifdef YOSYS_ENABLE_READLINE add_history(command); +#endif char *p = command + strspn(command, " \t\r\n"); if (!strncmp(p, "exit", 4)) { @@ -576,6 +595,7 @@ struct ShellPass : public Pass { } } ShellPass; +#ifdef YOSYS_ENABLE_READLINE struct HistoryPass : public Pass { HistoryPass() : Pass("history", "show last interactive commands") { } virtual void help() { @@ -593,6 +613,7 @@ struct HistoryPass : public Pass { log("%s\n", (*list)->line); } } HistoryPass; +#endif struct ScriptPass : public Pass { ScriptPass() : Pass("script", "execute commands from script file") { } diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index c73684f1..4e8234d1 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -18,7 +18,10 @@ */ #include "kernel/yosys.h" -#include + +#ifdef YOSYS_ENABLE_PLUGINS +# include +#endif YOSYS_NAMESPACE_BEGIN @@ -27,6 +30,7 @@ std::map loaded_plugin_aliases; void load_plugin(std::string filename, std::vector aliases) { +#ifdef YOSYS_ENABLE_PLUGINS if (filename.find('/') == std::string::npos) filename = "./" + filename; @@ -40,6 +44,9 @@ void load_plugin(std::string filename, std::vector aliases) for (auto &alias : aliases) loaded_plugin_aliases[alias] = filename; +#else + log_error("This version of yosys is built without plugin support.\n"); +#endif } struct PluginPass : public Pass { diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 4f6b811b..fc6e972e 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -22,7 +22,10 @@ #include "kernel/log.h" #include #include -#include + +#ifdef YOSYS_ENABLE_READLINE +# include +#endif using RTLIL::id2cstr; @@ -770,6 +773,7 @@ struct ShowPass : public Pass { } if (flag_pause) { + #ifdef YOSYS_ENABLE_READLINE char *input = NULL; while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) { if (input[strspn(input, " \t\r\n")] == 0) @@ -780,6 +784,9 @@ struct ShowPass : public Pass { break; } } + #else + log_cmd_error("This version of yosys is built without readline support => 'show -pause' is not available.\n"); + #endif } log_pop(); From fff12c719fc2d61e36e85f27080a4043078b0929 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 17:20:28 +0200 Subject: [PATCH 637/750] Added "stat -width" --- passes/cmds/stat.cc | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index fabc80ec..dea24227 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -63,7 +63,7 @@ namespace #undef X } - statdata_t(RTLIL::Design *design, RTLIL::Module *mod) + statdata_t(RTLIL::Design *design, RTLIL::Module *mod, bool width_mode) { #define X(_name) _name = 0; STAT_INT_MEMBERS @@ -90,11 +90,35 @@ namespace num_memory_bits += it.second->width * it.second->size; } - for (auto &it : mod->cells_) { + for (auto &it : mod->cells_) + { if (!design->selected(mod, it.second)) continue; + + RTLIL::IdString cell_type = it.second->type; + + if (width_mode) + { + if (cell_type.in("$not", "$pos", "$bu0", "$neg", + "$logic_not", "$logic_and", "$logic_or", + "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", + "$lut", "$and", "$or", "$xor", "$xnor", + "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", + "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", + "$add", "$sub", "$mul", "$div", "$mod", "$pow")) { + int width_a = it.second->hasPort("\\A") ? SIZE(it.second->getPort("\\A")) : 0; + int width_b = it.second->hasPort("\\B") ? SIZE(it.second->getPort("\\B")) : 0; + int width_y = it.second->hasPort("\\Y") ? SIZE(it.second->getPort("\\Y")) : 0; + cell_type = stringf("%s_%d", cell_type.c_str(), std::max({width_a, width_b, width_y})); + } + else if (cell_type.in("$mux", "$pmux")) + cell_type = stringf("%s_%d", cell_type.c_str(), SIZE(it.second->getPort("\\Y"))); + else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr")) + cell_type = stringf("%s_%d", cell_type.c_str(), SIZE(it.second->getPort("\\Q"))); + } + num_cells++; - num_cells_by_type[it.second->type]++; + num_cells_by_type[cell_type]++; } for (auto &it : mod->processes) { @@ -154,17 +178,26 @@ struct StatPass : public Pass { log(" selected and a module has the 'top' attribute set, this module is used\n"); log(" default value for this option.\n"); log("\n"); + log(" -width\n"); + log(" annotate internal cell types with their word width.\n"); + log(" e.g. $add_8 for an 8 bit wide $add cell.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Printing statistics.\n"); + bool width_mode = false; RTLIL::Module *top_mod = NULL; std::map mod_stat; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-width") { + width_mode = true; + continue; + } if (args[argidx] == "-top" && argidx+1 < args.size()) { if (design->modules_.count(RTLIL::escape_id(args[argidx+1])) == 0) log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str()); @@ -184,7 +217,7 @@ struct StatPass : public Pass { if (it.second->get_bool_attribute("\\top")) top_mod = it.second; - statdata_t data(design, it.second); + statdata_t data(design, it.second, width_mode); mod_stat[it.first] = data; log("\n"); From 5dce303a2a2c27d50e99856b6f33467798e13020 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 13:54:21 +0200 Subject: [PATCH 638/750] Changed backend-api from FILE to std::ostream --- backends/blif/blif.cc | 96 +++--- backends/btor/btor.cc | 130 ++++---- backends/edif/edif.cc | 132 ++++---- backends/ilang/ilang_backend.cc | 240 +++++++-------- backends/ilang/ilang_backend.h | 26 +- backends/intersynth/intersynth.cc | 14 +- backends/spice/spice.cc | 52 ++-- backends/verilog/verilog_backend.cc | 460 ++++++++++++++-------------- backends/verilog/verilog_backend.h | 5 +- kernel/log.cc | 25 +- kernel/register.cc | 28 +- kernel/register.h | 16 +- kernel/rtlil.cc | 11 +- kernel/yosys.h | 5 + passes/techmap/extract.cc | 9 +- passes/tests/test_autotb.cc | 186 +++++------ 16 files changed, 710 insertions(+), 725 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index b9b68b97..919022ab 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -44,13 +44,13 @@ struct BlifDumperConfig struct BlifDumper { - FILE *f; + std::ostream &f; RTLIL::Module *module; RTLIL::Design *design; BlifDumperConfig *config; CellTypes ct; - BlifDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) : + BlifDumper(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) : f(f), module(module), design(design), config(config), ct(design) { } @@ -97,8 +97,8 @@ struct BlifDumper void dump() { - fprintf(f, "\n"); - fprintf(f, ".model %s\n", cstr(module->name)); + f << stringf("\n"); + f << stringf(".model %s\n", cstr(module->name)); std::map inputs, outputs; @@ -110,33 +110,33 @@ struct BlifDumper outputs[wire->port_id] = wire; } - fprintf(f, ".inputs"); + f << stringf(".inputs"); for (auto &it : inputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, i))); + f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i))); } - fprintf(f, "\n"); + f << stringf("\n"); - fprintf(f, ".outputs"); + f << stringf(".outputs"); for (auto &it : outputs) { RTLIL::Wire *wire = it.second; for (int i = 0; i < wire->width; i++) - fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, i))); + f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i))); } - fprintf(f, "\n"); + f << stringf("\n"); if (!config->impltf_mode) { if (!config->false_type.empty()) - fprintf(f, ".%s %s %s=$false\n", subckt_or_gate(config->false_type), + f << stringf(".%s %s %s=$false\n", subckt_or_gate(config->false_type), config->false_type.c_str(), config->false_out.c_str()); else - fprintf(f, ".names $false\n"); + f << stringf(".names $false\n"); if (!config->true_type.empty()) - fprintf(f, ".%s %s %s=$true\n", subckt_or_gate(config->true_type), + f << stringf(".%s %s %s=$true\n", subckt_or_gate(config->true_type), config->true_type.c_str(), config->true_out.c_str()); else - fprintf(f, ".names $true\n1\n"); + f << stringf(".names $true\n1\n"); } for (auto &cell_it : module->cells_) @@ -144,116 +144,116 @@ struct BlifDumper RTLIL::Cell *cell = cell_it.second; if (!config->icells_mode && cell->type == "$_NOT_") { - fprintf(f, ".names %s %s\n0 1\n", + f << stringf(".names %s %s\n0 1\n", cstr(cell->getPort("\\A")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_AND_") { - fprintf(f, ".names %s %s %s\n11 1\n", + f << stringf(".names %s %s %s\n11 1\n", cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_OR_") { - fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n", + f << stringf(".names %s %s %s\n1- 1\n-1 1\n", cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_XOR_") { - fprintf(f, ".names %s %s %s\n10 1\n01 1\n", + f << stringf(".names %s %s %s\n10 1\n01 1\n", cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_MUX_") { - fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n", + f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n", cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_N_") { - fprintf(f, ".latch %s %s fe %s\n", + f << stringf(".latch %s %s fe %s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C"))); continue; } if (!config->icells_mode && cell->type == "$_DFF_P_") { - fprintf(f, ".latch %s %s re %s\n", + f << stringf(".latch %s %s re %s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C"))); continue; } if (!config->icells_mode && cell->type == "$lut") { - fprintf(f, ".names"); + f << stringf(".names"); auto &inputs = cell->getPort("\\A"); auto width = cell->parameters.at("\\WIDTH").as_int(); log_assert(inputs.size() == width); for (int i = 0; i < inputs.size(); i++) { - fprintf(f, " %s", cstr(inputs.extract(i, 1))); + f << stringf(" %s", cstr(inputs.extract(i, 1))); } auto &output = cell->getPort("\\Y"); log_assert(output.size() == 1); - fprintf(f, " %s", cstr(output)); - fprintf(f, "\n"); + f << stringf(" %s", cstr(output)); + f << stringf("\n"); auto mask = cell->parameters.at("\\LUT").as_string(); for (int i = 0; i < (1 << width); i++) { if (mask[i] == '0') continue; for (int j = width-1; j >= 0; j--) { - fputc((i>>j)&1 ? '1' : '0', f); + f << ((i>>j)&1 ? '1' : '0'); } - fprintf(f, " %c\n", mask[i]); + f << stringf(" %c\n", mask[i]); } continue; } - fprintf(f, ".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type)); + f << stringf(".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type)); for (auto &conn : cell->connections()) for (int i = 0; i < conn.second.size(); i++) { if (conn.second.size() == 1) - fprintf(f, " %s", cstr(conn.first)); + f << stringf(" %s", cstr(conn.first)); else - fprintf(f, " %s[%d]", cstr(conn.first), i); - fprintf(f, "=%s", cstr(conn.second.extract(i, 1))); + f << stringf(" %s[%d]", cstr(conn.first), i); + f << stringf("=%s", cstr(conn.second.extract(i, 1))); } - fprintf(f, "\n"); + f << stringf("\n"); if (config->param_mode) for (auto ¶m : cell->parameters) { - fprintf(f, ".param %s ", RTLIL::id2cstr(param.first)); + f << stringf(".param %s ", RTLIL::id2cstr(param.first)); if (param.second.flags & RTLIL::CONST_FLAG_STRING) { std::string str = param.second.decode_string(); - fprintf(f, "\""); + f << stringf("\""); for (char ch : str) if (ch == '"' || ch == '\\') - fprintf(f, "\\%c", ch); + f << stringf("\\%c", ch); else if (ch < 32 || ch >= 127) - fprintf(f, "\\%03o", ch); + f << stringf("\\%03o", ch); else - fprintf(f, "%c", ch); - fprintf(f, "\"\n"); + f << stringf("%c", ch); + f << stringf("\"\n"); } else - fprintf(f, "%s\n", param.second.as_string().c_str()); + f << stringf("%s\n", param.second.as_string().c_str()); } } for (auto &conn : module->connections()) for (int i = 0; i < conn.first.size(); i++) if (config->conn_mode) - fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); + f << stringf(".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); else if (!config->buf_type.empty()) - fprintf(f, ".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)), + f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)), config->buf_out.c_str(), cstr(conn.first.extract(i, 1))); else - fprintf(f, ".names %s %s\n1 1\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); + f << stringf(".names %s %s\n1 1\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); - fprintf(f, ".end\n"); + f << stringf(".end\n"); } - static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig &config) + static void dump(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig &config) { BlifDumper dumper(f, module, design, &config); dumper.dump(); @@ -303,7 +303,7 @@ struct BlifBackend : public Backend { log(" do not write definitions for the $true and $false wires.\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { std::string top_module_name; std::string buf_type, buf_in, buf_out; @@ -365,7 +365,7 @@ struct BlifBackend : public Backend { if (mod_it.second->get_bool_attribute("\\top")) top_module_name = mod_it.first.str(); - fprintf(f, "# Generated by %s\n", yosys_version_str); + *f << stringf("# Generated by %s\n", yosys_version_str); std::vector mod_list; @@ -381,7 +381,7 @@ struct BlifBackend : public Backend { log_error("Found munmapped emories in module %s: unmapped memories are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name)); if (module->name == RTLIL::escape_id(top_module_name)) { - BlifDumper::dump(f, module, design, config); + BlifDumper::dump(*f, module, design, config); top_module_name.clear(); continue; } @@ -393,7 +393,7 @@ struct BlifBackend : public Backend { log_error("Can't find top module `%s'!\n", top_module_name.c_str()); for (auto module : mod_list) - BlifDumper::dump(f, module, design, config); + BlifDumper::dump(*f, module, design, config); } } BlifBackend; diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index a81d8f15..9b770518 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -60,7 +60,7 @@ struct WireInfoOrder struct BtorDumper { - FILE *f; + std::ostream &f; RTLIL::Module *module; RTLIL::Design *design; BtorDumperConfig *config; @@ -75,7 +75,7 @@ struct BtorDumper std::map basic_wires;//input wires and registers RTLIL::IdString curr_cell; //current cell being dumped std::map cell_type_translation, s_cell_type_translation; //RTLIL to BTOR translation - BtorDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) : + BtorDumper(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) : f(f), module(module), design(design), config(config), ct(design), sigmap(module) { line_num=0; @@ -174,7 +174,7 @@ struct BtorDumper ++line_num; line_ref[wire->name]=line_num; str = stringf("%d var %d %s", line_num, wire->width, cstr(wire->name)); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); return line_num; } else return it->second; @@ -216,13 +216,13 @@ struct BtorDumper wire_line = ++line_num; str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks().at(j).width, cell_line, start_bit-1, start_bit-cell_output->chunks().at(j).width); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); wire_width += cell_output->chunks().at(j).width; if(prev_wire_line!=0) { ++line_num; str = stringf("%d concat %d %d %d", line_num, wire_width, wire_line, prev_wire_line); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); wire_line = line_num; } } @@ -259,7 +259,7 @@ struct BtorDumper int address_bits = ceil(log(memory->size)/log(2)); str = stringf("%d array %d %d", line_num, memory->width, address_bits); line_ref[memory->name]=line_num; - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); return line_num; } else return it->second; @@ -279,7 +279,7 @@ struct BtorDumper ++line_num; str = stringf("%d const %d %s", line_num, width, data_str.c_str()); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); return line_num; } else @@ -307,7 +307,7 @@ struct BtorDumper ++line_num; str = stringf("%d slice %d %d %d %d;2", line_num, chunk->width, wire_line_num, chunk->width + chunk->offset - 1, chunk->offset); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); l = line_num; } } @@ -339,7 +339,7 @@ struct BtorDumper w2 = s.chunks().at(i).width; ++line_num; str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); l1=line_num; w1+=w2; } @@ -361,17 +361,17 @@ struct BtorDumper //TODO: case the signal is signed ++line_num; str = stringf ("%d zero %d", line_num, expected_width - s.size()); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); l = line_num; } else if(expected_width < s.size()) { ++line_num; str = stringf ("%d slice %d %d %d %d;3", line_num, expected_width, l, expected_width-1, 0); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); l = line_num; } } @@ -397,21 +397,21 @@ struct BtorDumper int en_line = dump_sigspec(en, 1); int one_line = ++line_num; str = stringf("%d one 1", line_num); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$eq").c_str(), 1, en_line, one_line); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), 1, line_num-1, expr_line, one_line); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); int cell_line = ++line_num; str = stringf("%d %s %d %d", line_num, cell_type_translation.at("$assert").c_str(), 1, -1*(line_num-1)); //multiplying the line number with -1, which means logical negation //the reason for negative sign is that the properties in btor are given as "negation of the original property" //bug identified by bobosoft //http://www.reddit.com/r/yosys/comments/1w3xig/btor_backend_bug/ - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=cell_line; } //unary cells @@ -429,13 +429,13 @@ struct BtorDumper cell_line = ++line_num; bool reduced = (cell->type == "$not" || cell->type == "$neg") ? false : true; str = stringf ("%d %s %d %d", cell_line, cell_type_translation.at(cell->type.str()).c_str(), reduced?output_width:w, l); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } if(output_width < w && (cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos")) { ++line_num; str = stringf ("%d slice %d %d %d %d;4", line_num, output_width, cell_line, output_width-1, 0); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); cell_line = line_num; } line_ref[cell->name]=cell_line; @@ -451,17 +451,17 @@ struct BtorDumper { ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } else if(cell->type == "$reduce_xnor") { ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_xor").c_str(), output_width, l); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$not").c_str(), output_width, line_num-1); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } //binary cells @@ -497,7 +497,7 @@ struct BtorDumper } str = stringf ("%d %s %d %d %d", line_num, op.c_str(), output_width, l1, l2); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } @@ -532,13 +532,13 @@ struct BtorDumper op = s_cell_type_translation.at("$mody"); } str = stringf ("%d %s %d %d %d", line_num, op.c_str(), l1_width, l1, l2); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); if(output_width < l1_width) { ++line_num; str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, line_num-1, output_width-1, 0); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } line_ref[cell->name]=line_num; } @@ -556,7 +556,7 @@ struct BtorDumper int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); int cell_output = ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), l1_width, l1, l2); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); if(l2_width > ceil(log(l1_width)/log(2))) { @@ -564,19 +564,19 @@ struct BtorDumper l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width); ++line_num; str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf ("%d one %d", line_num, extra_width); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); int mux = ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$gt").c_str(), 1, line_num-2, line_num-1); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d %s %d", line_num, l1_signed && cell->type == "$sshr" ? "ones":"zero", l1_width); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), l1_width, mux, line_num-1, cell_output); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); cell_output = line_num; } @@ -584,7 +584,7 @@ struct BtorDumper { ++line_num; str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, cell_output, output_width-1, 0); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); cell_output = line_num; } line_ref[cell->name] = cell_output; @@ -602,14 +602,14 @@ struct BtorDumper { ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l1); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); l1 = line_num; } if(l2_width > 1) { ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l2); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); l2 = line_num; } if(cell->type == "$logic_and") @@ -622,7 +622,7 @@ struct BtorDumper ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$or").c_str(), output_width, l1, l2); } - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } //multiplexers @@ -636,7 +636,7 @@ struct BtorDumper ++line_num; str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } //registers @@ -663,7 +663,7 @@ struct BtorDumper slice = ++line_num; str = stringf ("%d slice %d %d %d %d;", line_num, output_width, value, start_bit-1, start_bit-output_width); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } if(cell->type == "$dffsr") { @@ -676,14 +676,14 @@ struct BtorDumper str = stringf ("%d %s %d %s%d %s%d %d", line_num, cell_type_translation.at("$mux").c_str(), output_width, sync_reset_pol ? "":"-", sync_reset, sync_reset_value_pol? "":"-", sync_reset_value, slice); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); slice = line_num; } ++line_num; str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), output_width, polarity?"":"-", cond, slice, reg); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); int next = line_num; if(cell->type == "$adff") { @@ -694,12 +694,12 @@ struct BtorDumper ++line_num; str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), output_width, async_reset_pol ? "":"-", async_reset, async_reset_value, next); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, reg, next); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } line_ref[cell->name]=line_num; } @@ -716,7 +716,7 @@ struct BtorDumper int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); ++line_num; str = stringf("%d read %d %d %d", line_num, data_width, mem, address); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } else if(cell->type == "$memwr") @@ -738,22 +738,22 @@ struct BtorDumper str = stringf("%d one 1", line_num); else str = stringf("%d zero 1", line_num); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d eq 1 %d %d", line_num, clk, line_num-1); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d and 1 %d %d", line_num, line_num-1, enable); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d write %d %d %d %d %d", line_num, data_width, address_width, mem, address, data); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d acond %d %d %d %d %d", line_num, data_width, address_width, line_num-2/*enable*/, line_num-1, mem); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); ++line_num; str = stringf("%d anext %d %d %d %d", line_num, data_width, address_width, mem, line_num-1); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } else if(cell->type == "$slice") @@ -769,7 +769,7 @@ struct BtorDumper int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int(); ++line_num; str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, input_line, output_width+offset-1, offset); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } else if(cell->type == "$concat") @@ -786,7 +786,7 @@ struct BtorDumper ++line_num; str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), input_a_width+input_b_width, input_a_line, input_b_line); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); line_ref[cell->name]=line_num; } curr_cell.clear(); @@ -825,12 +825,12 @@ struct BtorDumper int l = dump_wire(wire); ++line_num; str = stringf("%d root 1 %d", line_num, l); - fprintf(f, "%s\n", str.c_str()); + f << stringf("%s\n", str.c_str()); } void dump() { - fprintf(f, ";module %s\n", cstr(module->name)); + f << stringf(";module %s\n", cstr(module->name)); log("creating intermediate wires map\n"); //creating map of intermediate wires as output of some cell @@ -893,12 +893,12 @@ struct BtorDumper } } - fprintf(f, ";inputs\n"); + f << stringf(";inputs\n"); for (auto &it : inputs) { RTLIL::Wire *wire = it.second; dump_wire(wire); } - fprintf(f, "\n"); + f << stringf("\n"); log("writing memories\n"); for(auto mem_it = module->memories.begin(); mem_it != module->memories.end(); ++mem_it) @@ -921,19 +921,19 @@ struct BtorDumper for(auto it: safety) dump_property(it); - fprintf(f, "\n"); + f << stringf("\n"); log("writing outputs info\n"); - fprintf(f, ";outputs\n"); + f << stringf(";outputs\n"); for (auto &it : outputs) { RTLIL::Wire *wire = it.second; int l = dump_wire(wire); - fprintf(f, ";%d %s", l, cstr(wire->name)); + f << stringf(";%d %s", l, cstr(wire->name)); } - fprintf(f, "\n"); + f << stringf("\n"); } - static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config) + static void dump(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config) { BtorDumper dumper(f, module, design, &config); dumper.dump(); @@ -952,7 +952,7 @@ struct BtorBackend : public Backend { log("Write the current design to an BTOR file.\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { std::string top_module_name; std::string buf_type, buf_in, buf_out; @@ -970,10 +970,10 @@ struct BtorBackend : public Backend { if (mod_it.second->get_bool_attribute("\\top")) top_module_name = mod_it.first.str(); - fprintf(f, "; Generated by %s\n", yosys_version_str); - fprintf(f, "; %s developed and maintained by Clifford Wolf \n", yosys_version_str); - fprintf(f, "; BTOR Backend developed by Ahmed Irfan - Fondazione Bruno Kessler, Trento, Italy\n"); - fprintf(f, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"); + *f << stringf("; Generated by %s\n", yosys_version_str); + *f << stringf("; %s developed and maintained by Clifford Wolf \n", yosys_version_str); + *f << stringf("; BTOR Backend developed by Ahmed Irfan - Fondazione Bruno Kessler, Trento, Italy\n"); + *f << stringf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"); std::vector mod_list; @@ -987,7 +987,7 @@ struct BtorBackend : public Backend { log_error("Found unmapped processes in module %s: unmapped processes are not supported in BTOR backend!\n", RTLIL::id2cstr(module->name)); if (module->name == RTLIL::escape_id(top_module_name)) { - BtorDumper::dump(f, module, design, config); + BtorDumper::dump(*f, module, design, config); top_module_name.clear(); continue; } @@ -999,7 +999,7 @@ struct BtorBackend : public Backend { log_error("Can't find top module `%s'!\n", top_module_name.c_str()); for (auto module : mod_list) - BtorDumper::dump(f, module, design, config); + BtorDumper::dump(*f, module, design, config); } } BtorBackend; diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index ecdfaabf..ccedd91d 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -103,7 +103,7 @@ struct EdifBackend : public Backend { log("is targeted.\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { log_header("Executing EDIF backend.\n"); @@ -160,38 +160,38 @@ struct EdifBackend : public Backend { if (top_module_name.empty()) log_error("No module found in design!\n"); - fprintf(f, "(edif %s\n", EDIF_DEF(top_module_name)); - fprintf(f, " (edifVersion 2 0 0)\n"); - fprintf(f, " (edifLevel 0)\n"); - fprintf(f, " (keywordMap (keywordLevel 0))\n"); - fprintf(f, " (comment \"Generated by %s\")\n", yosys_version_str); + *f << stringf("(edif %s\n", EDIF_DEF(top_module_name)); + *f << stringf(" (edifVersion 2 0 0)\n"); + *f << stringf(" (edifLevel 0)\n"); + *f << stringf(" (keywordMap (keywordLevel 0))\n"); + *f << stringf(" (comment \"Generated by %s\")\n", yosys_version_str); - fprintf(f, " (external LIB\n"); - fprintf(f, " (edifLevel 0)\n"); - fprintf(f, " (technology (numberDefinition))\n"); + *f << stringf(" (external LIB\n"); + *f << stringf(" (edifLevel 0)\n"); + *f << stringf(" (technology (numberDefinition))\n"); - fprintf(f, " (cell GND\n"); - fprintf(f, " (cellType GENERIC)\n"); - fprintf(f, " (view VIEW_NETLIST\n"); - fprintf(f, " (viewType NETLIST)\n"); - fprintf(f, " (interface (port G (direction OUTPUT)))\n"); - fprintf(f, " )\n"); - fprintf(f, " )\n"); + *f << stringf(" (cell GND\n"); + *f << stringf(" (cellType GENERIC)\n"); + *f << stringf(" (view VIEW_NETLIST\n"); + *f << stringf(" (viewType NETLIST)\n"); + *f << stringf(" (interface (port G (direction OUTPUT)))\n"); + *f << stringf(" )\n"); + *f << stringf(" )\n"); - fprintf(f, " (cell VCC\n"); - fprintf(f, " (cellType GENERIC)\n"); - fprintf(f, " (view VIEW_NETLIST\n"); - fprintf(f, " (viewType NETLIST)\n"); - fprintf(f, " (interface (port P (direction OUTPUT)))\n"); - fprintf(f, " )\n"); - fprintf(f, " )\n"); + *f << stringf(" (cell VCC\n"); + *f << stringf(" (cellType GENERIC)\n"); + *f << stringf(" (view VIEW_NETLIST\n"); + *f << stringf(" (viewType NETLIST)\n"); + *f << stringf(" (interface (port P (direction OUTPUT)))\n"); + *f << stringf(" )\n"); + *f << stringf(" )\n"); for (auto &cell_it : lib_cell_ports) { - fprintf(f, " (cell %s\n", EDIF_DEF(cell_it.first)); - fprintf(f, " (cellType GENERIC)\n"); - fprintf(f, " (view VIEW_NETLIST\n"); - fprintf(f, " (viewType NETLIST)\n"); - fprintf(f, " (interface\n"); + *f << stringf(" (cell %s\n", EDIF_DEF(cell_it.first)); + *f << stringf(" (cellType GENERIC)\n"); + *f << stringf(" (view VIEW_NETLIST\n"); + *f << stringf(" (viewType NETLIST)\n"); + *f << stringf(" (interface\n"); for (auto &port_it : cell_it.second) { const char *dir = "INOUT"; if (ct.cell_known(cell_it.first)) { @@ -200,13 +200,13 @@ struct EdifBackend : public Backend { else if (!ct.cell_input(cell_it.first, port_it)) dir = "OUTPUT"; } - fprintf(f, " (port %s (direction %s))\n", EDIF_DEF(port_it), dir); + *f << stringf(" (port %s (direction %s))\n", EDIF_DEF(port_it), dir); } - fprintf(f, " )\n"); - fprintf(f, " )\n"); - fprintf(f, " )\n"); + *f << stringf(" )\n"); + *f << stringf(" )\n"); + *f << stringf(" )\n"); } - fprintf(f, " )\n"); + *f << stringf(" )\n"); std::vector sorted_modules; @@ -238,9 +238,9 @@ struct EdifBackend : public Backend { } - fprintf(f, " (library DESIGN\n"); - fprintf(f, " (edifLevel 0)\n"); - fprintf(f, " (technology (numberDefinition))\n"); + *f << stringf(" (library DESIGN\n"); + *f << stringf(" (edifLevel 0)\n"); + *f << stringf(" (technology (numberDefinition))\n"); for (auto module : sorted_modules) { if (module->get_bool_attribute("\\blackbox")) @@ -249,11 +249,11 @@ struct EdifBackend : public Backend { SigMap sigmap(module); std::map> net_join_db; - fprintf(f, " (cell %s\n", EDIF_DEF(module->name)); - fprintf(f, " (cellType GENERIC)\n"); - fprintf(f, " (view VIEW_NETLIST\n"); - fprintf(f, " (viewType NETLIST)\n"); - fprintf(f, " (interface\n"); + *f << stringf(" (cell %s\n", EDIF_DEF(module->name)); + *f << stringf(" (cellType GENERIC)\n"); + *f << stringf(" (view VIEW_NETLIST\n"); + *f << stringf(" (viewType NETLIST)\n"); + *f << stringf(" (interface\n"); for (auto &wire_it : module->wires_) { RTLIL::Wire *wire = wire_it.second; if (wire->port_id == 0) @@ -264,31 +264,31 @@ struct EdifBackend : public Backend { else if (!wire->port_input) dir = "OUTPUT"; if (wire->width == 1) { - fprintf(f, " (port %s (direction %s))\n", EDIF_DEF(wire->name), dir); + *f << stringf(" (port %s (direction %s))\n", EDIF_DEF(wire->name), dir); RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire)); net_join_db[sig].insert(stringf("(portRef %s)", EDIF_REF(wire->name))); } else { - fprintf(f, " (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir); + *f << stringf(" (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir); for (int i = 0; i < wire->width; i++) { RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, i)); net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), i)); } } } - fprintf(f, " )\n"); - fprintf(f, " (contents\n"); - fprintf(f, " (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n"); - fprintf(f, " (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n"); + *f << stringf(" )\n"); + *f << stringf(" (contents\n"); + *f << stringf(" (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n"); + *f << stringf(" (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n"); for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - fprintf(f, " (instance %s\n", EDIF_DEF(cell->name)); - fprintf(f, " (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type), + *f << stringf(" (instance %s\n", EDIF_DEF(cell->name)); + *f << stringf(" (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type), lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : ""); for (auto &p : cell->parameters) if ((p.second.flags & RTLIL::CONST_FLAG_STRING) != 0) - fprintf(f, "\n (property %s (string \"%s\"))", EDIF_DEF(p.first), p.second.decode_string().c_str()); + *f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(p.first), p.second.decode_string().c_str()); else if (p.second.bits.size() <= 32 && RTLIL::SigSpec(p.second).is_fully_def()) - fprintf(f, "\n (property %s (integer %u))", EDIF_DEF(p.first), p.second.as_int()); + *f << stringf("\n (property %s (integer %u))", EDIF_DEF(p.first), p.second.as_int()); else { std::string hex_string = ""; for (size_t i = 0; i < p.second.bits.size(); i += 4) { @@ -300,9 +300,9 @@ struct EdifBackend : public Backend { char digit_str[2] = { "0123456789abcdef"[digit_value], 0 }; hex_string = std::string(digit_str) + hex_string; } - fprintf(f, "\n (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str()); + *f << stringf("\n (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str()); } - fprintf(f, ")\n"); + *f << stringf(")\n"); for (auto &p : cell->connections()) { RTLIL::SigSpec sig = sigmap(p.second); for (int i = 0; i < SIZE(sig); i++) @@ -320,28 +320,28 @@ struct EdifBackend : public Backend { for (size_t i = 0; i < netname.size(); i++) if (netname[i] == ' ' || netname[i] == '\\') netname.erase(netname.begin() + i--); - fprintf(f, " (net %s (joined\n", EDIF_DEF(netname)); + *f << stringf(" (net %s (joined\n", EDIF_DEF(netname)); for (auto &ref : it.second) - fprintf(f, " %s\n", ref.c_str()); + *f << stringf(" %s\n", ref.c_str()); if (sig.wire == NULL) { if (sig == RTLIL::State::S0) - fprintf(f, " (portRef G (instanceRef GND))\n"); + *f << stringf(" (portRef G (instanceRef GND))\n"); if (sig == RTLIL::State::S1) - fprintf(f, " (portRef P (instanceRef VCC))\n"); + *f << stringf(" (portRef P (instanceRef VCC))\n"); } - fprintf(f, " ))\n"); + *f << stringf(" ))\n"); } - fprintf(f, " )\n"); - fprintf(f, " )\n"); - fprintf(f, " )\n"); + *f << stringf(" )\n"); + *f << stringf(" )\n"); + *f << stringf(" )\n"); } - fprintf(f, " )\n"); + *f << stringf(" )\n"); - fprintf(f, " (design %s\n", EDIF_DEF(top_module_name)); - fprintf(f, " (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name)); - fprintf(f, " )\n"); + *f << stringf(" (design %s\n", EDIF_DEF(top_module_name)); + *f << stringf(" (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name)); + *f << stringf(" )\n"); - fprintf(f, ")\n"); + *f << stringf(")\n"); } } EdifBackend; diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index b7088f59..13d3a8e4 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -23,16 +23,12 @@ */ #include "ilang_backend.h" -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" -#include -#include +#include "kernel/yosys.h" #include using namespace ILANG_BACKEND; -void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int offset, bool autoint) +void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint) { if (width < 0) width = data.bits.size() - offset; @@ -48,222 +44,222 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int } } if (val >= 0) { - fprintf(f, "%d", val); + f << stringf("%d", val); return; } } - fprintf(f, "%d'", width); + f << stringf("%d'", width); for (int i = offset+width-1; i >= offset; i--) { log_assert(i < (int)data.bits.size()); switch (data.bits[i]) { - case RTLIL::S0: fprintf(f, "0"); break; - case RTLIL::S1: fprintf(f, "1"); break; - case RTLIL::Sx: fprintf(f, "x"); break; - case RTLIL::Sz: fprintf(f, "z"); break; - case RTLIL::Sa: fprintf(f, "-"); break; - case RTLIL::Sm: fprintf(f, "m"); break; + case RTLIL::S0: f << stringf("0"); break; + case RTLIL::S1: f << stringf("1"); break; + case RTLIL::Sx: f << stringf("x"); break; + case RTLIL::Sz: f << stringf("z"); break; + case RTLIL::Sa: f << stringf("-"); break; + case RTLIL::Sm: f << stringf("m"); break; } } } else { - fprintf(f, "\""); + f << stringf("\""); std::string str = data.decode_string(); for (size_t i = 0; i < str.size(); i++) { if (str[i] == '\n') - fprintf(f, "\\n"); + f << stringf("\\n"); else if (str[i] == '\t') - fprintf(f, "\\t"); + f << stringf("\\t"); else if (str[i] < 32) - fprintf(f, "\\%03o", str[i]); + f << stringf("\\%03o", str[i]); else if (str[i] == '"') - fprintf(f, "\\\""); + f << stringf("\\\""); else if (str[i] == '\\') - fprintf(f, "\\\\"); + f << stringf("\\\\"); else - fputc(str[i], f); + f << str[i]; } - fprintf(f, "\""); + f << stringf("\""); } } -void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint) +void ILANG_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint) { if (chunk.wire == NULL) { dump_const(f, chunk.data, chunk.width, chunk.offset, autoint); } else { if (chunk.width == chunk.wire->width && chunk.offset == 0) - fprintf(f, "%s", chunk.wire->name.c_str()); + f << stringf("%s", chunk.wire->name.c_str()); else if (chunk.width == 1) - fprintf(f, "%s [%d]", chunk.wire->name.c_str(), chunk.offset); + f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset); else - fprintf(f, "%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset); + f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset); } } -void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint) +void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint) { if (sig.is_chunk()) { dump_sigchunk(f, sig.as_chunk(), autoint); } else { - fprintf(f, "{ "); + f << stringf("{ "); for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) { dump_sigchunk(f, *it, false); - fprintf(f, " "); + f << stringf(" "); } - fprintf(f, "}"); + f << stringf("}"); } } -void ILANG_BACKEND::dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wire) +void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire) { for (auto it = wire->attributes.begin(); it != wire->attributes.end(); it++) { - fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); + f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } - fprintf(f, "%s" "wire ", indent.c_str()); + f << stringf("%s" "wire ", indent.c_str()); if (wire->width != 1) - fprintf(f, "width %d ", wire->width); + f << stringf("width %d ", wire->width); if (wire->upto) - fprintf(f, "upto "); + f << stringf("upto "); if (wire->start_offset != 0) - fprintf(f, "offset %d ", wire->start_offset); + f << stringf("offset %d ", wire->start_offset); if (wire->port_input && !wire->port_output) - fprintf(f, "input %d ", wire->port_id); + f << stringf("input %d ", wire->port_id); if (!wire->port_input && wire->port_output) - fprintf(f, "output %d ", wire->port_id); + f << stringf("output %d ", wire->port_id); if (wire->port_input && wire->port_output) - fprintf(f, "inout %d ", wire->port_id); - fprintf(f, "%s\n", wire->name.c_str()); + f << stringf("inout %d ", wire->port_id); + f << stringf("%s\n", wire->name.c_str()); } -void ILANG_BACKEND::dump_memory(FILE *f, std::string indent, const RTLIL::Memory *memory) +void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory) { for (auto it = memory->attributes.begin(); it != memory->attributes.end(); it++) { - fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); + f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } - fprintf(f, "%s" "memory ", indent.c_str()); + f << stringf("%s" "memory ", indent.c_str()); if (memory->width != 1) - fprintf(f, "width %d ", memory->width); + f << stringf("width %d ", memory->width); if (memory->size != 0) - fprintf(f, "size %d ", memory->size); - fprintf(f, "%s\n", memory->name.c_str()); + f << stringf("size %d ", memory->size); + f << stringf("%s\n", memory->name.c_str()); } -void ILANG_BACKEND::dump_cell(FILE *f, std::string indent, const RTLIL::Cell *cell) +void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell) { for (auto it = cell->attributes.begin(); it != cell->attributes.end(); it++) { - fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); + f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } - fprintf(f, "%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str()); + f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str()); for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) { - fprintf(f, "%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str()); + f << stringf("%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str()); dump_const(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) { - fprintf(f, "%s connect %s ", indent.c_str(), it->first.c_str()); + f << stringf("%s connect %s ", indent.c_str(), it->first.c_str()); dump_sigspec(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } - fprintf(f, "%s" "end\n", indent.c_str()); + f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_proc_case_body(FILE *f, std::string indent, const RTLIL::CaseRule *cs) +void ILANG_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs) { for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, it->first); - fprintf(f, " "); + f << stringf(" "); dump_sigspec(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } for (auto it = cs->switches.begin(); it != cs->switches.end(); it++) dump_proc_switch(f, indent, *it); } -void ILANG_BACKEND::dump_proc_switch(FILE *f, std::string indent, const RTLIL::SwitchRule *sw) +void ILANG_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw) { for (auto it = sw->attributes.begin(); it != sw->attributes.end(); it++) { - fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); + f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } - fprintf(f, "%s" "switch ", indent.c_str()); + f << stringf("%s" "switch ", indent.c_str()); dump_sigspec(f, sw->signal); - fprintf(f, "\n"); + f << stringf("\n"); for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) { - fprintf(f, "%s case ", indent.c_str()); + f << stringf("%s case ", indent.c_str()); for (size_t i = 0; i < (*it)->compare.size(); i++) { if (i > 0) - fprintf(f, ", "); + f << stringf(", "); dump_sigspec(f, (*it)->compare[i]); } - fprintf(f, "\n"); + f << stringf("\n"); dump_proc_case_body(f, indent + " ", *it); } - fprintf(f, "%s" "end\n", indent.c_str()); + f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy) +void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy) { - fprintf(f, "%s" "sync ", indent.c_str()); + f << stringf("%s" "sync ", indent.c_str()); switch (sy->type) { - if (0) case RTLIL::ST0: fprintf(f, "low "); - if (0) case RTLIL::ST1: fprintf(f, "high "); - if (0) case RTLIL::STp: fprintf(f, "posedge "); - if (0) case RTLIL::STn: fprintf(f, "negedge "); - if (0) case RTLIL::STe: fprintf(f, "edge "); + if (0) case RTLIL::ST0: f << stringf("low "); + if (0) case RTLIL::ST1: f << stringf("high "); + if (0) case RTLIL::STp: f << stringf("posedge "); + if (0) case RTLIL::STn: f << stringf("negedge "); + if (0) case RTLIL::STe: f << stringf("edge "); dump_sigspec(f, sy->signal); - fprintf(f, "\n"); + f << stringf("\n"); break; - case RTLIL::STa: fprintf(f, "always\n"); break; - case RTLIL::STi: fprintf(f, "init\n"); break; + case RTLIL::STa: f << stringf("always\n"); break; + case RTLIL::STi: f << stringf("init\n"); break; } for (auto it = sy->actions.begin(); it != sy->actions.end(); it++) { - fprintf(f, "%s update ", indent.c_str()); + f << stringf("%s update ", indent.c_str()); dump_sigspec(f, it->first); - fprintf(f, " "); + f << stringf(" "); dump_sigspec(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } } -void ILANG_BACKEND::dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc) +void ILANG_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc) { for (auto it = proc->attributes.begin(); it != proc->attributes.end(); it++) { - fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); + f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } - fprintf(f, "%s" "process %s\n", indent.c_str(), proc->name.c_str()); + f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str()); dump_proc_case_body(f, indent + " ", &proc->root_case); for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++) dump_proc_sync(f, indent + " ", *it); - fprintf(f, "%s" "end\n", indent.c_str()); + f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) +void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - fprintf(f, "%s" "connect ", indent.c_str()); + f << stringf("%s" "connect ", indent.c_str()); dump_sigspec(f, left); - fprintf(f, " "); + f << stringf(" "); dump_sigspec(f, right); - fprintf(f, "\n"); + f << stringf("\n"); } -void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { bool print_header = flag_m || design->selected_whole_module(module->name); bool print_body = !flag_n || !design->selected_whole_module(module->name); @@ -271,12 +267,12 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module if (print_header) { for (auto it = module->attributes.begin(); it != module->attributes.end(); it++) { - fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); + f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); - fprintf(f, "\n"); + f << stringf("\n"); } - fprintf(f, "%s" "module %s\n", indent.c_str(), module->name.c_str()); + f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str()); } if (print_body) @@ -284,28 +280,28 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) if (!only_selected || design->selected(module, it->second)) { if (only_selected) - fprintf(f, "\n"); + f << stringf("\n"); dump_wire(f, indent + " ", it->second); } for (auto it = module->memories.begin(); it != module->memories.end(); it++) if (!only_selected || design->selected(module, it->second)) { if (only_selected) - fprintf(f, "\n"); + f << stringf("\n"); dump_memory(f, indent + " ", it->second); } for (auto it = module->cells_.begin(); it != module->cells_.end(); it++) if (!only_selected || design->selected(module, it->second)) { if (only_selected) - fprintf(f, "\n"); + f << stringf("\n"); dump_cell(f, indent + " ", it->second); } for (auto it = module->processes.begin(); it != module->processes.end(); it++) if (!only_selected || design->selected(module, it->second)) { if (only_selected) - fprintf(f, "\n"); + f << stringf("\n"); dump_proc(f, indent + " ", it->second); } @@ -323,7 +319,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module } if (show_conn) { if (only_selected && first_conn_line) - fprintf(f, "\n"); + f << stringf("\n"); dump_conn(f, indent + " ", it->first, it->second); first_conn_line = false; } @@ -331,10 +327,10 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module } if (print_header) - fprintf(f, "%s" "end\n", indent.c_str()); + f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void ILANG_BACKEND::dump_design(std::ostream &f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { int init_autoidx = autoidx; @@ -352,14 +348,14 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ if (!only_selected || flag_m) { if (only_selected) - fprintf(f, "\n"); - fprintf(f, "autoidx %d\n", autoidx); + f << stringf("\n"); + f << stringf("autoidx %d\n", autoidx); } for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { if (!only_selected || design->selected(it->second)) { if (only_selected) - fprintf(f, "\n"); + f << stringf("\n"); dump_module(f, "", it->second, design, only_selected, flag_m, flag_n); } } @@ -382,7 +378,7 @@ struct IlangBackend : public Backend { log(" only write selected parts of the design.\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { bool selected = false; @@ -400,8 +396,8 @@ struct IlangBackend : public Backend { extra_args(f, filename, args, argidx); log("Output filename: %s\n", filename.c_str()); - fprintf(f, "# Generated by %s\n", yosys_version_str); - ILANG_BACKEND::dump_design(f, design, selected, true, false); + *f << stringf("# Generated by %s\n", yosys_version_str); + ILANG_BACKEND::dump_design(*f, design, selected, true, false); } } IlangBackend; @@ -461,25 +457,27 @@ struct DumpPass : public Pass { } extra_args(args, argidx, design); - FILE *f = NULL; - char *buf_ptr; - size_t buf_size; + std::ostream *f; + std::stringstream buf; if (!filename.empty()) { - f = fopen(filename.c_str(), append ? "a" : "w"); - if (f == NULL) + std::ofstream *ff = new std::ofstream; + ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc); + if (ff->fail()) { + delete ff; log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + f = ff; } else { - f = open_memstream(&buf_ptr, &buf_size); + f = &buf; } - ILANG_BACKEND::dump_design(f, design, true, flag_m, flag_n); + ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n); - fclose(f); - - if (filename.empty()) { - log("%s", buf_ptr); - free(buf_ptr); + if (!filename.empty()) { + delete f; + } else { + log("%s", buf.str().c_str()); } } } DumpPass; diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h index b0fec488..138e10ef 100644 --- a/backends/ilang/ilang_backend.h +++ b/backends/ilang/ilang_backend.h @@ -31,19 +31,19 @@ YOSYS_NAMESPACE_BEGIN namespace ILANG_BACKEND { - void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); - void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint = true); - void dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint = true); - void dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wire); - void dump_memory(FILE *f, std::string indent, const RTLIL::Memory *memory); - void dump_cell(FILE *f, std::string indent, const RTLIL::Cell *cell); - void dump_proc_case_body(FILE *f, std::string indent, const RTLIL::CaseRule *cs); - void dump_proc_switch(FILE *f, std::string indent, const RTLIL::SwitchRule *sw); - void dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy); - void dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc); - void dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right); - void dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); - void dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); + void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); + void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint = true); + void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint = true); + void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); + void dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory); + void dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell); + void dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs); + void dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw); + void dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy); + void dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc); + void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right); + void dump_module(std::ostream &f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); + void dump_design(std::ostream &f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); } YOSYS_NAMESPACE_END diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 9faed77c..97ead3c6 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -69,7 +69,7 @@ struct IntersynthBackend : public Backend { log("http://www.clifford.at/intersynth/\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { log_header("Executing INTERSYNTH backend.\n"); log_push(); @@ -198,15 +198,15 @@ struct IntersynthBackend : public Backend { } if (!flag_notypes) { - fprintf(f, "### Connection Types\n"); + *f << stringf("### Connection Types\n"); for (auto code : conntypes_code) - fprintf(f, "%s", code.c_str()); - fprintf(f, "\n### Cell Types\n"); + *f << stringf("%s", code.c_str()); + *f << stringf("\n### Cell Types\n"); for (auto code : celltypes_code) - fprintf(f, "%s", code.c_str()); + *f << stringf("%s", code.c_str()); } - fprintf(f, "\n### Netlists\n"); - fprintf(f, "%s", netlists_code.c_str()); + *f << stringf("\n### Netlists\n"); + *f << stringf("%s", netlists_code.c_str()); for (auto lib : libs) delete lib; diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index be0086ff..b057063c 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -24,24 +24,24 @@ #include "kernel/log.h" #include -static void print_spice_net(FILE *f, RTLIL::SigBit s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) +static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) { if (s.wire) { if (s.wire->width > 1) - fprintf(f, " %s[%d]", RTLIL::id2cstr(s.wire->name), s.offset); + f << stringf(" %s[%d]", RTLIL::id2cstr(s.wire->name), s.offset); else - fprintf(f, " %s", RTLIL::id2cstr(s.wire->name)); + f << stringf(" %s", RTLIL::id2cstr(s.wire->name)); } else { if (s == RTLIL::State::S0) - fprintf(f, " %s", neg.c_str()); + f << stringf(" %s", neg.c_str()); else if (s == RTLIL::State::S1) - fprintf(f, " %s", pos.c_str()); + f << stringf(" %s", pos.c_str()); else - fprintf(f, " %s%d", ncpf.c_str(), nc_counter++); + f << stringf(" %s%d", ncpf.c_str(), nc_counter++); } } -static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian) +static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian) { SigMap sigmap(module); int cell_counter = 0, conn_counter = 0, nc_counter = 0; @@ -49,7 +49,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de for (auto &cell_it : module->cells_) { RTLIL::Cell *cell = cell_it.second; - fprintf(f, "X%d", cell_counter++); + f << stringf("X%d", cell_counter++); std::vector port_sigs; @@ -94,15 +94,15 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de } } - fprintf(f, " %s\n", RTLIL::id2cstr(cell->type)); + f << stringf(" %s\n", RTLIL::id2cstr(cell->type)); } for (auto &conn : module->connections()) for (int i = 0; i < conn.first.size(); i++) { - fprintf(f, "V%d", conn_counter++); + f << stringf("V%d", conn_counter++); print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter); print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter); - fprintf(f, " DC 0\n"); + f << stringf(" DC 0\n"); } } @@ -133,7 +133,7 @@ struct SpiceBackend : public Backend { log(" set the specified module as design top module\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { std::string top_module_name; RTLIL::Module *top_module = NULL; @@ -174,8 +174,8 @@ struct SpiceBackend : public Backend { if (mod_it.second->get_bool_attribute("\\top")) top_module_name = mod_it.first.str(); - fprintf(f, "* SPICE netlist generated by %s\n", yosys_version_str); - fprintf(f, "\n"); + *f << stringf("* SPICE netlist generated by %s\n", yosys_version_str); + *f << stringf("\n"); for (auto module_it : design->modules_) { @@ -203,31 +203,31 @@ struct SpiceBackend : public Backend { ports.at(wire->port_id-1) = wire; } - fprintf(f, ".SUBCKT %s", RTLIL::id2cstr(module->name)); + *f << stringf(".SUBCKT %s", RTLIL::id2cstr(module->name)); for (RTLIL::Wire *wire : ports) { log_assert(wire != NULL); if (wire->width > 1) { for (int i = 0; i < wire->width; i++) - fprintf(f, " %s[%d]", RTLIL::id2cstr(wire->name), big_endian ? wire->width - 1 - i : i); + *f << stringf(" %s[%d]", RTLIL::id2cstr(wire->name), big_endian ? wire->width - 1 - i : i); } else - fprintf(f, " %s", RTLIL::id2cstr(wire->name)); + *f << stringf(" %s", RTLIL::id2cstr(wire->name)); } - fprintf(f, "\n"); - print_spice_module(f, module, design, neg, pos, ncpf, big_endian); - fprintf(f, ".ENDS %s\n\n", RTLIL::id2cstr(module->name)); + *f << stringf("\n"); + print_spice_module(*f, module, design, neg, pos, ncpf, big_endian); + *f << stringf(".ENDS %s\n\n", RTLIL::id2cstr(module->name)); } if (!top_module_name.empty()) { if (top_module == NULL) log_error("Can't find top module `%s'!\n", top_module_name.c_str()); - print_spice_module(f, top_module, design, neg, pos, ncpf, big_endian); - fprintf(f, "\n"); + print_spice_module(*f, top_module, design, neg, pos, ncpf, big_endian); + *f << stringf("\n"); } - fprintf(f, "************************\n"); - fprintf(f, "* end of SPICE netlist *\n"); - fprintf(f, "************************\n"); - fprintf(f, "\n"); + *f << stringf("************************\n"); + *f << stringf("* end of SPICE netlist *\n"); + *f << stringf("************************\n"); + *f << stringf("\n"); } } SpiceBackend; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index f6095a5a..d1fa55b9 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -150,7 +150,7 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name) return true; } -void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false) +void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false) { if (width < 0) width = data.bits.size() - offset; @@ -166,112 +166,112 @@ void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = if (data.bits[i] == RTLIL::S1) val |= 1 << (i - offset); } - fprintf(f, "32'%sd%d", set_signed ? "s" : "", val); + f << stringf("32'%sd%d", set_signed ? "s" : "", val); } else { dump_bits: - fprintf(f, "%d'%sb", width, set_signed ? "s" : ""); + f << stringf("%d'%sb", width, set_signed ? "s" : ""); if (width == 0) - fprintf(f, "0"); + f << stringf("0"); for (int i = offset+width-1; i >= offset; i--) { log_assert(i < (int)data.bits.size()); switch (data.bits[i]) { - case RTLIL::S0: fprintf(f, "0"); break; - case RTLIL::S1: fprintf(f, "1"); break; - case RTLIL::Sx: fprintf(f, "x"); break; - case RTLIL::Sz: fprintf(f, "z"); break; - case RTLIL::Sa: fprintf(f, "z"); break; + case RTLIL::S0: f << stringf("0"); break; + case RTLIL::S1: f << stringf("1"); break; + case RTLIL::Sx: f << stringf("x"); break; + case RTLIL::Sz: f << stringf("z"); break; + case RTLIL::Sa: f << stringf("z"); break; case RTLIL::Sm: log_error("Found marker state in final netlist."); } } } } else { - fprintf(f, "\""); + f << stringf("\""); std::string str = data.decode_string(); for (size_t i = 0; i < str.size(); i++) { if (str[i] == '\n') - fprintf(f, "\\n"); + f << stringf("\\n"); else if (str[i] == '\t') - fprintf(f, "\\t"); + f << stringf("\\t"); else if (str[i] < 32) - fprintf(f, "\\%03o", str[i]); + f << stringf("\\%03o", str[i]); else if (str[i] == '"') - fprintf(f, "\\\""); + f << stringf("\\\""); else if (str[i] == '\\') - fprintf(f, "\\\\"); + f << stringf("\\\\"); else - fputc(str[i], f); + f << str[i]; } - fprintf(f, "\""); + f << stringf("\""); } } -void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool no_decimal = false) +void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool no_decimal = false) { if (chunk.wire == NULL) { dump_const(f, chunk.data, chunk.width, chunk.offset, no_decimal); } else { if (chunk.width == chunk.wire->width && chunk.offset == 0) { - fprintf(f, "%s", id(chunk.wire->name).c_str()); + f << stringf("%s", id(chunk.wire->name).c_str()); } else if (chunk.width == 1) { if (chunk.wire->upto) - fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset); + f << stringf("%s[%d]", id(chunk.wire->name).c_str(), (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset); else - fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset); + f << stringf("%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset); } else { if (chunk.wire->upto) - fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(), + f << stringf("%s[%d:%d]", id(chunk.wire->name).c_str(), (chunk.wire->width - (chunk.offset + chunk.width - 1) - 1) + chunk.wire->start_offset, (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset); else - fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(), + f << stringf("%s[%d:%d]", id(chunk.wire->name).c_str(), (chunk.offset + chunk.width - 1) + chunk.wire->start_offset, chunk.offset + chunk.wire->start_offset); } } } -void dump_sigspec(FILE *f, const RTLIL::SigSpec &sig) +void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig) { if (sig.is_chunk()) { dump_sigchunk(f, sig.as_chunk()); } else { - fprintf(f, "{ "); + f << stringf("{ "); for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) { if (it != sig.chunks().rbegin()) - fprintf(f, ", "); + f << stringf(", "); dump_sigchunk(f, *it, true); } - fprintf(f, " }"); + f << stringf(" }"); } } -void dump_attributes(FILE *f, std::string indent, std::map &attributes, char term = '\n') +void dump_attributes(std::ostream &f, std::string indent, std::map &attributes, char term = '\n') { if (noattr) return; for (auto it = attributes.begin(); it != attributes.end(); it++) { - fprintf(f, "%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str()); - fprintf(f, " = "); + f << stringf("%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str()); + f << stringf(" = "); dump_const(f, it->second); - fprintf(f, " %s%c", attr2comment ? "*/" : "*)", term); + f << stringf(" %s%c", attr2comment ? "*/" : "*)", term); } } -void dump_wire(FILE *f, std::string indent, RTLIL::Wire *wire) +void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire) { dump_attributes(f, indent, wire->attributes); #if 0 if (wire->port_input && !wire->port_output) - fprintf(f, "%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); + f << stringf("%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); else if (!wire->port_input && wire->port_output) - fprintf(f, "%s" "output %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); + f << stringf("%s" "output %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); else if (wire->port_input && wire->port_output) - fprintf(f, "%s" "inout %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); + f << stringf("%s" "inout %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); else - fprintf(f, "%s" "%s ", indent.c_str(), reg_wires.count(wire->name) ? "reg" : "wire"); + f << stringf("%s" "%s ", indent.c_str(), reg_wires.count(wire->name) ? "reg" : "wire"); if (wire->width != 1) - fprintf(f, "[%d:%d] ", wire->width - 1 + wire->start_offset, wire->start_offset); - fprintf(f, "%s;\n", id(wire->name).c_str()); + f << stringf("[%d:%d] ", wire->width - 1 + wire->start_offset, wire->start_offset); + f << stringf("%s;\n", id(wire->name).c_str()); #else // do not use Verilog-2k "outut reg" syntax in verilog export std::string range = ""; @@ -282,30 +282,30 @@ void dump_wire(FILE *f, std::string indent, RTLIL::Wire *wire) range = stringf(" [%d:%d]", wire->width - 1 + wire->start_offset, wire->start_offset); } if (wire->port_input && !wire->port_output) - fprintf(f, "%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); + f << stringf("%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); if (!wire->port_input && wire->port_output) - fprintf(f, "%s" "output%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); + f << stringf("%s" "output%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); if (wire->port_input && wire->port_output) - fprintf(f, "%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); + f << stringf("%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); if (reg_wires.count(wire->name)) - fprintf(f, "%s" "reg%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); + f << stringf("%s" "reg%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); else if (!wire->port_input && !wire->port_output) - fprintf(f, "%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); + f << stringf("%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); #endif } -void dump_memory(FILE *f, std::string indent, RTLIL::Memory *memory) +void dump_memory(std::ostream &f, std::string indent, RTLIL::Memory *memory) { dump_attributes(f, indent, memory->attributes); - fprintf(f, "%s" "reg [%d:0] %s [%d:0];\n", indent.c_str(), memory->width-1, id(memory->name).c_str(), memory->size-1); + f << stringf("%s" "reg [%d:0] %s [%d:0];\n", indent.c_str(), memory->width-1, id(memory->name).c_str(), memory->size-1); } -void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_signed = true) +void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, bool gen_signed = true) { if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) { - fprintf(f, "$signed("); + f << stringf("$signed("); dump_sigspec(f, cell->getPort("\\" + port)); - fprintf(f, ")"); + f << stringf(")"); } else dump_sigspec(f, cell->getPort("\\" + port)); } @@ -346,107 +346,107 @@ no_special_reg_name: } } -void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) +void dump_cell_expr_uniop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = %s ", op.c_str()); + f << stringf(" = %s ", op.c_str()); dump_attributes(f, "", cell->attributes, ' '); dump_cell_expr_port(f, cell, "A", true); - fprintf(f, ";\n"); + f << stringf(";\n"); } -void dump_cell_expr_binop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) +void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = "); + f << stringf(" = "); dump_cell_expr_port(f, cell, "A", true); - fprintf(f, " %s ", op.c_str()); + f << stringf(" %s ", op.c_str()); dump_attributes(f, "", cell->attributes, ' '); dump_cell_expr_port(f, cell, "B", true); - fprintf(f, ";\n"); + f << stringf(";\n"); } -bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) +bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) { if (cell->type == "$_NOT_") { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = "); - fprintf(f, "~"); + f << stringf(" = "); + f << stringf("~"); dump_attributes(f, "", cell->attributes, ' '); dump_cell_expr_port(f, cell, "A", false); - fprintf(f, ";\n"); + f << stringf(";\n"); return true; } if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_")) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = "); + f << stringf(" = "); if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_")) - fprintf(f, "~("); + f << stringf("~("); dump_cell_expr_port(f, cell, "A", false); - fprintf(f, " "); + f << stringf(" "); if (cell->type.in("$_AND_", "$_NAND_")) - fprintf(f, "&"); + f << stringf("&"); if (cell->type.in("$_OR_", "$_NOR_")) - fprintf(f, "|"); + f << stringf("|"); if (cell->type.in("$_XOR_", "$_XNOR_")) - fprintf(f, "^"); + f << stringf("^"); dump_attributes(f, "", cell->attributes, ' '); - fprintf(f, " "); + f << stringf(" "); dump_cell_expr_port(f, cell, "B", false); if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_")) - fprintf(f, ")"); - fprintf(f, ";\n"); + f << stringf(")"); + f << stringf(";\n"); return true; } if (cell->type == "$_MUX_") { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = "); + f << stringf(" = "); dump_cell_expr_port(f, cell, "S", false); - fprintf(f, " ? "); + f << stringf(" ? "); dump_attributes(f, "", cell->attributes, ' '); dump_cell_expr_port(f, cell, "B", false); - fprintf(f, " : "); + f << stringf(" : "); dump_cell_expr_port(f, cell, "A", false); - fprintf(f, ";\n"); + f << stringf(";\n"); return true; } if (cell->type.in("$_AOI3_", "$_OAI3_")) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = ~(("); + f << stringf(" = ~(("); dump_cell_expr_port(f, cell, "A", false); - fprintf(f, cell->type == "$_AOI3_" ? " & " : " | "); + f << stringf(cell->type == "$_AOI3_" ? " & " : " | "); dump_cell_expr_port(f, cell, "B", false); - fprintf(f, cell->type == "$_AOI3_" ? ") |" : ") &"); + f << stringf(cell->type == "$_AOI3_" ? ") |" : ") &"); dump_attributes(f, "", cell->attributes, ' '); - fprintf(f, " "); + f << stringf(" "); dump_cell_expr_port(f, cell, "C", false); - fprintf(f, ");\n"); + f << stringf(");\n"); return true; } if (cell->type.in("$_AOI4_", "$_OAI4_")) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = ~(("); + f << stringf(" = ~(("); dump_cell_expr_port(f, cell, "A", false); - fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); + f << stringf(cell->type == "$_AOI4_" ? " & " : " | "); dump_cell_expr_port(f, cell, "B", false); - fprintf(f, cell->type == "$_AOI4_" ? ") |" : ") &"); + f << stringf(cell->type == "$_AOI4_" ? ") |" : ") &"); dump_attributes(f, "", cell->attributes, ' '); - fprintf(f, " ("); + f << stringf(" ("); dump_cell_expr_port(f, cell, "C", false); - fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); + f << stringf(cell->type == "$_AOI4_" ? " & " : " | "); dump_cell_expr_port(f, cell, "D", false); - fprintf(f, "));\n"); + f << stringf("));\n"); return true; } @@ -456,33 +456,33 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); if (!out_is_reg_wire) - fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); + f << stringf("%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); - fprintf(f, "%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg"); + f << stringf("%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg"); dump_sigspec(f, cell->getPort("\\C")); if (cell->type[7] != '_') { - fprintf(f, " or %sedge ", cell->type[7] == 'P' ? "pos" : "neg"); + f << stringf(" or %sedge ", cell->type[7] == 'P' ? "pos" : "neg"); dump_sigspec(f, cell->getPort("\\R")); } - fprintf(f, ")\n"); + f << stringf(")\n"); if (cell->type[7] != '_') { - fprintf(f, "%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!"); + f << stringf("%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!"); dump_sigspec(f, cell->getPort("\\R")); - fprintf(f, ")\n"); - fprintf(f, "%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); - fprintf(f, "%s" " else\n", indent.c_str()); + f << stringf(")\n"); + f << stringf("%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); + f << stringf("%s" " else\n", indent.c_str()); } - fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str()); + f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); dump_cell_expr_port(f, cell, "D", false); - fprintf(f, ";\n"); + f << stringf(";\n"); if (!out_is_reg_wire) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Q")); - fprintf(f, " = %s;\n", reg_name.c_str()); + f << stringf(" = %s;\n", reg_name.c_str()); } return true; @@ -496,36 +496,36 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); if (!out_is_reg_wire) - fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); + f << stringf("%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); dump_attributes(f, indent, cell->attributes); - fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg"); + f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg"); dump_sigspec(f, cell->getPort("\\C")); - fprintf(f, " or %sedge ", pol_s == 'P' ? "pos" : "neg"); + f << stringf(" or %sedge ", pol_s == 'P' ? "pos" : "neg"); dump_sigspec(f, cell->getPort("\\S")); - fprintf(f, " or %sedge ", pol_r == 'P' ? "pos" : "neg"); + f << stringf(" or %sedge ", pol_r == 'P' ? "pos" : "neg"); dump_sigspec(f, cell->getPort("\\R")); - fprintf(f, ")\n"); + f << stringf(")\n"); - fprintf(f, "%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!"); + f << stringf("%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!"); dump_sigspec(f, cell->getPort("\\R")); - fprintf(f, ")\n"); - fprintf(f, "%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str()); + f << stringf(")\n"); + f << stringf("%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str()); - fprintf(f, "%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!"); + f << stringf("%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!"); dump_sigspec(f, cell->getPort("\\S")); - fprintf(f, ")\n"); - fprintf(f, "%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str()); + f << stringf(")\n"); + f << stringf("%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str()); - fprintf(f, "%s" " else\n", indent.c_str()); - fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str()); + f << stringf("%s" " else\n", indent.c_str()); + f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); dump_cell_expr_port(f, cell, "D", false); - fprintf(f, ";\n"); + f << stringf(";\n"); if (!out_is_reg_wire) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Q")); - fprintf(f, " = %s;\n", reg_name.c_str()); + f << stringf(" = %s;\n", reg_name.c_str()); } return true; @@ -581,16 +581,16 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) if (cell->type == "$mux") { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = "); + f << stringf(" = "); dump_sigspec(f, cell->getPort("\\S")); - fprintf(f, " ? "); + f << stringf(" ? "); dump_attributes(f, "", cell->attributes, ' '); dump_sigspec(f, cell->getPort("\\B")); - fprintf(f, " : "); + f << stringf(" : "); dump_sigspec(f, cell->getPort("\\A")); - fprintf(f, ";\n"); + f << stringf(";\n"); return true; } @@ -600,82 +600,82 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) int s_width = cell->getPort("\\S").size(); std::string func_name = cellname(cell); - fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); - fprintf(f, "%s" " input [%d:0] a;\n", indent.c_str(), width-1); - fprintf(f, "%s" " input [%d:0] b;\n", indent.c_str(), s_width*width-1); - fprintf(f, "%s" " input [%d:0] s;\n", indent.c_str(), s_width-1); + f << stringf("%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); + f << stringf("%s" " input [%d:0] a;\n", indent.c_str(), width-1); + f << stringf("%s" " input [%d:0] b;\n", indent.c_str(), s_width*width-1); + f << stringf("%s" " input [%d:0] s;\n", indent.c_str(), s_width-1); dump_attributes(f, indent + " ", cell->attributes); if (cell->type != "$pmux_safe" && !noattr) - fprintf(f, "%s" " (* parallel_case *)\n", indent.c_str()); - fprintf(f, "%s" " casez (s)", indent.c_str()); + f << stringf("%s" " (* parallel_case *)\n", indent.c_str()); + f << stringf("%s" " casez (s)", indent.c_str()); if (cell->type != "$pmux_safe") - fprintf(f, noattr ? " // synopsys parallel_case\n" : "\n"); + f << stringf(noattr ? " // synopsys parallel_case\n" : "\n"); for (int i = 0; i < s_width; i++) { - fprintf(f, "%s" " %d'b", indent.c_str(), s_width); + f << stringf("%s" " %d'b", indent.c_str(), s_width); for (int j = s_width-1; j >= 0; j--) - fprintf(f, "%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?'); + f << stringf("%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?'); - fprintf(f, ":\n"); - fprintf(f, "%s" " %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width); + f << stringf(":\n"); + f << stringf("%s" " %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width); } - fprintf(f, "%s" " default:\n", indent.c_str()); - fprintf(f, "%s" " %s = a;\n", indent.c_str(), func_name.c_str()); + f << stringf("%s" " default:\n", indent.c_str()); + f << stringf("%s" " %s = a;\n", indent.c_str(), func_name.c_str()); - fprintf(f, "%s" " endcase\n", indent.c_str()); - fprintf(f, "%s" "endfunction\n", indent.c_str()); + f << stringf("%s" " endcase\n", indent.c_str()); + f << stringf("%s" "endfunction\n", indent.c_str()); - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = %s(", func_name.c_str()); + f << stringf(" = %s(", func_name.c_str()); dump_sigspec(f, cell->getPort("\\A")); - fprintf(f, ", "); + f << stringf(", "); dump_sigspec(f, cell->getPort("\\B")); - fprintf(f, ", "); + f << stringf(", "); dump_sigspec(f, cell->getPort("\\S")); - fprintf(f, ");\n"); + f << stringf(");\n"); return true; } if (cell->type == "$slice") { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = "); + f << stringf(" = "); dump_sigspec(f, cell->getPort("\\A")); - fprintf(f, " >> %d;\n", cell->parameters.at("\\OFFSET").as_int()); + f << stringf(" >> %d;\n", cell->parameters.at("\\OFFSET").as_int()); return true; } if (cell->type == "$bu0") { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); if (cell->parameters["\\A_SIGNED"].as_bool()) { - fprintf(f, " = $signed("); + f << stringf(" = $signed("); dump_sigspec(f, cell->getPort("\\A")); - fprintf(f, ");\n"); + f << stringf(");\n"); } else { - fprintf(f, " = { 1'b0, "); + f << stringf(" = { 1'b0, "); dump_sigspec(f, cell->getPort("\\A")); - fprintf(f, " };\n"); + f << stringf(" };\n"); } return true; } if (cell->type == "$concat") { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Y")); - fprintf(f, " = { "); + f << stringf(" = { "); dump_sigspec(f, cell->getPort("\\B")); - fprintf(f, " , "); + f << stringf(" , "); dump_sigspec(f, cell->getPort("\\A")); - fprintf(f, " };\n"); + f << stringf(" };\n"); return true; } @@ -697,34 +697,34 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name); if (!out_is_reg_wire) - fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str()); + f << stringf("%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str()); - fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg"); + f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg"); dump_sigspec(f, sig_clk); if (cell->type == "$adff") { - fprintf(f, " or %sedge ", pol_arst ? "pos" : "neg"); + f << stringf(" or %sedge ", pol_arst ? "pos" : "neg"); dump_sigspec(f, sig_arst); } - fprintf(f, ")\n"); + f << stringf(")\n"); if (cell->type == "$adff") { - fprintf(f, "%s" " if (%s", indent.c_str(), pol_arst ? "" : "!"); + f << stringf("%s" " if (%s", indent.c_str(), pol_arst ? "" : "!"); dump_sigspec(f, sig_arst); - fprintf(f, ")\n"); - fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str()); + f << stringf(")\n"); + f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); dump_sigspec(f, val_arst); - fprintf(f, ";\n"); - fprintf(f, "%s" " else\n", indent.c_str()); + f << stringf(";\n"); + f << stringf("%s" " else\n", indent.c_str()); } - fprintf(f, "%s" " %s <= ", indent.c_str(), reg_name.c_str()); + f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str()); dump_cell_expr_port(f, cell, "D", false); - fprintf(f, ";\n"); + f << stringf(";\n"); if (!out_is_reg_wire) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, cell->getPort("\\Q")); - fprintf(f, " = %s;\n", reg_name.c_str()); + f << stringf(" = %s;\n", reg_name.c_str()); } return true; @@ -736,7 +736,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) return false; } -void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) +void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) { if (cell->type[0] == '$' && !noexpr) { if (dump_cell_expr(f, indent, cell)) @@ -744,26 +744,26 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) } dump_attributes(f, indent, cell->attributes); - fprintf(f, "%s" "%s", indent.c_str(), id(cell->type, false).c_str()); + f << stringf("%s" "%s", indent.c_str(), id(cell->type, false).c_str()); if (cell->parameters.size() > 0) { - fprintf(f, " #("); + f << stringf(" #("); for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) { if (it != cell->parameters.begin()) - fprintf(f, ","); - fprintf(f, "\n%s .%s(", indent.c_str(), id(it->first).c_str()); + f << stringf(","); + f << stringf("\n%s .%s(", indent.c_str(), id(it->first).c_str()); bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0; dump_const(f, it->second, -1, 0, !is_signed, is_signed); - fprintf(f, ")"); + f << stringf(")"); } - fprintf(f, "\n%s" ")", indent.c_str()); + f << stringf("\n%s" ")", indent.c_str()); } std::string cell_name = cellname(cell); if (cell_name != id(cell->name)) - fprintf(f, " %s /* %s */ (", cell_name.c_str(), id(cell->name).c_str()); + f << stringf(" %s /* %s */ (", cell_name.c_str(), id(cell->name).c_str()); else - fprintf(f, " %s (", cell_name.c_str()); + f << stringf(" %s (", cell_name.c_str()); bool first_arg = true; std::set numbered_ports; @@ -774,9 +774,9 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) if (it->first != str) continue; if (!first_arg) - fprintf(f, ","); + f << stringf(","); first_arg = false; - fprintf(f, "\n%s ", indent.c_str()); + f << stringf("\n%s ", indent.c_str()); dump_sigspec(f, it->second); numbered_ports.insert(it->first); goto found_numbered_port; @@ -788,86 +788,86 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) if (numbered_ports.count(it->first)) continue; if (!first_arg) - fprintf(f, ","); + f << stringf(","); first_arg = false; - fprintf(f, "\n%s .%s(", indent.c_str(), id(it->first).c_str()); + f << stringf("\n%s .%s(", indent.c_str(), id(it->first).c_str()); if (it->second.size() > 0) dump_sigspec(f, it->second); - fprintf(f, ")"); + f << stringf(")"); } - fprintf(f, "\n%s" ");\n", indent.c_str()); + f << stringf("\n%s" ");\n", indent.c_str()); } -void dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) +void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - fprintf(f, "%s" "assign ", indent.c_str()); + f << stringf("%s" "assign ", indent.c_str()); dump_sigspec(f, left); - fprintf(f, " = "); + f << stringf(" = "); dump_sigspec(f, right); - fprintf(f, ";\n"); + f << stringf(";\n"); } -void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw); +void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw); -void dump_case_body(FILE *f, std::string indent, RTLIL::CaseRule *cs, bool omit_trailing_begin = false) +void dump_case_body(std::ostream &f, std::string indent, RTLIL::CaseRule *cs, bool omit_trailing_begin = false) { int number_of_stmts = cs->switches.size() + cs->actions.size(); if (!omit_trailing_begin && number_of_stmts >= 2) - fprintf(f, "%s" "begin\n", indent.c_str()); + f << stringf("%s" "begin\n", indent.c_str()); for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) { if (it->first.size() == 0) continue; - fprintf(f, "%s ", indent.c_str()); + f << stringf("%s ", indent.c_str()); dump_sigspec(f, it->first); - fprintf(f, " = "); + f << stringf(" = "); dump_sigspec(f, it->second); - fprintf(f, ";\n"); + f << stringf(";\n"); } for (auto it = cs->switches.begin(); it != cs->switches.end(); it++) dump_proc_switch(f, indent + " ", *it); if (!omit_trailing_begin && number_of_stmts == 0) - fprintf(f, "%s /* empty */;\n", indent.c_str()); + f << stringf("%s /* empty */;\n", indent.c_str()); if (omit_trailing_begin || number_of_stmts >= 2) - fprintf(f, "%s" "end\n", indent.c_str()); + f << stringf("%s" "end\n", indent.c_str()); } -void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw) +void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw) { if (sw->signal.size() == 0) { - fprintf(f, "%s" "begin\n", indent.c_str()); + f << stringf("%s" "begin\n", indent.c_str()); for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) { if ((*it)->compare.size() == 0) dump_case_body(f, indent + " ", *it); } - fprintf(f, "%s" "end\n", indent.c_str()); + f << stringf("%s" "end\n", indent.c_str()); return; } - fprintf(f, "%s" "casez (", indent.c_str()); + f << stringf("%s" "casez (", indent.c_str()); dump_sigspec(f, sw->signal); - fprintf(f, ")\n"); + f << stringf(")\n"); for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) { - fprintf(f, "%s ", indent.c_str()); + f << stringf("%s ", indent.c_str()); if ((*it)->compare.size() == 0) - fprintf(f, "default"); + f << stringf("default"); else { for (size_t i = 0; i < (*it)->compare.size(); i++) { if (i > 0) - fprintf(f, ", "); + f << stringf(", "); dump_sigspec(f, (*it)->compare[i]); } } - fprintf(f, ":\n"); + f << stringf(":\n"); dump_case_body(f, indent + " ", *it); } - fprintf(f, "%s" "endcase\n", indent.c_str()); + f << stringf("%s" "endcase\n", indent.c_str()); } void case_body_find_regs(RTLIL::CaseRule *cs) @@ -883,7 +883,7 @@ void case_body_find_regs(RTLIL::CaseRule *cs) } } -void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_regs = false) +void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, bool find_regs = false) { if (find_regs) { case_body_find_regs(&proc->root_case); @@ -896,7 +896,7 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r return; } - fprintf(f, "%s" "always @* begin\n", indent.c_str()); + f << stringf("%s" "always @* begin\n", indent.c_str()); dump_case_body(f, indent, &proc->root_case, true); std::string backup_indent = indent; @@ -907,23 +907,23 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r indent = backup_indent; if (sync->type == RTLIL::STa) { - fprintf(f, "%s" "always @* begin\n", indent.c_str()); + f << stringf("%s" "always @* begin\n", indent.c_str()); } else { - fprintf(f, "%s" "always @(", indent.c_str()); + f << stringf("%s" "always @(", indent.c_str()); if (sync->type == RTLIL::STp || sync->type == RTLIL::ST1) - fprintf(f, "posedge "); + f << stringf("posedge "); if (sync->type == RTLIL::STn || sync->type == RTLIL::ST0) - fprintf(f, "negedge "); + f << stringf("negedge "); dump_sigspec(f, sync->signal); - fprintf(f, ") begin\n"); + f << stringf(") begin\n"); } std::string ends = indent + "end\n"; indent += " "; if (sync->type == RTLIL::ST0 || sync->type == RTLIL::ST1) { - fprintf(f, "%s" "if (%s", indent.c_str(), sync->type == RTLIL::ST0 ? "!" : ""); + f << stringf("%s" "if (%s", indent.c_str(), sync->type == RTLIL::ST0 ? "!" : ""); dump_sigspec(f, sync->signal); - fprintf(f, ") begin\n"); + f << stringf(") begin\n"); ends = indent + "end\n" + ends; indent += " "; } @@ -932,9 +932,9 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r for (size_t j = 0; j < proc->syncs.size(); j++) { RTLIL::SyncRule *sync2 = proc->syncs[j]; if (sync2->type == RTLIL::ST0 || sync2->type == RTLIL::ST1) { - fprintf(f, "%s" "if (%s", indent.c_str(), sync2->type == RTLIL::ST1 ? "!" : ""); + f << stringf("%s" "if (%s", indent.c_str(), sync2->type == RTLIL::ST1 ? "!" : ""); dump_sigspec(f, sync2->signal); - fprintf(f, ") begin\n"); + f << stringf(") begin\n"); ends = indent + "end\n" + ends; indent += " "; } @@ -944,24 +944,24 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r for (auto it = sync->actions.begin(); it != sync->actions.end(); it++) { if (it->first.size() == 0) continue; - fprintf(f, "%s ", indent.c_str()); + f << stringf("%s ", indent.c_str()); dump_sigspec(f, it->first); - fprintf(f, " <= "); + f << stringf(" <= "); dump_sigspec(f, it->second); - fprintf(f, ";\n"); + f << stringf(";\n"); } - fprintf(f, "%s", ends.c_str()); + f << stringf("%s", ends.c_str()); } } -void dump_module(FILE *f, std::string indent, RTLIL::Module *module) +void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) { reg_wires.clear(); reset_auto_counter(module); active_module = module; - fprintf(f, "\n"); + f << stringf("\n"); for (auto it = module->processes.begin(); it != module->processes.end(); it++) dump_process(f, indent + " ", it->second, true); @@ -995,7 +995,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) } dump_attributes(f, indent, module->attributes); - fprintf(f, "%s" "module %s(", indent.c_str(), id(module->name, false).c_str()); + f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str()); bool keep_running = true; for (int port_id = 1; keep_running; port_id++) { keep_running = false; @@ -1003,14 +1003,14 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) RTLIL::Wire *wire = it->second; if (wire->port_id == port_id) { if (port_id != 1) - fprintf(f, ", "); - fprintf(f, "%s", id(wire->name).c_str()); + f << stringf(", "); + f << stringf("%s", id(wire->name).c_str()); keep_running = true; continue; } } } - fprintf(f, ");\n"); + f << stringf(");\n"); for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) dump_wire(f, indent + " ", it->second); @@ -1027,7 +1027,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module) for (auto it = module->connections().begin(); it != module->connections().end(); it++) dump_conn(f, indent + " ", it->first, it->second); - fprintf(f, "%s" "endmodule\n", indent.c_str()); + f << stringf("%s" "endmodule\n", indent.c_str()); active_module = NULL; } @@ -1068,7 +1068,7 @@ struct VerilogBackend : public Backend { log(" not at all.\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { log_header("Executing Verilog backend.\n"); @@ -1137,7 +1137,7 @@ struct VerilogBackend : public Backend { } extra_args(f, filename, args, argidx); - fprintf(f, "/* Generated by %s */\n", yosys_version_str); + *f << stringf("/* Generated by %s */\n", yosys_version_str); for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { if (it->second->get_bool_attribute("\\blackbox") != blackboxes) continue; @@ -1147,7 +1147,7 @@ struct VerilogBackend : public Backend { continue; } log("Dumping module `%s'.\n", it->first.c_str()); - dump_module(f, "", it->second); + dump_module(*f, "", it->second); } reg_ct.clear(); diff --git a/backends/verilog/verilog_backend.h b/backends/verilog/verilog_backend.h index c40830ef..7e6ef5ab 100644 --- a/backends/verilog/verilog_backend.h +++ b/backends/verilog/verilog_backend.h @@ -29,11 +29,10 @@ #ifndef VERILOG_BACKEND_H #define VERILOG_BACKEND_H -#include "kernel/rtlil.h" -#include +#include "kernel/yosys.h" namespace VERILOG_BACKEND { - void verilog_backend(FILE *f, std::vector args, RTLIL::Design *design); + void verilog_backend(std::ostream &f, std::vector args, RTLIL::Design *design); } #endif diff --git a/kernel/log.cc b/kernel/log.cc index b742a549..2b4b5db5 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -210,20 +210,14 @@ void log_dump_val_worker(RTLIL::SigSpec v) { const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) { - char *ptr; - size_t size; - - FILE *f = open_memstream(&ptr, &size); - ILANG_BACKEND::dump_sigspec(f, sig, autoint); - fputc(0, f); - fclose(f); + std::stringstream buf; + ILANG_BACKEND::dump_sigspec(buf, sig, autoint); if (string_buf_size < 100) string_buf_size++; else string_buf.pop_front(); - string_buf.push_back(ptr); - free(ptr); + string_buf.push_back(buf.str()); return string_buf.back().c_str(); } @@ -239,16 +233,9 @@ const char *log_id(RTLIL::IdString str) void log_cell(RTLIL::Cell *cell, std::string indent) { - char *ptr; - size_t size; - - FILE *f = open_memstream(&ptr, &size); - ILANG_BACKEND::dump_cell(f, indent, cell); - fputc(0, f); - fclose(f); - - log("%s", ptr); - free(ptr); + std::stringstream buf; + ILANG_BACKEND::dump_cell(buf, indent, cell); + log("%s", buf.str().c_str()); } // --------------------------------------------------- diff --git a/kernel/register.cc b/kernel/register.cc index a9e21e6d..95ed0cbd 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -423,15 +423,15 @@ Backend::~Backend() void Backend::execute(std::vector args, RTLIL::Design *design) { - FILE *f = NULL; + std::ostream *f = NULL; auto state = pre_execute(); execute(f, std::string(), args, design); post_execute(state); - if (f != stdout) - fclose(f); + if (f != &std::cout) + delete f; } -void Backend::extra_args(FILE *&f, std::string &filename, std::vector args, size_t argidx) +void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector args, size_t argidx) { bool called_with_fp = f != NULL; @@ -446,14 +446,18 @@ void Backend::extra_args(FILE *&f, std::string &filename, std::vectoropen(filename.c_str(), std::ofstream::trunc); + if (ff->fail()) { + delete ff; log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); + } + f = ff; } if (called_with_fp) @@ -463,11 +467,11 @@ void Backend::extra_args(FILE *&f, std::string &filename, std::vector args; char *s = strdup(command.c_str()); @@ -477,7 +481,7 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, backend_call(design, f, filename, args); } -void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector args) +void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::vector args) { if (args.size() == 0) return; @@ -491,9 +495,9 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, backend_register[args[0]]->execute(f, filename, args, design); backend_register[args[0]]->post_execute(state); } else if (filename == "-") { - FILE *f_stdout = stdout; // workaround for OpenBSD 'stdout' implementation + std::ostream *f_cout = &std::cout; auto state = backend_register[args[0]]->pre_execute(); - backend_register[args[0]]->execute(f_stdout, "", args, design); + backend_register[args[0]]->execute(f_cout, "", args, design); backend_register[args[0]]->post_execute(state); } else { if (!filename.empty()) diff --git a/kernel/register.h b/kernel/register.h index d7e4281c..f2c6ad29 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -17,15 +17,11 @@ * */ +#include "kernel/yosys.h" + #ifndef REGISTER_H #define REGISTER_H -#include "kernel/yosys.h" -#include -#include -#include -#include - YOSYS_NAMESPACE_BEGIN struct Pass @@ -94,12 +90,12 @@ struct Backend : Pass virtual void run_register(); virtual ~Backend(); virtual void execute(std::vector args, RTLIL::Design *design) OVERRIDE FINAL; - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; - void extra_args(FILE *&f, std::string &filename, std::vector args, size_t argidx); + void extra_args(std::ostream *&f, std::string &filename, std::vector args, size_t argidx); - static void backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::string command); - static void backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector args); + static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command); + static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::vector args); }; // implemented in passes/cmds/select.cc diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 22bff7bd..28a45134 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -412,17 +412,12 @@ namespace { void error(int linenr) { - char *ptr; - size_t size; - - FILE *f = open_memstream(&ptr, &size); - ILANG_BACKEND::dump_cell(f, " ", cell); - fputc(0, f); - fclose(f); + std::stringstream buf; + ILANG_BACKEND::dump_cell(buf, " ", cell); log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s", module ? module->name.c_str() : "", module ? "." : "", - cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, ptr); + cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str()); } int param(const char *name) diff --git a/kernel/yosys.h b/kernel/yosys.h index c6cbcabc..bfadb5ff 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -45,6 +45,11 @@ #include #include +#include +#include +#include +#include + #include #include #include diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index ebf4d77f..eaa0f9fa 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -747,11 +747,12 @@ struct ExtractPass : public Pass { } } - FILE *f = fopen(mine_outfile.c_str(), "wt"); - if (f == NULL) + std::ofstream f; + f.open(mine_outfile.c_str(), std::ofstream::trunc); + if (f.fail()) log_error("Can't open output file `%s'.\n", mine_outfile.c_str()); - Backend::backend_call(map, f, mine_outfile, "ilang"); - fclose(f); + Backend::backend_call(map, &f, mine_outfile, "ilang"); + f.close(); } delete map; diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index d2600227..eed0f75f 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -70,26 +70,26 @@ static std::string idy(std::string str1, std::string str2 = std::string(), std:: return id(str1); } -static void autotest(FILE *f, RTLIL::Design *design, int num_iter) +static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) { - fprintf(f, "module testbench;\n\n"); + f << stringf("module testbench;\n\n"); - fprintf(f, "integer i;\n\n"); + f << stringf("integer i;\n\n"); - fprintf(f, "reg [31:0] xorshift128_x = 123456789;\n"); - fprintf(f, "reg [31:0] xorshift128_y = 362436069;\n"); - fprintf(f, "reg [31:0] xorshift128_z = 521288629;\n"); - fprintf(f, "reg [31:0] xorshift128_w = %u; // <-- seed value\n", int(time(NULL))); - fprintf(f, "reg [31:0] xorshift128_t;\n\n"); - fprintf(f, "task xorshift128;\n"); - fprintf(f, "begin\n"); - fprintf(f, "\txorshift128_t = xorshift128_x ^ (xorshift128_x << 11);\n"); - fprintf(f, "\txorshift128_x = xorshift128_y;\n"); - fprintf(f, "\txorshift128_y = xorshift128_z;\n"); - fprintf(f, "\txorshift128_z = xorshift128_w;\n"); - fprintf(f, "\txorshift128_w = xorshift128_w ^ (xorshift128_w >> 19) ^ xorshift128_t ^ (xorshift128_t >> 8);\n"); - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); + f << stringf("reg [31:0] xorshift128_x = 123456789;\n"); + f << stringf("reg [31:0] xorshift128_y = 362436069;\n"); + f << stringf("reg [31:0] xorshift128_z = 521288629;\n"); + f << stringf("reg [31:0] xorshift128_w = %u; // <-- seed value\n", int(time(NULL))); + f << stringf("reg [31:0] xorshift128_t;\n\n"); + f << stringf("task xorshift128;\n"); + f << stringf("begin\n"); + f << stringf("\txorshift128_t = xorshift128_x ^ (xorshift128_x << 11);\n"); + f << stringf("\txorshift128_x = xorshift128_y;\n"); + f << stringf("\txorshift128_y = xorshift128_z;\n"); + f << stringf("\txorshift128_z = xorshift128_w;\n"); + f << stringf("\txorshift128_w = xorshift128_w ^ (xorshift128_w >> 19) ^ xorshift128_t ^ (xorshift128_t >> 8);\n"); + f << stringf("end\n"); + f << stringf("endtask\n\n"); for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { @@ -110,7 +110,7 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) if (wire->port_output) { count_ports++; signal_out[idy("sig", mod->name.str(), wire->name.str())] = wire->width; - fprintf(f, "wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); + f << stringf("wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); } else if (wire->port_input) { count_ports++; bool is_clksignal = wire->get_bool_attribute("\\gentb_clock"); @@ -130,85 +130,85 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) if (wire->attributes.count("\\gentb_constant") != 0) signal_const[idy("sig", mod->name.str(), wire->name.str())] = wire->attributes["\\gentb_constant"].as_string(); } - fprintf(f, "reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); + f << stringf("reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); } } - fprintf(f, "%s %s(\n", id(mod->name.str()).c_str(), idy("uut", mod->name.str()).c_str()); + f << stringf("%s %s(\n", id(mod->name.str()).c_str(), idy("uut", mod->name.str()).c_str()); for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); it2++) { RTLIL::Wire *wire = it2->second; if (wire->port_output || wire->port_input) - fprintf(f, "\t.%s(%s)%s\n", id(wire->name.str()).c_str(), + f << stringf("\t.%s(%s)%s\n", id(wire->name.str()).c_str(), idy("sig", mod->name.str(), wire->name.str()).c_str(), --count_ports ? "," : ""); } - fprintf(f, ");\n\n"); + f << stringf(");\n\n"); - fprintf(f, "task %s;\n", idy(mod->name.str(), "reset").c_str()); - fprintf(f, "begin\n"); + f << stringf("task %s;\n", idy(mod->name.str(), "reset").c_str()); + f << stringf("begin\n"); int delay_counter = 0; for (auto it = signal_in.begin(); it != signal_in.end(); it++) - fprintf(f, "\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2); + f << stringf("\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2); for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) - fprintf(f, "\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2); + f << stringf("\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2); for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { - fprintf(f, "\t#100; %s <= 1;\n", it->first.c_str()); - fprintf(f, "\t#100; %s <= 0;\n", it->first.c_str()); + f << stringf("\t#100; %s <= 1;\n", it->first.c_str()); + f << stringf("\t#100; %s <= 0;\n", it->first.c_str()); } delay_counter = 0; for (auto it = signal_in.begin(); it != signal_in.end(); it++) - fprintf(f, "\t%s <= #%d ~0;\n", it->first.c_str(), ++delay_counter*2); + f << stringf("\t%s <= #%d ~0;\n", it->first.c_str(), ++delay_counter*2); for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { - fprintf(f, "\t#100; %s <= 1;\n", it->first.c_str()); - fprintf(f, "\t#100; %s <= 0;\n", it->first.c_str()); + f << stringf("\t#100; %s <= 1;\n", it->first.c_str()); + f << stringf("\t#100; %s <= 0;\n", it->first.c_str()); } delay_counter = 0; for (auto it = signal_in.begin(); it != signal_in.end(); it++) { if (signal_const.count(it->first) == 0) continue; - fprintf(f, "\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str()); + f << stringf("\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str()); } - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); + f << stringf("end\n"); + f << stringf("endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name.str(), "update_data").c_str()); - fprintf(f, "begin\n"); + f << stringf("task %s;\n", idy(mod->name.str(), "update_data").c_str()); + f << stringf("begin\n"); delay_counter = 0; for (auto it = signal_in.begin(); it != signal_in.end(); it++) { if (signal_const.count(it->first) > 0) continue; - fprintf(f, "\txorshift128;\n"); - fprintf(f, "\t%s <= #%d { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };\n", it->first.c_str(), ++delay_counter*2); + f << stringf("\txorshift128;\n"); + f << stringf("\t%s <= #%d { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };\n", it->first.c_str(), ++delay_counter*2); } - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); + f << stringf("end\n"); + f << stringf("endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name.str(), "update_clock").c_str()); - fprintf(f, "begin\n"); + f << stringf("task %s;\n", idy(mod->name.str(), "update_clock").c_str()); + f << stringf("begin\n"); if (signal_clk.size()) { - fprintf(f, "\txorshift128;\n"); - fprintf(f, "\t{"); + f << stringf("\txorshift128;\n"); + f << stringf("\t{"); int total_clock_bits = 0; for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { - fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); + f << stringf("%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); total_clock_bits += it->second; } - fprintf(f, " } = {"); + f << stringf(" } = {"); for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) - fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); - fprintf(f, " } ^ (%d'b1 << (xorshift128_w %% %d));\n", total_clock_bits, total_clock_bits); + f << stringf("%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); + f << stringf(" } ^ (%d'b1 << (xorshift128_w %% %d));\n", total_clock_bits, total_clock_bits); } - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); + f << stringf("end\n"); + f << stringf("endtask\n\n"); char shorthand = 'A'; std::vector header1; std::string header2 = ""; - fprintf(f, "task %s;\n", idy(mod->name.str(), "print_status").c_str()); - fprintf(f, "begin\n"); - fprintf(f, "\t$display(\"#OUT# %%b %%b %%b %%t %%d\", {"); + f << stringf("task %s;\n", idy(mod->name.str(), "print_status").c_str()); + f << stringf("begin\n"); + f << stringf("\t$display(\"#OUT# %%b %%b %%b %%t %%d\", {"); if (signal_in.size()) for (auto it = signal_in.begin(); it != signal_in.end(); it++) { - fprintf(f, "%s %s", it == signal_in.begin() ? "" : ",", it->first.c_str()); + f << stringf("%s %s", it == signal_in.begin() ? "" : ",", it->first.c_str()); int len = it->second; if (len > 1) header2 += "/", len--; @@ -220,14 +220,14 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) header1.back()[0] = shorthand++; } else { - fprintf(f, " 1'bx"); + f << stringf(" 1'bx"); header2 += "#"; } - fprintf(f, " }, {"); + f << stringf(" }, {"); header2 += " "; if (signal_clk.size()) { for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { - fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); + f << stringf("%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); int len = it->second; if (len > 1) header2 += "/", len--; @@ -239,14 +239,14 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) header1.back()[0] = shorthand++; } } else { - fprintf(f, " 1'bx"); + f << stringf(" 1'bx"); header2 += "#"; } - fprintf(f, " }, {"); + f << stringf(" }, {"); header2 += " "; if (signal_out.size()) { for (auto it = signal_out.begin(); it != signal_out.end(); it++) { - fprintf(f, "%s %s", it == signal_out.begin() ? "" : ",", it->first.c_str()); + f << stringf("%s %s", it == signal_out.begin() ? "" : ",", it->first.c_str()); int len = it->second; if (len > 1) header2 += "/", len--; @@ -258,47 +258,47 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter) header1.back()[0] = shorthand++; } } else { - fprintf(f, " 1'bx"); + f << stringf(" 1'bx"); header2 += "#"; } - fprintf(f, " }, $time, i);\n"); - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); + f << stringf(" }, $time, i);\n"); + f << stringf("end\n"); + f << stringf("endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name.str(), "print_header").c_str()); - fprintf(f, "begin\n"); - fprintf(f, "\t$display(\"#OUT#\");\n"); + f << stringf("task %s;\n", idy(mod->name.str(), "print_header").c_str()); + f << stringf("begin\n"); + f << stringf("\t$display(\"#OUT#\");\n"); for (auto &hdr : header1) - fprintf(f, "\t$display(\"#OUT# %s\");\n", hdr.c_str()); - fprintf(f, "\t$display(\"#OUT#\");\n"); - fprintf(f, "\t$display(\"#OUT# %s\");\n", header2.c_str()); - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); + f << stringf("\t$display(\"#OUT# %s\");\n", hdr.c_str()); + f << stringf("\t$display(\"#OUT#\");\n"); + f << stringf("\t$display(\"#OUT# %s\");\n", header2.c_str()); + f << stringf("end\n"); + f << stringf("endtask\n\n"); - fprintf(f, "task %s;\n", idy(mod->name.str(), "test").c_str()); - fprintf(f, "begin\n"); - fprintf(f, "\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name.str()).c_str()); - fprintf(f, "\t%s;\n", idy(mod->name.str(), "reset").c_str()); - fprintf(f, "\tfor (i=0; i<%d; i=i+1) begin\n", num_iter); - fprintf(f, "\t\tif (i %% 20 == 0) %s;\n", idy(mod->name.str(), "print_header").c_str()); - fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "update_data").c_str()); - fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "update_clock").c_str()); - fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "print_status").c_str()); - fprintf(f, "\tend\n"); - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); + f << stringf("task %s;\n", idy(mod->name.str(), "test").c_str()); + f << stringf("begin\n"); + f << stringf("\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name.str()).c_str()); + f << stringf("\t%s;\n", idy(mod->name.str(), "reset").c_str()); + f << stringf("\tfor (i=0; i<%d; i=i+1) begin\n", num_iter); + f << stringf("\t\tif (i %% 20 == 0) %s;\n", idy(mod->name.str(), "print_header").c_str()); + f << stringf("\t\t#100; %s;\n", idy(mod->name.str(), "update_data").c_str()); + f << stringf("\t\t#100; %s;\n", idy(mod->name.str(), "update_clock").c_str()); + f << stringf("\t\t#100; %s;\n", idy(mod->name.str(), "print_status").c_str()); + f << stringf("\tend\n"); + f << stringf("end\n"); + f << stringf("endtask\n\n"); } - fprintf(f, "initial begin\n"); - fprintf(f, "\t// $dumpfile(\"testbench.vcd\");\n"); - fprintf(f, "\t// $dumpvars(0, testbench);\n"); + f << stringf("initial begin\n"); + f << stringf("\t// $dumpfile(\"testbench.vcd\");\n"); + f << stringf("\t// $dumpvars(0, testbench);\n"); for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) if (!it->second->get_bool_attribute("\\gentb_skip")) - fprintf(f, "\t%s;\n", idy(it->first.str(), "test").c_str()); - fprintf(f, "\t$finish;\n"); - fprintf(f, "end\n\n"); + f << stringf("\t%s;\n", idy(it->first.str(), "test").c_str()); + f << stringf("\t$finish;\n"); + f << stringf("end\n\n"); - fprintf(f, "endmodule\n"); + f << stringf("endmodule\n"); } struct TestAutotbBackend : public Backend { @@ -328,7 +328,7 @@ struct TestAutotbBackend : public Backend { log(" number of iterations the test bench shuld run (default = 1000)\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) { int num_iter = 1000; @@ -345,7 +345,7 @@ struct TestAutotbBackend : public Backend { } extra_args(f, filename, args, argidx); - autotest(f, design, num_iter); + autotest(*f, design, num_iter); } } TestAutotbBackend; From 19cff41eb4261b20374058f16807a229af46f304 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:03:55 +0200 Subject: [PATCH 639/750] Changed frontend-api from FILE to std::istream --- backends/intersynth/intersynth.cc | 8 +++--- 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 +++--- kernel/register.cc | 23 +++++++++------ kernel/register.h | 8 +++--- kernel/yosys.h | 1 + passes/cmds/show.cc | 8 +++--- passes/cmds/write_file.cc | 4 +-- passes/techmap/dfflibmap.cc | 7 +++-- passes/techmap/extract.cc | 9 +++--- passes/techmap/libparse.cc | 40 +++++++++++++++----------- passes/techmap/libparse.h | 4 +-- passes/techmap/techmap.cc | 13 ++++----- 22 files changed, 116 insertions(+), 89 deletions(-) diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 97ead3c6..8502d90f 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -101,13 +101,13 @@ struct IntersynthBackend : public Backend { log("Output filename: %s\n", filename.c_str()); for (auto filename : libfiles) { - FILE *f = fopen(filename.c_str(), "rt"); - if (f == NULL) + std::ifstream f; + f.open(filename.c_str()); + if (f.fail()) log_error("Can't open lib file `%s'.\n", filename.c_str()); RTLIL::Design *lib = new RTLIL::Design; - Frontend::frontend_call(lib, f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); + Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); libs.push_back(lib); - fclose(f); } if (libs.size() > 0) diff --git a/frontends/ilang/ilang_frontend.cc b/frontends/ilang/ilang_frontend.cc index 2d4b99c5..f6f926db 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 317ec0d5..b04d6c51 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 f3bdeb1a..4109cd4b 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 e1ef39a5..a5cc0689 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 83bfce37..a9ab022a 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 f79f81a9..c9302aba 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 3512538c..a9f69a49 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 ae139741..f8343321 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 19578908..c63fbb08 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 dac5b3d0..af6495f8 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 f0545700..8b6f62a6 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); diff --git a/kernel/register.cc b/kernel/register.cc index 95ed0cbd..5f4e71d1 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -286,20 +286,20 @@ void Frontend::execute(std::vector args, RTLIL::Design *design) { log_assert(next_args.empty()); do { - FILE *f = NULL; + std::istream *f = NULL; next_args.clear(); auto state = pre_execute(); execute(f, std::string(), args, design); post_execute(state); args = next_args; - fclose(f); + delete f; } while (!args.empty()); } FILE *Frontend::current_script_file = NULL; std::string Frontend::last_here_document; -void Frontend::extra_args(FILE *&f, std::string &filename, std::vector args, size_t argidx) +void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector args, size_t argidx) { bool called_with_fp = f != NULL; @@ -338,11 +338,16 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vectoropen(filename.c_str()); + if (ff->fail()) + delete ff; + else + f = ff; } if (f == NULL) log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); @@ -367,7 +372,7 @@ void Frontend::extra_args(FILE *&f, std::string &filename, std::vector args; char *s = strdup(command.c_str()); @@ -377,7 +382,7 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam frontend_call(design, f, filename, args); } -void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector args) +void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::vector args) { if (args.size() == 0) return; @@ -389,9 +394,9 @@ void Frontend::frontend_call(RTLIL::Design *design, FILE *f, std::string filenam frontend_register[args[0]]->execute(f, filename, args, design); frontend_register[args[0]]->post_execute(state); } else if (filename == "-") { - FILE *f_stdin = stdin; // workaround for OpenBSD 'stdin' implementation + std::istream *f_cin = &std::cin; auto state = frontend_register[args[0]]->pre_execute(); - frontend_register[args[0]]->execute(f_stdin, "", args, design); + frontend_register[args[0]]->execute(f_cin, "", args, design); frontend_register[args[0]]->post_execute(state); } else { if (!filename.empty()) diff --git a/kernel/register.h b/kernel/register.h index f2c6ad29..a49675ed 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -74,13 +74,13 @@ struct Frontend : Pass virtual void run_register(); virtual ~Frontend(); virtual void execute(std::vector args, RTLIL::Design *design) OVERRIDE FINAL; - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) = 0; static std::vector next_args; - void extra_args(FILE *&f, std::string &filename, std::vector args, size_t argidx); + void extra_args(std::istream *&f, std::string &filename, std::vector args, size_t argidx); - static void frontend_call(RTLIL::Design *design, FILE *f, std::string filename, std::string command); - static void frontend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector args); + static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::string command); + static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::vector args); }; struct Backend : Pass diff --git a/kernel/yosys.h b/kernel/yosys.h index bfadb5ff..87c99d1f 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -47,6 +47,7 @@ #include #include +#include #include #include diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index fc6e972e..3468eae7 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -720,13 +720,13 @@ struct ShowPass : public Pass { } for (auto filename : libfiles) { - FILE *f = fopen(filename.c_str(), "rt"); - if (f == NULL) + std::ifstream f; + f.open(filename.c_str()); + if (f.fail()) log_error("Can't open lib file `%s'.\n", filename.c_str()); RTLIL::Design *lib = new RTLIL::Design; - Frontend::frontend_call(lib, f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); + Frontend::frontend_call(lib, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); libs.push_back(lib); - fclose(f); } if (libs.size() > 0) diff --git a/passes/cmds/write_file.cc b/passes/cmds/write_file.cc index a7cd7b43..813e215b 100644 --- a/passes/cmds/write_file.cc +++ b/passes/cmds/write_file.cc @@ -41,7 +41,7 @@ struct WriteFileFrontend : public Frontend { log(" EOT\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design*) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design*) { bool append_mode = false; std::string output_filename; @@ -67,7 +67,7 @@ struct WriteFileFrontend : public Frontend { char buffer[64 * 1024]; size_t bytes; - while (0 < (bytes = fread(buffer, 1, sizeof(buffer), f))) + while (0 < (bytes = f->readsome(buffer, sizeof(buffer)))) fwrite(buffer, bytes, 1, of); fclose(of); diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 6ce771ac..7e39040c 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -463,11 +463,12 @@ struct DfflibmapPass : public Pass { if (liberty_file.empty()) log_cmd_error("Missing `-liberty liberty_file' option!\n"); - FILE *f = fopen(liberty_file.c_str(), "r"); - if (f == NULL) + std::ifstream f; + f.open(liberty_file.c_str()); + if (f.fail()) log_cmd_error("Can't open liberty file `%s': %s\n", liberty_file.c_str(), strerror(errno)); LibertyParser libparser(f); - fclose(f); + f.close(); find_cell(libparser.ast, "$_DFF_N_", false, false, false, false); find_cell(libparser.ast, "$_DFF_P_", true, false, false, false); diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index eaa0f9fa..221e9e49 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -609,13 +609,14 @@ struct ExtractPass : public Pass { } else { - FILE *f = fopen(filename.c_str(), "rt"); - if (f == NULL) { + std::ifstream f; + f.open(filename.c_str()); + if (f.fail()) { delete map; log_cmd_error("Can't open map file `%s'.\n", filename.c_str()); } - Frontend::frontend_call(map, f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); - fclose(f); + Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog"); + f.close(); if (filename.size() <= 3 || filename.substr(filename.size()-3) != ".il") { Pass::call(map, "proc"); diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 2ff55153..612fa111 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -21,6 +21,10 @@ #include #include +#include +#include +#include + #ifndef FILTERLIB #include "kernel/log.h" #endif @@ -85,19 +89,19 @@ int LibertyParser::lexer(std::string &str) int c; do { - c = fgetc(f); + c = f.get(); } while (c == ' ' || c == '\t' || c == '\r'); if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.') { str = c; while (1) { - c = fgetc(f); + c = f.get(); if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.') str += c; else break; } - ungetc(c, f); + f.unget(); // fprintf(stderr, "LEX: identifier >>%s<<\n", str.c_str()); return 'v'; } @@ -105,7 +109,7 @@ int LibertyParser::lexer(std::string &str) if (c == '"') { str = c; while (1) { - c = fgetc(f); + c = f.get(); if (c == '\n') line++; str += c; @@ -117,34 +121,34 @@ int LibertyParser::lexer(std::string &str) } if (c == '/') { - c = fgetc(f); + c = f.get(); if (c == '*') { int last_c = 0; while (c > 0 && (last_c != '*' || c != '/')) { last_c = c; - c = fgetc(f); + c = f.get(); if (c == '\n') line++; } return lexer(str); } else if (c == '/') { while (c > 0 && c != '\n') - c = fgetc(f); + c = f.get(); line++; return lexer(str); } - ungetc(c, f); + f.unget(); // fprintf(stderr, "LEX: char >>/<<\n"); return '/'; } if (c == '\\') { - c = fgetc(f); + c = f.get(); if (c == '\r') - c = fgetc(f); + c = f.get(); if (c == '\n') return lexer(str); - ungetc(c, f); + f.unget(); return '\\'; } @@ -608,16 +612,20 @@ int main(int argc, char **argv) } } - FILE *f = stdin; + std::istream *f = &std::cin; + if (argc == 3) { - f = fopen(argv[2], "r"); - if (f == NULL) { + std::ifstream *ff = new std::ifstream; + ff->open(argv[2]); + if (ff->fail()) { + delete ff; fprintf(stderr, "Can't open liberty file `%s'.\n", argv[2]); usage(); } + f = ff; } - LibertyParser parser(f); + LibertyParser parser(*f); if (parser.ast) { if (flag_verilogsim) gen_verilogsim(parser.ast); @@ -626,7 +634,7 @@ int main(int argc, char **argv) } if (argc == 3) - fclose(f); + delete f; return 0; } diff --git a/passes/techmap/libparse.h b/passes/techmap/libparse.h index eff268bb..24748742 100644 --- a/passes/techmap/libparse.h +++ b/passes/techmap/libparse.h @@ -41,10 +41,10 @@ namespace PASS_DFFLIBMAP struct LibertyParser { - FILE *f; + std::istream &f; int line; LibertyAst *ast; - LibertyParser(FILE *f) : f(f), line(1), ast(parse()) {} + LibertyParser(std::istream &f) : f(f), line(1), ast(parse()) {} ~LibertyParser() { if (ast) delete ast; } int lexer(std::string &str); LibertyAst *parse(); diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index d9d8ddd6..beacdfa6 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -869,9 +869,8 @@ struct TechmapPass : public Pass { RTLIL::Design *map = new RTLIL::Design; if (map_files.empty()) { - FILE *f = fmemopen(stdcells_code, strlen(stdcells_code), "rt"); - Frontend::frontend_call(map, f, "", verilog_frontend); - fclose(f); + std::istringstream f(stdcells_code); + Frontend::frontend_call(map, &f, "", verilog_frontend); } else for (auto &fn : map_files) if (fn.substr(0, 1) == "%") { @@ -883,11 +882,11 @@ struct TechmapPass : public Pass { if (!map->has(mod->name)) map->add(mod->clone()); } else { - FILE *f = fopen(fn.c_str(), "rt"); - if (f == NULL) + std::ifstream f; + f.open(fn.c_str()); + if (f.fail()) log_cmd_error("Can't open map file `%s'\n", fn.c_str()); - Frontend::frontend_call(map, f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend); - fclose(f); + Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend); } std::map modules_new; From 58367cd87a5d2bac1de81512f60939c080b3b9ef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:14:58 +0200 Subject: [PATCH 640/750] Removed compatbility.{h,cc}: Not using open_memstream/fmemopen anymore --- Makefile | 3 +- frontends/verilog/verilog_frontend.cc | 5 +- kernel/compatibility.cc | 135 -------------------------- kernel/compatibility.h | 37 ------- kernel/log.cc | 10 ++ kernel/log.h | 1 + kernel/register.cc | 24 ++--- kernel/yosys.h | 1 - 8 files changed, 21 insertions(+), 195 deletions(-) delete mode 100644 kernel/compatibility.cc delete mode 100644 kernel/compatibility.h diff --git a/Makefile b/Makefile index ca595d9c..32757063 100644 --- a/Makefile +++ b/Makefile @@ -133,8 +133,7 @@ Q = S = endif -OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o -OBJS += kernel/compatibility.o kernel/yosys.o +OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index c63fbb08..c6d4a0b7 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 diff --git a/kernel/compatibility.cc b/kernel/compatibility.cc deleted file mode 100644 index 4c4cbd6d..00000000 --- a/kernel/compatibility.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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. - * - */ - -/** - * POSIX.2008 fake implementation for pre-POSIX.2008 systems. (OSX, BSD, MINGW, CYGWIN, older Linux &c.) - */ - -#include -#include -#include -#include - -#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L || defined(EMSCRIPTEN)) - -typedef struct memstream { - off_t pos; - off_t size; - char * buffer; - char ** bufp; - size_t * sizep; - bool realloc; -} memstream_t; - -static int memstream_read (void * cookie, char * buf, int size) -{ - memstream_t * mem = (memstream_t *) cookie; - off_t available = mem->size - mem->pos; - if (available < 0) - available = 0; - if (size > available) - size = available; - memcpy(buf, mem->buffer + mem->pos, size); - mem->pos += size; - return size; -} - -static int memstream_write (void * cookie, const char * buf, int size) -{ - memstream_t * mem = (memstream_t *) cookie; - off_t available = mem->size - mem->pos; - if (size > available) { - if (mem->realloc) { - mem->buffer = (char *) realloc(mem->buffer, mem->pos + size + 1); - memset(mem->buffer + mem->size, 0, mem->pos + size + 1 - mem->size); - mem->size = mem->pos + size; - if (mem->bufp) - *(mem->bufp) = mem->buffer; - if (mem->sizep) - *(mem->sizep) = mem->size; - } else { - size = available; - } - } - memcpy(mem->buffer + mem->pos, buf, sizeof(char) * size); - mem->pos += size; - return size; -} - -static fpos_t memstream_seek (void * cookie, fpos_t offset, int whence) -{ - memstream_t * mem = (memstream_t *) cookie; - switch (whence) { - case SEEK_SET: - if (offset < 0) - goto error_inval; - mem->pos = offset; - return 0; - case SEEK_CUR: - if (mem->pos + offset < 0) - goto error_inval; - mem->pos += offset; - return 0; - case SEEK_END: - if (mem->size + offset < 0) - goto error_inval; - mem->pos = mem->size + offset; - break; - default: - goto error_inval; - } - return mem->pos; -error_inval: - errno = EINVAL; - return -1; -} - -static int memstream_close (void * cookie) -{ - memstream_t * mem = (memstream_t *) cookie; - if (mem->bufp) - *(mem->bufp) = mem->buffer; - if (mem->sizep) - *(mem->sizep) = mem->size; - free(cookie); - return 0; -} - -FILE * compat_fmemopen (void * buf, size_t size, const char * mode) -{ - memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); - memset(mem, 0, sizeof(memstream_t)); - mem->size = size; - mem->buffer = (char *) buf; - (void) mode; - return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); -} - -FILE * compat_open_memstream (char ** bufp, size_t * sizep) -{ - memstream_t * mem = (memstream_t *) malloc(sizeof(memstream_t)); - memset(mem, 0, sizeof(memstream_t)); - mem->bufp = bufp; - mem->sizep = sizep; - mem->realloc = true; - return funopen(mem, memstream_read, memstream_write, memstream_seek, memstream_close); -} - -#endif /* !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) */ - diff --git a/kernel/compatibility.h b/kernel/compatibility.h deleted file mode 100644 index c7603c8a..00000000 --- a/kernel/compatibility.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * - */ - -#ifndef COMPATIBILITY_H -#define COMPATIBILITY_H - -#include -#include - -#if !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) - -#define open_memstream compat_open_memstream -#define fmemopen compat_fmemopen - -FILE * compat_open_memstream (char ** bufp, size_t * sizep); -FILE * compat_fmemopen (void * buf, size_t size, const char * mode); - -#endif /* !(_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L) */ - -#endif /* COMPATIBILITY_H */ - diff --git a/kernel/log.cc b/kernel/log.cc index 2b4b5db5..1b0eb664 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -32,6 +32,7 @@ YOSYS_NAMESPACE_BEGIN std::vector log_files; +std::vector log_streams; FILE *log_errfile = NULL; SHA1 *log_hasher = NULL; @@ -92,10 +93,16 @@ void logv(const char *format, va_list ap) for (auto f : log_files) fputs(time_str.c_str(), f); + + for (auto f : log_streams) + *f << time_str; } for (auto f : log_files) fputs(str.c_str(), f); + + for (auto f : log_streams) + *f << str; } void logv_header(const char *format, va_list ap) @@ -202,6 +209,9 @@ void log_flush() { for (auto f : log_files) fflush(f); + + for (auto f : log_streams) + f->flush(); } void log_dump_val_worker(RTLIL::SigSpec v) { diff --git a/kernel/log.h b/kernel/log.h index b1c44b46..e2b4db87 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -35,6 +35,7 @@ YOSYS_NAMESPACE_BEGIN struct log_cmd_error_expection { }; extern std::vector log_files; +extern std::vector log_streams; extern FILE *log_errfile; extern class SHA1 *log_hasher; diff --git a/kernel/register.cc b/kernel/register.cc index 5f4e71d1..a53bd84c 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -612,15 +612,11 @@ struct HelpPass : public Pass { FILE *f = fopen("command-reference-manual.tex", "wt"); fprintf(f, "%% Generated using the yosys 'help -write-tex-command-reference-manual' command.\n\n"); for (auto &it : pass_register) { - size_t memsize; - char *memptr; - FILE *memf = open_memstream(&memptr, &memsize); - log_files.push_back(memf); + std::ostringstream buf; + log_streams.push_back(&buf); it.second->help(); - log_files.pop_back(); - fclose(memf); - write_tex(f, it.first, it.second->short_help, memptr); - free(memptr); + log_streams.pop_back(); + write_tex(f, it.first, it.second->short_help, buf.str()); } fclose(f); } @@ -628,15 +624,11 @@ struct HelpPass : public Pass { else if (args[1] == "-write-web-command-reference-manual") { FILE *f = fopen("templates/cmd_index.in", "wt"); for (auto &it : pass_register) { - size_t memsize; - char *memptr; - FILE *memf = open_memstream(&memptr, &memsize); - log_files.push_back(memf); + std::ostringstream buf; + log_streams.push_back(&buf); it.second->help(); - log_files.pop_back(); - fclose(memf); - write_html(f, it.first, it.second->short_help, memptr); - free(memptr); + log_streams.pop_back(); + write_html(f, it.first, it.second->short_help, buf.str()); } fclose(f); } diff --git a/kernel/yosys.h b/kernel/yosys.h index 87c99d1f..9a4826ca 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -98,7 +98,6 @@ YOSYS_NAMESPACE_END #include "kernel/log.h" #include "kernel/rtlil.h" #include "kernel/register.h" -#include "kernel/compatibility.h" YOSYS_NAMESPACE_BEGIN From c642dd0b3eb1390b6c1acd39c1f19797da27b190 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:32:00 +0200 Subject: [PATCH 641/750] Only call proc_share_dirname() in techmap when necessary --- passes/techmap/techmap.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index beacdfa6..660f1b38 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -829,14 +829,13 @@ struct TechmapPass : public Pass { int max_iter = -1; size_t argidx; - std::string proc_share_path = proc_share_dirname(); for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-map" && argidx+1 < args.size()) { map_files.push_back(args[++argidx]); continue; } if (args[argidx] == "-share_map" && argidx+1 < args.size()) { - map_files.push_back(proc_share_path + args[++argidx]); + map_files.push_back(proc_share_dirname() + args[++argidx]); continue; } if (args[argidx] == "-max_iter" && argidx+1 < args.size()) { From 9c5a63c52c24f0570557b4bf7340b41666cf44b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 13:27:40 +0200 Subject: [PATCH 642/750] azonenberg: Make dump_vcd save model when temporal induction fails due to step limit --- passes/sat/sat.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index c6da4bb4..08ae9e92 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -1320,6 +1320,8 @@ struct SatPass : public Pass { } log("\nReached maximum number of time steps -> proof failed.\n"); + if(!vcd_file_name.empty()) + inductstep.dump_model_to_vcd(vcd_file_name); print_proof_failed(); tip_failed: From eda603105e2aa72441bfc07662774a20f3b978fe Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 15:14:00 +0200 Subject: [PATCH 643/750] Added is_signed argument to SigSpec.as_int() and Const.as_int() --- kernel/rtlil.cc | 11 +++++++---- kernel/rtlil.h | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 28a45134..df4d8b09 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -92,12 +92,15 @@ bool RTLIL::Const::as_bool() const return false; } -int RTLIL::Const::as_int() const +int RTLIL::Const::as_int(bool is_signed) const { - int ret = 0; + int32_t ret = 0; for (size_t i = 0; i < bits.size() && i < 32; i++) if (bits[i] == RTLIL::S1) ret |= 1 << i; + if (is_signed && bits.back() == RTLIL::S1) + for (size_t i = bits.size(); i < 32; i++) + ret |= 1 << i; return ret; } @@ -2647,14 +2650,14 @@ bool RTLIL::SigSpec::as_bool() const return false; } -int RTLIL::SigSpec::as_int() const +int RTLIL::SigSpec::as_int(bool is_signed) const { cover("kernel.rtlil.sigspec.as_int"); pack(); log_assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) - return chunks_[0].data.as_int(); + return chunks_[0].data.as_int(is_signed); return 0; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ebfe4ca2..d5887357 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -436,7 +436,7 @@ struct RTLIL::Const bool operator !=(const RTLIL::Const &other) const; bool as_bool() const; - int as_int() const; + int as_int(bool is_signed = false) const; std::string as_string() const; std::string decode_string() const; @@ -1038,7 +1038,7 @@ public: bool has_marked_bits() const; bool as_bool() const; - int as_int() const; + int as_int(bool is_signed = false) const; std::string as_string() const; RTLIL::Const as_const() const; RTLIL::Wire *as_wire() const; From 641501203c534b00a0ae3ad6844f8759d6bc8549 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 15:14:45 +0200 Subject: [PATCH 644/750] Added some additional log messages to opt_const --- passes/opt/opt_const.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 58a7f7df..c4f4bba3 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -79,7 +79,7 @@ static void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell log("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n", cell->type.c_str(), cell->name.c_str(), info.c_str(), module->name.c_str(), log_signal(Y), log_signal(out_val)); - // ILANG_BACKEND::dump_cell(stderr, "--> ", cell); + // log_cell(cell); assign_map.add(Y, out_val); module->connect(Y, out_val); module->remove(cell); @@ -380,6 +380,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if ((cell->type == "$_MUX_" || cell->type == "$mux") && invert_map.count(assign_map(cell->getPort("\\S"))) != 0) { cover_list("opt.opt_const.invert.muxsel", "$_MUX_", "$mux", cell->type.str()); + log("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module)); RTLIL::SigSpec tmp = cell->getPort("\\A"); cell->setPort("\\A", cell->getPort("\\B")); cell->setPort("\\B", tmp); @@ -545,10 +546,13 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo ACTION_DO("\\Y", cell->getPort("\\A")); } else { cover_list("opt.opt_const.eqneq.isnot", "$eq", "$ne", cell->type.str()); + log("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); cell->type = "$not"; cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); cell->unsetPort("\\B"); + OPT_DID_SOMETHING = true; + did_something = true; } goto next_cell; } @@ -638,6 +642,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(1, 1) && cell->getPort("\\B") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_invert", "$mux", "$_MUX_", cell->type.str()); + log("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module)); cell->setPort("\\A", cell->getPort("\\S")); cell->unsetPort("\\B"); cell->unsetPort("\\S"); @@ -656,6 +661,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\A") == RTLIL::SigSpec(0, 1)) { cover_list("opt.opt_const.mux_and", "$mux", "$_MUX_", cell->type.str()); + log("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); cell->setPort("\\A", cell->getPort("\\S")); cell->unsetPort("\\S"); if (cell->type == "$mux") { @@ -675,6 +681,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (consume_x && mux_bool && (cell->type == "$mux" || cell->type == "$_MUX_") && cell->getPort("\\B") == RTLIL::SigSpec(1, 1)) { cover_list("opt.opt_const.mux_or", "$mux", "$_MUX_", cell->type.str()); + log("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module)); cell->setPort("\\B", cell->getPort("\\S")); cell->unsetPort("\\S"); if (cell->type == "$mux") { @@ -727,6 +734,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } if (cell->getPort("\\S").size() != new_s.size()) { cover_list("opt.opt_const.mux_reduce", "$mux", "$pmux", cell->type.str()); + log("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n", + SIZE(cell->getPort("\\S")) - SIZE(new_s), log_id(cell->type), log_id(cell), log_id(module)); cell->setPort("\\A", new_a); cell->setPort("\\B", new_b); cell->setPort("\\S", new_s); From 7bbbe3580d249d8abab55ab4ef2703bf3dc51a3c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 17:08:07 +0200 Subject: [PATCH 645/750] Optimize shift ops with constant rhs in opt_const --- passes/opt/opt_const.cc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index c4f4bba3..a602cf5f 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -558,6 +558,41 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo } } + if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx") && assign_map(cell->getPort("\\B")).is_fully_const()) + { + bool sign_ext = cell->type == "$sshr" && cell->getParam("\\A_SIGNED").as_bool(); + int shift_bits = assign_map(cell->getPort("\\B")).as_int(cell->type.in("$shift", "$shiftx") && cell->getParam("\\B_SIGNED").as_bool()); + + if (cell->type.in("$shl", "$sshl")) + shift_bits *= -1; + + RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A")); + RTLIL::SigSpec sig_y(cell->type == "$shiftx" ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam("\\Y_WIDTH").as_int()); + + if (SIZE(sig_a) < SIZE(sig_y)) + sig_a.extend(SIZE(sig_y), cell->getParam("\\A_SIGNED").as_bool()); + + for (int i = 0; i < SIZE(sig_y); i++) { + int idx = i + shift_bits; + if (0 <= idx && idx < SIZE(sig_a)) + sig_y[i] = sig_a[idx]; + else if (SIZE(sig_a) <= idx && sign_ext) + sig_y[i] = sig_a[SIZE(sig_a)-1]; + } + + cover_list("opt.opt_const.constshift", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", cell->type.str()); + + log("Replacing %s cell `%s' (B=%s, SHR=%d) in module `%s' with fixed wiring: %s\n", + log_id(cell->type), log_id(cell), log_signal(assign_map(cell->getPort("\\B"))), shift_bits, log_id(module), log_signal(sig_y)); + + module->connect(cell->getPort("\\Y"), sig_y); + module->remove(cell); + + OPT_DID_SOMETHING = true; + did_something = true; + goto next_cell; + } + if (!keepdc) { bool identity_bu0 = false; From 672b2c6db1feb252e3fe907f1e24ae273156638a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 25 Aug 2014 12:48:20 +0200 Subject: [PATCH 646/750] Checking for valid CONFIG value in Makefile --- Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 32757063..09b2adbc 100644 --- a/Makefile +++ b/Makefile @@ -63,22 +63,22 @@ ABCPULL = 1 ifeq ($(CONFIG),clang) CXX = clang CXXFLAGS += -std=c++11 -Os -endif -ifeq ($(CONFIG),gcc) +else ifeq ($(CONFIG),gcc) CXX = gcc CXXFLAGS += -std=gnu++0x -Os -endif -ifeq ($(CONFIG),gcc-4.6) +else ifeq ($(CONFIG),gcc-4.6) CXX = gcc-4.6 CXXFLAGS += -std=gnu++0x -Os -endif -ifeq ($(CONFIG),emcc) +else ifeq ($(CONFIG),emcc) CXX = emcc CXXFLAGS += -std=c++11 -Os -Wno-warn-absolute-paths CXXFLAGS := $(filter-out -ggdb,$(CXXFLAGS)) + +else ifneq ($(CONFIG),none) +$(error Invalid CONFIG setting '$(CONFIG)'. Valid values: clang, gcc, gcc-4.6, emcc, none) endif ifeq ($(ENABLE_READLINE),1) From e70480655e8d1326bc4828ccada20e7669fa719f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 26 Aug 2014 10:11:46 +0200 Subject: [PATCH 647/750] Print Makefile.conf as make info message --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 09b2adbc..fa42cf7d 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,10 @@ OBJS = kernel/version_$(GIT_REV).o ABCREV = 4d547a5e065b ABCPULL = 1 --include Makefile.conf +ifneq ($(wildcard Makefile.conf),) +$(info $(shell sed 's,^,[Makefile.conf] ,' < Makefile.conf)) +include Makefile.conf +endif ifeq ($(CONFIG),clang) CXX = clang From 084685f4805e643c4799abcbfe114ab8c1138b72 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 26 Aug 2014 12:51:08 +0200 Subject: [PATCH 648/750] Implemented "rename -enumerate -pattern" --- passes/cmds/rename.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 3a600872..91de364f 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -58,10 +58,12 @@ struct RenamePass : public Pass { log("by this command.\n"); log("\n"); log("\n"); - log(" rename -enumerate [selection]\n"); + log(" rename -enumerate [-pattern ] [selection]\n"); log("\n"); log("Assign short auto-generated names to all selected wires and cells with private\n"); - log("names.\n"); + log("names. The -pattern option can be used to set the pattern for the new names.\n"); + log("The character %% in the pattern is replaced with a integer number. The default\n"); + log("pattern is '_%%_'.\n"); log("\n"); log(" rename -hide [selection]\n"); log("\n"); @@ -71,6 +73,7 @@ struct RenamePass : public Pass { } virtual void execute(std::vector args, RTLIL::Design *design) { + std::string pattern_prefix = "_", pattern_suffix = "_"; bool flag_enumerate = false; bool flag_hide = false; bool got_mode = false; @@ -89,6 +92,12 @@ struct RenamePass : public Pass { got_mode = true; continue; } + if (arg == "-pattern" && argidx+1 < args.size() && args[argidx+1].find('%') != std::string::npos) { + int pos = args[++argidx].find('%'); + pattern_prefix = args[argidx].substr(0, pos); + pattern_suffix = args[argidx].substr(pos+1); + continue; + } break; } @@ -107,7 +116,7 @@ struct RenamePass : public Pass { std::map new_wires; for (auto &it : module->wires_) { if (it.first[0] == '$' && design->selected(module, it.second)) - do it.second->name = stringf("\\_%d_", counter++); + do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str()); while (module->count_id(it.second->name) > 0); new_wires[it.second->name] = it.second; } @@ -116,7 +125,7 @@ struct RenamePass : public Pass { std::map new_cells; for (auto &it : module->cells_) { if (it.first[0] == '$' && design->selected(module, it.second)) - do it.second->name = stringf("\\_%d_", counter++); + do it.second->name = stringf("\\%s%d%s", pattern_prefix.c_str(), counter++, pattern_suffix.c_str()); while (module->count_id(it.second->name) > 0); new_cells[it.second->name] = it.second; } From cfb43383198aeb59e461bc0565a9a178d2ae6f01 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 27 Aug 2014 12:13:53 +0200 Subject: [PATCH 649/750] Fixed printing of multi-line Makefile.conf --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fa42cf7d..49a38726 100644 --- a/Makefile +++ b/Makefile @@ -58,8 +58,13 @@ OBJS = kernel/version_$(GIT_REV).o ABCREV = 4d547a5e065b ABCPULL = 1 +define newline + + +endef + ifneq ($(wildcard Makefile.conf),) -$(info $(shell sed 's,^,[Makefile.conf] ,' < Makefile.conf)) +$(info $(subst $$--$$,$(newline),$(shell sed 's,^,[Makefile.conf] ,; s,$$,$$--$$,;' < Makefile.conf | tr -d '\n' | sed 's,\$$--\$$$$,,'))) include Makefile.conf endif From d148b0af0d5d1a039b13b9e610859a2e55da945e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 27 Aug 2014 19:44:12 +0200 Subject: [PATCH 650/750] Fixed inserting of Q-inverters in dfflibmap --- passes/techmap/dfflibmap.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 7e39040c..07993b86 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -409,6 +409,11 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) if ('A' <= port.second && port.second <= 'Z') { sig = cell_connections[std::string("\\") + port.second]; } else + if (port.second == 'q') { + RTLIL::SigSpec old_sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))]; + sig = module->addWire(NEW_ID, SIZE(old_sig)); + module->addNotGate(NEW_ID, sig, old_sig); + } else if ('a' <= port.second && port.second <= 'z') { sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))]; sig = module->NotGate(NEW_ID, sig); From ab019b0bd505ccd63ba1d45013fa163134f6e13b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 14:11:57 +0200 Subject: [PATCH 651/750] Improved handling of $pmux cells in fsm_extract --- passes/fsm/fsm_extract.cc | 95 ++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 20 deletions(-) diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 871478de..d1d73db6 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -33,6 +33,7 @@ static RTLIL::Module *module; static SigMap assign_map; typedef std::pair sig2driver_entry_t; static SigSet sig2driver, sig2trigger; +static std::map> exclusive_ctrls; static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL::SigSpec &ctrl, std::map &states, RTLIL::Const *reset_state = NULL) { @@ -43,7 +44,7 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL assign_map.apply(sig); if (sig.is_fully_const()) { - if (states.count(sig.as_const()) == 0) { + if (sig.is_fully_def() && states.count(sig.as_const()) == 0) { log(" found state code: %s\n", log_signal(sig)); states[sig.as_const()] = -1; } @@ -123,18 +124,41 @@ static RTLIL::Const sig2const(ConstEval &ce, RTLIL::SigSpec sig, RTLIL::State no static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_data, std::map &states, int state_in, RTLIL::SigSpec ctrl_in, RTLIL::SigSpec ctrl_out, RTLIL::SigSpec dff_in, RTLIL::SigSpec dont_care) { + bool undef_bit_in_next_state_mode = false; RTLIL::SigSpec undef, constval; - if (ce.eval(ctrl_out, undef) && ce.eval(dff_in, undef)) { + if (ce.eval(ctrl_out, undef) && ce.eval(dff_in, undef)) + { + if (0) { +undef_bit_in_next_state: + for (auto &bit : dff_in) + if (bit.wire != nullptr) bit = RTLIL::Sm; + for (auto &bit : ctrl_out) + if (bit.wire != nullptr) bit = RTLIL::Sm; + undef_bit_in_next_state_mode = true; + } + log_assert(ctrl_out.is_fully_const() && dff_in.is_fully_const()); + FsmData::transition_t tr; - tr.state_in = state_in; - tr.state_out = states[ce.values_map(ce.assign_map(dff_in)).as_const()]; tr.ctrl_in = sig2const(ce, ctrl_in, RTLIL::State::Sa, dont_care); tr.ctrl_out = sig2const(ce, ctrl_out, RTLIL::State::Sx); + RTLIL::Const log_state_in = RTLIL::Const(RTLIL::State::Sx, fsm_data.state_bits); if (state_in >= 0) - log_state_in = fsm_data.state_table[tr.state_in]; + log_state_in = fsm_data.state_table.at(state_in); + + if (states.count(ce.values_map(ce.assign_map(dff_in)).as_const()) == 0) { + log(" transition: %10s %s -> INVALID_STATE(%s) %s %s\n", + log_signal(log_state_in), log_signal(tr.ctrl_in), + log_signal(ce.values_map(ce.assign_map(dff_in))), log_signal(tr.ctrl_out), + undef_bit_in_next_state_mode ? " SHORTENED" : ""); + return; + } + + tr.state_in = state_in; + tr.state_out = states.at(ce.values_map(ce.assign_map(dff_in)).as_const()); + if (dff_in.is_fully_def()) { fsm_data.transition_table.push_back(tr); log(" transition: %10s %s -> %10s %s\n", @@ -148,6 +172,10 @@ static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_d return; } + for (auto &bit : dff_in) + if (bit == RTLIL::Sx) + goto undef_bit_in_next_state; + log_assert(undef.size() > 0); log_assert(ce.stop_signals.check_all(undef)); @@ -159,21 +187,39 @@ static void find_transitions(ConstEval &ce, ConstEval &ce_nostop, FsmData &fsm_d ce.push(); dont_care.append(undef); ce.set(undef, constval.as_const()); + if (exclusive_ctrls.count(undef) && constval == RTLIL::S1) + for (auto &bit : exclusive_ctrls.at(undef)) { + RTLIL::SigSpec bitval = bit; + if (ce.eval(bitval) && bitval != RTLIL::S0) + goto found_contradiction_1; + else + ce.set(bit, RTLIL::S0); + } find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); + found_contradiction_1: ce.pop(); } else { ce.push(), ce_nostop.push(); - ce.set(undef, RTLIL::Const(0, 1)); - ce_nostop.set(undef, RTLIL::Const(0, 1)); + ce.set(undef, RTLIL::S0); + ce_nostop.set(undef, RTLIL::S0); find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); ce.pop(), ce_nostop.pop(); ce.push(), ce_nostop.push(); - ce.set(undef, RTLIL::Const(1, 1)); - ce_nostop.set(undef, RTLIL::Const(1, 1)); + ce.set(undef, RTLIL::S1); + ce_nostop.set(undef, RTLIL::S1); + if (exclusive_ctrls.count(undef)) + for (auto &bit : exclusive_ctrls.at(undef)) { + RTLIL::SigSpec bitval = bit; + if ((ce.eval(bitval) || ce_nostop.eval(bitval)) && bitval != RTLIL::S0) + goto found_contradiction_2; + else + ce.set(bit, RTLIL::S0), ce_nostop.set(bit, RTLIL::S0); + } find_transitions(ce, ce_nostop, fsm_data, states, state_in, ctrl_in, ctrl_out, dff_in, dont_care); + found_contradiction_2: ce.pop(), ce_nostop.pop(); } } @@ -188,8 +234,8 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::SigSpec dff_in(RTLIL::State::Sm, wire->width); RTLIL::Const reset_state(RTLIL::State::Sx, wire->width); - RTLIL::SigSpec clk = RTLIL::SigSpec(0, 1); - RTLIL::SigSpec arst = RTLIL::SigSpec(0, 1); + RTLIL::SigSpec clk = RTLIL::S0; + RTLIL::SigSpec arst = RTLIL::S0; bool clk_polarity = true; bool arst_polarity = true; @@ -294,8 +340,8 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); fsm_cell->setPort("\\CLK", clk); fsm_cell->setPort("\\ARST", arst); - fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); - fsm_cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity ? 1 : 0, 1); + fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? RTLIL::S1 : RTLIL::S0; + fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? RTLIL::S1 : RTLIL::S0; fsm_cell->setPort("\\CTRL_IN", ctrl_in); fsm_cell->setPort("\\CTRL_OUT", ctrl_out); fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str()); @@ -361,20 +407,29 @@ struct FsmExtractPass : public Pass { sig2driver.clear(); sig2trigger.clear(); - for (auto &cell_it : module->cells_) - for (auto &conn_it : cell_it.second->connections()) { - if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) { + exclusive_ctrls.clear(); + for (auto cell : module->cells()) { + for (auto &conn_it : cell->connections()) { + if (ct.cell_output(cell->type, conn_it.first) || !ct.cell_known(cell->type)) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); - sig2driver.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); + sig2driver.insert(sig, sig2driver_entry_t(cell->name, conn_it.first)); } - if (ct.cell_input(cell_it.second->type, conn_it.first) && cell_it.second->hasPort("\\Y") && - cell_it.second->getPort("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { + if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort("\\Y") && + cell->getPort("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) { RTLIL::SigSpec sig = conn_it.second; assign_map.apply(sig); - sig2trigger.insert(sig, sig2driver_entry_t(cell_it.first, conn_it.first)); + sig2trigger.insert(sig, sig2driver_entry_t(cell->name, conn_it.first)); } } + if (cell->type == "$pmux") { + RTLIL::SigSpec sel_sig = assign_map(cell->getPort("\\S")); + for (auto &bit1 : sel_sig) + for (auto &bit2 : sel_sig) + if (bit1 != bit2) + exclusive_ctrls[bit1].insert(bit2); + } + } std::vector wire_list; for (auto &wire_it : module->wires_) From f910481f35109d7333088ac79bb25729e516fa00 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 14:34:49 +0200 Subject: [PATCH 652/750] Using $pmux info in fsm_extract to optimize transition ctrl_in patterns --- passes/fsm/fsm_extract.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index d1d73db6..451f00fc 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -144,6 +144,16 @@ undef_bit_in_next_state: tr.ctrl_in = sig2const(ce, ctrl_in, RTLIL::State::Sa, dont_care); tr.ctrl_out = sig2const(ce, ctrl_out, RTLIL::State::Sx); + std::map ctrl_in_bit_indices; + for (int i = 0; i < SIZE(ctrl_in); i++) + ctrl_in_bit_indices[ctrl_in[i]] = i; + + for (auto &it : ctrl_in_bit_indices) + if (tr.ctrl_in.bits.at(it.second) == RTLIL::S1 && exclusive_ctrls.count(it.first) != 0) + for (auto &dc_bit : exclusive_ctrls.at(it.first)) + if (ctrl_in_bit_indices.count(dc_bit)) + tr.ctrl_in.bits.at(ctrl_in_bit_indices.at(dc_bit)) = RTLIL::State::Sa; + RTLIL::Const log_state_in = RTLIL::Const(RTLIL::State::Sx, fsm_data.state_bits); if (state_in >= 0) log_state_in = fsm_data.state_table.at(state_in); From 3a7d5d188d4b9cfeb225e0f5dea07ee7a40eceed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 14:43:06 +0200 Subject: [PATCH 653/750] Don't change existing binary FSM encoding if it is already optimal --- passes/fsm/fsm_recode.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index 9c0da0a3..ea10cdf8 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -82,7 +82,12 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs fsm_data.state_bits = fsm_data.state_table.size(); } else if (encoding == "binary") { - fsm_data.state_bits = ceil(log2(fsm_data.state_table.size())); + int new_num_state_bits = ceil(log2(fsm_data.state_table.size())); + if (fsm_data.state_bits == new_num_state_bits) { + log(" existing encoding is already a packed binary encoding.\n"); + return; + } + fsm_data.state_bits = new_num_state_bits; } else log_error("FSM encoding `%s' is not supported!\n", encoding.c_str()); From eb571cba6a8a2a53b179578d07798517addac7c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 15:12:39 +0200 Subject: [PATCH 654/750] Replaced $__alu CO/CS outputs with full-width CO output --- techlibs/common/techmap.v | 60 ++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 1486b801..452b64b8 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -251,19 +251,18 @@ endmodule // ALU Infrastructure // -------------------------------------------------------- -module \$__alu_ripple (A, B, CI, X, Y, CO, CS); +module \$__alu_ripple (A, B, CI, X, Y, CO); parameter WIDTH = 1; input [WIDTH-1:0] A, B; output [WIDTH-1:0] X, Y; input CI; - output CO, CS; + output [WIDTH-1:0] CO; wire [WIDTH:0] carry; assign carry[0] = CI; - assign CO = carry[WIDTH]; - assign CS = carry[WIDTH-1]; + assign CO = carry[WIDTH:1]; genvar i; generate @@ -291,7 +290,7 @@ module \$__lcu (P, G, CI, CO); input [WIDTH-1:0] P, G; input CI; - output reg [WIDTH:0] CO; + output [WIDTH-1:0] CO; integer i, j; reg [WIDTH-1:0] p, g; @@ -326,23 +325,20 @@ module \$__lcu (P, G, CI, CO); end end - assign CO = {g, CI}; + assign CO = g; endmodule -module \$__alu_lookahead (A, B, CI, X, Y, CO, CS); +module \$__alu_lookahead (A, B, CI, X, Y, CO); parameter WIDTH = 1; input [WIDTH-1:0] A, B; output [WIDTH-1:0] X, Y; input CI; - output CO, CS; + output [WIDTH-1:0] CO; wire [WIDTH-1:0] P, G; - wire [WIDTH:0] C; - - assign CO = C[WIDTH]; - assign CS = C[WIDTH-1]; + wire [WIDTH:0] carry; genvar i; generate @@ -354,15 +350,16 @@ module \$__alu_lookahead (A, B, CI, X, Y, CO, CS); \$_XOR_ gate2 ( .A(a), .B(b), .Y(p) ); \$_XOR_ gate3 ( .A(p), .B(c), .Y(y) ); - assign a = A[i], b = B[i], c = C[i]; + assign a = A[i], b = B[i], c = carry[i]; assign P[i] = p, G[i] = g, X[i] = p, Y[i] = y; end endgenerate - \$__lcu #(.WIDTH(WIDTH)) lcu (.P(P), .G(G), .CI(CI), .CO(C)); + \$__lcu #(.WIDTH(WIDTH)) lcu (.P(P), .G(G), .CI(CI), .CO(CO)); + assign carry = {CO, CI}; endmodule -module \$__alu (A, B, CI, BI, X, Y, CO, CS); +module \$__alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -375,19 +372,19 @@ module \$__alu (A, B, CI, BI, X, Y, CO, CS); // carry in, sub, carry out, carry sign input CI, BI; - output CO, CS; + output [Y_WIDTH-1:0] CO; wire [Y_WIDTH-1:0] A_buf, B_buf; \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); `ifdef ALU_RIPPLE - \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO), .CS(CS)); + \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO)); `else if (Y_WIDTH <= 4) begin - \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO), .CS(CS)); + \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO)); end else begin - \$__alu_lookahead #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO), .CS(CS)); + \$__alu_lookahead #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO)); end `endif endmodule @@ -397,7 +394,7 @@ endmodule // ALU Cell Types: Compare, Add, Subtract // -------------------------------------------------------- -`define ALU_COMMONS(_width, _ci, _bi) """ +`define ALU_COMMONS(_width, _sub) """ parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -410,8 +407,8 @@ endmodule input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; - wire alu_co, alu_cs; - wire [WIDTH-1:0] alu_x, alu_y; + wire [WIDTH-1:0] alu_x, alu_y, alu_co; + wire [WIDTH:0] carry = {alu_co, |_sub}; \$__alu #( .A_SIGNED(A_SIGNED), @@ -422,41 +419,40 @@ endmodule ) alu ( .A(A), .B(B), - .CI(_ci), - .BI(_bi), + .CI(|_sub), + .BI(|_sub), .X(alu_x), .Y(alu_y), - .CO(alu_co), - .CS(alu_cs) + .CO(alu_co) ); wire cf, of, zf, sf; - assign cf = !alu_co; - assign of = alu_co ^ alu_cs; + assign cf = !carry[WIDTH]; + assign of = carry[WIDTH] ^ carry[WIDTH-1]; assign sf = alu_y[WIDTH-1]; """ module \$lt (A, B, Y); wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1, 1) + `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1) assign Y = A_SIGNED && B_SIGNED ? of != sf : cf; endmodule module \$le (A, B, Y); wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1, 1) + `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1) assign Y = &alu_x || (A_SIGNED && B_SIGNED ? of != sf : cf); endmodule module \$add (A, B, Y); wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(Y_WIDTH, 0, 0) + `ALU_COMMONS(Y_WIDTH, 0) assign Y = alu_y; endmodule module \$sub (A, B, Y); wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(Y_WIDTH, 1, 1) + `ALU_COMMONS(Y_WIDTH, 1) assign Y = alu_y; endmodule From 66763fad4e3f93b11fbc72acd94174a56084ad17 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 17:39:08 +0200 Subject: [PATCH 655/750] Using worker class in memory_map --- passes/memory/memory_map.cc | 491 ++++++++++++++++++------------------ 1 file changed, 248 insertions(+), 243 deletions(-) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 8dc66f2c..87899467 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -23,283 +23,289 @@ #include #include -static std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "") +struct MemoryMapWorker { - std::stringstream sstr; - sstr << "$memory" << name.str() << token1; - - if (i >= 0) - sstr << "[" << i << "]"; + RTLIL::Design *design; + RTLIL::Module *module; - sstr << token2; + std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "") + { + std::stringstream sstr; + sstr << "$memory" << name.str() << token1; + + if (i >= 0) + sstr << "[" << i << "]"; - if (j >= 0) - sstr << "[" << j << "]"; + sstr << token2; - sstr << token3; + if (j >= 0) + sstr << "[" << j << "]"; - if (k >= 0) - sstr << "[" << k << "]"; + sstr << token3; - sstr << token4 << "$" << (autoidx++); - return sstr.str(); -} + if (k >= 0) + sstr << "[" << k << "]"; -static void handle_cell(RTLIL::Module *module, RTLIL::Cell *cell) -{ - std::set static_ports; - std::map static_cells_map; - int mem_size = cell->parameters["\\SIZE"].as_int(); - int mem_width = cell->parameters["\\WIDTH"].as_int(); - int mem_offset = cell->parameters["\\OFFSET"].as_int(); - int mem_abits = cell->parameters["\\ABITS"].as_int(); - - // delete unused memory cell - if (cell->parameters["\\RD_PORTS"].as_int() == 0 && cell->parameters["\\WR_PORTS"].as_int() == 0) { - module->remove(cell); - return; + sstr << token4 << "$" << (autoidx++); + return sstr.str(); } - // all write ports must share the same clock - RTLIL::SigSpec clocks = cell->getPort("\\WR_CLK"); - RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"]; - RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"]; - RTLIL::SigSpec refclock; - RTLIL::State refclock_pol = RTLIL::State::Sx; - for (int i = 0; i < clocks.size(); i++) { - RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(i * mem_width, mem_width); - if (wr_en.is_fully_const() && !wr_en.as_bool()) { - static_ports.insert(i); - continue; + void handle_cell(RTLIL::Cell *cell) + { + std::set static_ports; + std::map static_cells_map; + int mem_size = cell->parameters["\\SIZE"].as_int(); + int mem_width = cell->parameters["\\WIDTH"].as_int(); + int mem_offset = cell->parameters["\\OFFSET"].as_int(); + int mem_abits = cell->parameters["\\ABITS"].as_int(); + + // delete unused memory cell + if (cell->parameters["\\RD_PORTS"].as_int() == 0 && cell->parameters["\\WR_PORTS"].as_int() == 0) { + module->remove(cell); + return; } - if (clocks_en.bits[i] != RTLIL::State::S1) { - RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(i*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(i*mem_width, mem_width); - if (wr_addr.is_fully_const()) { - // FIXME: Actually we should check for wr_en.is_fully_const() also and - // create a $adff cell with this ports wr_en input as reset pin when wr_en - // is not a simple static 1. - static_cells_map[wr_addr.as_int()] = wr_data; + + // all write ports must share the same clock + RTLIL::SigSpec clocks = cell->getPort("\\WR_CLK"); + RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"]; + RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"]; + RTLIL::SigSpec refclock; + RTLIL::State refclock_pol = RTLIL::State::Sx; + for (int i = 0; i < clocks.size(); i++) { + RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(i * mem_width, mem_width); + if (wr_en.is_fully_const() && !wr_en.as_bool()) { static_ports.insert(i); continue; } - log("Not mapping memory cell %s in module %s (write port %d has no clock).\n", - cell->name.c_str(), module->name.c_str(), i); - return; - } - if (refclock.size() == 0) { - refclock = clocks.extract(i, 1); - refclock_pol = clocks_pol.bits[i]; - } - if (clocks.extract(i, 1) != refclock || clocks_pol.bits[i] != refclock_pol) { - log("Not mapping memory cell %s in module %s (write clock %d is incompatible with other clocks).\n", - cell->name.c_str(), module->name.c_str(), i); - return; - } - } - - log("Mapping memory cell %s in module %s:\n", cell->name.c_str(), module->name.c_str()); - - std::vector data_reg_in; - std::vector data_reg_out; - - int count_static = 0; - - for (int i = 0; i < mem_size; i++) - { - if (static_cells_map.count(i) > 0) - { - data_reg_in.push_back(RTLIL::SigSpec(RTLIL::State::Sz, mem_width)); - data_reg_out.push_back(static_cells_map[i]); - count_static++; - } - else - { - RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), "$dff"); - c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; - if (clocks_pol.bits.size() > 0) { - c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]); - c->setPort("\\CLK", clocks.extract(0, 1)); - } else { - c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1); - c->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::S0)); + if (clocks_en.bits[i] != RTLIL::State::S1) { + RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(i*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(i*mem_width, mem_width); + if (wr_addr.is_fully_const()) { + // FIXME: Actually we should check for wr_en.is_fully_const() also and + // create a $adff cell with this ports wr_en input as reset pin when wr_en + // is not a simple static 1. + static_cells_map[wr_addr.as_int()] = wr_data; + static_ports.insert(i); + continue; + } + log("Not mapping memory cell %s in module %s (write port %d has no clock).\n", + cell->name.c_str(), module->name.c_str(), i); + return; + } + if (refclock.size() == 0) { + refclock = clocks.extract(i, 1); + refclock_pol = clocks_pol.bits[i]; + } + if (clocks.extract(i, 1) != refclock || clocks_pol.bits[i] != refclock_pol) { + log("Not mapping memory cell %s in module %s (write clock %d is incompatible with other clocks).\n", + cell->name.c_str(), module->name.c_str(), i); + return; } - - RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width); - data_reg_in.push_back(RTLIL::SigSpec(w_in)); - c->setPort("\\D", data_reg_in.back()); - - std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); - if (module->wires_.count(w_out_name) > 0) - w_out_name = genid(cell->name, "", i, "$q"); - - RTLIL::Wire *w_out = module->addWire(w_out_name, mem_width); - w_out->start_offset = mem_offset; - - data_reg_out.push_back(RTLIL::SigSpec(w_out)); - c->setPort("\\Q", data_reg_out.back()); } - } - log(" created %d $dff cells and %d static cells of width %d.\n", mem_size-count_static, count_static, mem_width); + log("Mapping memory cell %s in module %s:\n", cell->name.c_str(), module->name.c_str()); - int count_dff = 0, count_mux = 0, count_wrmux = 0; + std::vector data_reg_in; + std::vector data_reg_out; - for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++) - { - RTLIL::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits); + int count_static = 0; - std::vector rd_signals; - rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width)); - - if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1) + for (int i = 0; i < mem_size; i++) { - if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1) + if (static_cells_map.count(i) > 0) { - RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); - c->parameters["\\WIDTH"] = RTLIL::Const(mem_abits); - c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1)); - c->setPort("\\D", rd_addr); - count_dff++; - - RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits); - - c->setPort("\\Q", RTLIL::SigSpec(w)); - rd_addr = RTLIL::SigSpec(w); + data_reg_in.push_back(RTLIL::SigSpec(RTLIL::State::Sz, mem_width)); + data_reg_out.push_back(static_cells_map[i]); + count_static++; } else { - RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); + RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), "$dff"); c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; - c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); - c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1)); - c->setPort("\\Q", rd_signals.back()); - count_dff++; - - RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width); - - rd_signals.clear(); - rd_signals.push_back(RTLIL::SigSpec(w)); - c->setPort("\\D", rd_signals.back()); - } - } - - for (int j = 0; j < mem_abits; j++) - { - std::vector next_rd_signals; - - for (size_t k = 0; k < rd_signals.size(); k++) - { - RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux"); - c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; - c->setPort("\\Y", rd_signals[k]); - c->setPort("\\S", rd_addr.extract(mem_abits-j-1, 1)); - count_mux++; - - c->setPort("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width)); - c->setPort("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width)); - - next_rd_signals.push_back(c->getPort("\\A")); - next_rd_signals.push_back(c->getPort("\\B")); - } - - next_rd_signals.swap(rd_signals); - } - - for (int j = 0; j < mem_size; j++) - module->connect(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); - } - - log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); - - for (int i = 0; i < mem_size; i++) - { - if (static_cells_map.count(i) > 0) - continue; - - RTLIL::SigSpec sig = data_reg_out[i]; - - for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++) - { - RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits); - RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width); - RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width); - - RTLIL::Cell *c = module->addCell(genid(cell->name, "$wreq", i, "", j), "$eq"); - c->parameters["\\A_SIGNED"] = RTLIL::Const(0); - c->parameters["\\B_SIGNED"] = RTLIL::Const(0); - c->parameters["\\A_WIDTH"] = cell->parameters["\\ABITS"]; - c->parameters["\\B_WIDTH"] = cell->parameters["\\ABITS"]; - c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->setPort("\\A", RTLIL::SigSpec(i, mem_abits)); - c->setPort("\\B", wr_addr); - count_wrmux++; - - RTLIL::Wire *w_seladdr = module->addWire(genid(cell->name, "$wreq", i, "", j, "$y")); - c->setPort("\\Y", w_seladdr); - - int wr_offset = 0; - while (wr_offset < wr_en.size()) - { - int wr_width = 1; - RTLIL::SigSpec wr_bit = wr_en.extract(wr_offset, 1); - - while (wr_offset + wr_width < wr_en.size()) { - RTLIL::SigSpec next_wr_bit = wr_en.extract(wr_offset + wr_width, 1); - if (next_wr_bit != wr_bit) - break; - wr_width++; + if (clocks_pol.bits.size() > 0) { + c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]); + c->setPort("\\CLK", clocks.extract(0, 1)); + } else { + c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1); + c->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::S0)); } - RTLIL::Wire *w = w_seladdr; + RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width); + data_reg_in.push_back(RTLIL::SigSpec(w_in)); + c->setPort("\\D", data_reg_in.back()); - if (wr_bit != RTLIL::SigSpec(1, 1)) + std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i); + if (module->wires_.count(w_out_name) > 0) + w_out_name = genid(cell->name, "", i, "$q"); + + RTLIL::Wire *w_out = module->addWire(w_out_name, mem_width); + w_out->start_offset = mem_offset; + + data_reg_out.push_back(RTLIL::SigSpec(w_out)); + c->setPort("\\Q", data_reg_out.back()); + } + } + + log(" created %d $dff cells and %d static cells of width %d.\n", mem_size-count_static, count_static, mem_width); + + int count_dff = 0, count_mux = 0, count_wrmux = 0; + + for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++) + { + RTLIL::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits); + + std::vector rd_signals; + rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width)); + + if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1) + { + if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1) { - c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); - c->parameters["\\A_SIGNED"] = RTLIL::Const(0); - c->parameters["\\B_SIGNED"] = RTLIL::Const(0); - c->parameters["\\A_WIDTH"] = RTLIL::Const(1); - c->parameters["\\B_WIDTH"] = RTLIL::Const(1); - c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->setPort("\\A", w); - c->setPort("\\B", wr_bit); + RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); + c->parameters["\\WIDTH"] = RTLIL::Const(mem_abits); + c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); + c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1)); + c->setPort("\\D", rd_addr); + count_dff++; - w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y")); - c->setPort("\\Y", RTLIL::SigSpec(w)); + RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits); + + c->setPort("\\Q", RTLIL::SigSpec(w)); + rd_addr = RTLIL::SigSpec(w); + } + else + { + RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdreg", i), "$dff"); + c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; + c->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]); + c->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1)); + c->setPort("\\Q", rd_signals.back()); + count_dff++; + + RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width); + + rd_signals.clear(); + rd_signals.push_back(RTLIL::SigSpec(w)); + c->setPort("\\D", rd_signals.back()); + } + } + + for (int j = 0; j < mem_abits; j++) + { + std::vector next_rd_signals; + + for (size_t k = 0; k < rd_signals.size(); k++) + { + RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux"); + c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"]; + c->setPort("\\Y", rd_signals[k]); + c->setPort("\\S", rd_addr.extract(mem_abits-j-1, 1)); + count_mux++; + + c->setPort("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width)); + c->setPort("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width)); + + next_rd_signals.push_back(c->getPort("\\A")); + next_rd_signals.push_back(c->getPort("\\B")); } - c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); - c->parameters["\\WIDTH"] = wr_width; - c->setPort("\\A", sig.extract(wr_offset, wr_width)); - c->setPort("\\B", wr_data.extract(wr_offset, wr_width)); - c->setPort("\\S", RTLIL::SigSpec(w)); - - w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); - c->setPort("\\Y", w); - - sig.replace(wr_offset, w); - wr_offset += wr_width; + next_rd_signals.swap(rd_signals); } + + for (int j = 0; j < mem_size; j++) + module->connect(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); } - module->connect(RTLIL::SigSig(data_reg_in[i], sig)); + log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); + + for (int i = 0; i < mem_size; i++) + { + if (static_cells_map.count(i) > 0) + continue; + + RTLIL::SigSpec sig = data_reg_out[i]; + + for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++) + { + RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits); + RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width); + RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width); + + RTLIL::Cell *c = module->addCell(genid(cell->name, "$wreq", i, "", j), "$eq"); + c->parameters["\\A_SIGNED"] = RTLIL::Const(0); + c->parameters["\\B_SIGNED"] = RTLIL::Const(0); + c->parameters["\\A_WIDTH"] = cell->parameters["\\ABITS"]; + c->parameters["\\B_WIDTH"] = cell->parameters["\\ABITS"]; + c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); + c->setPort("\\A", RTLIL::SigSpec(i, mem_abits)); + c->setPort("\\B", wr_addr); + count_wrmux++; + + RTLIL::Wire *w_seladdr = module->addWire(genid(cell->name, "$wreq", i, "", j, "$y")); + c->setPort("\\Y", w_seladdr); + + int wr_offset = 0; + while (wr_offset < wr_en.size()) + { + int wr_width = 1; + RTLIL::SigSpec wr_bit = wr_en.extract(wr_offset, 1); + + while (wr_offset + wr_width < wr_en.size()) { + RTLIL::SigSpec next_wr_bit = wr_en.extract(wr_offset + wr_width, 1); + if (next_wr_bit != wr_bit) + break; + wr_width++; + } + + RTLIL::Wire *w = w_seladdr; + + if (wr_bit != RTLIL::SigSpec(1, 1)) + { + c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); + c->parameters["\\A_SIGNED"] = RTLIL::Const(0); + c->parameters["\\B_SIGNED"] = RTLIL::Const(0); + c->parameters["\\A_WIDTH"] = RTLIL::Const(1); + c->parameters["\\B_WIDTH"] = RTLIL::Const(1); + c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); + c->setPort("\\A", w); + c->setPort("\\B", wr_bit); + + w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y")); + c->setPort("\\Y", RTLIL::SigSpec(w)); + } + + c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); + c->parameters["\\WIDTH"] = wr_width; + c->setPort("\\A", sig.extract(wr_offset, wr_width)); + c->setPort("\\B", wr_data.extract(wr_offset, wr_width)); + c->setPort("\\S", RTLIL::SigSpec(w)); + + w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width); + c->setPort("\\Y", w); + + sig.replace(wr_offset, w); + wr_offset += wr_width; + } + } + + module->connect(RTLIL::SigSig(data_reg_in[i], sig)); + } + + log(" write interface: %d blocks of $eq, $and and $mux cells.\n", count_wrmux); + + module->remove(cell); } - log(" write interface: %d blocks of $eq, $and and $mux cells.\n", count_wrmux); - - module->remove(cell); -} - -static void handle_module(RTLIL::Design *design, RTLIL::Module *module) -{ - std::vector cells; - for (auto &it : module->cells_) - if (it.second->type == "$mem" && design->selected(module, it.second)) - cells.push_back(it.second); - for (auto cell : cells) - handle_cell(module, cell); -} + MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module) + { + std::vector cells; + for (auto cell : module->selected_cells()) + if (cell->type == "$mem" && design->selected(module, cell)) + cells.push_back(cell); + for (auto cell : cells) + handle_cell(cell); + } +}; struct MemoryMapPass : public Pass { MemoryMapPass() : Pass("memory_map", "translate multiport memories to basic cells") { } @@ -316,9 +322,8 @@ struct MemoryMapPass : public Pass { virtual void execute(std::vector args, RTLIL::Design *design) { log_header("Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops).\n"); extra_args(args, 1, design); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - handle_module(design, mod_it.second); + for (auto mod : design->selected_modules()) + MemoryMapWorker(design, mod); } } MemoryMapPass; From dfbd7dd15a1520ce0c01d2722aaacbf7b7be71fa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:17:22 +0200 Subject: [PATCH 656/750] Fixed module->addPmux() --- kernel/rtlil.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index df4d8b09..7ba6911a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1309,7 +1309,6 @@ DEF_METHOD(LogicOr, 1, "$logic_or") RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y) { \ RTLIL::Cell *cell = addCell(name, _type); \ cell->parameters["\\WIDTH"] = sig_a.size(); \ - cell->parameters["\\WIDTH"] = sig_b.size(); \ if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \ cell->setPort("\\A", sig_a); \ cell->setPort("\\B", sig_b); \ From 6ff46323a30d710a9518cffb8c2ae9a5621b7bfc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:18:15 +0200 Subject: [PATCH 657/750] Improved write address decoder generation memory_map --- passes/memory/memory_map.cc | 44 +++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 87899467..eecb6f35 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -28,6 +28,8 @@ struct MemoryMapWorker RTLIL::Design *design; RTLIL::Module *module; + std::map, RTLIL::SigBit> decoder_cache; + std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "") { std::stringstream sstr; @@ -50,6 +52,27 @@ struct MemoryMapWorker return sstr.str(); } + RTLIL::Wire *addr_decode(RTLIL::SigSpec addr_sig, RTLIL::SigSpec addr_val) + { + std::pair key(addr_sig, addr_val); + log_assert(SIZE(addr_sig) == SIZE(addr_val)); + + if (decoder_cache.count(key) == 0) { + if (SIZE(addr_sig) < 2) { + decoder_cache[key] = module->Eq(NEW_ID, addr_sig, addr_val); + } else { + int split_at = SIZE(addr_sig) / 2; + RTLIL::SigBit left_eq = addr_decode(addr_sig.extract(0, split_at), addr_val.extract(0, split_at)); + RTLIL::SigBit right_eq = addr_decode(addr_sig.extract(split_at, SIZE(addr_sig) - split_at), addr_val.extract(split_at, SIZE(addr_val) - split_at)); + decoder_cache[key] = module->And(NEW_ID, left_eq, right_eq); + } + } + + RTLIL::SigBit bit = decoder_cache.at(key); + log_assert(bit.wire != nullptr && SIZE(bit.wire) == 1); + return bit.wire; + } + void handle_cell(RTLIL::Cell *cell) { std::set static_ports; @@ -230,19 +253,7 @@ struct MemoryMapWorker RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits); RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width); RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width); - - RTLIL::Cell *c = module->addCell(genid(cell->name, "$wreq", i, "", j), "$eq"); - c->parameters["\\A_SIGNED"] = RTLIL::Const(0); - c->parameters["\\B_SIGNED"] = RTLIL::Const(0); - c->parameters["\\A_WIDTH"] = cell->parameters["\\ABITS"]; - c->parameters["\\B_WIDTH"] = cell->parameters["\\ABITS"]; - c->parameters["\\Y_WIDTH"] = RTLIL::Const(1); - c->setPort("\\A", RTLIL::SigSpec(i, mem_abits)); - c->setPort("\\B", wr_addr); - count_wrmux++; - - RTLIL::Wire *w_seladdr = module->addWire(genid(cell->name, "$wreq", i, "", j, "$y")); - c->setPort("\\Y", w_seladdr); + RTLIL::Wire *w_seladdr = addr_decode(wr_addr, RTLIL::SigSpec(i, mem_abits)); int wr_offset = 0; while (wr_offset < wr_en.size()) @@ -261,7 +272,7 @@ struct MemoryMapWorker if (wr_bit != RTLIL::SigSpec(1, 1)) { - c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); + RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and"); c->parameters["\\A_SIGNED"] = RTLIL::Const(0); c->parameters["\\B_SIGNED"] = RTLIL::Const(0); c->parameters["\\A_WIDTH"] = RTLIL::Const(1); @@ -274,7 +285,7 @@ struct MemoryMapWorker c->setPort("\\Y", RTLIL::SigSpec(w)); } - c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); + RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux"); c->parameters["\\WIDTH"] = wr_width; c->setPort("\\A", sig.extract(wr_offset, wr_width)); c->setPort("\\B", wr_data.extract(wr_offset, wr_width)); @@ -285,13 +296,14 @@ struct MemoryMapWorker sig.replace(wr_offset, w); wr_offset += wr_width; + count_wrmux++; } } module->connect(RTLIL::SigSig(data_reg_in[i], sig)); } - log(" write interface: %d blocks of $eq, $and and $mux cells.\n", count_wrmux); + log(" write interface: %d write mux blocks.\n", count_wrmux); module->remove(cell); } From 88db09255baa92facbe2736937ef113dc1503e9b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:34:07 +0200 Subject: [PATCH 658/750] Added autotest -e (do not use -noexpr on write_verilog) --- tests/asicworld/run-test.sh | 2 +- tests/hana/run-test.sh | 2 +- tests/tools/autotest.sh | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/asicworld/run-test.sh b/tests/asicworld/run-test.sh index 2477181a..24983f1a 100755 --- a/tests/asicworld/run-test.sh +++ b/tests/asicworld/run-test.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec ${MAKE:-make} -f ../tools/autotest.mk *.v +exec ${MAKE:-make} -f ../tools/autotest.mk EXTRA_FLAGS="-e" *.v diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh index d719c46b..fb766eec 100755 --- a/tests/hana/run-test.sh +++ b/tests/hana/run-test.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec ${MAKE:-make} -f ../tools/autotest.mk EXTRA_FLAGS="-l hana_vlib.v -n 300" test_*.v +exec ${MAKE:-make} -f ../tools/autotest.mk EXTRA_FLAGS="-l hana_vlib.v -n 300 -e" test_*.v diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 9ae1c155..5003280e 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -19,7 +19,7 @@ if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdat ( set -ex; gcc -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1 fi -while getopts xmGl:wkjvrf:s:p:n: opt; do +while getopts xmGl:wkjvref:s:p:n: opt; do case "$opt" in x) use_xsim=true ;; @@ -39,6 +39,8 @@ while getopts xmGl:wkjvrf:s:p:n: opt; do verbose=true ;; r) backend_opts="$backend_opts -norename" ;; + e) + backend_opts="$( echo " $backend_opts " | sed 's, -noexpr ,,; s,^ ,,; s, $,,;'; )" ;; f) frontend="$OPTARG" ;; s) @@ -49,7 +51,7 @@ while getopts xmGl:wkjvrf:s:p:n: opt; do n) autotb_opts="$autotb_opts -n $OPTARG" ;; *) - echo "Usage: $0 [-x|-m] [-w] [-k] [-j] [-v] [-r] [-l libs] [-f frontend] [-s script] [-p cmdstring] verilog-files\n" >&2 + echo "Usage: $0 [-x|-m] [-w] [-k] [-j] [-v] [-r] [-e] [-l libs] [-f frontend] [-s script] [-p cmdstring] verilog-files\n" >&2 exit 1 esac done From 4724d94fbce587b39cd7343dc8de3b859311f55c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:59:05 +0200 Subject: [PATCH 659/750] Added $alu cell type --- kernel/celltypes.h | 2 ++ kernel/rtlil.cc | 14 ++++++++++++ manual/CHAPTER_CellLib.tex | 4 ++++ techlibs/common/simlib.v | 45 ++++++++++++++++++++++++++++++++++++++ techlibs/common/techmap.v | 5 ++--- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 515da25c..c1bb1d03 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -108,6 +108,8 @@ struct CellTypes for (auto type : std::vector({"$mux", "$pmux"})) setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); + setup_type("$alu", {"\\A", "\\B", "\\CI", "\\BI"}, {"\\X", "\\Y", "\\CO"}, true); + setup_type("$assert", {"\\A", "\\EN"}, std::set(), true); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7ba6911a..96b651d8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -557,6 +557,20 @@ namespace { return; } + if (cell->type == "$alu") { + param_bool("\\A_SIGNED"); + param_bool("\\B_SIGNED"); + port("\\A", param("\\A_WIDTH")); + port("\\B", param("\\B_WIDTH")); + port("\\CI", 1); + port("\\BI", 1); + port("\\X", param("\\Y_WIDTH")); + port("\\Y", param("\\Y_WIDTH")); + port("\\CO", param("\\Y_WIDTH")); + check_expected(); + return; + } + if (cell->type == "$logic_not") { param_bool("\\A_SIGNED"); port("\\A", param("\\A_WIDTH")); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 3eb2f946..82473f6a 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -430,6 +430,10 @@ Add information about {\tt \$assert} cells. Add information about {\tt \$slice} and {\tt \$concat} cells. \end{fixme} +\begin{fixme} +Add information about {\tt \$alu} cells. +\end{fixme} + \begin{fixme} Add information about {\tt \$\_NAND\_}, {\tt \$\_NOR\_}, {\tt \$\_XNOR\_}, {\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, and {\tt \$\_OAI4\_} cells. \end{fixme} diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 8c0a54e4..09ffa9a6 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -467,6 +467,51 @@ endmodule // -------------------------------------------------------- +module \$alu (A, B, CI, BI, X, Y, CO); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] X, Y; + +input CI, BI; +output [Y_WIDTH-1:0] CO; + +wire [Y_WIDTH-1:0] AA, BB; + +generate + if (A_SIGNED && B_SIGNED) begin:BLOCK1 + assign AA = $signed(A), BB = BI ? ~$signed(B) : $signed(B); + end else begin:BLOCK2 + assign AA = $unsigned(A), BB = BI ? ~$unsigned(B) : $unsigned(B); + end +endgenerate + +assign X = AA ^ BB; +assign Y = AA + BB + CI; + +function get_carry; + input a, b, c; + get_carry = (a&b) | (a&c) | (b&c); +endfunction + +genvar i; +generate + assign CO[0] = get_carry(AA[0], BB[0], CI); + for (i = 1; i < Y_WIDTH; i = i+1) begin:BLOCK3 + assign CO[i] = get_carry(AA[i], BB[i], CO[i-1]); + end +endgenerate + +endmodule + +// -------------------------------------------------------- + module \$lt (A, B, Y); parameter A_SIGNED = 0; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 452b64b8..d6b24945 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -359,7 +359,7 @@ module \$__alu_lookahead (A, B, CI, X, Y, CO); assign carry = {CO, CI}; endmodule -module \$__alu (A, B, CI, BI, X, Y, CO); +module \$alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -370,7 +370,6 @@ module \$__alu (A, B, CI, BI, X, Y, CO); input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] X, Y; - // carry in, sub, carry out, carry sign input CI, BI; output [Y_WIDTH-1:0] CO; @@ -410,7 +409,7 @@ endmodule wire [WIDTH-1:0] alu_x, alu_y, alu_co; wire [WIDTH:0] carry = {alu_co, |_sub}; - \$__alu #( + \$alu #( .A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH), From 2a1b08aeb34b7d5f2df1a43c9ef1f99abacb9cae Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 19:37:12 +0200 Subject: [PATCH 660/750] Added design->scratchpad --- kernel/rtlil.cc | 61 +++++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 11 +++++++ passes/opt/opt.cc | 11 +++---- passes/opt/opt_clean.cc | 7 ++--- passes/opt/opt_const.cc | 20 ++----------- passes/opt/opt_muxtree.cc | 4 +-- passes/opt/opt_reduce.cc | 6 ++-- passes/opt/opt_rmdff.cc | 5 ++-- passes/opt/opt_share.cc | 4 +-- passes/opt/opt_status.h | 26 ----------------- 10 files changed, 91 insertions(+), 64 deletions(-) delete mode 100644 passes/opt/opt_status.h diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 96b651d8..72eced91 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -273,6 +273,67 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) return module; } +void RTLIL::Design::scratchpad_unset(std::string varname) +{ + scratchpad.erase(varname); +} + +void RTLIL::Design::scratchpad_set_int(std::string varname, int value) +{ + scratchpad[varname] = stringf("%d", value); +} + +void RTLIL::Design::scratchpad_set_bool(std::string varname, bool value) +{ + scratchpad[varname] = value ? "true" : "false"; +} + +void RTLIL::Design::scratchpad_set_string(std::string varname, std::string value) +{ + scratchpad[varname] = value; +} + +int RTLIL::Design::scratchpad_get_int(std::string varname, int default_value) const +{ + if (scratchpad.count(varname) == 0) + return default_value; + + std::string str = scratchpad.at(varname); + + if (str == "0" || str == "false") + return 0; + + if (str == "1" || str == "true") + return 1; + + char *endptr = nullptr; + long int parsed_value = strtol(str.c_str(), &endptr, 10); + return *endptr ? default_value : parsed_value; +} + +bool RTLIL::Design::scratchpad_get_bool(std::string varname, bool default_value) const +{ + if (scratchpad.count(varname) == 0) + return default_value; + + std::string str = scratchpad.at(varname); + + if (str == "0" || str == "false") + return false; + + if (str == "1" || str == "true") + return true; + + return default_value; +} + +std::string RTLIL::Design::scratchpad_get_string(std::string varname, std::string default_value) const +{ + if (scratchpad.count(varname) == 0) + return default_value; + return scratchpad.at(varname); +} + void RTLIL::Design::remove(RTLIL::Module *module) { for (auto mon : monitors) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d5887357..e35c3c68 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -486,6 +486,7 @@ struct RTLIL::Monitor struct RTLIL::Design { std::set monitors; + std::map scratchpad; int refcount_modules_; std::map modules_; @@ -508,6 +509,16 @@ struct RTLIL::Design RTLIL::Module *addModule(RTLIL::IdString name); void remove(RTLIL::Module *module); + void scratchpad_unset(std::string varname); + + void scratchpad_set_int(std::string varname, int value); + void scratchpad_set_bool(std::string varname, bool value); + void scratchpad_set_string(std::string varname, std::string value); + + int scratchpad_get_int(std::string varname, int default_value = 0) const; + bool scratchpad_get_bool(std::string varname, bool default_value = false) const; + std::string scratchpad_get_string(std::string varname, std::string default_value = std::string()) const; + void check(); void optimize(); diff --git a/passes/opt/opt.cc b/passes/opt/opt.cc index b6d36f0e..b20521d1 100644 --- a/passes/opt/opt.cc +++ b/passes/opt/opt.cc @@ -17,14 +17,11 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/log.h" #include #include -bool OPT_DID_SOMETHING; - struct OptPass : public Pass { OptPass() : Pass("opt", "perform simple optimizations") { } virtual void help() @@ -113,9 +110,9 @@ struct OptPass : public Pass { while (1) { Pass::call(design, "opt_const" + opt_const_args); Pass::call(design, "opt_share"); - OPT_DID_SOMETHING = false; + design->scratchpad_unset("opt.did_something"); Pass::call(design, "opt_rmdff"); - if (OPT_DID_SOMETHING == false) + if (design->scratchpad_get_bool("opt.did_something") == false) break; Pass::call(design, "opt_clean" + opt_clean_args); log_header("Rerunning OPT passes. (Removed registers in this run.)\n"); @@ -127,14 +124,14 @@ struct OptPass : public Pass { Pass::call(design, "opt_const" + opt_const_args); Pass::call(design, "opt_share -nomux"); while (1) { - OPT_DID_SOMETHING = false; + design->scratchpad_unset("opt.did_something"); Pass::call(design, "opt_muxtree"); Pass::call(design, "opt_reduce" + opt_reduce_args); Pass::call(design, "opt_share"); Pass::call(design, "opt_rmdff"); Pass::call(design, "opt_clean" + opt_clean_args); Pass::call(design, "opt_const" + opt_const_args); - if (OPT_DID_SOMETHING == false) + if (design->scratchpad_get_bool("opt.did_something") == false) break; log_header("Rerunning OPT passes. (Maybe there is more to do..)\n"); } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index d47e4513..cc4fe4cc 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -17,7 +17,6 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" @@ -88,7 +87,7 @@ static void rmunused_module_cells(RTLIL::Module *module, bool verbose) for (auto cell : unused) { if (verbose) log(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str()); - OPT_DID_SOMETHING = true; + module->design->scratchpad_set_bool("opt.did_something", true); module->remove(cell); count_rm_cells++; } @@ -406,9 +405,9 @@ struct CleanPass : public Pass { for (auto &mod_it : design->modules_) { if (design->selected_whole_module(mod_it.first) && mod_it.second->processes.size() == 0) do { - OPT_DID_SOMETHING = false; + design->scratchpad_unset("opt.did_something"); rmunused_module(mod_it.second, purge_mode, false); - } while (OPT_DID_SOMETHING); + } while (design->scratchpad_get_bool("opt.did_something")); } if (count_rm_cells > 0 || count_rm_wires > 0) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index a602cf5f..ad696187 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -17,7 +17,6 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" @@ -67,7 +66,7 @@ static void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) log("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c)); module->connect(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width))); - OPT_DID_SOMETHING = true; + did_something = true; } } @@ -83,7 +82,6 @@ static void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell assign_map.add(Y, out_val); module->connect(Y, out_val); module->remove(cell); - OPT_DID_SOMETHING = true; did_something = true; } @@ -186,7 +184,6 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com cover_list("opt.opt_const.fine.group", "$not", "$pos", "$bu0", "$and", "$or", "$xor", "$xnor", cell->type.str()); module->remove(cell); - OPT_DID_SOMETHING = true; did_something = true; return true; } @@ -266,7 +263,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); cell->setPort("\\A", sig_a = new_a); cell->parameters.at("\\A_WIDTH") = 1; - OPT_DID_SOMETHING = true; did_something = true; } } @@ -293,7 +289,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a)); cell->setPort("\\A", sig_a = new_a); cell->parameters.at("\\A_WIDTH") = 1; - OPT_DID_SOMETHING = true; did_something = true; } } @@ -320,7 +315,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b)); cell->setPort("\\B", sig_b = new_b); cell->parameters.at("\\B_WIDTH") = 1; - OPT_DID_SOMETHING = true; did_something = true; } } @@ -385,7 +379,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->setPort("\\A", cell->getPort("\\B")); cell->setPort("\\B", tmp); cell->setPort("\\S", invert_map.at(assign_map(cell->getPort("\\S")))); - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -551,7 +544,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); cell->unsetPort("\\B"); - OPT_DID_SOMETHING = true; did_something = true; } goto next_cell; @@ -588,7 +580,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo module->connect(cell->getPort("\\Y"), sig_y); module->remove(cell); - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -661,7 +652,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->parameters.erase("\\B_SIGNED"); cell->check(); - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -689,7 +679,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$not"; } else cell->type = "$_NOT_"; - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -709,7 +698,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$and"; } else cell->type = "$_AND_"; - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -729,7 +717,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$or"; } else cell->type = "$_OR_"; - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -781,7 +768,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->type = "$mux"; cell->parameters.erase("\\S_WIDTH"); } - OPT_DID_SOMETHING = true; did_something = true; } } @@ -895,7 +881,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); module->remove(cell); - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -928,7 +913,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->setPort("\\B", new_b); cell->check(); - OPT_DID_SOMETHING = true; did_something = true; goto next_cell; } @@ -1018,6 +1002,8 @@ struct OptConstPass : public Pass { do { did_something = false; replace_const_cells(design, module, false, mux_undef, mux_bool, do_fine, keepdc); + if (did_something) + design->scratchpad_set_bool("opt.did_something", true); } while (did_something); replace_const_cells(design, module, true, mux_undef, mux_bool, do_fine, keepdc); } while (did_something); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index daa06381..2c5dcf66 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -17,7 +17,6 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" @@ -179,7 +178,6 @@ struct OptMuxtreeWorker } else { log(" dead port %zd/%zd on %s %s.\n", port_idx+1, mi.ports.size(), mi.cell->type.c_str(), mi.cell->name.c_str()); - OPT_DID_SOMETHING = true; removed_count++; } } @@ -434,6 +432,8 @@ struct OptMuxtreePass : public Pass { total_count += worker.removed_count; } } + if (total_count) + design->scratchpad_set_bool("opt.did_something", true); log("Removed %d multiplexer ports.\n", total_count); } } OptMuxtreePass; diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index e2b4243d..e9e2bb39 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -17,7 +17,6 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" @@ -88,7 +87,6 @@ struct OptReduceWorker if (new_sig_a != sig_a || sig_a.size() != cell->getPort("\\A").size()) { log(" New input vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_a)); did_something = true; - OPT_DID_SOMETHING = true; total_count++; } @@ -141,7 +139,6 @@ struct OptReduceWorker if (new_sig_s.size() != sig_s.size()) { log(" New ctrl vector for %s cell %s: %s\n", cell->type.c_str(), cell->name.c_str(), log_signal(new_sig_s)); did_something = true; - OPT_DID_SOMETHING = true; total_count++; } @@ -238,7 +235,6 @@ struct OptReduceWorker module->check(); did_something = true; - OPT_DID_SOMETHING = true; total_count++; } } @@ -376,6 +372,8 @@ struct OptReducePass : public Pass { } while (1); } + if (total_count) + design->scratchpad_set_bool("opt.did_something", true); log("Performed a total of %d changes.\n", total_count); } } OptReducePass; diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index bbf94d3b..48f406f6 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -17,7 +17,6 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" @@ -142,7 +141,6 @@ static bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) delete_dff: log("Removing %s (%s) from module %s.\n", dff->name.c_str(), dff->type.c_str(), mod->name.c_str()); - OPT_DID_SOMETHING = true; mod->remove(dff); return true; } @@ -210,6 +208,9 @@ struct OptRmdffPass : public Pass { assign_map.clear(); mux_drivers.clear(); + + if (total_count) + design->scratchpad_set_bool("opt.did_something", true); log("Replaced %d DFF cells.\n", total_count); } } OptRmdffPass; diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index e9a5e7fd..66f5e630 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -17,7 +17,6 @@ * */ -#include "opt_status.h" #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" @@ -265,7 +264,6 @@ struct OptShareWorker } log(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); module->remove(cell); - OPT_DID_SOMETHING = true; total_count++; } else { sharemap[cell] = cell; @@ -315,6 +313,8 @@ struct OptSharePass : public Pass { total_count += worker.total_count; } + if (total_count) + design->scratchpad_set_bool("opt.did_something", true); log("Removed a total of %d cells.\n", total_count); } } OptSharePass; diff --git a/passes/opt/opt_status.h b/passes/opt/opt_status.h deleted file mode 100644 index 3d12baa7..00000000 --- a/passes/opt/opt_status.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - * - */ - -#ifndef OPT_STATUS_H -#define OPT_STATUS_H - -extern bool OPT_DID_SOMETHING; - -#endif - From 8649b57b6f4c3a4322acaf73f5c02d5119629c1e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 17:06:36 +0200 Subject: [PATCH 661/750] Added $lut support in test_cell, techmap, satgen --- kernel/rtlil.cc | 10 +++++--- kernel/satgen.h | 51 ++++++++++++++++++++++++++++++++++++++- passes/tests/test_cell.cc | 33 +++++++++++++++++++++---- techlibs/common/techmap.v | 17 +++++++++++++ 4 files changed, 102 insertions(+), 9 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 72eced91..403bb6d2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1768,8 +1768,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") return; - if (type == "$mux" || type == "$pmux") - { + if (type == "$mux" || type == "$pmux") { parameters["\\WIDTH"] = SIZE(connections_["\\Y"]); if (type == "$pmux") parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]); @@ -1777,7 +1776,12 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) return; } - bool signedness_ab = type != "$slice" && type != "$concat"; + if (type == "$lut") { + parameters["\\WIDTH"] = SIZE(connections_["\\A"]); + return; + } + + bool signedness_ab = !type.in("$slice", "$concat"); if (connections_.count("\\A")) { if (signedness_ab) { diff --git a/kernel/satgen.h b/kernel/satgen.h index c02900a6..5d1c11c9 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -841,6 +841,56 @@ struct SatGen return true; } + if (cell->type == "$lut") + { + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + + std::vector lut; + for (auto bit : cell->getParam("\\LUT").bits) + lut.push_back(bit == RTLIL::S1 ? ez->TRUE : ez->FALSE); + while (SIZE(lut) < (1 << SIZE(a))) + lut.push_back(ez->FALSE); + lut.resize(1 << SIZE(a)); + + if (model_undef) + { + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector t(lut), u(SIZE(t), ez->FALSE); + + for (int i = SIZE(a)-1; i >= 0; i--) + { + std::vector t0(t.begin(), t.begin() + SIZE(t)/2); + std::vector t1(t.begin() + SIZE(t)/2, t.end()); + + std::vector u0(u.begin(), u.begin() + SIZE(u)/2); + std::vector u1(u.begin() + SIZE(u)/2, u.end()); + + t = ez->vec_ite(a[i], t1, t0); + u = ez->vec_ite(undef_a[i], ez->vec_or(ez->vec_xor(t0, t1), ez->vec_or(u0, u1)), ez->vec_ite(a[i], u1, u0)); + } + + log_assert(SIZE(t) == 1); + log_assert(SIZE(u) == 1); + undefGating(y, t, u); + ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort("\\Y"), timestep), u)); + } + else + { + std::vector t = lut; + for (int i = SIZE(a)-1; i >= 0; i--) + { + std::vector t0(t.begin(), t.begin() + SIZE(t)/2); + std::vector t1(t.begin() + SIZE(t)/2, t.end()); + t = ez->vec_ite(a[i], t1, t0); + } + + log_assert(SIZE(t) == 1); + ez->assume(ez->vec_eq(y, t)); + } + return true; + } + if (cell->type == "$slice") { RTLIL::SigSpec a = cell->getPort("\\A"); @@ -903,4 +953,3 @@ struct SatGen }; #endif - diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index a4b8be0c..4a2af304 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -30,20 +30,41 @@ static uint32_t xorshift32(uint32_t limit) { return xorshift32_state % limit; } -static void create_gold_module(RTLIL::Design *design, std::string cell_type, std::string cell_type_flags) +static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags) { RTLIL::Module *module = design->addModule("\\gold"); RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); + RTLIL::Wire *wire; + + if (cell_type == "$lut") + { + int width = 1 + xorshift32(6); + + wire = module->addWire("\\A"); + wire->width = width; + wire->port_input = true; + cell->setPort("\\A", wire); + + wire = module->addWire("\\Y"); + wire->port_output = true; + cell->setPort("\\Y", wire); + + RTLIL::SigSpec config; + for (int i = 0; i < (1 << width); i++) + config.append(xorshift32(2) ? RTLIL::S1 : RTLIL::S0); + + cell->setParam("\\LUT", config.as_const()); + } if (cell_type_flags.find('A') != std::string::npos) { - RTLIL::Wire *wire = module->addWire("\\A"); + wire = module->addWire("\\A"); wire->width = 1 + xorshift32(8); wire->port_input = true; cell->setPort("\\A", wire); } if (cell_type_flags.find('B') != std::string::npos) { - RTLIL::Wire *wire = module->addWire("\\B"); + wire = module->addWire("\\B"); if (cell_type_flags.find('h') != std::string::npos) wire->width = 1 + xorshift32(6); else @@ -67,7 +88,7 @@ static void create_gold_module(RTLIL::Design *design, std::string cell_type, std } if (cell_type_flags.find('Y') != std::string::npos) { - RTLIL::Wire *wire = module->addWire("\\Y"); + wire = module->addWire("\\Y"); wire->width = 1 + xorshift32(8); wire->port_output = true; cell->setPort("\\Y", wire); @@ -188,9 +209,11 @@ struct TestCellPass : public Pass { // cell_types["$pmux"] = "A"; // cell_types["$slice"] = "A"; // cell_types["$concat"] = "A"; - // cell_types["$lut"] = "A"; // cell_types["$assert"] = "A"; + cell_types["$lut"] = "*"; + // cell_types["$alu"] = "*"; + for (; argidx < SIZE(args); argidx++) { if (args[argidx].rfind("-", 0) == 0) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index d6b24945..c0645267 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -841,3 +841,20 @@ module \$pmux (A, B, S, Y); assign Y = |S ? Y_B : A; endmodule + +// -------------------------------------------------------- +// LUTs +// -------------------------------------------------------- + +`ifndef NOLUT +module \$lut (A, Y); + parameter WIDTH = 1; + parameter LUT = 0; + + input [WIDTH-1:0] A; + output Y; + + assign Y = LUT[A]; +endmodule +`endif + From 0b6769af3f7578dfb31c801014413174bd230208 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 17:07:07 +0200 Subject: [PATCH 662/750] Typo fixes in cell->*Param() API --- kernel/rtlil.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e35c3c68..90760040 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -848,10 +848,10 @@ public: const std::map &connections() const; // access cell parameters - bool hasParam(RTLIL::IdString portname) const; - void unsetParam(RTLIL::IdString portname); - void setParam(RTLIL::IdString portname, RTLIL::Const value); - const RTLIL::Const &getParam(RTLIL::IdString portname) const; + bool hasParam(RTLIL::IdString paramname) const; + void unsetParam(RTLIL::IdString paramname); + void setParam(RTLIL::IdString paramname, RTLIL::Const value); + const RTLIL::Const &getParam(RTLIL::IdString paramname) const; void check(); void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false); From a1c7d4a8e24c14eae7f1f7e383f18b25a190875b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 17:42:38 +0200 Subject: [PATCH 663/750] Added eval model for $lut cells --- kernel/celltypes.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index c1bb1d03..4a8be04d 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -297,6 +297,32 @@ struct CellTypes return ret; } + if (cell->type == "$lut") + { + int width = cell->parameters.at("\\WIDTH").as_int(); + + std::vector t = cell->parameters.at("\\LUT").bits; + while (SIZE(t) < (1 << width)) + t.push_back(RTLIL::S0); + t.resize(1 << width); + + for (int i = width-1; i >= 0; i--) { + RTLIL::State sel = arg1.bits.at(i); + std::vector new_t; + if (sel == RTLIL::S0) + new_t = std::vector(t.begin(), t.begin() + SIZE(t)/2); + else if (sel == RTLIL::S1) + new_t = std::vector(t.begin() + SIZE(t)/2, t.end()); + else + for (int j = 0; j < SIZE(t)/2; j++) + new_t.push_back(t[j] == t[j + SIZE(t)/2] ? t[j] : RTLIL::Sx); + t.swap(new_t); + } + + log_assert(SIZE(t) == 1); + return t; + } + bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1; From be44157c0f07c3bcca2363b5ce95a71fe7ad6dd9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 18:07:48 +0200 Subject: [PATCH 664/750] Added RTLIL::Const::size() --- kernel/rtlil.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 90760040..93532938 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -440,6 +440,8 @@ struct RTLIL::Const std::string as_string() const; std::string decode_string() const; + + inline int size() const { return bits.size(); } }; struct RTLIL::Selection From 83ec3fa2045cac1f29ea4bfb2c8c052c31b083a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 18:08:26 +0200 Subject: [PATCH 665/750] Fixed return size of const_*() eval functions --- kernel/calc.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/calc.cc b/kernel/calc.cc index 29717aad..7bfdb895 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -35,6 +35,8 @@ static void extend(RTLIL::Const &arg, int width, bool is_signed) while (int(arg.bits.size()) < width) arg.bits.push_back(padding); + + arg.bits.resize(width); } static void extend_u0(RTLIL::Const &arg, int width, bool is_signed) @@ -46,6 +48,8 @@ static void extend_u0(RTLIL::Const &arg, int width, bool is_signed) while (int(arg.bits.size()) < width) arg.bits.push_back(padding); + + arg.bits.resize(width); } static BigInteger const2big(const RTLIL::Const &val, bool as_signed, int &undef_bit_pos) @@ -312,7 +316,7 @@ RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2 RTLIL::Const RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; - extend_u0(arg1_ext, result_len, signed1); + extend_u0(arg1_ext, std::max(result_len, SIZE(arg1)), signed1); return const_shift_worker(arg1_ext, arg2, false, +1, result_len); } From e3664066d5684af444c5a1edb02b9e7543cba38d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 18:08:42 +0200 Subject: [PATCH 666/750] Added eval testing to test_cell --- passes/tests/test_cell.cc | 88 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 4a2af304..d9554bcf 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -19,6 +19,7 @@ */ #include "kernel/yosys.h" +#include "kernel/consteval.h" #include static uint32_t xorshift32_state = 123456789; @@ -99,6 +100,92 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->check(); } +static void run_eval_test(RTLIL::Design *design) +{ + RTLIL::Module *gold_mod = design->module("\\gold"); + RTLIL::Module *gate_mod = design->module("\\gate"); + ConstEval gold_ce(gold_mod), gate_ce(gate_mod); + + log("Eval testing: "); + + for (int i = 0; i < 64; i++) + { + log("."); + gold_ce.clear(); + gate_ce.clear(); + + for (auto port : gold_mod->ports) + { + RTLIL::Wire *gold_wire = gold_mod->wire(port); + RTLIL::Wire *gate_wire = gate_mod->wire(port); + + log_assert(gold_wire != nullptr); + log_assert(gate_wire != nullptr); + log_assert(gold_wire->port_input == gate_wire->port_input); + log_assert(SIZE(gold_wire) == SIZE(gate_wire)); + + if (!gold_wire->port_input) + continue; + + RTLIL::Const in_value; + for (int i = 0; i < SIZE(gold_wire); i++) + in_value.bits.push_back(xorshift32(2) ? RTLIL::S1 : RTLIL::S0); + + if (xorshift32(4) == 0) { + int inv_chance = 1 + xorshift32(8); + for (int i = 0; i < SIZE(gold_wire); i++) + if (xorshift32(inv_chance) == 0) + in_value.bits[i] = RTLIL::Sx; + } + + // log("%s: %s\n", log_id(gold_wire), log_signal(in_value)); + + gold_ce.set(gold_wire, in_value); + gate_ce.set(gate_wire, in_value); + } + + for (auto port : gold_mod->ports) + { + RTLIL::Wire *gold_wire = gold_mod->wire(port); + RTLIL::Wire *gate_wire = gate_mod->wire(port); + + log_assert(gold_wire != nullptr); + log_assert(gate_wire != nullptr); + log_assert(gold_wire->port_output == gate_wire->port_output); + log_assert(SIZE(gold_wire) == SIZE(gate_wire)); + + if (!gold_wire->port_output) + continue; + + RTLIL::SigSpec gold_outval(gold_wire); + RTLIL::SigSpec gate_outval(gate_wire); + + if (!gold_ce.eval(gold_outval)) + log_error("Failed to eval %s in gold module.\n", log_id(gold_wire)); + + if (!gate_ce.eval(gate_outval)) + log_error("Failed to eval %s in gate module.\n", log_id(gate_wire)); + + bool gold_gate_mismatch = false; + for (int i = 0; i < SIZE(gold_wire); i++) { + if (gold_outval[i] == RTLIL::Sx) + continue; + if (gold_outval[i] == gate_outval[i]) + continue; + gold_gate_mismatch = true; + break; + } + + if (gold_gate_mismatch) + log_error("Mismatch in output %s: gold:%s != gate:%s\n", log_id(gate_wire), log_signal(gold_outval), log_signal(gate_outval)); + + // log("%s: %s\n", log_id(gold_wire), log_signal(gold_outval)); + } + } + + log(" ok.\n"); +} + struct TestCellPass : public Pass { TestCellPass() : Pass("test_cell", "automatically test the implementation of a cell type") { } virtual void help() @@ -265,6 +352,7 @@ struct TestCellPass : public Pass { Pass::call(design, stringf("copy gold gate; %s gate; opt gate", techmap_cmd.c_str())); Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter; dump gold"); Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); + run_eval_test(design); delete design; } } From e07698818dfe3c8e5f87b13090c7e70d22189e2a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 11:36:02 +0200 Subject: [PATCH 667/750] Using std::vector instead of RTLIL::Const for RTLIL::SigChunk::data --- backends/btor/btor.cc | 3 +- kernel/rtlil.cc | 62 +++++++++++++++++++---------------------- kernel/rtlil.h | 6 ++-- passes/opt/opt_share.cc | 2 +- 4 files changed, 35 insertions(+), 38 deletions(-) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 9b770518..3482faa7 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -294,7 +294,8 @@ struct BtorDumper int l=-1; if(chunk->wire == NULL) { - l=dump_const(&chunk->data, chunk->width, chunk->offset); + RTLIL::Const data_const(chunk->data); + l=dump_const(&data_const, chunk->width, chunk->offset); } else { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 403bb6d2..f237f57e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1819,8 +1819,8 @@ RTLIL::SigChunk::SigChunk() RTLIL::SigChunk::SigChunk(const RTLIL::Const &value) { wire = NULL; - data = value; - width = data.bits.size(); + data = value.bits; + width = SIZE(data); offset = 0; } @@ -1843,24 +1843,24 @@ RTLIL::SigChunk::SigChunk(RTLIL::Wire *wire, int offset, int width) RTLIL::SigChunk::SigChunk(const std::string &str) { wire = NULL; - data = RTLIL::Const(str); - width = data.bits.size(); + data = RTLIL::Const(str).bits; + width = SIZE(data); offset = 0; } RTLIL::SigChunk::SigChunk(int val, int width) { wire = NULL; - data = RTLIL::Const(val, width); - this->width = data.bits.size(); + data = RTLIL::Const(val, width).bits; + this->width = SIZE(data); offset = 0; } RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width) { wire = NULL; - data = RTLIL::Const(bit, width); - this->width = data.bits.size(); + data = RTLIL::Const(bit, width).bits; + this->width = SIZE(data); offset = 0; } @@ -1869,7 +1869,7 @@ RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit) wire = bit.wire; offset = 0; if (wire == NULL) - data = RTLIL::Const(bit.data); + data = RTLIL::Const(bit.data).bits; else offset = bit.offset; width = 1; @@ -1884,7 +1884,7 @@ RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const ret.width = length; } else { for (int i = 0; i < length; i++) - ret.data.bits.push_back(data.bits[offset+i]); + ret.data.push_back(data[offset+i]); ret.width = length; } return ret; @@ -1905,16 +1905,12 @@ bool RTLIL::SigChunk::operator <(const RTLIL::SigChunk &other) const if (width != other.width) return width < other.width; - return data.bits < other.data.bits; + return data < other.data; } bool RTLIL::SigChunk::operator ==(const RTLIL::SigChunk &other) const { - if (wire != other.wire || width != other.width || offset != other.offset) - return false; - if (data.bits != other.data.bits) - return false; - return true; + return wire == other.wire && width == other.width && offset == other.offset && data == other.data; } bool RTLIL::SigChunk::operator !=(const RTLIL::SigChunk &other) const @@ -1964,7 +1960,7 @@ const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other) for (auto &bit : other.bits_) { if (last && bit.wire == last->wire) { if (bit.wire == NULL) { - last->data.bits.push_back(bit.data); + last->data.push_back(bit.data); last->width++; continue; } else if (last_end_offset == bit.offset) { @@ -2120,7 +2116,7 @@ void RTLIL::SigSpec::pack() const for (auto &bit : old_bits) { if (last && bit.wire == last->wire) { if (bit.wire == NULL) { - last->data.bits.push_back(bit.data); + last->data.push_back(bit.data); last->width++; continue; } else if (last_end_offset == bit.offset) { @@ -2171,7 +2167,7 @@ void RTLIL::SigSpec::hash() const that->hash_ = 5381; for (auto &c : that->chunks_) if (c.wire == NULL) { - for (auto &v : c.data.bits) + for (auto &v : c.data) DJB2(that->hash_, v); } else { DJB2(that->hash_, c.wire->name.index_); @@ -2444,8 +2440,8 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal) { auto &my_last_c = chunks_.back(); if (my_last_c.wire == NULL && other_c.wire == NULL) { - auto &this_data = my_last_c.data.bits; - auto &other_data = other_c.data.bits; + auto &this_data = my_last_c.data; + auto &other_data = other_c.data; this_data.insert(this_data.end(), other_data.begin(), other_data.end()); my_last_c.width += other_c.width; } else @@ -2472,7 +2468,7 @@ void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit) else if (bit.wire == NULL) if (chunks_.back().wire == NULL) { - chunks_.back().data.bits.push_back(bit.data); + chunks_.back().data.push_back(bit.data); chunks_.back().width++; } else chunks_.push_back(bit); @@ -2558,14 +2554,14 @@ void RTLIL::SigSpec::check() const if (i > 0) log_assert(chunks_[i-1].wire != NULL); log_assert(chunk.offset == 0); - log_assert(chunk.data.bits.size() == (size_t)chunk.width); + log_assert(chunk.data.size() == (size_t)chunk.width); } else { if (i > 0 && chunks_[i-1].wire == chunk.wire) log_assert(chunk.offset != chunks_[i-1].offset + chunks_[i-1].width); log_assert(chunk.offset >= 0); log_assert(chunk.width >= 0); log_assert(chunk.offset + chunk.width <= chunk.wire->width); - log_assert(chunk.data.bits.size() == 0); + log_assert(chunk.data.size() == 0); } w += chunk.width; } @@ -2681,8 +2677,8 @@ bool RTLIL::SigSpec::is_fully_def() const for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; - for (size_t i = 0; i < it->data.bits.size(); i++) - if (it->data.bits[i] != RTLIL::State::S0 && it->data.bits[i] != RTLIL::State::S1) + for (size_t i = 0; i < it->data.size(); i++) + if (it->data[i] != RTLIL::State::S0 && it->data[i] != RTLIL::State::S1) return false; } return true; @@ -2696,8 +2692,8 @@ bool RTLIL::SigSpec::is_fully_undef() const for (auto it = chunks_.begin(); it != chunks_.end(); it++) { if (it->width > 0 && it->wire != NULL) return false; - for (size_t i = 0; i < it->data.bits.size(); i++) - if (it->data.bits[i] != RTLIL::State::Sx && it->data.bits[i] != RTLIL::State::Sz) + for (size_t i = 0; i < it->data.size(); i++) + if (it->data[i] != RTLIL::State::Sx && it->data[i] != RTLIL::State::Sz) return false; } return true; @@ -2710,8 +2706,8 @@ bool RTLIL::SigSpec::has_marked_bits() const pack(); for (auto it = chunks_.begin(); it != chunks_.end(); it++) if (it->width > 0 && it->wire == NULL) { - for (size_t i = 0; i < it->data.bits.size(); i++) - if (it->data.bits[i] == RTLIL::State::Sm) + for (size_t i = 0; i < it->data.size(); i++) + if (it->data[i] == RTLIL::State::Sm) return true; } return false; @@ -2724,7 +2720,7 @@ bool RTLIL::SigSpec::as_bool() const pack(); log_assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) - return chunks_[0].data.as_bool(); + return RTLIL::Const(chunks_[0].data).as_bool(); return false; } @@ -2735,7 +2731,7 @@ int RTLIL::SigSpec::as_int(bool is_signed) const pack(); log_assert(is_fully_const() && SIZE(chunks_) <= 1); if (width_) - return chunks_[0].data.as_int(is_signed); + return RTLIL::Const(chunks_[0].data).as_int(is_signed); return 0; } @@ -2751,7 +2747,7 @@ std::string RTLIL::SigSpec::as_string() const for (int j = 0; j < chunk.width; j++) str += "?"; else - str += chunk.data.as_string(); + str += RTLIL::Const(chunk.data).as_string(); } return str; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 93532938..b8733c4e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -864,7 +864,7 @@ public: struct RTLIL::SigChunk { RTLIL::Wire *wire; - RTLIL::Const data; // only used if wire == NULL, LSB at index 0 + std::vector data; // only used if wire == NULL, LSB at index 0 int width, offset; SigChunk(); @@ -895,8 +895,8 @@ struct RTLIL::SigBit SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); } SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire); } - SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data.bits[0]; } - SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data.bits[index]; } + SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } + SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; } SigBit(const RTLIL::SigSpec &sig); bool operator <(const RTLIL::SigBit &other) const { diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 66f5e630..4b76a5a2 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -101,7 +101,7 @@ struct OptShareWorker int_to_hash_string(chunk.offset) + " " + int_to_hash_string(chunk.width) + "}"; else - hash_string += chunk.data.as_string(); + hash_string += RTLIL::Const(chunk.data).as_string(); } hash_string += "\n"; } From d5148f2e013a7c0e4cced043d0a01a7fb0d3f069 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 11:45:26 +0200 Subject: [PATCH 668/750] Moved "share" and "wreduce" to passes/opt/ --- passes/cmds/Makefile.inc | 1 - passes/opt/Makefile.inc | 2 ++ passes/{sat => opt}/share.cc | 0 passes/{cmds => opt}/wreduce.cc | 0 passes/sat/Makefile.inc | 1 - 5 files changed, 2 insertions(+), 2 deletions(-) rename passes/{sat => opt}/share.cc (100%) rename passes/{cmds => opt}/wreduce.cc (100%) diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 4cf61150..eba61d1d 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -20,6 +20,5 @@ OBJS += passes/cmds/write_file.o OBJS += passes/cmds/connwrappers.o OBJS += passes/cmds/cover.o OBJS += passes/cmds/trace.o -OBJS += passes/cmds/wreduce.o OBJS += passes/cmds/plugin.o diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index 9dfb32c8..3a8d27f9 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -6,4 +6,6 @@ OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_rmdff.o OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_const.o +OBJS += passes/opt/share.o +OBJS += passes/opt/wreduce.o diff --git a/passes/sat/share.cc b/passes/opt/share.cc similarity index 100% rename from passes/sat/share.cc rename to passes/opt/share.cc diff --git a/passes/cmds/wreduce.cc b/passes/opt/wreduce.cc similarity index 100% rename from passes/cmds/wreduce.cc rename to passes/opt/wreduce.cc diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index 9aa80642..4fa6bf0d 100644 --- a/passes/sat/Makefile.inc +++ b/passes/sat/Makefile.inc @@ -4,5 +4,4 @@ OBJS += passes/sat/freduce.o OBJS += passes/sat/eval.o OBJS += passes/sat/miter.o OBJS += passes/sat/expose.o -OBJS += passes/sat/share.o From 27a1bfbec62c8467cd14a8d44cf4a8a046576b91 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 11:45:47 +0200 Subject: [PATCH 669/750] Fixes in old SAT example.ys --- passes/sat/example.ys | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/passes/sat/example.ys b/passes/sat/example.ys index 11f5b924..cc72faac 100644 --- a/passes/sat/example.ys +++ b/passes/sat/example.ys @@ -1,13 +1,14 @@ read_verilog example.v proc; opt_clean +echo on sat -set y 1'b1 example001 sat -set y 1'b1 example002 sat -set y_sshl 8'hf0 -set y_sshr 8'hf0 -set sh 4'd3 example003 -sat -set y 1'b1 example004 +sat -set y 1'b1 -ignore_unknown_cells example004 sat -show rst,counter -set-at 3 y 1'b1 -seq 4 example004 -sat -prove y 1'b0 -show rst,counter,y example004 -sat -prove y 1'b0 -show rst,counter,y -set-at 1 rst 1'b1 -seq 1 example004 +sat -prove y 1'b0 -show rst,counter,y -ignore_unknown_cells example004 +sat -prove y 1'b0 -tempinduct -show rst,counter,y -set-at 1 rst 1'b1 -seq 1 example004 From 826fdb34d8933120f022e92bfec508588b9191de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 15:36:29 +0200 Subject: [PATCH 670/750] Added "techmap -autoproc" --- passes/techmap/techmap.cc | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 660f1b38..43a94d97 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -70,6 +70,7 @@ struct TechmapWorker bool assert_mode; bool flatten_mode; bool recursive_mode; + bool autoproc_mode; TechmapWorker() { @@ -77,6 +78,7 @@ struct TechmapWorker assert_mode = false; flatten_mode = false; recursive_mode = false; + autoproc_mode = false; } std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose) @@ -148,7 +150,11 @@ struct TechmapWorker log("Technology map yielded processes:\n"); for (auto &it : tpl->processes) log(" %s",RTLIL::id2cstr(it.first)); - log_error("Technology map yielded processes -> this is not supported.\n"); + if (autoproc_mode) { + Pass::call_on_module(tpl->design, tpl, "proc"); + log_assert(SIZE(tpl->processes) == 0); + } else + log_error("Technology map yielded processes -> this is not supported (use -autoproc to run 'proc' automatically).\n"); } std::string orig_cell_name; @@ -726,6 +732,9 @@ struct TechmapPass : public Pass { log(" depth-first algorithm. both methods should yield equivialent results,\n"); log(" but may differ in performance.\n"); log("\n"); + log(" -autoproc\n"); + log(" Automatically call \"proc\" on implementations that contain processes.\n"); + log("\n"); log(" -assert\n"); log(" this option will cause techmap to exit with an error if it can't map\n"); log(" a selected cell. only cell types that end on an underscore are accepted\n"); @@ -831,7 +840,10 @@ struct TechmapPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-map" && argidx+1 < args.size()) { - map_files.push_back(args[++argidx]); + if (args[argidx+1].substr(0, 2) == "+/") + map_files.push_back(proc_share_dirname() + args[++argidx].substr(2)); + else + map_files.push_back(args[++argidx]); continue; } if (args[argidx] == "-share_map" && argidx+1 < args.size()) { @@ -862,6 +874,10 @@ struct TechmapPass : public Pass { worker.recursive_mode = true; continue; } + if (args[argidx] == "-autoproc") { + worker.autoproc_mode = true; + continue; + } break; } extra_args(args, argidx, design); From c7f81e4e49b3c2be1280cd0895170a5d89d9c444 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 15:37:21 +0200 Subject: [PATCH 671/750] Added "test_cell -simlib -v" --- passes/tests/test_cell.cc | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index d9554bcf..7f9f1f9b 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -100,17 +100,17 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->check(); } -static void run_eval_test(RTLIL::Design *design) +static void run_eval_test(RTLIL::Design *design, bool verbose) { RTLIL::Module *gold_mod = design->module("\\gold"); RTLIL::Module *gate_mod = design->module("\\gate"); ConstEval gold_ce(gold_mod), gate_ce(gate_mod); - log("Eval testing: "); + log("Eval testing:%c", verbose ? '\n' : ' '); for (int i = 0; i < 64; i++) { - log("."); + log(verbose ? "\n" : "."); gold_ce.clear(); gate_ce.clear(); @@ -138,7 +138,8 @@ static void run_eval_test(RTLIL::Design *design) in_value.bits[i] = RTLIL::Sx; } - // log("%s: %s\n", log_id(gold_wire), log_signal(in_value)); + if (verbose) + log("%s: %s\n", log_id(gold_wire), log_signal(in_value)); gold_ce.set(gold_wire, in_value); gate_ce.set(gate_wire, in_value); @@ -179,11 +180,13 @@ static void run_eval_test(RTLIL::Design *design) if (gold_gate_mismatch) log_error("Mismatch in output %s: gold:%s != gate:%s\n", log_id(gate_wire), log_signal(gold_outval), log_signal(gate_outval)); - // log("%s: %s\n", log_id(gold_wire), log_signal(gold_outval)); + if (verbose) + log("%s: %s\n", log_id(gold_wire), log_signal(gold_outval)); } } - log(" ok.\n"); + if (!verbose) + log(" ok.\n"); } struct TestCellPass : public Pass { @@ -212,6 +215,12 @@ struct TestCellPass : public Pass { log(" -map {filename}\n"); log(" pass this option to techmap.\n"); log("\n"); + log(" -simplib\n"); + log(" use \"techmap -map +/simlib.v -max_iter 2 -autoproc\"\n"); + log("\n"); + log(" -v\n"); + log(" print additional debug information to the console\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design*) { @@ -219,6 +228,7 @@ struct TestCellPass : public Pass { std::string techmap_cmd = "techmap -assert"; std::string ilang_file; xorshift32_state = 0; + bool verbose = false; int argidx; for (argidx = 1; argidx < SIZE(args); argidx++) @@ -240,6 +250,14 @@ struct TestCellPass : public Pass { num_iter = 1; continue; } + if (args[argidx] == "-simlib") { + techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc"; + continue; + } + if (args[argidx] == "-v") { + verbose = true; + continue; + } break; } @@ -350,9 +368,12 @@ struct TestCellPass : public Pass { else create_gold_module(design, cell_type, cell_types.at(cell_type)); Pass::call(design, stringf("copy gold gate; %s gate; opt gate", techmap_cmd.c_str())); - Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter; dump gold"); + Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter"); + if (verbose) + Pass::call(design, "dump gate"); + Pass::call(design, "dump gold"); Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); - run_eval_test(design); + run_eval_test(design, verbose); delete design; } } From 9923762461d2bc0822daef76bf0b58e772045bc8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 15:37:56 +0200 Subject: [PATCH 672/750] Fixed "test_cell -simlib all" --- techlibs/common/simlib.v | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 09ffa9a6..3c931c81 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -108,12 +108,13 @@ parameter Y_WIDTH = 0; input [A_WIDTH-1:0] A; output [Y_WIDTH-1:0] Y; +wire [Y_WIDTH-1:0] tmp; generate if (A_SIGNED) begin:BLOCK1 - assign Y = -$signed(A); + assign tmp = $signed(A), Y = -tmp; end else begin:BLOCK2 - assign Y = -A; + assign tmp = A, Y = -tmp; end endgenerate From bae09dca2ba4d582bf7258b6419d4268f65f1476 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 16:35:25 +0200 Subject: [PATCH 673/750] Added SAT model for $alu cells --- kernel/satgen.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index 5d1c11c9..beb03768 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -183,9 +183,9 @@ struct SatGen bool importCell(RTLIL::Cell *cell, int timestep = -1) { bool arith_undef_handled = false; - bool is_arith_compare = cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt"; + bool is_arith_compare = cell->type.in("$lt", "$le", "$ge", "$gt"); - if (model_undef && (cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod" || is_arith_compare)) + if (model_undef && (cell->type.in("$add", "$sub", "$mul", "$div", "$mod") || is_arith_compare)) { std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); @@ -891,6 +891,73 @@ struct SatGen return true; } + if (cell->type == "$alu") + { + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector x = importDefSigSpec(cell->getPort("\\X"), timestep); + std::vector ci = importDefSigSpec(cell->getPort("\\CI"), timestep); + std::vector bi = importDefSigSpec(cell->getPort("\\BI"), timestep); + std::vector co = importDefSigSpec(cell->getPort("\\CO"), timestep); + + extendSignalWidth(a, b, y, cell); + extendSignalWidth(a, b, x, cell); + extendSignalWidth(a, b, co, cell); + + std::vector def_y = model_undef ? ez->vec_var(y.size()) : y; + std::vector def_x = model_undef ? ez->vec_var(x.size()) : x; + std::vector def_co = model_undef ? ez->vec_var(co.size()) : co; + + log_assert(SIZE(y) == SIZE(x)); + log_assert(SIZE(y) == SIZE(co)); + log_assert(SIZE(ci) == 1); + log_assert(SIZE(bi) == 1); + + for (int i = 0; i < SIZE(y); i++) + { + int s1 = a.at(i), s2 = ez->XOR(b.at(i), bi.at(0)), s3 = i ? co.at(i-1) : ci.at(0); + ez->SET(def_x.at(i), ez->XOR(s1, s2)); + ez->SET(def_y.at(i), ez->XOR(def_x.at(i), s3)); + ez->SET(def_co.at(i), ez->OR(ez->AND(s1, s2), ez->AND(s1, s3), ez->AND(s2, s3))); + } + + if (model_undef) + { + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep); + std::vector undef_bi = importUndefSigSpec(cell->getPort("\\BI"), timestep); + + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); + std::vector undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep); + + extendSignalWidth(undef_a, undef_b, undef_y, cell, true); + extendSignalWidth(undef_a, undef_b, undef_x, cell, true); + extendSignalWidth(undef_a, undef_b, undef_co, cell, true); + + std::vector all_inputs_undef; + all_inputs_undef.insert(all_inputs_undef.end(), undef_a.begin(), undef_a.end()); + all_inputs_undef.insert(all_inputs_undef.end(), undef_b.begin(), undef_b.end()); + all_inputs_undef.insert(all_inputs_undef.end(), undef_ci.begin(), undef_ci.end()); + all_inputs_undef.insert(all_inputs_undef.end(), undef_bi.begin(), undef_bi.end()); + int undef_any = ez->expression(ezSAT::OpOr, all_inputs_undef); + + for (int i = 0; i < SIZE(undef_y); i++) { + ez->SET(undef_y.at(i), undef_any); + ez->SET(undef_x.at(i), ez->OR(undef_a.at(i), undef_b.at(i), undef_bi.at(0))); + ez->SET(undef_co.at(i), undef_any); + } + + undefGating(y, def_y, undef_y); + undefGating(x, def_x, undef_x); + undefGating(co, def_co, undef_co); + } + log_ping(); + return true; + } + if (cell->type == "$slice") { RTLIL::SigSpec a = cell->getPort("\\A"); From 2fcf66b91d324758eb58807592702b6844bd37ab Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 16:35:46 +0200 Subject: [PATCH 674/750] Added ConstEval model for $alu cells --- kernel/consteval.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/kernel/consteval.h b/kernel/consteval.h index d42c2b0f..fb54b72f 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -154,6 +154,62 @@ struct ConstEval else set(sig_y, y_values.front()); } + else if (cell->type == "$alu") + { + bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); + bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); + + RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); + RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); + + if (!eval(sig_a, undef, cell)) + return false; + + if (!eval(sig_b, undef, cell)) + return false; + + if (!eval(sig_ci, undef, cell)) + return false; + + if (!eval(sig_bi, undef, cell)) + return false; + + RTLIL::SigSpec sig_x = cell->getPort("\\X"); + RTLIL::SigSpec sig_co = cell->getPort("\\CO"); + + bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def()); + sig_a.extend(SIZE(sig_y), signed_a); + sig_b.extend(SIZE(sig_y), signed_b); + + bool carry = sig_ci[0] == RTLIL::S1; + bool b_inv = sig_bi[0] == RTLIL::S1; + + for (int i = 0; i < SIZE(sig_y); i++) + { + RTLIL::SigSpec x_inputs = { sig_a[i], sig_b[i], sig_bi[0] }; + + if (!x_inputs.is_fully_def()) { + set(sig_x[i], RTLIL::Sx); + } else { + bool bit_a = sig_a[i] == RTLIL::S1; + bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; + bool bit_x = bit_a != bit_b; + set(sig_x[i], bit_x ? RTLIL::S1 : RTLIL::S0); + } + + if (any_input_undef) { + set(sig_y[i], RTLIL::Sx); + set(sig_co[i], RTLIL::Sx); + } else { + bool bit_a = sig_a[i] == RTLIL::S1; + bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; + bool bit_y = (bit_a != bit_b) != carry; + carry = (bit_a && bit_b) || (bit_a && carry) || (bit_b && carry); + set(sig_y[i], bit_y ? RTLIL::S1 : RTLIL::S0); + set(sig_co[i], carry ? RTLIL::S1 : RTLIL::S0); + } + } + } else { RTLIL::SigSpec sig_c, sig_d; From 630befdf6d58ab5f7c4ca1ea77c86df7b88ee259 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 16:36:04 +0200 Subject: [PATCH 675/750] Added $alu support to test_cell --- passes/tests/test_cell.cc | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 7f9f1f9b..7c7d6b7f 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -95,6 +95,27 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->setPort("\\Y", wire); } + if (cell_type == "$alu") + { + wire = module->addWire("\\CI"); + wire->port_input = true; + cell->setPort("\\CI", wire); + + wire = module->addWire("\\BI"); + wire->port_input = true; + cell->setPort("\\BI", wire); + + wire = module->addWire("\\X"); + wire->width = SIZE(cell->getPort("\\Y")); + wire->port_output = true; + cell->setPort("\\X", wire); + + wire = module->addWire("\\CO"); + wire->width = SIZE(cell->getPort("\\Y")); + wire->port_output = true; + cell->setPort("\\CO", wire); + } + module->fixup_ports(); cell->fixup_parameters(); cell->check(); @@ -317,7 +338,7 @@ struct TestCellPass : public Pass { // cell_types["$assert"] = "A"; cell_types["$lut"] = "*"; - // cell_types["$alu"] = "*"; + cell_types["$alu"] = "ABSY"; for (; argidx < SIZE(args); argidx++) { From 9f00a0cd2d972a5fc4a75f8c1bdba723a5f66b7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 03:28:46 +0200 Subject: [PATCH 676/750] Using "xdot" instead of "yosys-svgviewer" in show command --- README | 2 +- passes/cmds/show.cc | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README b/README index 2e713ffe..2c7703a1 100644 --- a/README +++ b/README @@ -58,7 +58,7 @@ will install all prerequisites for building yosys: $ yosys_deps="git g++ clang make bison flex libreadline-dev tcl8.5-dev zlib1g-dev libqt4-dev libffi-dev - mercurial iverilog graphviz" + mercurial iverilog graphviz xdot" $ sudo apt-get install $yosys_deps There are also pre-compiled packages for Yosys on Ubuntu. Visit the Yosys diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 3468eae7..6ab0e1ba 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -751,8 +751,8 @@ struct ShowPass : public Pass { if (worker.page_counter == 0) log_cmd_error("Nothing there to show.\n"); - if (format != "dot") { - std::string cmd = stringf("dot -T%s -o '%s' '%s'", format.empty() ? "svg" : format.c_str(), out_file.c_str(), dot_file.c_str()); + if (format != "dot" && !format.empty()) { + std::string cmd = stringf("dot -T%s -o '%s' '%s'", format.c_str(), out_file.c_str(), dot_file.c_str()); log("Exec: %s\n", cmd.c_str()); if (system(cmd.c_str()) != 0) log_cmd_error("Shell command failed!\n"); @@ -765,8 +765,7 @@ struct ShowPass : public Pass { log_cmd_error("Shell command failed!\n"); } else if (format.empty()) { - std::string svgviewer = proc_self_dirname() + "yosys-svgviewer"; - std::string cmd = stringf("fuser -s '%s' || '%s' '%s' &", out_file.c_str(), svgviewer.c_str(), out_file.c_str()); + std::string cmd = stringf("fuser -s '%s' || xdot '%s' < '%s' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str()); log("Exec: %s\n", cmd.c_str()); if (system(cmd.c_str()) != 0) log_cmd_error("Shell command failed!\n"); From ee29ae2206b913fbb8cd41782001eed24c53b39d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 03:52:46 +0200 Subject: [PATCH 677/750] Removed yosys-svgviewer --- Makefile | 11 -- README | 35 +++-- libs/svgviewer/.gitignore | 6 - libs/svgviewer/files/bubbles.svg | 215 ----------------------------- libs/svgviewer/files/cubic.svg | 77 ----------- libs/svgviewer/files/spheres.svg | 72 ---------- libs/svgviewer/main.cpp | 66 --------- libs/svgviewer/mainwindow.cpp | 205 ---------------------------- libs/svgviewer/mainwindow.h | 86 ------------ libs/svgviewer/svgview.cpp | 227 ------------------------------- libs/svgviewer/svgview.h | 87 ------------ libs/svgviewer/svgviewer.desktop | 11 -- libs/svgviewer/svgviewer.pro | 33 ----- libs/svgviewer/svgviewer.qrc | 6 - 14 files changed, 17 insertions(+), 1120 deletions(-) delete mode 100644 libs/svgviewer/.gitignore delete mode 100644 libs/svgviewer/files/bubbles.svg delete mode 100644 libs/svgviewer/files/cubic.svg delete mode 100644 libs/svgviewer/files/spheres.svg delete mode 100644 libs/svgviewer/main.cpp delete mode 100644 libs/svgviewer/mainwindow.cpp delete mode 100644 libs/svgviewer/mainwindow.h delete mode 100644 libs/svgviewer/svgview.cpp delete mode 100644 libs/svgviewer/svgview.h delete mode 100644 libs/svgviewer/svgviewer.desktop delete mode 100644 libs/svgviewer/svgviewer.pro delete mode 100644 libs/svgviewer/svgviewer.qrc diff --git a/Makefile b/Makefile index 49a38726..ce4a68c5 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ CONFIG := clang # features (the more the better) ENABLE_TCL := 1 -ENABLE_QT4 := 1 ENABLE_ABC := 1 ENABLE_PLUGINS := 1 ENABLE_READLINE := 1 @@ -111,10 +110,6 @@ CXXFLAGS += -pg LDFLAGS += -pg endif -ifeq ($(ENABLE_QT4),1) -TARGETS += yosys-svgviewer -endif - ifeq ($(ENABLE_ABC),1) TARGETS += yosys-abc endif @@ -215,10 +210,6 @@ yosys-config: yosys-config.in -e 's,@BINDIR@,$(DESTDIR)/bin,;' -e 's,@DATDIR@,$(DESTDIR)/share/yosys,;' < yosys-config.in > yosys-config $(Q) chmod +x yosys-config -yosys-svgviewer: libs/svgviewer/*.h libs/svgviewer/*.cpp - $(P) cd libs/svgviewer && $(QMAKE) && $(MAKE) $(S) - $(Q) cp `find libs/svgviewer -name svgviewer -type f` yosys-svgviewer - abc/abc-$(ABCREV): $(P) ifneq ($(ABCREV),default) @@ -288,7 +279,6 @@ clean: rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) rm -f kernel/version_*.o kernel/version_*.cc abc/abc-[0-9a-f]* rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d - test ! -f libs/svgviewer/Makefile || make -C libs/svgviewer distclean clean-abc: make -C abc clean @@ -319,7 +309,6 @@ config-gcc-4.6: clean config-emcc: clean echo 'CONFIG := emcc' > Makefile.conf echo 'ENABLE_TCL := 0' >> Makefile.conf - echo 'ENABLE_QT4 := 0' >> Makefile.conf echo 'ENABLE_ABC := 0' >> Makefile.conf echo 'ENABLE_PLUGINS := 0' >> Makefile.conf echo 'ENABLE_READLINE := 0' >> Makefile.conf diff --git a/README b/README index 2c7703a1..7e8a42a8 100644 --- a/README +++ b/README @@ -50,15 +50,13 @@ Getting Started You need a C++ compiler with C++11 support (up-to-date CLANG or GCC is recommended) and some standard tools such as GNU Flex, GNU Bison, and GNU Make. -The Qt4 library is needed for the yosys SVG viewer, that is used to display -schematics, the minisat library is required for the SAT features in yosys -and TCL for the scripting functionality. The extensive test suite requires -Icarus Verilog. For example on Ubuntu Linux 12.04 LTS the following commands -will install all prerequisites for building yosys: +TCL, readline and libffi are optional (see ENABLE_* settings in Makefile). +Xdot (graphviz) is used by the "show" command in yosys to display schematics. +For example on Ubuntu Linux 14.04 LTS the following commands will install all +prerequisites for building yosys: - $ yosys_deps="git g++ clang make bison flex libreadline-dev - tcl8.5-dev zlib1g-dev libqt4-dev libffi-dev - mercurial iverilog graphviz xdot" + $ yosys_deps="build-essential clang bison flex libreadline-dev + tcl8.5-dev libffi-dev git mercurial graphviz xdot" $ sudo apt-get install $yosys_deps There are also pre-compiled packages for Yosys on Ubuntu. Visit the Yosys @@ -66,12 +64,10 @@ download page to learn more about this: http://www.clifford.at/yosys/download.html -To configure the build system to use a specific set of compiler and -build configuration, use one of +To configure the build system to use a specific compiler, use one of - $ make config-clang-debug - $ make config-gcc-debug - $ make config-release + $ make config-clang + $ make config-gcc For other compilers and build configurations it might be necessary to make some changes to the config section of the @@ -118,7 +114,7 @@ some simple optimizations: yosys> proc; opt -display design netlist using the yosys svg viewer: +display design netlist using xdot: yosys> show @@ -156,17 +152,20 @@ commands in the synthesis script: $ ./yosys -o synth.v tests/simple/fiedler-cooley.v synth.ys -The following synthesis script works reasonable for all designs: +The following very basic synthesis script should work well with all designs: # check design hierarchy hierarchy - # translate processes (always blocks) and memories (arrays) - proc; memory; opt + # translate processes (always blocks) + proc; opt # detect and optimize FSM encodings fsm; opt + # implement memories (arrays) + memory; opt + # convert to gate logic techmap; opt @@ -175,7 +174,7 @@ in the liberty file mycells.lib, the following synthesis script will synthesize for the given cell library: # the high-level stuff - hierarchy; proc; memory; opt; fsm; opt + hierarchy; proc; fsm; opt; memory; opt # mapping to internal cell library techmap; opt diff --git a/libs/svgviewer/.gitignore b/libs/svgviewer/.gitignore deleted file mode 100644 index b46f84a6..00000000 --- a/libs/svgviewer/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile -moc_mainwindow.cpp -moc_svgview.cpp -qrc_svgviewer.cpp -svgviewer -svgviewer.app diff --git a/libs/svgviewer/files/bubbles.svg b/libs/svgviewer/files/bubbles.svg deleted file mode 100644 index 51730124..00000000 --- a/libs/svgviewer/files/bubbles.svg +++ /dev/null @@ -1,215 +0,0 @@ - - - - Spheres - Semi-transparent bubbles on a colored background. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/svgviewer/files/cubic.svg b/libs/svgviewer/files/cubic.svg deleted file mode 100644 index 492bb72b..00000000 --- a/libs/svgviewer/files/cubic.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - Example cubic02 - cubic Bezier commands in path data - Picture showing examples of "C" and "S" commands, - along with annotations showing the control points - and end points - - - - - - - - - - - - M100,200 C100,100 400,100 400,200 - - - - - - - - - - M100,500 C25,400 475,400 400,500 - - - - - - - - - - M100,800 C175,700 325,700 400,800 - - - - - - - - - - M600,200 C675,100 975,100 900,200 - - - - - - - - - - M600,500 C600,350 900,650 900,500 - - - - - - - - - - - - - - - M600,800 C625,700 725,700 750,800 - S875,900 900,800 - diff --git a/libs/svgviewer/files/spheres.svg b/libs/svgviewer/files/spheres.svg deleted file mode 100644 index b23164bc..00000000 --- a/libs/svgviewer/files/spheres.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - Spheres - Gradient filled spheres with different colors. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/svgviewer/main.cpp b/libs/svgviewer/main.cpp deleted file mode 100644 index 34866f85..00000000 --- a/libs/svgviewer/main.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#ifndef QT_NO_OPENGL -#include -#endif - -#include "mainwindow.h" - -int main(int argc, char **argv) -{ - Q_INIT_RESOURCE(svgviewer); - - QApplication app(argc, argv); - - MainWindow window; - if (argc == 2) - window.openFile(argv[1]); - else - window.openFile(":/files/bubbles.svg"); -#if defined(Q_OS_SYMBIAN) - window.showMaximized(); -#else - window.show(); -#endif - return app.exec(); -} diff --git a/libs/svgviewer/mainwindow.cpp b/libs/svgviewer/mainwindow.cpp deleted file mode 100644 index 70da140e..00000000 --- a/libs/svgviewer/mainwindow.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" - -#include -#include -#include - -#include "svgview.h" - -MainWindow::MainWindow() - : QMainWindow() - , m_view(new SvgView) - , m_watcher(NULL) - , m_filehandle(NULL) -{ - QMenu *fileMenu = new QMenu(tr("&File"), this); - QAction *openAction = fileMenu->addAction(tr("&Open...")); - openAction->setShortcut(QKeySequence(tr("Ctrl+O"))); - QAction *quitAction = fileMenu->addAction(tr("E&xit")); - quitAction->setShortcuts(QKeySequence::Quit); - - menuBar()->addMenu(fileMenu); - - QMenu *viewMenu = new QMenu(tr("&View"), this); - - m_interactiveAction = viewMenu->addAction(tr("&Interactive")); - m_interactiveAction->setEnabled(false); - m_interactiveAction->setCheckable(true); - m_interactiveAction->setChecked(false); - connect(m_interactiveAction, SIGNAL(toggled(bool)), m_view, SLOT(setViewInteractive(bool))); - - m_backgroundAction = viewMenu->addAction(tr("&Background")); - m_backgroundAction->setEnabled(false); - m_backgroundAction->setCheckable(true); - m_backgroundAction->setChecked(false); - m_backgroundAction->setVisible(false); - connect(m_backgroundAction, SIGNAL(toggled(bool)), m_view, SLOT(setViewBackground(bool))); - - m_outlineAction = viewMenu->addAction(tr("&Outline")); - m_outlineAction->setEnabled(false); - m_outlineAction->setCheckable(true); - m_outlineAction->setChecked(true); - connect(m_outlineAction, SIGNAL(toggled(bool)), m_view, SLOT(setViewOutline(bool))); - - menuBar()->addMenu(viewMenu); - - QMenu *rendererMenu = new QMenu(tr("&Renderer"), this); - m_nativeAction = rendererMenu->addAction(tr("&Native")); - m_nativeAction->setCheckable(true); - m_nativeAction->setChecked(true); -#ifndef QT_NO_OPENGL - m_glAction = rendererMenu->addAction(tr("&OpenGL")); - m_glAction->setCheckable(true); -#endif - m_imageAction = rendererMenu->addAction(tr("&Image")); - m_imageAction->setCheckable(true); - -#ifndef QT_NO_OPENGL - rendererMenu->addSeparator(); - m_highQualityAntialiasingAction = rendererMenu->addAction(tr("&High Quality Antialiasing")); - m_highQualityAntialiasingAction->setEnabled(false); - m_highQualityAntialiasingAction->setCheckable(true); - m_highQualityAntialiasingAction->setChecked(false); - connect(m_highQualityAntialiasingAction, SIGNAL(toggled(bool)), m_view, SLOT(setHighQualityAntialiasing(bool))); -#endif - - QActionGroup *rendererGroup = new QActionGroup(this); - rendererGroup->addAction(m_nativeAction); -#ifndef QT_NO_OPENGL - rendererGroup->addAction(m_glAction); -#endif - rendererGroup->addAction(m_imageAction); - - menuBar()->addMenu(rendererMenu); - - connect(openAction, SIGNAL(triggered()), this, SLOT(openFile())); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(rendererGroup, SIGNAL(triggered(QAction*)), - this, SLOT(setRenderer(QAction*))); - - setCentralWidget(m_view); - setWindowTitle(tr("Yosys SVG Viewer")); -} - -void MainWindow::openFile(const QString &path, bool reload) -{ - QString fileName; - if (path.isNull()) - fileName = QFileDialog::getOpenFileName(this, tr("Open SVG File"), - m_currentPath, "SVG files (*.svg *.svgz *.svg.gz)"); - else - fileName = path; - - if (m_watcher) { - delete m_watcher; - m_watcher = NULL; - } - if (m_filehandle) { - fclose(m_filehandle); - m_filehandle = NULL; - } - - if (!fileName.isEmpty()) { - QFile file(fileName); - if (!file.exists()) { - QMessageBox::critical(this, tr("Open SVG File"), - QString("Could not open file '%1'.").arg(fileName)); - - m_interactiveAction->setEnabled(false); - m_outlineAction->setEnabled(false); - m_backgroundAction->setEnabled(false); - return; - } - - QTransform oldTransform = m_view->transform(); - m_view->openFile(file); - - if (!fileName.startsWith(":/")) - { - m_currentPath = fileName; - setWindowTitle(tr("%1 - Yosys SVG Viewer").arg(m_currentPath)); - - // just keep the file open so this process is found using 'fuser' - m_filehandle = fopen(fileName.toAscii(), "r"); - - m_watcher = new QFileSystemWatcher(this); - m_watcher->addPath(fileName); - connect(m_watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(reloadFile())); - } - - m_interactiveAction->setEnabled(true); - m_outlineAction->setEnabled(true); - m_backgroundAction->setEnabled(true); - - if (reload) - m_view->setTransform(oldTransform); - else - resize(m_view->sizeHint() + QSize(80, 80 + menuBar()->height())); - } -} - -void MainWindow::reloadFile() -{ - // give the writer ~100 ms to finish writing - usleep(100000); - openFile(m_currentPath, true); -} - -void MainWindow::setRenderer(QAction *action) -{ -#ifndef QT_NO_OPENGL - m_highQualityAntialiasingAction->setEnabled(false); -#endif - - if (action == m_nativeAction) - m_view->setRenderer(SvgView::Native); -#ifndef QT_NO_OPENGL - else if (action == m_glAction) { - m_highQualityAntialiasingAction->setEnabled(true); - m_view->setRenderer(SvgView::OpenGL); - } -#endif - else if (action == m_imageAction) { - m_view->setRenderer(SvgView::Image); - } -} diff --git a/libs/svgviewer/mainwindow.h b/libs/svgviewer/mainwindow.h deleted file mode 100644 index dfb5586d..00000000 --- a/libs/svgviewer/mainwindow.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include -#include - -class SvgView; - -QT_BEGIN_NAMESPACE -class QAction; -class QGraphicsView; -class QGraphicsScene; -class QGraphicsRectItem; -class QFileSystemWatcher; -QT_END_NAMESPACE - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - MainWindow(); - -public slots: - void openFile(const QString &path = QString(), bool reload = false); - void setRenderer(QAction *action); - void reloadFile(); - -private: - QAction *m_nativeAction; - QAction *m_glAction; - QAction *m_imageAction; - QAction *m_highQualityAntialiasingAction; - QAction *m_interactiveAction; - QAction *m_backgroundAction; - QAction *m_outlineAction; - - SvgView *m_view; - - QString m_currentPath; - QFileSystemWatcher *m_watcher; - FILE *m_filehandle; -}; - -#endif diff --git a/libs/svgviewer/svgview.cpp b/libs/svgviewer/svgview.cpp deleted file mode 100644 index 5a1a5ab2..00000000 --- a/libs/svgviewer/svgview.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "svgview.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef QT_NO_OPENGL -#include -#endif - -SvgView::SvgView(QWidget *parent) - : QGraphicsView(parent) - , m_renderer(Native) - , m_svgItem(0) - , m_webview(0) - , m_backgroundItem(0) - , m_outlineItem(0) -{ - setScene(new QGraphicsScene(this)); - setTransformationAnchor(AnchorUnderMouse); - setDragMode(ScrollHandDrag); - setViewportUpdateMode(FullViewportUpdate); - - // Prepare background check-board pattern - QPixmap tilePixmap(64, 64); - tilePixmap.fill(Qt::white); - QPainter tilePainter(&tilePixmap); - QColor color(220, 220, 220); - tilePainter.fillRect(0, 0, 32, 32, color); - tilePainter.fillRect(32, 32, 32, 32, color); - tilePainter.end(); - - setBackgroundBrush(tilePixmap); -} - -void SvgView::drawBackground(QPainter *p, const QRectF &) -{ - p->save(); - p->resetTransform(); - p->drawTiledPixmap(viewport()->rect(), backgroundBrush().texture()); - p->restore(); -} - -void SvgView::openFile(const QFile &file) -{ - if (!file.exists()) - return; - - QGraphicsScene *s = scene(); - - fn = file.fileName(); - if (fn[0] != '/') { - char cwd_buffer[4096]; - if (getcwd(cwd_buffer, 4096) != NULL) - fn = cwd_buffer + ("/" + fn); - } - - bool drawBackground = (m_backgroundItem ? m_backgroundItem->isVisible() : false); - bool drawOutline = (m_outlineItem ? m_outlineItem->isVisible() : true); - bool useWebview = (m_webview ? m_webview->isVisible() : false); - - s->clear(); - resetTransform(); - - m_svgItem = new QGraphicsSvgItem(file.fileName()); - m_svgItem->setFlags(QGraphicsItem::ItemClipsToShape); - m_svgItem->setCacheMode(QGraphicsItem::NoCache); - m_svgItem->setVisible(!useWebview); - m_svgItem->setZValue(1); - s->addItem(m_svgItem); - - if (useWebview) { - m_webview = new QGraphicsWebView(); - m_webview->load(QUrl::fromLocalFile(fn)); - m_webview->setResizesToContents(true); - m_webview->setZoomFactor(0.75); - m_webview->setVisible(useWebview); - m_webview->setZValue(1); - s->addItem(m_webview); - } else - m_webview = NULL; - - m_backgroundItem = new QGraphicsRectItem(m_svgItem->boundingRect()); - m_backgroundItem->setBrush(Qt::white); - m_backgroundItem->setPen(Qt::NoPen); - m_backgroundItem->setVisible(drawBackground); - m_backgroundItem->setZValue(0); - s->addItem(m_backgroundItem); - - m_outlineItem = new QGraphicsRectItem(m_svgItem->boundingRect()); - QPen outline(Qt::black, 2, Qt::DashLine); - outline.setCosmetic(true); - m_outlineItem->setPen(outline); - m_outlineItem->setBrush(Qt::NoBrush); - m_outlineItem->setVisible(drawOutline); - m_outlineItem->setZValue(2); - s->addItem(m_outlineItem); - - s->setSceneRect(m_outlineItem->boundingRect().adjusted(-10, -10, 10, 10)); -} - -void SvgView::setRenderer(RendererType type) -{ - m_renderer = type; - - if (m_renderer == OpenGL) { -#ifndef QT_NO_OPENGL - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); -#endif - } else { - setViewport(new QWidget); - } -} - -void SvgView::setHighQualityAntialiasing(bool highQualityAntialiasing) -{ -#ifndef QT_NO_OPENGL - setRenderHint(QPainter::HighQualityAntialiasing, highQualityAntialiasing); -#else - Q_UNUSED(highQualityAntialiasing); -#endif -} - -void SvgView::setViewInteractive(bool enable) -{ - if (!m_svgItem) - return; - if (!m_webview) { - m_webview = new QGraphicsWebView(); - m_webview->load(QUrl::fromLocalFile(fn)); - m_webview->setResizesToContents(true); - m_webview->setZoomFactor(0.75); - m_webview->setVisible(false); - m_webview->setZValue(1); - m_svgItem->scene()->addItem(m_webview); - } - m_svgItem->setVisible(!enable); - m_webview->setVisible(enable); -} - -void SvgView::setViewBackground(bool enable) -{ - if (!m_backgroundItem) - return; - - m_backgroundItem->setVisible(enable); -} - -void SvgView::setViewOutline(bool enable) -{ - if (!m_outlineItem) - return; - - m_outlineItem->setVisible(enable); -} - -void SvgView::paintEvent(QPaintEvent *event) -{ - if (m_renderer == Image) { - if (m_image.size() != viewport()->size()) { - m_image = QImage(viewport()->size(), QImage::Format_ARGB32_Premultiplied); - } - - QPainter imagePainter(&m_image); - QGraphicsView::render(&imagePainter); - imagePainter.end(); - - QPainter p(viewport()); - p.drawImage(0, 0, m_image); - - } else { - QGraphicsView::paintEvent(event); - } -} - -void SvgView::wheelEvent(QWheelEvent *event) -{ - qreal factor = qPow(1.2, event->delta() / 240.0); - scale(factor, factor); - event->accept(); -} - diff --git a/libs/svgviewer/svgview.h b/libs/svgviewer/svgview.h deleted file mode 100644 index 833bb52e..00000000 --- a/libs/svgviewer/svgview.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SVGVIEW_H -#define SVGVIEW_H - -#include -#include - -QT_BEGIN_NAMESPACE -class QWheelEvent; -class QPaintEvent; -class QFile; -QT_END_NAMESPACE - -class SvgView : public QGraphicsView -{ - Q_OBJECT - -public: - enum RendererType { Native, OpenGL, Image }; - - SvgView(QWidget *parent = 0); - - void openFile(const QFile &file); - void setRenderer(RendererType type = Native); - void drawBackground(QPainter *p, const QRectF &rect); - -public slots: - void setHighQualityAntialiasing(bool highQualityAntialiasing); - void setViewInteractive(bool enable); - void setViewBackground(bool enable); - void setViewOutline(bool enable); - -protected: - void wheelEvent(QWheelEvent *event); - void paintEvent(QPaintEvent *event); - -private: - RendererType m_renderer; - - QString fn; - QGraphicsItem *m_svgItem; - QGraphicsWebView *m_webview; - QGraphicsRectItem *m_backgroundItem; - QGraphicsRectItem *m_outlineItem; - - QImage m_image; -}; -#endif // SVGVIEW_H diff --git a/libs/svgviewer/svgviewer.desktop b/libs/svgviewer/svgviewer.desktop deleted file mode 100644 index 477ef789..00000000 --- a/libs/svgviewer/svgviewer.desktop +++ /dev/null @@ -1,11 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Version=1.0 -Type=Application -Terminal=false -Name=SVG Viewer -Exec=/opt/usr/bin/svgviewer -Icon=svgviewer -X-Window-Icon= -X-HildonDesk-ShowInToolbar=true -X-Osso-Type=application/x-executable diff --git a/libs/svgviewer/svgviewer.pro b/libs/svgviewer/svgviewer.pro deleted file mode 100644 index 488c62fd..00000000 --- a/libs/svgviewer/svgviewer.pro +++ /dev/null @@ -1,33 +0,0 @@ -HEADERS = mainwindow.h \ - svgview.h -RESOURCES = svgviewer.qrc -SOURCES = main.cpp \ - mainwindow.cpp \ - svgview.cpp -QT += webkit svg xml - -contains(QT_CONFIG, opengl): QT += opengl - -CONFIG += console - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/painting/svgviewer -sources.files = $$SOURCES $$HEADERS $$RESOURCES svgviewer.pro files -sources.path = $$[QT_INSTALL_EXAMPLES]/painting/svgviewer -INSTALLS += target sources - -wince*: { - addFiles.files = files\\*.svg - addFiles.path = "\\My Documents" - DEPLOYMENT += addFiles -} - -symbian: { - TARGET.UID3 = 0xA000A64E - include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - addFiles.files = files\\*.svg - addFiles.path = . - DEPLOYMENT += addFiles -} -maemo5: include($$QT_SOURCE_TREE/examples/maemo5pkgrules.pri) - diff --git a/libs/svgviewer/svgviewer.qrc b/libs/svgviewer/svgviewer.qrc deleted file mode 100644 index db611f51..00000000 --- a/libs/svgviewer/svgviewer.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - files/bubbles.svg - - - From 37fe7c7bdfd65071311049ce4287ef235797096e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 04:03:06 +0200 Subject: [PATCH 678/750] Removed references to yosys-svgviewer from docs --- .gitignore | 1 - manual/APPNOTE_011_Design_Investigation.tex | 24 +++++++++------------ manual/CHAPTER_Auxprogs.tex | 7 ------ passes/cmds/show.cc | 4 ++-- 4 files changed, 12 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index bb50d357..803e1302 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,5 @@ /yosys-abc /yosys-config /yosys-filterlib -/yosys-svgviewer /kernel/version_*.cc /share diff --git a/manual/APPNOTE_011_Design_Investigation.tex b/manual/APPNOTE_011_Design_Investigation.tex index c0481186..504ab7ec 100644 --- a/manual/APPNOTE_011_Design_Investigation.tex +++ b/manual/APPNOTE_011_Design_Investigation.tex @@ -54,7 +54,7 @@ \begin{document} \title{Yosys Application Note 011: \\ Interactive Design Investigation} -\author{Clifford Wolf \\ December 2013} +\author{Clifford Wolf \\ Original Verision December 2013} \maketitle \begin{abstract} @@ -74,9 +74,7 @@ commands for evaluating circuits and solving SAT problems. This Application Note is based on the Yosys \cite{yosys} GIT Rev. {\tt 2b90ba1} from 2013-12-08. The {\tt README} file covers how to install Yosys. The {\tt show} command requires a working installation of GraphViz \cite{graphviz} -for generating the actual circuit diagrams. Yosys must be build with Qt -support for the built-in SVG viewer. Alternatively an external viewer can be -used, if Qt is not available. +and \cite{xdot} for generating the actual circuit diagrams. \section{Overview} @@ -131,8 +129,8 @@ The {\tt show} command generates a circuit diagram for the design in its current state. Various options can be used to change the appearance of the circuit diagram, set the name and format for the output file, and so forth. When called without any special options, it saves the circuit diagram in -a temporary file and launches {\tt yosys-svgviewer} to display the diagram. -Subsequent calls to {\tt show} re-use the {\tt yosys-svgviewer} instance +a temporary file and launches {\tt xdot} to display the diagram. +Subsequent calls to {\tt show} re-use the {\tt xdot} instance (if still running). \subsection{A simple circuit} @@ -270,18 +268,12 @@ command only operates on interior signals. \subsection{Miscellaneous notes} -Per default the {\tt show} command outputs a temporary SVG file and launches -{\tt yosys-svgviewer} to display it. The options {\tt -format}, {\tt -viewer} +Per default the {\tt show} command outputs a temporary {\tt dot} file and launches +{\tt xdot} to display it. The options {\tt -format}, {\tt -viewer} and {\tt -prefix} can be used to change format, viewer and filename prefix. Note that the {\tt pdf} and {\tt ps} format are the only formats that support plotting multiple modules in one run. -In {\tt yosys-svgviewer} the left mouse button is per default bound to move the -diagram (and the mouse wheel can be used for zooming in and out). However, in -some cases one wants to copy text from the diagram. In this cases the -View->Interactive checkbox must be activated. This switches the rendering back-end -in a mode that supports interaction with the SVG file, such as selecting text. - In densely connected circuits it is sometimes hard to keep track of the individual signal wires. For this cases it can be useful to call {\tt show} with the {\tt -colors } argument, which randomly assigns colors to the @@ -1056,6 +1048,10 @@ Clifford Wolf. The Yosys Open SYnthesis Suite. Graphviz - Graph Visualization Software. \url{http://www.graphviz.org/} +\bibitem{xdot} +xdot.py - an interactive viewer for graphs written in Graphviz's dot language. +\url{https://github.com/jrfonseca/xdot.py} + \bibitem{CircuitSAT} {\it Circuit satisfiability problem} on Wikipedia \url{http://en.wikipedia.org/wiki/Circuit_satisfiability} diff --git a/manual/CHAPTER_Auxprogs.tex b/manual/CHAPTER_Auxprogs.tex index eefd3697..cce3741c 100644 --- a/manual/CHAPTER_Auxprogs.tex +++ b/manual/CHAPTER_Auxprogs.tex @@ -17,10 +17,3 @@ The {\tt yosys-filterlib} tool is a small utility that can be used to strip or extract information from a Liberty file. See Sec.~\ref{sec:techmap_extern} for details. -\section{yosys-svgviewer} - -The {\tt yosys-svgviewer} tool is a small Qt program that can be used to view -SVG files. This tool is automatically launched by the {\tt show} command when -no {\tt -format} and no {\tt -viewer} option is passed to the command. See -{\tt help show} or Sec.~\ref{cmd:show} for details. - diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 6ab0e1ba..0451ebc2 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -598,8 +598,8 @@ struct ShowPass : public Pass { log(" -notitle\n"); log(" do not add the module name as graph title to the dot file\n"); log("\n"); - log("When no is specified, SVG is used. When no and is\n"); - log("specified, 'yosys-svgviewer' is used to display the schematic.\n"); + log("When no is specified, 'dot' is used. When no and is\n"); + log("specified, 'xdot' is used to display the schematic.\n"); log("\n"); log("The generated output files are '~/.yosys_show.dot' and '~/.yosys_show.',\n"); log("unless another prefix is specified using -prefix .\n"); From acd7a99aef0f698580dc6a6d202a79f36fdf5360 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 17:28:13 +0200 Subject: [PATCH 679/750] Added SAT testing to test_cell eval stage --- passes/tests/test_cell.cc | 90 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 7c7d6b7f..de68ee7e 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -19,6 +19,7 @@ */ #include "kernel/yosys.h" +#include "kernel/satgen.h" #include "kernel/consteval.h" #include @@ -123,11 +124,22 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, static void run_eval_test(RTLIL::Design *design, bool verbose) { + log("Eval testing:%c", verbose ? '\n' : ' '); + RTLIL::Module *gold_mod = design->module("\\gold"); RTLIL::Module *gate_mod = design->module("\\gate"); ConstEval gold_ce(gold_mod), gate_ce(gate_mod); - log("Eval testing:%c", verbose ? '\n' : ' '); + ezDefaultSAT ez1, ez2; + SigMap sigmap(gold_mod); + SatGen satgen1(&ez1, &sigmap); + SatGen satgen2(&ez2, &sigmap); + satgen2.model_undef = true; + + for (auto cell : gold_mod->cells()) { + satgen1.importCell(cell); + satgen2.importCell(cell); + } for (int i = 0; i < 64; i++) { @@ -135,6 +147,9 @@ static void run_eval_test(RTLIL::Design *design, bool verbose) gold_ce.clear(); gate_ce.clear(); + RTLIL::SigSpec in_sig, in_val; + RTLIL::SigSpec out_sig, out_val; + for (auto port : gold_mod->ports) { RTLIL::Wire *gold_wire = gold_mod->wire(port); @@ -162,6 +177,9 @@ static void run_eval_test(RTLIL::Design *design, bool verbose) if (verbose) log("%s: %s\n", log_id(gold_wire), log_signal(in_value)); + in_sig.append(gold_wire); + in_val.append(in_value); + gold_ce.set(gold_wire, in_value); gate_ce.set(gate_wire, in_value); } @@ -203,6 +221,76 @@ static void run_eval_test(RTLIL::Design *design, bool verbose) if (verbose) log("%s: %s\n", log_id(gold_wire), log_signal(gold_outval)); + + out_sig.append(gold_wire); + out_val.append(gold_outval); + } + + if (verbose) + log("EVAL: %s\n", out_val.as_string().c_str()); + + std::vector sat1_in_sig = satgen1.importSigSpec(in_sig); + std::vector sat1_in_val = satgen1.importSigSpec(in_val); + + std::vector sat1_model = satgen1.importSigSpec(out_sig); + std::vector sat1_model_value; + + if (!ez1.solve(sat1_model, sat1_model_value, ez1.vec_eq(sat1_in_sig, sat1_in_val))) + log_error("Evaluating sat model 1 (no undef modeling) failed!\n"); + + if (verbose) { + log("SAT 1: "); + for (int i = SIZE(out_sig)-1; i >= 0; i--) + log("%c", sat1_model_value.at(i) ? '1' : '0'); + log("\n"); + } + + for (int i = 0; i < SIZE(out_sig); i++) { + if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) + continue; + if (out_val[i] == RTLIL::S0 && sat1_model_value.at(i) == false) + continue; + if (out_val[i] == RTLIL::S1 && sat1_model_value.at(i) == true) + continue; + log_error("Mismatch in sat model 1 (no undef modeling) output!\n"); + } + + std::vector sat2_in_def_sig = satgen2.importDefSigSpec(in_sig); + std::vector sat2_in_def_val = satgen2.importDefSigSpec(in_val); + + std::vector sat2_in_undef_sig = satgen2.importUndefSigSpec(in_sig); + std::vector sat2_in_undef_val = satgen2.importUndefSigSpec(in_val); + + std::vector sat2_model_def_sig = satgen2.importDefSigSpec(out_sig); + std::vector sat2_model_undef_sig = satgen2.importUndefSigSpec(out_sig); + + std::vector sat2_model; + sat2_model.insert(sat2_model.end(), sat2_model_def_sig.begin(), sat2_model_def_sig.end()); + sat2_model.insert(sat2_model.end(), sat2_model_undef_sig.begin(), sat2_model_undef_sig.end()); + + std::vector sat2_model_value; + + if (!ez2.solve(sat2_model, sat2_model_value, ez2.vec_eq(sat2_in_def_sig, sat2_in_def_val), ez2.vec_eq(sat2_in_undef_sig, sat2_in_undef_val))) + log_error("Evaluating sat model 2 (undef modeling) failed!\n"); + + if (verbose) { + log("SAT 2: "); + for (int i = SIZE(out_sig)-1; i >= 0; i--) + log("%c", sat2_model_value.at(SIZE(out_sig) + i) ? 'x' : sat2_model_value.at(i) ? '1' : '0'); + log("\n"); + } + + for (int i = 0; i < SIZE(out_sig); i++) { + if (sat2_model_value.at(SIZE(out_sig) + i)) { + if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) + continue; + } else { + if (out_val[i] == RTLIL::S0 && sat2_model_value.at(i) == false) + continue; + if (out_val[i] == RTLIL::S1 && sat2_model_value.at(i) == true) + continue; + } + log_error("Mismatch in sat model 2 (undef modeling) output!\n"); } } From c38283dbd033ba95554600bbaa850de707ab2a78 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 17:48:41 +0200 Subject: [PATCH 680/750] Small bug fixes in $not, $neg, and $shiftx models --- kernel/calc.cc | 5 ++--- kernel/satgen.h | 7 ++++--- techlibs/common/simlib.v | 5 ++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/kernel/calc.cc b/kernel/calc.cc index 7bfdb895..4048e4a1 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -591,10 +591,9 @@ RTLIL::Const RTLIL::const_bu0(const RTLIL::Const &arg1, const RTLIL::Const&, boo RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; - extend(arg1_ext, result_len, signed1); - RTLIL::Const zero(RTLIL::State::S0, 1); - return RTLIL::const_sub(zero, arg1_ext, false, signed1, result_len); + + return RTLIL::const_sub(zero, arg1_ext, true, signed1, result_len); } YOSYS_NAMESPACE_END diff --git a/kernel/satgen.h b/kernel/satgen.h index beb03768..3685cd6e 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -357,7 +357,7 @@ struct SatGen if (model_undef) { std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); - extendSignalWidthUnary(undef_a, undef_y, cell, true); + extendSignalWidthUnary(undef_a, undef_y, cell, false); ez->assume(ez->vec_eq(undef_a, undef_y)); undefGating(y, yy, undef_y); } @@ -671,7 +671,7 @@ struct SatGen int extend_bit = ez->FALSE; - if (cell->type != "$shift" && cell->type != "$shiftx" && cell->parameters["\\A_SIGNED"].as_bool()) + if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) extend_bit = a.back(); while (y.size() < a.size()) @@ -703,7 +703,8 @@ struct SatGen std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); std::vector undef_a_shifted; - if (cell->type != "$shift" && cell->type != "$shiftx" && cell->parameters["\\A_SIGNED"].as_bool()) + extend_bit = cell->type == "$shiftx" ? ez->TRUE : ez->FALSE; + if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) extend_bit = undef_a.back(); while (undef_y.size() < undef_a.size()) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 3c931c81..09ffa9a6 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -108,13 +108,12 @@ parameter Y_WIDTH = 0; input [A_WIDTH-1:0] A; output [Y_WIDTH-1:0] Y; -wire [Y_WIDTH-1:0] tmp; generate if (A_SIGNED) begin:BLOCK1 - assign tmp = $signed(A), Y = -tmp; + assign Y = -$signed(A); end else begin:BLOCK2 - assign tmp = A, Y = -tmp; + assign Y = -A; end endgenerate From da360771a193707b59eac9b95b3bfe1652a057aa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 22:49:24 +0200 Subject: [PATCH 681/750] Create a default selection stack in RTLIL::Design::Design() --- kernel/rtlil.cc | 1 + kernel/yosys.cc | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f237f57e..35cd54b4 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -228,6 +228,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) RTLIL::Design::Design() { refcount_modules_ = 0; + selection_stack.push_back(RTLIL::Selection()); } RTLIL::Design::~Design() diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 7b8173b6..0ecb4cda 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -74,9 +74,7 @@ int SIZE(RTLIL::Wire *wire) void yosys_setup() { Pass::init_register(); - yosys_design = new RTLIL::Design; - yosys_design->selection_stack.push_back(RTLIL::Selection()); log_push(); } From 66bf2bb92eb102dbb6b942c0c09b90f3925621a7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 22:49:43 +0200 Subject: [PATCH 682/750] Added test_cell -vlog --- passes/tests/test_cell.cc | 81 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index de68ee7e..aead7b46 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -122,7 +122,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->check(); } -static void run_eval_test(RTLIL::Design *design, bool verbose) +static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_name, std::ofstream &vlog_file) { log("Eval testing:%c", verbose ? '\n' : ' '); @@ -141,6 +141,35 @@ static void run_eval_test(RTLIL::Design *design, bool verbose) satgen2.importCell(cell); } + if (vlog_file.is_open()) + { + vlog_file << stringf("\nmodule %s;\n", uut_name.c_str()); + + for (auto port : gold_mod->ports) { + RTLIL::Wire *wire = gold_mod->wire(port); + if (wire->port_input) + vlog_file << stringf(" reg [%d:0] %s;\n", SIZE(wire)-1, log_id(wire)); + else + vlog_file << stringf(" wire [%d:0] %s_expr, %s_noexpr;\n", SIZE(wire)-1, log_id(wire), log_id(wire)); + } + + vlog_file << stringf(" %s_expr uut_expr(", uut_name.c_str()); + for (int i = 0; i < SIZE(gold_mod->ports); i++) + vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", log_id(gold_mod->ports[i]), log_id(gold_mod->ports[i]), + gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_expr"); + vlog_file << stringf(");\n"); + + vlog_file << stringf(" %s_expr uut_noexpr(", uut_name.c_str()); + for (int i = 0; i < SIZE(gold_mod->ports); i++) + vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", log_id(gold_mod->ports[i]), log_id(gold_mod->ports[i]), + gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_noexpr"); + vlog_file << stringf(");\n"); + + vlog_file << stringf(" task run;\n"); + vlog_file << stringf(" begin\n"); + vlog_file << stringf(" $display(\"%s\");\n", uut_name.c_str()); + } + for (int i = 0; i < 64; i++) { log(verbose ? "\n" : "."); @@ -182,8 +211,14 @@ static void run_eval_test(RTLIL::Design *design, bool verbose) gold_ce.set(gold_wire, in_value); gate_ce.set(gate_wire, in_value); + + if (vlog_file.is_open()) + vlog_file << stringf(" %s = 'b%s;\n", log_id(gold_wire), in_value.as_string().c_str()); } + if (vlog_file.is_open()) + vlog_file << stringf(" #1;\n"); + for (auto port : gold_mod->ports) { RTLIL::Wire *gold_wire = gold_mod->wire(port); @@ -224,6 +259,13 @@ static void run_eval_test(RTLIL::Design *design, bool verbose) out_sig.append(gold_wire); out_val.append(gold_outval); + + if (vlog_file.is_open()) { + vlog_file << stringf(" $display(\"[%s %s] %s expected: %%b, expr: %%b, noexpr: %%b\", %d'b%s, %s_expr, %s_noexpr);\n", + log_signal(in_sig), log_signal(in_val), log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str(), log_id(gold_wire), log_id(gold_wire)); + vlog_file << stringf(" if (%s_expr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str()); + vlog_file << stringf(" if (%s_noexpr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str()); + } } if (verbose) @@ -294,6 +336,12 @@ static void run_eval_test(RTLIL::Design *design, bool verbose) } } + if (vlog_file.is_open()) { + vlog_file << stringf(" end\n"); + vlog_file << stringf(" endtask\n"); + vlog_file << stringf("endmodule\n"); + } + if (!verbose) log(" ok.\n"); } @@ -330,6 +378,9 @@ struct TestCellPass : public Pass { log(" -v\n"); log(" print additional debug information to the console\n"); log("\n"); + log(" -vlog {filename}\n"); + log(" create a verilog test bench to test simlib and write_verilog\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design*) { @@ -337,6 +388,7 @@ struct TestCellPass : public Pass { std::string techmap_cmd = "techmap -assert"; std::string ilang_file; xorshift32_state = 0; + std::ofstream vlog_file; bool verbose = false; int argidx; @@ -367,6 +419,12 @@ struct TestCellPass : public Pass { verbose = true; continue; } + if (args[argidx] == "-vlog" && argidx+1 < SIZE(args)) { + vlog_file.open(args[++argidx], std::ios_base::trunc); + if (!vlog_file.is_open()) + log_cmd_error("Failed to open output file `%s'.\n", args[argidx].c_str()); + continue; + } break; } @@ -468,6 +526,8 @@ struct TestCellPass : public Pass { if (selected_cell_types.empty()) log_cmd_error("No cell type to test specified.\n"); + std::vector task_names; + for (auto cell_type : selected_cell_types) for (int i = 0; i < num_iter; i++) { @@ -482,9 +542,26 @@ struct TestCellPass : public Pass { Pass::call(design, "dump gate"); Pass::call(design, "dump gold"); Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); - run_eval_test(design, verbose); + std::string uut_name = stringf("uut_%s_%d", cell_type.substr(1).c_str(), i); + if (vlog_file.is_open()) { + Pass::call(design, stringf("copy gold %s_expr; select %s_expr", uut_name.c_str(), uut_name.c_str())); + Backend::backend_call(design, &vlog_file, "", "verilog -selected"); + Pass::call(design, stringf("copy gold %s_noexpr; select %s_noexpr", uut_name.c_str(), uut_name.c_str())); + Backend::backend_call(design, &vlog_file, "", "verilog -selected -noexpr"); + task_names.push_back(uut_name + ".run"); + } + run_eval_test(design, verbose, uut_name, vlog_file); delete design; } + + if (vlog_file.is_open()) { + vlog_file << "\nmodule testbench;\n"; + vlog_file << " initial begin\n"; + for (auto &task : task_names) + vlog_file << " " << task << ";\n"; + vlog_file << " end\n"; + vlog_file << "endmodule\n"; + } } } TestCellPass; From f1869667cac35e897c0531c05074f3c77bfa5db9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 23:21:15 +0200 Subject: [PATCH 683/750] Improvements in "test_cell -vlog" --- passes/tests/test_cell.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index aead7b46..627c2f7d 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -178,6 +178,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_n RTLIL::SigSpec in_sig, in_val; RTLIL::SigSpec out_sig, out_val; + std::string vlog_pattern_info; for (auto port : gold_mod->ports) { @@ -212,8 +213,12 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_n gold_ce.set(gold_wire, in_value); gate_ce.set(gate_wire, in_value); - if (vlog_file.is_open()) + if (vlog_file.is_open()) { vlog_file << stringf(" %s = 'b%s;\n", log_id(gold_wire), in_value.as_string().c_str()); + if (!vlog_pattern_info.empty()) + vlog_pattern_info += " "; + vlog_pattern_info += stringf("%s=%s", log_id(gold_wire), log_signal(in_value)); + } } if (vlog_file.is_open()) @@ -261,8 +266,8 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_n out_val.append(gold_outval); if (vlog_file.is_open()) { - vlog_file << stringf(" $display(\"[%s %s] %s expected: %%b, expr: %%b, noexpr: %%b\", %d'b%s, %s_expr, %s_noexpr);\n", - log_signal(in_sig), log_signal(in_val), log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str(), log_id(gold_wire), log_id(gold_wire)); + vlog_file << stringf(" $display(\"[%s] %s expected: %%b, expr: %%b, noexpr: %%b\", %d'b%s, %s_expr, %s_noexpr);\n", + vlog_pattern_info.c_str(), log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str(), log_id(gold_wire), log_id(gold_wire)); vlog_file << stringf(" if (%s_expr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str()); vlog_file << stringf(" if (%s_noexpr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str()); } From 635b922afeabea8c69ac4e749881b10aeda7448b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 23:21:59 +0200 Subject: [PATCH 684/750] Undef-related fixes in simlib $alu model --- techlibs/common/simlib.v | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 09ffa9a6..61215f59 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -492,8 +492,11 @@ generate end endgenerate +// this is 'x' if Y and CO should be all 'x', and '0' otherwise +wire y_co_undef = ^{A, A, B, B, CI, CI, BI, BI}; + assign X = AA ^ BB; -assign Y = AA + BB + CI; +assign Y = (AA + BB + CI) ^ {Y_WIDTH{y_co_undef}}; function get_carry; input a, b, c; @@ -502,9 +505,9 @@ endfunction genvar i; generate - assign CO[0] = get_carry(AA[0], BB[0], CI); + assign CO[0] = get_carry(AA[0], BB[0], CI) ^ y_co_undef; for (i = 1; i < Y_WIDTH; i = i+1) begin:BLOCK3 - assign CO[i] = get_carry(AA[i], BB[i], CO[i-1]); + assign CO[i] = get_carry(AA[i], BB[i], CO[i-1]) ^ y_co_undef; end endgenerate From 50ac2848239cf5969b80c427a95b6098fd1e2f1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 3 Sep 2014 13:39:46 +0200 Subject: [PATCH 685/750] Fixes in $alu SAT- and eval-models --- kernel/consteval.h | 4 ++-- kernel/satgen.h | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/kernel/consteval.h b/kernel/consteval.h index fb54b72f..c73a0b35 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -178,8 +178,8 @@ struct ConstEval RTLIL::SigSpec sig_co = cell->getPort("\\CO"); bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def()); - sig_a.extend(SIZE(sig_y), signed_a); - sig_b.extend(SIZE(sig_y), signed_b); + sig_a.extend_u0(SIZE(sig_y), signed_a); + sig_b.extend_u0(SIZE(sig_y), signed_b); bool carry = sig_ci[0] == RTLIL::S1; bool b_inv = sig_bi[0] == RTLIL::S1; diff --git a/kernel/satgen.h b/kernel/satgen.h index 3685cd6e..c7f1680d 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -934,9 +934,9 @@ struct SatGen std::vector undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); std::vector undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep); - extendSignalWidth(undef_a, undef_b, undef_y, cell, true); - extendSignalWidth(undef_a, undef_b, undef_x, cell, true); - extendSignalWidth(undef_a, undef_b, undef_co, cell, true); + extendSignalWidth(undef_a, undef_b, undef_y, cell); + extendSignalWidth(undef_a, undef_b, undef_x, cell); + extendSignalWidth(undef_a, undef_b, undef_co, cell); std::vector all_inputs_undef; all_inputs_undef.insert(all_inputs_undef.end(), undef_a.begin(), undef_a.end()); @@ -955,7 +955,6 @@ struct SatGen undefGating(x, def_x, undef_x); undefGating(co, def_co, undef_co); } - log_ping(); return true; } From 5733f4a39d56388e531b6c1471f56c3efb023f31 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 3 Sep 2014 13:43:37 +0200 Subject: [PATCH 686/750] Fixed "test_cells -vlog" --- passes/tests/test_cell.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 627c2f7d..dce76804 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -531,7 +531,7 @@ struct TestCellPass : public Pass { if (selected_cell_types.empty()) log_cmd_error("No cell type to test specified.\n"); - std::vector task_names; + std::vector uut_names; for (auto cell_type : selected_cell_types) for (int i = 0; i < num_iter; i++) @@ -553,7 +553,7 @@ struct TestCellPass : public Pass { Backend::backend_call(design, &vlog_file, "", "verilog -selected"); Pass::call(design, stringf("copy gold %s_noexpr; select %s_noexpr", uut_name.c_str(), uut_name.c_str())); Backend::backend_call(design, &vlog_file, "", "verilog -selected -noexpr"); - task_names.push_back(uut_name + ".run"); + uut_names.push_back(uut_name); } run_eval_test(design, verbose, uut_name, vlog_file); delete design; @@ -561,9 +561,11 @@ struct TestCellPass : public Pass { if (vlog_file.is_open()) { vlog_file << "\nmodule testbench;\n"; + for (auto &uut : uut_names) + vlog_file << stringf(" %s %s ();\n", uut.c_str(), uut.c_str()); vlog_file << " initial begin\n"; - for (auto &task : task_names) - vlog_file << " " << task << ";\n"; + for (auto &uut : uut_names) + vlog_file << " " << uut << ".run;\n"; vlog_file << " end\n"; vlog_file << "endmodule\n"; } From b9cb483f3e2a498ee75a422e09164a920918362b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 3 Sep 2014 21:20:59 +0200 Subject: [PATCH 687/750] Using $pos models for $bu0 --- backends/verilog/verilog_backend.cc | 17 +---------------- kernel/calc.cc | 2 +- kernel/satgen.h | 2 +- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index d1fa55b9..79672540 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -538,6 +538,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) HANDLE_UNIOP("$not", "~") HANDLE_UNIOP("$pos", "+") + HANDLE_UNIOP("$bu0", "+") HANDLE_UNIOP("$neg", "-") HANDLE_BINOP("$and", "&") @@ -651,22 +652,6 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type == "$bu0") - { - f << stringf("%s" "assign ", indent.c_str()); - dump_sigspec(f, cell->getPort("\\Y")); - if (cell->parameters["\\A_SIGNED"].as_bool()) { - f << stringf(" = $signed("); - dump_sigspec(f, cell->getPort("\\A")); - f << stringf(");\n"); - } else { - f << stringf(" = { 1'b0, "); - dump_sigspec(f, cell->getPort("\\A")); - f << stringf(" };\n"); - } - return true; - } - if (cell->type == "$concat") { f << stringf("%s" "assign ", indent.c_str()); diff --git a/kernel/calc.cc b/kernel/calc.cc index 4048e4a1..da03f616 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -575,7 +575,7 @@ RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2 RTLIL::Const RTLIL::const_pos(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; - extend(arg1_ext, result_len, signed1); + extend_u0(arg1_ext, result_len, signed1); return arg1_ext; } diff --git a/kernel/satgen.h b/kernel/satgen.h index c7f1680d..eed3adaa 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -470,7 +470,7 @@ struct SatGen { std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); - extendSignalWidthUnary(undef_a, undef_y, cell, cell->type != "$bu0"); + extendSignalWidthUnary(undef_a, undef_y, cell); if (cell->type == "$pos" || cell->type == "$bu0") { ez->assume(ez->vec_eq(undef_a, undef_y)); From 8927aa6148f5575b2da9bfb76afb4af076fe18f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 4 Sep 2014 02:07:52 +0200 Subject: [PATCH 688/750] Removed $bu0 cell type --- backends/verilog/verilog_backend.cc | 1 - frontends/ast/genrtlil.cc | 10 +++++----- kernel/calc.cc | 21 --------------------- kernel/celltypes.h | 5 ++--- kernel/rtlil.cc | 3 +-- kernel/rtlil.h | 2 -- kernel/satgen.h | 6 +++--- manual/CHAPTER_CellLib.tex | 6 ------ manual/PRESENTATION_Prog.tex | 2 +- manual/command-reference-manual.tex | 2 +- passes/cmds/stat.cc | 2 +- passes/opt/opt_const.cc | 10 ++++------ passes/opt/share.cc | 1 - passes/opt/wreduce.cc | 6 +++--- passes/techmap/simplemap.cc | 13 +------------ passes/tests/test_cell.cc | 1 - techlibs/common/simlib.v | 24 ------------------------ techlibs/common/techmap.v | 15 +++++---------- 18 files changed, 27 insertions(+), 103 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 79672540..82a2c519 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -538,7 +538,6 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) HANDLE_UNIOP("$not", "~") HANDLE_UNIOP("$pos", "+") - HANDLE_UNIOP("$bu0", "+") HANDLE_UNIOP("$neg", "-") HANDLE_BINOP("$and", "&") diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 506c2bb2..0c7be1f5 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); diff --git a/kernel/calc.cc b/kernel/calc.cc index da03f616..41179d04 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -26,19 +26,6 @@ YOSYS_NAMESPACE_BEGIN -static void extend(RTLIL::Const &arg, int width, bool is_signed) -{ - RTLIL::State padding = RTLIL::State::S0; - - if (arg.bits.size() > 0 && (is_signed || arg.bits.back() > RTLIL::State::S1)) - padding = arg.bits.back(); - - while (int(arg.bits.size()) < width) - arg.bits.push_back(padding); - - arg.bits.resize(width); -} - static void extend_u0(RTLIL::Const &arg, int width, bool is_signed) { RTLIL::State padding = RTLIL::State::S0; @@ -580,14 +567,6 @@ RTLIL::Const RTLIL::const_pos(const RTLIL::Const &arg1, const RTLIL::Const&, boo return arg1_ext; } -RTLIL::Const RTLIL::const_bu0(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len) -{ - RTLIL::Const arg1_ext = arg1; - extend_u0(arg1_ext, result_len, signed1); - - return arg1_ext; -} - RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, bool signed1, bool, int result_len) { RTLIL::Const arg1_ext = arg1; diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 4a8be04d..a8d88603 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -86,7 +86,7 @@ struct CellTypes void setup_internals() { std::vector unary_ops = { - "$not", "$pos", "$bu0", "$neg", + "$not", "$pos", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$logic_not", "$slice", "$lut" }; @@ -219,7 +219,7 @@ struct CellTypes type = "$shl"; if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" && - type != "$pos" && type != "$neg" && type != "$not" && type != "$bu0") { + type != "$pos" && type != "$neg" && type != "$not") { if (!signed1 || !signed2) signed1 = false, signed2 = false; } @@ -259,7 +259,6 @@ struct CellTypes HANDLE_CELL_TYPE(mod) HANDLE_CELL_TYPE(pow) HANDLE_CELL_TYPE(pos) - HANDLE_CELL_TYPE(bu0) HANDLE_CELL_TYPE(neg) #undef HANDLE_CELL_TYPE diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 35cd54b4..08c79bea 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -563,7 +563,7 @@ namespace { cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:") return; - if (cell->type.in("$not", "$pos", "$bu0", "$neg")) { + if (cell->type.in("$not", "$pos", "$neg")) { param_bool("\\A_SIGNED"); port("\\A", param("\\A_WIDTH")); port("\\Y", param("\\Y_WIDTH")); @@ -1326,7 +1326,6 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth } DEF_METHOD(Not, sig_a.size(), "$not") DEF_METHOD(Pos, sig_a.size(), "$pos") -DEF_METHOD(Bu0, sig_a.size(), "$bu0") DEF_METHOD(Neg, sig_a.size(), "$neg") DEF_METHOD(ReduceAnd, 1, "$reduce_and") DEF_METHOD(ReduceOr, 1, "$reduce_or") diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b8733c4e..c4883769 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -314,7 +314,6 @@ namespace RTLIL RTLIL::Const const_pow (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_pos (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); - RTLIL::Const const_bu0 (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); RTLIL::Const const_neg (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len); @@ -651,7 +650,6 @@ public: RTLIL::Cell* addNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addPos (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); - RTLIL::Cell* addBu0 (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addNeg (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false); RTLIL::Cell* addAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false); diff --git a/kernel/satgen.h b/kernel/satgen.h index eed3adaa..ae155a2e 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -451,7 +451,7 @@ struct SatGen return true; } - if (cell->type == "$pos" || cell->type == "$bu0" || cell->type == "$neg") + if (cell->type == "$pos" || cell->type == "$neg") { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); @@ -459,7 +459,7 @@ struct SatGen std::vector yy = model_undef ? ez->vec_var(y.size()) : y; - if (cell->type == "$pos" || cell->type == "$bu0") { + if (cell->type == "$pos") { ez->assume(ez->vec_eq(a, yy)); } else { std::vector zero(a.size(), ez->FALSE); @@ -472,7 +472,7 @@ struct SatGen std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); extendSignalWidthUnary(undef_a, undef_y, cell); - if (cell->type == "$pos" || cell->type == "$bu0") { + if (cell->type == "$pos") { ez->assume(ez->vec_eq(undef_a, undef_y)); } else { int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 82473f6a..5045960c 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -97,12 +97,6 @@ The width of the output port \B{Y}. Table~\ref{tab:CellLib_binary} lists all cells for binary RTL operators. -The additional cell type {\tt \$bu0} is similar to {\tt \$pos}, but always -extends unsigned arguments with zeros. ({\tt \$pos} extends unsigned arguments -with {\tt x}-bits if the most significant bit is {\tt x}.) This is used -internally to correctly implement the {\tt ==} and {\tt !=} operators for -constant arguments. - \subsection{Multiplexers} Multiplexers are generated by the Verilog HDL frontend for {\tt diff --git a/manual/PRESENTATION_Prog.tex b/manual/PRESENTATION_Prog.tex index 4e9f4b21..590451be 100644 --- a/manual/PRESENTATION_Prog.tex +++ b/manual/PRESENTATION_Prog.tex @@ -300,7 +300,7 @@ The {\tt type} may refer to another module in the same design, a cell name from cell name from the internal cell library: \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont] -$not $pos $bu0 $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor +$not $pos $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor $reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff $dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_NOT_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex index 54fec542..9d9665c1 100644 --- a/manual/command-reference-manual.tex +++ b/manual/command-reference-manual.tex @@ -1204,7 +1204,7 @@ unless another prefix is specified using -prefix . This pass maps a small selection of simple coarse-grain cells to yosys gate primitives. The following internal cell types are mapped by this pass: - $not, $pos, $bu0, $and, $or, $xor, $xnor + $not, $pos, $and, $or, $xor, $xnor $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool $logic_not, $logic_and, $logic_or, $mux $sr, $dff, $dffsr, $adff, $dlatch diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index dea24227..19cdaa62 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -99,7 +99,7 @@ namespace if (width_mode) { - if (cell_type.in("$not", "$pos", "$bu0", "$neg", + if (cell_type.in("$not", "$pos", "$neg", "$logic_not", "$logic_and", "$logic_or", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$lut", "$and", "$or", "$xor", "$xnor", diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index ad696187..d315dba3 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -181,7 +181,7 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com log("\n"); } - cover_list("opt.opt_const.fine.group", "$not", "$pos", "$bu0", "$and", "$or", "$xor", "$xnor", cell->type.str()); + cover_list("opt.opt_const.fine.group", "$not", "$pos", "$and", "$or", "$xor", "$xnor", cell->type.str()); module->remove(cell); did_something = true; @@ -236,7 +236,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (do_fine) { - if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$bu0" || + if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") if (group_cell_inputs(module, cell, true, cell->type != "$pos", assign_map)) goto next_cell; @@ -586,7 +586,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo if (!keepdc) { - bool identity_bu0 = false; bool identity_wrt_a = false; bool identity_wrt_b = false; @@ -607,7 +606,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo RTLIL::SigSpec b = assign_map(cell->getPort("\\B")); if (b.is_fully_const() && b.as_bool() == false) - identity_wrt_a = true, identity_bu0 = true; + identity_wrt_a = true; } if (cell->type == "$mul") @@ -646,7 +645,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo cell->parameters.at("\\A_SIGNED") = cell->parameters.at("\\B_SIGNED"); } - cell->type = identity_bu0 ? "$bu0" : "$pos"; + cell->type = "$pos"; cell->unsetPort("\\B"); cell->parameters.erase("\\B_WIDTH"); cell->parameters.erase("\\B_SIGNED"); @@ -840,7 +839,6 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo FOLD_2ARG_CELL(pow) FOLD_1ARG_CELL(pos) - FOLD_1ARG_CELL(bu0) FOLD_1ARG_CELL(neg) // be very conservative with optimizing $mux cells as we do not want to break mux trees diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 5f3cf421..c372ed78 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -923,7 +923,6 @@ struct SharePass : public Pass { config.generic_uni_ops.insert("$not"); // config.generic_uni_ops.insert("$pos"); - // config.generic_uni_ops.insert("$bu0"); config.generic_uni_ops.insert("$neg"); config.generic_cbin_ops.insert("$and"); diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 2269859d..321a1aa5 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -37,7 +37,7 @@ struct WreduceConfig WreduceConfig() { - supported_cell_types << "$not" << "$pos" << "$bu0" << "$neg"; + supported_cell_types << "$not" << "$pos" << "$neg"; supported_cell_types << "$and" << "$or" << "$xor" << "$xnor"; supported_cell_types << "$shl" << "$shr" << "$sshl" << "$sshr" << "$shift" << "$shiftx"; supported_cell_types << "$lt" << "$le" << "$eq" << "$ne" << "$eqx" << "$nex" << "$ge" << "$gt"; @@ -181,7 +181,7 @@ struct WreduceWorker int max_port_a_size = cell->hasPort("\\A") ? SIZE(cell->getPort("\\A")) : -1; int max_port_b_size = cell->hasPort("\\B") ? SIZE(cell->getPort("\\B")) : -1; - if (cell->type.in("$not", "$pos", "$bu0", "$neg", "$and", "$or", "$xor", "$add", "$sub")) { + if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) { max_port_a_size = std::min(max_port_a_size, SIZE(cell->getPort("\\Y"))); max_port_b_size = std::min(max_port_b_size, SIZE(cell->getPort("\\Y"))); } @@ -216,7 +216,7 @@ struct WreduceWorker } } - if (cell->type.in("$pos", "$bu0", "$add", "$mul", "$and", "$or", "$xor")) + if (cell->type.in("$pos", "$add", "$mul", "$and", "$or", "$xor")) { bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index f5d9bbee..f8d5d458 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -45,16 +45,6 @@ static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - sig_a.extend(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); - - module->connect(RTLIL::SigSig(sig_y, sig_a)); -} - -static void simplemap_bu0(RTLIL::Module *module, RTLIL::Cell *cell) -{ - RTLIL::SigSpec sig_a = cell->getPort("\\A"); - RTLIL::SigSpec sig_y = cell->getPort("\\Y"); - sig_a.extend_u0(SIZE(sig_y), cell->parameters.at("\\A_SIGNED").as_bool()); module->connect(RTLIL::SigSig(sig_y, sig_a)); @@ -386,7 +376,6 @@ void simplemap_get_mappers(std::map Date: Thu, 4 Sep 2014 08:55:58 +0200 Subject: [PATCH 689/750] Fixed "opt_const -fine" for $pos cells --- passes/opt/opt_const.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index d315dba3..f9b78c05 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -85,7 +85,7 @@ static void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell did_something = true; } -static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, bool extend_u0, SigMap &sigmap) +static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutative, SigMap &sigmap) { std::string b_name = cell->hasPort("\\B") ? "\\B" : "\\A"; @@ -96,13 +96,8 @@ static bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool com RTLIL::SigSpec sig_b = sigmap(cell->getPort(b_name)); RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y")); - if (extend_u0) { - sig_a.extend_u0(sig_y.size(), a_signed); - sig_b.extend_u0(sig_y.size(), b_signed); - } else { - sig_a.extend(sig_y.size(), a_signed); - sig_b.extend(sig_y.size(), b_signed); - } + sig_a.extend_u0(sig_y.size(), a_signed); + sig_b.extend_u0(sig_y.size(), b_signed); std::vector bits_a = sig_a, bits_b = sig_b, bits_y = sig_y; @@ -238,7 +233,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo { if (cell->type == "$not" || cell->type == "$pos" || cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor") - if (group_cell_inputs(module, cell, true, cell->type != "$pos", assign_map)) + if (group_cell_inputs(module, cell, true, assign_map)) goto next_cell; if (cell->type == "$reduce_and") From 01ef34c147dd3e3e3d13864f9c726727a4013207 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 4 Sep 2014 15:07:30 +0200 Subject: [PATCH 690/750] Added tests/various/constmsk_test.ys --- tests/various/constmsk_test.v | 4 +++ tests/various/constmsk_test.ys | 15 ++++++++++ tests/various/constmsk_testmap.v | 49 ++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 tests/various/constmsk_test.v create mode 100644 tests/various/constmsk_test.ys create mode 100644 tests/various/constmsk_testmap.v diff --git a/tests/various/constmsk_test.v b/tests/various/constmsk_test.v new file mode 100644 index 00000000..0d0e58fe --- /dev/null +++ b/tests/various/constmsk_test.v @@ -0,0 +1,4 @@ +module test(input [3:0] A, output [3:0] Y1, Y2); + assign Y1 = |{A[3], 1'b0, A[1]}; + assign Y2 = |{A[2], 1'b1, A[0]}; +endmodule diff --git a/tests/various/constmsk_test.ys b/tests/various/constmsk_test.ys new file mode 100644 index 00000000..ce36efc3 --- /dev/null +++ b/tests/various/constmsk_test.ys @@ -0,0 +1,15 @@ +read_verilog constmsk_test.v + +copy test gold +rename test gate + +cd gate +techmap -map constmsk_testmap.v;; +cd .. + +select -assert-count 2 gold/r:A_WIDTH=3 +select -assert-count 1 gate/r:A_WIDTH=2 +select -assert-count 1 gate/c:* + +miter -equiv -flatten gold gate miter +sat -verify -prove trigger 0 miter diff --git a/tests/various/constmsk_testmap.v b/tests/various/constmsk_testmap.v new file mode 100644 index 00000000..fab1b1bb --- /dev/null +++ b/tests/various/constmsk_testmap.v @@ -0,0 +1,49 @@ +(* techmap_celltype = "$reduce_or" *) +module my_opt_reduce_or(...); + parameter A_SIGNED = 0; + parameter A_WIDTH = 1; + parameter Y_WIDTH = 1; + + input [A_WIDTH-1:0] A; + output reg [Y_WIDTH-1:0] Y; + + parameter _TECHMAP_CONSTMSK_A_ = 0; + parameter _TECHMAP_CONSTVAL_A_ = 0; + + wire _TECHMAP_FAIL_ = count_nonconst_bits() == A_WIDTH; + wire [1024:0] _TECHMAP_DO_ = "proc;;"; + + function integer count_nonconst_bits; + integer i; + begin + count_nonconst_bits = 0; + for (i = 0; i < A_WIDTH; i=i+1) + if (!_TECHMAP_CONSTMSK_A_[i]) + count_nonconst_bits = count_nonconst_bits+1; + end + endfunction + + function has_const_one; + integer i; + begin + has_const_one = 0; + for (i = 0; i < A_WIDTH; i=i+1) + if (_TECHMAP_CONSTMSK_A_[i] && _TECHMAP_CONSTVAL_A_[i] === 1'b1) + has_const_one = 1; + end + endfunction + + integer i; + reg [count_nonconst_bits()-1:0] tmp; + + always @* begin + if (has_const_one()) begin + Y = 1; + end else begin + for (i = 0; i < A_WIDTH; i=i+1) + if (!_TECHMAP_CONSTMSK_A_[i]) + tmp = {A[i], tmp[count_nonconst_bits()-1:1]}; + Y = |tmp; + end + end +endmodule From 79cbf9067c07ed810b3466174278d77b9a05b46d Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Sat, 6 Sep 2014 08:47:06 +0200 Subject: [PATCH 691/750] Corrected spelling mistakes found by lintian --- Makefile | 2 +- backends/blif/blif.cc | 2 +- frontends/ast/simplify.cc | 2 +- frontends/verific/build_amd64.txt | 2 +- frontends/verific/verific.cc | 2 +- frontends/vhdl2verilog/vhdl2verilog.cc | 2 +- kernel/register.cc | 6 +++--- libs/minisat/Solver.h | 4 ++-- manual/CHAPTER_Prog/stubnets.cc | 2 +- manual/CHAPTER_Techmap.tex | 2 +- manual/CHAPTER_Verilog.tex | 6 +++--- manual/command-reference-manual.tex | 14 +++++++------- manual/manual.tex | 2 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 4 ++-- passes/cmds/splice.cc | 4 ++-- passes/cmds/splitnets.cc | 2 +- passes/fsm/fsm_recode.cc | 2 +- passes/hierarchy/hierarchy.cc | 8 ++++---- passes/memory/memory_share.cc | 2 +- passes/opt/opt_clean.cc | 4 ++-- passes/sat/sat.cc | 2 +- 22 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index ce4a68c5..a499157a 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ else endif YOSYS_VER := 0.3.0+ -GIT_REV := $(shell git rev-parse --short HEAD 2> /dev/null || echo UNKOWN) +GIT_REV := $(shell git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o # set 'ABCREV = default' to use abc/ as it is diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 919022ab..ee12546c 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -280,7 +280,7 @@ struct BlifBackend : public Backend { log(" -false \n"); log(" use the specified cell types to drive nets that are constant 1 or 0\n"); log("\n"); - log("The following options can be usefull when the generated file is not going to be\n"); + log("The following options can be useful when the generated file is not going to be\n"); log("read by a BLIF parser but a custom tool. It is recommended to not name the output\n"); log("file *.blif when any of this options is used.\n"); log("\n"); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 68c17271..1998c12e 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 2c3ba7b4..94615d38 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 0440f88e..d0f14838 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 8b6f62a6..b408d621 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"); diff --git a/kernel/register.cc b/kernel/register.cc index a53bd84c..2f7b89ff 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -132,7 +132,7 @@ void Pass::extra_args(std::vector args, size_t argidx, RTLIL::Desig std::string arg = args[argidx]; if (arg.substr(0, 1) == "-") - cmd_error(args, argidx, "Unkown option or option in arguments."); + cmd_error(args, argidx, "Unknown option or option in arguments."); if (!select) cmd_error(args, argidx, "Extra argument."); @@ -309,7 +309,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector stub_bits; - // get a signal description for this wire and split it into seperate bits + // get a signal description for this wire and split it into separate bits RTLIL::SigSpec sig = sigmap(wire); // for each bit (unless it is a constant): diff --git a/manual/CHAPTER_Techmap.tex b/manual/CHAPTER_Techmap.tex index 26632d0b..e5c7456c 100644 --- a/manual/CHAPTER_Techmap.tex +++ b/manual/CHAPTER_Techmap.tex @@ -32,7 +32,7 @@ the Yosys source tree. Additional features have been added to {\tt techmap} to allow for conditional mapping of cells (see {\tt help techmap} or Sec.~\ref{cmd:techmap}). This can -for example be usefull if the target architecture supports hardware multipliers for +for example be useful if the target architecture supports hardware multipliers for certain bit-widths but not for others. A usual synthesis flow would first use the {\tt techmap} pass to directly map diff --git a/manual/CHAPTER_Verilog.tex b/manual/CHAPTER_Verilog.tex index 96074774..485b4f35 100644 --- a/manual/CHAPTER_Verilog.tex +++ b/manual/CHAPTER_Verilog.tex @@ -444,7 +444,7 @@ on the AST data structure: \begin{itemize} \item Inline all task and function calls. \item Evaluate all \lstinline[language=Verilog]{generate}-statements and unroll all \lstinline[language=Verilog]{for}-loops. -\item Perform const folding where it is neccessary (e.g.~in the value part of {\tt AST\_PARAMETER}, {\tt AST\_LOCALPARAM}, +\item Perform const folding where it is necessary (e.g.~in the value part of {\tt AST\_PARAMETER}, {\tt AST\_LOCALPARAM}, {\tt AST\_PARASET} and {\tt AST\_RANGE} nodes). \item Replace {\tt AST\_PRIMITIVE} nodes with appropriate {\tt AST\_ASSIGN} nodes. \item Replace dynamic bit ranges in the left-hand-side of assignments with {\tt AST\_CASE} nodes with {\tt AST\_COND} children @@ -819,7 +819,7 @@ the \C{RTLIL::SyncRule}s that describe the output registers. % \item {\tt proc\_dff} \\ This pass replaces the \C{RTLIL::SyncRule}s to d-type flip-flops (with -asynchronous resets if neccessary). +asynchronous resets if necessary). % \item {\tt proc\_clean} \\ A final call to {\tt proc\_clean} removes the now empty \C{RTLIL::Process} objects. @@ -827,7 +827,7 @@ A final call to {\tt proc\_clean} removes the now empty \C{RTLIL::Process} objec Performing these last processing steps in passes instead of in the Verilog frontend has two important benefits: -First it improves the transparency of the process. Everything that happens in a seperate pass is easier to debug, +First it improves the transparency of the process. Everything that happens in a separate pass is easier to debug, as the RTLIL data structures can be easily investigated before and after each of the steps. Second it improves flexibility. This scheme can easily be extended to support other types of storage-elements, such diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex index 9d9665c1..35249ed8 100644 --- a/manual/command-reference-manual.tex +++ b/manual/command-reference-manual.tex @@ -85,10 +85,10 @@ This is just a shortcut for 'select -clear'. This is identical to 'opt_clean', but less verbose. -When commands are seperated using the ';;' token, this command will be executed +When commands are separated using the ';;' token, this command will be executed between the commands. -When commands are seperated using the ';;;' token, this command will be executed +When commands are separated using the ';;;' token, this command will be executed in -purge mode between the commands. \end{lstlisting} @@ -419,7 +419,7 @@ commands. hierarchy [-check] [-top ] hierarchy -generate -In parametric designs, a module might exists in serveral variations with +In parametric designs, a module might exists in several variations with different parameter values. This pass looks at all modules in the current design an re-runs the language frontends for the parametric modules as needed. @@ -881,7 +881,7 @@ The following options can be used to set up a sequential problem: -set-def-at -set-any-undef-at -set-all-undef-at - add undef contraints in the given timestep. + add undef constraints in the given timestep. -set-init set the initial value for the register driving the signal to the value @@ -942,7 +942,7 @@ design. -all_cell_types Usually this command only considers internal non-memory cells. With - this option set, all cells are considered. For unkown cells all ports + this option set, all cells are considered. For unknown cells all ports are assumed to be bidirectional 'inout' ports. -set_attr @@ -1089,7 +1089,7 @@ The following actions can be performed on the top sets on the stack: (i.e. select all cells connected to selected wires and select all wires connected to selected cells) The rules specify which cell ports to use for this. the syntax for a rule is a '-' for exclusion - and a '+' for inclusion, followed by an optional comma seperated + and a '+' for inclusion, followed by an optional comma separated list of cell types followed by an optional comma separated list of cell ports in square brackets. a rule can also be just a cell or wire name that limits the expansion (is included but does not go beyond). @@ -1452,7 +1452,7 @@ Write the current design to an BLIF file. -false use the specified cell types to drive nets that are constant 1 or 0 -The following options can be usefull when the generated file is not going to be +The following options can be useful when the generated file is not going to be read by a BLIF parser but a custom tool. It is recommended to not name the output file *.blif when any of this options is used. diff --git a/manual/manual.tex b/manual/manual.tex index c305ecb0..19d3b7b2 100644 --- a/manual/manual.tex +++ b/manual/manual.tex @@ -144,7 +144,7 @@ Most of today's digital design is done in HDL code (mostly Verilog or VHDL) and with the help of HDL synthesis tools. In special cases such as synthesis for coarse-grain cell libraries or when -testing new synthesis algorithms it might be neccessary to write a custom HDL +testing new synthesis algorithms it might be necessary to write a custom HDL synthesis tool or add new features to an existing one. It this cases the availability of a Free and Open Source (FOSS) synthesis tool that can be used as basis for custom tools would be helpful. diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 8c039e3e..5224f5bc 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -216,7 +216,7 @@ struct SccPass : public Pass { log("\n"); log(" -all_cell_types\n"); log(" Usually this command only considers internal non-memory cells. With\n"); - log(" this option set, all cells are considered. For unkown cells all ports\n"); + log(" this option set, all cells are considered. For unknown cells all ports\n"); log(" are assumed to be bidirectional 'inout' ports.\n"); log("\n"); log(" -set_attr \n"); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 2d49e85e..4c540ca6 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -985,7 +985,7 @@ struct SelectPass : public Pass { log(" (i.e. select all cells connected to selected wires and select all\n"); log(" wires connected to selected cells) The rules specify which cell\n"); log(" ports to use for this. the syntax for a rule is a '-' for exclusion\n"); - log(" and a '+' for inclusion, followed by an optional comma seperated\n"); + log(" and a '+' for inclusion, followed by an optional comma separated\n"); log(" list of cell types followed by an optional comma separated list of\n"); log(" cell ports in square brackets. a rule can also be just a cell or wire\n"); log(" name that limits the expansion (is included but does not go beyond).\n"); @@ -1089,7 +1089,7 @@ struct SelectPass : public Pass { continue; } if (arg.size() > 0 && arg[0] == '-') - log_cmd_error("Unkown option %s.\n", arg.c_str()); + log_cmd_error("Unknown option %s.\n", arg.c_str()); select_stmt(design, arg); sel_str += " " + arg; } diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index ca71f7d8..d03aaf3b 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -251,12 +251,12 @@ struct SplicePass : public Pass { log("\n"); log(" -sel_by_cell\n"); log(" only select the cell ports to rewire by the cell. if the selection\n"); - log(" contains a cell, than all cell inputs are rewired, if neccessary.\n"); + log(" contains a cell, than all cell inputs are rewired, if necessary.\n"); log("\n"); log(" -sel_by_wire\n"); log(" only select the cell ports to rewire by the wire. if the selection\n"); log(" contains a wire, than all cell ports driven by this wire are wired,\n"); - log(" if neccessary.\n"); + log(" if necessary.\n"); log("\n"); log(" -sel_any_bit\n"); log(" it is sufficient if the driver of any bit of a cell port is selected.\n"); diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index cef0a272..344b03fc 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -76,7 +76,7 @@ struct SplitnetsPass : public Pass { log(" -format char1[char2[char3]]\n"); log(" the first char is inserted between the net name and the bit index, the\n"); log(" second char is appended to the netname. e.g. -format () creates net\n"); - log(" names like 'mysignal(42)'. the 3rd character is the range seperation\n"); + log(" names like 'mysignal(42)'. the 3rd character is the range separation\n"); log(" character when creating multi-bit wires. the default is '[]:'.\n"); log("\n"); log(" -ports\n"); diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc index ea10cdf8..873ee7a1 100644 --- a/passes/fsm/fsm_recode.cc +++ b/passes/fsm/fsm_recode.cc @@ -55,7 +55,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs log("Recoding FSM `%s' from module `%s' using `%s' encoding:\n", cell->name.c_str(), module->name.c_str(), encoding.c_str()); if (encoding != "none" && encoding != "one-hot" && encoding != "binary" && encoding != "auto") { - log(" unkown encoding `%s': using auto instead.\n", encoding.c_str()); + log(" unknown encoding `%s': using auto instead.\n", encoding.c_str()); encoding = "auto"; } diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 2f28afb2..14bf8d1b 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -216,7 +216,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla int idx = it.second.first, num = it.second.second; if (design->modules_.count(cell->type) == 0) - log_error("Array cell `%s.%s' of unkown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); + log_error("Array cell `%s.%s' of unknown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); RTLIL::Module *mod = design->modules_[cell->type]; @@ -232,7 +232,7 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla } } if (mod->wires_.count(portname) == 0) - log_error("Array cell `%s.%s' connects to unkown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); + log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); int port_size = mod->wires_.at(portname)->width; if (conn_size == port_size) continue; @@ -294,7 +294,7 @@ struct HierarchyPass : public Pass { log(" hierarchy [-check] [-top ]\n"); log(" hierarchy -generate \n"); log("\n"); - log("In parametric designs, a module might exists in serveral variations with\n"); + log("In parametric designs, a module might exists in several variations with\n"); log("different parameter values. This pass looks at all modules in the current\n"); log("design an re-runs the language frontends for the parametric modules as\n"); log("needed.\n"); @@ -309,7 +309,7 @@ struct HierarchyPass : public Pass { log("\n"); log(" -libdir \n"); log(" search for files named .v in the specified directory\n"); - log(" for unkown modules and automatically run read_verilog for each\n"); + log(" for unknown modules and automatically run read_verilog for each\n"); log(" unknown module.\n"); log("\n"); log(" -keep_positionals\n"); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index ace6eeaf..3ae0cd2c 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -720,7 +720,7 @@ struct MemorySharePass : public Pass { log(" address, then this feedback path is converted to a write port with\n"); log(" byte/part enable signals.\n"); log("\n"); - log(" - When multiple write ports access the same adress then this is converted\n"); + log(" - When multiple write ports access the same address then this is converted\n"); log(" to a single write port with a more complex data and/or enable logic path.\n"); log("\n"); log(" - When multiple write ports are never accessed at the same time (a SAT\n"); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index cc4fe4cc..5046752f 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -367,10 +367,10 @@ struct CleanPass : public Pass { log("\n"); log("This is identical to 'opt_clean', but less verbose.\n"); log("\n"); - log("When commands are seperated using the ';;' token, this command will be executed\n"); + log("When commands are separated using the ';;' token, this command will be executed\n"); log("between the commands.\n"); log("\n"); - log("When commands are seperated using the ';;;' token, this command will be executed\n"); + log("When commands are separated using the ';;;' token, this command will be executed\n"); log("in -purge mode between the commands.\n"); log("\n"); } diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 08ae9e92..fd0abf4a 100644 --- a/passes/sat/sat.cc +++ b/passes/sat/sat.cc @@ -874,7 +874,7 @@ struct SatPass : public Pass { log(" -set-def-at \n"); log(" -set-any-undef-at \n"); log(" -set-all-undef-at \n"); - log(" add undef contraints in the given timestep.\n"); + log(" add undef constraints in the given timestep.\n"); log("\n"); log(" -set-init \n"); log(" set the initial value for the register driving the signal to the value\n"); From e1743b3bac8c86f3cf857892dabf66bec5573a7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 11:46:07 +0200 Subject: [PATCH 692/750] Added "test_cell -script" --- passes/tests/test_cell.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index f82bbfeb..26aad435 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -380,6 +380,9 @@ struct TestCellPass : public Pass { log(" -simplib\n"); log(" use \"techmap -map +/simlib.v -max_iter 2 -autoproc\"\n"); log("\n"); + log(" -script {script_file}\n"); + log(" instead of calling \"techmap\", call \"script {script_file}\".\n"); + log("\n"); log(" -v\n"); log(" print additional debug information to the console\n"); log("\n"); @@ -416,6 +419,10 @@ struct TestCellPass : public Pass { num_iter = 1; continue; } + if (args[argidx] == "-script" && argidx+1 < SIZE(args)) { + techmap_cmd = "script " + args[++argidx]; + continue; + } if (args[argidx] == "-simlib") { techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc"; continue; @@ -540,7 +547,7 @@ struct TestCellPass : public Pass { Frontend::frontend_call(design, NULL, std::string(), "ilang " + ilang_file); else create_gold_module(design, cell_type, cell_types.at(cell_type)); - Pass::call(design, stringf("copy gold gate; %s gate; opt gate", techmap_cmd.c_str())); + Pass::call(design, stringf("copy gold gate; cd gate; %s; cd ..; opt -fast gate", techmap_cmd.c_str())); Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter"); if (verbose) Pass::call(design, "dump gate"); From 76f8128123a546c06dcb4624e8c8ed4255a030c5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 12:10:57 +0200 Subject: [PATCH 693/750] Fixed autotest for non-basename arguments --- tests/tools/autotest.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 5003280e..102c021e 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -105,6 +105,9 @@ do body() { cd ${bn}.out + fn=$(basename $fn) + bn=$(basename $bn) + cp ../$fn $fn if [ ! -f ../${bn}_tb.v ]; then "$toolsdir"/../../yosys -b "test_autotb $autotb_opts" -o ${bn}_tb.v $fn From b847ec8a0bfb3b729278f1132ae2819676498ee7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 15:47:46 +0200 Subject: [PATCH 694/750] Added $macc cell type --- kernel/celltypes.h | 11 ++- kernel/macc.h | 171 ++++++++++++++++++++++++++++++++++++++ kernel/rtlil.cc | 14 +++- passes/tests/test_cell.cc | 55 +++++++++++- 4 files changed, 242 insertions(+), 9 deletions(-) create mode 100644 kernel/macc.h diff --git a/kernel/celltypes.h b/kernel/celltypes.h index a8d88603..74e9f1fd 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -20,12 +20,9 @@ #ifndef CELLTYPES_H #define CELLTYPES_H -#include -#include -#include +#include -#include -#include +YOSYS_NAMESPACE_BEGIN struct CellType { @@ -96,7 +93,7 @@ struct CellTypes "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", "$add", "$sub", "$mul", "$div", "$mod", "$pow", - "$logic_and", "$logic_or", "$concat" + "$logic_and", "$logic_or", "$concat", "$macc" }; for (auto type : unary_ops) @@ -361,5 +358,7 @@ struct CellTypes } }; +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/macc.h b/kernel/macc.h new file mode 100644 index 00000000..362acab2 --- /dev/null +++ b/kernel/macc.h @@ -0,0 +1,171 @@ +/* + * 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. + * + */ + +#ifndef MACC_H +#define MACC_H + +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +struct Macc +{ + struct port_t { + RTLIL::SigSpec in_a, in_b; + bool is_signed, do_subtract; + }; + + std::vector ports; + RTLIL::SigSpec bit_ports; + + void from_cell(RTLIL::Cell *cell) + { + RTLIL::SigSpec port_a = cell->getPort("\\A"); + + ports.clear(); + bit_ports = cell->getPort("\\B"); + + std::vector config_bits = cell->getParam("\\CONFIG").bits; + int config_width = cell->getParam("\\CONFIG_WIDTH").as_int(); + int config_cursor = 0; + + log_assert(SIZE(config_bits) >= config_width); + + int num_bits = 0; + if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 1; + if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 2; + if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 4; + if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 8; + + int port_a_cursor = 0; + while (port_a_cursor < SIZE(port_a)) + { + log_assert(config_cursor + 2 + 2*num_bits <= config_width); + + port_t this_port; + this_port.is_signed = config_bits[config_cursor++] == RTLIL::S1; + this_port.do_subtract = config_bits[config_cursor++] == RTLIL::S1; + + int size_a = 0; + for (int i = 0; i < num_bits; i++) + if (config_bits[config_cursor++] == RTLIL::S1) + size_a |= 1 << i; + + this_port.in_a = port_a.extract(port_a_cursor, size_a); + port_a_cursor += size_a; + + int size_b = 0; + for (int i = 0; i < num_bits; i++) + if (config_bits[config_cursor++] == RTLIL::S1) + size_b |= 1 << i; + + this_port.in_b = port_a.extract(port_a_cursor, size_b); + port_a_cursor += size_b; + + if (size_a || size_b) + ports.push_back(this_port); + } + + log_assert(config_cursor == config_width); + log_assert(port_a_cursor == SIZE(port_a)); + } + + void to_cell(RTLIL::Cell *cell) const + { + RTLIL::SigSpec port_a; + std::vector config_bits; + int max_size = 0, num_bits = 0; + + for (auto &port : ports) { + max_size = std::max(max_size, SIZE(port.in_a)); + max_size = std::max(max_size, SIZE(port.in_b)); + } + + while (max_size) + num_bits++, max_size /= 2; + + log_assert(num_bits < 16); + config_bits.push_back(num_bits & 1 ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(num_bits & 2 ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(num_bits & 4 ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(num_bits & 8 ? RTLIL::S1 : RTLIL::S0); + + for (auto &port : ports) + { + if (SIZE(port.in_a) == 0) + continue; + + config_bits.push_back(port.is_signed ? RTLIL::S1 : RTLIL::S0); + config_bits.push_back(port.do_subtract ? RTLIL::S1 : RTLIL::S0); + + int size_a = SIZE(port.in_a); + for (int i = 0; i < num_bits; i++) + config_bits.push_back(size_a & (1 << i) ? RTLIL::S1 : RTLIL::S0); + + int size_b = SIZE(port.in_b); + for (int i = 0; i < num_bits; i++) + config_bits.push_back(size_b & (1 << i) ? RTLIL::S1 : RTLIL::S0); + + port_a.append(port.in_a); + port_a.append(port.in_b); + } + + cell->setPort("\\A", port_a); + cell->setPort("\\B", bit_ports); + cell->setParam("\\CONFIG", config_bits); + cell->setParam("\\CONFIG_WIDTH", SIZE(config_bits)); + cell->setParam("\\A_WIDTH", SIZE(port_a)); + cell->setParam("\\B_WIDTH", SIZE(bit_ports)); + } + + bool eval(RTLIL::Const &result) const + { + for (auto &bit : result.bits) + bit = RTLIL::S0; + + for (auto &port : ports) + { + if (!port.in_a.is_fully_const() || !port.in_b.is_fully_const()) + return false; + + RTLIL::Const summand; + if (SIZE(port.in_b) == 0) + summand = const_pos(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, SIZE(result)); + else + summand = const_mul(port.in_a.as_const(), port.in_b.as_const(), port.is_signed, port.is_signed, SIZE(result)); + + if (port.do_subtract) + result = const_sub(result, summand, port.is_signed, port.is_signed, SIZE(result)); + else + result = const_add(result, summand, port.is_signed, port.is_signed, SIZE(result)); + } + + for (auto bit : bit_ports) { + if (bit.wire) + return false; + result = const_add(result, bit.data, false, false, SIZE(result)); + } + + return true; + } +}; + +YOSYS_NAMESPACE_END + +#endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 08c79bea..97a2946a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -18,6 +18,7 @@ */ #include "kernel/yosys.h" +#include "kernel/macc.h" #include "frontends/verilog/verilog_frontend.h" #include "backends/ilang/ilang_backend.h" @@ -633,6 +634,17 @@ namespace { return; } + if (cell->type == "$macc") { + param("\\CONFIG"); + param("\\CONFIG_WIDTH"); + port("\\A", param("\\A_WIDTH")); + port("\\B", param("\\B_WIDTH")); + port("\\Y", param("\\Y_WIDTH")); + check_expected(); + Macc().from_cell(cell); + return; + } + if (cell->type == "$logic_not") { param_bool("\\A_SIGNED"); port("\\A", param("\\A_WIDTH")); @@ -1781,7 +1793,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) return; } - bool signedness_ab = !type.in("$slice", "$concat"); + bool signedness_ab = !type.in("$slice", "$concat", "$macc"); if (connections_.count("\\A")) { if (signedness_ab) { diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 26aad435..96f08de4 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -21,6 +21,7 @@ #include "kernel/yosys.h" #include "kernel/satgen.h" #include "kernel/consteval.h" +#include "kernel/macc.h" #include static uint32_t xorshift32_state = 123456789; @@ -38,6 +39,53 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); RTLIL::Wire *wire; + if (cell_type == "$macc") + { + Macc macc; + int width = 1 + xorshift32(16); + int depth = 1 + xorshift32(6); + int mulbits = 0; + + RTLIL::Wire *wire_a = module->addWire("\\A"); + wire_a->width = 0; + wire_a->port_input = true; + + for (int i = 0; i < depth; i++) + { + int size_a = xorshift32(width) + 1; + int size_b = xorshift32(width) + 1; + + if (mulbits + size_a*size_b > 256 || xorshift32(2) == 1) + size_b = 0; + else + mulbits += size_a*size_b; + + Macc::port_t this_port; + + wire_a->width += size_a; + this_port.in_a = RTLIL::SigSpec(wire_a, wire_a->width - size_a, size_a); + + wire_a->width += size_b; + this_port.in_b = RTLIL::SigSpec(wire_a, wire_a->width - size_b, size_b); + + this_port.is_signed = xorshift32(2) == 1; + this_port.do_subtract = xorshift32(2) == 1; + macc.ports.push_back(this_port); + } + + wire = module->addWire("\\B"); + wire->width = xorshift32(xorshift32(16)+1); + wire->port_input = true; + macc.bit_ports = wire; + + wire = module->addWire("\\Y"); + wire->width = width; + wire->port_output = true; + cell->setPort("\\Y", wire); + + macc.to_cell(cell); + } + if (cell_type == "$lut") { int width = 1 + xorshift32(6); @@ -440,8 +488,10 @@ struct TestCellPass : public Pass { break; } - if (xorshift32_state == 0) - xorshift32_state = time(NULL); + if (xorshift32_state == 0) { + xorshift32_state = time(NULL) & 0x7fffffff; + log("Rng seed value: %d\n", int(xorshift32_state)); + } std::map cell_types; std::vector selected_cell_types; @@ -496,6 +546,7 @@ struct TestCellPass : public Pass { cell_types["$lut"] = "*"; cell_types["$alu"] = "ABSY"; + cell_types["$macc"] = "*"; for (; argidx < SIZE(args); argidx++) { From deff416ea7d60b490b0e4f8d70abdb1ad8d4d0f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 17:58:27 +0200 Subject: [PATCH 695/750] Fixed assignment of out-of bounds array element --- frontends/ast/genrtlil.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 0c7be1f5..f87a68f6 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; From bff4706b62ca73ba0a627eda2ad903b487634cae Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 17:59:12 +0200 Subject: [PATCH 696/750] Added $macc simlib model (also use as techmap rule for now) --- techlibs/common/simlib.v | 86 +++++++++++++++++++++++++++++++++++++++ techlibs/common/techmap.v | 86 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 17700a61..eabd6595 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -755,6 +755,92 @@ endmodule // -------------------------------------------------------- +module \$macc (A, B, Y); + parameter A_WIDTH = 0; + parameter B_WIDTH = 0; + parameter Y_WIDTH = 0; + parameter CONFIG = 4'b0000; + parameter CONFIG_WIDTH = 4; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output reg [Y_WIDTH-1:0] Y; + + localparam integer num_bits = CONFIG[3:0]; + localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); + localparam integer num_abits = $clog2(A_WIDTH); + + function [2*num_ports*num_abits-1:0] get_port_offsets; + input [CONFIG_WIDTH-1:0] CONFIG; + integer i, cursor; + begin + cursor = 0; + get_port_offsets = 0; + for (i = 0; i < num_ports; i = i+1) begin + get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; + cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; + get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; + cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; + end + end + endfunction + + localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); + + `define PORT_IS_SIGNED (0 + CONFIG[4 + i*(2 + 2*num_bits)]) + `define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1]) + `define PORT_SIZE_A (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]) + `define PORT_SIZE_B (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]) + `define PORT_OFFSET_A (0 + port_offsets[2*i*num_abits +: num_abits]) + `define PORT_OFFSET_B (0 + port_offsets[2*i*num_abits + num_abits +: num_abits]) + + integer i, j; + reg [Y_WIDTH-1:0] tmp_a, tmp_b; + + always @* begin + Y = 0; + for (i = 0; i < num_ports; i = i+1) + begin + tmp_a = 0; + tmp_b = 0; + + for (j = 0; j < `PORT_SIZE_A; j = j+1) + tmp_a[j] = A[`PORT_OFFSET_A + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0) + for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1) + tmp_a[j] = tmp_a[`PORT_SIZE_A-1]; + + for (j = 0; j < `PORT_SIZE_B; j = j+1) + tmp_b[j] = A[`PORT_OFFSET_B + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0) + for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1) + tmp_b[j] = tmp_b[`PORT_SIZE_B-1]; + + if (`PORT_SIZE_B > 0) + tmp_a = tmp_a * tmp_b; + + if (`PORT_DO_SUBTRACT) + Y = Y - tmp_a; + else + Y = Y + tmp_a; + end + for (i = 0; i < B_WIDTH; i = i+1) begin + Y = Y + B[i]; + end + end + + `undef PORT_IS_SIGNED + `undef PORT_DO_SUBTRACT + `undef PORT_SIZE_A + `undef PORT_SIZE_B + `undef PORT_OFFSET_A + `undef PORT_OFFSET_B +endmodule + +// -------------------------------------------------------- + module \$div (A, B, Y); parameter A_SIGNED = 0; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index fccbe2f8..8237a737 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -579,6 +579,92 @@ module \$mul (A, B, Y); ); endmodule +module \$macc (A, B, Y); + parameter A_WIDTH = 0; + parameter B_WIDTH = 0; + parameter Y_WIDTH = 0; + parameter CONFIG = 4'b0000; + parameter CONFIG_WIDTH = 4; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output reg [Y_WIDTH-1:0] Y; + + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; + + localparam integer num_bits = CONFIG[3:0]; + localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); + localparam integer num_abits = $clog2(A_WIDTH); + + function [2*num_ports*num_abits-1:0] get_port_offsets; + input [CONFIG_WIDTH-1:0] CONFIG; + integer i, cursor; + begin + cursor = 0; + get_port_offsets = 0; + for (i = 0; i < num_ports; i = i+1) begin + get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; + cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; + get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; + cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; + end + end + endfunction + + localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); + + `define PORT_IS_SIGNED (0 + CONFIG[4 + i*(2 + 2*num_bits)]) + `define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1]) + `define PORT_SIZE_A (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]) + `define PORT_SIZE_B (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]) + `define PORT_OFFSET_A (0 + port_offsets[2*i*num_abits +: num_abits]) + `define PORT_OFFSET_B (0 + port_offsets[2*i*num_abits + num_abits +: num_abits]) + + integer i, j; + reg [Y_WIDTH-1:0] tmp_a, tmp_b; + + always @* begin + Y = 0; + for (i = 0; i < num_ports; i = i+1) + begin + tmp_a = 0; + tmp_b = 0; + + for (j = 0; j < `PORT_SIZE_A; j = j+1) + tmp_a[j] = A[`PORT_OFFSET_A + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0) + for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1) + tmp_a[j] = tmp_a[`PORT_SIZE_A-1]; + + for (j = 0; j < `PORT_SIZE_B; j = j+1) + tmp_b[j] = A[`PORT_OFFSET_B + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0) + for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1) + tmp_b[j] = tmp_b[`PORT_SIZE_B-1]; + + if (`PORT_SIZE_B > 0) + tmp_a = tmp_a * tmp_b; + + if (`PORT_DO_SUBTRACT) + Y = Y - tmp_a; + else + Y = Y + tmp_a; + end + for (i = 0; i < B_WIDTH; i = i+1) begin + Y = Y + B[i]; + end + end + + `undef PORT_IS_SIGNED + `undef PORT_DO_SUBTRACT + `undef PORT_SIZE_A + `undef PORT_SIZE_B + `undef PORT_OFFSET_A + `undef PORT_OFFSET_B +endmodule + // -------------------------------------------------------- // Divide and Modulo From 680eaaac41bc64000faa483955279155b0fc0a6b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 19:31:04 +0200 Subject: [PATCH 697/750] Fixed $clog2 (off by one error) --- frontends/ast/simplify.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 1998c12e..9e797573 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; From fa64942018a39085301d7f24832ad0ad7b0d22f1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 19:44:11 +0200 Subject: [PATCH 698/750] Added $macc SAT model --- kernel/satgen.h | 71 +++++++++++++++++++++++++++++++++++++++ passes/tests/test_cell.cc | 11 +++--- techlibs/common/simlib.v | 6 ++-- techlibs/common/techmap.v | 6 ++-- 4 files changed, 83 insertions(+), 11 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index ae155a2e..3429f823 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -23,6 +23,7 @@ #include "kernel/rtlil.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/macc.h" #include "libs/ezsat/ezminisat.h" typedef ezMiniSAT ezDefaultSAT; @@ -762,6 +763,76 @@ struct SatGen return true; } + if (cell->type == "$macc") + { + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + + Macc macc; + macc.from_cell(cell); + + std::vector tmp(SIZE(y), ez->FALSE); + + for (auto &port : macc.ports) + { + std::vector in_a = importDefSigSpec(port.in_a, timestep); + std::vector in_b = importDefSigSpec(port.in_b, timestep); + + while (SIZE(in_a) < SIZE(y)) + in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() : ez->FALSE); + in_a.resize(SIZE(y)); + + if (SIZE(in_b)) + { + while (SIZE(in_b) < SIZE(y)) + in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() : ez->FALSE); + in_b.resize(SIZE(y)); + + for (int i = 0; i < SIZE(in_b); i++) { + std::vector shifted_a(in_a.size(), ez->FALSE); + for (int j = i; j < int(in_a.size()); j++) + shifted_a.at(j) = in_a.at(j-i); + if (port.do_subtract) + tmp = ez->vec_ite(in_b.at(i), ez->vec_sub(tmp, shifted_a), tmp); + else + tmp = ez->vec_ite(in_b.at(i), ez->vec_add(tmp, shifted_a), tmp); + } + } + else + { + if (port.do_subtract) + tmp = ez->vec_sub(tmp, in_a); + else + tmp = ez->vec_add(tmp, in_a); + } + } + + for (int i = 0; i < SIZE(b); i++) { + std::vector val(SIZE(y), ez->FALSE); + val.at(0) = b.at(i); + tmp = ez->vec_add(tmp, val); + } + + if (model_undef) + { + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + + int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); + int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); + + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + ez->assume(ez->vec_eq(undef_y, std::vector(SIZE(y), ez->OR(undef_any_a, undef_any_b)))); + + undefGating(y, tmp, undef_y); + } + else + ez->assume(ez->vec_eq(y, tmp)); + + return true; + } + if (cell->type == "$div" || cell->type == "$mod") { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 96f08de4..edab51eb 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -42,9 +42,9 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, if (cell_type == "$macc") { Macc macc; - int width = 1 + xorshift32(16); + int width = 1 + xorshift32(8); int depth = 1 + xorshift32(6); - int mulbits = 0; + int mulbits_a = 0, mulbits_b = 0; RTLIL::Wire *wire_a = module->addWire("\\A"); wire_a->width = 0; @@ -55,10 +55,11 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, int size_a = xorshift32(width) + 1; int size_b = xorshift32(width) + 1; - if (mulbits + size_a*size_b > 256 || xorshift32(2) == 1) + if (mulbits_a + size_a*size_b <= 96 && mulbits_b + size_a + size_b <= 16 && xorshift32(2) == 1) { + mulbits_a += size_a * size_b; + mulbits_b += size_a + size_b; + } else size_b = 0; - else - mulbits += size_a*size_b; Macc::port_t this_port; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index eabd6595..b1f871d9 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -771,16 +771,16 @@ module \$macc (A, B, Y); localparam integer num_abits = $clog2(A_WIDTH); function [2*num_ports*num_abits-1:0] get_port_offsets; - input [CONFIG_WIDTH-1:0] CONFIG; + input [CONFIG_WIDTH-1:0] cfg; integer i, cursor; begin cursor = 0; get_port_offsets = 0; for (i = 0; i < num_ports; i = i+1) begin get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; - cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; - cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; end end endfunction diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 8237a737..f0397858 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -597,16 +597,16 @@ module \$macc (A, B, Y); localparam integer num_abits = $clog2(A_WIDTH); function [2*num_ports*num_abits-1:0] get_port_offsets; - input [CONFIG_WIDTH-1:0] CONFIG; + input [CONFIG_WIDTH-1:0] cfg; integer i, cursor; begin cursor = 0; get_port_offsets = 0; for (i = 0; i < num_ports; i = i+1) begin get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; - cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; - cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; end end endfunction From 98e6463ca78d8c0a342c9b86d9223dbeb45c093c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 19:44:28 +0200 Subject: [PATCH 699/750] Added $macc eval model --- kernel/consteval.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/kernel/consteval.h b/kernel/consteval.h index c73a0b35..f995c9cc 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -23,6 +23,7 @@ #include "kernel/rtlil.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" +#include "kernel/macc.h" struct ConstEval { @@ -210,6 +211,27 @@ struct ConstEval } } } + else if (cell->type == "$macc") + { + Macc macc; + macc.from_cell(cell); + + if (!eval(macc.bit_ports, undef, cell)) + return false; + + for (auto &port : macc.ports) { + if (!eval(port.in_a, undef, cell)) + return false; + if (!eval(port.in_b, undef, cell)) + return false; + } + + RTLIL::Const result(0, SIZE(cell->getPort("\\Y"))); + if (!macc.eval(result)) + log_abort(); + + set(cell->getPort("\\Y"), result); + } else { RTLIL::SigSpec sig_c, sig_d; From 9329a768181d3765a08c3b264c8b0031b732c0d4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 20:30:46 +0200 Subject: [PATCH 700/750] Various bug fixes (related to $macc model testing) --- backends/verilog/verilog_backend.cc | 3 ++- passes/tests/test_cell.cc | 2 +- techlibs/common/simlib.v | 2 +- techlibs/common/techmap.v | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 82a2c519..bbdbbbfa 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -973,7 +973,8 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) for (int i = 0; i < wire->width; i++) if (reg_bits.count(std::pair(wire, i)) == 0) goto this_wire_aint_reg; - reg_wires.insert(wire->name); + if (wire->width) + reg_wires.insert(wire->name); this_wire_aint_reg:; } } diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index edab51eb..c69bd123 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -262,7 +262,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_n gold_ce.set(gold_wire, in_value); gate_ce.set(gate_wire, in_value); - if (vlog_file.is_open()) { + if (vlog_file.is_open() && SIZE(in_value) > 0) { vlog_file << stringf(" %s = 'b%s;\n", log_id(gold_wire), in_value.as_string().c_str()); if (!vlog_pattern_info.empty()) vlog_pattern_info += " "; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index b1f871d9..465efc0a 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -768,7 +768,7 @@ module \$macc (A, B, Y); localparam integer num_bits = CONFIG[3:0]; localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); - localparam integer num_abits = $clog2(A_WIDTH); + localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; function [2*num_ports*num_abits-1:0] get_port_offsets; input [CONFIG_WIDTH-1:0] cfg; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index f0397858..3fc6ccb8 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -594,7 +594,7 @@ module \$macc (A, B, Y); localparam integer num_bits = CONFIG[3:0]; localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); - localparam integer num_abits = $clog2(A_WIDTH); + localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; function [2*num_ports*num_abits-1:0] get_port_offsets; input [CONFIG_WIDTH-1:0] cfg; From 15b3c54fea80b7ccfd02c66c28ed38c610e23254 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 17:05:41 +0200 Subject: [PATCH 701/750] Added "test_cell -nosat" --- passes/tests/test_cell.cc | 140 +++++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 63 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index c69bd123..a38023d1 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -53,7 +53,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, for (int i = 0; i < depth; i++) { int size_a = xorshift32(width) + 1; - int size_b = xorshift32(width) + 1; + int size_b = depth > 4 ? 0 : xorshift32(width) + 1; if (mulbits_a + size_a*size_b <= 96 && mulbits_b + size_a + size_b <= 16 && xorshift32(2) == 1) { mulbits_a += size_a * size_b; @@ -75,7 +75,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, } wire = module->addWire("\\B"); - wire->width = xorshift32(xorshift32(16)+1); + wire->width = xorshift32(mulbits_a ? xorshift32(4)+1 : xorshift32(16)+1); wire->port_input = true; macc.bit_ports = wire; @@ -171,7 +171,7 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->check(); } -static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_name, std::ofstream &vlog_file) +static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std::string uut_name, std::ofstream &vlog_file) { log("Eval testing:%c", verbose ? '\n' : ' '); @@ -185,10 +185,11 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_n SatGen satgen2(&ez2, &sigmap); satgen2.model_undef = true; - for (auto cell : gold_mod->cells()) { - satgen1.importCell(cell); - satgen2.importCell(cell); - } + if (!nosat) + for (auto cell : gold_mod->cells()) { + satgen1.importCell(cell); + satgen2.importCell(cell); + } if (vlog_file.is_open()) { @@ -325,68 +326,71 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, std::string uut_n if (verbose) log("EVAL: %s\n", out_val.as_string().c_str()); - std::vector sat1_in_sig = satgen1.importSigSpec(in_sig); - std::vector sat1_in_val = satgen1.importSigSpec(in_val); + if (!nosat) + { + std::vector sat1_in_sig = satgen1.importSigSpec(in_sig); + std::vector sat1_in_val = satgen1.importSigSpec(in_val); - std::vector sat1_model = satgen1.importSigSpec(out_sig); - std::vector sat1_model_value; + std::vector sat1_model = satgen1.importSigSpec(out_sig); + std::vector sat1_model_value; - if (!ez1.solve(sat1_model, sat1_model_value, ez1.vec_eq(sat1_in_sig, sat1_in_val))) - log_error("Evaluating sat model 1 (no undef modeling) failed!\n"); + if (!ez1.solve(sat1_model, sat1_model_value, ez1.vec_eq(sat1_in_sig, sat1_in_val))) + log_error("Evaluating sat model 1 (no undef modeling) failed!\n"); - if (verbose) { - log("SAT 1: "); - for (int i = SIZE(out_sig)-1; i >= 0; i--) - log("%c", sat1_model_value.at(i) ? '1' : '0'); - log("\n"); - } + if (verbose) { + log("SAT 1: "); + for (int i = SIZE(out_sig)-1; i >= 0; i--) + log("%c", sat1_model_value.at(i) ? '1' : '0'); + log("\n"); + } - for (int i = 0; i < SIZE(out_sig); i++) { - if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) - continue; - if (out_val[i] == RTLIL::S0 && sat1_model_value.at(i) == false) - continue; - if (out_val[i] == RTLIL::S1 && sat1_model_value.at(i) == true) - continue; - log_error("Mismatch in sat model 1 (no undef modeling) output!\n"); - } - - std::vector sat2_in_def_sig = satgen2.importDefSigSpec(in_sig); - std::vector sat2_in_def_val = satgen2.importDefSigSpec(in_val); - - std::vector sat2_in_undef_sig = satgen2.importUndefSigSpec(in_sig); - std::vector sat2_in_undef_val = satgen2.importUndefSigSpec(in_val); - - std::vector sat2_model_def_sig = satgen2.importDefSigSpec(out_sig); - std::vector sat2_model_undef_sig = satgen2.importUndefSigSpec(out_sig); - - std::vector sat2_model; - sat2_model.insert(sat2_model.end(), sat2_model_def_sig.begin(), sat2_model_def_sig.end()); - sat2_model.insert(sat2_model.end(), sat2_model_undef_sig.begin(), sat2_model_undef_sig.end()); - - std::vector sat2_model_value; - - if (!ez2.solve(sat2_model, sat2_model_value, ez2.vec_eq(sat2_in_def_sig, sat2_in_def_val), ez2.vec_eq(sat2_in_undef_sig, sat2_in_undef_val))) - log_error("Evaluating sat model 2 (undef modeling) failed!\n"); - - if (verbose) { - log("SAT 2: "); - for (int i = SIZE(out_sig)-1; i >= 0; i--) - log("%c", sat2_model_value.at(SIZE(out_sig) + i) ? 'x' : sat2_model_value.at(i) ? '1' : '0'); - log("\n"); - } - - for (int i = 0; i < SIZE(out_sig); i++) { - if (sat2_model_value.at(SIZE(out_sig) + i)) { + for (int i = 0; i < SIZE(out_sig); i++) { if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) continue; - } else { - if (out_val[i] == RTLIL::S0 && sat2_model_value.at(i) == false) + if (out_val[i] == RTLIL::S0 && sat1_model_value.at(i) == false) continue; - if (out_val[i] == RTLIL::S1 && sat2_model_value.at(i) == true) + if (out_val[i] == RTLIL::S1 && sat1_model_value.at(i) == true) continue; + log_error("Mismatch in sat model 1 (no undef modeling) output!\n"); + } + + std::vector sat2_in_def_sig = satgen2.importDefSigSpec(in_sig); + std::vector sat2_in_def_val = satgen2.importDefSigSpec(in_val); + + std::vector sat2_in_undef_sig = satgen2.importUndefSigSpec(in_sig); + std::vector sat2_in_undef_val = satgen2.importUndefSigSpec(in_val); + + std::vector sat2_model_def_sig = satgen2.importDefSigSpec(out_sig); + std::vector sat2_model_undef_sig = satgen2.importUndefSigSpec(out_sig); + + std::vector sat2_model; + sat2_model.insert(sat2_model.end(), sat2_model_def_sig.begin(), sat2_model_def_sig.end()); + sat2_model.insert(sat2_model.end(), sat2_model_undef_sig.begin(), sat2_model_undef_sig.end()); + + std::vector sat2_model_value; + + if (!ez2.solve(sat2_model, sat2_model_value, ez2.vec_eq(sat2_in_def_sig, sat2_in_def_val), ez2.vec_eq(sat2_in_undef_sig, sat2_in_undef_val))) + log_error("Evaluating sat model 2 (undef modeling) failed!\n"); + + if (verbose) { + log("SAT 2: "); + for (int i = SIZE(out_sig)-1; i >= 0; i--) + log("%c", sat2_model_value.at(SIZE(out_sig) + i) ? 'x' : sat2_model_value.at(i) ? '1' : '0'); + log("\n"); + } + + for (int i = 0; i < SIZE(out_sig); i++) { + if (sat2_model_value.at(SIZE(out_sig) + i)) { + if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) + continue; + } else { + if (out_val[i] == RTLIL::S0 && sat2_model_value.at(i) == false) + continue; + if (out_val[i] == RTLIL::S1 && sat2_model_value.at(i) == true) + continue; + } + log_error("Mismatch in sat model 2 (undef modeling) output!\n"); } - log_error("Mismatch in sat model 2 (undef modeling) output!\n"); } } @@ -432,6 +436,9 @@ struct TestCellPass : public Pass { log(" -script {script_file}\n"); log(" instead of calling \"techmap\", call \"script {script_file}\".\n"); log("\n"); + log(" -nosat\n"); + log(" do not check SAT model or run SAT equivalence checking\n"); + log("\n"); log(" -v\n"); log(" print additional debug information to the console\n"); log("\n"); @@ -447,6 +454,7 @@ struct TestCellPass : public Pass { xorshift32_state = 0; std::ofstream vlog_file; bool verbose = false; + bool nosat = false; int argidx; for (argidx = 1; argidx < SIZE(args); argidx++) @@ -476,6 +484,10 @@ struct TestCellPass : public Pass { techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc"; continue; } + if (args[argidx] == "-nosat") { + nosat = true; + continue; + } if (args[argidx] == "-v") { verbose = true; continue; @@ -600,11 +612,13 @@ struct TestCellPass : public Pass { else create_gold_module(design, cell_type, cell_types.at(cell_type)); Pass::call(design, stringf("copy gold gate; cd gate; %s; cd ..; opt -fast gate", techmap_cmd.c_str())); - Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter"); + if (!nosat) + Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter"); if (verbose) Pass::call(design, "dump gate"); Pass::call(design, "dump gold"); - Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); + if (!nosat) + Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); std::string uut_name = stringf("uut_%s_%d", cell_type.substr(1).c_str(), i); if (vlog_file.is_open()) { Pass::call(design, stringf("copy gold %s_expr; select %s_expr", uut_name.c_str(), uut_name.c_str())); @@ -613,7 +627,7 @@ struct TestCellPass : public Pass { Backend::backend_call(design, &vlog_file, "", "verilog -selected -noexpr"); uut_names.push_back(uut_name); } - run_eval_test(design, verbose, uut_name, vlog_file); + run_eval_test(design, verbose, nosat, uut_name, vlog_file); delete design; } From 015dcdc84c5d0f9c899b520c9718ce32c9d2c8f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 18:23:04 +0200 Subject: [PATCH 702/750] Added "maccmap" command --- passes/techmap/Makefile.inc | 1 + passes/techmap/maccmap.cc | 318 ++++++++++++++++++++++++++++++++++++ 2 files changed, 319 insertions(+) create mode 100644 passes/techmap/maccmap.cc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index b49259a8..da527ccf 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -8,6 +8,7 @@ ifneq ($(SMALL),1) OBJS += passes/techmap/iopadmap.o OBJS += passes/techmap/hilomap.o OBJS += passes/techmap/extract.o +OBJS += passes/techmap/maccmap.o endif GENFILES += passes/techmap/techmap.inc diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc new file mode 100644 index 00000000..49850c0a --- /dev/null +++ b/passes/techmap/maccmap.cc @@ -0,0 +1,318 @@ +/* + * 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/yosys.h" +#include "kernel/macc.h" + +extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false); + +struct MaccmapWorker +{ + std::vector> bits; + RTLIL::Module *module; + int width; + + MaccmapWorker(RTLIL::Module *module, int width) : module(module), width(width) + { + bits.resize(width); + } + + void add(RTLIL::SigBit bit, int position) + { + if (position >= width || bit == RTLIL::S0) + return; + + if (bits.at(position).count(bit)) { + bits.at(position).erase(bit); + add(bit, position+1); + } else { + bits.at(position).insert(bit); + } + } + + void add(RTLIL::SigSpec a, bool is_signed, bool do_subtract) + { + a.extend(width, is_signed); + + if (do_subtract) { + a = module->Not(NEW_ID, a); + add(RTLIL::S1, 0); + } + + for (int i = 0; i < width; i++) + add(a[i], i); + } + + void add(RTLIL::SigSpec a, RTLIL::SigSpec b, bool is_signed, bool do_subtract) + { + if (SIZE(a) < SIZE(b)) + std::swap(a, b); + + a.extend(width, is_signed); + + if (SIZE(b) > width) + b.extend(width, is_signed); + + for (int i = 0; i < SIZE(b); i++) + if (is_signed && i+1 == SIZE(b)) + { + a = {module->Not(NEW_ID, a.extract(i, width-i)), RTLIL::SigSpec(0, i)}; + add(module->And(NEW_ID, a, RTLIL::SigSpec(b[i], width)), false, do_subtract); + add({b[i], RTLIL::SigSpec(0, i)}, false, do_subtract); + } + else + { + add(module->And(NEW_ID, a, RTLIL::SigSpec(b[i], width)), false, do_subtract); + a = {a.extract(0, width-1), RTLIL::S0}; + } + } + + void fulladd(RTLIL::SigSpec &in1, RTLIL::SigSpec &in2, RTLIL::SigSpec &in3, RTLIL::SigSpec &out1, RTLIL::SigSpec &out2) + { + RTLIL::SigSpec t1 = module->Xor(NEW_ID, in1, in2); + out1 = module->Xor(NEW_ID, t1, in3); + + RTLIL::SigSpec t2 = module->And(NEW_ID, in1, in2); + RTLIL::SigSpec t3 = module->And(NEW_ID, in3, t1); + out2 = module->Or(NEW_ID, t2, t3); + } + + int tree_bit_slots(int n) + { + #if 0 + int retval = 0; + while (n > 2) { + retval += n / 3; + n = 2*(n / 3) + (n % 3); + } + return retval; + #else + return std::max(n - 2, 0); + #endif + } + + RTLIL::SigSpec synth() + { + std::vector summands; + std::vector tree_sum_bits; + int unique_tree_bits = 0; + + while (1) + { + RTLIL::SigSpec summand(0, width); + bool got_data_bits = false; + + for (int i = 0; i < width; i++) + if (!bits.at(i).empty()) { + auto it = bits.at(i).begin(); + summand[i] = *it; + bits.at(i).erase(it); + got_data_bits = true; + } + + if (!got_data_bits) + break; + + summands.push_back(summand); + int free_bit_slots = tree_bit_slots(SIZE(summands)) - SIZE(tree_sum_bits); + + for (int i = 0; i < width && (1 << i) <= free_bit_slots; i++) + while (!bits.at(i).empty() && (1 << i) <= free_bit_slots) { + auto it = bits.at(i).begin(); + RTLIL::SigBit bit = *it; + bits.at(i).erase(it); + for (int k = 0; k < (1 << i); k++, free_bit_slots--) + tree_sum_bits.push_back(bit); + unique_tree_bits++; + } + } + + if (!tree_sum_bits.empty()) + log(" packed %d (%d) bits into adder tree\n", SIZE(tree_sum_bits), unique_tree_bits); + + if (SIZE(summands) == 0) + return RTLIL::SigSpec(0, width); + + if (SIZE(summands) == 1) + return summands.front(); + + while (SIZE(summands) > 2) + { + std::vector new_summands; + for (int i = 0; i < SIZE(summands); i += 3) + if (i+2 < SIZE(summands)) { + RTLIL::SigSpec in1 = summands[i]; + RTLIL::SigSpec in2 = summands[i+1]; + RTLIL::SigSpec in3 = summands[i+2]; + RTLIL::SigSpec out1, out2; + fulladd(in1, in2, in3, out1, out2); + RTLIL::SigBit extra_bit = RTLIL::S0; + if (!tree_sum_bits.empty()) { + extra_bit = tree_sum_bits.back(); + tree_sum_bits.pop_back(); + } + new_summands.push_back(out1); + new_summands.push_back({out2.extract(0, width-1), extra_bit}); + } else { + new_summands.push_back(summands[i]); + i -= 2; + } + summands.swap(new_summands); + } + + return module->Add(NEW_ID, summands.front(), summands.back()); + } +}; + +void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap) +{ + int width = SIZE(cell->getPort("\\Y")); + + Macc macc; + macc.from_cell(cell); + + RTLIL::SigSpec all_input_bits; + all_input_bits.append(cell->getPort("\\A")); + all_input_bits.append(cell->getPort("\\B")); + + if (all_input_bits.to_sigbit_set().count(RTLIL::Sx)) { + module->connect(cell->getPort("\\Y"), RTLIL::SigSpec(RTLIL::Sx, width)); + return; + } + + for (auto &port : macc.ports) + if (SIZE(port.in_b) == 0) + log(" %s %s (%d bits, %s)\n", port.do_subtract ? "sub" : "add", log_signal(port.in_a), + SIZE(port.in_a), port.is_signed ? "signed" : "unsigned"); + else + log(" %s %s * %s (%dx%d bits, %s)\n", port.do_subtract ? "sub" : "add", log_signal(port.in_a), log_signal(port.in_b), + SIZE(port.in_a), SIZE(port.in_b), port.is_signed ? "signed" : "unsigned"); + + if (SIZE(macc.bit_ports) != 0) + log(" add bits %s (%d bits)\n", log_signal(macc.bit_ports), SIZE(macc.bit_ports)); + + if (unmap) + { + typedef std::pair summand_t; + std::vector summands; + + for (auto &port : macc.ports) { + summand_t this_summand; + if (SIZE(port.in_b)) { + this_summand.first = module->addWire(NEW_ID, width); + module->addMul(NEW_ID, port.in_a, port.in_b, this_summand.first, port.is_signed); + } else if (SIZE(port.in_a) != width) { + this_summand.first = module->addWire(NEW_ID, width); + module->addPos(NEW_ID, port.in_a, this_summand.first, port.is_signed); + } else { + this_summand.first = port.in_a; + } + this_summand.second = port.do_subtract; + summands.push_back(this_summand); + } + + for (auto &bit : macc.bit_ports) + summands.push_back(summand_t(bit, false)); + + if (SIZE(summands) == 0) + summands.push_back(summand_t(RTLIL::SigSpec(0, width), false)); + + while (SIZE(summands) > 1) + { + std::vector new_summands; + for (int i = 0; i < SIZE(summands); i += 2) { + if (i+1 < SIZE(summands)) { + summand_t this_summand; + this_summand.first = module->addWire(NEW_ID, width); + this_summand.second = summands[i].second && summands[i+1].second; + if (summands[i].second == summands[i+1].second) + module->addAdd(NEW_ID, summands[i].first, summands[i+1].first, this_summand.first); + else if (summands[i].second) + module->addSub(NEW_ID, summands[i+1].first, summands[i].first, this_summand.first); + else if (summands[i+1].second) + module->addSub(NEW_ID, summands[i].first, summands[i+1].first, this_summand.first); + else + log_abort(); + new_summands.push_back(this_summand); + } else + new_summands.push_back(summands[i]); + } + summands.swap(new_summands); + } + + if (summands.front().second) + module->addNeg(NEW_ID, summands.front().first, cell->getPort("\\Y")); + else + module->connect(cell->getPort("\\Y"), summands.front().first); + } + else + { + MaccmapWorker worker(module, width); + + for (auto &port : macc.ports) + if (SIZE(port.in_b) == 0) + worker.add(port.in_a, port.is_signed, port.do_subtract); + else + worker.add(port.in_a, port.in_b, port.is_signed, port.do_subtract); + + for (auto &bit : macc.bit_ports) + worker.add(bit, 0); + + module->connect(cell->getPort("\\Y"), worker.synth()); + } +} + +struct MaccmapPass : public Pass { + MaccmapPass() : Pass("maccmap", "mapping macc cells") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" maccmap [-unmap] [selection]\n"); + log("\n"); + log("This pass maps $macc cells to yosys gate primitives. When the -unmap option is\n"); + log("used then the $macc cell is mapped to $and, $sub, etc. cells instead.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + bool unmap_mode = false; + + log_header("Executing MACCMAP pass (map $macc cells).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-unmap") { + unmap_mode = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + for (auto mod : design->selected_modules()) + for (auto cell : mod->selected_cells()) + if (cell->type == "$macc") { + log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type)); + maccmap(mod, cell, unmap_mode); + mod->remove(cell); + } + } +} MaccmapPass; + From c50b841b292f82d2da1f106b4e56c5c05ac9fede Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 18:23:37 +0200 Subject: [PATCH 703/750] Added 'techmap_maccmap' techmap attribute --- passes/techmap/techmap.cc | 72 ++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 43a94d97..93ba7c40 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -31,6 +31,9 @@ // see simplemap.cc extern void simplemap_get_mappers(std::map &mappers); +// see maccmap.cc +extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false); + static void apply_prefix(std::string prefix, std::string &id) { if (id[0] == '\\') @@ -338,27 +341,35 @@ struct TechmapWorker if (!flatten_mode) { + std::string extmapper_name; + if (tpl->get_bool_attribute("\\techmap_simplemap")) + extmapper_name = "simplemap"; + + if (tpl->get_bool_attribute("\\techmap_maccmap")) + extmapper_name = "maccmap"; + + if (!extmapper_name.empty()) { cell->type = cell_type; if (extern_mode && !in_recursion) { - std::string m_name = stringf("$extern:simplemap:%s", log_id(cell->type)); + std::string m_name = stringf("$extern:%s:%s", extmapper_name.c_str(), log_id(cell->type)); for (auto &c : cell->parameters) m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second)); - RTLIL::Module *simplemap_module = design->module(m_name); + RTLIL::Module *extmapper_module = design->module(m_name); - if (simplemap_module == nullptr) + if (extmapper_module == nullptr) { - simplemap_module = design->addModule(m_name); - RTLIL::Cell *simplemap_cell = simplemap_module->addCell(cell->type, cell); + extmapper_module = design->addModule(m_name); + RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell); int port_counter = 1; - for (auto &c : simplemap_cell->connections_) { - RTLIL::Wire *w = simplemap_module->addWire(c.first, SIZE(c.second)); + for (auto &c : extmapper_cell->connections_) { + RTLIL::Wire *w = extmapper_module->addWire(c.first, SIZE(c.second)); if (w->name == "\\Y" || w->name == "\\Q") w->port_output = true; else @@ -367,25 +378,45 @@ struct TechmapWorker c.second = w; } - simplemap_module->check(); + extmapper_module->check(); - log("Creating %s with simplemap.\n", log_id(simplemap_module)); - if (simplemap_mappers.count(simplemap_cell->type) == 0) - log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(simplemap_cell->type)); - simplemap_mappers.at(simplemap_cell->type)(simplemap_module, simplemap_cell); - simplemap_module->remove(simplemap_cell); + if (extmapper_name == "simplemap") { + log("Creating %s with simplemap.\n", log_id(extmapper_module)); + if (simplemap_mappers.count(extmapper_cell->type) == 0) + log_error("No simplemap mapper for cell type %s found!\n", log_id(extmapper_cell->type)); + simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell); + } + + if (extmapper_name == "maccmap") { + log("Creating %s with maccmap.\n", log_id(extmapper_module)); + if (extmapper_cell->type != "$macc") + log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type)); + maccmap(extmapper_module, extmapper_cell); + } + + extmapper_module->remove(extmapper_cell); } - log("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(simplemap_module)); - cell->type = simplemap_module->name; + log("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module)); + cell->type = extmapper_module->name; cell->parameters.clear(); } else { - log("%s %s.%s (%s) with simplemap.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type)); - if (simplemap_mappers.count(cell->type) == 0) - log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); - simplemap_mappers.at(cell->type)(module, cell); + log("%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), extmapper_name.c_str()); + + if (extmapper_name == "simplemap") { + if (simplemap_mappers.count(cell->type) == 0) + log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type)); + simplemap_mappers.at(cell->type)(module, cell); + } + + if (extmapper_name == "maccmap") { + if (cell->type != "$macc") + log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(cell->type)); + maccmap(module, cell); + } + module->remove(cell); cell = NULL; } @@ -752,6 +783,9 @@ struct TechmapPass : public Pass { log("When a module in the map file has the 'techmap_simplemap' attribute set, techmap\n"); log("will use 'simplemap' (see 'help simplemap') to map cells matching the module.\n"); log("\n"); + log("When a module in the map file has the 'techmap_maccmap' attribute set, techmap\n"); + log("will use 'maccmap' (see 'help maccmap') to map cells matching the module.\n"); + log("\n"); log("All wires in the modules from the map file matching the pattern _TECHMAP_*\n"); log("or *._TECHMAP_* are special wires that are used to pass instructions from\n"); log("the mapping module to the techmap command. At the moment the following special\n"); From dd887cc02544e76f4ff9e57547231391388c1fa1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 18:24:08 +0200 Subject: [PATCH 704/750] Using maccmap for $macc and $mul techmap --- techlibs/common/techmap.v | 204 +++----------------------------------- 1 file changed, 15 insertions(+), 189 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 3fc6ccb8..dc52ca5f 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -455,102 +455,8 @@ endmodule // Multiply // -------------------------------------------------------- -module \$__acc_set (acc_new, value); - parameter WIDTH = 1; - output reg [2*WIDTH-1:0] acc_new; - input [WIDTH-1:0] value; - - wire [1023:0] _TECHMAP_DO_ = "proc;;;"; - - integer k; - always @* begin - for (k = 0; k < WIDTH; k = k+1) begin - acc_new[2*k +: 2] = value[k]; - end - end -endmodule - -module \$__acc_add (acc_new, acc_old, value); - parameter WIDTH = 1; - output reg [2*WIDTH-1:0] acc_new; - input [2*WIDTH-1:0] acc_old; - input [WIDTH-1:0] value; - - wire [1023:0] _TECHMAP_DO_ = "proc; simplemap; opt -purge"; - - integer k; - reg a, b, c; - - always @* begin - for (k = 0; k < WIDTH; k = k+1) begin - a = acc_old[2*k]; - b = k ? acc_old[2*k-1] : 1'b0; - c = value[k]; - acc_new[2*k] = (a ^ b) ^ c; - acc_new[2*k+1] = (a & b) | ((a ^ b) & c); - end - end -endmodule - -module \$__acc_get (value, acc); - parameter WIDTH = 1; - output reg [WIDTH-1:0] value; - input [2*WIDTH-1:0] acc; - - wire [1023:0] _TECHMAP_DO_ = "proc;;;"; - - integer k; - - always @* begin - // at the end of the multiplier chain the carry-save accumulator - // should also have propagated all carries. thus we just need to - // copy the even bits from the carry accumulator to the output. - for (k = 0; k < WIDTH; k = k+1) begin - value[k] = acc[2*k]; - end - end -endmodule - -module \$__acc_mul (A, B, Y); - parameter WIDTH = 1; - input [WIDTH-1:0] A, B; - output [WIDTH-1:0] Y; - - wire [1023:0] _TECHMAP_DO_ = "proc;;"; - - integer i; - reg [WIDTH-1:0] x; - reg [2*WIDTH-1:0] y; - - (* via_celltype = "\\$__acc_set acc_new" *) - (* via_celltype_defparam_WIDTH = WIDTH *) - function [2*WIDTH-1:0] acc_set; - input [WIDTH-1:0] value; - endfunction - - (* via_celltype = "\\$__acc_add acc_new" *) - (* via_celltype_defparam_WIDTH = WIDTH *) - function [2*WIDTH-1:0] acc_add; - input [2*WIDTH-1:0] acc_old; - input [WIDTH-1:0] value; - endfunction - - (* via_celltype = "\\$__acc_get value" *) - (* via_celltype_defparam_WIDTH = WIDTH *) - function [WIDTH-1:0] acc_get; - input [2*WIDTH-1:0] acc; - endfunction - - always @* begin - x = B; - y = acc_set(A[0] ? x : 1'b0); - for (i = 1; i < WIDTH; i = i+1) begin - x = {x[WIDTH-2:0], 1'b0}; - y = acc_add(y, A[i] ? x : 1'b0); - end - end - - assign Y = acc_get(y); +(* techmap_maccmap *) +module \$macc ; endmodule module \$mul (A, B, Y); @@ -566,105 +472,25 @@ module \$mul (A, B, Y); wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt -purge"; - wire [Y_WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + localparam [ 3:0] CONFIG_WIDTH_BITS = 15; + localparam [ 0:0] CONFIG_IS_SIGNED = A_SIGNED && B_SIGNED; + localparam [ 0:0] CONFIG_DO_SUBTRACT = 0; + localparam [14:0] CONFIG_A_WIDTH = A_WIDTH; + localparam [14:0] CONFIG_B_WIDTH = B_WIDTH; - \$__acc_mul #( - .WIDTH(Y_WIDTH) + \$macc #( + .CONFIG({CONFIG_B_WIDTH, CONFIG_A_WIDTH, CONFIG_DO_SUBTRACT, CONFIG_IS_SIGNED, CONFIG_WIDTH_BITS}), + .CONFIG_WIDTH(15 + 15 + 2 + 4), + .A_WIDTH(B_WIDTH + A_WIDTH), + .B_WIDTH(0), + .Y_WIDTH(Y_WIDTH) ) _TECHMAP_REPLACE_ ( - .A(A_buf), - .B(B_buf), + .A({B, A}), + .B(), .Y(Y) ); endmodule -module \$macc (A, B, Y); - parameter A_WIDTH = 0; - parameter B_WIDTH = 0; - parameter Y_WIDTH = 0; - parameter CONFIG = 4'b0000; - parameter CONFIG_WIDTH = 4; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output reg [Y_WIDTH-1:0] Y; - - wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; - - localparam integer num_bits = CONFIG[3:0]; - localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); - localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; - - function [2*num_ports*num_abits-1:0] get_port_offsets; - input [CONFIG_WIDTH-1:0] cfg; - integer i, cursor; - begin - cursor = 0; - get_port_offsets = 0; - for (i = 0; i < num_ports; i = i+1) begin - get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; - cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; - get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; - cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; - end - end - endfunction - - localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); - - `define PORT_IS_SIGNED (0 + CONFIG[4 + i*(2 + 2*num_bits)]) - `define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1]) - `define PORT_SIZE_A (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]) - `define PORT_SIZE_B (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]) - `define PORT_OFFSET_A (0 + port_offsets[2*i*num_abits +: num_abits]) - `define PORT_OFFSET_B (0 + port_offsets[2*i*num_abits + num_abits +: num_abits]) - - integer i, j; - reg [Y_WIDTH-1:0] tmp_a, tmp_b; - - always @* begin - Y = 0; - for (i = 0; i < num_ports; i = i+1) - begin - tmp_a = 0; - tmp_b = 0; - - for (j = 0; j < `PORT_SIZE_A; j = j+1) - tmp_a[j] = A[`PORT_OFFSET_A + j]; - - if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0) - for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1) - tmp_a[j] = tmp_a[`PORT_SIZE_A-1]; - - for (j = 0; j < `PORT_SIZE_B; j = j+1) - tmp_b[j] = A[`PORT_OFFSET_B + j]; - - if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0) - for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1) - tmp_b[j] = tmp_b[`PORT_SIZE_B-1]; - - if (`PORT_SIZE_B > 0) - tmp_a = tmp_a * tmp_b; - - if (`PORT_DO_SUBTRACT) - Y = Y - tmp_a; - else - Y = Y + tmp_a; - end - for (i = 0; i < B_WIDTH; i = i+1) begin - Y = Y + B[i]; - end - end - - `undef PORT_IS_SIGNED - `undef PORT_DO_SUBTRACT - `undef PORT_SIZE_A - `undef PORT_SIZE_B - `undef PORT_OFFSET_A - `undef PORT_OFFSET_B -endmodule - // -------------------------------------------------------- // Divide and Modulo From 6747a7047e105b7dae79ed8b8e1111d1ff8888d2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 11:12:39 +0200 Subject: [PATCH 705/750] Added "test_cell -const" --- passes/tests/test_cell.cc | 47 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index a38023d1..310c3bdf 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -33,7 +33,7 @@ static uint32_t xorshift32(uint32_t limit) { return xorshift32_state % limit; } -static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags) +static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags, bool constmode) { RTLIL::Module *module = design->addModule("\\gold"); RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); @@ -166,6 +166,41 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->setPort("\\CO", wire); } + if (constmode) + { + auto conn_list = cell->connections(); + for (auto &conn : conn_list) + { + RTLIL::SigSpec sig = conn.second; + + if (SIZE(sig) == 0 || sig[0].wire == nullptr || sig[0].wire->port_output) + continue; + + int n, m; + switch (xorshift32(5)) + { + case 0: + n = xorshift32(SIZE(sig) + 1); + for (int i = 0; i < n; i++) + sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; + break; + case 1: + n = xorshift32(SIZE(sig) + 1); + for (int i = n; i < SIZE(sig); i++) + sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; + break; + case 2: + n = xorshift32(SIZE(sig)); + m = xorshift32(SIZE(sig)); + for (int i = std::min(n, m); i < std::max(n, m); i++) + sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; + break; + } + + cell->setPort(conn.first, sig); + } + } + module->fixup_ports(); cell->fixup_parameters(); cell->check(); @@ -436,6 +471,9 @@ struct TestCellPass : public Pass { log(" -script {script_file}\n"); log(" instead of calling \"techmap\", call \"script {script_file}\".\n"); log("\n"); + log(" -const\n"); + log(" set some input bits to random constant values\n"); + log("\n"); log(" -nosat\n"); log(" do not check SAT model or run SAT equivalence checking\n"); log("\n"); @@ -454,6 +492,7 @@ struct TestCellPass : public Pass { xorshift32_state = 0; std::ofstream vlog_file; bool verbose = false; + bool constmode = false; bool nosat = false; int argidx; @@ -484,6 +523,10 @@ struct TestCellPass : public Pass { techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc"; continue; } + if (args[argidx] == "-const") { + constmode = true; + continue; + } if (args[argidx] == "-nosat") { nosat = true; continue; @@ -610,7 +653,7 @@ struct TestCellPass : public Pass { if (cell_type == "ilang") Frontend::frontend_call(design, NULL, std::string(), "ilang " + ilang_file); else - create_gold_module(design, cell_type, cell_types.at(cell_type)); + create_gold_module(design, cell_type, cell_types.at(cell_type), constmode); Pass::call(design, stringf("copy gold gate; cd gate; %s; cd ..; opt -fast gate", techmap_cmd.c_str())); if (!nosat) Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter"); From 1a88e47396305bd6b5ee2a7a91a1d014ebd37c10 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 11:21:58 +0200 Subject: [PATCH 706/750] Trim msb/lsb zero bits from full adder in maccmap --- passes/techmap/maccmap.cc | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index 49850c0a..a9c223fa 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -85,12 +85,34 @@ struct MaccmapWorker void fulladd(RTLIL::SigSpec &in1, RTLIL::SigSpec &in2, RTLIL::SigSpec &in3, RTLIL::SigSpec &out1, RTLIL::SigSpec &out2) { - RTLIL::SigSpec t1 = module->Xor(NEW_ID, in1, in2); - out1 = module->Xor(NEW_ID, t1, in3); + int start_index = 0, stop_index = SIZE(in1); - RTLIL::SigSpec t2 = module->And(NEW_ID, in1, in2); - RTLIL::SigSpec t3 = module->And(NEW_ID, in3, t1); - out2 = module->Or(NEW_ID, t2, t3); + while (start_index < stop_index && in1[start_index] == RTLIL::S0 && in2[start_index] == RTLIL::S0 && in3[start_index] == RTLIL::S0) + start_index++; + + while (start_index < stop_index && in1[stop_index-1] == RTLIL::S0 && in2[stop_index-1] == RTLIL::S0 && in3[stop_index-1] == RTLIL::S0) + stop_index--; + + if (start_index == stop_index) + { + out1 = RTLIL::SigSpec(0, SIZE(in1)); + out2 = RTLIL::SigSpec(0, SIZE(in1)); + } + else + { + RTLIL::SigSpec out_zeros_lsb(0, start_index), out_zeros_msb(0, SIZE(in1)-stop_index); + + in1 = in1.extract(start_index, stop_index-start_index); + in2 = in2.extract(start_index, stop_index-start_index); + in3 = in3.extract(start_index, stop_index-start_index); + + RTLIL::SigSpec t1 = module->Xor(NEW_ID, in1, in2); + out1 = {out_zeros_msb, module->Xor(NEW_ID, t1, in3), out_zeros_lsb}; + + RTLIL::SigSpec t2 = module->And(NEW_ID, in1, in2); + RTLIL::SigSpec t3 = module->And(NEW_ID, in3, t1); + out2 = {out_zeros_msb, module->Or(NEW_ID, t2, t3), out_zeros_lsb}; + } } int tree_bit_slots(int n) From d46bac330520f91ee5bf8027abe98a8f9389f696 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 12:15:39 +0200 Subject: [PATCH 707/750] Added "$fa" cell type --- kernel/celltypes.h | 1 + kernel/consteval.h | 25 ++++++++++++++++++++ kernel/rtlil.cc | 15 ++++++++++++ kernel/satgen.h | 49 +++++++++++++++++++++++++++++++++++++++ passes/techmap/maccmap.cc | 20 ++++++++++++---- passes/tests/test_cell.cc | 31 +++++++++++++++++++++++++ techlibs/common/simlib.v | 16 +++++++++++++ techlibs/common/techmap.v | 12 ++++++++++ 8 files changed, 164 insertions(+), 5 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 74e9f1fd..b42cf4e9 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -106,6 +106,7 @@ struct CellTypes setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); setup_type("$alu", {"\\A", "\\B", "\\CI", "\\BI"}, {"\\X", "\\Y", "\\CO"}, true); + setup_type("$fa", {"\\A", "\\B", "\\C"}, {"\\X", "\\Y"}, true); setup_type("$assert", {"\\A", "\\EN"}, std::set(), true); } diff --git a/kernel/consteval.h b/kernel/consteval.h index f995c9cc..7423f950 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -155,6 +155,31 @@ struct ConstEval else set(sig_y, y_values.front()); } + else if (cell->type == "$fa") + { + RTLIL::SigSpec sig_c = cell->getPort("\\C"); + RTLIL::SigSpec sig_x = cell->getPort("\\X"); + int width = SIZE(sig_c); + + if (!eval(sig_a, undef, cell)) + return false; + + if (!eval(sig_b, undef, cell)) + return false; + + if (!eval(sig_c, undef, cell)) + return false; + + RTLIL::Const t1 = const_xor(sig_a.as_const(), sig_b.as_const(), false, false, width); + RTLIL::Const val_y = const_xor(t1, sig_c.as_const(), false, false, width); + + RTLIL::Const t2 = const_and(sig_a.as_const(), sig_b.as_const(), false, false, width); + RTLIL::Const t3 = const_and(sig_c.as_const(), t1, false, false, width); + RTLIL::Const val_x = const_or(t2, t3, false, false, width); + + set(sig_y, val_y); + set(sig_x, val_x); + } else if (cell->type == "$alu") { bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 97a2946a..b5cede8b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -620,6 +620,16 @@ namespace { return; } + if (cell->type == "$fa") { + port("\\A", param("\\WIDTH")); + port("\\B", param("\\WIDTH")); + port("\\C", param("\\WIDTH")); + port("\\X", param("\\WIDTH")); + port("\\Y", param("\\WIDTH")); + check_expected(); + return; + } + if (cell->type == "$alu") { param_bool("\\A_SIGNED"); param_bool("\\B_SIGNED"); @@ -1793,6 +1803,11 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) return; } + if (type == "$fa") { + parameters["\\WIDTH"] = SIZE(connections_["\\Y"]); + return; + } + bool signedness_ab = !type.in("$slice", "$concat", "$macc"); if (connections_.count("\\A")) { diff --git a/kernel/satgen.h b/kernel/satgen.h index 3429f823..4aabe437 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -963,6 +963,55 @@ struct SatGen return true; } + if (cell->type == "$fa") + { + std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); + std::vector b = importDefSigSpec(cell->getPort("\\B"), timestep); + std::vector c = importDefSigSpec(cell->getPort("\\C"), timestep); + std::vector y = importDefSigSpec(cell->getPort("\\Y"), timestep); + std::vector x = importDefSigSpec(cell->getPort("\\X"), timestep); + + std::vector yy = model_undef ? ez->vec_var(y.size()) : y; + std::vector xx = model_undef ? ez->vec_var(x.size()) : x; + + std::vector t1 = ez->vec_xor(a, b); + ez->assume(ez->vec_eq(yy, ez->vec_xor(t1, c))); + + std::vector t2 = ez->vec_and(a, b); + std::vector t3 = ez->vec_and(c, t1); + ez->assume(ez->vec_eq(xx, ez->vec_or(t2, t3))); + + if (model_undef) + { + std::vector undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); + std::vector undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); + std::vector undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep); + + std::vector undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); + std::vector undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); + + ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c))); + + std::vector undef_t1 = ez->vec_or(undef_a, undef_b); + + std::vector a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); + std::vector b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); + std::vector undef_t2 = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0))); + + std::vector c0 = ez->vec_and(ez->vec_not(c), ez->vec_not(undef_c)); + std::vector t10 = ez->vec_and(ez->vec_not(t1), ez->vec_not(undef_t1)); + std::vector undef_t3 = ez->vec_and(ez->vec_or(undef_c, undef_t1), ez->vec_not(ez->vec_or(c0, t10))); + + std::vector t21 = ez->vec_and(t2, ez->vec_not(undef_t2)); + std::vector t31 = ez->vec_and(t3, ez->vec_not(undef_t3)); + ez->assume(ez->vec_eq(undef_x, ez->vec_and(ez->vec_or(undef_t2, undef_t3), ez->vec_not(ez->vec_or(t21, t31))))); + + undefGating(y, yy, undef_y); + undefGating(x, xx, undef_x); + } + return true; + } + if (cell->type == "$alu") { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index a9c223fa..c2dc9aa8 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -106,12 +106,20 @@ struct MaccmapWorker in2 = in2.extract(start_index, stop_index-start_index); in3 = in3.extract(start_index, stop_index-start_index); - RTLIL::SigSpec t1 = module->Xor(NEW_ID, in1, in2); - out1 = {out_zeros_msb, module->Xor(NEW_ID, t1, in3), out_zeros_lsb}; + int width = SIZE(in1); + RTLIL::Wire *w1 = module->addWire(NEW_ID, width); + RTLIL::Wire *w2 = module->addWire(NEW_ID, width); - RTLIL::SigSpec t2 = module->And(NEW_ID, in1, in2); - RTLIL::SigSpec t3 = module->And(NEW_ID, in3, t1); - out2 = {out_zeros_msb, module->Or(NEW_ID, t2, t3), out_zeros_lsb}; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$fa"); + cell->setParam("\\WIDTH", width); + cell->setPort("\\A", in1); + cell->setPort("\\B", in2); + cell->setPort("\\C", in3); + cell->setPort("\\Y", w1); + cell->setPort("\\X", w2); + + out1 = {out_zeros_msb, w1, out_zeros_lsb}; + out2 = {out_zeros_msb, w2, out_zeros_lsb}; } } @@ -198,6 +206,8 @@ struct MaccmapWorker summands.swap(new_summands); } + log_assert(tree_sum_bits.empty()); + return module->Add(NEW_ID, summands.front(), summands.back()); } }; diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 310c3bdf..72fb74d3 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -39,6 +39,36 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); RTLIL::Wire *wire; + if (cell_type == "$fa") + { + int width = 1 + xorshift32(8); + + wire = module->addWire("\\A"); + wire->width = width; + wire->port_input = true; + cell->setPort("\\A", wire); + + wire = module->addWire("\\B"); + wire->width = width; + wire->port_input = true; + cell->setPort("\\B", wire); + + wire = module->addWire("\\C"); + wire->width = width; + wire->port_input = true; + cell->setPort("\\C", wire); + + wire = module->addWire("\\X"); + wire->width = width; + wire->port_output = true; + cell->setPort("\\X", wire); + + wire = module->addWire("\\Y"); + wire->width = width; + wire->port_output = true; + cell->setPort("\\Y", wire); + } + if (cell_type == "$macc") { Macc macc; @@ -603,6 +633,7 @@ struct TestCellPass : public Pass { cell_types["$lut"] = "*"; cell_types["$alu"] = "ABSY"; cell_types["$macc"] = "*"; + cell_types["$fa"] = "*"; for (; argidx < SIZE(args); argidx++) { diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 465efc0a..c170945e 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -443,6 +443,22 @@ endmodule // -------------------------------------------------------- +module \$fa (A, B, C, X, Y); + +parameter WIDTH = 1; + +input [WIDTH-1:0] A, B, C; +output [WIDTH-1:0] X, Y; + +wire [WIDTH-1:0] t1, t2, t3; + +assign t1 = A ^ B, t2 = A & B, t3 = C & t1; +assign Y = t1 ^ C, X = t2 | t3; + +endmodule + +// -------------------------------------------------------- + module \$alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index dc52ca5f..05074637 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -246,6 +246,18 @@ endmodule // ALU Infrastructure // -------------------------------------------------------- +module \$fa (A, B, C, X, Y); + parameter WIDTH = 1; + + input [WIDTH-1:0] A, B, C; + output [WIDTH-1:0] X, Y; + + wire [WIDTH-1:0] t1, t2, t3; + + assign t1 = A ^ B, t2 = A & B, t3 = C & t1; + assign Y = t1 ^ C, X = t2 | t3; +endmodule + module \$__alu_ripple (A, B, CI, X, Y, CO); parameter WIDTH = 1; From 48b00dcceab8bb046258cd6f0912636a6e5b232c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 12:25:23 +0200 Subject: [PATCH 708/750] Another $clog2 bugfix --- frontends/ast/simplify.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 9e797573..969cc230 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; From af0c8873bbc13eea10b3d705061b4cf68fe27c17 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 13:28:23 +0200 Subject: [PATCH 709/750] Added $lcu cell type --- kernel/celltypes.h | 1 + kernel/consteval.h | 37 +++++++++++++++++ kernel/rtlil.cc | 14 +++++++ kernel/satgen.h | 32 +++++++++++++++ manual/CHAPTER_CellLib.tex | 2 +- passes/tests/test_cell.cc | 27 ++++++++++++- techlibs/common/simlib.v | 23 +++++++++++ techlibs/common/techmap.v | 82 ++++---------------------------------- 8 files changed, 142 insertions(+), 76 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index b42cf4e9..85c21ef3 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -105,6 +105,7 @@ struct CellTypes for (auto type : std::vector({"$mux", "$pmux"})) setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true); + setup_type("$lcu", {"\\P", "\\G", "\\CI"}, {"\\CO"}, true); setup_type("$alu", {"\\A", "\\B", "\\CI", "\\BI"}, {"\\X", "\\Y", "\\CO"}, true); setup_type("$fa", {"\\A", "\\B", "\\C"}, {"\\X", "\\Y"}, true); diff --git a/kernel/consteval.h b/kernel/consteval.h index 7423f950..6e507bd5 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -86,6 +86,43 @@ struct ConstEval bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef) { + if (cell->type == "$lcu") + { + RTLIL::SigSpec sig_p = cell->getPort("\\P"); + RTLIL::SigSpec sig_g = cell->getPort("\\G"); + RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); + RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort("\\CO"))); + + if (sig_co.is_fully_const()) + return true; + + if (!eval(sig_p, undef, cell)) + return false; + + if (!eval(sig_g, undef, cell)) + return false; + + if (!eval(sig_ci, undef, cell)) + return false; + + if (sig_p.is_fully_def() && sig_g.is_fully_def() && sig_ci.is_fully_def()) + { + RTLIL::Const coval(RTLIL::Sx, SIZE(sig_co)); + bool carry = sig_ci.as_bool(); + + for (int i = 0; i < SIZE(coval); i++) { + carry = (sig_g[i] == RTLIL::S1) || (sig_p[i] == RTLIL::S1 && carry); + coval.bits[i] = carry ? RTLIL::S1 : RTLIL::S0; + } + + set(sig_co, coval); + } + else + set(sig_co, RTLIL::Const(RTLIL::Sx, SIZE(sig_co))); + + return true; + } + RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; log_assert(cell->hasPort("\\Y")); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b5cede8b..ec4375f2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -630,6 +630,15 @@ namespace { return; } + if (cell->type == "$lcu") { + port("\\P", param("\\WIDTH")); + port("\\G", param("\\WIDTH")); + port("\\CI", 1); + port("\\CO", param("\\WIDTH")); + check_expected(); + return; + } + if (cell->type == "$alu") { param_bool("\\A_SIGNED"); param_bool("\\B_SIGNED"); @@ -1808,6 +1817,11 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) return; } + if (type == "$lcu") { + parameters["\\WIDTH"] = SIZE(connections_["\\CO"]); + return; + } + bool signedness_ab = !type.in("$slice", "$concat", "$macc"); if (connections_.count("\\A")) { diff --git a/kernel/satgen.h b/kernel/satgen.h index 4aabe437..91f8ab40 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -1012,6 +1012,38 @@ struct SatGen return true; } + if (cell->type == "$lcu") + { + std::vector p = importDefSigSpec(cell->getPort("\\P"), timestep); + std::vector g = importDefSigSpec(cell->getPort("\\G"), timestep); + std::vector ci = importDefSigSpec(cell->getPort("\\CI"), timestep); + std::vector co = importDefSigSpec(cell->getPort("\\CO"), timestep); + + std::vector yy = model_undef ? ez->vec_var(co.size()) : co; + + for (int i = 0; i < SIZE(co); i++) + ez->SET(yy[i], ez->OR(g[i], ez->AND(p[i], i ? yy[i-1] : ci[0]))); + + if (model_undef) + { + std::vector undef_p = importUndefSigSpec(cell->getPort("\\P"), timestep); + std::vector undef_g = importUndefSigSpec(cell->getPort("\\G"), timestep); + std::vector undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep); + std::vector undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep); + + int undef_any_p = ez->expression(ezSAT::OpOr, undef_p); + int undef_any_g = ez->expression(ezSAT::OpOr, undef_g); + int undef_any_ci = ez->expression(ezSAT::OpOr, undef_ci); + int undef_co_bit = ez->OR(undef_any_p, undef_any_g, undef_any_ci); + + std::vector undef_co_bits(undef_co.size(), undef_co_bit); + ez->assume(ez->vec_eq(undef_co_bits, undef_co)); + + undefGating(co, yy, undef_co); + } + return true; + } + if (cell->type == "$alu") { std::vector a = importDefSigSpec(cell->getPort("\\A"), timestep); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 5045960c..64d3633e 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -425,7 +425,7 @@ Add information about {\tt \$slice} and {\tt \$concat} cells. \end{fixme} \begin{fixme} -Add information about {\tt \$alu} cells. +Add information about {\tt \$alu}, {\tt \$macc}, {\tt \$fa}, and {\tt \$lcu} cells. \end{fixme} \begin{fixme} diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 72fb74d3..1fa90b54 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -69,6 +69,30 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->setPort("\\Y", wire); } + if (cell_type == "$lcu") + { + int width = 1 + xorshift32(8); + + wire = module->addWire("\\P"); + wire->width = width; + wire->port_input = true; + cell->setPort("\\P", wire); + + wire = module->addWire("\\G"); + wire->width = width; + wire->port_input = true; + cell->setPort("\\G", wire); + + wire = module->addWire("\\CI"); + wire->port_input = true; + cell->setPort("\\CI", wire); + + wire = module->addWire("\\CO"); + wire->width = width; + wire->port_output = true; + cell->setPort("\\CO", wire); + } + if (cell_type == "$macc") { Macc macc; @@ -477,7 +501,7 @@ struct TestCellPass : public Pass { log("\n"); log(" test_cell [options] {cell-types}\n"); log("\n"); - log("Tests the internal implementation of the given cell type (for example '$mux')\n"); + log("Tests the internal implementation of the given cell type (for example '$add')\n"); log("by comparing SAT solver, EVAL and TECHMAP implementations of the cell types..\n"); log("\n"); log("Run with 'all' instead of a cell type to run the test on all supported\n"); @@ -632,6 +656,7 @@ struct TestCellPass : public Pass { cell_types["$lut"] = "*"; cell_types["$alu"] = "ABSY"; + cell_types["$lcu"] = "*"; cell_types["$macc"] = "*"; cell_types["$fa"] = "*"; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index c170945e..1b67f325 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -459,6 +459,29 @@ endmodule // -------------------------------------------------------- +module \$lcu (P, G, CI, CO); + +parameter WIDTH = 1; + +input [WIDTH-1:0] P, G; +input CI; + +output reg [WIDTH-1:0] CO; + +integer i; +always @* begin + CO = 'bx; + if (^{P, G, CI} !== 1'bx) begin + CO[0] = G[0] || (P[0] && CI); + for (i = 1; i < WIDTH; i = i+1) + CO[i] = G[i] || (P[i] && CO[i-1]); + end +end + +endmodule + +// -------------------------------------------------------- + module \$alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 05074637..491511db 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -258,40 +258,7 @@ module \$fa (A, B, C, X, Y); assign Y = t1 ^ C, X = t2 | t3; endmodule -module \$__alu_ripple (A, B, CI, X, Y, CO); - parameter WIDTH = 1; - - input [WIDTH-1:0] A, B; - output [WIDTH-1:0] X, Y; - - input CI; - output [WIDTH-1:0] CO; - - wire [WIDTH:0] carry; - assign carry[0] = CI; - assign CO = carry[WIDTH:1]; - - genvar i; - generate - for (i = 0; i < WIDTH; i = i+1) - begin:V - // {x, y} = a + b + c - wire a, b, c, x, y; - wire t1, t2, t3; - - \$_AND_ gate1 ( .A(a), .B(b), .Y(t1) ); - \$_XOR_ gate2 ( .A(a), .B(b), .Y(t2) ); - \$_AND_ gate3 ( .A(t2), .B(c), .Y(t3) ); - \$_XOR_ gate4 ( .A(t2), .B(c), .Y(y) ); - \$_OR_ gate5 ( .A(t1), .B(t3), .Y(x) ); - - assign a = A[i], b = B[i], c = carry[i]; - assign carry[i+1] = x, X[i] = t2, Y[i] = y; - end - endgenerate -endmodule - -module \$__lcu (P, G, CI, CO); +module \$lcu (P, G, CI, CO); parameter WIDTH = 2; input [WIDTH-1:0] P, G; @@ -335,37 +302,6 @@ module \$__lcu (P, G, CI, CO); assign CO = g; endmodule -module \$__alu_lookahead (A, B, CI, X, Y, CO); - parameter WIDTH = 1; - - input [WIDTH-1:0] A, B; - output [WIDTH-1:0] X, Y; - - input CI; - output [WIDTH-1:0] CO; - - wire [WIDTH-1:0] P, G; - wire [WIDTH:0] carry; - - genvar i; - generate - for (i = 0; i < WIDTH; i = i+1) - begin:V - wire a, b, c, p, g, y; - - \$_AND_ gate1 ( .A(a), .B(b), .Y(g) ); - \$_XOR_ gate2 ( .A(a), .B(b), .Y(p) ); - \$_XOR_ gate3 ( .A(p), .B(c), .Y(y) ); - - assign a = A[i], b = B[i], c = carry[i]; - assign P[i] = p, G[i] = g, X[i] = p, Y[i] = y; - end - endgenerate - - \$__lcu #(.WIDTH(WIDTH)) lcu (.P(P), .G(G), .CI(CI), .CO(CO)); - assign carry = {CO, CI}; -endmodule - module \$alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; parameter B_SIGNED = 0; @@ -384,15 +320,13 @@ module \$alu (A, B, CI, BI, X, Y, CO); \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); -`ifdef ALU_RIPPLE - \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO)); -`else - if (Y_WIDTH <= 4) begin - \$__alu_ripple #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO)); - end else begin - \$__alu_lookahead #(.WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_buf), .B(BI ? ~B_buf : B_buf), .CI(CI), .X(X), .Y(Y), .CO(CO)); - end -`endif + wire [Y_WIDTH-1:0] AA = A_buf; + wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; + + \$lcu #(.WIDTH(Y_WIDTH)) lcu (.P(X), .G(AA & BB), .CI(CI), .CO(CO)); + + assign X = AA ^ BB; + assign Y = X ^ {CO, CI}; endmodule From 6dc07eb1f23757b17b6d856c95d0901d751eeb25 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 13:29:13 +0200 Subject: [PATCH 710/750] Fixes and cleanups for blackbox.v --- techlibs/common/blackbox.sed | 5 +- techlibs/common/simlib.v | 150 ++++++++++++++++++----------------- 2 files changed, 79 insertions(+), 76 deletions(-) diff --git a/techlibs/common/blackbox.sed b/techlibs/common/blackbox.sed index 21693ecd..db890034 100644 --- a/techlibs/common/blackbox.sed +++ b/techlibs/common/blackbox.sed @@ -1,4 +1,5 @@ #!/bin/sed -r -/^(wire|assign|reg|event)/ d; -/^(genvar|generate|always|initial)/,/^end/ d; +/^(wire|assign|reg|event|integer|localparam|\/\/|[\/ ]\*| *$|`)/ d; +/^(genvar|generate|always|initial|task|function)/,/^end/ d; +/^endmodule/ s/$/\n/; s/ reg / /; diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 1b67f325..da745b5e 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -795,87 +795,89 @@ endmodule // -------------------------------------------------------- module \$macc (A, B, Y); - parameter A_WIDTH = 0; - parameter B_WIDTH = 0; - parameter Y_WIDTH = 0; - parameter CONFIG = 4'b0000; - parameter CONFIG_WIDTH = 4; - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output reg [Y_WIDTH-1:0] Y; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; +parameter CONFIG = 4'b0000; +parameter CONFIG_WIDTH = 4; - localparam integer num_bits = CONFIG[3:0]; - localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); - localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output reg [Y_WIDTH-1:0] Y; - function [2*num_ports*num_abits-1:0] get_port_offsets; - input [CONFIG_WIDTH-1:0] cfg; - integer i, cursor; - begin - cursor = 0; - get_port_offsets = 0; - for (i = 0; i < num_ports; i = i+1) begin - get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; - cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; - get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; - cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; - end - end - endfunction +localparam integer num_bits = CONFIG[3:0]; +localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); +localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; - localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); - - `define PORT_IS_SIGNED (0 + CONFIG[4 + i*(2 + 2*num_bits)]) - `define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1]) - `define PORT_SIZE_A (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]) - `define PORT_SIZE_B (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]) - `define PORT_OFFSET_A (0 + port_offsets[2*i*num_abits +: num_abits]) - `define PORT_OFFSET_B (0 + port_offsets[2*i*num_abits + num_abits +: num_abits]) - - integer i, j; - reg [Y_WIDTH-1:0] tmp_a, tmp_b; - - always @* begin - Y = 0; - for (i = 0; i < num_ports; i = i+1) - begin - tmp_a = 0; - tmp_b = 0; - - for (j = 0; j < `PORT_SIZE_A; j = j+1) - tmp_a[j] = A[`PORT_OFFSET_A + j]; - - if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0) - for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1) - tmp_a[j] = tmp_a[`PORT_SIZE_A-1]; - - for (j = 0; j < `PORT_SIZE_B; j = j+1) - tmp_b[j] = A[`PORT_OFFSET_B + j]; - - if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0) - for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1) - tmp_b[j] = tmp_b[`PORT_SIZE_B-1]; - - if (`PORT_SIZE_B > 0) - tmp_a = tmp_a * tmp_b; - - if (`PORT_DO_SUBTRACT) - Y = Y - tmp_a; - else - Y = Y + tmp_a; - end - for (i = 0; i < B_WIDTH; i = i+1) begin - Y = Y + B[i]; +function [2*num_ports*num_abits-1:0] get_port_offsets; + input [CONFIG_WIDTH-1:0] cfg; + integer i, cursor; + begin + cursor = 0; + get_port_offsets = 0; + for (i = 0; i < num_ports; i = i+1) begin + get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; + get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; + cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; end end +endfunction + +localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); + +`define PORT_IS_SIGNED (0 + CONFIG[4 + i*(2 + 2*num_bits)]) +`define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1]) +`define PORT_SIZE_A (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]) +`define PORT_SIZE_B (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]) +`define PORT_OFFSET_A (0 + port_offsets[2*i*num_abits +: num_abits]) +`define PORT_OFFSET_B (0 + port_offsets[2*i*num_abits + num_abits +: num_abits]) + +integer i, j; +reg [Y_WIDTH-1:0] tmp_a, tmp_b; + +always @* begin + Y = 0; + for (i = 0; i < num_ports; i = i+1) + begin + tmp_a = 0; + tmp_b = 0; + + for (j = 0; j < `PORT_SIZE_A; j = j+1) + tmp_a[j] = A[`PORT_OFFSET_A + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0) + for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1) + tmp_a[j] = tmp_a[`PORT_SIZE_A-1]; + + for (j = 0; j < `PORT_SIZE_B; j = j+1) + tmp_b[j] = A[`PORT_OFFSET_B + j]; + + if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0) + for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1) + tmp_b[j] = tmp_b[`PORT_SIZE_B-1]; + + if (`PORT_SIZE_B > 0) + tmp_a = tmp_a * tmp_b; + + if (`PORT_DO_SUBTRACT) + Y = Y - tmp_a; + else + Y = Y + tmp_a; + end + for (i = 0; i < B_WIDTH; i = i+1) begin + Y = Y + B[i]; + end +end + +`undef PORT_IS_SIGNED +`undef PORT_DO_SUBTRACT +`undef PORT_SIZE_A +`undef PORT_SIZE_B +`undef PORT_OFFSET_A +`undef PORT_OFFSET_B - `undef PORT_IS_SIGNED - `undef PORT_DO_SUBTRACT - `undef PORT_SIZE_A - `undef PORT_SIZE_B - `undef PORT_OFFSET_A - `undef PORT_OFFSET_B endmodule // -------------------------------------------------------- From fcb46138cebd57587d35489cef3a3a48ebe40bcf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 16:59:39 +0200 Subject: [PATCH 711/750] Simplified $fa undef model --- kernel/consteval.h | 4 ++++ kernel/satgen.h | 15 +-------------- techlibs/common/simlib.v | 2 +- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/kernel/consteval.h b/kernel/consteval.h index 6e507bd5..2d29d3f7 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -214,6 +214,10 @@ struct ConstEval RTLIL::Const t3 = const_and(sig_c.as_const(), t1, false, false, width); RTLIL::Const val_x = const_or(t2, t3, false, false, width); + for (int i = 0; i < SIZE(val_y); i++) + if (val_y.bits[i] == RTLIL::Sx) + val_x.bits[i] = RTLIL::Sx; + set(sig_y, val_y); set(sig_x, val_x); } diff --git a/kernel/satgen.h b/kernel/satgen.h index 91f8ab40..692c6e7f 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -991,20 +991,7 @@ struct SatGen std::vector undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c))); - - std::vector undef_t1 = ez->vec_or(undef_a, undef_b); - - std::vector a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)); - std::vector b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b)); - std::vector undef_t2 = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0))); - - std::vector c0 = ez->vec_and(ez->vec_not(c), ez->vec_not(undef_c)); - std::vector t10 = ez->vec_and(ez->vec_not(t1), ez->vec_not(undef_t1)); - std::vector undef_t3 = ez->vec_and(ez->vec_or(undef_c, undef_t1), ez->vec_not(ez->vec_or(c0, t10))); - - std::vector t21 = ez->vec_and(t2, ez->vec_not(undef_t2)); - std::vector t31 = ez->vec_and(t3, ez->vec_not(undef_t3)); - ez->assume(ez->vec_eq(undef_x, ez->vec_and(ez->vec_or(undef_t2, undef_t3), ez->vec_not(ez->vec_or(t21, t31))))); + ez->assume(ez->vec_eq(undef_x, undef_y)); undefGating(y, yy, undef_y); undefGating(x, xx, undef_x); diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index da745b5e..dd12bd39 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -453,7 +453,7 @@ output [WIDTH-1:0] X, Y; wire [WIDTH-1:0] t1, t2, t3; assign t1 = A ^ B, t2 = A & B, t3 = C & t1; -assign Y = t1 ^ C, X = t2 | t3; +assign Y = t1 ^ C, X = (t2 | t3) ^ (Y ^ Y); endmodule From 44b5bd4b631874e5ed083d5de75f5b87431f935f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 17:09:39 +0200 Subject: [PATCH 712/750] Fixed simlib $macc model for xilinx xsim --- techlibs/common/simlib.v | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index dd12bd39..0ad8d14b 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -806,9 +806,23 @@ input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; output reg [Y_WIDTH-1:0] Y; +// Xilinx XSIM does not like $clog2() below.. +function integer my_clog2; + input integer v; + begin + if (v > 0) + v = v - 1; + my_clog2 = 0; + while (v) begin + v = v >> 1; + my_clog2 = my_clog2 + 1; + end + end +endfunction + localparam integer num_bits = CONFIG[3:0]; localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); -localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1; +localparam integer num_abits = my_clog2(A_WIDTH) > 0 ? my_clog2(A_WIDTH) : 1; function [2*num_ports*num_abits-1:0] get_port_offsets; input [CONFIG_WIDTH-1:0] cfg; From 3ae96f85a5528414eee458e8aa992aae90ceba7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 13 Sep 2014 17:28:15 +0200 Subject: [PATCH 713/750] Using pkg-config to find libffi --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a499157a..3ec89916 100644 --- a/Makefile +++ b/Makefile @@ -94,8 +94,8 @@ LDLIBS += -lreadline endif ifeq ($(ENABLE_PLUGINS),1) -CXXFLAGS += -DYOSYS_ENABLE_PLUGINS -LDLIBS += -lffi -ldl +CXXFLAGS += -DYOSYS_ENABLE_PLUGINS $(shell pkg-config --silence-errors --cflags libffi) +LDLIBS += $(shell pkg-config --silence-errors --libs libffi || echo -lffi) -ldl endif ifeq ($(ENABLE_TCL),1) From aab0e3bf702640806c6e81d42e922f938b0e0085 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 10:01:30 +0200 Subject: [PATCH 714/750] Cleanup in wreduce --- passes/opt/wreduce.cc | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 321a1aa5..9e43bb90 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -26,23 +26,20 @@ using namespace RTLIL; PRIVATE_NAMESPACE_BEGIN -static inline std::set &operator<<(std::set &set, IdString id) { - set.insert(id); - return set; -} - struct WreduceConfig { std::set supported_cell_types; WreduceConfig() { - supported_cell_types << "$not" << "$pos" << "$neg"; - supported_cell_types << "$and" << "$or" << "$xor" << "$xnor"; - supported_cell_types << "$shl" << "$shr" << "$sshl" << "$sshr" << "$shift" << "$shiftx"; - supported_cell_types << "$lt" << "$le" << "$eq" << "$ne" << "$eqx" << "$nex" << "$ge" << "$gt"; - supported_cell_types << "$add" << "$sub"; // << "$mul" << "$div" << "$mod" << "$pow" - supported_cell_types << "$mux" << "$pmux"; + supported_cell_types = { + "$not", "$pos", "$neg", + "$and", "$or", "$xor", "$xnor", + "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", + "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", + "$add", "$sub", // "$mul", "$div", "$mod", "$pow", + "$mux", "$pmux" + }; } }; From ff157fb74fc1b46408c075a0827adbca1b8c496e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 10:02:00 +0200 Subject: [PATCH 715/750] alumacc skeleton --- passes/techmap/Makefile.inc | 1 + passes/techmap/alumacc.cc | 63 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 passes/techmap/alumacc.cc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index da527ccf..72998f87 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -9,6 +9,7 @@ OBJS += passes/techmap/iopadmap.o OBJS += passes/techmap/hilomap.o OBJS += passes/techmap/extract.o OBJS += passes/techmap/maccmap.o +OBJS += passes/techmap/alumacc.o endif GENFILES += passes/techmap/techmap.inc diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc new file mode 100644 index 00000000..0e2fe4e7 --- /dev/null +++ b/passes/techmap/alumacc.cc @@ -0,0 +1,63 @@ +/* + * 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/yosys.h" +#include "kernel/macc.h" + +struct AlumaccWorker +{ + RTLIL::Module *module; + + AlumaccWorker(RTLIL::Module *module) : module(module) + { + } +}; + +struct AlumaccPass : public Pass { + AlumaccPass() : Pass("alumacc", "extract ALU and MACC cells") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" alumacc [selection]\n"); + log("\n"); + log("This pass translates arithmetic operations $add, $mul, $lt, etc. to $alu and\n"); + log("$macc cells.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + log_header("Executing ALUMACC pass (create $alu and $macc cells).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + // if (args[argidx] == "-foobar") { + // foobar_mode = true; + // continue; + // } + break; + } + extra_args(args, argidx, design); + + for (auto mod : design->selected_modules()) { + AlumaccWorker worker(mod); + } + } +} AlumaccPass; + From 0b72f0acb13e14d329cf408d22b636d61174eb8e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 10:45:28 +0200 Subject: [PATCH 716/750] Basic $macc extract in alumacc --- passes/techmap/alumacc.cc | 108 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 0e2fe4e7..757dc7cf 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -18,14 +18,112 @@ */ #include "kernel/yosys.h" +#include "kernel/sigtools.h" #include "kernel/macc.h" struct AlumaccWorker { RTLIL::Module *module; + SigMap sigmap; - AlumaccWorker(RTLIL::Module *module) : module(module) + struct maccnode_t { + Macc macc; + RTLIL::Cell *cell; + RTLIL::SigSpec y; + int users; + }; + + std::map bit_users; + std::map sig_macc; + + AlumaccWorker(RTLIL::Module *module) : module(module), sigmap(module) { } + + void count_bit_users() { + for (auto port : module->ports) + for (auto bit : sigmap(module->wire(port))) + bit_users[bit]++; + + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + for (auto bit : sigmap(conn.second)) + bit_users[bit]++; + } + + void extract_macc() + { + for (auto cell : module->selected_cells()) + { + if (!cell->type.in("$pos", "$neg", "$add", "$sub", "$mul")) + continue; + + maccnode_t *n = new maccnode_t; + Macc::port_t new_port; + + n->cell = cell; + n->y = sigmap(cell->getPort("\\Y")); + n->users = 0; + + for (auto bit : n->y) + n->users = std::max(n->users, bit_users.at(bit) - 1); + + + if (cell->type.in("$pos", "$neg")) + { + new_port.in_a = sigmap(cell->getPort("\\A")); + new_port.is_signed = cell->getParam("\\A_SIGNED").as_bool(); + new_port.do_subtract = cell->type == "$neg"; + n->macc.ports.push_back(new_port); + } + + if (cell->type.in("$add", "$sub")) + { + new_port.in_a = sigmap(cell->getPort("\\A")); + new_port.is_signed = cell->getParam("\\A_SIGNED").as_bool(); + new_port.do_subtract = false; + n->macc.ports.push_back(new_port); + + new_port.in_a = sigmap(cell->getPort("\\B")); + new_port.is_signed = cell->getParam("\\B_SIGNED").as_bool(); + new_port.do_subtract = cell->type == "$sub"; + n->macc.ports.push_back(new_port); + } + + if (cell->type.in("$mul")) + { + new_port.in_a = sigmap(cell->getPort("\\A")); + new_port.in_b = sigmap(cell->getPort("\\B")); + new_port.is_signed = cell->getParam("\\A_SIGNED").as_bool(); + new_port.do_subtract = false; + n->macc.ports.push_back(new_port); + } + + log_assert(sig_macc.count(n->y) == 0); + sig_macc[n->y] = n; + } + } + + void replace_macc() + { + for (auto &it : sig_macc) + { + auto n = it.second; + auto cell = module->addCell(NEW_ID, "$macc"); + n->macc.to_cell(cell); + cell->setPort("\\Y", n->y); + cell->fixup_parameters(); + module->remove(n->cell); + delete n; + } + + sig_macc.clear(); + } + + void run() + { + count_bit_users(); + extract_macc(); + replace_macc(); } }; @@ -55,9 +153,11 @@ struct AlumaccPass : public Pass { } extra_args(args, argidx, design); - for (auto mod : design->selected_modules()) { - AlumaccWorker worker(mod); - } + for (auto mod : design->selected_modules()) + if (!mod->has_processes_warn()) { + AlumaccWorker worker(mod); + worker.run(); + } } } AlumaccPass; From 7b16c63101d46274cb3b93907489c8403e5d9bc5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 11:21:37 +0200 Subject: [PATCH 717/750] Merge $macc cells in alumacc pass --- passes/techmap/alumacc.cc | 60 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 757dc7cf..5a15e825 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -57,6 +57,8 @@ struct AlumaccWorker if (!cell->type.in("$pos", "$neg", "$add", "$sub", "$mul")) continue; + log(" creating $macc model for %s (%s).\n", log_id(cell), log_id(cell->type)); + maccnode_t *n = new maccnode_t; Macc::port_t new_port; @@ -67,7 +69,6 @@ struct AlumaccWorker for (auto bit : n->y) n->users = std::max(n->users, bit_users.at(bit) - 1); - if (cell->type.in("$pos", "$neg")) { new_port.in_a = sigmap(cell->getPort("\\A")); @@ -103,6 +104,60 @@ struct AlumaccWorker } } + void merge_macc() + { + while (1) + { + std::set delete_nodes; + + for (auto &it : sig_macc) + { + auto n = it.second; + + if (delete_nodes.count(n)) + continue; + + for (int i = 0; i < SIZE(n->macc.ports); i++) + { + auto &port = n->macc.ports[i]; + + if (SIZE(port.in_b) > 0 || sig_macc.count(port.in_a) == 0) + continue; + + auto other_n = sig_macc.at(port.in_a); + + if (other_n->users > 1) + continue; + + if (SIZE(other_n->y) != SIZE(n->y)) + continue; + + log(" merging $macc model for %s into %s.\n", log_id(other_n->cell), log_id(n->cell)); + + bool do_subtract = port.do_subtract; + for (int j = 0; j < SIZE(other_n->macc.ports); j++) { + if (do_subtract) + other_n->macc.ports[j].do_subtract = !other_n->macc.ports[j].do_subtract; + if (j == 0) + n->macc.ports[i--] = other_n->macc.ports[j]; + else + n->macc.ports.push_back(other_n->macc.ports[j]); + } + + delete_nodes.insert(other_n); + } + } + + if (delete_nodes.empty()) + break; + + for (auto n : delete_nodes) { + sig_macc.erase(n->y); + delete n; + } + } + } + void replace_macc() { for (auto &it : sig_macc) @@ -121,8 +176,11 @@ struct AlumaccWorker void run() { + log("Extracting $alu and $macc cells in module %s:\n", log_id(module)); + count_bit_users(); extract_macc(); + merge_macc(); replace_macc(); } }; From 0df1d9ad72ad16af6c1d2d0c5f412914f322e326 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 13:23:44 +0200 Subject: [PATCH 718/750] Extract $alu cells in alumacc --- passes/techmap/alumacc.cc | 297 +++++++++++++++++++++++++++++++++++++- 1 file changed, 296 insertions(+), 1 deletion(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 5a15e825..2a4f8178 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -33,10 +33,78 @@ struct AlumaccWorker int users; }; + struct alunode_t + { + std::vector cells; + RTLIL::SigSpec a, b, c, y; + std::vector> cmp; + bool is_signed, invert_b; + + RTLIL::Cell *alu_cell; + RTLIL::SigSpec cached_lt, cached_gt, cached_eq, cached_ne; + RTLIL::SigSpec cached_cf, cached_of, cached_sf; + + RTLIL::SigSpec get_lt() { + if (SIZE(cached_lt) == 0) + cached_lt = is_signed ? alu_cell->module->Xor(NEW_ID, get_of(), get_sf()) : get_cf(); + return cached_lt; + } + + RTLIL::SigSpec get_gt() { + if (SIZE(cached_gt) == 0) + cached_gt = alu_cell->module->Not(NEW_ID, alu_cell->module->Or(NEW_ID, get_lt(), get_eq())); + return cached_gt; + } + + RTLIL::SigSpec get_eq() { + if (SIZE(cached_eq) == 0) + cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort("\\X")); + return cached_eq; + } + + RTLIL::SigSpec get_ne() { + if (SIZE(cached_ne) == 0) + cached_ne = alu_cell->module->Not(NEW_ID, get_eq()); + return cached_ne; + } + + RTLIL::SigSpec get_cf() { + if (SIZE(cached_cf) == 0) { + cached_cf = alu_cell->getPort("\\CO"); + log_assert(SIZE(cached_cf) >= 1); + cached_cf = alu_cell->module->Not(NEW_ID, cached_cf[SIZE(cached_cf)-1]); + } + return cached_cf; + } + + RTLIL::SigSpec get_of() { + if (SIZE(cached_of) == 0) { + cached_of = {alu_cell->getPort("\\CO"), alu_cell->getPort("\\CI")}; + log_assert(SIZE(cached_of) >= 2); + cached_of = alu_cell->module->Xor(NEW_ID, cached_of[SIZE(cached_of)-1], cached_of[SIZE(cached_of)-2]); + } + return cached_of; + } + + RTLIL::SigSpec get_sf() { + if (SIZE(cached_sf) == 0) { + cached_sf = alu_cell->getPort("\\Y"); + cached_sf = cached_sf[SIZE(cached_sf)-1]; + } + return cached_sf; + } + }; + std::map bit_users; std::map sig_macc; + std::map> sig_alu; + int macc_counter, alu_counter; - AlumaccWorker(RTLIL::Module *module) : module(module), sigmap(module) { } + AlumaccWorker(RTLIL::Module *module) : module(module), sigmap(module) + { + macc_counter = 0; + alu_counter = 0; + } void count_bit_users() { @@ -158,12 +226,96 @@ struct AlumaccWorker } } + void macc_to_alu() + { + std::set delete_nodes; + + for (auto &it : sig_macc) + { + auto n = it.second; + RTLIL::SigSpec A, B, C = n->macc.bit_ports; + bool a_signed = false, b_signed = false; + bool subtract_b = false; + alunode_t *alunode; + + for (auto &port : n->macc.ports) + if (SIZE(port.in_b) > 0) { + goto next_macc; + } else if (SIZE(port.in_a) == 1 && !port.is_signed && !port.do_subtract) { + C.append(port.in_a); + } else if (SIZE(A) || port.do_subtract) { + if (SIZE(B)) + goto next_macc; + B = port.in_a; + b_signed = port.is_signed; + subtract_b = port.do_subtract; + } else { + if (SIZE(A)) + goto next_macc; + A = port.in_a; + a_signed = port.is_signed; + } + + if (!a_signed || !b_signed) { + if (SIZE(A) == SIZE(n->y)) + a_signed = false; + if (SIZE(B) == SIZE(n->y)) + b_signed = false; + if (a_signed != b_signed) + goto next_macc; + } + + if (SIZE(A) == 0 && SIZE(C) > 0) { + A = C[0]; + C.remove(0); + } + + if (SIZE(B) == 0 && SIZE(C) > 0) { + B = C[0]; + C.remove(0); + } + + if (subtract_b) + C.append(RTLIL::S1); + + if (SIZE(C) > 1) + goto next_macc; + + if (!subtract_b && B < A) + std::swap(A, B); + + log(" creating $alu model for $macc %s.\n", log_id(n->cell)); + + alunode = new alunode_t; + alunode->cells.push_back(n->cell); + alunode->is_signed = a_signed; + alunode->invert_b = subtract_b; + + alunode->a = A; + alunode->b = B; + alunode->c = C; + alunode->y = n->y; + + sig_alu[RTLIL::SigSig(A, B)].insert(alunode); + delete_nodes.insert(n); + next_macc:; + } + + for (auto n : delete_nodes) { + sig_macc.erase(n->y); + delete n; + } + } + void replace_macc() { + macc_counter += SIZE(sig_macc); + for (auto &it : sig_macc) { auto n = it.second; auto cell = module->addCell(NEW_ID, "$macc"); + log(" creating $macc cell for %s: %s\n", log_id(n->cell), log_id(cell)); n->macc.to_cell(cell); cell->setPort("\\Y", n->y); cell->fixup_parameters(); @@ -174,6 +326,144 @@ struct AlumaccWorker sig_macc.clear(); } + void extract_cmp_alu() + { + std::vector lge_cells, eq_cells; + + for (auto cell : module->selected_cells()) + { + if (cell->type.in("$lt", "$le", "$ge", "$gt")) + lge_cells.push_back(cell); + if (cell->type.in("$eq", "$eqx", "$ne", "$nex")) + eq_cells.push_back(cell); + } + + for (auto cell : lge_cells) + { + log(" creating $alu model for %s (%s):", log_id(cell), log_id(cell->type)); + + bool cmp_less = cell->type.in("$lt", "$le"); + bool cmp_equal = cell->type.in("$le", "$ge"); + bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + + RTLIL::SigSpec A = sigmap(cell->getPort("\\A")); + RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); + RTLIL::SigSpec Y = sigmap(cell->getPort("\\Y")); + + if (B < A) { + cmp_less = !cmp_less; + std::swap(A, B); + } + + alunode_t *n = nullptr; + + for (auto node : sig_alu[RTLIL::SigSig(A, B)]) + if (node->is_signed == is_signed && node->invert_b && node->c == RTLIL::S1) { + n = node; + break; + } + + if (n == nullptr) { + n = new alunode_t; + n->a = A; + n->b = B; + n->c = RTLIL::S1; + n->y = module->addWire(NEW_ID, std::max(SIZE(A), SIZE(B))); + n->is_signed = is_signed; + n->invert_b = true; + sig_alu[RTLIL::SigSig(A, B)].insert(n); + log(" new $alu\n"); + } else { + log(" merged with %s.\n", log_id(n->cells.front())); + } + + n->cells.push_back(cell); + n->cmp.push_back(std::make_tuple(cmp_less, !cmp_less, cmp_equal, false, Y)); + } + + for (auto cell : eq_cells) + { + bool cmp_equal = cell->type.in("$eq", "$eqx"); + bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); + + RTLIL::SigSpec A = sigmap(cell->getPort("\\A")); + RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); + RTLIL::SigSpec Y = sigmap(cell->getPort("\\Y")); + + if (B < A) + std::swap(A, B); + + alunode_t *n = nullptr; + + for (auto node : sig_alu[RTLIL::SigSig(A, B)]) + if (node->is_signed == is_signed && node->invert_b && node->c == RTLIL::S1) { + n = node; + break; + } + + if (n != nullptr) { + log(" creating $alu model for %s (%s): merged with %s.\n", log_id(cell), log_id(cell->type), log_id(n->cells.front())); + n->cells.push_back(cell); + n->cmp.push_back(std::make_tuple(false, false, cmp_equal, !cmp_equal, Y)); + } + } + } + + void replace_alu() + { + alu_counter += SIZE(sig_alu); + + for (auto &it1 : sig_alu) + for (auto n : it1.second) + { + n->alu_cell = module->addCell(NEW_ID, "$alu"); + + log(" creating $alu cell for "); + for (int i = 0; i < SIZE(n->cells); i++) + log("%s%s", i ? ", ": "", log_id(n->cells[i])); + log(": %s\n", log_id(n->alu_cell)); + + RTLIL::Wire *x = module->addWire(NEW_ID, SIZE(n->y)); + RTLIL::Wire *co = module->addWire(NEW_ID, SIZE(n->y)); + + n->alu_cell->setPort("\\A", n->a); + n->alu_cell->setPort("\\B", n->b); + n->alu_cell->setPort("\\CI", SIZE(n->c) ? n->c : RTLIL::S0); + n->alu_cell->setPort("\\BI", n->invert_b ? RTLIL::S1 : RTLIL::S0); + n->alu_cell->setPort("\\Y", n->y); + n->alu_cell->setPort("\\X", x); + n->alu_cell->setPort("\\CO", co); + n->alu_cell->fixup_parameters(); + + for (auto &it : n->cmp) + { + bool cmp_lt = std::get<0>(it); + bool cmp_gt = std::get<1>(it); + bool cmp_eq = std::get<2>(it); + bool cmp_ne = std::get<3>(it); + RTLIL::SigSpec cmp_y = std::get<4>(it); + + RTLIL::SigSpec sig; + if (cmp_lt) sig.append(n->get_lt()); + if (cmp_gt) sig.append(n->get_gt()); + if (cmp_eq) sig.append(n->get_eq()); + if (cmp_ne) sig.append(n->get_ne()); + + if (SIZE(sig) > 1) + sig = module->ReduceOr(NEW_ID, sig); + + sig.extend(SIZE(cmp_y)); + module->connect(cmp_y, sig); + } + + for (auto c : n->cells) + module->remove(c); + delete n; + } + + sig_alu.clear(); + } + void run() { log("Extracting $alu and $macc cells in module %s:\n", log_id(module)); @@ -181,7 +471,12 @@ struct AlumaccWorker count_bit_users(); extract_macc(); merge_macc(); + macc_to_alu(); replace_macc(); + extract_cmp_alu(); + replace_alu(); + + log(" created %d $alu and %d $macc cells.\n", alu_counter, macc_counter); } }; From b34ca151853aa2b5052afd56269a53079e17429d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:00:14 +0200 Subject: [PATCH 719/750] alumacc fix for $pos cells --- passes/techmap/alumacc.cc | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 2a4f8178..d6ee9e66 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -281,7 +281,7 @@ struct AlumaccWorker if (SIZE(C) > 1) goto next_macc; - if (!subtract_b && B < A) + if (!subtract_b && B < A && SIZE(B)) std::swap(A, B); log(" creating $alu model for $macc %s.\n", log_id(n->cell)); @@ -309,13 +309,14 @@ struct AlumaccWorker void replace_macc() { - macc_counter += SIZE(sig_macc); - for (auto &it : sig_macc) { auto n = it.second; auto cell = module->addCell(NEW_ID, "$macc"); + macc_counter++; + log(" creating $macc cell for %s: %s\n", log_id(n->cell), log_id(cell)); + n->macc.to_cell(cell); cell->setPort("\\Y", n->y); cell->fixup_parameters(); @@ -350,7 +351,7 @@ struct AlumaccWorker RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); RTLIL::SigSpec Y = sigmap(cell->getPort("\\Y")); - if (B < A) { + if (B < A && SIZE(B)) { cmp_less = !cmp_less; std::swap(A, B); } @@ -390,7 +391,7 @@ struct AlumaccWorker RTLIL::SigSpec B = sigmap(cell->getPort("\\B")); RTLIL::SigSpec Y = sigmap(cell->getPort("\\Y")); - if (B < A) + if (B < A && SIZE(B)) std::swap(A, B); alunode_t *n = nullptr; @@ -411,29 +412,38 @@ struct AlumaccWorker void replace_alu() { - alu_counter += SIZE(sig_alu); - for (auto &it1 : sig_alu) for (auto n : it1.second) { + if (SIZE(n->b) == 0 && SIZE(n->c) == 0 && SIZE(n->cmp) == 0) + { + n->alu_cell = module->addPos(NEW_ID, n->a, n->y, n->is_signed); + + log(" creating $pos cell for "); + for (int i = 0; i < SIZE(n->cells); i++) + log("%s%s", i ? ", ": "", log_id(n->cells[i])); + log(": %s\n", log_id(n->alu_cell)); + + goto delete_node; + } + n->alu_cell = module->addCell(NEW_ID, "$alu"); + alu_counter++; log(" creating $alu cell for "); for (int i = 0; i < SIZE(n->cells); i++) log("%s%s", i ? ", ": "", log_id(n->cells[i])); log(": %s\n", log_id(n->alu_cell)); - RTLIL::Wire *x = module->addWire(NEW_ID, SIZE(n->y)); - RTLIL::Wire *co = module->addWire(NEW_ID, SIZE(n->y)); - n->alu_cell->setPort("\\A", n->a); n->alu_cell->setPort("\\B", n->b); n->alu_cell->setPort("\\CI", SIZE(n->c) ? n->c : RTLIL::S0); n->alu_cell->setPort("\\BI", n->invert_b ? RTLIL::S1 : RTLIL::S0); n->alu_cell->setPort("\\Y", n->y); - n->alu_cell->setPort("\\X", x); - n->alu_cell->setPort("\\CO", co); - n->alu_cell->fixup_parameters(); + n->alu_cell->setPort("\\X", module->addWire(NEW_ID, SIZE(n->y))); + n->alu_cell->setPort("\\CO", module->addWire(NEW_ID, SIZE(n->y))); + n->alu_cell->fixup_parameters(n->is_signed, n->is_signed); + log_cell(n->alu_cell); for (auto &it : n->cmp) { @@ -456,6 +466,7 @@ struct AlumaccWorker module->connect(cmp_y, sig); } + delete_node: for (auto c : n->cells) module->remove(c); delete n; From 124e759280fecf9e8698b7e09c5d9e87d8fb3f96 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:49:26 +0200 Subject: [PATCH 720/750] Added techmap_wrap attribute --- passes/techmap/techmap.cc | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 93ba7c40..8332e988 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -349,22 +349,26 @@ struct TechmapWorker if (tpl->get_bool_attribute("\\techmap_maccmap")) extmapper_name = "maccmap"; + if (tpl->attributes.count("\\techmap_wrap")) + extmapper_name = "wrap"; + if (!extmapper_name.empty()) { cell->type = cell_type; - if (extern_mode && !in_recursion) + if ((extern_mode && !in_recursion) || extmapper_name == "wrap") { std::string m_name = stringf("$extern:%s:%s", extmapper_name.c_str(), log_id(cell->type)); for (auto &c : cell->parameters) m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second)); - RTLIL::Module *extmapper_module = design->module(m_name); + RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design; + RTLIL::Module *extmapper_module = extmapper_design->module(m_name); if (extmapper_module == nullptr) { - extmapper_module = design->addModule(m_name); + extmapper_module = extmapper_design->addModule(m_name); RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell); int port_counter = 1; @@ -378,6 +382,7 @@ struct TechmapWorker c.second = w; } + extmapper_module->fixup_ports(); extmapper_module->check(); if (extmapper_name == "simplemap") { @@ -385,6 +390,7 @@ struct TechmapWorker if (simplemap_mappers.count(extmapper_cell->type) == 0) log_error("No simplemap mapper for cell type %s found!\n", log_id(extmapper_cell->type)); simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell); + extmapper_module->remove(extmapper_cell); } if (extmapper_name == "maccmap") { @@ -392,14 +398,26 @@ struct TechmapWorker if (extmapper_cell->type != "$macc") log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type)); maccmap(extmapper_module, extmapper_cell); + extmapper_module->remove(extmapper_cell); } - extmapper_module->remove(extmapper_cell); + if (extmapper_name == "wrap") { + std::string cmd_string = tpl->attributes.at("\\techmap_wrap").decode_string(); + log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module)); + Pass::call_on_module(extmapper_design, extmapper_module, cmd_string); + log_continue = true; + } + } + + cell->type = extmapper_module->name; + cell->parameters.clear(); + + if (!extern_mode || in_recursion) { + tpl = extmapper_module; + goto use_wrapper_tpl; } log("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module)); - cell->type = extmapper_module->name; - cell->parameters.clear(); } else { @@ -426,6 +444,7 @@ struct TechmapWorker break; } + use_wrapper_tpl: for (auto conn : cell->connections()) { if (conn.first.substr(0, 1) == "$") continue; @@ -786,6 +805,10 @@ struct TechmapPass : public Pass { log("When a module in the map file has the 'techmap_maccmap' attribute set, techmap\n"); log("will use 'maccmap' (see 'help maccmap') to map cells matching the module.\n"); log("\n"); + log("When a module in the map file has the 'techmap_wrap' attribute set, techmap\n"); + log("will create a wrapper for the cell and then run the command string that the\n"); + log("attribute is set to on the wrapper module.\n"); + log("\n"); log("All wires in the modules from the map file matching the pattern _TECHMAP_*\n"); log("or *._TECHMAP_* are special wires that are used to pass instructions from\n"); log("the mapping module to the techmap command. At the moment the following special\n"); From 014bb34e0ecd058545fafbf1dbb0ba5064714c1d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:49:53 +0200 Subject: [PATCH 721/750] Various fixes/cleanups in alumacc and maccmap --- passes/techmap/alumacc.cc | 1 - passes/techmap/maccmap.cc | 12 +++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index d6ee9e66..3fddcef1 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -443,7 +443,6 @@ struct AlumaccWorker n->alu_cell->setPort("\\X", module->addWire(NEW_ID, SIZE(n->y))); n->alu_cell->setPort("\\CO", module->addWire(NEW_ID, SIZE(n->y))); n->alu_cell->fixup_parameters(n->is_signed, n->is_signed); - log_cell(n->alu_cell); for (auto &it : n->cmp) { diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index c2dc9aa8..e17231cb 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -208,7 +208,17 @@ struct MaccmapWorker log_assert(tree_sum_bits.empty()); - return module->Add(NEW_ID, summands.front(), summands.back()); + RTLIL::Cell *c = module->addCell(NEW_ID, "$alu"); + c->setPort("\\A", summands.front()); + c->setPort("\\B", summands.back()); + c->setPort("\\CI", RTLIL::S0); + c->setPort("\\BI", RTLIL::S0); + c->setPort("\\Y", module->addWire(NEW_ID, width)); + c->setPort("\\X", module->addWire(NEW_ID, width)); + c->setPort("\\CO", module->addWire(NEW_ID, width)); + c->fixup_parameters(); + + return c->getPort("\\Y"); } }; From 923bbbeaf049d2c5386765cb4fe62014a1770204 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:50:15 +0200 Subject: [PATCH 722/750] Using alumacc in techmap.v --- techlibs/common/techmap.v | 270 +++++--------------------------------- 1 file changed, 33 insertions(+), 237 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 491511db..b6c075b6 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -40,101 +40,27 @@ (* techmap_simplemap *) (* techmap_celltype = "$not $and $or $xor $xnor" *) -module simplemap_bool_ops; +module _90_simplemap_bool_ops; endmodule (* techmap_simplemap *) (* techmap_celltype = "$reduce_and $reduce_or $reduce_xor $reduce_xnor $reduce_bool" *) -module simplemap_reduce_ops; +module _90_simplemap_reduce_ops; endmodule (* techmap_simplemap *) (* techmap_celltype = "$logic_not $logic_and $logic_or" *) -module simplemap_logic_ops; +module _90_simplemap_logic_ops; endmodule (* techmap_simplemap *) (* techmap_celltype = "$pos $slice $concat $mux" *) -module simplemap_various; +module _90_simplemap_various; endmodule (* techmap_simplemap *) (* techmap_celltype = "$sr $dff $adff $dffsr $dlatch" *) -module simplemap_registers; -endmodule - - -// -------------------------------------------------------- -// Trivial substitutions -// -------------------------------------------------------- - -module \$neg (A, Y); - parameter A_SIGNED = 0; - parameter A_WIDTH = 1; - parameter Y_WIDTH = 1; - - input [A_WIDTH-1:0] A; - output [Y_WIDTH-1:0] Y; - - \$sub #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(1), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A(1'b0), - .B(A), - .Y(Y) - ); -endmodule - -module \$ge (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - \$le #( - .A_SIGNED(B_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(B_WIDTH), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A(B), - .B(A), - .Y(Y) - ); -endmodule - -module \$gt (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - \$lt #( - .A_SIGNED(B_SIGNED), - .B_SIGNED(A_SIGNED), - .A_WIDTH(B_WIDTH), - .B_WIDTH(A_WIDTH), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A(B), - .B(A), - .Y(Y) - ); +module _90_simplemap_registers; endmodule @@ -143,7 +69,7 @@ endmodule // -------------------------------------------------------- (* techmap_celltype = "$shr $shl $sshl $sshr" *) -module shift_ops_shr_shl_sshl_sshr (A, B, Y); +module _90_shift_ops_shr_shl_sshl_sshr (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -187,7 +113,7 @@ module shift_ops_shr_shl_sshl_sshr (A, B, Y); endmodule (* techmap_celltype = "$shift $shiftx" *) -module shift_shiftx (A, B, Y); +module _90_shift_shiftx (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -243,10 +169,11 @@ endmodule // -------------------------------------------------------- -// ALU Infrastructure +// Arithmetic operators // -------------------------------------------------------- -module \$fa (A, B, C, X, Y); +(* techmap_celltype = "$fa" *) +module _90_fa (A, B, C, X, Y); parameter WIDTH = 1; input [WIDTH-1:0] A, B, C; @@ -258,7 +185,8 @@ module \$fa (A, B, C, X, Y); assign Y = t1 ^ C, X = t2 | t3; endmodule -module \$lcu (P, G, CI, CO); +(* techmap_celltype = "$lcu" *) +module _90_lcu (P, G, CI, CO); parameter WIDTH = 2; input [WIDTH-1:0] P, G; @@ -302,7 +230,8 @@ module \$lcu (P, G, CI, CO); assign CO = g; endmodule -module \$alu (A, B, CI, BI, X, Y, CO); +(* techmap_celltype = "$alu" *) +module _90_alu (A, B, CI, BI, X, Y, CO); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -329,112 +258,14 @@ module \$alu (A, B, CI, BI, X, Y, CO); assign Y = X ^ {CO, CI}; endmodule - -// -------------------------------------------------------- -// ALU Cell Types: Compare, Add, Subtract -// -------------------------------------------------------- - -`define ALU_COMMONS(_width, _sub) """ - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - localparam WIDTH = _width; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire [WIDTH-1:0] alu_x, alu_y, alu_co; - wire [WIDTH:0] carry = {alu_co, |_sub}; - - \$alu #( - .A_SIGNED(A_SIGNED), - .B_SIGNED(B_SIGNED), - .A_WIDTH(A_WIDTH), - .B_WIDTH(B_WIDTH), - .Y_WIDTH(WIDTH) - ) alu ( - .A(A), - .B(B), - .CI(|_sub), - .BI(|_sub), - .X(alu_x), - .Y(alu_y), - .CO(alu_co) - ); - - wire cf, of, zf, sf; - assign cf = !carry[WIDTH]; - assign of = carry[WIDTH] ^ carry[WIDTH-1]; - assign sf = alu_y[WIDTH-1]; -""" - -module \$lt (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1) - assign Y = A_SIGNED && B_SIGNED ? of != sf : cf; -endmodule - -module \$le (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(`MAX(A_WIDTH, B_WIDTH), 1) - assign Y = &alu_x || (A_SIGNED && B_SIGNED ? of != sf : cf); -endmodule - -module \$add (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(Y_WIDTH, 0) - assign Y = alu_y; -endmodule - -module \$sub (A, B, Y); - wire [1023:0] _TECHMAP_DO_ = "RECURSION; opt_const -mux_undef -mux_bool -fine;;;"; - `ALU_COMMONS(Y_WIDTH, 1) - assign Y = alu_y; -endmodule - - -// -------------------------------------------------------- -// Multiply -// -------------------------------------------------------- - (* techmap_maccmap *) -module \$macc ; +(* techmap_celltype = "$macc" *) +module _90_macc; endmodule -module \$mul (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt -purge"; - - localparam [ 3:0] CONFIG_WIDTH_BITS = 15; - localparam [ 0:0] CONFIG_IS_SIGNED = A_SIGNED && B_SIGNED; - localparam [ 0:0] CONFIG_DO_SUBTRACT = 0; - localparam [14:0] CONFIG_A_WIDTH = A_WIDTH; - localparam [14:0] CONFIG_B_WIDTH = B_WIDTH; - - \$macc #( - .CONFIG({CONFIG_B_WIDTH, CONFIG_A_WIDTH, CONFIG_DO_SUBTRACT, CONFIG_IS_SIGNED, CONFIG_WIDTH_BITS}), - .CONFIG_WIDTH(15 + 15 + 2 + 4), - .A_WIDTH(B_WIDTH + A_WIDTH), - .B_WIDTH(0), - .Y_WIDTH(Y_WIDTH) - ) _TECHMAP_REPLACE_ ( - .A({B, A}), - .B(), - .Y(Y) - ); +(* techmap_wrap = "alumacc" *) +(* techmap_celltype = "$lt $le $ge $gt $add $sub $neg $mul" *) +module _90_alumacc; endmodule @@ -504,7 +335,8 @@ module \$__div_mod (A, B, Y, R); assign R = A_SIGNED && B_SIGNED && A_buf[WIDTH-1] ? -R_u : R_u; endmodule -module \$div (A, B, Y); +(* techmap_celltype = "$div" *) +module _90_div (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -528,7 +360,8 @@ module \$div (A, B, Y); ); endmodule -module \$mod (A, B, Y); +(* techmap_celltype = "$mod" *) +module _90_mod (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -557,7 +390,8 @@ endmodule // Power // -------------------------------------------------------- -module \$pow (A, B, Y); +(* techmap_celltype = "$pow" *) +module _90_pow (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -576,7 +410,8 @@ endmodule // Equal and Not-Equal // -------------------------------------------------------- -module \$eq (A, B, Y); +(* techmap_celltype = "$eq $eqx" *) +module _90_eq_eqx (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -597,49 +432,8 @@ module \$eq (A, B, Y); assign Y = ~|(A_buf ^ B_buf); endmodule -module \$ne (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire carry, carry_sign; - wire [WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - - assign Y = |(A_buf ^ B_buf); -endmodule - -module \$eqx (A, B, Y); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire carry, carry_sign; - wire [WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf)); - - assign Y = ~|(A_buf ^ B_buf); -endmodule - -module \$nex (A, B, Y); +(* techmap_celltype = "$ne $nex" *) +module _90_ne_nex (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -665,7 +459,8 @@ endmodule // Parallel Multiplexers // -------------------------------------------------------- -module \$pmux (A, B, S, Y); +(* techmap_celltype = "$pmux" *) +module _90_pmux (A, B, S, Y); parameter WIDTH = 1; parameter S_WIDTH = 1; @@ -700,7 +495,8 @@ endmodule // -------------------------------------------------------- `ifndef NOLUT -module \$lut (A, Y); +(* techmap_celltype = "$lut" *) +module _90_lut (A, Y); parameter WIDTH = 1; parameter LUT = 0; From 7e156a541909ec857fbaa4a08940d0aaf0d27d4b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 15:34:36 +0200 Subject: [PATCH 723/750] Fixed techmap_wrap for techmap_celltype --- passes/techmap/techmap.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 8332e988..ed466faa 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -363,6 +363,9 @@ struct TechmapWorker for (auto &c : cell->parameters) m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second)); + if (extmapper_name == "wrap") + m_name += ":" + sha1(tpl->attributes.at("\\techmap_wrap").decode_string()); + RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design; RTLIL::Module *extmapper_module = extmapper_design->module(m_name); @@ -444,7 +447,6 @@ struct TechmapWorker break; } - use_wrapper_tpl: for (auto conn : cell->connections()) { if (conn.first.substr(0, 1) == "$") continue; @@ -511,16 +513,21 @@ struct TechmapWorker } } - std::pair> key(tpl_name, parameters); - if (techmap_cache.count(key) > 0) { - tpl = techmap_cache[key]; + if (0) { + use_wrapper_tpl:; + // do not register techmap_wrap modules with techmap_cache } else { - if (cell->parameters.size() != 0) { - derived_name = tpl->derive(map, parameters); - tpl = map->module(derived_name); - log_continue = true; + std::pair> key(tpl_name, parameters); + if (techmap_cache.count(key) > 0) { + tpl = techmap_cache[key]; + } else { + if (cell->parameters.size() != 0) { + derived_name = tpl->derive(map, parameters); + tpl = map->module(derived_name); + log_continue = true; + } + techmap_cache[key] = tpl; } - techmap_cache[key] = tpl; } if (flatten_mode) { From 7815f81c320a025c5b92677e375c12951dcbd14b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 16:09:06 +0200 Subject: [PATCH 724/750] Added "synth" command --- Makefile | 1 + README | 21 +++-- kernel/driver.cc | 14 +--- techlibs/common/Makefile.inc | 2 + techlibs/common/synth.cc | 152 +++++++++++++++++++++++++++++++++++ tests/tools/autotest.sh | 4 +- 6 files changed, 174 insertions(+), 20 deletions(-) create mode 100644 techlibs/common/synth.cc diff --git a/Makefile b/Makefile index 3ec89916..7e8c7042 100644 --- a/Makefile +++ b/Makefile @@ -111,6 +111,7 @@ LDFLAGS += -pg endif ifeq ($(ENABLE_ABC),1) +CXXFLAGS += -DYOSYS_ENABLE_ABC TARGETS += yosys-abc endif diff --git a/README b/README index 7e8a42a8..d7f5aaa4 100644 --- a/README +++ b/README @@ -199,6 +199,19 @@ Various more complex liberty files (for testing) can be found here: ../cadence/lib/tsmc018/signalstorm/osu018_stdcells.lib ../cadence/lib/ami05/signalstorm/osu05_stdcells.lib +The command "synth" provides a good default synthesis script (see "help synth"). +If possible a synthesis script should borrow from "synth". For example: + + # the high-level stuff + hierarchy + synth -run coarse + + # mapping to internal cells + techmap; opt -fast + dfflibmap -liberty mycells.lib + abc -liberty mycells.lib + clean + Yosys is under construction. A more detailed documentation will follow. @@ -351,12 +364,7 @@ from SystemVerilog: Roadmap / Large-scale TODOs =========================== -- Verification and Regression Tests - - VlogHammer: http://www.clifford.at/yosys/vloghammer.html - - yosys-bigsim: https://github.com/cliffordwolf/yosys-bigsim - - Technology mapping for real-world applications - - Rewrite current techmap.v rules (modular and clean) - Improve Xilinx FGPA synthesis (RAMB, CARRY4, SLR, etc.) - Implement SAT-based formal equivialence checker @@ -382,7 +390,4 @@ Other Unsorted TODOs - Add brief source code documentation to most passes and kernel code - Implement mux-to-tribuf pass and rebalance mixed mux/tribuf trees - - Add more commands for changing the design (delete, add, modify objects) - - Add full support for $lut cell type (const evaluation, sat solving, etc.) - - Smarter resource sharing pass (add MUXes and get rid of duplicated cells) diff --git a/kernel/driver.cc b/kernel/driver.cc index e778e138..f26d9ef8 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -76,13 +76,7 @@ int main(int argc, char **argv) printf("%s\n", yosys_version_str); exit(0); case 'S': - passes_commands.push_back("hierarchy"); - passes_commands.push_back("proc"); - passes_commands.push_back("opt"); - passes_commands.push_back("memory"); - passes_commands.push_back("opt"); - passes_commands.push_back("techmap"); - passes_commands.push_back("opt"); + passes_commands.push_back("synth"); break; case 'm': plugin_filenames.push_back(optarg); @@ -187,10 +181,10 @@ int main(int argc, char **argv) fprintf(stderr, " -V\n"); fprintf(stderr, " print version information and exit\n"); fprintf(stderr, "\n"); - fprintf(stderr, "The option -S is an alias for the following options that perform a simple\n"); - fprintf(stderr, "transformation of the input to a gate-level netlist.\n"); + fprintf(stderr, "The option -S is an shortcut for calling the \"synth\" command, a default\n"); + fprintf(stderr, "script for transforming the verilog input to a gate-level netlist. For example:\n"); fprintf(stderr, "\n"); - fprintf(stderr, " -p hierarchy -p proc -p opt -p memory -p opt -p techmap -p opt\n"); + fprintf(stderr, " yosys -o output.blif -S input.v\n"); fprintf(stderr, "\n"); fprintf(stderr, "For more complex synthesis jobs it is recommended to use the read_* and write_*\n"); fprintf(stderr, "commands in a script file instead of specifying input and output files on the\n"); diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 461c1cb4..7c8cc2f6 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -1,4 +1,6 @@ +OBJS += techlibs/common/synth.o + EXTRA_TARGETS += techlibs/common/blackbox.v techlibs/common/blackbox.v: techlibs/common/blackbox.sed techlibs/common/simlib.v techlibs/common/simcells.v diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc new file mode 100644 index 00000000..95221afa --- /dev/null +++ b/techlibs/common/synth.cc @@ -0,0 +1,152 @@ +/* + * 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/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +static bool check_label(bool &active, std::string run_from, std::string run_to, std::string label) +{ + if (!run_from.empty() && run_from == run_to) { + active = (label == run_from); + } else { + if (label == run_from) + active = true; + if (label == run_to) + active = false; + } + return active; +} + +struct SynthPass : public Pass { + SynthPass() : Pass("synth", "generic synthesis script") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth [options]\n"); + log("\n"); + log("This command runs the default synthesis script. This command does not operate\n"); + log("on partly selected designs.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module (default='top')\n"); + log("\n"); + log(" -run [:]\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + log("\n"); + log(" begin:\n"); + log(" hierarchy -check [-top ]\n"); + log("\n"); + log(" coarse:\n"); + log(" proc\n"); + log(" opt\n"); + log(" wreduce\n"); + log(" alumacc\n"); + log(" share\n"); + log(" opt -fast\n"); + log(" fsm\n"); + log(" opt -fast\n"); + log(" memory\n"); + log("\n"); + log(" fine:\n"); + log(" techmap\n"); + log(" opt -fast\n"); + #ifdef YOSYS_ENABLE_ABC + log(" abc\n"); + #endif + log(" clean\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + std::string top_module; + std::string run_from, run_to; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_module = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) { + run_from = args[++argidx]; + run_to = args[argidx]; + } else { + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + } + continue; + } + break; + } + extra_args(args, argidx, design); + + if (!design->full_selection()) + log_cmd_error("This comannd only operates on fully selected designs!\n"); + + bool active = run_from.empty(); + + log_header("Executing SYNTH pass.\n"); + log_push(); + + if (check_label(active, run_from, run_to, "begin")) + { + if (top_module.empty()) + Pass::call(design, stringf("hierarchy -check")); + else + Pass::call(design, stringf("hierarchy -check -top %s", top_module.c_str())); + } + + if (check_label(active, run_from, run_to, "coarse")) + { + Pass::call(design, "proc"); + Pass::call(design, "opt"); + Pass::call(design, "wreduce"); + Pass::call(design, "alumacc"); + Pass::call(design, "share"); + Pass::call(design, "opt -fast"); + Pass::call(design, "fsm"); + Pass::call(design, "opt -fast"); + Pass::call(design, "memory"); + } + + if (check_label(active, run_from, run_to, "fine")) + { + Pass::call(design, "techmap"); + Pass::call(design, "opt -fast"); + #ifdef YOSYS_ENABLE_ABC + Pass::call(design, "abc"); + #endif + Pass::call(design, "clean"); + } + + log_pop(); + } +} SynthPass; + diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index 102c021e..50f5cb58 100755 --- a/tests/tools/autotest.sh +++ b/tests/tools/autotest.sh @@ -145,8 +145,8 @@ do elif [ "$frontend" = "verific_gates" ]; then test_passes -p "verific -vlog2k $fn; verific -import -gates -all; opt; memory;;" else - test_passes -f "$frontend" -p "hierarchy; proc; opt_const; opt_share;; wreduce;; share;; opt; memory -nomap;; fsm; opt" $fn - test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt -fine; techmap; opt; abc -dff; opt" $fn + test_passes -f "$frontend" -p "hierarchy; proc; opt; memory; opt; fsm; opt -fine" $fn + test_passes -f "$frontend" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" $fn fi touch ../${bn}.log } From 2442eb38327f42e1e786f7dd9ddf1838bf2bf4b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 17:04:39 +0200 Subject: [PATCH 725/750] Fixed monitor notifications for removed cell --- kernel/rtlil.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ec4375f2..6556b82e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1148,6 +1148,9 @@ void RTLIL::Module::remove(const std::set &wires) void RTLIL::Module::remove(RTLIL::Cell *cell) { + while (!cell->connections_.empty()) + cell->unsetPort(cell->connections_.begin()->first); + log_assert(cells_.count(cell->name) != 0); log_assert(refcount_cells_ == 0); cells_.erase(cell->name); From 2cbdbaad1f81f76422455901f1987d886fa10d19 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 11:29:09 +0200 Subject: [PATCH 726/750] Fixed wreduce $shiftx handling --- passes/opt/wreduce.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 9e43bb90..58a6d1b0 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -186,7 +186,7 @@ struct WreduceWorker bool port_a_signed = false; bool port_b_signed = false; - if (max_port_a_size >= 0) + if (max_port_a_size >= 0 && cell->type != "$shiftx") run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something); if (max_port_b_size >= 0) From fcbda0741166bfbc3244f05f92e9cc5f925160e6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 12:00:19 +0200 Subject: [PATCH 727/750] Improved maccmap tree bit packing --- passes/techmap/maccmap.cc | 66 +++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc index e17231cb..2d625eef 100644 --- a/passes/techmap/maccmap.cc +++ b/passes/techmap/maccmap.cc @@ -126,14 +126,14 @@ struct MaccmapWorker int tree_bit_slots(int n) { #if 0 - int retval = 0; + int retval = 1; while (n > 2) { retval += n / 3; n = 2*(n / 3) + (n % 3); } return retval; #else - return std::max(n - 2, 0); + return std::max(n - 1, 0); #endif } @@ -142,6 +142,7 @@ struct MaccmapWorker std::vector summands; std::vector tree_sum_bits; int unique_tree_bits = 0; + int count_tree_words = 0; while (1) { @@ -160,27 +161,55 @@ struct MaccmapWorker break; summands.push_back(summand); - int free_bit_slots = tree_bit_slots(SIZE(summands)) - SIZE(tree_sum_bits); - for (int i = 0; i < width && (1 << i) <= free_bit_slots; i++) - while (!bits.at(i).empty() && (1 << i) <= free_bit_slots) { - auto it = bits.at(i).begin(); - RTLIL::SigBit bit = *it; - bits.at(i).erase(it); - for (int k = 0; k < (1 << i); k++, free_bit_slots--) - tree_sum_bits.push_back(bit); - unique_tree_bits++; - } + while (1) + { + int free_bit_slots = tree_bit_slots(SIZE(summands)) - SIZE(tree_sum_bits); + + int max_depth = 0, max_position = 0; + for (int i = 0; i < width; i++) + if (max_depth <= SIZE(bits.at(i))) { + max_depth = SIZE(bits.at(i)); + max_position = i; + } + + if (max_depth == 0 || max_position > 4) + break; + + int required_bits = 0; + for (int i = 0; i <= max_position; i++) + if (SIZE(bits.at(i)) == max_depth) + required_bits += 1 << i; + + if (required_bits > free_bit_slots) + break; + + for (int i = 0; i <= max_position; i++) + if (SIZE(bits.at(i)) == max_depth) { + auto it = bits.at(i).begin(); + RTLIL::SigBit bit = *it; + for (int k = 0; k < (1 << i); k++, free_bit_slots--) + tree_sum_bits.push_back(bit); + bits.at(i).erase(it); + unique_tree_bits++; + } + + count_tree_words++; + } } if (!tree_sum_bits.empty()) - log(" packed %d (%d) bits into adder tree\n", SIZE(tree_sum_bits), unique_tree_bits); + log(" packed %d (%d) bits / %d words into adder tree\n", SIZE(tree_sum_bits), unique_tree_bits, count_tree_words); - if (SIZE(summands) == 0) + if (SIZE(summands) == 0) { + log_assert(tree_sum_bits.empty()); return RTLIL::SigSpec(0, width); + } - if (SIZE(summands) == 1) + if (SIZE(summands) == 1) { + log_assert(tree_sum_bits.empty()); return summands.front(); + } while (SIZE(summands) > 2) { @@ -206,7 +235,6 @@ struct MaccmapWorker summands.swap(new_summands); } - log_assert(tree_sum_bits.empty()); RTLIL::Cell *c = module->addCell(NEW_ID, "$alu"); c->setPort("\\A", summands.front()); @@ -218,6 +246,12 @@ struct MaccmapWorker c->setPort("\\CO", module->addWire(NEW_ID, width)); c->fixup_parameters(); + if (!tree_sum_bits.empty()) { + c->setPort("\\CI", tree_sum_bits.back()); + tree_sum_bits.pop_back(); + } + log_assert(tree_sum_bits.empty()); + return c->getPort("\\Y"); } }; From b470c480e97fe112810d04a6051d1029ce1e8c29 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 12:22:03 +0200 Subject: [PATCH 728/750] Added the obvious optimizations to alumacc $macc generator --- kernel/macc.h | 60 +++++++++++++++++++++++++++++++++++++++ passes/techmap/alumacc.cc | 1 + 2 files changed, 61 insertions(+) diff --git a/kernel/macc.h b/kernel/macc.h index 362acab2..27114111 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -34,6 +34,66 @@ struct Macc std::vector ports; RTLIL::SigSpec bit_ports; + void optimize(int width) + { + std::vector new_ports; + RTLIL::SigSpec new_bit_ports; + RTLIL::Const off(0, width); + + for (auto &port : ports) + { + if (SIZE(port.in_a) == 0 && SIZE(port.in_b) == 0) + continue; + + if (SIZE(port.in_a) == 1 && SIZE(port.in_b) == 0 && !port.is_signed && !port.do_subtract) { + bit_ports.append(port.in_a); + continue; + } + + if (port.in_a.is_fully_const() && port.in_b.is_fully_const()) { + RTLIL::Const v = port.in_a.as_const(); + if (SIZE(port.in_b)) + v = const_mul(v, port.in_b.as_const(), port.is_signed, port.is_signed, width); + if (port.do_subtract) + off = const_sub(off, v, port.is_signed, port.is_signed, width); + else + off = const_add(off, v, port.is_signed, port.is_signed, width); + continue; + } + + if (port.is_signed) { + while (SIZE(port.in_a) > 1 && port.in_a[SIZE(port.in_a)-1] == port.in_a[SIZE(port.in_a)-2]) + port.in_a.remove(SIZE(port.in_a)-1); + while (SIZE(port.in_b) > 1 && port.in_b[SIZE(port.in_b)-1] == port.in_b[SIZE(port.in_b)-2]) + port.in_b.remove(SIZE(port.in_b)-1); + } else { + while (SIZE(port.in_a) > 1 && port.in_a[SIZE(port.in_a)-1] == RTLIL::S0) + port.in_a.remove(SIZE(port.in_a)-1); + while (SIZE(port.in_b) > 1 && port.in_b[SIZE(port.in_b)-1] == RTLIL::S0) + port.in_b.remove(SIZE(port.in_b)-1); + } + + new_ports.push_back(port); + } + + for (auto &bit : bit_ports) + if (bit == RTLIL::S1) + off = const_add(off, RTLIL::Const(1, width), false, false, width); + else if (bit != RTLIL::S0) + new_bit_ports.append(bit); + + if (off.as_bool()) { + port_t port; + port.in_a = off; + port.is_signed = false; + port.do_subtract = false; + new_ports.push_back(port); + } + + new_ports.swap(ports); + bit_ports = new_bit_ports; + } + void from_cell(RTLIL::Cell *cell) { RTLIL::SigSpec port_a = cell->getPort("\\A"); diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index 3fddcef1..c52e0e4c 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -317,6 +317,7 @@ struct AlumaccWorker log(" creating $macc cell for %s: %s\n", log_id(n->cell), log_id(cell)); + n->macc.optimize(SIZE(n->y)); n->macc.to_cell(cell); cell->setPort("\\Y", n->y); cell->fixup_parameters(); From b86410b2ab902b587cbd8f6b14c13caf684af725 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 12:42:11 +0200 Subject: [PATCH 729/750] More aggressive $macc merging in alumacc --- passes/techmap/alumacc.cc | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc index c52e0e4c..1115eead 100644 --- a/passes/techmap/alumacc.cc +++ b/passes/techmap/alumacc.cc @@ -172,6 +172,42 @@ struct AlumaccWorker } } + static bool macc_may_overflow(Macc &macc, int width, bool is_signed) + { + std::vector port_sizes; + + for (auto &port : macc.ports) { + if (port.is_signed != is_signed) + return true; + if (!port.is_signed && port.do_subtract) + return true; + if (SIZE(port.in_b)) + port_sizes.push_back(SIZE(port.in_a) + SIZE(port.in_b)); + else + port_sizes.push_back(SIZE(port.in_a)); + } + + std::sort(port_sizes.begin(), port_sizes.end()); + + int acc_sum = 0, acc_shift = 0; + for (int sz : port_sizes) { + while ((sz - acc_shift) > 20) { + if (acc_sum & 1) + acc_sum++; + acc_sum = acc_sum >> 1; + acc_shift++; + } + acc_sum += (1 << (sz - acc_shift)) - 1; + } + + while (acc_sum) { + acc_sum = acc_sum >> 1; + acc_shift++; + } + + return acc_shift > width; + } + void merge_macc() { while (1) @@ -197,7 +233,7 @@ struct AlumaccWorker if (other_n->users > 1) continue; - if (SIZE(other_n->y) != SIZE(n->y)) + if (SIZE(other_n->y) != SIZE(n->y) && macc_may_overflow(other_n->macc, SIZE(other_n->y), port.is_signed)) continue; log(" merging $macc model for %s into %s.\n", log_id(other_n->cell), log_id(n->cell)); From 6644e27cd4112070eca0958c19b71e97ba29a80d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 08:19:35 +0200 Subject: [PATCH 730/750] Fixed $macc simlib model for zero-config --- techlibs/common/simlib.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 0ad8d14b..2d8088ad 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -820,7 +820,7 @@ function integer my_clog2; end endfunction -localparam integer num_bits = CONFIG[3:0]; +localparam integer num_bits = CONFIG[3:0] > 0 ? CONFIG[3:0] : 1; localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); localparam integer num_abits = my_clog2(A_WIDTH) > 0 ? my_clog2(A_WIDTH) : 1; From fa96cf4a1694afb1ac83e9fc9b894420fc210b97 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 11:26:44 +0200 Subject: [PATCH 731/750] Added new CodingReadme file (replaces CodingStyle and CHECKLISTS) --- CHECKLISTS => CodingReadme | 108 ++++++++++++++++++++++++++++--------- CodingStyle | 43 --------------- kernel/yosys.h | 2 + 3 files changed, 86 insertions(+), 67 deletions(-) rename CHECKLISTS => CodingReadme (57%) delete mode 100644 CodingStyle diff --git a/CHECKLISTS b/CodingReadme similarity index 57% rename from CHECKLISTS rename to CodingReadme index 4a421651..8f515e1f 100644 --- a/CHECKLISTS +++ b/CodingReadme @@ -1,17 +1,93 @@ -This file contains checklists for various tasks. - -Table of contents -================= - -1. Checklist for creating Yosys releases -2. Checklist for adding internal cell types +Getting Started +=============== -1. Checklist for creating Yosys releases +Reading List +------------ + +To write Yosys C++ code you need to know at least the following classes in kernel/rtlil.h: + + RTLIL::Wire + RTLIL::Cell + RTLIL::Module + RTLIL::SigSpec + +The following yosys commands are a good starting point if you are looking for examples +of how to use the Yosys API: + + passes/opt/wreduce.cc + passes/techmap/maccmap.cc + + +Notes on the existing codebase +------------------------------ + +For historical reasons not all parts of Yosys adhere to the current coding +styles. When adding code to existing parts of the system, adhere to this guide +for the new code instead of trying to mimic the style of the surrounding code. + + + +Coding Style +============ + + +Formatting of code +------------------ + +- Yosys code is using tabs for indentation. Tabs are 8 characters. + +- A continuation of a statement in the following line is indented by + two additional tabs. + +- Lines are as long as you want them to be. A good rule of thumb is + to break lines at about column 150. + +- Opening braces can be put on the same or next line as the statement + opening the block (if, switch, for, while, do). Put the opening brace + on its own line for larger blocks, especially blocks that contains + blank lines. + +- Otherwise stick to the Linux Kernel Coding Stlye: + https://www.kernel.org/doc/Documentation/CodingStyle + + +C++ Langugage +------------- + +Yosys is written in C++11. At the moment only constructs supported by +gcc 4.6 is allowed in Yosys code. This will change in future releases. + +In general Yosys uses "int" instead of "size_t". To avoid compiler +warnings for implicit type casts, always use "SIZE(foobar)" instead +of "foobar.size()". (the macro SIZE() is defined by kernel/yosys.h) + +Use range-based for loops whenever applicable. + + + +Checklist for adding internal cell types ======================================== +Things to do right away: + + - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) + - Add to InternalCellChecker::check() in kernel/rtlil.cc + - Add to techlibs/common/simlib.v + - Add to techlibs/common/techmap.v + +Things to do after finalizing the cell interface: + + - Add support to kernel/satgen.h for the new cell type + - Add to manual/CHAPTER_CellLib.tex (or just add a fixme to the bottom) + - Maybe add support to the verilog backend for dumping such cells as expression + + + +Checklist for creating Yosys releases +===================================== Update the CHANGELOG file: @@ -116,19 +192,3 @@ In master branch: git commit --amend -am "Yosys x.y.z+" -2. Checklist for adding internal cell types -=========================================== - -Things to do right away: - - - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) - - Add to InternalCellChecker::check() in kernel/rtlil.cc - - Add to techlibs/common/simlib.v - - Add to techlibs/common/techmap.v - -Things to do after finalizing the cell interface: - - - Add support to kernel/satgen.h for the new cell type - - Add to manual/CHAPTER_CellLib.tex (or just add a fixme to the bottom) - - Maybe add support to the verilog backend for dumping such cells as expression - diff --git a/CodingStyle b/CodingStyle deleted file mode 100644 index e076cbd8..00000000 --- a/CodingStyle +++ /dev/null @@ -1,43 +0,0 @@ - - -Section 0: Notes on the existing codebase ------------------------------------------ - -Not all parts of Yosys adhere to this coding styles for historical -reasons. When adding code to existing parts of the system, adhere -to this guide for the new code instead of trying to mimic to style -of the surrounding code. - - - -Section 1: Formatting of code ------------------------------ - -- Yosys code is using tabs for indentation. Tabs are 8 characters. - -- A continuation of a statement in the following line is indented by - two additional tabs. - -- Lines are as long as you want them to be. A good rule of thumb is - to break lines at about column 150. - -- Opening braces can be put on the same or next line as the statement - opening the block (if, switch, for, while, do). Put the opening brace - on its own line for larger blocks. - -- Otherwise stick to the Linux Kernel Coding Stlye: - https://www.kernel.org/doc/Documentation/CodingStyle - - -Section 2: C++ Langugage ------------------------- - -Yosys is written in C++11. At the moment only constructs supported by -gcc 4.6 is allowed in Yosys code. This will change in future releases. - -In general Yosys uses "int" instead of "size_t". To avoid compiler -warnings for implicit type casts, always use "SIZE(foobar)" instead -of "foobar.size()". (the macro SIZE() is defined by kernel/yosys.h) - -Use range-based for loops whenever applicable. - diff --git a/kernel/yosys.h b/kernel/yosys.h index 9a4826ca..b571e177 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -32,6 +32,8 @@ // // This header is very boring. It just defines some general things that // belong nowhere else and includes the interesting headers. +// +// Find more information in the "CodingReadme" file. #ifndef YOSYS_H From ae02d9cb9a990bfbe76d056fd341d88a9a5f129c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 12:40:58 +0200 Subject: [PATCH 732/750] Fixed $memwr/$memrd order in memory_dff --- passes/memory/memory_dff.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index cdd0b85e2..302ab3ab 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -169,12 +169,14 @@ static void handle_module(RTLIL::Module *module, bool flag_wr_only) if (cell->type == "$dff") dff_cells.push_back(cell); - for (auto cell : module->selected_cells()) { + for (auto cell : module->selected_cells()) if (cell->type == "$memwr" && !cell->parameters["\\CLK_ENABLE"].as_bool()) - handle_wr_cell(module, dff_cells, cell); - if (!flag_wr_only && cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool()) + handle_wr_cell(module, dff_cells, cell); + + if (!flag_wr_only) + for (auto cell : module->selected_cells()) + if (cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool()) handle_rd_cell(module, dff_cells, cell); - } } struct MemoryDffPass : public Pass { From 9ae559b9909a5042cb60b44b020d87b3d5b60b8b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 12:45:05 +0200 Subject: [PATCH 733/750] Fixed $_NOR vs. $_NOR_ typo in abc.cc --- passes/abc/abc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index fd56668c..b18f8835 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -166,7 +166,7 @@ static void extract_cell(RTLIL::Cell *cell, bool keepff) return; } - if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR", "$_XOR_", "$_XNOR_")) + if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_")) { RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigSpec sig_b = cell->getPort("\\B"); From ba61925071ec2da067226183d18964b4b215fea5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 17 Sep 2014 07:19:34 +0200 Subject: [PATCH 734/750] Added commit count to devel version number --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7e8c7042..5a75320c 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ else LDLIBS += -lrt endif -YOSYS_VER := 0.3.0+ +YOSYS_VER := 0.3.0+$(shell test -d .git && { git log --author=clifford@clifford.at --oneline ca125bf41.. | wc -l; }) GIT_REV := $(shell git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) OBJS = kernel/version_$(GIT_REV).o From 815fab9d7136506aec0d38300e68bd88810195d3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 18 Sep 2014 12:57:37 +0200 Subject: [PATCH 735/750] Added "abc -fast" --- passes/abc/abc.cc | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index b18f8835..11818bf1 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -34,6 +34,11 @@ #define ABC_COMMAND_LUT "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; if -v" #define ABC_COMMAND_DFL "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v" +#define ABC_FAST_COMMAND_LIB "strash; scorr -v; retime -v {D}; strash; map -v {D}" +#define ABC_FAST_COMMAND_CTR "strash; scorr -v; retime -v {D}; strash; map -v {D}; buffer -v; upsize -v {D}; dnsize -v {D}; stime -p" +#define ABC_FAST_COMMAND_LUT "strash; scorr -v; retime -v; strash; if -v" +#define ABC_FAST_COMMAND_DFL "strash; scorr -v; retime -v; strash; map -v" + #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/log.h" @@ -479,7 +484,7 @@ static std::string fold_abc_cmd(std::string str) static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str, - bool keepff, std::string delay_target) + bool keepff, std::string delay_target, bool fast_mode) { module = current_module; map_autoidx = autoidx++; @@ -512,11 +517,11 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std } else abc_command = stringf("source %s", script_file.c_str()); } else if (lut_mode) - abc_command = ABC_COMMAND_LUT; + abc_command = fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; else if (!liberty_file.empty()) - abc_command = constr_file.empty() ? ABC_COMMAND_LIB : ABC_COMMAND_CTR; + abc_command = constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); else - abc_command = ABC_COMMAND_DFL; + abc_command = fast_mode ? ABC_FAST_COMMAND_DFL : ABC_COMMAND_DFL; for (size_t pos = abc_command.find("{D}"); pos != std::string::npos; pos = abc_command.find("{D}", pos)) abc_command = abc_command.substr(0, pos) + delay_target + abc_command.substr(pos+3); @@ -1041,6 +1046,22 @@ struct AbcPass : public Pass { log(" otherwise:\n"); log("%s\n", fold_abc_cmd(ABC_COMMAND_DFL).c_str()); log("\n"); + log(" -fast\n"); + log(" use different default scripts that are slightly faster (at the cost\n"); + log(" of output quality):\n"); + log("\n"); + log(" for -liberty without -constr:\n"); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_LIB).c_str()); + log("\n"); + log(" for -liberty with -constr:\n"); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_CTR).c_str()); + log("\n"); + log(" for -lut:\n"); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_LUT).c_str()); + log("\n"); + log(" otherwise:\n"); + log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_DFL).c_str()); + log("\n"); log(" -liberty \n"); log(" generate netlists for the specified cell library (using the liberty\n"); log(" file format).\n"); @@ -1097,7 +1118,7 @@ struct AbcPass : public Pass { std::string exe_file = proc_self_dirname() + "yosys-abc"; std::string script_file, liberty_file, constr_file, clk_str, delay_target; - bool dff_mode = false, keepff = false, cleanup = true; + bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; int lut_mode = 0; size_t argidx; @@ -1138,6 +1159,10 @@ struct AbcPass : public Pass { lut_mode = atoi(args[++argidx].c_str()); continue; } + if (arg == "-fast") { + fast_mode = true; + continue; + } if (arg == "-dff") { dff_mode = true; continue; @@ -1168,7 +1193,7 @@ struct AbcPass : public Pass { if (mod_it.second->processes.size() > 0) log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str()); else - abc_module(design, mod_it.second, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, dff_mode, clk_str, keepff, delay_target); + abc_module(design, mod_it.second, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, dff_mode, clk_str, keepff, delay_target, fast_mode); } assign_map.clear(); From 4888d61c651e1230c592cff7c0d8143bcc8394e1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 18 Sep 2014 12:57:55 +0200 Subject: [PATCH 736/750] Improvements in "synth" script --- techlibs/common/synth.cc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 95221afa..4ccacd30 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -66,18 +66,20 @@ struct SynthPass : public Pass { log(" wreduce\n"); log(" alumacc\n"); log(" share\n"); - log(" opt -fast\n"); + log(" opt\n"); log(" fsm\n"); log(" opt -fast\n"); - log(" memory\n"); + log(" memory -nomap\n"); + log(" opt_clean\n"); log("\n"); log(" fine:\n"); + log(" memory_map\n"); log(" techmap\n"); log(" opt -fast\n"); #ifdef YOSYS_ENABLE_ABC - log(" abc\n"); + log(" abc -fast\n"); + log(" opt_clean\n"); #endif - log(" clean\n"); log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) @@ -130,20 +132,22 @@ struct SynthPass : public Pass { Pass::call(design, "wreduce"); Pass::call(design, "alumacc"); Pass::call(design, "share"); - Pass::call(design, "opt -fast"); + Pass::call(design, "opt"); Pass::call(design, "fsm"); Pass::call(design, "opt -fast"); - Pass::call(design, "memory"); + Pass::call(design, "memory -nomap"); + Pass::call(design, "opt_clean"); } if (check_label(active, run_from, run_to, "fine")) { + Pass::call(design, "memory_map"); Pass::call(design, "techmap"); Pass::call(design, "opt -fast"); #ifdef YOSYS_ENABLE_ABC - Pass::call(design, "abc"); + Pass::call(design, "abc -fast"); + Pass::call(design, "opt_clean"); #endif - Pass::call(design, "clean"); } log_pop(); From f56b92818b05c898740df76e0a15bf94ce533e17 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 18 Sep 2014 19:00:21 +0200 Subject: [PATCH 737/750] Do not run "scorr" in "abc -fast" --- passes/abc/abc.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 11818bf1..d99eff7d 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -34,10 +34,10 @@ #define ABC_COMMAND_LUT "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; if -v" #define ABC_COMMAND_DFL "strash; scorr -v; ifraig -v; retime -v; strash; dch -vf; map -v" -#define ABC_FAST_COMMAND_LIB "strash; scorr -v; retime -v {D}; strash; map -v {D}" -#define ABC_FAST_COMMAND_CTR "strash; scorr -v; retime -v {D}; strash; map -v {D}; buffer -v; upsize -v {D}; dnsize -v {D}; stime -p" -#define ABC_FAST_COMMAND_LUT "strash; scorr -v; retime -v; strash; if -v" -#define ABC_FAST_COMMAND_DFL "strash; scorr -v; retime -v; strash; map -v" +#define ABC_FAST_COMMAND_LIB "retime -v {D}; map -v {D}" +#define ABC_FAST_COMMAND_CTR "retime -v {D}; map -v {D}; buffer -v; upsize -v {D}; dnsize -v {D}; stime -p" +#define ABC_FAST_COMMAND_LUT "retime -v; if -v" +#define ABC_FAST_COMMAND_DFL "retime -v; map -v" #include "kernel/register.h" #include "kernel/sigtools.h" From f7bb8f244beff135aa2ef6c771bece45ce240c5d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 11:13:10 +0200 Subject: [PATCH 738/750] Alphabetically sort port names in "show" output --- passes/cmds/show.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 0451ebc2..2218eded 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -355,6 +355,9 @@ struct ShowWorker out_ports.push_back(conn.first); } + std::sort(in_ports.begin(), in_ports.end(), RTLIL::sort_by_id_str()); + std::sort(out_ports.begin(), out_ports.end(), RTLIL::sort_by_id_str()); + std::string label_string = "{{"; for (auto &p : in_ports) From 3aa003c8e9c207758797e533cb85514cdb0db2c6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 13:15:31 +0200 Subject: [PATCH 739/750] Using "NOT" instead of "INV" as cell name in default abc genlib file --- passes/abc/abc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index d99eff7d..75368e3c 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -712,7 +712,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std fprintf(f, "GATE ZERO 1 Y=CONST0;\n"); fprintf(f, "GATE ONE 1 Y=CONST1;\n"); fprintf(f, "GATE BUF 1 Y=A; PIN * NONINV 1 999 1 0 1 0\n"); - fprintf(f, "GATE INV 1 Y=!A; PIN * INV 1 999 1 0 1 0\n"); + fprintf(f, "GATE NOT 1 Y=!A; PIN * INV 1 999 1 0 1 0\n"); fprintf(f, "GATE AND 1 Y=A*B; PIN * NONINV 1 999 1 0 1 0\n"); fprintf(f, "GATE NAND 1 Y=!(A*B); PIN * INV 1 999 1 0 1 0\n"); fprintf(f, "GATE OR 1 Y=A+B; PIN * NONINV 1 999 1 0 1 0\n"); @@ -854,7 +854,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std module->connect(conn); continue; } - if (c->type == "\\INV") { + if (c->type == "\\NOT") { RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_NOT_"); cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); From 5827826098fd827c7ac964ed45e99f92d63d9267 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 14:05:41 +0200 Subject: [PATCH 740/750] Small improvements in "abc" command handle_loops() function --- passes/abc/abc.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 75368e3c..f1d56b23 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -287,8 +287,9 @@ static void dump_loop_graph(FILE *f, int &nr, std::map> &edge log("Dumping loop state graph to slide %d.\n", ++nr); - fprintf(f, "digraph slide%d {\n", nr); - fprintf(f, " rankdir=\"LR\";\n"); + fprintf(f, "digraph \"slide%d\" {\n", nr); + fprintf(f, " label=\"slide%d\";\n", nr); + fprintf(f, " rankdir=\"TD\";\n"); std::set nodes; for (auto &e : edges) { @@ -375,10 +376,10 @@ static void handle_loops() int id2 = edge_it.first; RTLIL::Wire *w1 = signal_list[id1].bit.wire; RTLIL::Wire *w2 = signal_list[id2].bit.wire; - if (w1 != NULL) - continue; - else if (w2 == NULL) + if (w1 == NULL) id1 = id2; + else if (w2 == NULL) + continue; else if (w1->name[0] == '$' && w2->name[0] == '\\') id1 = id2; else if (w1->name[0] == '\\' && w2->name[0] == '$') @@ -387,7 +388,7 @@ static void handle_loops() id1 = id2; else if (edges[id1].size() > edges[id2].size()) continue; - else if (w2->name < w1->name) + else if (w2->name.str() < w1->name.str()) id1 = id2; } @@ -396,6 +397,8 @@ static void handle_loops() continue; } + log_assert(signal_list[id1].bit.wire != NULL); + std::stringstream sstr; sstr << "$abcloop$" << (autoidx++); RTLIL::Wire *wire = module->addWire(sstr.str()); From 309623ff177f2538a4c529dbc025374008d85880 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 15:50:34 +0200 Subject: [PATCH 741/750] Sorting of object names in ilang backend --- backends/ilang/ilang_backend.cc | 66 +++++++++++++++++++++++---------- backends/ilang/ilang_backend.h | 4 +- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index 13d3a8e4..48d818d7 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -111,7 +111,9 @@ void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, boo void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire) { - for (auto it = wire->attributes.begin(); it != wire->attributes.end(); it++) { + std::map sorted_attributes(wire->attributes.begin(), wire->attributes.end()); + + for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) { f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); f << stringf("\n"); @@ -134,7 +136,9 @@ void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL:: void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory) { - for (auto it = memory->attributes.begin(); it != memory->attributes.end(); it++) { + std::map sorted_attributes(memory->attributes.begin(), memory->attributes.end()); + + for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) { f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); f << stringf("\n"); @@ -149,18 +153,22 @@ void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell) { - for (auto it = cell->attributes.begin(); it != cell->attributes.end(); it++) { + std::map sorted_attributes(cell->attributes.begin(), cell->attributes.end()); + std::map sorted_parameters(cell->parameters.begin(), cell->parameters.end()); + std::map sorted_connections(cell->connections().begin(), cell->connections().end()); + + for (auto it = sorted_attributes.begin(); it != sorted_attributes.end(); it++) { f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str()); dump_const(f, it->second); f << stringf("\n"); } f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str()); - for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) { + for (auto it = sorted_parameters.begin(); it != sorted_parameters.end(); it++) { f << stringf("%s parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str()); dump_const(f, it->second); f << stringf("\n"); } - for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) { + for (auto it = sorted_connections.begin(); it != sorted_connections.end(); it++) { f << stringf("%s connect %s ", indent.c_str(), it->first.c_str()); dump_sigspec(f, it->second); f << stringf("\n"); @@ -259,7 +267,7 @@ void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL:: f << stringf("\n"); } -void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { bool print_header = flag_m || design->selected_whole_module(module->name); bool print_body = !flag_n || !design->selected_whole_module(module->name); @@ -277,32 +285,52 @@ void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, const RTLIL if (print_body) { - for (auto it = module->wires_.begin(); it != module->wires_.end(); it++) - if (!only_selected || design->selected(module, it->second)) { + std::vector sorted_wires; + for (auto it : module->wires()) + sorted_wires.push_back(it); + std::sort(sorted_wires.begin(), sorted_wires.end(), RTLIL::sort_by_name_str()); + + std::vector sorted_memories; + for (auto it : module->memories) + sorted_memories.push_back(it.second); + std::sort(sorted_memories.begin(), sorted_memories.end(), RTLIL::sort_by_name_str()); + + std::vector sorted_cells; + for (auto it : module->cells()) + sorted_cells.push_back(it); + std::sort(sorted_cells.begin(), sorted_cells.end(), RTLIL::sort_by_name_str()); + + std::vector sorted_processes; + for (auto it : module->processes) + sorted_processes.push_back(it.second); + std::sort(sorted_processes.begin(), sorted_processes.end(), RTLIL::sort_by_name_str()); + + for (auto it : sorted_wires) + if (!only_selected || design->selected(module, it)) { if (only_selected) f << stringf("\n"); - dump_wire(f, indent + " ", it->second); + dump_wire(f, indent + " ", it); } - for (auto it = module->memories.begin(); it != module->memories.end(); it++) - if (!only_selected || design->selected(module, it->second)) { + for (auto it : sorted_memories) + if (!only_selected || design->selected(module, it)) { if (only_selected) f << stringf("\n"); - dump_memory(f, indent + " ", it->second); + dump_memory(f, indent + " ", it); } - for (auto it = module->cells_.begin(); it != module->cells_.end(); it++) - if (!only_selected || design->selected(module, it->second)) { + for (auto it : sorted_cells) + if (!only_selected || design->selected(module, it)) { if (only_selected) f << stringf("\n"); - dump_cell(f, indent + " ", it->second); + dump_cell(f, indent + " ", it); } - for (auto it = module->processes.begin(); it != module->processes.end(); it++) - if (!only_selected || design->selected(module, it->second)) { + for (auto it : sorted_processes) + if (!only_selected || design->selected(module, it)) { if (only_selected) f << stringf("\n"); - dump_proc(f, indent + " ", it->second); + dump_proc(f, indent + " ", it); } bool first_conn_line = true; @@ -330,7 +358,7 @@ void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, const RTLIL f << stringf("%s" "end\n", indent.c_str()); } -void ILANG_BACKEND::dump_design(std::ostream &f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { int init_autoidx = autoidx; diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h index 138e10ef..159cd719 100644 --- a/backends/ilang/ilang_backend.h +++ b/backends/ilang/ilang_backend.h @@ -42,8 +42,8 @@ namespace ILANG_BACKEND { void dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy); void dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc); void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right); - void dump_module(std::ostream &f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); - void dump_design(std::ostream &f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); + void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); + void dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); } YOSYS_NAMESPACE_END From 00964f2f618d241a2e5cd32f4e7dbbcf55de4fb4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 15:50:55 +0200 Subject: [PATCH 742/750] Initialize RTLIL::Const from std::vector --- kernel/rtlil.cc | 7 +++++++ kernel/rtlil.h | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 6556b82e..00be796f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -65,6 +65,13 @@ RTLIL::Const::Const(RTLIL::State bit, int width) bits.push_back(bit); } +RTLIL::Const::Const(const std::vector &bits) +{ + flags = RTLIL::CONST_FLAG_NONE; + for (auto b : bits) + this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0); +} + bool RTLIL::Const::operator <(const RTLIL::Const &other) const { if (bits.size() != other.bits.size()) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c4883769..a0ae8f08 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -428,7 +428,8 @@ struct RTLIL::Const Const(std::string str); Const(int val, int width = 32); Const(RTLIL::State bit, int width = 1); - Const(std::vector bits) : bits(bits) { flags = CONST_FLAG_NONE; }; + Const(const std::vector &bits) : bits(bits) { flags = CONST_FLAG_NONE; }; + Const(const std::vector &bits); bool operator <(const RTLIL::Const &other) const; bool operator ==(const RTLIL::Const &other) const; From a7758ef953eccff9295ec9f152ec1b6bef831f89 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 15:51:34 +0200 Subject: [PATCH 743/750] Added "test_abcloop" command --- passes/tests/Makefile.inc | 1 + passes/tests/test_abcloop.cc | 285 +++++++++++++++++++++++++++++++++++ 2 files changed, 286 insertions(+) create mode 100644 passes/tests/test_abcloop.cc diff --git a/passes/tests/Makefile.inc b/passes/tests/Makefile.inc index a60cfe66..531943d7 100644 --- a/passes/tests/Makefile.inc +++ b/passes/tests/Makefile.inc @@ -1,4 +1,5 @@ OBJS += passes/tests/test_autotb.o OBJS += passes/tests/test_cell.o +OBJS += passes/tests/test_abcloop.o diff --git a/passes/tests/test_abcloop.cc b/passes/tests/test_abcloop.cc new file mode 100644 index 00000000..0a0ceb1d --- /dev/null +++ b/passes/tests/test_abcloop.cc @@ -0,0 +1,285 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2014 Clifford Wolf + * Copyright (C) 2014 Johann Glaser + * + * 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/yosys.h" +#include "kernel/satgen.h" + +static uint32_t xorshift32_state = 123456789; + +static uint32_t xorshift32(uint32_t limit) { + xorshift32_state ^= xorshift32_state << 13; + xorshift32_state ^= xorshift32_state >> 17; + xorshift32_state ^= xorshift32_state << 5; + return xorshift32_state % limit; +} + +static RTLIL::Wire *getw(std::vector &wires, RTLIL::Wire *w) +{ + while (1) { + int idx = xorshift32(SIZE(wires)); + if (wires[idx] != w && !wires[idx]->port_output) + return wires[idx]; + } +} + +static void test_abcloop() +{ + log("Rng seed value: %u\n", int(xorshift32_state)); + + RTLIL::Design *design = new RTLIL::Design; + RTLIL::Module *module = nullptr; + RTLIL::SigSpec in_sig, out_sig; + + bool truthtab[16][4]; + int create_cycles = 0; + + while (1) + { + module = design->addModule("\\uut"); + create_cycles++; + + in_sig = {}; + out_sig = {}; + + std::vector wires; + + for (int i = 0; i < 4; i++) { + RTLIL::Wire *w = module->addWire(stringf("\\i%d", i)); + w->port_input = true; + wires.push_back(w); + in_sig.append(w); + } + + for (int i = 0; i < 4; i++) { + RTLIL::Wire *w = module->addWire(stringf("\\o%d", i)); + w->port_output = true; + wires.push_back(w); + out_sig.append(w); + } + + for (int i = 0; i < 16; i++) { + RTLIL::Wire *w = module->addWire(stringf("\\t%d", i)); + wires.push_back(w); + } + + for (auto w : wires) + if (!w->port_input) + switch (xorshift32(12)) + { + case 0: + module->addNotGate(w->name.str() + "g", getw(wires, w), w); + break; + case 1: + module->addAndGate(w->name.str() + "g", getw(wires, w), getw(wires, w), w); + break; + case 2: + module->addNandGate(w->name.str() + "g", getw(wires, w), getw(wires, w), w); + break; + case 3: + module->addOrGate(w->name.str() + "g", getw(wires, w), getw(wires, w), w); + break; + case 4: + module->addNorGate(w->name.str() + "g", getw(wires, w), getw(wires, w), w); + break; + case 5: + module->addXorGate(w->name.str() + "g", getw(wires, w), getw(wires, w), w); + break; + case 6: + module->addXnorGate(w->name.str() + "g", getw(wires, w), getw(wires, w), w); + break; + case 7: + module->addMuxGate(w->name.str() + "g", getw(wires, w), getw(wires, w), getw(wires, w), w); + break; + case 8: + module->addAoi3Gate(w->name.str() + "g", getw(wires, w), getw(wires, w), getw(wires, w), w); + break; + case 9: + module->addOai3Gate(w->name.str() + "g", getw(wires, w), getw(wires, w), getw(wires, w), w); + break; + case 10: + module->addAoi4Gate(w->name.str() + "g", getw(wires, w), getw(wires, w), getw(wires, w), getw(wires, w), w); + break; + case 11: + module->addOai4Gate(w->name.str() + "g", getw(wires, w), getw(wires, w), getw(wires, w), getw(wires, w), w); + break; + } + + module->fixup_ports(); + Pass::call(design, "clean"); + + ezDefaultSAT ez; + SigMap sigmap(module); + SatGen satgen(&ez, &sigmap); + + for (auto c : module->cells()) { + bool ok = satgen.importCell(c); + log_assert(ok); + } + + std::vector in_vec = satgen.importSigSpec(in_sig); + std::vector inverse_in_vec = ez.vec_not(in_vec); + + std::vector out_vec = satgen.importSigSpec(out_sig); + + for (int i = 0; i < 16; i++) + { + std::vector assumptions; + for (int j = 0; j < SIZE(in_vec); j++) + assumptions.push_back((i & (1 << j)) ? in_vec.at(j) : inverse_in_vec.at(j)); + + std::vector results; + if (!ez.solve(out_vec, results, assumptions)) { + log("No stable solution for input %d found -> recreate module.\n", i); + goto recreate_module; + } + + for (int j = 0; j < 4; j++) + truthtab[i][j] = results[j]; + + assumptions.push_back(ez.vec_ne(out_vec, ez.vec_const(results))); + + std::vector results2; + if (ez.solve(out_vec, results2, assumptions)) { + log("Two stable solutions for input %d found -> recreate module.\n", i); + goto recreate_module; + } + } + break; + + recreate_module: + design->remove(module); + } + + log("Found viable UUT after %d cycles:\n", create_cycles); + Pass::call(design, "write_ilang"); + Pass::call(design, "abc"); + + log("\n"); + log("Pre- and post-abc truth table:\n"); + + ezDefaultSAT ez; + SigMap sigmap(module); + SatGen satgen(&ez, &sigmap); + + for (auto c : module->cells()) { + bool ok = satgen.importCell(c); + log_assert(ok); + } + + std::vector in_vec = satgen.importSigSpec(in_sig); + std::vector inverse_in_vec = ez.vec_not(in_vec); + + std::vector out_vec = satgen.importSigSpec(out_sig); + + bool found_error = false; + bool truthtab2[16][4]; + + for (int i = 0; i < 16; i++) + { + std::vector assumptions; + for (int j = 0; j < SIZE(in_vec); j++) + assumptions.push_back((i & (1 << j)) ? in_vec.at(j) : inverse_in_vec.at(j)); + + for (int j = 0; j < 4; j++) + truthtab2[i][j] = truthtab[i][j]; + + std::vector results; + if (!ez.solve(out_vec, results, assumptions)) { + log("No stable solution for input %d found.\n", i); + found_error = true; + continue; + } + + for (int j = 0; j < 4; j++) + truthtab2[i][j] = results[j]; + + assumptions.push_back(ez.vec_ne(out_vec, ez.vec_const(results))); + + std::vector results2; + if (ez.solve(out_vec, results2, assumptions)) { + log("Two stable solutions for input %d found -> recreate module.\n", i); + found_error = true; + } + } + + for (int i = 0; i < 16; i++) { + log("%3d ", i); + for (int j = 0; j < 4; j++) + log("%c", truthtab[i][j] ? '1' : '0'); + log(" "); + for (int j = 0; j < 4; j++) + log("%c", truthtab2[i][j] ? '1' : '0'); + for (int j = 0; j < 4; j++) + if (truthtab[i][j] != truthtab2[i][j]) { + found_error = true; + log(" !"); + break; + } + log("\n"); + } + + log_assert(found_error == false); + log("\n"); +} + +struct TestAbcloopPass : public Pass { + TestAbcloopPass() : Pass("test_abcloop", "automatically test handling of loops in abc command") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" test_abcloop [options]\n"); + log("\n"); + log("Test handling of logic loops in ABC.\n"); + log("\n"); + log(" -n {integer}\n"); + log(" create this number of circuits and test them (default = 100).\n"); + log("\n"); + log(" -s {positive_integer}\n"); + log(" use this value as rng seed value (default = unix time).\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design*) + { + int num_iter = 100; + xorshift32_state = 0; + + int argidx; + for (argidx = 1; argidx < SIZE(args); argidx++) + { + if (args[argidx] == "-n" && argidx+1 < SIZE(args)) { + num_iter = atoi(args[++argidx].c_str()); + continue; + } + if (args[argidx] == "-s" && argidx+1 < SIZE(args)) { + xorshift32_state = atoi(args[++argidx].c_str()); + continue; + } + break; + } + + if (xorshift32_state == 0) + xorshift32_state = time(NULL) & 0x7fffffff; + + for (int i = 0; i < num_iter; i++) + test_abcloop(); + } +} TestAbcloopPass; + From edf11c635a40c2cfb291089be509b2f31737958b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 12:57:33 +0200 Subject: [PATCH 744/750] Assert on new logic loops in "share" pass --- kernel/utils.h | 2 +- passes/opt/share.cc | 48 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/kernel/utils.h b/kernel/utils.h index 7f10619b..a03caf80 100644 --- a/kernel/utils.h +++ b/kernel/utils.h @@ -155,7 +155,7 @@ struct TopoSort void sort_worker(const T &n, std::set &marked_cells, std::set &active_cells, std::vector &active_stack) { if (active_cells.count(n)) { - found_loops = false; + found_loops = true; if (analyze_loops) { std::set loop; for (int i = SIZE(active_stack)-1; i >= 0; i--) { diff --git a/passes/opt/share.cc b/passes/opt/share.cc index c372ed78..02e84584 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -21,6 +21,7 @@ #include "kernel/satgen.h" #include "kernel/sigtools.h" #include "kernel/modtools.h" +#include "kernel/utils.h" PRIVATE_NAMESPACE_BEGIN @@ -640,6 +641,48 @@ struct ShareWorker } + // ------------------------------------------------------------------------------------------------ + // Find SCCs (logic loops). This is only used to make sure that this pass does not introduce loops. + // ------------------------------------------------------------------------------------------------ + + bool module_has_scc() + { + SigMap sigmap(module); + + CellTypes ct; + ct.setup_internals(); + ct.setup_stdcells(); + + TopoSort toposort; + toposort.analyze_loops = false; + + std::map> cell_to_bits; + std::map> bit_to_cells; + + for (auto cell : module->cells()) + if (ct.cell_known(cell->type)) + for (auto &conn : cell->connections()) { + if (ct.cell_output(cell->type, conn.first)) + for (auto bit : sigmap(conn.second)) + cell_to_bits[cell].insert(bit); + else + for (auto bit : sigmap(conn.second)) + bit_to_cells[bit].insert(cell); + } + + for (auto &it : cell_to_bits) + { + RTLIL::Cell *c1 = it.first; + + for (auto bit : it.second) + for (auto c2 : bit_to_cells[bit]) + toposort.edge(c1, c2); + } + + return !toposort.sort(); + } + + // ------------- // Setup and run // ------------- @@ -647,6 +690,8 @@ struct ShareWorker ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : config(config), design(design), module(module) { + bool before_scc = module_has_scc(); + generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end()); generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end()); generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end()); @@ -879,6 +924,9 @@ struct ShareWorker } log_assert(recursion_state.empty()); + + bool after_scc = before_scc || module_has_scc(); + log_assert(before_scc == after_scc); } }; From 8d60754aefbded7b5742ceae2b34fb6b4dcda93d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 13:52:39 +0200 Subject: [PATCH 745/750] Do not introduce new logic loops in "share" --- passes/opt/share.cc | 53 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 02e84584..af2966bc 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -47,6 +47,8 @@ struct ShareWorker std::set cells_to_remove; std::set recursion_state; + std::map> to_drivers_edges; + // ------------------------------------------------------------------------------ // Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree @@ -641,11 +643,11 @@ struct ShareWorker } - // ------------------------------------------------------------------------------------------------ - // Find SCCs (logic loops). This is only used to make sure that this pass does not introduce loops. - // ------------------------------------------------------------------------------------------------ + // ------------------------------------------------------------------------------------- + // Helper functions used to make sure that this pass does not introduce new logic loops. + // ------------------------------------------------------------------------------------- - bool module_has_scc() + bool module_has_scc(std::map> *edges = NULL) { SigMap sigmap(module); @@ -679,7 +681,32 @@ struct ShareWorker toposort.edge(c1, c2); } - return !toposort.sort(); + bool found_scc = !toposort.sort(); + if (edges) + *edges = std::move(toposort.database); + return found_scc; + } + + bool find_in_input_cone_worker(RTLIL::Cell *root, RTLIL::Cell *needle, std::set &stop) + { + if (root == needle) + return true; + + if (stop.count(root)) + return false; + + stop.insert(root); + + for (auto c : to_drivers_edges[root]) + if (find_in_input_cone_worker(c, needle, stop)) + return true; + return false; + } + + bool find_in_input_cone(RTLIL::Cell *root, RTLIL::Cell *needle) + { + std::set stop; + return find_in_input_cone_worker(root, needle, stop); } @@ -690,7 +717,7 @@ struct ShareWorker ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : config(config), design(design), module(module) { - bool before_scc = module_has_scc(); + bool before_scc = module_has_scc(&to_drivers_edges); generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end()); generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end()); @@ -878,6 +905,17 @@ struct ShareWorker } log(" According to the SAT solver this pair of cells can be shared.\n"); + + if (find_in_input_cone(cell, other_cell)) { + log(" Sharing not possible: %s is in input cone of %s.\n", log_id(other_cell), log_id(cell)); + continue; + } + + if (find_in_input_cone(other_cell, cell)) { + log(" Sharing not possible: %s is in input cone of %s.\n", log_id(cell), log_id(other_cell)); + continue; + } + shareable_cells.erase(other_cell); int cell_select_score = 0; @@ -911,6 +949,9 @@ struct ShareWorker cells_to_remove.insert(cell); cells_to_remove.insert(other_cell); + + to_drivers_edges[cell].insert(to_drivers_edges[other_cell].begin(), to_drivers_edges[other_cell].end()); + to_drivers_edges[other_cell] = to_drivers_edges[cell]; break; } } From a6c08b40fe281a69e1e6cb369b73c55ab6192f45 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 14:51:07 +0200 Subject: [PATCH 746/750] Still loop bug in "share": changed assert to warning --- passes/opt/share.cc | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index af2966bc..cdda2934 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -47,7 +47,9 @@ struct ShareWorker std::set cells_to_remove; std::set recursion_state; - std::map> to_drivers_edges; + SigMap topo_sigmap; + std::map> topo_cell_drivers; + std::map> topo_bit_drivers; // ------------------------------------------------------------------------------ @@ -647,10 +649,8 @@ struct ShareWorker // Helper functions used to make sure that this pass does not introduce new logic loops. // ------------------------------------------------------------------------------------- - bool module_has_scc(std::map> *edges = NULL) + bool module_has_scc() { - SigMap sigmap(module); - CellTypes ct; ct.setup_internals(); ct.setup_stdcells(); @@ -658,6 +658,9 @@ struct ShareWorker TopoSort toposort; toposort.analyze_loops = false; + topo_sigmap.set(module); + topo_bit_drivers.clear(); + std::map> cell_to_bits; std::map> bit_to_cells; @@ -665,10 +668,12 @@ struct ShareWorker if (ct.cell_known(cell->type)) for (auto &conn : cell->connections()) { if (ct.cell_output(cell->type, conn.first)) - for (auto bit : sigmap(conn.second)) + for (auto bit : topo_sigmap(conn.second)) { cell_to_bits[cell].insert(bit); + topo_bit_drivers[bit].insert(cell); + } else - for (auto bit : sigmap(conn.second)) + for (auto bit : topo_sigmap(conn.second)) bit_to_cells[bit].insert(cell); } @@ -682,8 +687,8 @@ struct ShareWorker } bool found_scc = !toposort.sort(); - if (edges) - *edges = std::move(toposort.database); + topo_cell_drivers = std::move(toposort.database); + return found_scc; } @@ -697,7 +702,7 @@ struct ShareWorker stop.insert(root); - for (auto c : to_drivers_edges[root]) + for (auto c : topo_cell_drivers[root]) if (find_in_input_cone_worker(c, needle, stop)) return true; return false; @@ -717,7 +722,7 @@ struct ShareWorker ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : config(config), design(design), module(module) { - bool before_scc = module_has_scc(&to_drivers_edges); + bool before_scc = module_has_scc(); generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end()); generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end()); @@ -950,8 +955,12 @@ struct ShareWorker cells_to_remove.insert(cell); cells_to_remove.insert(other_cell); - to_drivers_edges[cell].insert(to_drivers_edges[other_cell].begin(), to_drivers_edges[other_cell].end()); - to_drivers_edges[other_cell] = to_drivers_edges[cell]; + for (auto bit : topo_sigmap(all_ctrl_signals)) + for (auto c : topo_bit_drivers[bit]) + topo_cell_drivers[cell].insert(c); + + topo_cell_drivers[cell].insert(topo_cell_drivers[other_cell].begin(), topo_cell_drivers[other_cell].end()); + topo_cell_drivers[other_cell] = topo_cell_drivers[cell]; break; } } @@ -967,7 +976,10 @@ struct ShareWorker log_assert(recursion_state.empty()); bool after_scc = before_scc || module_has_scc(); - log_assert(before_scc == after_scc); + if (before_scc != after_scc) + log("Warning: introduced topological logic loops!\n"); + // Pass::call_on_module(design, module, "scc;; show"); + // log_assert(before_scc == after_scc); } }; From b28be0759f46326d4d2a7ac74f1d1f79477435da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 15:13:06 +0200 Subject: [PATCH 747/750] Added "share -limit" --- passes/opt/share.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index cdda2934..5ed9af00 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -27,6 +27,7 @@ PRIVATE_NAMESPACE_BEGIN struct ShareWorkerConfig { + int limit; bool opt_force; bool opt_aggressive; bool opt_fast; @@ -751,7 +752,7 @@ struct ShareWorker log("Found %d cells in module %s that may be considered for resource sharing.\n", SIZE(shareable_cells), log_id(module)); - while (!shareable_cells.empty()) + while (!shareable_cells.empty() && config.limit != 0) { RTLIL::Cell *cell = *shareable_cells.begin(); shareable_cells.erase(cell); @@ -959,6 +960,9 @@ struct ShareWorker for (auto c : topo_bit_drivers[bit]) topo_cell_drivers[cell].insert(c); + if (config.limit > 0) + config.limit--; + topo_cell_drivers[cell].insert(topo_cell_drivers[other_cell].begin(), topo_cell_drivers[other_cell].end()); topo_cell_drivers[other_cell] = topo_cell_drivers[cell]; break; @@ -1013,11 +1017,15 @@ struct SharePass : public Pass { log(" in much easier SAT problems at the cost of maybe missing some oportunities\n"); log(" for resource sharing.\n"); log("\n"); + log(" -limit N\n"); + log(" Only perform the first N merges, then stop. This is useful for debugging.\n"); + log("\n"); } virtual void execute(std::vector args, RTLIL::Design *design) { ShareWorkerConfig config; + config.limit = -1; config.opt_force = false; config.opt_aggressive = false; config.opt_fast = false; @@ -1073,6 +1081,10 @@ struct SharePass : public Pass { config.opt_fast = true; continue; } + if (args[argidx] == "-limit" && argidx+1 < args.size()) { + config.limit = atoi(args[++argidx].c_str()); + continue; + } break; } extra_args(args, argidx, design); From d6e2ace95be79274f8707a897e3ac265ab85b11a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 15:13:44 +0200 Subject: [PATCH 748/750] Logic loop bugfix for "share" pass --- passes/opt/share.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 5ed9af00..b91a67ee 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -958,13 +958,17 @@ struct ShareWorker for (auto bit : topo_sigmap(all_ctrl_signals)) for (auto c : topo_bit_drivers[bit]) - topo_cell_drivers[cell].insert(c); + topo_cell_drivers[supercell].insert(c); + + topo_cell_drivers[supercell].insert(topo_cell_drivers[cell].begin(), topo_cell_drivers[cell].end()); + topo_cell_drivers[supercell].insert(topo_cell_drivers[other_cell].begin(), topo_cell_drivers[other_cell].end()); + + topo_cell_drivers[cell] = { supercell }; + topo_cell_drivers[other_cell] = { supercell }; if (config.limit > 0) config.limit--; - topo_cell_drivers[cell].insert(topo_cell_drivers[other_cell].begin(), topo_cell_drivers[other_cell].end()); - topo_cell_drivers[other_cell] = topo_cell_drivers[cell]; break; } } From 96e821dc6cf170168218fa4cddc7c9ddafd6f439 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 19:36:56 +0200 Subject: [PATCH 749/750] Various improvements regarding logic loops in "share" results --- passes/opt/share.cc | 145 +++++++++++++++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 37 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index b91a67ee..e3b0159c 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -44,6 +44,7 @@ struct ShareWorker CellTypes fwd_ct, cone_ct; ModWalker modwalker; + ModIndex mi; std::set cells_to_remove; std::set recursion_state; @@ -102,7 +103,7 @@ struct ShareWorker // Find shareable cells and compatible groups of cells // --------------------------------------------------- - std::set shareable_cells; + std::set> shareable_cells; void find_shareable_cells() { @@ -252,7 +253,7 @@ struct ShareWorker // Create replacement cell // ----------------------- - RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act) + RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act, std::set &supercell_aux) { log_assert(c1->type == c2->type); @@ -283,10 +284,12 @@ struct ShareWorker int a_width = std::max(a1.size(), a2.size()); int y_width = std::max(y1.size(), y2.size()); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); + a1.extend_u0(a_width, a_signed); + a2.extend_u0(a_width, a_signed); + + RTLIL::SigSpec a = module->addWire(NEW_ID, a_width); + supercell_aux.insert(module->addMux(NEW_ID, a2, a1, act, a)); - RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); @@ -296,12 +299,10 @@ struct ShareWorker supercell->setPort("\\A", a); supercell->setPort("\\Y", y); - RTLIL::SigSpec new_y1(y, 0, y1.size()); - RTLIL::SigSpec new_y2(y, 0, y2.size()); - - module->connect(RTLIL::SigSig(y1, new_y1)); - module->connect(RTLIL::SigSig(y2, new_y2)); + supercell_aux.insert(module->addPos(NEW_ID, y, y1)); + supercell_aux.insert(module->addPos(NEW_ID, y, y2)); + supercell_aux.insert(supercell); return supercell; } @@ -386,23 +387,27 @@ struct ShareWorker { a_width = std::max(y_width, a_width); - if (a1.size() < y1.size()) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, y1.size()), true)->getPort("\\Y"); - if (a2.size() < y2.size()) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, y2.size()), true)->getPort("\\Y"); + if (a1.size() < y1.size()) a1.extend_u0(y1.size(), true); + if (a2.size() < y2.size()) a2.extend_u0(y2.size(), true); - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), false)->getPort("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), false)->getPort("\\Y"); + a1.extend_u0(a_width, false); + a2.extend_u0(a_width, false); } else { - if (a1.size() != a_width) a1 = module->addPos(NEW_ID, a1, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); - if (a2.size() != a_width) a2 = module->addPos(NEW_ID, a2, module->addWire(NEW_ID, a_width), a_signed)->getPort("\\Y"); + a1.extend_u0(a_width, a_signed); + a2.extend_u0(a_width, a_signed); } - if (b1.size() != b_width) b1 = module->addPos(NEW_ID, b1, module->addWire(NEW_ID, b_width), b_signed)->getPort("\\Y"); - if (b2.size() != b_width) b2 = module->addPos(NEW_ID, b2, module->addWire(NEW_ID, b_width), b_signed)->getPort("\\Y"); + b1.extend_u0(b_width, b_signed); + b2.extend_u0(b_width, b_signed); + + RTLIL::SigSpec a = module->addWire(NEW_ID, a_width); + RTLIL::SigSpec b = module->addWire(NEW_ID, b_width); + + supercell_aux.insert(module->addMux(NEW_ID, a2, a1, act, a)); + supercell_aux.insert(module->addMux(NEW_ID, b2, b1, act, b)); - RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); - RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); RTLIL::Wire *y = module->addWire(NEW_ID, y_width); RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); @@ -416,19 +421,18 @@ struct ShareWorker supercell->setPort("\\Y", y); supercell->check(); - RTLIL::SigSpec new_y1(y, 0, y1.size()); - RTLIL::SigSpec new_y2(y, 0, y2.size()); - - module->connect(RTLIL::SigSig(y1, new_y1)); - module->connect(RTLIL::SigSig(y2, new_y2)); + supercell_aux.insert(module->addPos(NEW_ID, y, y1)); + supercell_aux.insert(module->addPos(NEW_ID, y, y2)); + supercell_aux.insert(supercell); return supercell; } if (c1->type == "$memrd") { RTLIL::Cell *supercell = module->addCell(NEW_ID, c1); - module->connect(c2->getPort("\\DATA"), supercell->getPort("\\DATA")); + supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort("\\DATA"), c2->getPort("\\DATA"))); + supercell_aux.insert(supercell); return supercell; } @@ -633,16 +637,21 @@ struct ShareWorker } } - RTLIL::SigSpec make_cell_activation_logic(const std::set> &activation_patterns) + RTLIL::SigSpec make_cell_activation_logic(const std::set> &activation_patterns, std::set &supercell_aux) { RTLIL::Wire *all_cases_wire = module->addWire(NEW_ID, 0); + for (auto &p : activation_patterns) { all_cases_wire->width++; - module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec(all_cases_wire, all_cases_wire->width - 1)); + supercell_aux.insert(module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec(all_cases_wire, all_cases_wire->width - 1))); } + if (all_cases_wire->width == 1) return all_cases_wire; - return module->ReduceOr(NEW_ID, all_cases_wire); + + RTLIL::Wire *result_wire = module->addWire(NEW_ID); + supercell_aux.insert(module->addReduceOr(NEW_ID, all_cases_wire, result_wire)); + return result_wire; } @@ -690,6 +699,13 @@ struct ShareWorker bool found_scc = !toposort.sort(); topo_cell_drivers = std::move(toposort.database); + if (found_scc && toposort.analyze_loops) + for (auto &loop : toposort.loops) { + log("### loop ###\n"); + for (auto &c : loop) + log("%s (%s)\n", log_id(c), log_id(c->type)); + } + return found_scc; } @@ -715,13 +731,52 @@ struct ShareWorker return find_in_input_cone_worker(root, needle, stop); } + bool is_part_of_scc(RTLIL::Cell *cell) + { + CellTypes ct; + ct.setup_internals(); + ct.setup_stdcells(); + + std::set queue, covered; + queue.insert(cell); + + while (!queue.empty()) + { + std::set new_queue; + + for (auto c : queue) { + if (!ct.cell_known(c->type)) + continue; + for (auto &conn : c->connections()) + if (ct.cell_input(c->type, conn.first)) + for (auto bit : conn.second) + for (auto &pi : mi.query_ports(bit)) + if (ct.cell_known(pi.cell->type) && ct.cell_output(pi.cell->type, pi.port)) + new_queue.insert(pi.cell); + covered.insert(c); + } + + queue.clear(); + for (auto c : new_queue) { + if (cells_to_remove.count(c)) + continue; + if (c == cell) + return true; + if (!covered.count(c)) + queue.insert(c); + } + } + + return false; + } + // ------------- // Setup and run // ------------- ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : - config(config), design(design), module(module) + config(config), design(design), module(module), mi(module) { bool before_scc = module_has_scc(); @@ -934,18 +989,37 @@ struct ShareWorker other_cell_select_score += p.first.size(); RTLIL::Cell *supercell; + std::set supercell_aux; if (cell_select_score <= other_cell_select_score) { - RTLIL::SigSpec act = make_cell_activation_logic(filtered_cell_activation_patterns); - supercell = make_supercell(cell, other_cell, act); + RTLIL::SigSpec act = make_cell_activation_logic(filtered_cell_activation_patterns, supercell_aux); + supercell = make_supercell(cell, other_cell, act, supercell_aux); log(" Activation signal for %s: %s\n", log_id(cell), log_signal(act)); } else { - RTLIL::SigSpec act = make_cell_activation_logic(filtered_other_cell_activation_patterns); - supercell = make_supercell(other_cell, cell, act); + RTLIL::SigSpec act = make_cell_activation_logic(filtered_other_cell_activation_patterns, supercell_aux); + supercell = make_supercell(other_cell, cell, act, supercell_aux); log(" Activation signal for %s: %s\n", log_id(other_cell), log_signal(act)); } log(" New cell: %s (%s)\n", log_id(supercell), log_id(supercell->type)); + cells_to_remove.insert(cell); + cells_to_remove.insert(other_cell); + + for (auto c : supercell_aux) + if (is_part_of_scc(c)) + goto do_rollback; + + if (0) { + do_rollback: + log(" New topology contains loops! Rolling back..\n"); + cells_to_remove.erase(cell); + cells_to_remove.erase(other_cell); + shareable_cells.insert(other_cell); + for (auto cc : supercell_aux) + module->remove(cc); + continue; + } + std::set> supercell_activation_patterns; supercell_activation_patterns.insert(filtered_cell_activation_patterns.begin(), filtered_cell_activation_patterns.end()); supercell_activation_patterns.insert(filtered_other_cell_activation_patterns.begin(), filtered_other_cell_activation_patterns.end()); @@ -953,9 +1027,6 @@ struct ShareWorker activation_patterns_cache[supercell] = supercell_activation_patterns; shareable_cells.insert(supercell); - cells_to_remove.insert(cell); - cells_to_remove.insert(other_cell); - for (auto bit : topo_sigmap(all_ctrl_signals)) for (auto c : topo_bit_drivers[bit]) topo_cell_drivers[supercell].insert(c); From 13117bb346dd02d2345f716b4403239aebe3d0e2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 19:44:08 +0200 Subject: [PATCH 750/750] Re-enabled assert for new logic loops in "share" pass --- passes/opt/share.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index e3b0159c..74b049bb 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1055,10 +1055,7 @@ struct ShareWorker log_assert(recursion_state.empty()); bool after_scc = before_scc || module_has_scc(); - if (before_scc != after_scc) - log("Warning: introduced topological logic loops!\n"); - // Pass::call_on_module(design, module, "scc;; show"); - // log_assert(before_scc == after_scc); + log_assert(before_scc == after_scc); } };