From 0defc86519fb02dd366b20ccec4add09302eae98 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Feb 2014 19:17:07 +0100 Subject: renamed ilang "scope error" to "ilang error" --- frontends/ilang/parser.y | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index c2e090220..ebb4d3095 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -87,7 +87,7 @@ design: module: TOK_MODULE TOK_ID EOL { if (current_design->modules.count($2) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of module %s.", $2).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); current_module = new RTLIL::Module; current_module->name = $2; current_module->attributes = attrbuf; @@ -120,7 +120,7 @@ wire_stmt: attrbuf.clear(); } wire_options TOK_ID EOL { if (current_module->wires.count($4) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of wire %s.", $4).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); current_wire->name = $4; current_module->wires[$4] = current_wire; free($4); @@ -157,7 +157,7 @@ memory_stmt: attrbuf.clear(); } memory_options TOK_ID EOL { if (current_module->memories.count($4) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of memory %s.", $4).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of memory %s.", $4).c_str()); current_memory->name = $4; current_module->memories[$4] = current_memory; free($4); @@ -175,7 +175,7 @@ memory_options: cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { if (current_module->cells.count($3) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of cell %s.", $3).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); current_cell = new RTLIL::Cell; current_cell->type = $2; current_cell->name = $3; @@ -200,7 +200,7 @@ cell_body: } | cell_body TOK_CONNECT TOK_ID sigspec EOL { if (current_cell->connections.count($3) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of cell port %s.", $3).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); current_cell->connections[$3] = *$4; delete $4; free($3); @@ -210,7 +210,7 @@ cell_body: proc_stmt: TOK_PROCESS TOK_ID EOL { if (current_module->processes.count($2) != 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: redefinition of process %s.", $2).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of process %s.", $2).c_str()); current_process = new RTLIL::Process; current_process->name = $2; current_process->attributes = attrbuf; @@ -362,7 +362,7 @@ sigspec: } | TOK_ID { if (current_module->wires.count($1) == 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: wire %s not found", $1).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); RTLIL::SigChunk chunk; chunk.wire = current_module->wires[$1]; chunk.width = current_module->wires[$1]->width; @@ -374,7 +374,7 @@ sigspec: } | TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: wire %s not found", $1).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); RTLIL::SigChunk chunk; chunk.wire = current_module->wires[$1]; chunk.offset = $3; @@ -386,7 +386,7 @@ sigspec: } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) - rtlil_frontend_ilang_yyerror(stringf("scope error: wire %s not found", $1).c_str()); + rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); RTLIL::SigChunk chunk; chunk.wire = current_module->wires[$1]; chunk.width = $3 - $5 + 1; -- cgit v1.2.3 From ab71bd0746c39402aefaea85322fe36bdbaabb09 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 08:35:42 +0100 Subject: 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 697cf69fe..9a8a277a5 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 5aa13572e..e6b7a72d8 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"); -- cgit v1.2.3 From 9ce7b0fc3bcd1fcb8cebe4f3c86318eaa4fbc943 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 13:11:58 +0100 Subject: 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 7bccd9a5a..b7ec8b8fe 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 } -- cgit v1.2.3 From 007bdff55d69e6e29091c7beff19c36eeb7ed078 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 23:29:54 +0100 Subject: Added support for functions returning integer --- frontends/verilog/parser.y | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 5b6bf58c2..8080729b0 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -106,7 +106,7 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT -%type wire_type range non_opt_range expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -360,6 +360,16 @@ range: $$ = NULL; }; +range_or_integer: + range { + $$ = $1; + } | + TOK_INTEGER { + $$ = new AstNode(AST_RANGE); + $$->children.push_back(AstNode::mkconst_int(31, true)); + $$->children.push_back(AstNode::mkconst_int(0, true)); + }; + module_body: module_body module_body_stmt | /* empty */; @@ -380,7 +390,7 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range TOK_ID ';' { + TOK_FUNCTION opt_signed range_or_integer TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$4; ast_stack.back()->children.push_back(current_function_or_task); -- cgit v1.2.3 From 7664f5d92b9fd78c7a858702544887d48c1d5aec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 08:07:08 +0100 Subject: 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 9a8a277a5..72bd6d1ee 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 e6b7a72d8..1115bdc7b 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 b7ec8b8fe..7bccd9a5a 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 } -- cgit v1.2.3 From b4639078903847469c2cfe211b3e5d7006a78cc8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 08:12:52 +0100 Subject: 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 1115bdc7b..dae3a22fc 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" -- cgit v1.2.3 From cd9e8741a71502c303c6f25d02bb2259a7dd7ff3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 13:59:13 +0100 Subject: Implemented read_verilog -defer --- frontends/ast/ast.cc | 135 ++++++++++++++++++++-------------- frontends/ast/ast.h | 2 +- frontends/verilog/verilog_frontend.cc | 12 ++- passes/hierarchy/hierarchy.cc | 26 +++++-- 4 files changed, 109 insertions(+), 66 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 96608ae37..ab2972b2c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -747,14 +747,18 @@ bool AstNode::asBool() } // create a new AstModule from an AST_MODULE AST node -static AstModule* process_module(AstNode *ast) +static AstModule* process_module(AstNode *ast, bool defer) { assert(ast->type == AST_MODULE); - log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str()); + + if (defer) + log("Storing AST representation for module `%s'.\n", ast->str.c_str()); + else + log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str()); current_module = new AstModule; current_module->ast = NULL; - current_module->name = ast->str; + current_module->name = defer ? "$abstract" + ast->str : ast->str; current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); current_ast_mod = ast; @@ -766,60 +770,63 @@ static AstModule* process_module(AstNode *ast) log("--- END OF AST DUMP ---\n"); } - while (ast->simplify(!flag_noopt, false, false, 0, -1, false)) { } + if (!defer) + { + while (ast->simplify(!flag_noopt, false, false, 0, -1, false)) { } - if (flag_dump_ast2) { - log("Dumping verilog AST after simplification:\n"); - ast->dumpAst(NULL, " "); - log("--- END OF AST DUMP ---\n"); - } + if (flag_dump_ast2) { + log("Dumping verilog AST after simplification:\n"); + ast->dumpAst(NULL, " "); + log("--- END OF AST DUMP ---\n"); + } - if (flag_dump_vlog) { - log("Dumping verilog AST (as requested by dump_vlog option):\n"); - ast->dumpVlog(NULL, " "); - log("--- END OF AST DUMP ---\n"); - } + if (flag_dump_vlog) { + log("Dumping verilog AST (as requested by dump_vlog option):\n"); + ast->dumpVlog(NULL, " "); + log("--- END OF AST DUMP ---\n"); + } - if (flag_lib) { - std::vector new_children; - for (auto child : ast->children) { - if (child->type == AST_WIRE && (child->is_input || child->is_output)) - new_children.push_back(child); - else - delete child; + if (flag_lib) { + std::vector new_children; + for (auto child : ast->children) { + if (child->type == AST_WIRE && (child->is_input || child->is_output)) + new_children.push_back(child); + else + delete child; + } + ast->children.swap(new_children); + ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); } - ast->children.swap(new_children); - ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); - } - ignoreThisSignalsInInitial = RTLIL::SigSpec(); + ignoreThisSignalsInInitial = RTLIL::SigSpec(); - for (auto &attr : ast->attributes) { - if (attr.second->type != AST_CONSTANT) - log_error("Attribute `%s' with non-constant value at %s:%d!\n", - attr.first.c_str(), ast->filename.c_str(), ast->linenum); - current_module->attributes[attr.first] = attr.second->asAttrConst(); - } - for (size_t i = 0; i < ast->children.size(); i++) { - AstNode *node = ast->children[i]; - if (node->type == AST_WIRE || node->type == AST_MEMORY) - node->genRTLIL(); - } - for (size_t i = 0; i < ast->children.size(); i++) { - AstNode *node = ast->children[i]; - if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL) - node->genRTLIL(); - } + for (auto &attr : ast->attributes) { + if (attr.second->type != AST_CONSTANT) + log_error("Attribute `%s' with non-constant value at %s:%d!\n", + attr.first.c_str(), ast->filename.c_str(), ast->linenum); + current_module->attributes[attr.first] = attr.second->asAttrConst(); + } + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type == AST_WIRE || node->type == AST_MEMORY) + node->genRTLIL(); + } + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL) + node->genRTLIL(); + } - ignoreThisSignalsInInitial.sort_and_unify(); + ignoreThisSignalsInInitial.sort_and_unify(); - for (size_t i = 0; i < ast->children.size(); i++) { - AstNode *node = ast->children[i]; - if (node->type == AST_INITIAL) - node->genRTLIL(); - } + for (size_t i = 0; i < ast->children.size(); i++) { + AstNode *node = ast->children[i]; + if (node->type == AST_INITIAL) + node->genRTLIL(); + } - ignoreThisSignalsInInitial = RTLIL::SigSpec(); + ignoreThisSignalsInInitial = RTLIL::SigSpec(); + } current_module->ast = ast_before_simplify; current_module->nolatches = flag_nolatches; @@ -832,7 +839,7 @@ static AstModule* process_module(AstNode *ast) } // create AstModule instances for all modules in the AST tree and add them to 'design' -void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef) +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer) { current_ast = ast; flag_dump_ast1 = dump_ast1; @@ -847,7 +854,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { - if (design->modules.count((*it)->str) != 0) { + if (design->modules.count((*it)->str) != 0 && design->modules.count("$abstract" + (*it)->str) != 0) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -855,7 +862,10 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - design->modules[(*it)->str] = process_module(*it); + if (defer) + design->modules["$abstract" + (*it)->str] = process_module(*it, true); + else + design->modules[(*it)->str] = process_module(*it, false); } } @@ -869,7 +879,12 @@ AstModule::~AstModule() // create a new parametric module (when needed) and return the name of the generated module RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map parameters) { - log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", name.c_str()); + std::string stripped_name = name; + + if (stripped_name.substr(0, 9) == "$abstract") + stripped_name = stripped_name.substr(9); + + log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); current_ast = NULL; flag_dump_ast1 = false; @@ -885,12 +900,13 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map hash_data; - hash_data.insert(hash_data.end(), name.begin(), name.end()); + hash_data.insert(hash_data.end(), stripped_name.begin(), stripped_name.end()); hash_data.push_back(0); AstNode *new_ast = ast->clone(); int para_counter = 0; + int orig_parameters_n = parameters.size(); for (auto it = new_ast->children.begin(); it != new_ast->children.end(); it++) { AstNode *child = *it; if (child->type != AST_PARAMETER) @@ -917,10 +933,15 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map 0) - log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), name.c_str()); + log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), stripped_name.c_str()); std::string modname; + if (orig_parameters_n == 0) + { + modname = stripped_name; + } + else if (para_info.size() > 60) { unsigned char hash[20]; @@ -933,16 +954,16 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapmodules.count(modname) == 0) { new_ast->str = modname; - design->modules[modname] = process_module(new_ast); + design->modules[modname] = process_module(new_ast, false); design->modules[modname]->check(); } else { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 01702c3cf..8335db096 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -232,7 +232,7 @@ namespace AST }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code - void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1 = false, bool dump_ast2 = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false, bool noopt = false, bool icells = false, bool ignore_redef = false); + void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1 = false, bool dump_ast2 = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false, bool noopt = false, bool icells = false, bool ignore_redef = false, bool defer = true); // parametric modules are supported directly by the AST library // therfore we need our own derivate of RTLIL::Module with overloaded virtual functions diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index c70d6f305..d46dfa6e2 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -106,6 +106,11 @@ struct VerilogFrontend : public Frontend { log(" ignore re-definitions of modules. (the default behavior is to\n"); log(" create an error message.)\n"); log("\n"); + log(" -defer\n"); + log(" only read the abstract syntax tree and defer actual compilation\n"); + log(" to a later 'hierarchy' command. Useful in cases where the default\n"); + log(" parameters of modules yield invalid or not synthesizable code.\n"); + log("\n"); log(" -setattr \n"); log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); @@ -135,6 +140,7 @@ struct VerilogFrontend : public Frontend { bool flag_noopt = false; bool flag_icells = false; bool flag_ignore_redef = false; + bool flag_defer = false; std::map defines_map; std::list include_dirs; std::list attributes; @@ -199,6 +205,10 @@ struct VerilogFrontend : public Frontend { flag_ignore_redef = true; continue; } + if (arg == "-defer") { + flag_defer = true; + continue; + } if (arg == "-setattr" && argidx+1 < args.size()) { attributes.push_back(RTLIL::escape_id(args[++argidx])); continue; @@ -264,7 +274,7 @@ struct VerilogFrontend : public Frontend { child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } - AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef); + AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer); if (!flag_nopp) fclose(fp); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 50d0e6e47..526d17294 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) { -- cgit v1.2.3 From a1239416185aebca03d131dc3ebe3e3d45c5a9f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 18:56:36 +0100 Subject: Updated ABC --- Makefile | 2 +- passes/abc/abc.cc | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 72bd6d1ee..89e4a9154 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 dae3a22fc..eaecb7910 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) -- cgit v1.2.3 From de3ea9269a55b653b94651559bebc93e01e28afb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 19:14:15 +0100 Subject: 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 eaecb7910..4add6452d 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" -- cgit v1.2.3 From 3121d19d95ae916b96baa000197f3ec2aa5c5ad7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 11:28:42 +0100 Subject: 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 4add6452d..bd0d983ac 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(); -- cgit v1.2.3 From 534c1a5dd009b41629d2d05acfde747ce6fbc19c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 19:56:44 +0100 Subject: Created basic support for function calls in parameter values --- frontends/ast/ast.cc | 2 +- frontends/ast/ast.h | 7 +- frontends/ast/genrtlil.cc | 12 +-- frontends/ast/simplify.cc | 212 +++++++++++++++++++++++++++++++++++++--------- 4 files changed, 184 insertions(+), 49 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index ab2972b2c..7e199cd5c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -772,7 +772,7 @@ static AstModule* process_module(AstNode *ast, bool defer) if (!defer) { - while (ast->simplify(!flag_noopt, false, false, 0, -1, false)) { } + while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { } if (flag_dump_ast2) { log("Dumping verilog AST after simplification:\n"); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8335db096..ec4f4f62b 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -190,7 +190,7 @@ namespace AST // simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc. // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() - bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint); + bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); void expand_genblock(std::string index_var, std::string prefix, std::map &name_map); void replace_ids(std::map &rules); void mem2reg_as_needed_pass1(std::map> &mem2reg_places, @@ -198,6 +198,11 @@ namespace AST void mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode *mod, AstNode *block); void meminfo(int &mem_width, int &mem_size, int &addr_bits); + // additional functionality for evaluating constant functions + struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; + void replace_variables(std::map &variables, AstNode *fcall); + AstNode *eval_const_function(AstNode *fcall); + // create a human-readable text representation of the AST (for debugging) void dumpAst(FILE *f, std::string indent); void dumpVlog(FILE *f, std::string indent); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 591d027cb..d92da4000 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -648,8 +648,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) else if (!range->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } + while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); @@ -665,7 +665,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_TO_BITS: - while (children[0]->simplify(true, false, false, 1, -1, false) == true) { } + while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } if (children[0]->type != AST_CONSTANT) log_error("Left operand of tobits expression is not constant at %s:%d!\n", filename.c_str(), linenum); children[1]->detectSignWidthWorker(sub_width_hint, sign_hint); @@ -693,7 +693,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_REPLICATE: - while (children[0]->simplify(true, false, false, 1, -1, false) == true) { } + while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } if (children[0]->type != AST_CONSTANT) log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum); children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint); @@ -961,8 +961,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false)) { } + while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b51079ce5..85dc1d3c2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -43,7 +43,7 @@ using namespace AST_INTERNAL; // // this function also does all name resolving and sets the id2ast member of all // nodes that link to a different node using names and lexical scoping. -bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint) +bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param) { AstNode *newNode = NULL; bool did_something = false; @@ -52,7 +52,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { assert(type == AST_MODULE); - while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint)) { } + while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { } if (!flag_nomem2reg && !get_bool_attribute("\\nomem2reg")) { @@ -114,7 +114,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, reg->is_reg = true; reg->is_signed = node->is_signed; children.push_back(reg); - while (reg->simplify(true, false, false, 1, -1, false)) { } + while (reg->simplify(true, false, false, 1, -1, false, false)) { } } } @@ -128,7 +128,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } - while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint)) { } + while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { } return false; } @@ -148,7 +148,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.) if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX) - const_fold = true; + const_fold = true, in_param = true; if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) const_fold = true; @@ -215,7 +215,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE) - while (node->simplify(true, false, false, 1, -1, false)) { } + while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) { } } } @@ -237,8 +237,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_ASSIGN_EQ: case AST_ASSIGN_LE: case AST_ASSIGN: - while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false) == true) { } - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) { } + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) { } children[0]->detectSignWidth(backup_width_hint, backup_sign_hint); children[1]->detectSignWidth(width_hint, sign_hint); width_hint = std::max(width_hint, backup_width_hint); @@ -247,11 +247,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_PARAMETER: case AST_LOCALPARAM: - while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) { } children[0]->detectSignWidth(width_hint, sign_hint); if (children.size() > 1) { assert(children[1]->type == AST_RANGE); - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false) == true) { } + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) { } if (!children[1]->range_valid) log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); width_hint = std::max(width_hint, children[1]->range_left - children[1]->range_right + 1); @@ -307,7 +307,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint = -1; sign_hint = true; for (auto child : children) { - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } child->detectSignWidthWorker(width_hint, sign_hint); } reset_width_after_children = true; @@ -337,9 +337,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (detect_width_simple && width_hint < 0) { for (auto child : children) - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } if (type == AST_REPLICATE) - while (children[0]->simplify(true, false, in_lvalue, stage, -1, false) == true) { } + while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) { } detectSignWidth(width_hint, sign_hint); } @@ -379,13 +379,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint_here = -1, sign_hint_here = false; if (children_are_self_determined) width_hint_here = -1, sign_hint_here = false; - did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here); + did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param); if (did_something_here) did_something = true; } } for (auto &attr : attributes) { - while (attr.second->simplify(true, false, false, stage, -1, false)) { } + while (attr.second->simplify(true, false, false, stage, -1, false, true)) { } } if (reset_width_after_children) { @@ -556,7 +556,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (current_block) wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false); current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false)) { } + while (wire->simplify(true, false, false, 1, -1, false, false)) { } AstNode *data = clone(); delete data->children[1]; @@ -621,7 +621,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // eval 1st expression AstNode *varbuf = init_ast->children[1]->clone(); - while (varbuf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (varbuf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (varbuf->type != AST_CONSTANT) log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); @@ -643,7 +643,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { // eval 2nd expression AstNode *buf = while_ast->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); @@ -672,7 +672,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENFOR) { for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } } else { @@ -684,7 +684,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // eval 3rd expression buf = next_ast->children[1]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum); @@ -708,7 +708,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::vector new_children; for (size_t i = 0; i < children.size(); i++) if (children[i]->type == AST_WIRE) { - children[i]->simplify(false, false, false, stage, -1, false); + children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); } else new_children.push_back(children[i]); @@ -727,7 +727,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < children.size(); i++) { - children[i]->simplify(false, false, false, stage, -1, false); + children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); } @@ -739,7 +739,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENIF && children.size() != 0) { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -764,7 +764,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -780,7 +780,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENCASE && children.size() != 0) { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -814,7 +814,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, continue; buf = child->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -840,7 +840,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(false, false, false, stage, -1, false); + buf->children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -955,8 +955,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, shift_expr = range->children[1]->clone(); AstNode *left_at_zero_ast = range->children[0]->clone(); AstNode *right_at_zero_ast = range->children[1]->clone(); - while (left_at_zero_ast->simplify(true, true, false, stage, -1, false)) { } - while (right_at_zero_ast->simplify(true, true, false, stage, -1, false)) { } + while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); @@ -988,7 +988,7 @@ skip_dynamic_range_lvalue_expansion:; wire_check->str = id_check; current_ast_mod->children.push_back(wire_check); current_scope[wire_check->str] = wire_check; - while (wire_check->simplify(true, false, false, 1, -1, false)) { } + while (wire_check->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_en = new AstNode(AST_WIRE); wire_en->str = id_en; @@ -996,7 +996,7 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(0, false, 1))))); current_ast_mod->children.back()->children[0]->children[0]->children[0]->str = id_en; current_scope[wire_en->str] = wire_en; - while (wire_en->simplify(true, false, false, 1, -1, false)) { } + while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } std::vector x_bit; x_bit.push_back(RTLIL::State::Sx); @@ -1070,19 +1070,19 @@ skip_dynamic_range_lvalue_expansion:; wire_addr->str = id_addr; current_ast_mod->children.push_back(wire_addr); current_scope[wire_addr->str] = wire_addr; - while (wire_addr->simplify(true, false, false, 1, -1, false)) { } + while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; current_ast_mod->children.push_back(wire_data); current_scope[wire_data->str] = wire_data; - while (wire_data->simplify(true, false, false, 1, -1, false)) { } + while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_en = new AstNode(AST_WIRE); wire_en->str = id_en; current_ast_mod->children.push_back(wire_en); current_scope[wire_en->str] = wire_en; - while (wire_en->simplify(true, false, false, 1, -1, false)) { } + while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } std::vector x_bits; for (int i = 0; i < mem_width; i++) @@ -1138,7 +1138,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$clog2") { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { } + while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); @@ -1160,6 +1160,23 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } + if (in_param) + { + bool all_args_const = true; + for (auto child : children) + if (child->type != AST_CONSTANT) + all_args_const = false; + + if (all_args_const) { + AstNode *func_workspace = current_scope[str]->clone(); + newNode = func_workspace->eval_const_function(this); + delete func_workspace; + goto apply_newNode; + } + + log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); + } + AstNode *decl = current_scope[str]; std::stringstream sstr; sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++) << "$"; @@ -1184,7 +1201,7 @@ skip_dynamic_range_lvalue_expansion:; wire->is_output = false; current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false)) { } + while (wire->simplify(true, false, false, 1, -1, false, false)) { } AstNode *lvalue = new AstNode(AST_IDENTIFIER); lvalue->str = wire->str; @@ -1206,7 +1223,7 @@ skip_dynamic_range_lvalue_expansion:; wire->is_input = false; wire->is_output = false; current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false)) { } + while (wire->simplify(true, false, false, 1, -1, false, false)) { } replace_rules[child->str] = wire->str; @@ -1628,14 +1645,14 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * wire_addr->is_reg = true; wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_addr); - while (wire_addr->simplify(true, false, false, 1, -1, false)) { } + while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; wire_data->is_reg = true; wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_data); - while (wire_data->simplify(true, false, false, 1, -1, false)) { } + while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } assert(block != NULL); size_t assign_idx = 0; @@ -1694,7 +1711,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * if (block) wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_addr); - while (wire_addr->simplify(true, false, false, 1, -1, false)) { } + while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; @@ -1702,7 +1719,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * if (block) wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_data); - while (wire_data->simplify(true, false, false, 1, -1, false)) { } + while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; @@ -1779,3 +1796,116 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) addr_bits++; } +// helper function for AstNode::eval_const_function() +void AstNode::replace_variables(std::map &variables, AstNode *fcall) +{ + if (type == AST_IDENTIFIER && variables.count(str)) { + int offset = variables.at(str).offset, width = variables.at(str).val.bits.size(); + if (!children.empty()) { + while (simplify(true, false, false, 1, -1, false, true)) { } + if (!range_valid) + log_error("Non-constant range in %s:%d (called from %s:%d).\n", + filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); + offset = std::min(range_left, range_right); + width = std::min(std::abs(range_left - range_right) + 1, width); + } + offset -= variables.at(str).offset; + std::vector &var_bits = variables.at(str).val.bits; + std::vector new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width); + AstNode *newNode = mkconst_bits(new_bits, variables.at(str).is_signed); + newNode->cloneInto(this); + delete newNode; + return; + } + + for (auto &child : children) + child->replace_variables(variables, fcall); +} + +// evaluate functions with all-const arguments +AstNode *AstNode::eval_const_function(AstNode *fcall) +{ + std::map backup_scope; + std::map variables; + AstNode *block = NULL; + + size_t argidx = 0; + for (auto child : children) + { + if (child->type == AST_BLOCK) + { + log_assert(block == NULL); + block = child; + continue; + } + + if (child->type == AST_WIRE) + { + while (child->simplify(true, false, false, 1, -1, false, true)) { } + if (!child->range_valid) + log_error("Can't determine size of variable %s in %s:%d (called from %s:%d).\n", + child->str.c_str(), child->filename.c_str(), child->linenum, fcall->filename.c_str(), fcall->linenum); + variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1); + variables[child->str].offset = std::min(child->range_left, child->range_right); + variables[child->str].is_signed = child->is_signed; + if (child->is_input && argidx < fcall->children.size()) + variables[child->str].val = fcall->children.at(argidx++)->bitsAsConst(variables[child->str].val.bits.size()); + backup_scope[child->str] = current_scope[child->str]; + current_scope[child->str] = child; + continue; + } + + log_abort(); + } + + log_assert(block != NULL); + log_assert(variables.count(str)); + + while (!block->children.empty()) + { + AstNode *stmt = block->children.front(); + +#if 0 + log("-----------------------------------\n"); + for (auto &it : variables) + log("%20s %40s\n", it.first.c_str(), log_signal(it.second.val)); + stmt->dumpAst(NULL, "stmt> "); +#endif + + if (stmt->type == AST_ASSIGN_EQ) + { + stmt->children.at(1)->replace_variables(variables, fcall); + while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + + if (stmt->children.at(1)->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + if (stmt->children.at(0)->type != AST_IDENTIFIER || !stmt->children.at(0)->children.empty()) + log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + if (!variables.count(stmt->children.at(0)->str)) + log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + + block->children.erase(block->children.begin()); + continue; + } + + log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + log_abort(); + } + + for (auto &it : backup_scope) + if (it.second == NULL) + current_scope.erase(it.first); + else + current_scope[it.first] = it.second; + + return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed); +} + -- cgit v1.2.3 From e8af3def7fbefa1608e72609e1c534091fc7c88e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 20:33:22 +0100 Subject: Added support for FOR loops in function calls in parameters --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7e199cd5c..56e9393b7 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -136,6 +136,7 @@ std::string AST::type2str(AstNodeType type) X(AST_COND) X(AST_DEFAULT) X(AST_FOR) + X(AST_WHILE) X(AST_GENVAR) X(AST_GENFOR) X(AST_GENIF) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index ec4f4f62b..f42bc35fb 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -116,6 +116,7 @@ namespace AST AST_COND, AST_DEFAULT, AST_FOR, + AST_WHILE, AST_GENVAR, AST_GENFOR, diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 85dc1d3c2..236843d5d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1891,10 +1891,51 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + delete block->children.front(); block->children.erase(block->children.begin()); continue; } + if (stmt->type == AST_FOR) + { + block->children.insert(block->children.begin(), stmt->children.at(0)); + stmt->children.at(3)->children.push_back(stmt->children.at(2)); + stmt->children.erase(stmt->children.begin() + 2); + stmt->children.erase(stmt->children.begin()); + stmt->type = AST_WHILE; + continue; + } + + if (stmt->type == AST_WHILE) + { + AstNode *cond = stmt->children.at(0)->clone(); + cond->replace_variables(variables, fcall); + while (cond->simplify(true, false, false, 1, -1, false, true)) { } + + if (cond->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + if (cond->asBool()) { + block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); + } else { + delete block->children.front(); + block->children.erase(block->children.begin()); + } + + delete cond; + continue; + } + + if (stmt->type == AST_BLOCK) + { + block->children.erase(block->children.begin()); + block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end()); + stmt->children.clear(); + delete stmt; + continue; + } + log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); log_abort(); -- cgit v1.2.3 From 45d2b6ffce24c3a4254ef7f80f300cc7840fec25 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Feb 2014 20:45:30 +0100 Subject: Be more conservative with new const-function code --- frontends/ast/simplify.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 236843d5d..2ae3cae08 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -148,10 +148,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.) if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX) - const_fold = true, in_param = true; + const_fold = true; if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) const_fold = true; + // in certain cases a function must be evaluated constant. this is what in_param controls. + if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_PREFIX) + in_param = true; + std::map backup_scope; // create name resolution entries for all objects with names -- cgit v1.2.3 From 4440610d3ffc5426c38e5cf8fccd757203c11a0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 12:57:28 +0100 Subject: Added liberty frontend --- frontends/liberty/Makefile.inc | 3 + frontends/liberty/liberty.cc | 359 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 362 insertions(+) create mode 100644 frontends/liberty/Makefile.inc create mode 100644 frontends/liberty/liberty.cc diff --git a/frontends/liberty/Makefile.inc b/frontends/liberty/Makefile.inc new file mode 100644 index 000000000..a02ef5e45 --- /dev/null +++ b/frontends/liberty/Makefile.inc @@ -0,0 +1,3 @@ + +OBJS += frontends/liberty/liberty.o + diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc new file mode 100644 index 000000000..220f32f5e --- /dev/null +++ b/frontends/liberty/liberty.cc @@ -0,0 +1,359 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "passes/techmap/libparse.h" +#include "kernel/register.h" +#include "kernel/log.h" + +using namespace PASS_DFFLIBMAP; + +struct token_t { + char type; + RTLIL::SigSpec sig; + token_t (char t) : type(t) { } + token_t (char t, RTLIL::SigSpec s) : type(t), sig(s) { } +}; + +static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&expr) +{ + log_assert(*expr != 0); + + int id_len = 0; + while (('a' <= expr[id_len] && expr[id_len] <= 'z') || ('A' <= expr[id_len] && expr[id_len] <= 'Z') || + ('0' <= expr[id_len] && expr[id_len] <= '9') || expr[id_len] == '.' || expr[id_len] == '_') id_len++; + + if (id_len == 0) + log_error("Expected identifier at `%s'.\n", expr); + + if (id_len == 1 && (*expr == '0' || *expr == '1')) + return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1; + + std::string id = RTLIL::escape_id(std::string(expr, id_len)); + if (!module->wires.count(id)) + log_error("Can't resolve wire name %s.\n", RTLIL::id2cstr(id)); + + expr += id_len; + return module->wires.at(id); +} + +static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_INV_"; + cell->connections["\\A"] = A; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_XOR_"; + cell->connections["\\A"] = A; + cell->connections["\\B"] = B; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_AND_"; + cell->connections["\\A"] = A; + cell->connections["\\B"] = B; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) +{ + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_OR_"; + cell->connections["\\A"] = A; + cell->connections["\\B"] = B; + cell->connections["\\Y"] = NEW_WIRE(module, 1); + module->add(cell); + return cell->connections["\\Y"]; +} + +static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) +{ + int top = int(stack.size())-1; + + if (0 <= top-1 && stack[top].type == 0 && stack[top-1].type == '!') { + token_t t = token_t(0, create_inv_cell(module, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top-1 && stack[top].type == '\'' && stack[top-1].type == 0) { + token_t t = token_t(0, create_inv_cell(module, stack[top-1].sig)); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top && stack[top].type == 0) { + if (next_token.type == '\'') + return false; + stack[top].type = 1; + return true; + } + + if (0 <= top-2 && stack[top-2].type == 1 && stack[top-1].type == '^' && stack[top].type == 1) { + token_t t = token_t(1, create_xor_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top && stack[top].type == 1) { + if (next_token.type == '^') + return false; + stack[top].type = 2; + return true; + } + + if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) { + token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top-2 && stack[top-2].type == 2 && (stack[top-1].type == '*' || stack[top-1].type == '&') && stack[top].type == 2) { + token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top && stack[top].type == 2) { + if (next_token.type == '*' || next_token.type == '&' || next_token.type == 0) + return false; + stack[top].type = 3; + return true; + } + + if (0 <= top-2 && stack[top-2].type == 3 && (stack[top-1].type == '+' || stack[top-1].type == '|') && stack[top].type == 3) { + token_t t = token_t(3, create_or_cell(module, stack[top-2].sig, stack[top].sig)); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + if (0 <= top-2 && stack[top-2].type == '(' && stack[top-1].type == 3 && stack[top].type == ')') { + token_t t = token_t(0, stack[top-1].sig); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(t); + return true; + } + + return false; +} + +static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) +{ + const char *orig_expr = expr; + std::vector stack; + + while (*expr) + { + if (*expr == ' ' || *expr == '\t' || *expr == '\r' || *expr == '\n' || *expr == '"') { + expr++; + continue; + } + + token_t next_token(0); + if (*expr == '(' || *expr == ')' || *expr == '\'' || *expr == '!' || *expr == '^' || *expr == '*' || *expr == '+' || *expr == '|') + next_token = token_t(*(expr++)); + else + next_token = token_t(0, parse_func_identifier(module, expr)); + + while (parse_func_reduce(module, stack, next_token)) {} + stack.push_back(next_token); + } + + while (parse_func_reduce(module, stack, token_t('.'))) {} + +#if 0 + for (size_t i = 0; i < stack.size(); i++) + if (stack[i].type < 16) + log("%3d: %d %s\n", int(i), stack[i].type, log_signal(stack[i].sig)); + else + log("%3d: %c\n", int(i), stack[i].type); +#endif + + if (stack.size() != 1 || stack.back().type != 3) + log_error("Parser error in function expr `%s'.\n", orig_expr); + + return stack.back().sig; +} + +struct LibertyFrontend : public Frontend { + LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" read_liberty [filename]\n"); + log("\n"); + log("Read cells from liberty file as modules into current design.\n"); + log("\n"); + log(" -lib\n"); + log(" only create empty blackbox modules\n"); + log("\n"); + log(" -ignore_redef\n"); + log(" ignore re-definitions of modules. (the default behavior is to\n"); + log(" create an error message.)\n"); + log("\n"); + log(" -setattr \n"); + log(" set the specified attribute (to the value 1) on all loaded modules\n"); + log("\n"); + } + virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + { + bool flag_lib = false; + bool flag_ignore_redef = false; + std::vector attributes; + + log_header("Executing Liberty frontend.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + std::string arg = args[argidx]; + if (arg == "-lib") { + flag_lib = true; + continue; + } + if (arg == "-ignore_redef") { + flag_ignore_redef = true; + continue; + } + if (arg == "-setattr" && argidx+1 < args.size()) { + attributes.push_back(RTLIL::escape_id(args[++argidx])); + continue; + } + break; + } + extra_args(f, filename, args, argidx); + + LibertyParser parser(f); + int cell_count = 0; + + for (auto cell : parser.ast->children) + { + if (cell->id != "cell" || cell->args.size() != 1) + continue; + + std::string cell_name = RTLIL::escape_id(cell->args.at(0)); + + if (design->modules.count(cell_name)) { + if (flag_ignore_redef) + continue; + log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); + } + + if (!flag_lib) + { + LibertyAst *ff = cell->find("ff"); + if (ff != NULL) { + log("Warning: skipping flip-flop cell %s.\n", RTLIL::id2cstr(cell_name)); + continue; + } + + LibertyAst *latch = cell->find("latch"); + if (latch != NULL) { + log("Warning: skipping latch cell %s.\n", RTLIL::id2cstr(cell_name)); + continue; + } + } + + // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); + cell_count++; + + RTLIL::Module *module = new RTLIL::Module; + module->name = cell_name; + design->modules[module->name] = module; + + for (auto &attr : attributes) + module->attributes[attr] = 1; + + for (auto pin : cell->children) + { + if (pin->id != "pin" || pin->args.size() != 1) + continue; + + LibertyAst *dir = pin->find("direction"); + if (dir == NULL || dir->value == "internal") + continue; + + log_assert(dir->value == "input" || dir->value == "output"); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(pin->args.at(0)); + module->add(wire); + + if (dir->value == "input") { + wire->port_input = true; + continue; + } + + wire->port_output = true; + + if (flag_lib) + continue; + + LibertyAst *func = pin->find("function"); + if (func == NULL) + log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + + RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); + module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + + continue; + } + + module->fixup_ports(); + } + + log("Imported %d cell types from liberty file.\n", cell_count); + } +} LibertyFrontend; + -- cgit v1.2.3 From 67effc9f5bc82b45ff163bfefea53c40d2c8819a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 13:16:08 +0100 Subject: 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 34d1a69c1..f611d7211 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; -- cgit v1.2.3 From 30379ea20d0f07016f24652336e85493bcff2f18 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 15:40:17 +0100 Subject: 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 7bccd9a5a..0e6c357c7 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 } -- cgit v1.2.3 From 5e39e6ece28e1145a04e8f00f9ac4f5d9a738acf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 15:42:10 +0100 Subject: Correctly convert constants to RTLIL (fixed undef handling) --- frontends/ast/genrtlil.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index d92da4000..12fe23fd8 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -905,18 +905,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (width_hint < 0) detectSignWidth(width_hint, sign_hint); - RTLIL::SigChunk chunk; - chunk.wire = NULL; - chunk.data.bits = bits; - chunk.width = bits.size(); - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; - is_signed = sign_hint; - return sig; + return RTLIL::SigSpec(bitsAsConst(width_hint, sign_hint)); } // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node -- cgit v1.2.3 From cdf0f10760d08b8349f392f1cbe41a6ca2b1f49e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 16:34:12 +0100 Subject: 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 23d93353f..fd5fa86e1 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]; -- cgit v1.2.3 From 96b1ebc8dc337b5412ebce91a7cecb84264b474a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 19:36:09 +0100 Subject: Bugfix in expression parser of read_liberty --- frontends/liberty/liberty.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 220f32f5e..ca899cb95 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -143,8 +143,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack } if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) { - token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig)); - stack.pop_back(); + token_t t = token_t(2, create_and_cell(module, stack[top-1].sig, stack[top].sig)); stack.pop_back(); stack.pop_back(); stack.push_back(t); -- cgit v1.2.3 From 118517ca5ae12d2793b1b5d1127f7fe3603d9fed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 19:36:33 +0100 Subject: Added ff and latch support to read_liberty --- frontends/liberty/liberty.cc | 294 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 254 insertions(+), 40 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index ca899cb95..485d28ee1 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -160,7 +160,7 @@ static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack } if (0 <= top && stack[top].type == 2) { - if (next_token.type == '*' || next_token.type == '&' || next_token.type == 0) + if (next_token.type == '*' || next_token.type == '&' || next_token.type == 0 || next_token.type == '(') return false; stack[top].type = 3; return true; @@ -225,6 +225,223 @@ static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) return stack.back().sig; } +static void create_ff(RTLIL::Module *module, LibertyAst *node) +{ + RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + + RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig; + bool clk_polarity = true, clear_polarity = true, preset_polarity = true; + + for (auto child : node->children) { + if (child->id == "clocked_on") + clk_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "next_state") + data_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "clear") + clear_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "preset") + preset_sig = parse_func_expr(module, child->value.c_str()); + } + + if (clk_sig.width == 0 || data_sig.width == 0) + log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); + + for (bool rerun_invert_rollback = true; rerun_invert_rollback;) + { + rerun_invert_rollback = false; + + for (auto &it : module->cells) { + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clk_sig) { + clk_sig = it.second->connections.at("\\A"); + clk_polarity = !clk_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { + clear_sig = it.second->connections.at("\\A"); + clear_polarity = !clear_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { + preset_sig = it.second->connections.at("\\A"); + preset_polarity = !preset_polarity; + rerun_invert_rollback = true; + } + } + } + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_INV_"; + cell->connections["\\A"] = iq_sig; + cell->connections["\\Y"] = iqn_sig; + module->add(cell); + + cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->connections["\\D"] = data_sig; + cell->connections["\\Q"] = iq_sig; + cell->connections["\\C"] = clk_sig; + module->add(cell); + + if (clear_sig.width == 0 && preset_sig.width == 0) { + cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); + } + + if (clear_sig.width == 1 && preset_sig.width == 0) { + cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + cell->connections["\\R"] = clear_sig; + } + + if (clear_sig.width == 0 && preset_sig.width == 1) { + cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); + cell->connections["\\R"] = preset_sig; + } + + if (clear_sig.width == 1 && preset_sig.width == 1) { + cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); + cell->connections["\\S"] = preset_sig; + cell->connections["\\R"] = clear_sig; + } + + log_assert(!cell->type.empty()); +} + +static void create_latch(RTLIL::Module *module, LibertyAst *node) +{ + RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + + RTLIL::SigSpec enable_sig, data_sig, clear_sig, preset_sig; + bool enable_polarity = true, clear_polarity = true, preset_polarity = true; + + for (auto child : node->children) { + if (child->id == "enable") + enable_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "data_in") + data_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "clear") + clear_sig = parse_func_expr(module, child->value.c_str()); + if (child->id == "preset") + preset_sig = parse_func_expr(module, child->value.c_str()); + } + + if (enable_sig.width == 0 || data_sig.width == 0) + log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); + + for (bool rerun_invert_rollback = true; rerun_invert_rollback;) + { + rerun_invert_rollback = false; + + for (auto &it : module->cells) { + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == enable_sig) { + enable_sig = it.second->connections.at("\\A"); + enable_polarity = !enable_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { + clear_sig = it.second->connections.at("\\A"); + clear_polarity = !clear_polarity; + rerun_invert_rollback = true; + } + if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { + preset_sig = it.second->connections.at("\\A"); + preset_polarity = !preset_polarity; + rerun_invert_rollback = true; + } + } + } + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = "$_INV_"; + cell->connections["\\A"] = iq_sig; + cell->connections["\\Y"] = iqn_sig; + module->add(cell); + + if (clear_sig.width == 1) + { + RTLIL::SigSpec clear_negative = clear_sig; + RTLIL::SigSpec clear_enable = clear_sig; + + if (clear_polarity == true || clear_polarity != enable_polarity) + { + RTLIL::Cell *inv = new RTLIL::Cell; + inv->name = NEW_ID; + inv->type = "$_INV_"; + inv->connections["\\A"] = clear_sig; + inv->connections["\\Y"] = NEW_WIRE(module, 1);; + module->add(inv); + + if (clear_polarity == true) + clear_negative = inv->connections["\\Y"]; + if (clear_polarity != enable_polarity) + clear_enable = inv->connections["\\Y"]; + } + + RTLIL::Cell *data_gate = new RTLIL::Cell; + data_gate->name = NEW_ID; + data_gate->type = "$_AND_"; + data_gate->connections["\\A"] = data_sig; + data_gate->connections["\\B"] = clear_negative; + data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(data_gate); + + RTLIL::Cell *enable_gate = new RTLIL::Cell; + enable_gate->name = NEW_ID; + enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + enable_gate->connections["\\A"] = enable_sig; + enable_gate->connections["\\B"] = clear_enable; + enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(enable_gate); + } + + if (preset_sig.width == 1) + { + RTLIL::SigSpec preset_positive = preset_sig; + RTLIL::SigSpec preset_enable = preset_sig; + + if (preset_polarity == false || preset_polarity != enable_polarity) + { + RTLIL::Cell *inv = new RTLIL::Cell; + inv->name = NEW_ID; + inv->type = "$_INV_"; + inv->connections["\\A"] = preset_sig; + inv->connections["\\Y"] = NEW_WIRE(module, 1);; + module->add(inv); + + if (preset_polarity == false) + preset_positive = inv->connections["\\Y"]; + if (preset_polarity != enable_polarity) + preset_enable = inv->connections["\\Y"]; + } + + RTLIL::Cell *data_gate = new RTLIL::Cell; + data_gate->name = NEW_ID; + data_gate->type = "$_OR_"; + data_gate->connections["\\A"] = data_sig; + data_gate->connections["\\B"] = preset_positive; + data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(data_gate); + + RTLIL::Cell *enable_gate = new RTLIL::Cell; + enable_gate->name = NEW_ID; + enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + enable_gate->connections["\\A"] = enable_sig; + enable_gate->connections["\\B"] = preset_enable; + enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + module->add(enable_gate); + } + + cell = new RTLIL::Cell; + cell->name = NEW_ID; + cell->type = stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N'); + cell->connections["\\D"] = data_sig; + cell->connections["\\Q"] = iq_sig; + cell->connections["\\E"] = enable_sig; + module->add(cell); +} + struct LibertyFrontend : public Frontend { LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { } virtual void help() @@ -289,21 +506,6 @@ struct LibertyFrontend : public Frontend { log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); } - if (!flag_lib) - { - LibertyAst *ff = cell->find("ff"); - if (ff != NULL) { - log("Warning: skipping flip-flop cell %s.\n", RTLIL::id2cstr(cell_name)); - continue; - } - - LibertyAst *latch = cell->find("latch"); - if (latch != NULL) { - log("Warning: skipping latch cell %s.\n", RTLIL::id2cstr(cell_name)); - continue; - } - } - // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); cell_count++; @@ -314,39 +516,51 @@ struct LibertyFrontend : public Frontend { for (auto &attr : attributes) module->attributes[attr] = 1; - for (auto pin : cell->children) - { - if (pin->id != "pin" || pin->args.size() != 1) - continue; + for (auto node : cell->children) + if (node->id == "pin" && node->args.size() == 1) { + LibertyAst *dir = node->find("direction"); + if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "internal")) + log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + if (!flag_lib || dir->value != "internal") + module->new_wire(1, RTLIL::escape_id(node->args.at(0))); + } - LibertyAst *dir = pin->find("direction"); - if (dir == NULL || dir->value == "internal") - continue; + for (auto node : cell->children) + { + if (!flag_lib) { + if (node->id == "ff" && node->args.size() == 2) + create_ff(module, node); + if (node->id == "latch" && node->args.size() == 2) + create_latch(module, node); + } - log_assert(dir->value == "input" || dir->value == "output"); + if (node->id == "pin" && node->args.size() == 1) + { + LibertyAst *dir = node->find("direction"); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(pin->args.at(0)); - module->add(wire); + if (flag_lib && dir->value == "internal") + continue; - if (dir->value == "input") { - wire->port_input = true; - continue; - } + RTLIL::Wire *wire = module->wires.at(RTLIL::escape_id(node->args.at(0))); - wire->port_output = true; + if (dir && dir->value == "input") { + wire->port_input = true; + continue; + } - if (flag_lib) - continue; + if (dir && dir->value == "output") + wire->port_output = true; - LibertyAst *func = pin->find("function"); - if (func == NULL) - log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + if (flag_lib) + continue; - RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); - module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + LibertyAst *func = node->find("function"); + if (func == NULL) + log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); - continue; + RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); + module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + } } module->fixup_ports(); -- cgit v1.2.3 From 623a68f5283331d96cded03bfd323266c88286f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Feb 2014 21:59:26 +0100 Subject: 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 b98214977..cc678516f 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; -- cgit v1.2.3 From 9a816b65a80a7a56b06ac5d0859be73b24008202 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 00:16:54 +0100 Subject: 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 a1a64f145..3a886b1c8 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) == ">=") -- cgit v1.2.3 From c05c3098f1d8a319706ad671607e7d894f33758e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 00:35:53 +0100 Subject: Tagging Yoys 0.2.0 --- CHANGELOG | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- Makefile | 2 +- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fa2c9b08d..ebc4c6449 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 89e4a9154..94a168a97 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 -- cgit v1.2.3 From b0ae19fa92787436e4c139f42af5f5890f0d4dd8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 00:54:41 +0100 Subject: 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 ebc4c6449..c014f4586 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 94a168a97..730a5355b 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 -- cgit v1.2.3 From 7ac524e8e8d1745dec4605c32944e318f46daf4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 13:16:38 +0100 Subject: Improved support for constant functions --- frontends/ast/simplify.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2ae3cae08..5e37911d3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1167,9 +1167,11 @@ skip_dynamic_range_lvalue_expansion:; if (in_param) { bool all_args_const = true; - for (auto child : children) + for (auto child : children) { + while (child->simplify(true, false, false, 1, -1, false, true)) { } if (child->type != AST_CONSTANT) all_args_const = false; + } if (all_args_const) { AstNode *func_workspace = current_scope[str]->clone(); @@ -1931,6 +1933,53 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (stmt->type == AST_CASE) + { + AstNode *expr = stmt->children.at(0)->clone(); + expr->replace_variables(variables, fcall); + while (expr->simplify(true, false, false, 1, -1, false, true)) { } + + AstNode *sel_case = NULL; + for (size_t i = 1; i < stmt->children.size(); i++) + { + bool found_match = false; + log_assert(stmt->children.at(i)->type == AST_COND); + + if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) { + sel_case = stmt->children.at(i)->children.back(); + continue; + } + + for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++) + { + AstNode *cond = stmt->children.at(i)->children.at(j)->clone(); + cond->replace_variables(variables, fcall); + + cond = new AstNode(AST_EQ, expr->clone(), cond); + while (cond->simplify(true, false, false, 1, -1, false, true)) { } + + if (cond->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + found_match = cond->asBool(); + delete cond; + } + + if (found_match) { + sel_case = stmt->children.at(i)->children.back(); + break; + } + } + + block->children.erase(block->children.begin()); + if (sel_case) + block->children.insert(block->children.begin(), sel_case->clone()); + delete stmt; + delete expr; + continue; + } + if (stmt->type == AST_BLOCK) { block->children.erase(block->children.begin()); -- cgit v1.2.3 From 9c29969bbc1b19f251011feaa791d242ac8e5e81 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 13:45:47 +0100 Subject: 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 21c5cdecc..3f5743da7 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 f38bd6ceb..673b3a213 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 000000000..0750a1307 --- /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 000000000..24ca9dab4 --- /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 000000000..bcdd32cbf --- /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 000000000..b92346034 --- /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 -- cgit v1.2.3 From aeb36b0b8b499a5b758840998afe9f1b4d7fc166 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 14:32:56 +0100 Subject: 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 3f5743da7..4ef10d7ad 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 673b3a213..4ee5886d2 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 000000000..ce1771544 --- /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 000000000..293c5b841 --- /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 000000000..eb715f83d --- /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 000000000..0c07e7e87 --- /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 -- cgit v1.2.3 From d3dc22a90f8b87ffe0109b0fa2074d887642e7cb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 17:16:44 +0100 Subject: Added recursion support to techmap --- passes/techmap/techmap.cc | 522 +++++++++++++++++++++++----------------------- 1 file changed, 262 insertions(+), 260 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index eeeebd111..eb044d6fe 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 TechmapWorker +{ + std::map simplemap_mappers; + std::map>, RTLIL::Module*> techmap_cache; + std::map techmap_do_cache; -struct TechmapWireData { - RTLIL::Wire *wire; - RTLIL::SigSpec value; -}; + struct TechmapWireData { + RTLIL::Wire *wire; + RTLIL::SigSpec value; + }; -typedef std::map> TechmapWires; + typedef std::map> TechmapWires; -static TechmapWires techmap_find_special_wires(RTLIL::Module *module) -{ - TechmapWires result; + TechmapWires techmap_find_special_wires(RTLIL::Module *module) + { + TechmapWires result; - if (module == NULL) - return result; + if (module == NULL) + return result; - for (auto &it : module->wires) { - const char *p = it.first.c_str(); - if (*p == '$') - continue; + for (auto &it : module->wires) { + const char *p = it.first.c_str(); + if (*p == '$') + continue; - const char *q = strrchr(p+1, '.'); - p = q ? q : p+1; + 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 (!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; -} + if (!result.empty()) { + SigMap sigmap(module); + for (auto &it1 : result) + for (auto &it2 : it1.second) + sigmap.apply(it2.value); + } -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); + return result; } - 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); + 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); } - 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); + + 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); + // 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); + // 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->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); + 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[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; } - 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; -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; - 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_it : module->cells) - cell_names.push_back(cell_it.first); + for (auto &cell_name : cell_names) + { + if (module->cells.count(cell_name) == 0) + continue; - for (auto &cell_name : cell_names) - { - 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; - if (!design->selected(module, cell) || handled_cells.count(cell) > 0) - continue; + if (celltypeMap.count(cell->type) == 0) + continue; - if (celltypeMap.count(cell->type) == 0) - continue; + 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; - 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; + } - 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(); + } - 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 (0) { + next_tpl: 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 (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; + 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; } - 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; + if (flatten_mode) + techmap_do_cache[tpl] = true; - while (keep_running) + if (techmap_do_cache.count(tpl) == 0) { - 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; + 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; + if (!techmap_do_cache[tpl]) + break; - for (auto &it : twd) - { - if (it.first.substr(0, 12) != "_TECHMAP_DO_" || it.second.empty()) - continue; + for (auto &it : twd) + { + if (it.first.substr(0, 12) != "_TECHMAP_DO_" || it.second.empty()) + continue; - auto &data = it.second.front(); + 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)); + 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; + 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); + 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(); + 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(); + 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; + 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 (techmap_do_cache.at(tpl) == false) + continue; + + if (log_continue) { + log_header("Continuing TECHMAP pass.\n"); + log_continue = false; + } - 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; } - 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; -- cgit v1.2.3 From 42ce3db983fdb512e181daab1817991a661066ff Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 17:39:50 +0100 Subject: 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 da9ef43f9..7e043bcff 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(); } -- cgit v1.2.3 From f08c71b96c325f2432abb4f95fd823ae243e003b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 17:56:19 +0100 Subject: 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 4ef10d7ad..cf36d32cc 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 4ee5886d2..74f263270 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 000000000..e888a7a7c --- /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 000000000..620a06d9e --- /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 000000000..48203e319 --- /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 -- cgit v1.2.3 From 7d7e068dd1c5e04cf0c2b9e18abade2b49fe677e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 20:20:25 +0100 Subject: Added a warning note about error reporting to read_verilog help message --- frontends/verilog/verilog_frontend.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index d46dfa6e2..477f26b45 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -125,6 +125,11 @@ struct VerilogFrontend : public Frontend { log("The command 'verilog_defaults' can be used to register default options for\n"); log("subsequent calls to 'read_verilog'.\n"); log("\n"); + log("Note that the Verilog frontend does a pretty good job of processing valid\n"); + log("verilog input, but has not very good error reporting. It generally is\n"); + log("recommended to use a simulator (for example icarus verilog) for checking\n"); + log("the syntax of the code, rather than to rely on read_verilog for that.\n"); + log("\n"); } virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) { -- cgit v1.2.3 From 28e14ee50a3effcd5335ec06f5b1c2acda008a4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 21:58:27 +0100 Subject: 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 733a1cbf1..d330fb7bd 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(); -- cgit v1.2.3 From a9b11d7c83a060e59185636711c3ffa4f1c76591 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 21:58:59 +0100 Subject: 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 eb044d6fe..da87c3ab7 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"); -- cgit v1.2.3 From 6d63f39eb6abbefd8a12f0fe081c33ef1638800c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 22:18:06 +0100 Subject: 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 da87c3ab7..f0d1e6da4 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) -- cgit v1.2.3 From 37cbb1ca60b03cbaaef5041db5f631b90a303f9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 22:31:53 +0100 Subject: 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 cf36d32cc..483389d84 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 74f263270..3bbc239a4 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 000000000..4a3c2a062 --- /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 000000000..4b975f414 --- /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 000000000..c5dac49eb --- /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 -- cgit v1.2.3 From ca53ef50982d84917a4f6d293dd0d07805bb8eb6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 09:44:39 +0100 Subject: 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 f0d1e6da4..53164b58a 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) { -- cgit v1.2.3 From 0fbc1a59dd617aa3e9e9219180b8df0a37447300 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 09:45:04 +0100 Subject: 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 483389d84..80210b96d 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 35d0b8a78..432ce3688 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 312cb8986..275766474 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} -- cgit v1.2.3 From 4a948d780a6dd7de73b4dd05aecabe3a12863f3f Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 17 Feb 2014 06:06:04 -0500 Subject: 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 c08271590..1cf4f0841 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; } -- cgit v1.2.3 From 0851c2b6ea7044d9bce2014a2be2365a2bf7e1b0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 13:57:14 +0100 Subject: 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 1cf4f0841..2cd15d01c 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); -- cgit v1.2.3 From 02e6f2c5be8c5514cc8cdb7b3344f6170fb87af9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 14:28:52 +0100 Subject: Added Verilog support for "`default_nettype none" --- frontends/ast/ast.cc | 8 ++++++-- frontends/ast/ast.h | 6 +++--- frontends/ast/genrtlil.cc | 5 ++++- frontends/verilog/lexer.l | 12 ++++++++++++ frontends/verilog/parser.y | 1 + frontends/verilog/preproc.cc | 1 - frontends/verilog/verilog_frontend.cc | 3 ++- frontends/verilog/verilog_frontend.h | 3 +++ 8 files changed, 31 insertions(+), 8 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 56e9393b7..58be06791 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -46,7 +46,7 @@ namespace AST { // instanciate global variables (private API) namespace AST_INTERNAL { - bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells; + bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map current_scope; RTLIL::SigSpec *genRTLIL_subst_from = NULL; @@ -836,11 +836,12 @@ static AstModule* process_module(AstNode *ast, bool defer) current_module->lib = flag_lib; current_module->noopt = flag_noopt; current_module->icells = flag_icells; + current_module->autowire = flag_autowire; return current_module; } // create AstModule instances for all modules in the AST tree and add them to 'design' -void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer) +void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire) { current_ast = ast; flag_dump_ast1 = dump_ast1; @@ -852,6 +853,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_lib = lib; flag_noopt = noopt; flag_icells = icells; + flag_autowire = autowire; assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { @@ -897,6 +899,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::maplib = lib; new_mod->noopt = noopt; new_mod->icells = icells; + new_mod->autowire = autowire; return new_mod; } diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index f42bc35fb..72a2a4600 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -238,13 +238,13 @@ namespace AST }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code - void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1 = false, bool dump_ast2 = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false, bool noopt = false, bool icells = false, bool ignore_redef = false, bool defer = true); + void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire); // parametric modules are supported directly by the AST library // therfore we need our own derivate of RTLIL::Module with overloaded virtual functions struct AstModule : RTLIL::Module { AstNode *ast; - bool nolatches, nomem2reg, mem2reg, lib, noopt, icells; + bool nolatches, nomem2reg, mem2reg, lib, noopt, icells, autowire; virtual ~AstModule(); virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); virtual RTLIL::Module *clone() const; @@ -265,7 +265,7 @@ namespace AST namespace AST_INTERNAL { // internal state variables - extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells; + extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; extern AST::AstNode *current_ast, *current_ast_mod; extern std::map current_scope; extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 12fe23fd8..bc3783bda 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -921,7 +921,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Wire *wire = new RTLIL::Wire; wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); wire->name = str; - log("Warning: Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum); + if (flag_autowire) + log("Warning: Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum); + else + log_error("Identifier `%s' is implicitly declared at %s:%d and `default_nettype is set to none.\n", str.c_str(), filename.c_str(), linenum); current_module->wires[str] = wire; } else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) { diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 81167cf4e..79f44b4a6 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -81,6 +81,18 @@ namespace VERILOG_FRONTEND { "`timescale"[ \t]+[^ \t\r\n/]+[ \t]*"/"[ \t]*[^ \t\r\n]* /* ignore timescale directive */ +"`default_nettype"[ \t]+[^ \t\r\n/]+ { + char *p = yytext; + while (*p != 0 && *p != ' ' && *p != '\t') p++; + while (*p == ' ' || *p == '\t') p++; + if (!strcmp(p, "none")) + VERILOG_FRONTEND::default_nettype_wire = false; + else if (!strcmp(p, "wire")) + VERILOG_FRONTEND::default_nettype_wire = true; + else + frontend_verilog_yyerror("Unsupported default nettype: %s", p); +} + "`"[a-zA-Z_$][a-zA-Z0-9_$]* { frontend_verilog_yyerror("Unimplemented compiler directive or undefined macro %s.", yytext); } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 8080729b0..4726f1aa3 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -53,6 +53,7 @@ namespace VERILOG_FRONTEND { struct AstNode *current_ast, *current_ast_mod; int current_function_or_task_port_id; std::vector case_type_stack; + bool default_nettype_wire; } static void append_attr(AstNode *ast, std::map *al) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index db53e8c68..873ae3d51 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -373,7 +373,6 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } if (tok == "`timescale") { - std::string name; skip_spaces(); while (!tok.empty() && tok != "\n") tok = next_token(true); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 477f26b45..13c2676db 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -256,6 +256,7 @@ struct VerilogFrontend : public Frontend { AST::get_line_num = &frontend_verilog_yyget_lineno; current_ast = new AST::AstNode(AST::AST_DESIGN); + default_nettype_wire = true; FILE *fp = f; std::string code_after_preproc; @@ -279,7 +280,7 @@ struct VerilogFrontend : public Frontend { child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } - AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer); + AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire); if (!flag_nopp) fclose(fp); diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 8b4fae6e9..99b2164ef 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -42,6 +42,9 @@ namespace VERILOG_FRONTEND // this function converts a Verilog constant to an AST_CONSTANT node AST::AstNode *const2ast(std::string code, char case_type = 0); + + // state of `default_nettype + extern bool default_nettype_wire; } // the pre-processor -- cgit v1.2.3 From 13051e6acf6c1fd506a49d258c3d99c1334c78cc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:03:16 +0100 Subject: Added "sat -initsteps" --- passes/sat/sat.cc | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc index 2cd15d01c..2dc7a16ba 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()); + + if (!inductstep.solve(inductstep.ez.NOT(property))) { + if (inductstep.gotTimeout) + goto timeout; + log("Induction step proven: SUCCESS!\n"); + print_qed(); + goto tip_success; + } - log("Induction step failed. Incrementing induction length.\n"); - inductstep.ez.assume(property); - - 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"); -- cgit v1.2.3 From 61a2bf57b43eff81f177f1280574dff22885ad86 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:25:41 +0100 Subject: 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 dccc00555..577625259 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); } } -- cgit v1.2.3 From 32af10fa9b0fb8c86451a15f780288da13d4ab99 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:28:05 +0100 Subject: 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 2dc7a16ba..3b4a394ec 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); } -- cgit v1.2.3 From a78bba1f5cf5b8c312c453e5c2c1a57b6946bebd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 09:29:08 +0100 Subject: 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 3b4a394ec..d18a220d3 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; -- cgit v1.2.3 From a71d09421d31b43b6bda6f6958373ec8a409e3c1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 19:23:32 +0100 Subject: 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 53164b58a..74621d3e5 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"); -- cgit v1.2.3 From 3d9da919d8ec2f73df77dc1df02b132b12241d8e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Feb 2014 19:37:39 +0100 Subject: 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 80210b96d..e42a535f4 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 3bbc239a4..2a2858e5f 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 000000000..b6d91b01b --- /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 000000000..b53271faa --- /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 000000000..c08f1106a --- /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 275766474..1c07928b0 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}). -- cgit v1.2.3 From 772330608acd9726e406d182a339a314d2f046a2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 19 Feb 2014 12:40:49 +0100 Subject: 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 000000000..cfefe339f --- /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 000000000..92d3d1652 --- /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 = ""; + } + } +} + -- cgit v1.2.3 From 98940260e1a0e5d9d5d305b5fabe0aed89c9f57c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 12:46:29 +0100 Subject: 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 +++++++++++ manual/PRESENTATION_ExAdv/macc_simple_test_01.v | 6 ++ manual/PRESENTATION_ExAdv/macc_simple_test_02.v | 6 ++ manual/PRESENTATION_ExAdv/macc_simple_xmap.v | 6 ++ manual/PRESENTATION_ExAdv/select.v | 15 +++++ manual/PRESENTATION_ExAdv/select.ys | 10 +++ manual/PRESENTATION_ExAdv/select_01.v | 15 ----- manual/PRESENTATION_ExAdv/select_01.ys | 10 --- manual/PRESENTATION_Intro.tex | 2 +- 12 files changed, 175 insertions(+), 33 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 create mode 100644 manual/PRESENTATION_ExAdv/select.v create mode 100644 manual/PRESENTATION_ExAdv/select.ys delete mode 100644 manual/PRESENTATION_ExAdv/select_01.v delete mode 100644 manual/PRESENTATION_ExAdv/select_01.ys diff --git a/manual/PRESENTATION_ExAdv.tex b/manual/PRESENTATION_ExAdv.tex index e42a535f4..155403b85 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 2a2858e5f..60da31693 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 000000000..6358a47c9 --- /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 000000000..d5b01237b --- /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 000000000..8391fb383 --- /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 000000000..3630102fa --- /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 000000000..42f5bae95 --- /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.v b/manual/PRESENTATION_ExAdv/select.v new file mode 100644 index 000000000..1b0bb7eeb --- /dev/null +++ b/manual/PRESENTATION_ExAdv/select.v @@ -0,0 +1,15 @@ +module test(clk, s, a, y); + input clk, s; + input [15:0] a; + output [15:0] y; + reg [15:0] b, c; + + always @(posedge clk) begin + b <= a; + c <= b; + end + + wire [15:0] state_a = (a ^ b) + c; + wire [15:0] state_b = (a ^ b) - c; + assign y = !s ? state_a : state_b; +endmodule diff --git a/manual/PRESENTATION_ExAdv/select.ys b/manual/PRESENTATION_ExAdv/select.ys new file mode 100644 index 000000000..9832c104b --- /dev/null +++ b/manual/PRESENTATION_ExAdv/select.ys @@ -0,0 +1,10 @@ +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 -format pdf -notitle \ + -color red @cone_ab -color magenta @cone_a \ + -color blue @cone_b diff --git a/manual/PRESENTATION_ExAdv/select_01.v b/manual/PRESENTATION_ExAdv/select_01.v deleted file mode 100644 index 1b0bb7eeb..000000000 --- a/manual/PRESENTATION_ExAdv/select_01.v +++ /dev/null @@ -1,15 +0,0 @@ -module test(clk, s, a, y); - input clk, s; - input [15:0] a; - output [15:0] y; - reg [15:0] b, c; - - always @(posedge clk) begin - b <= a; - c <= b; - end - - wire [15:0] state_a = (a ^ b) + c; - wire [15:0] state_b = (a ^ b) - c; - assign y = !s ? state_a : state_b; -endmodule diff --git a/manual/PRESENTATION_ExAdv/select_01.ys b/manual/PRESENTATION_ExAdv/select_01.ys deleted file mode 100644 index a7fe27288..000000000 --- a/manual/PRESENTATION_ExAdv/select_01.ys +++ /dev/null @@ -1,10 +0,0 @@ -read_verilog select_01.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 \ - -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 1c07928b0..543fb41ed 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} -- cgit v1.2.3 From 4bd25edcd4773d312cc47384e639161d485492de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 19:12:32 +0100 Subject: Cleanups in handling of read_verilog -defer and -icells --- frontends/ast/ast.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 58be06791..d9ad6d8ef 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -759,7 +759,7 @@ static AstModule* process_module(AstNode *ast, bool defer) current_module = new AstModule; current_module->ast = NULL; - current_module->name = defer ? "$abstract" + ast->str : ast->str; + current_module->name = ast->str; current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); current_ast_mod = ast; @@ -857,7 +857,11 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { - if (design->modules.count((*it)->str) != 0 && design->modules.count("$abstract" + (*it)->str) != 0) { + if (flag_icells && (*it)->str.substr(0, 2) == "\\$") + (*it)->str = (*it)->str.substr(1); + if (defer) + (*it)->str = "$abstract" + (*it)->str; + if (design->modules.count((*it)->str)) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -865,10 +869,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - if (defer) - design->modules["$abstract" + (*it)->str] = process_module(*it, true); - else - design->modules[(*it)->str] = process_module(*it, false); + design->modules[(*it)->str] = process_module(*it, defer); } } -- cgit v1.2.3 From 0dadfed46d938282d7651c9a817f33b1d87397c7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 20:44:11 +0100 Subject: 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 f01a1c4b5..77cac2b45 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 000000000..dd8b4fede --- /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; + -- cgit v1.2.3 From b0e84802ecf3e224387317245786cd1437773a42 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 20:44:41 +0100 Subject: Progress in presentation --- manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v | 30 +++++++ manual/PRESENTATION_ExAdv/macc_xilinx_test.v | 6 ++ manual/PRESENTATION_ExAdv/macc_xilinx_test.ys | 17 ++++ manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v | 63 +++++++++++++++ manual/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 000000000..1f4867d11 --- /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 000000000..d08d939e9 --- /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 000000000..8cbc80b5e --- /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 000000000..386635ac2 --- /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 000000000..d1ded2954 --- /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 + -- cgit v1.2.3 From 483c99fe46d6b1cd35abddd38a629d30e13289b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:28:59 +0100 Subject: 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 83e1059c6..b582f98c9 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 80a6c0731..7b8889d60 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; - + -- cgit v1.2.3 From 236fc4209c17bf96b37e6f8a29a8aa3f24d5df45 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:30:15 +0100 Subject: Added "extract -map %" --- passes/techmap/extract.cc | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index eff14ff01..06b0df2de 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); - - if (filename.size() <= 3 || filename.substr(filename.size()-3) != ".il") { - Pass::call(map, "proc"); - Pass::call(map, "opt_clean"); + 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"); + } } } } -- cgit v1.2.3 From 737b71c73576d67b707119805cb599644a43777d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:31:13 +0100 Subject: 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 06b0df2de..d2193c7b1 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); -- cgit v1.2.3 From 4e43cb731701679e6d584ba14163befcb846e87b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:42:07 +0100 Subject: 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 74621d3e5..f163c024e 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"); -- cgit v1.2.3 From 9351e4d3caef1af7b7768d66b7f6edc12713d109 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Feb 2014 23:44:28 +0100 Subject: Progress in presentation --- manual/PRESENTATION_ExAdv/macc_xilinx_test.v | 9 ++++++- manual/PRESENTATION_ExAdv/macc_xilinx_test.ys | 31 +++++++++++++++++++--- manual/PRESENTATION_ExAdv/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 d08d939e9..d8fdf724c 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 8cbc80b5e..85c4a24f6 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 386635ac2..a80538d5b 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 000000000..15bd04ed1 --- /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 -- cgit v1.2.3 From 2aff7b2a47d2ad65ff34e10f008733da9ef50c4a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 02:13:02 +0100 Subject: 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 155403b85..f2080922b 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 60da31693..993a9d9e1 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 d5b01237b..8d106a28c 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 d8fdf724c..683d9d847 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 85c4a24f6..3f7893fa2 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 -- cgit v1.2.3 From 79f8944811cba40ca0f3bda98ab951395d24fa0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 10:40:15 +0100 Subject: 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 f5a982760..1c06fe519 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; -- cgit v1.2.3 From 81b3f52519d388f252405fa7cc7472ca9e51bc49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 12:06:40 +0100 Subject: 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 730a5355b..85b45577d 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 000000000..397b4a762 --- /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 000000000..7ecdd2dee --- /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 000000000..d207cc1bc --- /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 000000000..8285875b8 --- /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 000000000..532626960 --- /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 000000000..8d4614595 --- /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 000000000..e2fc11e52 --- /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 -- cgit v1.2.3 From 3c5e9730924e5cc1ac5769f1fadd3f1d15a2aaa3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 12:14:38 +0100 Subject: 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 d207cc1bc..5f93914c1 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 ( -- cgit v1.2.3 From f3ff29d4107355f5a1941da67e6402644dffefa4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 13:10:36 +0100 Subject: 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 1748ed810..5020cd67e 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))); } } } -- cgit v1.2.3 From 038eac741415c3d7ddef3a1e9348586e7ba3d4ad Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 13:40:43 +0100 Subject: 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 5020cd67e..8ac7cc7b2 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"); -- cgit v1.2.3 From 79edcd4318590974ef49b2d5f561382eea3454bf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 14:59:59 +0100 Subject: Progress in presentation --- manual/PRESENTATION_ExAdv.tex | 117 ++++++++++++++++++--- manual/PRESENTATION_ExAdv/macc_xilinx_swap_map.v | 4 +- manual/PRESENTATION_ExAdv/macc_xilinx_test.ys | 2 +- manual/PRESENTATION_ExAdv/macc_xilinx_unwrap_map.v | 6 +- manual/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 f2080922b..bf9b350ff 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 1f4867d11..e36967225 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 3f7893fa2..f3e8af4f0 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 a80538d5b..9dfaef131 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 d1ded2954..f23f6c02a 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 15bd04ed1..06372f5af 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; -- cgit v1.2.3 From 0a60f95224376304565d950832f8320d5f4fb70e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 18:59:49 +0100 Subject: Added vhdl2verilog --- frontends/vhdl2verilog/Makefile.inc | 1 + frontends/vhdl2verilog/vhdl2verilog.cc | 154 +++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 frontends/vhdl2verilog/Makefile.inc create mode 100644 frontends/vhdl2verilog/vhdl2verilog.cc diff --git a/frontends/vhdl2verilog/Makefile.inc b/frontends/vhdl2verilog/Makefile.inc new file mode 100644 index 000000000..003d89c4a --- /dev/null +++ b/frontends/vhdl2verilog/Makefile.inc @@ -0,0 +1 @@ +OBJS += frontends/vhdl2verilog/vhdl2verilog.o diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc new file mode 100644 index 000000000..9e9953ced --- /dev/null +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -0,0 +1,154 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include +#include + +struct Vhdl2verilogPass : public Pass { + Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" vhdl2verilog [options] ..\n"); + log("\n"); + log("This pass looks for subcircuits that are isomorphic to any of the modules\n"); + log("in the given map file and replaces them with instances of this modules. The\n"); + log("map file can be a verilog source file (*.v) or an ilang file (*.il).\n"); + log("\n"); + log(" -out \n"); + log(" do not import the vhdl2verilog output. instead write it to the\n"); + log(" specified file.\n"); + log("\n"); + log(" -vhdl2verilog_dir \n"); + log(" do use the specified vhdl2verilog installations. this is the directory\n"); + log(" that contains the setup_env.sh file. when this option is not present,\n"); + log(" it is assumed that vhdl2verilog is in the PATH environment variable.\n"); + log("\n"); + log(" -top \n"); + log(" The name of the top entity. This option is mandatory.\n"); + log("\n"); + log("vhdl2verilog can be obtained from:\n"); + log("http://www.edautils.com/vhdl2verilog.html\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + log_header("Executing VHDL2VERILOG (importing VHDL designs using vhdl2verilog).\n"); + log_push(); + + std::string out_file, top_entity; + std::string vhdl2verilog_dir; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-out" && argidx+1 < args.size()) { + out_file = args[++argidx]; + continue; + } + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_entity = args[++argidx]; + continue; + } + if (args[argidx] == "-vhdl2verilog_dir" && argidx+1 < args.size()) { + vhdl2verilog_dir = args[++argidx]; + continue; + } + break; + } + + if (argidx == args.size()) + cmd_error(args, argidx, "Missing filenames."); + if (args[argidx].substr(0, 1) == "-") + cmd_error(args, argidx, "Unkown option."); + if (top_entity.empty()) + log_cmd_error("Missing -top option.\n"); + + char tempdir_name[] = "/tmp/yosys-abc-XXXXXX"; + char *p = mkdtemp(tempdir_name); + log("Using temp directory %s.\n", tempdir_name); + if (p == NULL) + log_error("For some reason mkdtemp() failed!\n"); + + if (!out_file.empty() && out_file[0] != '/') { + char *pwd = get_current_dir_name(); + out_file = pwd + ("/" + out_file); + free(pwd); + } + + FILE *f = fopen(stringf("%s/files.list", tempdir_name).c_str(), "wt"); + while (argidx < args.size()) { + std::string file = args[argidx++]; + if (file.empty()) + continue; + if (file[0] != '/') { + char *pwd = get_current_dir_name(); + file = pwd + ("/" + file); + free(pwd); + } + fprintf(f, "%s\n", file.c_str()); + log("Adding '%s' to the file list.\n", file.c_str()); + } + fclose(f); + + std::string command = "exec 2>&1; "; + if (!vhdl2verilog_dir.empty()) + command += stringf("cd '%s'; . ./setup_env.sh; ", vhdl2verilog_dir.c_str()); + command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'", tempdir_name, + out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str()); + + log("Running '%s'..\n", command.c_str()); + + errno = ENOMEM; // popen does not set errno if memory allocation fails, therefore set it by hand + f = popen(command.c_str(), "r"); + if (f == NULL) + log_error("Opening pipe to `%s' for reading failed: %s\n", command.c_str(), strerror(errno)); + + char logbuf[1024]; + while (fgets(logbuf, 1024, f) != NULL) + log("%s", logbuf); + + int ret = pclose(f); + if (ret < 0) + log_error("Closing pipe to `%s' failed: %s\n", command.c_str(), strerror(errno)); + if (WEXITSTATUS(ret) != 0) + log_error("Execution of command \"%s\" failed: the shell returned %d\n", command.c_str(), WEXITSTATUS(ret)); + + if (out_file.empty()) { + f = fopen(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str(), "rt"); + if (f == NULL) + log_error("Can't open vhdl2verilog output file `vhdl2verilog_output.v'.\n"); + Frontend::frontend_call(design, f, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog"); + fclose(f); + } + + log_header("Removing temp directory `%s':\n", tempdir_name); + system(stringf("rm -rf '%s'", tempdir_name).c_str()); + + log_pop(); + } +} Vhdl2verilogPass; + -- cgit v1.2.3 From 8b508dc90b87c99e13f1fa9f8e79e48c7fa52e90 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Feb 2014 23:34:45 +0100 Subject: 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 571946573..057378e7c 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); -- cgit v1.2.3 From 1ec01d8c637e611eddd16a492d1eb0f652b95da0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 01:29:02 +0100 Subject: 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 d545834cf..4d3301c4d 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 2919aa2e3..04a010d68 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; -- cgit v1.2.3 From 357f3f6e93df1ebf2aa28a6c433a84f320fad043 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 11:34:31 +0100 Subject: 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 4d3301c4d..a1cb80520 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 04a010d68..59fa21348 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 -- cgit v1.2.3 From 337b461d26f3cdc34f4a2b6c49d61427ef10ef96 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 14:25:32 +0100 Subject: 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 1c06fe519..498f13511 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++) { -- cgit v1.2.3 From 548519875bbffda02c5c7a891ce67fd3738d6e6f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 17:07:22 +0100 Subject: 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 f611d7211..ad9a71b15 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; -- cgit v1.2.3 From f8c9143b2b232e2f22e6cfbf9c431b2a1b756afa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 22 Feb 2014 17:08:00 +0100 Subject: Fixed bug in generation of undefs for $memwr MUXes --- frontends/ast/simplify.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5e37911d3..55ed28b01 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1088,14 +1088,16 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - std::vector x_bits; + std::vector x_bits_addr, x_bits_data; + for (int i = 0; i < addr_bits; i++) + x_bits_addr.push_back(RTLIL::State::Sx); for (int i = 0; i < mem_width; i++) - x_bits.push_back(RTLIL::State::Sx); + x_bits_data.push_back(RTLIL::State::Sx); - AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits, false)); + AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); assign_addr->children[0]->str = id_addr; - AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits, false)); + AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); assign_data->children[0]->str = id_data; AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1)); -- cgit v1.2.3 From b76528d8a557dc324b1dfaa366e2b620795f582d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 23 Feb 2014 01:28:29 +0100 Subject: 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 325709664..ee14ffbad 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)) { -- cgit v1.2.3 From dab1612f81212d1bc1c07ee77b265167861ec883 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 23 Feb 2014 01:35:59 +0100 Subject: 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 840700cbd..539210442 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 a1cb80520..c6126d862 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 59fa21348..e7e082891 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 577625259..e6c005c69 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 547edb93b..79100b876 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 { -- cgit v1.2.3 From 6bc94b7eb2ecc7c2836c2fc10029542ce92eae11 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 24 Feb 2014 12:41:25 +0100 Subject: Don't blow up constants unneccessarily in Verilog frontend --- frontends/ast/genrtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index bc3783bda..dda069cb8 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -906,7 +906,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); is_signed = sign_hint; - return RTLIL::SigSpec(bitsAsConst(width_hint, sign_hint)); + return RTLIL::SigSpec(bitsAsConst()); } // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node -- cgit v1.2.3 From aaaa604853caaecf8dcbfa928914495efb5556c6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 26 Feb 2014 21:31:34 +0100 Subject: 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 539210442..d9bcb4250 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); -- cgit v1.2.3 From ae5032af845b4c85510b3ce4a63fea3cca5e6a00 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 26 Feb 2014 21:32:19 +0100 Subject: Fixed bit-extending in $mux argument (use $bu0 instead of $pos) --- frontends/ast/genrtlil.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dda069cb8..c3025913c 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -83,7 +83,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) -static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed) +static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) { if (width <= sig.width) { sig.extend(width, is_signed); @@ -96,7 +96,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s RTLIL::Cell *cell = new RTLIL::Cell; cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); cell->name = sstr.str(); - cell->type = "$pos"; + cell->type = celltype; current_module->cells[cell->name] = cell; RTLIL::Wire *wire = new RTLIL::Wire; @@ -1041,7 +1041,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = arg.width; if (width_hint > 0) { width = width_hint; - widthExtend(this, arg, width, is_signed); + widthExtend(this, arg, width, is_signed, "$pos"); } return uniop2rtlil(this, type_name, width, arg); } @@ -1196,8 +1196,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = std::max(val1.width, val2.width); is_signed = children[1]->is_signed && children[2]->is_signed; - widthExtend(this, val1, width, is_signed); - widthExtend(this, val2, width, is_signed); + widthExtend(this, val1, width, is_signed, "$bu0"); + widthExtend(this, val2, width, is_signed, "$bu0"); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); -- cgit v1.2.3 From 9e9998433616f438cb0185519bb5b7f8e1a8f543 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 27 Feb 2014 04:09:32 +0100 Subject: 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 34a6e56fa..4a600af9d 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 ad9a71b15..da71ec30e 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 -- cgit v1.2.3 From 04999f4af0f6e5c46843d9212abb0c962f533cca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 17:47:19 +0100 Subject: Fixed vhdl2verilog help message --- frontends/vhdl2verilog/vhdl2verilog.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 9e9953ced..367e63fe0 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -35,9 +35,8 @@ struct Vhdl2verilogPass : public Pass { log("\n"); log(" vhdl2verilog [options] ..\n"); log("\n"); - log("This pass looks for subcircuits that are isomorphic to any of the modules\n"); - log("in the given map file and replaces them with instances of this modules. The\n"); - log("map file can be a verilog source file (*.v) or an ilang file (*.il).\n"); + log("This command reads VHDL source files using the 'vhdl2verilog' tool and the\n"); + log("Yosys Verilog frontend.\n"); log("\n"); log(" -out \n"); log(" do not import the vhdl2verilog output. instead write it to the\n"); -- cgit v1.2.3 From ef90236a5dd59497661e9c9ba440adf22d6052de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 17:48:15 +0100 Subject: Fixed vhdl2verilog temp dir name --- frontends/vhdl2verilog/vhdl2verilog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 367e63fe0..de3936939 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -86,7 +86,7 @@ struct Vhdl2verilogPass : public Pass { if (top_entity.empty()) log_cmd_error("Missing -top option.\n"); - char tempdir_name[] = "/tmp/yosys-abc-XXXXXX"; + char tempdir_name[] = "/tmp/yosys-vhdl2verilog-XXXXXX"; char *p = mkdtemp(tempdir_name); log("Using temp directory %s.\n", tempdir_name); if (p == NULL) -- cgit v1.2.3 From e3debea4e659126c538a2ff5c6a9987ca7778d89 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 20:53:09 +0100 Subject: 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 e6c005c69..4ae5f4fda 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) -- cgit v1.2.3 From edc21460565ea75cff54cab69933da8c5e9db382 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 20:55:06 +0100 Subject: 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 4ae5f4fda..f77a3b918 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 79100b876..8d340b3d6 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 cc0fe5734..8283686e3 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; -- cgit v1.2.3 From 23f0a12c727721478bcb87ec142fb86a329f7cdb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 20:59:00 +0100 Subject: 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 c6126d862..287177b1c 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 f77a3b918..cc6301e44 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); -- cgit v1.2.3 From d500bd749f84c0b05a8ec96d2a5fc33ace0c5b58 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 1 Mar 2014 21:00:34 +0100 Subject: 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 287177b1c..d488a9062 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 e7e082891..c634e66e7 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 cc6301e44..4389c7a62 100644 --- a/libs/ezsat/ezsat.cc +++ b/libs/ezsat/ezsat.cc @@ -348,9 +348,13 @@ void ezSAT::freeze(int) { } -void ezSAT::assume(int id) +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 8d340b3d6..16f940a1d 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; -- cgit v1.2.3 From 895e9fc70cb2d45c606c64a7b12d51dc0564c005 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 3 Mar 2014 02:12:45 +0100 Subject: 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 4389c7a62..bbebee74f 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 16f940a1d..13b39d4ef 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; } -- cgit v1.2.3 From d5bd93997c9ce7c31ef430684700a2096618672e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 3 Mar 2014 02:13:17 +0100 Subject: 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 bbebee74f..fb3d24996 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 13b39d4ef..b0b731d0a 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); -- cgit v1.2.3 From 96e753041dbd0abc86ff0a6404f13d29edcb985d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 3 Mar 2014 02:14:27 +0100 Subject: 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 81250b000..746523f82 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++) -- cgit v1.2.3 From de7bd12004f24b7e9fff3ba1f253537704db4e44 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:45:33 +0100 Subject: Bugfix in recursive AST simplification --- frontends/ast/simplify.cc | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 55ed28b01..72d90e4ae 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -219,7 +219,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE) - while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) { } + while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) + did_something = true; } } @@ -241,8 +242,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_ASSIGN_EQ: case AST_ASSIGN_LE: case AST_ASSIGN: - while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) { } - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) + did_something = true; + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) + did_something = true; children[0]->detectSignWidth(backup_width_hint, backup_sign_hint); children[1]->detectSignWidth(width_hint, sign_hint); width_hint = std::max(width_hint, backup_width_hint); @@ -251,11 +254,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_PARAMETER: case AST_LOCALPARAM: - while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) { } + while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) + did_something = true; children[0]->detectSignWidth(width_hint, sign_hint); if (children.size() > 1) { assert(children[1]->type == AST_RANGE); - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) { } + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) + did_something = true; if (!children[1]->range_valid) log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); width_hint = std::max(width_hint, children[1]->range_left - children[1]->range_right + 1); @@ -311,7 +316,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint = -1; sign_hint = true; for (auto child : children) { - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) + did_something = true; child->detectSignWidthWorker(width_hint, sign_hint); } reset_width_after_children = true; @@ -341,9 +347,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (detect_width_simple && width_hint < 0) { for (auto child : children) - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) { } + while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) + did_something = true; if (type == AST_REPLICATE) - while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) { } + while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) + did_something = true; detectSignWidth(width_hint, sign_hint); } @@ -389,7 +397,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } for (auto &attr : attributes) { - while (attr.second->simplify(true, false, false, stage, -1, false, true)) { } + while (attr.second->simplify(true, false, false, stage, -1, false, true)) + did_something = true; } if (reset_width_after_children) { @@ -539,7 +548,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, current_scope[str] = auto_wire; did_something = true; } - id2ast = current_scope[str]; + if (id2ast != current_scope[str]) { + id2ast = current_scope[str]; + did_something = true; + } } // split memory access with bit select to individual statements -- cgit v1.2.3 From d6a01fe412419d32ec5b0d91f9076849d1ed489d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:55:58 +0100 Subject: Fixed merging of compatible wire decls in AST frontend --- frontends/ast/simplify.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 72d90e4ae..a20aacff5 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -206,10 +206,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, did_something = true; delete node; continue; + wires_are_incompatible: + if (stage > 1) + log_error("Incompatible re-declaration of wire %s at %s:%d.\n", node->str.c_str(), filename.c_str(), linenum); + continue; } this_wire_scope[node->str] = node; } - wires_are_incompatible: if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR || node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_CELL) { backup_scope[node->str] = current_scope[node->str]; -- cgit v1.2.3 From 09805ee9ec0408bdc68b914927899f02371efcb7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:56:31 +0100 Subject: Include id2ast pointers when dumping AST --- frontends/ast/ast.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d9ad6d8ef..f2f2d0e69 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -244,6 +244,12 @@ void AstNode::dumpAst(FILE *f, std::string indent) std::string type_name = type2str(type); fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum); + + if (id2ast) + fprintf(f, " [%p -> %p]", this, id2ast); + else + fprintf(f, " [%p]", this); + if (!str.empty()) fprintf(f, " str='%s'", str.c_str()); if (!bits.empty()) { -- cgit v1.2.3 From b1b8fe3a566099e5fd29e6d8c60e8f8b4feb0f34 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 5 Mar 2014 19:57:10 +0100 Subject: 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 c634e66e7..ac9c071c3 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 -- cgit v1.2.3 From a1bfde8c5ea0d5c9778579bf78165637ac6c9b25 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 11:53:37 +0100 Subject: 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 a56db93aa..749589f20 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 d9bcb4250..3ae9502f8 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++) -- cgit v1.2.3 From d7f29bb23f9bb2c74e02bc1221bcf27efc7ee4dc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 11:54:22 +0100 Subject: 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 fdee26b6f..a51dcb944 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 -- cgit v1.2.3 From 1ecaf1bb767834dc6a763549b63d9d4653c342d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 12:15:17 +0100 Subject: 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 f163c024e..937f41315 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"); -- cgit v1.2.3 From 8406e7f7b6cb8e79f7df02c2c616073a51c1ea9e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 12:15:44 +0100 Subject: 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 a51dcb944..cddaf4c6f 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) -- cgit v1.2.3 From 97710ffad5d4750b538dac5f08b77dce37e3cda4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 13:08:44 +0100 Subject: 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 3ae9502f8..bf72a31cb 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; } -- cgit v1.2.3 From 973507d85b0a20118f6a56ec787d44d6b574d3a6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 13:22:10 +0100 Subject: 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 cddaf4c6f..a05ea2786 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; -- cgit v1.2.3 From 9b9c3327ccf3a8e69f9af57333839f470df0ce66 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 14:18:34 +0100 Subject: 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 dd1299810..fee8fb71b 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; -- cgit v1.2.3 From 4d07f8825845618daffb4d61bdcbb3eda0e1393a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 16:37:19 +0100 Subject: Fixed gcc compiler warning --- frontends/vhdl2verilog/vhdl2verilog.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index de3936939..0467810e5 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -145,7 +145,8 @@ struct Vhdl2verilogPass : public Pass { } log_header("Removing temp directory `%s':\n", tempdir_name); - system(stringf("rm -rf '%s'", tempdir_name).c_str()); + if (system(stringf("rm -rf '%s'", tempdir_name).c_str()) != 0) + log_error("Execution of \"rm -rf '%s'\" failed!\n", tempdir_name); log_pop(); } -- cgit v1.2.3 From da5859a6744943469d5165724fa79ce243e5d8e3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 18:14:26 +0100 Subject: 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 746523f82..8d7ce5aaf 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); -- cgit v1.2.3 From 54d74cf6165ebefc2cf7aee4fab43566362eedb1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 6 Mar 2014 22:06:58 +0100 Subject: 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 8d7ce5aaf..22af13454 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); -- cgit v1.2.3 From f7bd0a523203ed52713ecde56c1cfb89df4d48af Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 15:56:10 +0100 Subject: 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 03ef183a5..45f7b4143 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, -- cgit v1.2.3 From 620d51d9f713d68ebc920b5b1cac59cc176b0b9d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 17:19:14 +0100 Subject: Bugfix in ilang frontend autoidx recovery --- frontends/ilang/lexer.l | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 5da8ce675..000919275 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -131,8 +131,8 @@ void update_autoidx(const char *p) q++; if ((q - p) < 10) { int idx = atoi(p); - if (idx > RTLIL::autoidx) - RTLIL::autoidx = idx; + if (idx >= RTLIL::autoidx) + RTLIL::autoidx = idx+1; } } } -- cgit v1.2.3 From 6f8865d81ab6392bdd1413f0ae6f5a5774524d28 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 18:29:04 +0100 Subject: 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 22af13454..eb94cad28 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) : -- cgit v1.2.3 From e3b11ea2d64724102070f96e667c4dea07c0c3e5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 7 Mar 2014 18:44:23 +0100 Subject: 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 eb94cad28..d4b7b5c10 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; -- cgit v1.2.3 From 22aabe05c9dcb7a7f5c16988fc98a43e55b52beb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Mar 2014 15:15:38 +0100 Subject: 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 bd0d983ac..2829e660f 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) -- cgit v1.2.3 From fcae92868de81de87079c1415d3d0123dce8d84c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Mar 2014 15:16:07 +0100 Subject: 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 8cbb8e2be..2ff551537 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()) -- cgit v1.2.3 From 8d06f9f2fe19cc581e61ff66d0641bc03f815fb3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 9 Mar 2014 20:40:04 +0100 Subject: Added "verific" command --- 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 85b45577d..a68ceccb4 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 000000000..74a669ef4 --- /dev/null +++ b/frontends/verific/Makefile.inc @@ -0,0 +1 @@ +OBJS += frontends/verific/verific.o diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc new file mode 100644 index 000000000..5c2b933cb --- /dev/null +++ b/frontends/verific/verific.cc @@ -0,0 +1,488 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/log.h" +#include +#include +#include +#include +#include +#include + +#ifdef VERIFIC_DIR + +#include "veri_file.h" +#include "vhdl_file.h" +#include "VeriWrite.h" +#include "DataBase.h" +#include "Message.h" + +#ifdef VERIFIC_NAMESPACE +using namespace Verific ; +#endif + +static void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefile, const char *msg, va_list args) +{ + log("VERIFIC-%s [%s] ", + msg_type == VERIFIC_NONE ? "NONE" : + msg_type == VERIFIC_ERROR ? "ERROR" : + msg_type == VERIFIC_WARNING ? "WARNING" : + msg_type == VERIFIC_IGNORE ? "IGNORE" : + msg_type == VERIFIC_INFO ? "INFO" : + msg_type == VERIFIC_COMMENT ? "COMMENT" : + msg_type == VERIFIC_PROGRAM_ERROR ? "PROGRAM_ERROR" : "UNKNOWN", message_id); + if (linefile) + log("%s:%d: ", LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile)); + logv(msg, args); + log("\n"); +} + +void import_attributes(std::map &attributes, DesignObj *obj) +{ + MapIter mi; + Att *attr; + + if (obj->Linefile()) + attributes["\\src"] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile())); + + // FIXME: Parse numeric attributes + FOREACH_ATTRIBUTE(obj, mi, attr) + attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(std::string(attr->Value())); +} + +static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set &nl_todo) +{ + if (design->modules.count(RTLIL::escape_id(nl->Owner()->Name()))) + log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); + + RTLIL::Module *module = new RTLIL::Module; + module->name = RTLIL::escape_id(nl->Owner()->Name()); + design->modules[module->name] = module; + + log("Importing module %s.\n", RTLIL::id2cstr(module->name)); + + std::map net_map; + + MapIter mi, mi2; + Port *port; + PortBus *portbus; + Net *net; + NetBus *netbus; + Instance *inst; + + FOREACH_PORT_OF_NETLIST(nl, mi, port) + { + if (port->Bus()) + continue; + + // log(" importing port %s.\n", port->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(port->Name()); + import_attributes(wire->attributes, port); + module->add(wire); + + if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_IN) + wire->port_input = true; + if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_OUT) + wire->port_output = true; + + if (port->GetNet()) { + net = port->GetNet(); + if (net_map.count(net) == 0) + net_map[net] = wire; + else if (wire->port_input) + module->connections.push_back(RTLIL::SigSig(net_map.at(net), wire)); + else + module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + } + } + + FOREACH_PORTBUS_OF_NETLIST(nl, mi, portbus) + { + // log(" importing portbus %s.\n", portbus->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(portbus->Name()); + wire->width = portbus->Size(); + wire->start_offset = std::min(portbus->LeftIndex(), portbus->RightIndex()); + import_attributes(wire->attributes, port); + module->add(wire); + + if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN) + wire->port_input = true; + if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_OUT) + wire->port_output = true; + + for (int i = portbus->LeftIndex();; i += portbus->IsUp() ? +1 : -1) { + if (portbus->ElementAtIndex(i) && portbus->ElementAtIndex(i)->GetNet()) { + net = portbus->ElementAtIndex(i)->GetNet(); + RTLIL::SigBit bit(wire, i - wire->start_offset); + if (net_map.count(net) == 0) + net_map[net] = bit; + else if (wire->port_input) + module->connections.push_back(RTLIL::SigSig(net_map.at(net), bit)); + else + module->connections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + } + if (i == portbus->RightIndex()) + break; + } + } + + module->fixup_ports(); + + FOREACH_NET_OF_NETLIST(nl, mi, net) + { + if (net_map.count(net)) { + // log(" skipping net %s.\n", net->Name()); + continue; + } + + if (net->Bus()) + continue; + + // log(" importing net %s.\n", net->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(net->Name()); + while (module->count_id(wire->name)) + wire->name += "_"; + import_attributes(wire->attributes, port); + module->add(wire); + + if (net_map.count(net) == 0) + net_map[net] = wire; + else + module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + } + + FOREACH_NETBUS_OF_NETLIST(nl, mi, netbus) + { + bool found_new_net = false; + for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { + net = netbus->ElementAtIndex(i); + if (net_map.count(net) == 0) + found_new_net = true; + if (i == netbus->RightIndex()) + break; + } + + if (found_new_net) + { + // log(" importing netbus %s.\n", netbus->Name()); + + RTLIL::Wire *wire = new RTLIL::Wire; + wire->name = RTLIL::escape_id(netbus->Name()); + wire->width = netbus->Size(); + wire->start_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); + while (module->count_id(wire->name)) + wire->name += "_"; + import_attributes(wire->attributes, port); + module->add(wire); + + for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { + if (netbus->ElementAtIndex(i)) { + net = netbus->ElementAtIndex(i); + RTLIL::SigBit bit(wire, i - wire->start_offset); + if (net_map.count(net) == 0) + net_map[net] = bit; + else + module->connections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + } + if (i == netbus->RightIndex()) + break; + } + } + else + { + // log(" skipping netbus %s.\n", netbus->Name()); + } + } + + FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) + { + log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); + + if (inst->Type() == PRIM_PWR) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S1)); + continue; + } + + if (inst->Type() == PRIM_GND) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S0)); + continue; + } + + if (inst->Type() == PRIM_X) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sx)); + continue; + } + + if (inst->Type() == PRIM_Z) { + module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sz)); + continue; + } + + if (inst->Type() == PRIM_AND || inst->Type() == PRIM_OR || inst->Type() == PRIM_XOR || inst->Type() == PRIM_XNOR) { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = inst->Type() == PRIM_AND ? "$and" : inst->Type() == PRIM_OR ? "$or" : + inst->Type() == PRIM_XOR ? "$xor" : "$xnor"; + cell->parameters["\\A_SIGNED"] = 0; + cell->parameters["\\B_SIGNED"] = 0; + cell->parameters["\\A_WIDTH"] = 1; + cell->parameters["\\B_WIDTH"] = 1; + cell->parameters["\\Y_WIDTH"] = 1; + cell->connections["\\A"] = net_map.at(inst->GetInput1()); + cell->connections["\\B"] = net_map.at(inst->GetInput2()); + cell->connections["\\Y"] = net_map.at(inst->GetOutput()); + module->add(cell); + continue; + } + + if (inst->Type() == PRIM_INV) { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$not"; + cell->parameters["\\A_SIGNED"] = 0; + cell->parameters["\\A_WIDTH"] = 1; + cell->parameters["\\Y_WIDTH"] = 1; + cell->connections["\\A"] = net_map.at(inst->GetInput()); + cell->connections["\\Y"] = net_map.at(inst->GetOutput()); + module->add(cell); + continue; + } + + if (inst->Type() == PRIM_MUX) { + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$mux"; + cell->parameters["\\WIDTH"] = 1; + cell->connections["\\A"] = net_map.at(inst->GetInput1()); + cell->connections["\\B"] = net_map.at(inst->GetInput2()); + cell->connections["\\S"] = net_map.at(inst->GetControl()); + cell->connections["\\Y"] = net_map.at(inst->GetOutput()); + module->add(cell); + continue; + } + + if (inst->Type() == PRIM_FADD) + { + RTLIL::Cell *cell1 = new RTLIL::Cell; + cell1->name = RTLIL::escape_id(NEW_ID); + cell1->type = "$add"; + cell1->parameters["\\A_SIGNED"] = 0; + cell1->parameters["\\B_SIGNED"] = 0; + cell1->parameters["\\A_WIDTH"] = 1; + cell1->parameters["\\B_WIDTH"] = 1; + cell1->parameters["\\Y_WIDTH"] = 2; + cell1->connections["\\A"] = net_map.at(inst->GetInput1()); + cell1->connections["\\B"] = net_map.at(inst->GetInput2()); + cell1->connections["\\Y"] = module->new_wire(2, NEW_ID); + module->add(cell1); + + RTLIL::Cell *cell2 = new RTLIL::Cell; + cell2->name = RTLIL::escape_id(inst->Name()); + cell2->type = "$add"; + cell2->parameters["\\A_SIGNED"] = 0; + cell2->parameters["\\B_SIGNED"] = 0; + cell2->parameters["\\A_WIDTH"] = 2; + cell2->parameters["\\B_WIDTH"] = 1; + cell2->parameters["\\Y_WIDTH"] = 2; + cell2->connections["\\A"] = cell1->connections["\\Y"]; + cell2->connections["\\B"] = net_map.at(inst->GetCin()); + cell2->connections["\\Y"] = net_map.at(inst->GetOutput()); + cell2->connections["\\Y"].append(net_map.at(inst->GetCout())); + module->add(cell2); + continue; + } + + if (inst->IsPrimitive()) + log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); + + nl_todo.insert(inst->View()); + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = RTLIL::escape_id(inst->View()->Owner()->Name()); + module->add(cell); + + PortRef *pr ; + FOREACH_PORTREF_OF_INST(inst, mi2, pr) { + // log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name()); + const char *port_name = pr->GetPort()->Name(); + int port_offset = 0; + if (pr->GetPort()->Bus()) { + port_name = pr->GetPort()->Bus()->Name(); + port_offset = pr->GetPort()->Bus()->IndexOf(pr->GetPort()) - + std::min(pr->GetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); + } + RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; + while (conn.width <= port_offset) + conn.append(RTLIL::State::Sz); + conn.replace(port_offset, net_map.at(pr->GetNet())); + } + } +} + +#endif /* VERIFIC_DIR */ + +struct VerificPass : public Pass { + VerificPass() : Pass("verific", "load Verilog and VHDL designs using Verific") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" verific {-vlog95|-vlog2k|-sv2005|-sv2009|-sv} ..\n"); + log("\n"); + log("Load the specified Verilog/SystemVerilog files into Verific.\n"); + log("\n"); + log("\n"); + log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008} ..\n"); + log("\n"); + log("Load the specified VHDL files into Verific.\n"); + log("\n"); + log("\n"); + log(" verific -import ..\n"); + log("\n"); + log("Elaborate the design for the sepcified top modules, import to Yosys and\n"); + log("reset the internal state of Verific.\n"); + log("\n"); + log("\n"); + log("Visit http://verific.com/ for more information on Verific.\n"); + log("\n"); + } +#ifdef VERIFIC_DIR + virtual void execute(std::vector args, RTLIL::Design *design) + { + log_header("Executing VERIFIC (loading Verilog and VHDL designs using the Verific library).\n"); + + Message::SetConsoleOutput(0); + Message::RegisterCallBackMsg(msg_func); + + if (args.size() > 1 && args[1] == "-vlog95") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::VERILOG_95)) + log_cmd_error("Reading `%s' in VERILOG_95 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vlog2k") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::VERILOG_2K)) + log_cmd_error("Reading `%s' in VERILOG_2K mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-sv2005") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::SYSTEM_VERILOG_2005)) + log_cmd_error("Reading `%s' in SYSTEM_VERILOG_2005 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-sv2009") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::SYSTEM_VERILOG_2009)) + log_cmd_error("Reading `%s' in SYSTEM_VERILOG_2009 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-sv") { + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!veri_file::Analyze(args[argidx].c_str(), veri_file::SYSTEM_VERILOG)) + log_cmd_error("Reading `%s' in SYSTEM_VERILOG mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl87") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_87)) + log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl93") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_93)) + log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl2k") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2K)) + log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-vhdl2008") { + vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + for (size_t argidx = 2; argidx < args.size(); argidx++) + if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2008)) + log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", args[argidx].c_str()); + return; + } + + if (args.size() > 1 && args[1] == "-import") + { + std::set nl_todo, nl_done; + + if (args.size() == 2) + log_cmd_error("No top module specified.\n"); + + for (size_t argidx = 2; argidx < args.size(); argidx++) { + if (veri_file::GetModule(args[argidx].c_str())) { + if (!veri_file::Elaborate(args[argidx].c_str())) + log_cmd_error("Elaboration of top module `%s' failed.\n", args[argidx].c_str()); + nl_todo.insert(Netlist::PresentDesign()); + } else { + if (!vhdl_file::Elaborate(args[argidx].c_str())) + log_cmd_error("Elaboration of top module `%s' failed.\n", args[argidx].c_str()); + nl_todo.insert(Netlist::PresentDesign()); + } + } + + while (!nl_todo.empty()) { + Netlist *nl = *nl_todo.begin(); + if (nl_done.count(nl) == 0) + import_netlist(design, nl, nl_todo); + nl_todo.erase(nl); + nl_done.insert(nl); + } + + Libset::Reset(); + return; + } + + log_cmd_error("Missing or unsupported mode parameter.\n"); + } +#else /* VERIFIC_DIR */ + virtual void execute(std::vector, RTLIL::Design *) { + log_cmd_error("This version of Yosys is built without Verific support.\n"); + } +#endif +} VerificPass; + -- cgit v1.2.3 From fdef064b1d8bbaff8d8f3f2dbf728132ef463010 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 03:02:27 +0100 Subject: 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 396eaf110..811289a4d 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 caadf1981..48f3e3921 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 { -- cgit v1.2.3 From c71791a1ffa566585317a01becd5c33ad452fe57 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 03:03:08 +0100 Subject: Improvements in verific command --- frontends/verific/verific.cc | 98 ++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 59 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 5c2b933cb..1b25fecac 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -220,7 +220,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName(), inst->View()->Owner()->Name()); + // log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); if (inst->Type() == PRIM_PWR) { module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S1)); @@ -242,77 +242,57 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_AND || inst->Type() == PRIM_OR || inst->Type() == PRIM_XOR || inst->Type() == PRIM_XNOR) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = inst->Type() == PRIM_AND ? "$and" : inst->Type() == PRIM_OR ? "$or" : - inst->Type() == PRIM_XOR ? "$xor" : "$xnor"; - cell->parameters["\\A_SIGNED"] = 0; - cell->parameters["\\B_SIGNED"] = 0; - cell->parameters["\\A_WIDTH"] = 1; - cell->parameters["\\B_WIDTH"] = 1; - cell->parameters["\\Y_WIDTH"] = 1; - cell->connections["\\A"] = net_map.at(inst->GetInput1()); - cell->connections["\\B"] = net_map.at(inst->GetInput2()); - cell->connections["\\Y"] = net_map.at(inst->GetOutput()); - module->add(cell); + if (inst->Type() == PRIM_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + continue; + } + + if (inst->Type() == PRIM_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + continue; + } + + if (inst->Type() == PRIM_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + continue; + } + + if (inst->Type() == PRIM_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); continue; } if (inst->Type() == PRIM_INV) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = "$not"; - cell->parameters["\\A_SIGNED"] = 0; - cell->parameters["\\A_WIDTH"] = 1; - cell->parameters["\\Y_WIDTH"] = 1; - cell->connections["\\A"] = net_map.at(inst->GetInput()); - cell->connections["\\Y"] = net_map.at(inst->GetOutput()); - module->add(cell); + module->addNot(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); continue; } if (inst->Type() == PRIM_MUX) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = "$mux"; - cell->parameters["\\WIDTH"] = 1; - cell->connections["\\A"] = net_map.at(inst->GetInput1()); - cell->connections["\\B"] = net_map.at(inst->GetInput2()); - cell->connections["\\S"] = net_map.at(inst->GetControl()); - cell->connections["\\Y"] = net_map.at(inst->GetOutput()); - module->add(cell); + module->addMux(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); continue; } if (inst->Type() == PRIM_FADD) { - RTLIL::Cell *cell1 = new RTLIL::Cell; - cell1->name = RTLIL::escape_id(NEW_ID); - cell1->type = "$add"; - cell1->parameters["\\A_SIGNED"] = 0; - cell1->parameters["\\B_SIGNED"] = 0; - cell1->parameters["\\A_WIDTH"] = 1; - cell1->parameters["\\B_WIDTH"] = 1; - cell1->parameters["\\Y_WIDTH"] = 2; - cell1->connections["\\A"] = net_map.at(inst->GetInput1()); - cell1->connections["\\B"] = net_map.at(inst->GetInput2()); - cell1->connections["\\Y"] = module->new_wire(2, NEW_ID); - module->add(cell1); - - RTLIL::Cell *cell2 = new RTLIL::Cell; - cell2->name = RTLIL::escape_id(inst->Name()); - cell2->type = "$add"; - cell2->parameters["\\A_SIGNED"] = 0; - cell2->parameters["\\B_SIGNED"] = 0; - cell2->parameters["\\A_WIDTH"] = 2; - cell2->parameters["\\B_WIDTH"] = 1; - cell2->parameters["\\Y_WIDTH"] = 2; - cell2->connections["\\A"] = cell1->connections["\\Y"]; - cell2->connections["\\B"] = net_map.at(inst->GetCin()); - cell2->connections["\\Y"] = net_map.at(inst->GetOutput()); - cell2->connections["\\Y"].append(net_map.at(inst->GetCout())); - module->add(cell2); + RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); + RTLIL::SigSpec y = net_map.at(inst->GetOutput()); + y.append(net_map.at(inst->GetCout())); + + module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); + module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + continue; + } + + if (inst->Type() == PRIM_DFFRS) + { + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec d = module->new_wire(1, NEW_ID); + + module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); + module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); + module->addAnd(NEW_ID, tmp1, tmp2, d); + module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); continue; } -- cgit v1.2.3 From 5a15539c9b4280b1ed3a77a131f3197a1127404f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 12:06:57 +0100 Subject: Improved verific command (added support for some operators) --- frontends/verific/verific.cc | 162 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 160 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1b25fecac..c78d19f24 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -55,7 +55,7 @@ static void msg_func(msg_type_t msg_type, const char *message_id, linefile_type log("\n"); } -void import_attributes(std::map &attributes, DesignObj *obj) +static void import_attributes(std::map &attributes, DesignObj *obj) { MapIter mi; Att *attr; @@ -68,6 +68,61 @@ void import_attributes(std::map &attributes, Desi attributes[RTLIL::escape_id(attr->Key())] = RTLIL::Const(std::string(attr->Value())); } +static RTLIL::SigSpec operatorInput(Instance *inst, std::map &net_map) +{ + RTLIL::SigSpec sig; + for (unsigned i = 0; i < inst->InputSize(); i++) + if (inst->GetInputBit(i)) + sig.append(net_map.at(inst->GetInputBit(i))); + else + sig.append(RTLIL::State::Sz); + sig.optimize(); + return sig; +} + +static RTLIL::SigSpec operatorInput1(Instance *inst, std::map &net_map) +{ + RTLIL::SigSpec sig; + for (unsigned i = 0; i < inst->Input1Size(); i++) + if (inst->GetInput1Bit(i)) + sig.append(net_map.at(inst->GetInput1Bit(i))); + else + sig.append(RTLIL::State::Sz); + sig.optimize(); + return sig; +} + +static RTLIL::SigSpec operatorInput2(Instance *inst, std::map &net_map) +{ + RTLIL::SigSpec sig; + for (unsigned i = 0; i < inst->Input2Size(); i++) + if (inst->GetInput2Bit(i)) + sig.append(net_map.at(inst->GetInput2Bit(i))); + else + sig.append(RTLIL::State::Sz); + sig.optimize(); + return sig; +} + +static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, RTLIL::Module *module) +{ + RTLIL::SigSpec sig; + RTLIL::Wire *dummy_wire = NULL; + for (unsigned i = 0; i < inst->OutputSize(); i++) + if (inst->GetInput2Bit(i)) { + sig.append(net_map.at(inst->GetInput2Bit(i))); + dummy_wire = NULL; + } else { + if (dummy_wire == NULL) + dummy_wire = module->new_wire(1, NEW_ID); + else + dummy_wire->width++; + sig.append(RTLIL::SigSpec(dummy_wire, 1, dummy_wire->width - 1)); + } + sig.optimize(); + return sig; +} + static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set &nl_todo) { if (design->modules.count(RTLIL::escape_id(nl->Owner()->Name()))) @@ -296,6 +351,109 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setView()->IsSigned() + + if (inst->Type() == OPER_ADDER) { + module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_MULTIPLIER) { + module->addMul(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_DIVIDER) { + module->addDiv(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_MODULO) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + // FIXME: OPER_REMAINDER -- how is this different from OPER_MODULO ? + + if (inst->Type() == OPER_REMAINDER) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_SHIFT_LEFT) { + module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_SHIFT_RIGHT) { + module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + // FIXME: OPER_ROTATE_LEFT OPER_ROTATE_RIGHT -- are they $sshl / $sshr cells? + + if (inst->Type() == OPER_REDUCE_AND) { + module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_REDUCE_OR) { + module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_REDUCE_XOR) { + module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_REDUCE_NAND) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + continue; + } + + if (inst->Type() == OPER_REDUCE_NOR) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceOr(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + continue; + } + + if (inst->Type() == OPER_REDUCE_XNOR) { + module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_LESSTHAN) { + module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_EQUAL) { + module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_NEQUAL) { + module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + #undef IN + #undef IN1 + #undef IN2 + #undef OUT + #undef SIGNED + + if (inst->IsOperator()) + log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); + if (inst->IsPrimitive()) log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); @@ -354,7 +512,7 @@ struct VerificPass : public Pass { #ifdef VERIFIC_DIR virtual void execute(std::vector args, RTLIL::Design *design) { - log_header("Executing VERIFIC (loading Verilog and VHDL designs using the Verific library).\n"); + log_header("Executing VERIFIC (loading Verilog and VHDL designs using Verific).\n"); Message::SetConsoleOutput(0); Message::RegisterCallBackMsg(msg_func); -- cgit v1.2.3 From 78c64a64017dbc3e15aeac3246d5fc159555fbe2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 10 Mar 2014 12:07:26 +0100 Subject: 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 811289a4d..21fcae2b5 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 -- cgit v1.2.3 From 9b3d83359cc3f55049b5a48cb736a9a43bf04afc Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:35:46 +0100 Subject: - 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 3a886b1c8..59f936b01 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 5a4e091cf..b02287962 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 fd5fa86e1..4bf73358b 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; -- cgit v1.2.3 From f7c2cf6fe29fc452385c37f015e03febf650ecd3 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:35:53 +0100 Subject: - 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 2829e660f..24a634f65 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()) -- cgit v1.2.3 From 40e0b79495195eaa2bc6bf32e8d52a5aa956a2b4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:35:59 +0100 Subject: - 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 fb3d24996..6da363fc1 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; -- cgit v1.2.3 From 8111938e962b60294e51d5f0d10b6d1855bc1b91 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:07 +0100 Subject: - 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 c4c03352a..fbc3c1c39 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() { -- cgit v1.2.3 From 6698d67d2416069ea728b879db67b6ea0582cce4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:12 +0100 Subject: - 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 00a61ec0f..ce95cad4f 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include -- cgit v1.2.3 From c056217e72ff1e2da1340f97ad3a76f3ed486841 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:23 +0100 Subject: - 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 ee14ffbad..ab5cba11b 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 -- cgit v1.2.3 From f6579282d73aec055e2fc4ebebd1b6313da248fd Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:36:27 +0100 Subject: - 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 0467810e5..d8568fe94 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()); -- cgit v1.2.3 From 9327d434d522f888609e5f4a42a6e06f01864e79 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:37:14 +0100 Subject: - 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 385ee2c0a..45febc2f9 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 -- cgit v1.2.3 From 0fb044a58f7cc66364af3a0a53c8b5089e0149ad Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 14:38:01 +0100 Subject: - 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 f251d2b6d..77d6e29e5 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 a68ceccb4..c0d43a2c3 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 000000000..d3fb00873 --- /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 000000000..d6eaade05 --- /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 + -- cgit v1.2.3 From 8a0216bd9f81faf45e1ff463edcc6d82dfa20565 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 15:02:58 +0100 Subject: - 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 d488a9062..92f56b00a 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); } -- cgit v1.2.3 From 63ca8d3fe4273d9e07233f94037a63659d6d18e4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 15:07:37 +0100 Subject: - 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 c0d43a2c3..7bd8a450e 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 6d94d5c9b..c68b13f6c 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 -- cgit v1.2.3 From 2f2e76ac68dc8da8618ebbf602e2c871f5d4b1b8 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 19:50:02 +0100 Subject: - 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 d8568fe94..83035d329 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 24a634f65..286b750cc 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -45,6 +45,7 @@ #include #include #include +#include #include "blifparse.h" -- cgit v1.2.3 From 4d56e23e318a6739ec06ce74d81dfa1d940aef0f Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: - 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 7bd8a450e..82c09d058 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 -- cgit v1.2.3 From 113f129b348c48fff67242fe65906b3821ae7bd4 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: - 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 82c09d058..849860a33 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) -- cgit v1.2.3 From d091be401140088431ac2c1bf2bc97415e37c9ff Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:23:55 +0100 Subject: - 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 92f56b00a..4677f68bd 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); -- cgit v1.2.3 From 876c016904989bc54eafada1363e31f291854542 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: - 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 849860a33..ce9a99bc0 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': -- cgit v1.2.3 From 4fd1a4c12b8a57454bc6e7f3b7bba6a7aeade96c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 11:39:30 +0100 Subject: 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 8285875b8..541da483e 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 -- cgit v1.2.3 From bada3ee815c05933723a64234106ab68b7599568 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 11:59:58 +0100 Subject: 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 541da483e..e2c6303da 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 -- cgit v1.2.3 From fa75c8286e066ba4b73da94068662834cb671640 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 13:09:01 +0100 Subject: 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 2d46d1a8e..1d4da19ad 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) -- cgit v1.2.3 From 707b46956e7de08ae44ec1d8812fe0393e60457b Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 14:06:41 +0100 Subject: - 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 ae1ebbb56..b83ab8495 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 -- cgit v1.2.3 From 9992026a8d4482abd8fbae8cb246a87cbbbde364 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:06:57 +0100 Subject: Added support for `line compiler directive --- frontends/verilog/lexer.l | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 79f44b4a6..e3e5e4ab2 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -75,6 +75,17 @@ namespace VERILOG_FRONTEND { ln_stack.pop_back(); } +"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { + char *p = yytext + 5; + while (*p == ' ' || *p == '\t') p++; + frontend_verilog_yyset_lineno(atoi(p)); + while (*p && *p != ' ' && *p != '\t') p++; + while (*p == ' ' || *p == '\t') p++; + char *q = *p ? p + 1 : p; + while (*q && *q != '"') q++; + current_filename = std::string(p).substr(1, q-p-1); +} + "`file_notfound "[^\n]* { log_error("Can't open include file `%s'!\n", yytext + 15); } -- cgit v1.2.3 From 91704a78531bec2e3eea3ddf90eaedb28e1d696d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:24:24 +0100 Subject: Merged a few fixes for non-posix systems from github.com/Siesh1oo/yosys (see https://github.com/cliffordwolf/yosys/pull/28) --- 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 385ee2c0a..45febc2f9 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 0467810e5..83035d329 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -26,6 +26,8 @@ #include #include #include +#include +#include struct Vhdl2verilogPass : public Pass { Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } @@ -93,9 +95,12 @@ struct Vhdl2verilogPass : public Pass { log_error("For some reason mkdtemp() failed!\n"); if (!out_file.empty() && out_file[0] != '/') { - char *pwd = get_current_dir_name(); + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s", strerror(errno)); + log_abort(); + } out_file = pwd + ("/" + out_file); - free(pwd); } FILE *f = fopen(stringf("%s/files.list", tempdir_name).c_str(), "wt"); @@ -104,9 +109,12 @@ struct Vhdl2verilogPass : public Pass { if (file.empty()) continue; if (file[0] != '/') { - char *pwd = get_current_dir_name(); + char pwd [PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s", strerror(errno)); + log_abort(); + } file = pwd + ("/" + file); - free(pwd); } fprintf(f, "%s\n", file.c_str()); log("Adding '%s' to the file list.\n", file.c_str()); diff --git a/kernel/driver.cc b/kernel/driver.cc index 00a61ec0f..ce95cad4f 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 c4c03352a..fbc3c1c39 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 ee14ffbad..ab5cba11b 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 d488a9062..4677f68bd 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 fb3d24996..6da363fc1 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 2829e660f..286b750cc 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 3a886b1c8..59f936b01 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 5a4e091cf..b02287962 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 fd5fa86e1..4bf73358b 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; -- cgit v1.2.3 From 7aa2d746b76a354daedd4c8a7b4d8c15b1805b21 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:42:58 +0100 Subject: 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 a68ceccb4..abb473ba9 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 6d94d5c9b..c68b13f6c 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 -- cgit v1.2.3 From 9087ece97c20d76359fb23cfd7a0f13552c1f2fd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:52:37 +0100 Subject: 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 ae1ebbb56..85d580ce8 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 -- cgit v1.2.3 From 59d68e158281983c6b18914fb29c09b130552479 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 19:39:01 +0100 Subject: - Makefile: resolve merge conflict. --- Makefile | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index abb473ba9..5f40b594f 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 \ -- cgit v1.2.3 From 4958559456c849811f213cb1b9e2beea61916e3c Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: - 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 5f40b594f..ad68ee1e3 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 -- cgit v1.2.3 From 4d56fbc150e5dcdefb1709d82aee91c9bb0d1227 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: - 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 ad68ee1e3..75a8f42bb 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) -- cgit v1.2.3 From c17ee0f6dd5bb6e53ff0bf6da4650972323fc82d Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: - 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 75a8f42bb..9f888c861 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': -- cgit v1.2.3 From 59239f65dda58980c5b20a4b4723cd725e740fda Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 22:00:49 +0100 Subject: - 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 ce9a99bc0..c1c81b8e7 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) -- cgit v1.2.3 From 94c1307c262e4b14f4a91b1bbcf9099ee6202bab Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Mar 2014 10:17:51 +0100 Subject: 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 abb473ba9..0acc0d0e4 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 45febc2f9..5a48a207c 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 bf72a31cb..81d029295 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 4677f68bd..caee73f88 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 000000000..7f7eac61f --- /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 000000000..0de4f07ca --- /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 000000000..383e894be --- /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 000000000..a75124627 --- /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 000000000..61dd0f679 --- /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 000000000..c48816284 --- /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 000000000..22816ff39 --- /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 000000000..93b6da31c --- /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 000000000..b1b3e31ba --- /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 000000000..7d140a1ff --- /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 000000000..7b2ddc554 --- /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 000000000..1cae4f5ad --- /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 000000000..cf7061014 --- /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 000000000..232368106 --- /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 000000000..fc9bb4391 --- /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 000000000..ebca294a7 --- /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 000000000..73fc7d4cf --- /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 000000000..be40a4c37 --- /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 000000000..4a25a9b49 --- /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 000000000..01d0dfe11 --- /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 000000000..eb8a7e4d3 --- /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 000000000..88fcf759a --- /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 000000000..2086e0bb2 --- /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 000000000..1da176028 --- /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 -- cgit v1.2.3 From 31528634796c15d0dcdb113ff730fa743663ca07 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Mar 2014 10:46:27 +0100 Subject: Fixed dependencies of "make test" --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0acc0d0e4..73051e524 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 -- cgit v1.2.3 From 8f3fa094817ec2c7df4253c690b5ccdb50a5b7d8 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 19:39:01 +0100 Subject: - Makefile: resolve merge conflict. --- Makefile | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 73051e524..8da8b4c5c 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 \ -- cgit v1.2.3 From 94bc11f0216010e54a8a4dd1fd390af97181f627 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: - 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 8da8b4c5c..1bafd2179 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: -- cgit v1.2.3 From 51bf1c871e89167228c406649201e608fd618d5c Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: - 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 1bafd2179..39b324b4d 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) -- cgit v1.2.3 From cfabaa16895d85ce21b0a1bf020f5ac1108cc614 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: - 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 39b324b4d..9460e3413 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': -- cgit v1.2.3 From 948d04c06c181a1c270017b6d7c819426a360303 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:12:52 +0100 Subject: - 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 01d0dfe11..59e65fb56 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 -- cgit v1.2.3 From 18367919ea64a0881da7cf439c99365a8807d3a3 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:15:53 +0100 Subject: - 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 ebca294a7..14aa39355 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); } -- cgit v1.2.3 From a8efb61e1f5221bdb013d90e83530392f61c13f8 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:16:55 +0100 Subject: - 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 6950fcbaa..7bbc258d3 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 \ -- cgit v1.2.3 From aead1b75e81b98332583ec859aa02c9757cc359f Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:18:07 +0100 Subject: - .gitignore: ignore qmake/OSX package libs/svgviewer/svgviewer.app --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 77d6e29e5..10491a3a1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /qtcreator.config /qtcreator.creator /qtcreator.creator.user +/libs/svgviewer/svgviewer.app /Makefile.conf /minisat /abc -- cgit v1.2.3 From 50423e3935095e535aa42aa17c80f0d178730e93 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:42:26 +0100 Subject: - 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 7bbc258d3..f7b466fdc 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 -- cgit v1.2.3 From 5a50760e2c327ded7a4da223fb16591febcb773f Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: - 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 f7b466fdc..b7bf4485c 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 ce95cad4f..da4962b82 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); - - 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; + 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 - 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 b582f98c9..f3d3f70ae 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 286b750cc..30e78e588 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 fdccb4bcc..bf37e5dae 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 937f41315..0ca601e3b 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()) { -- cgit v1.2.3 From 8127d5e8c35da6610dc9fd43cca66ff9ca41f078 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: - 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 ce95cad4f..da4962b82 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); - - 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; + 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 - 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 b582f98c9..f3d3f70ae 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 286b750cc..30e78e588 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 fdccb4bcc..bf37e5dae 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 937f41315..0ca601e3b 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()) { -- cgit v1.2.3 From a4d72de91dc017b299d6c11d67786274f1326133 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Mar 2014 23:28:10 +0100 Subject: 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 ebca294a7..14aa39355 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 01d0dfe11..df4155af3 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 88fcf759a..539ee23f8 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 -- cgit v1.2.3 From 89443aadbc6a20270de024f41ae1cc79ec75a8cf Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Tue, 11 Mar 2014 19:39:01 +0100 Subject: - Makefile: resolve merge conflict. --- Makefile | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 73051e524..8da8b4c5c 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 \ -- cgit v1.2.3 From cb4293624e11d61f64e51027fabc73fbcf504fa2 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: - 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 8da8b4c5c..1bafd2179 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: -- cgit v1.2.3 From 1cd7fbb6b8da3b56273426cf2fd13bec49ec0fed Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:12:20 +0100 Subject: - 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 1bafd2179..39b324b4d 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) -- cgit v1.2.3 From 4cad0462332f84b747ff4402fd95fec22fae1735 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: - 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 39b324b4d..9460e3413 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': -- cgit v1.2.3 From 989ef95a7f095e69c1f763b8854c5ed56c29ad9d Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:18:07 +0100 Subject: - .gitignore: ignore qmake/OSX package libs/svgviewer/svgviewer.app --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f251d2b6d..69d56bfac 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /qtcreator.config /qtcreator.creator /qtcreator.creator.user +/libs/svgviewer/svgviewer.app /Makefile.conf /abc /yosys -- cgit v1.2.3 From c621bfa746b1ca2d698b09d7b9e65da9d191a39b Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:42:26 +0100 Subject: - 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 9460e3413..1eef767b3 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 -- cgit v1.2.3 From 26895223a1b2528f8416d3d3ca19d540c38c3cfe Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: - 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 1eef767b3..035f7c5a4 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 -- cgit v1.2.3 From 1d0abb3ad2a85188eef6201e0a32acbcec1e78b3 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:06:46 +0100 Subject: - 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 035f7c5a4..39b324b4d 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 -- cgit v1.2.3 From 95e309b94d759c34173ef87f730814bbb73ebb9b Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Mon, 10 Mar 2014 20:27:39 +0100 Subject: - 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 39b324b4d..9460e3413 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': -- cgit v1.2.3 From ed2c577592e1547e63a840b1e7a119c20387a7bd Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 14:42:26 +0100 Subject: - 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 9460e3413..1eef767b3 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 -- cgit v1.2.3 From 49c0bfa3adcceb25886d879c54c08ba9b93f6488 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Wed, 12 Mar 2014 18:33:37 +0100 Subject: - 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 1eef767b3..035f7c5a4 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 -- cgit v1.2.3 From 0e30f16af1f27543a138898c3398feddd3e92457 Mon Sep 17 00:00:00 2001 From: Siesh1oo Date: Thu, 13 Mar 2014 11:34:21 +0100 Subject: - 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 73051e524..5e6df2425 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 000000000..d3fb00873 --- /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 000000000..ed8fc8966 --- /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 + -- cgit v1.2.3 From fad8558eb5ecbd62e2032a48c537bfecfad3dfc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 12:48:10 +0100 Subject: Merged OSX fixes from Siesh1oo with some modifications --- 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 73051e524..325f25a17 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 c585d40c5..b3d96b28e 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 13c2676db..8e9efa173 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -27,6 +27,7 @@ */ #include "verilog_frontend.h" +#include "kernel/compatibility.h" #include "kernel/register.h" #include "kernel/log.h" #include "libs/sha1/sha1.h" diff --git a/kernel/compatibility.cc b/kernel/compatibility.cc new file mode 100644 index 000000000..2ef023eb3 --- /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 000000000..58e0b52e9 --- /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 779f93737..b2c92e4e1 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 ab5cba11b..511afaac0 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 21fcae2b5..7259845a0 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 b92d91f8b..b46f84a66 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 0ca601e3b..69ffb9230 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" -- cgit v1.2.3 From 542afc562fa8b828f3c87e9dbe47a373ac09f147 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 12:55:15 +0100 Subject: 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 58e0b52e9..c7603c8a5 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 -- cgit v1.2.3 From 7a1ac1120351d5cf0de2c9173fb7353795b0137e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 13:12:06 +0100 Subject: Added test_navre.ys for verific frontend --- frontends/verific/test_navre.ys | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 frontends/verific/test_navre.ys diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys new file mode 100644 index 000000000..9e11cde05 --- /dev/null +++ b/frontends/verific/test_navre.ys @@ -0,0 +1,17 @@ +verific -vlog2k ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +verific -import softusb_navre + +flatten softusb_navre +rename softusb_navre gate + +read_verilog ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +cd softusb_navre; proc; opt; memory; opt; cd .. +rename softusb_navre gold + +expose -dff -shared gold gate +miter -equiv -ignore_gold_x -make_assert -make_outputs -make_outcmp gold gate miter + +cd miter +flatten; opt -undriven +sat -verify -maxsteps 5 -set-init-undef -set-def-inputs -prove-asserts -tempinduct-def \ + -seq 1 -set-at 1 in_rst 1 # -show-inputs -show-outputs -- cgit v1.2.3 From 34e54cda5b45fb96cd44597622c3cba00e410265 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 13:12:49 +0100 Subject: 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 d18a220d3..87bff4c48 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))); -- cgit v1.2.3 From 6a53bc7b271662dfc67f055917578ef8c1949fd6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 17:34:31 +0100 Subject: Copy Verific vdbs files to Yosys "share" data directory --- 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 325f25a17..45bdc47ac 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 74a669ef4..eca23e58c 100644 --- a/frontends/verific/Makefile.inc +++ b/frontends/verific/Makefile.inc @@ -1 +1,16 @@ + OBJS += frontends/verific/verific.o + +ifeq ($(ENABLE_VERIFIC),1) + +EXTRA_TARGETS += share/verific + +share/verific: + rm -rf share/verific.new + mkdir -p share/verific.new + cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs share/verific.new/vhdl_vdbs_1993 + cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008 share/verific.new/vhdl_vdbs_2008 + mv share/verific.new share/verific + +endif + diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c78d19f24..bc6abc5f8 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -27,7 +27,7 @@ #include #include -#ifdef VERIFIC_DIR +#ifdef YOSYS_ENABLE_VERIFIC #include "veri_file.h" #include "vhdl_file.h" @@ -482,7 +482,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set args, RTLIL::Design *design) { log_header("Executing VERIFIC (loading Verilog and VHDL designs using Verific).\n"); @@ -553,7 +553,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl87") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_87)) log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", args[argidx].c_str()); @@ -561,7 +561,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl93") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_93)) log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", args[argidx].c_str()); @@ -569,7 +569,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl2k") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2K)) log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", args[argidx].c_str()); @@ -577,7 +577,7 @@ struct VerificPass : public Pass { } if (args.size() > 1 && args[1] == "-vhdl2008") { - vhdl_file::SetDefaultLibraryPath(VERIFIC_DIR "/vhdl_packages/vdbs"); + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); for (size_t argidx = 2; argidx < args.size(); argidx++) if (!vhdl_file::Analyze(args[argidx].c_str(), "work", vhdl_file::VHDL_2008)) log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", args[argidx].c_str()); @@ -617,7 +617,7 @@ struct VerificPass : public Pass { log_cmd_error("Missing or unsupported mode parameter.\n"); } -#else /* VERIFIC_DIR */ +#else /* YOSYS_ENABLE_VERIFIC */ virtual void execute(std::vector, RTLIL::Design *) { log_cmd_error("This version of Yosys is built without Verific support.\n"); } -- cgit v1.2.3 From 9a1accf692adfb9f0f505a1f7e7646731fff10d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 18:21:00 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 75 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index bc6abc5f8..455bf8170 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -71,7 +71,7 @@ static void import_attributes(std::map &attribute static RTLIL::SigSpec operatorInput(Instance *inst, std::map &net_map) { RTLIL::SigSpec sig; - for (unsigned i = 0; i < inst->InputSize(); i++) + for (int i = int(inst->InputSize())-1; i >= 0; i--) if (inst->GetInputBit(i)) sig.append(net_map.at(inst->GetInputBit(i))); else @@ -83,7 +83,7 @@ static RTLIL::SigSpec operatorInput(Instance *inst, std::map &net_map) { RTLIL::SigSpec sig; - for (unsigned i = 0; i < inst->Input1Size(); i++) + for (int i = int(inst->Input1Size())-1; i >= 0; i--) if (inst->GetInput1Bit(i)) sig.append(net_map.at(inst->GetInput1Bit(i))); else @@ -95,7 +95,7 @@ static RTLIL::SigSpec operatorInput1(Instance *inst, std::map &net_map) { RTLIL::SigSpec sig; - for (unsigned i = 0; i < inst->Input2Size(); i++) + for (int i = int(inst->Input2Size())-1; i >= 0; i--) if (inst->GetInput2Bit(i)) sig.append(net_map.at(inst->GetInput2Bit(i))); else @@ -108,9 +108,9 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::mapOutputSize(); i++) - if (inst->GetInput2Bit(i)) { - sig.append(net_map.at(inst->GetInput2Bit(i))); + for (int i = int(inst->OutputSize())-1; i >= 0; i--) + if (inst->GetOutputBit(i)) { + sig.append(net_map.at(inst->GetOutputBit(i))); dummy_wire = NULL; } else { if (dummy_wire == NULL) @@ -377,8 +377,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_REMAINDER) { module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); continue; @@ -394,8 +392,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_REDUCE_AND) { module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); continue; @@ -435,6 +431,60 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_WIDE_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_NAND) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_NOR) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_BUF) { + module->addPos(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_WIDE_INV) { + module->addNot(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_MINUS) { + module->addSub(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + continue; + } + + if (inst->Type() == OPER_UMINUS) { + module->addNeg(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + continue; + } + if (inst->Type() == OPER_EQUAL) { module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); continue; @@ -445,6 +495,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_WIDE_MUX) { + module->addMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); + continue; + } + #undef IN #undef IN1 #undef IN2 -- cgit v1.2.3 From 77e5968323e76dd8f5dec431cadd95c69d77dc94 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 11:45:44 +0100 Subject: 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 7259845a0..420f528a3 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 48f3e3921..e55a88eba 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 { -- cgit v1.2.3 From 0ac915a757a10f50fd74e18365cbcf351885c162 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 11:46:13 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 560 ++++++++++++++++++++++++++----------------- 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 455bf8170..b10b3326e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -29,12 +29,18 @@ #ifdef YOSYS_ENABLE_VERIFIC +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverloaded-virtual" + #include "veri_file.h" #include "vhdl_file.h" -#include "VeriWrite.h" +#include "VeriModule.h" +#include "VhdlUnits.h" #include "DataBase.h" #include "Message.h" +#pragma clang diagnostic pop + #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif @@ -123,13 +129,288 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &nl_todo) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, Instance *inst) +{ + if (inst->Type() == PRIM_AND) { + module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_OR) { + module->addOrGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_XOR) { + module->addXorGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_INV) { + module->addInvGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_MUX) { + module->addMuxGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_FADD) + { + RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); + RTLIL::SigSpec y = net_map.at(inst->GetOutput()); + y.append(net_map.at(inst->GetCout())); + + module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); + module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + return true; + } + + if (inst->Type() == PRIM_DFFRS) + { + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec d = module->new_wire(1, NEW_ID); + + module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); + module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); + module->addAnd(NEW_ID, tmp1, tmp2, d); + module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); + return true; + } + + return false; +} + +static bool import_netlist_instance_cells(RTLIL::Module *module, std::map &net_map, Instance *inst) +{ + if (inst->Type() == PRIM_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_INV) { + module->addNot(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_MUX) { + module->addMux(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + + if (inst->Type() == PRIM_FADD) + { + RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); + RTLIL::SigSpec y = net_map.at(inst->GetOutput()); + y.append(net_map.at(inst->GetCout())); + + module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); + module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + return true; + } + + if (inst->Type() == PRIM_DFFRS) + { + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec d = module->new_wire(1, NEW_ID); + + module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); + module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); + module->addAnd(NEW_ID, tmp1, tmp2, d); + module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); + return true; + } + + #define IN operatorInput(inst, net_map) + #define IN1 operatorInput1(inst, net_map) + #define IN2 operatorInput2(inst, net_map) + #define OUT operatorOutput(inst, net_map, module) + #define SIGNED inst->View()->IsSigned() + +#if 0 + if (inst->Type() == OPER_ADDER) { + module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_MULTIPLIER) { + module->addMul(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_DIVIDER) { + module->addDiv(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_MODULO) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REMAINDER) { + module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_SHIFT_LEFT) { + module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_SHIFT_RIGHT) { + module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_AND) { + module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_OR) { + module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_XOR) { + module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_REDUCE_NAND) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + return true; + } + + if (inst->Type() == OPER_REDUCE_NOR) { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addReduceOr(NEW_ID, IN, tmp, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + return true; + } + + if (inst->Type() == OPER_REDUCE_XNOR) { + module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_LESSTHAN) { + module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_AND) { + module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_OR) { + module->addOr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_XOR) { + module->addXor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_NAND) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_NOR) { + RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); + module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); + module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_XNOR) { + module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_BUF) { + module->addPos(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_INV) { + module->addNot(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_MINUS) { + module->addSub(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_UMINUS) { + module->addNeg(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_EQUAL) { + module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_NEQUAL) { + module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + return true; + } + + if (inst->Type() == OPER_WIDE_MUX) { + module->addMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); + return true; + } +#endif + + #undef IN + #undef IN1 + #undef IN2 + #undef OUT + #undef SIGNED + + return false; +} + +static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set &nl_todo, bool mode_gates) { - if (design->modules.count(RTLIL::escape_id(nl->Owner()->Name()))) - log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); - + std::string module_name = nl->IsOperator() ? std::string("$verific$") + nl->Owner()->Name() : RTLIL::escape_id(nl->Owner()->Name()); + + if (design->modules.count(module_name)) { + if (!nl->IsOperator()) + log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); + return; + } + RTLIL::Module *module = new RTLIL::Module; - module->name = RTLIL::escape_id(nl->Owner()->Name()); + module->name = module_name; design->modules[module->name] = module; log("Importing module %s.\n", RTLIL::id2cstr(module->name)); @@ -297,217 +578,15 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_AND) { - module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_OR) { - module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_XOR) { - module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_XNOR) { - module->addXnor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_INV) { - module->addNot(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_MUX) { - module->addMux(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); - continue; - } - - if (inst->Type() == PRIM_FADD) - { - RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = net_map.at(inst->GetOutput()); - y.append(net_map.at(inst->GetCout())); - - module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); - module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); - continue; - } - - if (inst->Type() == PRIM_DFFRS) - { - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec d = module->new_wire(1, NEW_ID); - - module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); - module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); - module->addAnd(NEW_ID, tmp1, tmp2, d); - module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); - continue; - } - - #define IN operatorInput(inst, net_map) - #define IN1 operatorInput1(inst, net_map) - #define IN2 operatorInput2(inst, net_map) - #define OUT operatorOutput(inst, net_map, module) - #define SIGNED inst->View()->IsSigned() - - if (inst->Type() == OPER_ADDER) { - module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_MULTIPLIER) { - module->addMul(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_DIVIDER) { - module->addDiv(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_MODULO) { - module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REMAINDER) { - module->addMod(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_SHIFT_LEFT) { - module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_SHIFT_RIGHT) { - module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_AND) { - module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_OR) { - module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_XOR) { - module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_REDUCE_NAND) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); - continue; - } - - if (inst->Type() == OPER_REDUCE_NOR) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceOr(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); - continue; - } - - if (inst->Type() == OPER_REDUCE_XNOR) { - module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_LESSTHAN) { - module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_AND) { - module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_OR) { - module->addOr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_XOR) { - module->addXor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_NAND) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_NOR) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - continue; + if (!mode_gates) { + if (import_netlist_instance_cells(module, net_map, inst)) + continue; + if (inst->IsOperator()) + log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); } - if (inst->Type() == OPER_WIDE_XNOR) { - module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + if (import_netlist_instance_gates(module, net_map, inst)) continue; - } - - if (inst->Type() == OPER_WIDE_BUF) { - module->addPos(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_INV) { - module->addNot(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_MINUS) { - module->addSub(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_UMINUS) { - module->addNeg(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_EQUAL) { - module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_NEQUAL) { - module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); - continue; - } - - if (inst->Type() == OPER_WIDE_MUX) { - module->addMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); - continue; - } - - #undef IN - #undef IN1 - #undef IN2 - #undef OUT - #undef SIGNED - - if (inst->IsOperator()) - log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); if (inst->IsPrimitive()) log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); @@ -516,7 +595,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(inst->Name()); - cell->type = RTLIL::escape_id(inst->View()->Owner()->Name()); + cell->type = inst->IsOperator() ? std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()); module->add(cell); PortRef *pr ; @@ -555,11 +634,11 @@ struct VerificPass : public Pass { log("Load the specified VHDL files into Verific.\n"); log("\n"); log("\n"); - log(" verific -import ..\n"); + log(" verific -import [-gates] {-all | ..}\n"); log("\n"); log("Elaborate the design for the sepcified top modules, import to Yosys and\n"); - log("reset the internal state of Verific.\n"); - log("\n"); + log("reset the internal state of Verific. A gate-level netlist is created\n"); + log("when called with -gates.\n"); log("\n"); log("Visit http://verific.com/ for more information on Verific.\n"); log("\n"); @@ -642,11 +721,48 @@ struct VerificPass : public Pass { if (args.size() > 1 && args[1] == "-import") { std::set nl_todo, nl_done; + bool mode_all = false, mode_gates = false; - if (args.size() == 2) - log_cmd_error("No top module specified.\n"); + size_t argidx = 2; + for (; argidx < args.size(); argidx++) { + if (args[argidx] == "-all") { + mode_all = true; + continue; + } + if (args[argidx] == "-gates") { + mode_gates = true; + continue; + } + break; + } + + if (argidx > args.size() && args[argidx].substr(0, 1) == "-") + cmd_error(args, argidx, "unkown option"); + + if (mode_all) + { + if (argidx != args.size()) + log_cmd_error("Got -all and an explicit list of top modules.\n"); + + MapIter m1, m2, m3; + VeriModule *mod; + FOREACH_VERILOG_MODULE(m1, mod) + args.push_back(mod->Name()); + + VhdlLibrary *lib; + VhdlPrimaryUnit *primunit; + FOREACH_VHDL_LIBRARY(m1, lib) + FOREACH_VHDL_PRIMARY_UNIT(lib, m2, primunit) { + if (primunit->IsPackageDecl()) + continue; + args.push_back(primunit->Name()); + } + } + else + if (argidx == args.size()) + log_cmd_error("No top module specified.\n"); - for (size_t argidx = 2; argidx < args.size(); argidx++) { + for (; argidx < args.size(); argidx++) { if (veri_file::GetModule(args[argidx].c_str())) { if (!veri_file::Elaborate(args[argidx].c_str())) log_cmd_error("Elaboration of top module `%s' failed.\n", args[argidx].c_str()); @@ -661,7 +777,7 @@ struct VerificPass : public Pass { while (!nl_todo.empty()) { Netlist *nl = *nl_todo.begin(); if (nl_done.count(nl) == 0) - import_netlist(design, nl, nl_todo); + import_netlist(design, nl, nl_todo, mode_gates); nl_todo.erase(nl); nl_done.insert(nl); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 420f528a3..ee73ebe44 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 0e6c357c7..fafd044d8 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 } -- cgit v1.2.3 From 5da9558fa8a6be6e98eb0a7a7d0c6dd8bd86347f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 16:39:50 +0100 Subject: 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 fbc3c1c39..5fbd2fc68 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) { -- cgit v1.2.3 From e37d672ae7dc47952bac483afb85aae32cb727f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 14 Mar 2014 16:40:25 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 51 +++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index b10b3326e..59fce136a 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -129,7 +129,7 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, Instance *inst) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, std::map&, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -183,7 +183,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, Instance *inst) +static bool import_netlist_instance_cells(RTLIL::Module *module, std::map &net_map, std::map &const_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -245,9 +245,19 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapView()->IsSigned() -#if 0 if (inst->Type() == OPER_ADDER) { - module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + RTLIL::SigSpec out = OUT; + Net *cin = inst->GetNet(inst->View()->GetPort("cin")); + Net *cout = inst->GetNet(inst->View()->GetPort("cout")); + if (cout != NULL) + out.append(net_map.at(cout)); + if (const_map.count(cin) && const_map.at(cin) == RTLIL::State::S0) { + module->addAdd(RTLIL::escape_id(inst->Name()) + "_", IN1, IN2, out, SIGNED); + } else { + RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); + module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(cin), out, false); + } return true; } @@ -282,36 +292,36 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_REDUCE_AND) { - module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_REDUCE_OR) { - module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceOr(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_REDUCE_XOR) { - module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceXor(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_REDUCE_NAND) { RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } if (inst->Type() == OPER_REDUCE_NOR) { RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); module->addReduceOr(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, OUT); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } if (inst->Type() == OPER_REDUCE_XNOR) { - module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, OUT, SIGNED); + module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } @@ -388,7 +398,6 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapaddMux(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetControl()), OUT); return true; } -#endif #undef IN #undef IN1 @@ -416,6 +425,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname)); std::map net_map; + std::map const_map; MapIter mi, mi2; Port *port; @@ -554,6 +564,21 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_PWR) + const_map[inst->GetOutput()] = RTLIL::State::S1; + + if (inst->Type() == PRIM_GND) + const_map[inst->GetOutput()] = RTLIL::State::S1; + + if (inst->Type() == PRIM_X) + const_map[inst->GetOutput()] = RTLIL::State::S1; + + if (inst->Type() == PRIM_Z) + const_map[inst->GetOutput()] = RTLIL::State::S1; + } + FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) { // log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); @@ -579,13 +604,13 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); } - if (import_netlist_instance_gates(module, net_map, inst)) + if (import_netlist_instance_gates(module, net_map, const_map, inst)) continue; if (inst->IsPrimitive()) -- cgit v1.2.3 From b7c71d92f6003dcd626f58a0cf06f43c6a3b8d4c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 14:35:29 +0100 Subject: 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 ee73ebe44..072910e30 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 e55a88eba..44142bf29 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 { -- cgit v1.2.3 From 1d00ad9d4d241ffaa7cce35d7afc03d06521b15e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 14:36:11 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 62 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 59fce136a..30437437b 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -129,7 +129,7 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, std::map&, Instance *inst) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, std::map &const_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -158,25 +158,32 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_FADD) { - RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = net_map.at(inst->GetOutput()); - y.append(net_map.at(inst->GetCout())); - - module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); - module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); + RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); + RTLIL::SigSpec x = net_map.at(inst->GetCout()), y = net_map.at(inst->GetOutput()); + RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp3 = module->new_wire(1, NEW_ID); + module->addXorGate(NEW_ID, a, b, tmp1); + module->addXorGate(RTLIL::escape_id(inst->Name()), tmp1, c, y); + module->addAndGate(NEW_ID, tmp1, c, tmp2); + module->addAndGate(NEW_ID, a, b, tmp3); + module->addOrGate(NEW_ID, tmp2, tmp3, x); return true; } if (inst->Type() == PRIM_DFFRS) { - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec d = module->new_wire(1, NEW_ID); - - module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); - module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); - module->addAnd(NEW_ID, tmp1, tmp2, d); - module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); + if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0 && const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + module->addDffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + else if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0) + module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); + else if (const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); + else + module->addDffsrGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); return true; } @@ -228,15 +235,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_DFFRS) { - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec d = module->new_wire(1, NEW_ID); - - module->addOr(NEW_ID, net_map.at(inst->GetInput()), net_map.at(inst->GetSet()), tmp1); - module->addNot(NEW_ID, net_map.at(inst->GetReset()), tmp2); - module->addAnd(NEW_ID, tmp1, tmp2, d); - module->addDff(NEW_ID, net_map.at(inst->GetClock()), d, net_map.at(inst->GetOutput())); - return true; + // FIXME } #define IN operatorInput(inst, net_map) @@ -247,16 +246,14 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_ADDER) { RTLIL::SigSpec out = OUT; - Net *cin = inst->GetNet(inst->View()->GetPort("cin")); - Net *cout = inst->GetNet(inst->View()->GetPort("cout")); - if (cout != NULL) - out.append(net_map.at(cout)); - if (const_map.count(cin) && const_map.at(cin) == RTLIL::State::S0) { + if (inst->GetCout() != NULL) + out.append(net_map.at(inst->GetCout())); + if (const_map.count(inst->GetCin()) && const_map.at(inst->GetCin()) == RTLIL::State::S0) { module->addAdd(RTLIL::escape_id(inst->Name()) + "_", IN1, IN2, out, SIGNED); } else { RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); - module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(cin), out, false); + module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetCin()), out, false); } return true; } @@ -634,8 +631,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; - while (conn.width <= port_offset) + while (conn.width <= port_offset) { + if (pr->GetPort()->GetDir() != DIR_IN) + conn.append(module->new_wire(port_offset - conn.width, NEW_ID)); conn.append(RTLIL::State::Sz); + } conn.replace(port_offset, net_map.at(pr->GetNet())); } } -- cgit v1.2.3 From fc2c821407fde02248bb475c432df5bb89a1bd1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 15:31:54 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 30437437b..4564d7425 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -249,9 +249,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapGetCout() != NULL) out.append(net_map.at(inst->GetCout())); if (const_map.count(inst->GetCin()) && const_map.at(inst->GetCin()) == RTLIL::State::S0) { - module->addAdd(RTLIL::escape_id(inst->Name()) + "_", IN1, IN2, out, SIGNED); + module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, out, SIGNED); } else { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); + RTLIL::SigSpec tmp = module->new_wire(out.width, NEW_ID); module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetCin()), out, false); } @@ -278,6 +278,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_SHIFT_LEFT) { module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; @@ -287,6 +290,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapaddShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; } +#endif if (inst->Type() == OPER_REDUCE_AND) { module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); @@ -322,10 +326,14 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_LESSTHAN) { module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; } +#endif if (inst->Type() == OPER_WIDE_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); @@ -382,12 +390,12 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_EQUAL) { - module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + module->addEq(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); return true; } if (inst->Type() == OPER_NEQUAL) { - module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + module->addNe(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); return true; } @@ -567,13 +575,13 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetOutput()] = RTLIL::State::S1; if (inst->Type() == PRIM_GND) - const_map[inst->GetOutput()] = RTLIL::State::S1; + const_map[inst->GetOutput()] = RTLIL::State::S0; if (inst->Type() == PRIM_X) - const_map[inst->GetOutput()] = RTLIL::State::S1; + const_map[inst->GetOutput()] = RTLIL::State::Sx; if (inst->Type() == PRIM_Z) - const_map[inst->GetOutput()] = RTLIL::State::S1; + const_map[inst->GetOutput()] = RTLIL::State::Sz; } FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) -- cgit v1.2.3 From 0ebee4c8e7743004ba0b7af714f3b1aff301bc61 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 22:51:12 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 55 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4564d7425..0e203a267 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -278,19 +278,22 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_SHIFT_LEFT) { - module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + module->addShl(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, false); return true; } if (inst->Type() == OPER_SHIFT_RIGHT) { - module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + Net *net_cin = inst->GetCin(); + Net *net_a_msb = inst->GetInput1Bit(0); + if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, false); + else if (net_cin == net_a_msb) + module->addSshr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, true); + else + log_error("Can't import Verific OPER_SHIFT_RIGHT instance %s: carry_in is neither 0 nor msb of left input\n", inst->Name()); return true; } -#endif if (inst->Type() == OPER_REDUCE_AND) { module->addReduceAnd(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); @@ -307,33 +310,21 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_REDUCE_NAND) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceAnd(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); - return true; - } - - if (inst->Type() == OPER_REDUCE_NOR) { - RTLIL::SigSpec tmp = module->new_wire(inst->OutputSize(), NEW_ID); - module->addReduceOr(NEW_ID, IN, tmp, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); - return true; - } - if (inst->Type() == OPER_REDUCE_XNOR) { module->addReduceXnor(RTLIL::escape_id(inst->Name()), IN, net_map.at(inst->GetOutput()), SIGNED); return true; } -#if 0 - // FIXME: tests/simple/sincos.v exposes a bug in this operator - if (inst->Type() == OPER_LESSTHAN) { - module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); + Net *net_cin = inst->GetCin(); + if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); + else if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S1) + module->addLe(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); + else + log_error("Can't import Verific OPER_LESSTHAN instance %s: carry_in is neither 0 nor 1\n", inst->Name()); return true; } -#endif if (inst->Type() == OPER_WIDE_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); @@ -350,20 +341,6 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_NAND) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addAnd(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - return true; - } - - if (inst->Type() == OPER_WIDE_NOR) { - RTLIL::SigSpec tmp1 = module->new_wire(inst->OutputSize(), NEW_ID); - module->addOr(NEW_ID, IN1, IN2, tmp1, SIGNED); - module->addNot(RTLIL::escape_id(inst->Name()), tmp1, OUT, SIGNED); - return true; - } - if (inst->Type() == OPER_WIDE_XNOR) { module->addXnor(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, SIGNED); return true; -- cgit v1.2.3 From ef1795a1e8df76873074a891f9132948181febcc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 15 Mar 2014 22:52:10 +0100 Subject: 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 072910e30..2b28f3232 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") -- cgit v1.2.3 From 7545510edcc1d9ab14e53cae285f1ef0dfb3d7d4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Mar 2014 16:06:03 +0100 Subject: Use Verific Net::{IsGnd,IsPwr} API in Verific bindings --- frontends/verific/verific.cc | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 0e203a267..bf24c8234 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -129,7 +129,7 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, std::map &const_map, Instance *inst) +static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAndGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -173,12 +173,12 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_DFFRS) { - if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0 && const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + if (inst->GetSet()->IsGnd() && inst->GetReset()->IsGnd()) module->addDffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); - else if (const_map.count(inst->GetSet()) && const_map.at(inst->GetSet()) == RTLIL::State::S0) + else if (inst->GetSet()->IsGnd()) module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); - else if (const_map.count(inst->GetReset()) && const_map.at(inst->GetReset()) == RTLIL::State::S0) + else if (inst->GetReset()->IsGnd()) module->addAdffGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); else @@ -190,7 +190,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::map &net_map, std::map &const_map, Instance *inst) +static bool import_netlist_instance_cells(RTLIL::Module *module, std::map &net_map, Instance *inst) { if (inst->Type() == PRIM_AND) { module->addAnd(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); @@ -248,7 +248,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapGetCout() != NULL) out.append(net_map.at(inst->GetCout())); - if (const_map.count(inst->GetCin()) && const_map.at(inst->GetCin()) == RTLIL::State::S0) { + if (inst->GetCin()->IsGnd()) { module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, out, SIGNED); } else { RTLIL::SigSpec tmp = module->new_wire(out.width, NEW_ID); @@ -286,7 +286,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_SHIFT_RIGHT) { Net *net_cin = inst->GetCin(); Net *net_a_msb = inst->GetInput1Bit(0); - if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + if (net_cin->IsGnd()) module->addShr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, false); else if (net_cin == net_a_msb) module->addSshr(RTLIL::escape_id(inst->Name()), IN1, IN2, OUT, true); @@ -317,9 +317,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_LESSTHAN) { Net *net_cin = inst->GetCin(); - if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S0) + if (net_cin->IsGnd()) module->addLt(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); - else if (const_map.count(net_cin) && const_map.at(net_cin) == RTLIL::State::S1) + else if (net_cin->IsPwr()) module->addLe(RTLIL::escape_id(inst->Name()), IN1, IN2, net_map.at(inst->GetOutput()), SIGNED); else log_error("Can't import Verific OPER_LESSTHAN instance %s: carry_in is neither 0 nor 1\n", inst->Name()); @@ -407,7 +407,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname)); std::map net_map; - std::map const_map; MapIter mi, mi2; Port *port; @@ -546,21 +545,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == PRIM_PWR) - const_map[inst->GetOutput()] = RTLIL::State::S1; - - if (inst->Type() == PRIM_GND) - const_map[inst->GetOutput()] = RTLIL::State::S0; - - if (inst->Type() == PRIM_X) - const_map[inst->GetOutput()] = RTLIL::State::Sx; - - if (inst->Type() == PRIM_Z) - const_map[inst->GetOutput()] = RTLIL::State::Sz; - } - FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) { // log(" importing cell %s (%s).\n", inst->Name(), inst->View()->Owner()->Name()); @@ -586,13 +570,13 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); } - if (import_netlist_instance_gates(module, net_map, const_map, inst)) + if (import_netlist_instance_gates(module, net_map, inst)) continue; if (inst->IsPrimitive()) -- cgit v1.2.3 From acda74c12cd39ae1a17d15f472728b49ad584e91 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Mar 2014 17:05:05 +0100 Subject: Added support for memories to verific bindings --- frontends/verific/test_navre.ys | 1 + frontends/verific/verific.cc | 86 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys index 9e11cde05..6f63761ab 100644 --- a/frontends/verific/test_navre.ys +++ b/frontends/verific/test_navre.ys @@ -1,6 +1,7 @@ verific -vlog2k ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v verific -import softusb_navre +memory softusb_navre flatten softusb_navre rename softusb_navre gate diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index bf24c8234..8b42ca8c1 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -408,12 +408,14 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set net_map; + SetIter si; MapIter mi, mi2; Port *port; PortBus *portbus; Net *net; NetBus *netbus; Instance *inst; + PortRef *pr; FOREACH_PORT_OF_NETLIST(nl, mi, port) { @@ -479,6 +481,33 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsRamNet()) + { + RTLIL::Memory *memory = new RTLIL::Memory; + memory->name = RTLIL::escape_id(net->Name()); + log_assert(module->count_id(memory->name) == 0); + module->memories[memory->name] = memory; + + int number_of_bits = net->Size(); + int bits_in_word = number_of_bits; + FOREACH_PORTREF_OF_NET(net, si, pr) { + if (pr->GetInst()->Type() == OPER_READ_PORT) { + bits_in_word = std::min(bits_in_word, pr->GetInst()->OutputSize()); + continue; + } + if (pr->GetInst()->Type() == OPER_WRITE_PORT || pr->GetInst()->Type() == OPER_CLOCKED_WRITE_PORT) { + bits_in_word = std::min(bits_in_word, pr->GetInst()->Input2Size()); + continue; + } + log_error("Verific RamNet %s is connected to unsupported instance type %s (%s).\n", + net->Name(), pr->GetInst()->View()->Owner()->Name(), pr->GetInst()->Name()); + } + + memory->width = bits_in_word; + memory->size = number_of_bits / bits_in_word; + continue; + } + if (net_map.count(net)) { // log(" skipping net %s.\n", net->Name()); continue; @@ -569,6 +598,62 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setType() == OPER_READ_PORT) + { + RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetInput()->Name())); + if (memory->width != int(inst->OutputSize())) + log_error("Import of asymetric memories from Verific is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name()); + + RTLIL::SigSpec addr = operatorInput1(inst, net_map); + RTLIL::SigSpec data = operatorOutput(inst, net_map, module); + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$memrd"; + cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\CLK_ENABLE"] = false; + cell->parameters["\\CLK_POLARITY"] = true; + cell->parameters["\\TRANSPARENT"] = false; + cell->parameters["\\ABITS"] = addr.width; + cell->parameters["\\WIDTH"] = data.width; + cell->connections["\\CLK"] = RTLIL::State::S0; + cell->connections["\\ADDR"] = addr; + cell->connections["\\DATA"] = data; + module->add(cell); + continue; + } + + if (inst->Type() == OPER_WRITE_PORT || inst->Type() == OPER_CLOCKED_WRITE_PORT) + { + RTLIL::Memory *memory = module->memories.at(RTLIL::escape_id(inst->GetOutput()->Name())); + if (memory->width != int(inst->Input2Size())) + log_error("Import of asymetric memories from Verific is not supported yet: %s %s\n", inst->Name(), inst->GetInput()->Name()); + + RTLIL::SigSpec addr = operatorInput1(inst, net_map); + RTLIL::SigSpec data = operatorInput2(inst, net_map); + + RTLIL::Cell *cell = new RTLIL::Cell; + cell->name = RTLIL::escape_id(inst->Name()); + cell->type = "$memwr"; + cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\CLK_ENABLE"] = false; + cell->parameters["\\CLK_POLARITY"] = true; + cell->parameters["\\PRIORITY"] = 0; + cell->parameters["\\ABITS"] = addr.width; + cell->parameters["\\WIDTH"] = data.width; + cell->connections["\\EN"] = net_map.at(inst->GetControl()); + cell->connections["\\CLK"] = RTLIL::State::S0; + cell->connections["\\ADDR"] = addr; + cell->connections["\\DATA"] = data; + module->add(cell); + + if (inst->Type() == OPER_CLOCKED_WRITE_PORT) { + cell->parameters["\\CLK_ENABLE"] = true; + cell->connections["\\CLK"] = net_map.at(inst->GetClock()); + } + continue; + } + if (!mode_gates) { if (import_netlist_instance_cells(module, net_map, inst)) continue; @@ -589,7 +674,6 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::settype = inst->IsOperator() ? std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()); module->add(cell); - PortRef *pr ; FOREACH_PORTREF_OF_INST(inst, mi2, pr) { // log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name()); const char *port_name = pr->GetPort()->Name(); -- cgit v1.2.3 From a67cd2d4a284cb945af6d477cc215cef7bdd22a8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 01:56:00 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 2 ++ 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 8b42ca8c1..84e5e6736 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -429,6 +429,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setattributes, port); module->add(wire); + wire->port_id = nl->IndexOf(port) + 1; + if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_IN) wire->port_input = true; if (port->GetDir() == DIR_INOUT || port->GetDir() == DIR_OUT) diff --git a/tests/simple/forgen01.v b/tests/simple/forgen01.v index 70ee7e667..8b7aa279d 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 4022f57cd..9bd38fcb3 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 fafd044d8..d459f988e 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 -- cgit v1.2.3 From 0b0dcfda7d6a860713e67f3a0c50f6636be687d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 02:43:53 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 55 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 84e5e6736..21aca6d43 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -110,6 +110,33 @@ static RTLIL::SigSpec operatorInput2(Instance *inst, std::map &net_map) +{ + PortBus *portbus = inst->View()->GetPortBus(portname); + if (portbus) { + RTLIL::SigSpec sig; + for (unsigned i = 0; i < portbus->Size(); i++) { + Net *net = inst->GetNet(portbus->ElementAtIndex(i)); + if (net) { + if (net->IsGnd()) + sig.append(RTLIL::State::S0); + else if (net->IsPwr()) + sig.append(RTLIL::State::S1); + else + sig.append(net_map.at(net)); + } else + sig.append(RTLIL::State::Sz); + } + sig.optimize(); + return sig; + } else { + Port *port = inst->View()->GetPort(portname); + log_assert(port != NULL); + Net *net = inst->GetNet(port); + return net_map.at(net); + } +} + static RTLIL::SigSpec operatorOutput(Instance *inst, std::map &net_map, RTLIL::Module *module) { RTLIL::SigSpec sig; @@ -235,7 +262,18 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_DFFRS) { - // FIXME + if (inst->GetSet()->IsGnd() && inst->GetReset()->IsGnd()) + module->addDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + else if (inst->GetSet()->IsGnd()) + module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); + else if (inst->GetReset()->IsGnd()) + module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); + else + module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetReset()), + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + return true; } #define IN operatorInput(inst, net_map) @@ -381,6 +419,16 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_DFFRS) { + RTLIL::SigSpec sig_set = operatorInport(inst, "set", net_map); + RTLIL::SigSpec sig_reset = operatorInport(inst, "reset", net_map); + if (sig_set.is_fully_const() && !sig_set.as_bool() && sig_set.is_fully_const() && !sig_set.as_bool()) { + module->addDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), IN, OUT); + } else + module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), sig_set, sig_reset, IN, OUT); + return true; + } + #undef IN #undef IN1 #undef IN2 @@ -527,10 +575,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setattributes, port); module->add(wire); - if (net_map.count(net) == 0) - net_map[net] = wire; - else - module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + net_map[net] = wire; } FOREACH_NETBUS_OF_NETLIST(nl, mi, netbus) -- cgit v1.2.3 From e164edc8d11356c0999c44dfdb52d0b2b337f212 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 14:41:41 +0100 Subject: 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 2b28f3232..1d53bc79b 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; -- cgit v1.2.3 From cdf12575651da53bff456617be2c5d1f825ba7fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Mar 2014 14:42:07 +0100 Subject: Progress in Verific bindings --- frontends/verific/verific.cc | 59 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 21aca6d43..1e15ef89f 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -163,11 +163,25 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NAND) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addAndGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_OR) { module->addOrGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; } + if (inst->Type() == PRIM_NOR) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addOrGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_XOR) { module->addXorGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; @@ -183,6 +197,11 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_TRI) { + module->addMuxGate(RTLIL::escape_id(inst->Name()), RTLIL::State::Sz, net_map.at(inst->GetInput()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_FADD) { RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); @@ -224,11 +243,25 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_NAND) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addAnd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_OR) { module->addOr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; } + if (inst->Type() == PRIM_NOR) { + RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + module->addOr(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); + module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_XOR) { module->addXor(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), net_map.at(inst->GetOutput())); return true; @@ -249,6 +282,11 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_TRI) { + module->addMux(RTLIL::escape_id(inst->Name()), RTLIL::State::Sz, net_map.at(inst->GetInput()), net_map.at(inst->GetControl()), net_map.at(inst->GetOutput())); + return true; + } + if (inst->Type() == PRIM_FADD) { RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); @@ -266,10 +304,10 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapaddDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); else if (inst->GetSet()->IsGnd()) module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetReset()), - net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), false); + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), RTLIL::State::S0); else if (inst->GetReset()->IsGnd()) module->addAdff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), - net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), true); + net_map.at(inst->GetInput()), net_map.at(inst->GetOutput()), RTLIL::State::S1); else module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), net_map.at(inst->GetSet()), net_map.at(inst->GetReset()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); @@ -419,6 +457,11 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_TRI) { + module->addMux(RTLIL::escape_id(inst->Name()), RTLIL::SigSpec(RTLIL::State::Sz, inst->OutputSize()), IN, net_map.at(inst->GetControl()), OUT); + return true; + } + if (inst->Type() == OPER_WIDE_DFFRS) { RTLIL::SigSpec sig_set = operatorInport(inst, "set", net_map); RTLIL::SigSpec sig_reset = operatorInport(inst, "reset", net_map); @@ -503,7 +546,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(portbus->Name()); wire->width = portbus->Size(); wire->start_offset = std::min(portbus->LeftIndex(), portbus->RightIndex()); - import_attributes(wire->attributes, port); + import_attributes(wire->attributes, portbus); module->add(wire); if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN) @@ -572,7 +615,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(net->Name()); while (module->count_id(wire->name)) wire->name += "_"; - import_attributes(wire->attributes, port); + import_attributes(wire->attributes, net); module->add(wire); net_map[net] = wire; @@ -599,7 +642,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setstart_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); while (module->count_id(wire->name)) wire->name += "_"; - import_attributes(wire->attributes, port); + import_attributes(wire->attributes, netbus); module->add(wire); for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { @@ -706,11 +749,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); + } else { + if (import_netlist_instance_gates(module, net_map, inst)) + continue; } - if (import_netlist_instance_gates(module, net_map, inst)) - continue; - if (inst->IsPrimitive()) log_error("Unsupported Verific primitive: %s\n", inst->View()->Owner()->Name()); -- cgit v1.2.3 From 9a34486bfbc8780d9a3af3164e99977e44d2a65f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 19 Mar 2014 10:05:01 +0100 Subject: Fixed performance problem in opt_mux with nets driven by many conflicting drivers --- passes/opt/opt_muxtree.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 47100869c..3292a46c8 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); + 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); } }; -- cgit v1.2.3 From 470c2455e471318f4528da597e0dd8c7499b47ce Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Mar 2014 13:26:52 +0100 Subject: Fixed mapping of Verific FADD primitive with unconnected outputs --- frontends/verific/verific.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1e15ef89f..cf72b7819 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -205,7 +205,8 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_FADD) { RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); - RTLIL::SigSpec x = net_map.at(inst->GetCout()), y = net_map.at(inst->GetOutput()); + RTLIL::SigSpec x = inst->GetCout() ? net_map.at(inst->GetCout()) : module->new_wire(1, NEW_ID); + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); RTLIL::SigSpec tmp3 = module->new_wire(1, NEW_ID); @@ -290,9 +291,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_FADD) { RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = net_map.at(inst->GetOutput()); - y.append(net_map.at(inst->GetCout())); - + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); + if (inst->GetCout()) + y.append(net_map.at(inst->GetCout())); module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); module->addAdd(RTLIL::escape_id(inst->Name()), a_plus_b, net_map.at(inst->GetCin()), y); return true; -- cgit v1.2.3 From a3b9692a68e88bbe3e32e0dbbd30c5e20f3800b7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Mar 2014 13:40:01 +0100 Subject: Fixed mapping of Verific WIDE_DFFRS operator --- frontends/verific/verific.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index cf72b7819..7411e9434 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -466,9 +466,9 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == OPER_WIDE_DFFRS) { RTLIL::SigSpec sig_set = operatorInport(inst, "set", net_map); RTLIL::SigSpec sig_reset = operatorInport(inst, "reset", net_map); - if (sig_set.is_fully_const() && !sig_set.as_bool() && sig_set.is_fully_const() && !sig_set.as_bool()) { + if (sig_set.is_fully_const() && !sig_set.as_bool() && sig_reset.is_fully_const() && !sig_reset.as_bool()) module->addDff(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), IN, OUT); - } else + else module->addDffsr(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetClock()), sig_set, sig_reset, IN, OUT); return true; } -- cgit v1.2.3 From d4a1b0af5b41d1360c74a73fb2ae92ee5f6c3bd0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 31 Mar 2014 14:14:40 +0200 Subject: 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 4a600af9d..769145838 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 1d53bc79b..1168102a3 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 44142bf29..b95a04422 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 10a809db6..5ecec7891 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 4436abfe7..908314f84 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 = ""; -- cgit v1.2.3 From e24797add0ceb0e8c3571cec9351a2b0120e9b19 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Apr 2014 21:06:55 +0200 Subject: 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 908314f84..16e6a1b21 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); -- cgit v1.2.3 From 7370ae01e978f0552f1565b88c0f44b402d09f4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Apr 2014 21:28:33 +0200 Subject: 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 16e6a1b21..be9d24f18 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); -- cgit v1.2.3 From b950197da1e0a53c7d220dd666ff3afbb61a1f18 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 4 Apr 2014 16:39:03 -0600 Subject: Remove non-POSIX 'rm -v'. --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 45bdc47ac..69fbf5222 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 -- cgit v1.2.3 From 66a5da5edc41a2b33413c965337001bb179d30f6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 4 Apr 2014 16:51:27 -0600 Subject: 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 539ee23f8..a84290279 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 13554c01b..f4a2ea83a 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 -- cgit v1.2.3 From 9c1e578afe6af40be4600c20c883fa016fc7fa26 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 11 Apr 2014 02:42:59 -0600 Subject: 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 9cc4720e2..c0eda0e84 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 675d24026..f735d46b2 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 d6ffd95a6..c305ecb05 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 -- cgit v1.2.3 From 12a3c05229a958a4ff3fb8ad782ceb28bab6dca1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Apr 2014 10:19:46 +0200 Subject: Updated README --- README | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/README b/README index 5a48a207c..d021c8864 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). -- cgit v1.2.3 From d2d48996c4d6a81226f5dbdb8c6acf108ce26a5b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:17:40 +0200 Subject: 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 000000000..e21683f98 --- /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 be40a4c37..a47c2ce83 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 a84290279..68c7c60ee 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 + -- cgit v1.2.3 From a1be4816d602548f4454242dc17f8a85ccaa91bd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:22:11 +0200 Subject: Replaced depricated %name-prefix= bison directive --- frontends/ilang/parser.y | 2 +- frontends/verilog/parser.y | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index ebb4d3095..6b41b0873 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -39,7 +39,7 @@ namespace ILANG_FRONTEND { using namespace ILANG_FRONTEND; %} -%name-prefix="rtlil_frontend_ilang_yy" +%name-prefix "rtlil_frontend_ilang_yy" %union { char *string; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 4726f1aa3..ed9be692b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -84,7 +84,7 @@ static void free_attr(std::map *al) %} -%name-prefix="frontend_verilog_yy" +%name-prefix "frontend_verilog_yy" %union { std::string *string; -- cgit v1.2.3 From 7188542155902bcf3880d482d472e91331f8a3ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:28:23 +0200 Subject: Fixed clang -Wdeprecated-register warnings --- frontends/ilang/lexer.l | 7 +++++++ frontends/verilog/lexer.l | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index 000919275..6557f98ab 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -23,9 +23,16 @@ */ %{ + +#ifdef __clang__ +// bison generates code using the 'register' storage class specifier +#pragma clang diagnostic ignored "-Wdeprecated-register" +#endif + #include "kernel/rtlil.h" #include "parser.tab.h" void update_autoidx(const char *p); + %} %option yylineno diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index e3e5e4ab2..226a26709 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -34,6 +34,11 @@ %{ +#ifdef __clang__ +// bison generates code using the 'register' storage class specifier +#pragma clang diagnostic ignored "-Wdeprecated-register" +#endif + #include "kernel/log.h" #include "verilog_frontend.h" #include "frontends/ast/ast.h" -- cgit v1.2.3 From 154c9f8b513db97d0397ac8d4c3c5c7276f6260f Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 2 May 2014 03:08:40 -0600 Subject: 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 a2c40bea4..691225805 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 b9df57d1c..ec402231f 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. -- cgit v1.2.3 From 75a5d6bd1ec6f23e508a52d04a6e384d247efd90 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 2 May 2014 13:22:26 +0200 Subject: 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 511afaac0..cb8ad473c 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); -- cgit v1.2.3 From a5a519a9d15f188b93723c84890d6005d2e9c4be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 3 May 2014 12:55:56 +0200 Subject: 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 cb8ad473c..5d882ab43 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); -- cgit v1.2.3 From 30774ec6bc732478cce1a5ceff5f666893c416a6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 May 2014 13:48:25 +0200 Subject: 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 da2355a9b..e831cc6f0 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 b0b731d0a..852405566 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 56d293260..aee0044b4 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 8283686e3..8332ad919 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(); -- cgit v1.2.3 From 51a615b26d95eddb39e7389d431c0ab7002d52bb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 6 May 2014 14:42:04 +0200 Subject: 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 bf9b350ff..7aa014242 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 -- cgit v1.2.3 From bfd62268cc6a6115c540a0386c02301cd1ee2e22 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 9 May 2014 18:23:21 +0200 Subject: Updated ABC to 67c84cdd49e4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 69fbf5222..54699e4df 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 -- cgit v1.2.3 From f69b5800c940557cafd20598b03d774dd6cf6f8d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 10 May 2014 16:22:56 +0200 Subject: 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 bf37e5dae..92fc5bd55 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, -- cgit v1.2.3 From 68c059565a3b75808e74eb481f14cb7f0c907f37 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 12 May 2014 12:45:47 +0200 Subject: 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 fee8fb71b..dfe214416 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; } } -- cgit v1.2.3 From 684c85902d259a0db3ac5271b540549e98646306 Mon Sep 17 00:00:00 2001 From: Johann Glaser Date: Mon, 26 May 2014 17:13:41 +0200 Subject: 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 69ffb9230..4c5a0febc 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); -- cgit v1.2.3 From 63dfbb18cfb34d72746565a3eb3ffbcd7451cdab Mon Sep 17 00:00:00 2001 From: Johann Glaser Date: Wed, 28 May 2014 16:50:13 +0200 Subject: new flags -ignore_miss_func and -ignore_miss_dir for read_liberty --- frontends/liberty/liberty.cc | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 485d28ee1..285491e06 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -459,6 +459,13 @@ struct LibertyFrontend : public Frontend { log(" ignore re-definitions of modules. (the default behavior is to\n"); log(" create an error message.)\n"); log("\n"); + log(" -ignore_miss_func\n"); + log(" ignore cells with missing function specification of outputs\n"); + log("\n"); + log(" -ignore_miss_dir\n"); + log(" ignore cells with a missing or invalid direction\n"); + log(" specification on a pin\n"); + log("\n"); log(" -setattr \n"); log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); @@ -467,6 +474,8 @@ struct LibertyFrontend : public Frontend { { bool flag_lib = false; bool flag_ignore_redef = false; + bool flag_ignore_miss_func = false; + bool flag_ignore_miss_dir = false; std::vector attributes; log_header("Executing Liberty frontend.\n"); @@ -482,6 +491,14 @@ struct LibertyFrontend : public Frontend { flag_ignore_redef = true; continue; } + if (arg == "-ignore_miss_func") { + flag_ignore_miss_func = true; + continue; + } + if (arg == "-ignore_miss_dir") { + flag_ignore_miss_dir = true; + continue; + } if (arg == "-setattr" && argidx+1 < args.size()) { attributes.push_back(RTLIL::escape_id(args[++argidx])); continue; @@ -507,11 +524,9 @@ struct LibertyFrontend : public Frontend { } // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); - cell_count++; RTLIL::Module *module = new RTLIL::Module; module->name = cell_name; - design->modules[module->name] = module; for (auto &attr : attributes) module->attributes[attr] = 1; @@ -520,7 +535,16 @@ struct LibertyFrontend : public Frontend { if (node->id == "pin" && node->args.size() == 1) { LibertyAst *dir = node->find("direction"); if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "internal")) - log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + { + if (!flag_ignore_miss_dir) + { + log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + } else { + log("Ignoring cell %s with missing or invalid dircetion for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); + delete module; + goto skip_cell; + } + } if (!flag_lib || dir->value != "internal") module->new_wire(1, RTLIL::escape_id(node->args.at(0))); } @@ -556,7 +580,16 @@ struct LibertyFrontend : public Frontend { LibertyAst *func = node->find("function"); if (func == NULL) - log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + { + if (!flag_ignore_miss_func) + { + log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + } else { + log("Ignoring cell %s with missing function on output %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + delete module; + goto skip_cell; + } + } RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); module->connections.push_back(RTLIL::SigSig(wire, out_sig)); @@ -564,6 +597,9 @@ struct LibertyFrontend : public Frontend { } module->fixup_ports(); + design->modules[module->name] = module; + cell_count++; +skip_cell:; } log("Imported %d cell types from liberty file.\n", cell_count); -- cgit v1.2.3 From 278085fa01a9013051fbec842314cb6b5642e9bb Mon Sep 17 00:00:00 2001 From: Johann Glaser Date: Wed, 28 May 2014 18:05:38 +0200 Subject: 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 2ac7b35f6..831a43aa5 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 db12cb57d..6c8e2ff48 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; -- cgit v1.2.3 From d5497f770bf49b893c8a90879d325a73f4d13ee5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 29 May 2014 11:03:15 +0200 Subject: Updated ABC to rev fa4404b395f0 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 54699e4df..04bae3cf4 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 -- cgit v1.2.3 From 68c99bf7349cf56385ee803144dd7d8e219be8d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 1 Jun 2014 11:32:27 +0200 Subject: 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 2502a8b61..e8da6d642 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) -- cgit v1.2.3 From 7020f7fc138ac9bad46f9f2b41150321f315f992 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 3 Jun 2014 09:23:31 +0200 Subject: 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 77cac2b45..3a4b2da71 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 000000000..dd9591954 --- /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; + -- cgit v1.2.3 From f9c1cd5edba5acb4d9b9dd287c7265111cf22087 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 4 Jun 2014 09:10:50 +0200 Subject: Improved error message for options after front-end filename arguments --- frontends/verilog/verilog_frontend.cc | 2 +- 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 8e9efa173..108214586 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -48,7 +48,7 @@ struct VerilogFrontend : public Frontend { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" read_verilog [filename]\n"); + log(" read_verilog [options] [filename]\n"); log("\n"); log("Load modules from a verilog file to the current design. A large subset of\n"); log("Verilog-2005 is supported.\n"); diff --git a/kernel/register.cc b/kernel/register.cc index 5d882ab43..8da5a725f 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: 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 f2f2d0e69..105645f95 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -137,6 +137,7 @@ std::string AST::type2str(AstNodeType type) X(AST_DEFAULT) X(AST_FOR) X(AST_WHILE) + X(AST_REPEAT) X(AST_GENVAR) X(AST_GENFOR) X(AST_GENIF) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 72a2a4600..8f9c35349 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -117,6 +117,7 @@ namespace AST AST_DEFAULT, AST_FOR, AST_WHILE, + AST_REPEAT, AST_GENVAR, AST_GENFOR, diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 226a26709..5300d1b26 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -140,6 +140,8 @@ namespace VERILOG_FRONTEND { "default" { return TOK_DEFAULT; } "generate" { return TOK_GENERATE; } "endgenerate" { return TOK_ENDGENERATE; } +"while" { return TOK_WHILE; } +"repeat" { return TOK_REPEAT; } "assert"([ \t\r\n]+"property")? { return TOK_ASSERT; } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index ed9be692b..a12dcf142 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -98,7 +98,7 @@ static void free_attr(std::map *al) %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL -%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR +%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT %token TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK @@ -819,6 +819,32 @@ behavioral_stmt: ast_stack.pop_back(); ast_stack.pop_back(); } | + attr TOK_WHILE '(' expr ')' { + AstNode *node = new AstNode(AST_WHILE); + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + append_attr(node, $1); + AstNode *block = new AstNode(AST_BLOCK); + ast_stack.back()->children.push_back($4); + ast_stack.back()->children.push_back(block); + ast_stack.push_back(block); + } behavioral_stmt { + ast_stack.pop_back(); + ast_stack.pop_back(); + } | + attr TOK_REPEAT '(' expr ')' { + AstNode *node = new AstNode(AST_REPEAT); + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + append_attr(node, $1); + AstNode *block = new AstNode(AST_BLOCK); + ast_stack.back()->children.push_back($4); + ast_stack.back()->children.push_back(block); + ast_stack.push_back(block); + } behavioral_stmt { + ast_stack.pop_back(); + ast_stack.pop_back(); + } | attr TOK_IF '(' expr ')' { AstNode *node = new AstNode(AST_CASE); AstNode *block = new AstNode(AST_BLOCK); -- cgit v1.2.3 From ab54ce17c82e55cb26bf5c0dd7512decbd941b12 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 17:40:45 +0200 Subject: improved ast simplify of const functions --- frontends/ast/simplify.cc | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a20aacff5..5f40b60a8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -140,7 +140,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_FUNCTION || type == AST_TASK) return false; - // deactivate all calls non-synthesis system taks + // deactivate all calls to non-synthesis system taks if ((type == AST_FCALL || type == AST_TCALL) && (str == "$display" || str == "$stop" || str == "$finish")) { delete_children(); str = std::string(); @@ -245,9 +245,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_ASSIGN_EQ: case AST_ASSIGN_LE: case AST_ASSIGN: - while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, false) == true) + while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, in_param) == true) did_something = true; - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, false) == true) + while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param) == true) did_something = true; children[0]->detectSignWidth(backup_width_hint, backup_sign_hint); children[1]->detectSignWidth(width_hint, sign_hint); @@ -1825,12 +1825,16 @@ void AstNode::replace_variables(std::map &varia if (type == AST_IDENTIFIER && variables.count(str)) { int offset = variables.at(str).offset, width = variables.at(str).val.bits.size(); if (!children.empty()) { + if (children.size() != 1 || children.at(0)->type != AST_RANGE) + log_error("Memory access in constant function is not supported in %s:%d (called from %s:%d).\n", + filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); + children.at(0)->replace_variables(variables, fcall); while (simplify(true, false, false, 1, -1, false, true)) { } - if (!range_valid) + if (!children.at(0)->range_valid) log_error("Non-constant range in %s:%d (called from %s:%d).\n", filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum); - offset = std::min(range_left, range_right); - width = std::min(std::abs(range_left - range_right) + 1, width); + offset = std::min(children.at(0)->range_left, children.at(0)->range_right); + width = std::min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width); } offset -= variables.at(str).offset; std::vector &var_bits = variables.at(str).val.bits; @@ -1850,6 +1854,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) { std::map backup_scope; std::map variables; + bool delete_temp_block = false; AstNode *block = NULL; size_t argidx = 0; @@ -1878,6 +1883,16 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (child->type == AST_ASSIGN_EQ) + { + log_assert(block == NULL); + delete_temp_block = true; + block = new AstNode(AST_BLOCK); + block->children.push_back(child->clone()); + continue; + } + + child->dumpAst(NULL, "unexpected> "); log_abort(); } @@ -1900,8 +1915,11 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) stmt->children.at(1)->replace_variables(variables, fcall); while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + if (stmt->type != AST_ASSIGN_EQ) + continue; + if (stmt->children.at(1)->type != AST_CONSTANT) - log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); if (stmt->children.at(0)->type != AST_IDENTIFIER || !stmt->children.at(0)->children.empty()) @@ -2011,6 +2029,9 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_abort(); } + if (delete_temp_block) + delete block; + for (auto &it : backup_scope) if (it.second == NULL) current_scope.erase(it.first); -- cgit v1.2.3 From c82db39935e969ff95b0728dbb92231f0e9e9891 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 17:47:20 +0200 Subject: 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 000000000..8c5b4b371 --- /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 -- cgit v1.2.3 From 5c10d2ee364c8807d10069ba7be3d1da3d252fa1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 21:29:23 +0200 Subject: fix functions with no block (but single statement, loop, etc.) --- frontends/ast/simplify.cc | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5f40b60a8..47ea880c6 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1883,17 +1883,10 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } - if (child->type == AST_ASSIGN_EQ) - { - log_assert(block == NULL); - delete_temp_block = true; - block = new AstNode(AST_BLOCK); - block->children.push_back(child->clone()); - continue; - } - - child->dumpAst(NULL, "unexpected> "); - log_abort(); + log_assert(block == NULL); + delete_temp_block = true; + block = new AstNode(AST_BLOCK); + block->children.push_back(child->clone()); } log_assert(block != NULL); -- cgit v1.2.3 From 76da2fe172ed6b0822a9e4a8cf9483ef7c8f5f40 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 22:55:02 +0200 Subject: improved const function support --- frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 2 +- frontends/ast/simplify.cc | 43 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8f9c35349..6c5a0eae4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -202,6 +202,7 @@ namespace AST // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; + bool has_const_only_constructs(); void replace_variables(std::map &variables, AstNode *fcall); AstNode *eval_const_function(AstNode *fcall); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index c3025913c..2efdee10a 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -579,7 +579,7 @@ struct AST_INTERNAL::ProcessGenerator break; default: - assert(0); + log_abort(); } } }; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 47ea880c6..71e7cbc6d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -606,6 +606,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, goto apply_newNode; } + if (type == AST_WHILE) + log_error("While loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum); + + if (type == AST_REPEAT) + log_error("Repeat loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum); + // unroll for loops and generate-for blocks if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0) { @@ -1181,7 +1187,7 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } - if (in_param) + if (in_param || current_scope[str]->has_const_only_constructs()) { bool all_args_const = true; for (auto child : children) { @@ -1197,7 +1203,10 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } - log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); + if (in_param) + log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); + else + log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } AstNode *decl = current_scope[str]; @@ -1819,6 +1828,19 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) addr_bits++; } +bool AstNode::has_const_only_constructs() +{ + if (type == AST_WHILE || type == AST_REPEAT) + return true; + if (type == AST_FCALL && current_scope.count(str)) + if (current_scope[str]->has_const_only_constructs()) + return true; + for (auto child : children) + if (child->AstNode::has_const_only_constructs()) + return true; + return false; +} + // helper function for AstNode::eval_const_function() void AstNode::replace_variables(std::map &variables, AstNode *fcall) { @@ -1915,7 +1937,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); - if (stmt->children.at(0)->type != AST_IDENTIFIER || !stmt->children.at(0)->children.empty()) + if (stmt->children.at(0)->type != AST_IDENTIFIER) log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); @@ -1923,7 +1945,20 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n", stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); - variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + if (stmt->children.at(0)->children.empty()) { + variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size()); + } else { + AstNode *range = stmt->children.at(0)->children.at(0); + if (!range->range_valid) + log_error("Non-constant range in %s:%d (called from %s:%d).\n", + range->filename.c_str(), range->linenum, fcall->filename.c_str(), fcall->linenum); + int offset = std::min(range->range_left, range->range_right); + int width = std::min(std::abs(range->range_left - range->range_right) + 1, width); + varinfo_t &v = variables[stmt->children.at(0)->str]; + RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size()); + for (int i = 0; i < width; i++) + v.val.bits.at(i+offset-v.offset) = r.bits.at(i); + } delete block->children.front(); block->children.erase(block->children.begin()); -- cgit v1.2.3 From 5281562d0e9468c584e6db6f30908e3155a76ad2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 23:05:01 +0200 Subject: made the generate..endgenrate keywords optional --- frontends/verilog/parser.y | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index a12dcf142..42a8f91c5 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -373,6 +373,8 @@ range_or_integer: module_body: module_body module_body_stmt | + /* the following line makes the generate..endgenrate keywords optional */ + module_body gen_stmt | /* empty */; module_body_stmt: @@ -1013,9 +1015,12 @@ single_arg: }; module_gen_body: - module_gen_body gen_stmt | + module_gen_body gen_stmt_or_module_body_stmt | /* empty */; +gen_stmt_or_module_body_stmt: + gen_stmt | module_body_stmt; + // this production creates the obligatory if-else shift/reduce conflict gen_stmt: TOK_FOR '(' { @@ -1054,15 +1059,14 @@ gen_stmt: if ($6 != NULL) delete $6; ast_stack.pop_back(); - } | - module_body_stmt; + }; gen_stmt_block: { AstNode *node = new AstNode(AST_GENBLOCK); ast_stack.back()->children.push_back(node); ast_stack.push_back(node); - } gen_stmt { + } gen_stmt_or_module_body_stmt { ast_stack.pop_back(); }; -- cgit v1.2.3 From 7c8a7b2131aa672d04ee0ed641f3e6b120f3ec49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 00:02:05 +0200 Subject: further improved const function support --- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 10 +++++----- frontends/ast/simplify.cc | 27 ++++++++++++++++----------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6c5a0eae4..3e69e3bc0 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -202,7 +202,7 @@ namespace AST // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; - bool has_const_only_constructs(); + bool has_const_only_constructs(bool &recommend_const_eval); void replace_variables(std::map &variables, AstNode *fcall); AstNode *eval_const_function(AstNode *fcall); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 2efdee10a..9273636f4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -623,10 +623,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) if (id_ast->type == AST_AUTOWIRE) this_width = 1; else { - // current_ast_mod->dumpAst(stdout, ""); - // printf("---\n"); - // dumpAst(stdout, ""); - // fflush(stdout); + // current_ast_mod->dumpAst(NULL, "mod> "); + // log("---\n"); + // id_ast->dumpAst(NULL, "decl> "); + // dumpAst(NULL, "ref> "); log_error("Failed to detect with of signal access `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); } } else { @@ -693,7 +693,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_REPLICATE: - while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } + while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { } if (children[0]->type != AST_CONSTANT) log_error("Left operand of replicate expression is not constant at %s:%d!\n", filename.c_str(), linenum); children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 71e7cbc6d..8a4d42e1b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -349,12 +349,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (detect_width_simple && width_hint < 0) { + if (type == AST_REPLICATE) + while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, true) == true) + did_something = true; for (auto child : children) while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) did_something = true; - if (type == AST_REPLICATE) - while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param) == true) - did_something = true; detectSignWidth(width_hint, sign_hint); } @@ -376,8 +376,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, bool const_fold_here = const_fold, in_lvalue_here = in_lvalue; int width_hint_here = width_hint; bool sign_hint_here = sign_hint; - if (i == 0 && type == AST_REPLICATE) - const_fold_here = true; + bool in_param_here = in_param; + if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE)) + const_fold_here = true, in_param_here = true; if (type == AST_PARAMETER || type == AST_LOCALPARAM) const_fold_here = true; if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE)) @@ -394,7 +395,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint_here = -1, sign_hint_here = false; if (children_are_self_determined) width_hint_here = -1, sign_hint_here = false; - did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param); + did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here); if (did_something_here) did_something = true; } @@ -1187,7 +1188,9 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } - if (in_param || current_scope[str]->has_const_only_constructs()) + bool recommend_const_eval = false; + bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval); + if (in_param || recommend_const_eval || require_const_eval) { bool all_args_const = true; for (auto child : children) { @@ -1205,7 +1208,7 @@ skip_dynamic_range_lvalue_expansion:; if (in_param) log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum); - else + if (require_const_eval) log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } @@ -1828,15 +1831,17 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) addr_bits++; } -bool AstNode::has_const_only_constructs() +bool AstNode::has_const_only_constructs(bool &recommend_const_eval) { + if (type == AST_FOR) + recommend_const_eval = true; if (type == AST_WHILE || type == AST_REPEAT) return true; if (type == AST_FCALL && current_scope.count(str)) - if (current_scope[str]->has_const_only_constructs()) + if (current_scope[str]->has_const_only_constructs(recommend_const_eval)) return true; for (auto child : children) - if (child->AstNode::has_const_only_constructs()) + if (child->AstNode::has_const_only_constructs(recommend_const_eval)) return true; return false; } -- cgit v1.2.3 From 0b1ce63a19025f73fe4d2a54253134ea9a4de625 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 10:47:53 +0200 Subject: Added support for repeat stmt in const functions --- frontends/ast/simplify.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8a4d42e1b..e5e8980a2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2001,6 +2001,25 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (stmt->type == AST_REPEAT) + { + AstNode *num = stmt->children.at(0)->clone(); + num->replace_variables(variables, fcall); + while (num->simplify(true, false, false, 1, -1, false, true)) { } + + if (num->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + block->children.erase(block->children.begin()); + for (int i = 0; i < num->bitsAsConst().as_int(); i++) + block->children.insert(block->children.begin(), stmt->children.at(1)->clone()); + + delete stmt; + delete num; + continue; + } + if (stmt->type == AST_CASE) { AstNode *expr = stmt->children.at(0)->clone(); -- cgit v1.2.3 From e275e8eef9ae47670075bd73a671f3acd3c0ca52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 11:48:50 +0200 Subject: Add support for cell arrays --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 25 +++++++++++++++++++++++++ frontends/verilog/parser.y | 7 +++++++ 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 105645f95..0780f7b59 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -127,6 +127,7 @@ std::string AST::type2str(AstNodeType type) X(AST_ASSIGN) X(AST_CELL) X(AST_PRIMITIVE) + X(AST_CELLARRAY) X(AST_ALWAYS) X(AST_INITIAL) X(AST_BLOCK) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 3e69e3bc0..802bf98ff 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -107,6 +107,7 @@ namespace AST AST_ASSIGN, AST_CELL, AST_PRIMITIVE, + AST_CELLARRAY, AST_ALWAYS, AST_INITIAL, AST_BLOCK, diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e5e8980a2..fc040baac 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -878,6 +878,31 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, did_something = true; } + // unroll cell arrays + if (type == AST_CELLARRAY) + { + if (!children.at(0)->range_valid) + log_error("Non-constant array range on cell array at %s:%d.\n", filename.c_str(), linenum); + + newNode = new AstNode(AST_GENBLOCK); + int num = std::max(children.at(0)->range_left, children.at(0)->range_right) - std::min(children.at(0)->range_left, children.at(0)->range_right) + 1; + + for (int i = 0; i < num; i++) { + int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i; + AstNode *new_cell = children.at(1)->clone(); + newNode->children.push_back(new_cell); + new_cell->str += stringf("[%d]", idx); + if (new_cell->type == AST_PRIMITIVE) { + log_error("Cell arrays of primitives are currently not supported at %s:%d.\n", filename.c_str(), linenum); + } else { + log_assert(new_cell->children.at(0)->type == AST_CELLTYPE); + new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str()); + } + } + + goto apply_newNode; + } + // replace primitives with assignmens if (type == AST_PRIMITIVE) { diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 42a8f91c5..f422258c7 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -634,6 +634,13 @@ single_cell: astbuf2->str = *$1; delete $1; ast_stack.back()->children.push_back(astbuf2); + } '(' cell_port_list ')' | + TOK_ID non_opt_range { + astbuf2 = astbuf1->clone(); + if (astbuf2->type != AST_PRIMITIVE) + astbuf2->str = *$1; + delete $1; + ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2)); } '(' cell_port_list ')'; prim_list: diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1168102a3..028cd6d81 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 526d17294..6890cb9ea 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; } -- cgit v1.2.3 From 744e51846776a304828301914f5cd74fb7d0a5ca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 12:17:06 +0200 Subject: 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 6890cb9ea..d8a23c727 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) -- cgit v1.2.3 From 3af7c69d1e3c17d7aaa5d3a7da9f8a2ae12ed9bf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 12:18:00 +0200 Subject: added tests for new verilog features --- tests/simple/arraycells.v | 15 +++++++++++++++ tests/simple/repwhile.v | 28 ++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 6 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 000000000..ad5098000 --- /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 8c5b4b371..cde37c563 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 + function [31:0] myexp2; + input [7:0] value; + begin + myexp2 = 1; + repeat (value) + myexp2 = myexp2 << 1; + end + 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 - localparam tmp = mylog2(i); - assign y[i] = tmp; + y_table[i] <= mylog2(i); + x_table[i] <= myexp2(i); end - endgenerate + end + + assign y = y_table[a]; + assign x = x_table[a]; endmodule -- cgit v1.2.3 From 94e9ee6baba2952c8dd055dbab45fb3c9c64121e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Jun 2014 10:12:39 +0200 Subject: Updated ABC to 7600ffb9340c --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 04bae3cf4..38e404ce0 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 -- cgit v1.2.3 From ca125bf41b6de9251f6396fd06ba7a50c7eb48c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Jun 2014 15:28:36 +0200 Subject: Tagging Yosys 0.3.0 --- CHANGELOG | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- Makefile | 2 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c014f4586..77d7551bf 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 38e404ce0..c0c6fe3f3 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 -- cgit v1.2.3 From 9a6cd64fc2ca46c9aed1bd03b6898c7734420c53 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 8 Jun 2014 15:31:27 +0200 Subject: 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 77d7551bf..356957297 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 c0c6fe3f3..a84215b27 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 -- cgit v1.2.3 From 482d9208aa9dacb7afe21f08c882d4881581013a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jun 2014 11:54:20 +0200 Subject: Added read_verilog -sv options, added support for bit, logic, allways_ff, always_comb, and always_latch --- 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 d021c8864..05628a8e3 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 5300d1b26..8f4b49916 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -52,6 +52,14 @@ namespace VERILOG_FRONTEND { std::vector ln_stack; } +#define SV_KEYWORD(_tok) \ + if (sv_mode) return _tok; \ + log("Lexer warning: The SystemVerilog keyword `%s' (at %s:%d) is not "\ + "recognized unless read_verilog is called with -sv!\n", yytext, \ + AST::current_filename.c_str(), frontend_verilog_yyget_lineno()); \ + frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \ + return TOK_ID; + %} %option yylineno @@ -143,7 +151,14 @@ namespace VERILOG_FRONTEND { "while" { return TOK_WHILE; } "repeat" { return TOK_REPEAT; } -"assert"([ \t\r\n]+"property")? { return TOK_ASSERT; } +"always_comb" { SV_KEYWORD(TOK_ALWAYS); } +"always_ff" { SV_KEYWORD(TOK_ALWAYS); } +"always_latch" { SV_KEYWORD(TOK_ALWAYS); } + +"assert" { SV_KEYWORD(TOK_ASSERT); } +"property" { SV_KEYWORD(TOK_PROPERTY); } +"logic" { SV_KEYWORD(TOK_REG); } +"bit" { SV_KEYWORD(TOK_REG); } "input" { return TOK_INPUT; } "output" { return TOK_OUTPUT; } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index f422258c7..cce8a8c40 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -54,6 +54,7 @@ namespace VERILOG_FRONTEND { int current_function_or_task_port_id; std::vector case_type_stack; bool default_nettype_wire; + bool sv_mode; } static void append_attr(AstNode *ast, std::map *al) @@ -105,7 +106,7 @@ static void free_attr(std::map *al) %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED -%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT +%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY %type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id @@ -379,7 +380,7 @@ module_body: module_body_stmt: task_func_decl | param_decl | localparam_decl | defparam_decl | wire_decl | assign_stmt | cell_stmt | - always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert; + always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: TOK_TASK TOK_ID ';' { @@ -773,6 +774,11 @@ assert: ast_stack.back()->children.push_back(new AstNode(AST_ASSERT, $3)); }; +assert_property: + TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' { + ast_stack.back()->children.push_back(new AstNode(AST_ASSERT, $4)); + }; + simple_behavioral_stmt: lvalue '=' expr { AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $3); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 108214586..437fc3ec0 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -53,6 +53,10 @@ struct VerilogFrontend : public Frontend { log("Load modules from a verilog file to the current design. A large subset of\n"); log("Verilog-2005 is supported.\n"); log("\n"); + log(" -sv\n"); + log(" enable support for SystemVerilog features. (only a small subset\n"); + log(" of SystemVerilog is supported)\n"); + log("\n"); log(" -dump_ast1\n"); log(" dump abstract syntax tree (before simplification)\n"); log("\n"); @@ -150,7 +154,9 @@ struct VerilogFrontend : public Frontend { std::map defines_map; std::list include_dirs; std::list attributes; + frontend_verilog_yydebug = false; + sv_mode = false; log_header("Executing Verilog-2005 frontend.\n"); @@ -159,6 +165,10 @@ struct VerilogFrontend : public Frontend { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; + if (arg == "-sv") { + sv_mode = true; + continue; + } if (arg == "-dump_ast1") { flag_dump_ast1 = true; continue; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 99b2164ef..6d01a1532 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -45,6 +45,9 @@ namespace VERILOG_FRONTEND // state of `default_nettype extern bool default_nettype_wire; + + // running in SystemVerilog mode + extern bool sv_mode; } // the pre-processor diff --git a/tests/sat/asserts.ys b/tests/sat/asserts.ys index de5e7c9aa..d8f994925 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 c622ef610..e97686644 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 -- cgit v1.2.3 From 7ef0da32cdcddb50de8ba8acf0c6421fe5732c55 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jun 2014 11:29:23 +0200 Subject: Added Verilog lexer and parser support for real values --- frontends/ast/ast.cc | 5 +++++ frontends/ast/ast.h | 2 ++ frontends/verilog/lexer.l | 10 ++++++++++ frontends/verilog/parser.y | 17 ++++++++++++++--- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0780f7b59..1ce7efc84 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -77,6 +77,7 @@ std::string AST::type2str(AstNodeType type) X(AST_ARGUMENT) X(AST_RANGE) X(AST_CONSTANT) + X(AST_REALVALUE) X(AST_CELLTYPE) X(AST_IDENTIFIER) X(AST_PREFIX) @@ -460,6 +461,10 @@ void AstNode::dumpVlog(FILE *f, std::string indent) fprintf(f, "%zd'b %s", bits.size(), RTLIL::Const(bits).as_string().c_str()); break; + case AST_REALVALUE: + fprintf(f, "%e", realvalue); + break; + case AST_BLOCK: if (children.size() == 1) { children[0]->dumpVlog(f, indent); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 802bf98ff..aeb56e352 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -55,6 +55,7 @@ namespace AST AST_ARGUMENT, AST_RANGE, AST_CONSTANT, + AST_REALVALUE, AST_CELLTYPE, AST_IDENTIFIER, AST_PREFIX, @@ -153,6 +154,7 @@ namespace AST bool is_input, is_output, is_reg, is_signed, is_string, range_valid; int port_id, range_left, range_right; uint32_t integer; + double realvalue; // this is set by simplify and used during RTLIL generation AstNode *id2ast; diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 8f4b49916..ed304572b 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -179,6 +179,16 @@ namespace VERILOG_FRONTEND { return TOK_CONST; } +[0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? { + frontend_verilog_yylval.string = new std::string(yytext); + return TOK_REAL; +} + +[0-9][0-9_]*[eE][-+]?[0-9_]+ { + frontend_verilog_yylval.string = new std::string(yytext); + return TOK_REAL; +} + \" { BEGIN(STRING); } \\. { yymore(); } \" { diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index cce8a8c40..e51712b3f 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -35,7 +35,7 @@ %{ #include -#include +#include #include "verilog_frontend.h" #include "kernel/log.h" @@ -94,7 +94,7 @@ static void free_attr(std::map *al) bool boolean; } -%token TOK_STRING TOK_ID TOK_CONST TOK_PRIMITIVE +%token TOK_STRING TOK_ID TOK_CONST TOK_REAL TOK_PRIMITIVE %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG @@ -221,7 +221,7 @@ module: frontend_verilog_yyerror("Missing details for module port `%s'.", port_stubs.begin()->first.c_str()); ast_stack.pop_back(); - assert(ast_stack.size() == 0); + log_assert(ast_stack.size() == 0); }; module_para_opt: @@ -1133,6 +1133,17 @@ basic_expr: log_error("Value conversion failed: `%s'\n", $1->c_str()); delete $1; } | + TOK_REAL { + $$ = new AstNode(AST_REALVALUE); + char *p = strdup($1->c_str()), *q; + for (int i = 0, j = 0; !p[j]; j++) + if (p[j] != '_') + p[i++] = p[j], p[i] = 0; + $$->realvalue = strtod(p, &q); + log_assert(*q == 0); + delete $1; + free(p); + } | TOK_STRING { $$ = AstNode::mkconst_str(*$1); delete $1; -- cgit v1.2.3 From 9dd16fa41c01c8da2e4905184cce0391a7547fa3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 07:44:19 +0200 Subject: Added real->int convertion in ast genrtlil --- frontends/ast/genrtlil.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9273636f4..5b43f57ff 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -602,6 +602,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) sign_hint = false; break; + case AST_REALVALUE: + width_hint = std::max(width_hint, 32); + break; + case AST_IDENTIFIER: id_ast = id2ast; if (id_ast == NULL && current_scope.count(str)) @@ -909,6 +913,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) return RTLIL::SigSpec(bitsAsConst()); } + case AST_REALVALUE: + { + int intvalue = round(realvalue); + log("Warning: converting real value %e to integer %d at %s:%d.\n", + realvalue, intvalue, filename.c_str(), linenum); + return RTLIL::SigSpec(intvalue); + } + // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node // for identifiers with dynamic bit ranges (e.g. "foo[bar]" or "foo[bar+3:bar]") a // shifter cell is created and the output signal of this cell is returned -- cgit v1.2.3 From 442a8e2875eab679ed3b31aee3d9725b87dbf4fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 08:51:22 +0200 Subject: Implemented basic real arithmetic --- frontends/ast/ast.cc | 31 ++++++++++++++++++++++++++++++- frontends/ast/ast.h | 4 ++++ frontends/ast/simplify.cc | 22 +++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 1ce7efc84..3af08b9d1 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -32,7 +32,7 @@ #include #include -#include +#include using namespace AST; using namespace AST_INTERNAL; @@ -760,6 +760,35 @@ bool AstNode::asBool() return false; } +int AstNode::isConst() +{ + if (type == AST_CONSTANT) + return 1; + if (type == AST_REALVALUE) + return 2; + return 0; +} + +double AstNode::asReal(bool is_signed) +{ + if (type == AST_CONSTANT) { + RTLIL::Const val; + val.bits = bits; + + double p = exp2(val.bits.size()-32); + if (val.bits.size() > 32) + val.bits.erase(val.bits.begin(), val.bits.begin()+(val.bits.size()-32)); + int32_t v = val.as_int() << (32-val.bits.size()); + + if (is_signed) + return v * p; + return uint32_t(v) * p; + } + if (type == AST_REALVALUE) + return realvalue; + return 0; +} + // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer) { diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index aeb56e352..95f0f142f 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -240,6 +240,10 @@ namespace AST RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); bool asBool(); + + // helper functions for real valued const eval + int isConst(); // return '1' for AST_CONSTANT and '2' for AST_REALVALUE + double asReal(bool is_signed); }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index fc040baac..7e4c265bd 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -32,7 +32,7 @@ #include #include -#include +#include using namespace AST; using namespace AST_INTERNAL; @@ -1433,10 +1433,22 @@ skip_dynamic_range_lvalue_expansion:; if (0) { case AST_MUL: const_func = RTLIL::const_mul; } if (0) { case AST_DIV: const_func = RTLIL::const_div; } if (0) { case AST_MOD: const_func = RTLIL::const_mod; } - if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { - RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), - children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); - newNode = mkconst_bits(y.bits, sign_hint); + if (children[0]->isConst() && children[1]->isConst()) { + if (children[0]->isConst() + children[1]->isConst() > 2) { + newNode = new AstNode(AST_REALVALUE); + switch (type) { + case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break; + case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break; + case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break; + case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break; + case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break; + default: log_abort(); + } + } else { + RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), + children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); + newNode = mkconst_bits(y.bits, sign_hint); + } } break; if (0) { case AST_POS: const_func = RTLIL::const_pos; } -- cgit v1.2.3 From fc7b6d172a67965c89d84696e5f2cf1218855ea5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 11:27:05 +0200 Subject: Implemented more real arithmetic --- frontends/ast/simplify.cc | 97 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7e4c265bd..77bab6b0d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1348,7 +1348,9 @@ skip_dynamic_range_lvalue_expansion:; } else if (children.size() == 0) newNode = current_scope[str]->children[0]->clone(); - } + } else + if (current_scope[str]->children[0]->isConst()) + newNode = current_scope[str]->children[0]->clone(); } else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) { newNode = mkconst_int(0, sign_hint, width_hint); @@ -1391,6 +1393,9 @@ skip_dynamic_range_lvalue_expansion:; if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1); newNode = mkconst_bits(y.bits, false); + } else + if (children[0]->isConst()) { + newNode = mkconst_int(children[0]->asReal(sign_hint) == 0, false, 1); } break; if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; } @@ -1399,6 +1404,12 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits), children[0]->is_signed, children[1]->is_signed, -1); newNode = mkconst_bits(y.bits, false); + } else + if (children[0]->isConst() && children[1]->isConst()) { + if (type == AST_LOGIC_AND) + newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1); + else + newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1); } break; if (0) { case AST_SHIFT_LEFT: const_func = RTLIL::const_shl; } @@ -1410,6 +1421,10 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint); newNode = mkconst_bits(y.bits, sign_hint); + } else + if (type == AST_POW && children[0]->isConst() && children[1]->isConst()) { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = pow(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); } break; if (0) { case AST_LT: const_func = RTLIL::const_lt; } @@ -1426,6 +1441,19 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed), children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1); newNode = mkconst_bits(y.bits, false); + } else + if (children[0]->isConst() && children[1]->isConst()) { + switch (type) { + case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); + case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); + case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); + case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); + case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); + case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); + case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); + case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); + default: log_abort(); + } } break; if (0) { case AST_ADD: const_func = RTLIL::const_add; } @@ -1433,21 +1461,20 @@ skip_dynamic_range_lvalue_expansion:; if (0) { case AST_MUL: const_func = RTLIL::const_mul; } if (0) { case AST_DIV: const_func = RTLIL::const_div; } if (0) { case AST_MOD: const_func = RTLIL::const_mod; } + if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) { + RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), + children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); + newNode = mkconst_bits(y.bits, sign_hint); + } else if (children[0]->isConst() && children[1]->isConst()) { - if (children[0]->isConst() + children[1]->isConst() > 2) { - newNode = new AstNode(AST_REALVALUE); - switch (type) { - case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break; - case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break; - case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break; - case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break; - case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break; - default: log_abort(); - } - } else { - RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), - children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint); - newNode = mkconst_bits(y.bits, sign_hint); + newNode = new AstNode(AST_REALVALUE); + switch (type) { + case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break; + case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break; + case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break; + case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break; + case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break; + default: log_abort(); } } break; @@ -1456,29 +1483,45 @@ skip_dynamic_range_lvalue_expansion:; if (children[0]->type == AST_CONSTANT) { RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint); newNode = mkconst_bits(y.bits, sign_hint); + } else + if (children[0]->isConst()) { + newNode = new AstNode(AST_REALVALUE); + if (type == AST_POS) + newNode->realvalue = +children[0]->asReal(sign_hint); + else + newNode->realvalue = -children[0]->asReal(sign_hint); } break; case AST_TERNARY: - if (children[0]->type == AST_CONSTANT) { + if (children[0]->isConst()) { bool found_sure_true = false; bool found_maybe_true = false; - for (auto &bit : children[0]->bits) { - if (bit == RTLIL::State::S1) - found_sure_true = true; - if (bit > RTLIL::State::S1) - found_maybe_true = true; + if (children[0]->type == AST_CONSTANT) { + for (auto &bit : children[0]->bits) { + if (bit == RTLIL::State::S1) + found_sure_true = true; + if (bit > RTLIL::State::S1) + found_maybe_true = true; + } + } else { + found_sure_true = children[0]->asReal(false) != 0; } AstNode *choice = NULL; if (found_sure_true) choice = children[1]; else if (!found_maybe_true) choice = children[2]; - if (choice != NULL && choice->type == AST_CONSTANT) { - RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); - if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) - newNode = mkconst_str(y.bits); - else - newNode = mkconst_bits(y.bits, sign_hint); + if (choice != NULL) { + if (choice->type == AST_CONSTANT) { + RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); + if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) + newNode = mkconst_str(y.bits); + else + newNode = mkconst_bits(y.bits, sign_hint); + } else + if (choice->isConst()) { + newNode = choice->clone(); + } } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) { RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint); RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint); -- cgit v1.2.3 From 9bd7d5c46856f25fd7befcdfe20198fd8eb59ccd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 12:00:47 +0200 Subject: Added handling of real-valued parameters/localparams --- frontends/ast/ast.cc | 13 ++++++++---- frontends/ast/simplify.cc | 51 ++++++++++++++++++++++++++++++++++------------ frontends/verilog/lexer.l | 5 +++-- frontends/verilog/parser.y | 17 +++++++++++----- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3af08b9d1..f3cf8fa7a 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -185,6 +185,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2) range_left = -1; range_right = 0; integer = 0; + realvalue = 0; id2ast = NULL; basic_prep = false; @@ -278,6 +279,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) fprintf(f, " range=[%d:%d]%s", range_left, range_right, range_valid ? "" : "!"); if (integer != 0) fprintf(f, " int=%u", (int)integer); + if (realvalue != 0) + fprintf(f, " real=%e", realvalue); fprintf(f, "\n"); for (auto &it : attributes) { @@ -775,18 +778,20 @@ double AstNode::asReal(bool is_signed) RTLIL::Const val; val.bits = bits; - double p = exp2(val.bits.size()-32); + double p = exp2(int(val.bits.size())-32); if (val.bits.size() > 32) - val.bits.erase(val.bits.begin(), val.bits.begin()+(val.bits.size()-32)); - int32_t v = val.as_int() << (32-val.bits.size()); + val.bits.erase(val.bits.begin(), val.bits.begin()+(int(val.bits.size())-32)); + int32_t v = val.as_int() << (32-int(val.bits.size())); if (is_signed) return v * p; return uint32_t(v) * p; } + if (type == AST_REALVALUE) return realvalue; - return 0; + + log_abort(); } // create a new AstModule from an AST_MODULE AST node diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 77bab6b0d..a5c4d0230 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -48,6 +48,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *newNode = NULL; bool did_something = false; +#if 0 + log("-------------\n"); + log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n", + int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param)); + dumpAst(NULL, "> "); +#endif + if (stage == 0) { assert(type == AST_MODULE); @@ -260,8 +267,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) did_something = true; children[0]->detectSignWidth(width_hint, sign_hint); - if (children.size() > 1) { - assert(children[1]->type == AST_RANGE); + if (children.size() > 1 && children[1]->type == AST_RANGE) { while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) did_something = true; if (!children[1]->range_valid) @@ -519,18 +525,37 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } // trim/extend parameters - if ((type == AST_PARAMETER || type == AST_LOCALPARAM) && children[0]->type == AST_CONSTANT && children.size() > 1) { - if (!children[1]->range_valid) - log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); - int width = children[1]->range_left - children[1]->range_right + 1; - if (width != int(children[0]->bits.size())) { - RTLIL::SigSpec sig(children[0]->bits); - sig.extend_u0(width, children[0]->is_signed); - AstNode *old_child_0 = children[0]; - children[0] = mkconst_bits(sig.as_const().bits, children[0]->is_signed); - delete old_child_0; + if (type == AST_PARAMETER || type == AST_LOCALPARAM) { + if (children.size() > 1 && children[1]->type == AST_RANGE) { + if (children[0]->type == AST_REALVALUE) { + int intvalue = round(children[0]->realvalue); + log("Warning: converting real value %e to integer %d at %s:%d.\n", + children[0]->realvalue, intvalue, filename.c_str(), linenum); + delete children[0]; + children[0] = mkconst_int(intvalue, sign_hint); + did_something = true; + } + if (children[0]->type == AST_CONSTANT) { + if (!children[1]->range_valid) + log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); + int width = children[1]->range_left - children[1]->range_right + 1; + if (width != int(children[0]->bits.size())) { + RTLIL::SigSpec sig(children[0]->bits); + sig.extend_u0(width, children[0]->is_signed); + AstNode *old_child_0 = children[0]; + children[0] = mkconst_bits(sig.as_const().bits, children[0]->is_signed); + delete old_child_0; + } + children[0]->is_signed = is_signed; + } + } else + if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) { + double as_realvalue = children[0]->asReal(sign_hint); + delete children[0]; + children[0] = new AstNode(AST_REALVALUE); + children[0]->realvalue = as_realvalue; + did_something = true; } - children[0]->is_signed = is_signed; } // annotate identifiers using scope resolution and create auto-wires as needed diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index ed304572b..0839f5cf9 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -168,6 +168,7 @@ namespace VERILOG_FRONTEND { "integer" { return TOK_INTEGER; } "signed" { return TOK_SIGNED; } "genvar" { return TOK_GENVAR; } +"real" { return TOK_REAL; } [0-9]+ { frontend_verilog_yylval.string = new std::string(yytext); @@ -181,12 +182,12 @@ namespace VERILOG_FRONTEND { [0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? { frontend_verilog_yylval.string = new std::string(yytext); - return TOK_REAL; + return TOK_REALVAL; } [0-9][0-9_]*[eE][-+]?[0-9_]+ { frontend_verilog_yylval.string = new std::string(yytext); - return TOK_REAL; + return TOK_REALVAL; } \" { BEGIN(STRING); } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index e51712b3f..57defd56b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -94,7 +94,7 @@ static void free_attr(std::map *al) bool boolean; } -%token TOK_STRING TOK_ID TOK_CONST TOK_REAL TOK_PRIMITIVE +%token TOK_STRING TOK_ID TOK_CONST TOK_REALVAL TOK_PRIMITIVE %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG @@ -103,7 +103,7 @@ static void free_attr(std::map *al) %token TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK -%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR +%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY @@ -438,6 +438,13 @@ param_integer: astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); } | /* empty */; +param_real: + TOK_REAL { + if (astbuf1->children.size() != 1) + frontend_verilog_yyerror("Syntax error."); + astbuf1->children.push_back(new AstNode(AST_REALVALUE)); + } | /* empty */; + param_range: range { if ($1 != NULL) { @@ -451,7 +458,7 @@ param_decl: TOK_PARAMETER { astbuf1 = new AstNode(AST_PARAMETER); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); - } param_signed param_integer param_range param_decl_list ';' { + } param_signed param_integer param_real param_range param_decl_list ';' { delete astbuf1; }; @@ -459,7 +466,7 @@ localparam_decl: TOK_LOCALPARAM { astbuf1 = new AstNode(AST_LOCALPARAM); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); - } param_signed param_integer param_range param_decl_list ';' { + } param_signed param_integer param_real param_range param_decl_list ';' { delete astbuf1; }; @@ -1133,7 +1140,7 @@ basic_expr: log_error("Value conversion failed: `%s'\n", $1->c_str()); delete $1; } | - TOK_REAL { + TOK_REALVAL { $$ = new AstNode(AST_REALVALUE); char *p = strdup($1->c_str()), *q; for (int i = 0, j = 0; !p[j]; j++) -- cgit v1.2.3 From 406f86a91ec0ed024037e27d1cbf2a1bc73777d9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 12:01:17 +0200 Subject: 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 000000000..47f81214a --- /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 -- cgit v1.2.3 From f3b4a9dd2466d243fdb1b4ebf8c5e1e0d05d21af Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 13:36:23 +0200 Subject: Added support for math functions --- frontends/ast/simplify.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++ tests/simple/realexpr.v | 57 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index a5c4d0230..89dc8ef73 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1215,6 +1215,10 @@ skip_dynamic_range_lvalue_expansion:; { if (str == "\\$clog2") { + if (children.size() != 1) + log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", + RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + AstNode *buf = children[0]->clone(); while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) @@ -1230,6 +1234,72 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } + if (str == "\\$ln" || str == "\\$log10" || str == "\\$exp" || str == "\\$sqrt" || str == "\\$pow" || + str == "\\$floor" || str == "\\$ceil" || str == "\\$sin" || str == "\\$cos" || str == "\\$tan" || + str == "\\$asin" || str == "\\$acos" || str == "\\$atan" || str == "\\$atan2" || str == "\\$hypot" || + str == "\\$sinh" || str == "\\$cosh" || str == "\\$tanh" || str == "\\$asinh" || str == "\\$acosh" || str == "\\$atanh") + { + bool func_with_two_arguments = str == "\\$pow" || str == "\\$atan2" || str == "\\$hypot"; + double x = 0, y = 0; + + if (func_with_two_arguments) { + if (children.size() != 2) + log_error("System function %s got %d arguments, expected 2 at %s:%d.\n", + RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + } else { + if (children.size() != 1) + log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", + RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + } + + if (children.size() >= 1) { + while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + if (!children[0]->isConst()) + log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", + RTLIL::id2cstr(str), filename.c_str(), linenum); + int child_width_hint = width_hint; + bool child_sign_hint = sign_hint; + children[0]->detectSignWidth(child_width_hint, child_sign_hint); + x = children[0]->asReal(child_sign_hint); + } + + if (children.size() >= 2) { + while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + if (!children[1]->isConst()) + log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", + RTLIL::id2cstr(str), filename.c_str(), linenum); + int child_width_hint = width_hint; + bool child_sign_hint = sign_hint; + children[1]->detectSignWidth(child_width_hint, child_sign_hint); + y = children[1]->asReal(child_sign_hint); + } + + newNode = new AstNode(AST_REALVALUE); + if (str == "\\$ln") newNode->realvalue = log(x); + else if (str == "\\$log10") newNode->realvalue = log10(x); + else if (str == "\\$exp") newNode->realvalue = exp(x); + else if (str == "\\$sqrt") newNode->realvalue = sqrt(x); + else if (str == "\\$pow") newNode->realvalue = pow(x, y); + else if (str == "\\$floor") newNode->realvalue = floor(x); + else if (str == "\\$ceil") newNode->realvalue = ceil(x); + else if (str == "\\$sin") newNode->realvalue = sin(x); + else if (str == "\\$cos") newNode->realvalue = cos(x); + else if (str == "\\$tan") newNode->realvalue = tan(x); + else if (str == "\\$asin") newNode->realvalue = asin(x); + else if (str == "\\$acos") newNode->realvalue = acos(x); + else if (str == "\\$atan") newNode->realvalue = atan(x); + else if (str == "\\$atan2") newNode->realvalue = atan2(x, y); + else if (str == "\\$hypot") newNode->realvalue = hypot(x, y); + else if (str == "\\$sinh") newNode->realvalue = sinh(x); + else if (str == "\\$cosh") newNode->realvalue = cosh(x); + else if (str == "\\$tanh") newNode->realvalue = tanh(x); + else if (str == "\\$asinh") newNode->realvalue = asinh(x); + else if (str == "\\$acosh") newNode->realvalue = acosh(x); + else if (str == "\\$atanh") newNode->realvalue = atanh(x); + else log_abort(); + goto apply_newNode; + } + if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 47f81214a..2b63ca6f9 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 + -- cgit v1.2.3 From 22a998903b14b93180b98fe71129160e27793e38 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 16:19:32 +0200 Subject: 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 59f936b01..38d43f8df 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"); -- cgit v1.2.3 From 1a487303a081849bd7561772641f90126dcce24e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 16:42:30 +0200 Subject: 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 13ec3d193..64c4af721 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 000000000..cf658897d --- /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 000000000..a12beadad --- /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 000000000..d4c1fa2bb --- /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 000000000..2ef14c56e --- /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 + -- cgit v1.2.3 From ebe2d733302fea50b75d3dd43d1a115e43dcb523 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 19:24:01 +0200 Subject: 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 000000000..c76533213 --- /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') + -- cgit v1.2.3 From d5765b5e14319c20a62a20f470e8ec5dc48d0010 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 19:33:58 +0200 Subject: Fixed relational operators for const real expressions --- frontends/ast/simplify.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 89dc8ef73..61bc03b9f 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1539,14 +1539,14 @@ skip_dynamic_range_lvalue_expansion:; } else if (children[0]->isConst() && children[1]->isConst()) { switch (type) { - case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); - case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); - case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); - case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); - case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); - case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); - case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); - case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); + case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); break; + case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); break; + case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; + case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; + case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; + case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; + case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); break; + case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); break; default: log_abort(); } } -- cgit v1.2.3 From 39eb347c67056f9b56ecfdab1704362d4cd276e1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 19:56:22 +0200 Subject: 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 c76533213..f280e1c3d 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 000000000..9568cdd6a --- /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 + -- cgit v1.2.3 From 149fe83a8dbe37fecc16326163bbc40400147a9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 20:38:05 +0200 Subject: improved (fixed) conversion of real values to bit vectors --- frontends/ast/ast.cc | 18 ++++++++++++++++++ frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 8 ++++---- frontends/ast/simplify.cc | 14 +++++++------- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index f3cf8fa7a..25ea3a824 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -794,6 +794,24 @@ double AstNode::asReal(bool is_signed) log_abort(); } +RTLIL::Const AstNode::realAsConst(int width) +{ + double v = round(realvalue); + RTLIL::Const result; + if (!isfinite(v)) { + result.bits = std::vector(width, RTLIL::State::Sx); + } else { + bool is_negative = v < 0; + if (is_negative) + v *= -1; + for (int i = 0; i < width; i++, v /= 2) + result.bits.push_back((int(v) & 1) ? RTLIL::State::S1 : RTLIL::State::S0); + if (is_negative) + result = const_neg(result, result, false, false, result.bits.size()); + } + return result; +} + // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer) { diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 95f0f142f..74a476b5e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -244,6 +244,7 @@ namespace AST // helper functions for real valued const eval int isConst(); // return '1' for AST_CONSTANT and '2' for AST_REALVALUE double asReal(bool is_signed); + RTLIL::Const realAsConst(int width); }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 5b43f57ff..8a57a0ee7 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -915,10 +915,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_REALVALUE: { - int intvalue = round(realvalue); - log("Warning: converting real value %e to integer %d at %s:%d.\n", - realvalue, intvalue, filename.c_str(), linenum); - return RTLIL::SigSpec(intvalue); + RTLIL::SigSpec sig = realAsConst(width_hint); + log("Warning: converting real value %e to binary %s at %s:%d.\n", + realvalue, log_signal(sig), filename.c_str(), linenum); + return sig; } // simply return the corresponding RTLIL::SigSpec for an AST_IDENTIFIER node diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 61bc03b9f..ed5ee1721 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -527,18 +527,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // trim/extend parameters if (type == AST_PARAMETER || type == AST_LOCALPARAM) { if (children.size() > 1 && children[1]->type == AST_RANGE) { + if (!children[1]->range_valid) + log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); + int width = children[1]->range_left - children[1]->range_right + 1; if (children[0]->type == AST_REALVALUE) { - int intvalue = round(children[0]->realvalue); - log("Warning: converting real value %e to integer %d at %s:%d.\n", - children[0]->realvalue, intvalue, filename.c_str(), linenum); + RTLIL::Const constvalue = children[0]->realAsConst(width); + log("Warning: converting real value %e to binary %s at %s:%d.\n", + realvalue, log_signal(constvalue), filename.c_str(), linenum); delete children[0]; - children[0] = mkconst_int(intvalue, sign_hint); + children[0] = mkconst_bits(constvalue.bits, sign_hint); did_something = true; } if (children[0]->type == AST_CONSTANT) { - if (!children[1]->range_valid) - log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum); - int width = children[1]->range_left - children[1]->range_right + 1; if (width != int(children[0]->bits.size())) { RTLIL::SigSpec sig(children[0]->bits); sig.extend_u0(width, children[0]->is_signed); -- cgit v1.2.3 From 11d2add1b9984a9dabe02e5073e09ca497024dd8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 20:38:40 +0200 Subject: 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 f280e1c3d..af7648b87 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;') -- cgit v1.2.3 From 48dc6ab98dbd74bd7eb00f14b4bd8429531166f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:38:31 +0200 Subject: Improved AstNode::asReal for large integers --- frontends/ast/ast.cc | 21 ++++++++++++--------- frontends/ast/simplify.cc | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 25ea3a824..cc7f442bb 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -775,17 +775,20 @@ int AstNode::isConst() double AstNode::asReal(bool is_signed) { if (type == AST_CONSTANT) { - RTLIL::Const val; - val.bits = bits; + RTLIL::Const val(bits); - double p = exp2(int(val.bits.size())-32); - if (val.bits.size() > 32) - val.bits.erase(val.bits.begin(), val.bits.begin()+(int(val.bits.size())-32)); - int32_t v = val.as_int() << (32-int(val.bits.size())); + bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1; + if (is_negative) + val = const_neg(val, val, false, false, val.bits.size()); - if (is_signed) - return v * p; - return uint32_t(v) * p; + double v = 0; + for (size_t i = 0; i < val.bits.size(); i++) + if (val.bits.at(i) == RTLIL::State::S1) + v += exp2(i); + if (is_negative) + v *= -1; + + return v; } if (type == AST_REALVALUE) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index ed5ee1721..80fd28d55 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -533,7 +533,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (children[0]->type == AST_REALVALUE) { RTLIL::Const constvalue = children[0]->realAsConst(width); log("Warning: converting real value %e to binary %s at %s:%d.\n", - realvalue, log_signal(constvalue), filename.c_str(), linenum); + children[0]->realvalue, log_signal(constvalue), filename.c_str(), linenum); delete children[0]; children[0] = mkconst_bits(constvalue.bits, sign_hint); did_something = true; -- cgit v1.2.3 From 7f57bc838517a5660beaf0645d7bb4cc6ed71ce9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:48:17 +0200 Subject: Improved parsing of large integer constants --- frontends/verilog/const2ast.cc | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index c95ce5dc4..8491a6b47 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -52,6 +52,8 @@ static int my_decimal_div_by_two(std::vector &digits) carry = digits[i] % 2; digits[i] /= 2; } + while (!digits.empty() && !digits.front()) + digits.erase(digits.begin()); return carry; } @@ -90,10 +92,15 @@ static void my_strtobin(std::vector &data, const char *str, int le if (base == 10) { data.clear(); - if (len_in_bits < 0) - len_in_bits = ceil(digits.size()/log10(2)); - for (int i = 0; i < len_in_bits; i++) - data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + if (len_in_bits < 0) { + while (!digits.empty()) + data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + while (data.size() < 32) + data.push_back(RTLIL::S0); + } else { + for (int i = 0; i < len_in_bits; i++) + data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + } return; } @@ -151,20 +158,24 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) str = code.c_str(); char *endptr; - long intval = strtol(str, &endptr, 10); + long len_in_bits = strtol(str, &endptr, 10); + + // Simple base-10 integer + if (*endptr == 0) { + std::vector data; + my_strtobin(data, str, -1, 10, case_type); + if (data.back() == RTLIL::S1) + data.push_back(RTLIL::S0); + return AstNode::mkconst_bits(data, true); + } - // Simple 32 bit integer - if (*endptr == 0) - return AstNode::mkconst_int(intval, true); - // unsized constant if (str == endptr) - intval = -1; + len_in_bits = -1; // The "'s?[bodh]" syntax if (*endptr == '\'') { - int len_in_bits = intval; std::vector data; bool is_signed = false; if (*(endptr+1) == 's') { @@ -188,6 +199,12 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) default: return NULL; } + if (len_in_bits < 0) { + if (is_signed && data.back() == RTLIL::S1) + data.push_back(RTLIL::S0); + while (data.size() < 32) + data.push_back(RTLIL::S0); + } return AstNode::mkconst_bits(data, is_signed); } -- cgit v1.2.3 From 656685fa31b54cebf0210518d3cac8aa496dddd7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:48:41 +0200 Subject: 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 af7648b87..58cedf028 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 9568cdd6a..48e87417c 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 -- cgit v1.2.3 From 4d1df128fa42a9e6718f38e794be8b2f8c2ff7c7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 09:27:09 +0200 Subject: Improved AstNode::realAsConst for large numbers --- frontends/ast/ast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index cc7f442bb..967111d30 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -808,7 +808,7 @@ RTLIL::Const AstNode::realAsConst(int width) if (is_negative) v *= -1; for (int i = 0; i < width; i++, v /= 2) - result.bits.push_back((int(v) & 1) ? RTLIL::State::S1 : RTLIL::State::S0); + result.bits.push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0); if (is_negative) result = const_neg(result, result, false, false, result.bits.size()); } -- cgit v1.2.3 From a4ec19c25c97d68b9347d3d98637add7b18cf073 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 09:31:03 +0200 Subject: 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 a84215b27..61fb5dc49 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 bf27d15f8..9153f55ff 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 b8e7231c7..199bb916e 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 48e87417c..a28863d31 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 eb6fd10ba..3d00c7eb2 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 -- cgit v1.2.3 From 398482eced4c16a22a5617246f75bbd14eaa618f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 09:39:22 +0200 Subject: 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 2b63ca6f9..351661103 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 - -- cgit v1.2.3 From b1b96d199f7d0b97d203e3fd60af698ebaf03d73 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 11:51:51 +0200 Subject: Added more calls to "hierarchy" to README file --- README | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README b/README index 05628a8e3..ba90e72a6 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 -- cgit v1.2.3 From 5bfe865cec15c12e2a9e764a0a57c01f97f8235e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:00:57 +0200 Subject: Added found_real feature to AstNode::detectSignWidth --- frontends/ast/ast.h | 4 ++-- frontends/ast/genrtlil.cc | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 74a476b5e..f89af633e 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -214,8 +214,8 @@ namespace AST void dumpVlog(FILE *f, std::string indent); // used by genRTLIL() for detecting expression width and sign - void detectSignWidthWorker(int &width_hint, bool &sign_hint); - void detectSignWidth(int &width_hint, bool &sign_hint); + void detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real = NULL); + void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real = NULL); // create RTLIL code for this AST node // for expressions the resulting signal vector is returned diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 8a57a0ee7..1f0ef4450 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -585,7 +585,7 @@ struct AST_INTERNAL::ProcessGenerator }; // detect sign and width of an expression -void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) +void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *found_real) { std::string type_name; bool sub_sign_hint = true; @@ -603,6 +603,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) break; case AST_REALVALUE: + if (found_real) + *found_real = true; width_hint = std::max(width_hint, 32); break; @@ -788,10 +790,13 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint) } // detect sign and width of an expression -void AstNode::detectSignWidth(int &width_hint, bool &sign_hint) +void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real) { - width_hint = -1, sign_hint = true; - detectSignWidthWorker(width_hint, sign_hint); + width_hint = -1; + sign_hint = true; + if (found_real) + *found_real = false; + detectSignWidthWorker(width_hint, sign_hint, found_real); } // create RTLIL from an AST node -- cgit v1.2.3 From 0c4c79c4c6f8a433ef4b141b1523bccc261f8231 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:02:40 +0200 Subject: Fixed parsing of TOK_INTEGER (implies TOK_SIGNED) --- frontends/verilog/parser.y | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 57defd56b..37c3232aa 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -108,7 +108,7 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY -%type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type wire_type range non_opt_range range_or_signed_int expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -322,6 +322,7 @@ wire_type_token: astbuf3->is_reg = true; astbuf3->range_left = 31; astbuf3->range_right = 0; + astbuf3->is_signed = true; } | TOK_GENVAR { astbuf3->type = AST_GENVAR; @@ -362,7 +363,7 @@ range: $$ = NULL; }; -range_or_integer: +range_or_signed_int: range { $$ = $1; } | @@ -370,6 +371,7 @@ range_or_integer: $$ = new AstNode(AST_RANGE); $$->children.push_back(AstNode::mkconst_int(31, true)); $$->children.push_back(AstNode::mkconst_int(0, true)); + $$->is_signed = true; }; module_body: @@ -394,16 +396,19 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range_or_integer TOK_ID ';' { + TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$4; ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); AstNode *outreg = new AstNode(AST_WIRE); - if ($3 != NULL) - outreg->children.push_back($3); outreg->str = *$4; outreg->is_signed = $2; + if ($3 != NULL) { + outreg->children.push_back($3); + outreg->is_signed = $2 || $3->is_signed; + $3->is_signed = false; + } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; delete $4; @@ -436,6 +441,7 @@ param_integer: astbuf1->children.push_back(new AstNode(AST_RANGE)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); + astbuf1->is_signed = true; } | /* empty */; param_real: -- cgit v1.2.3 From 82bbd2f0772e62555eb669eb64883d75de4ca29a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:05:37 +0200 Subject: Use undef (x/z vs. NaN) rules for real values from IEEE Std 1800-2012 --- frontends/ast/ast.cc | 2 ++ frontends/ast/simplify.cc | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 967111d30..3f704bea4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -783,6 +783,8 @@ double AstNode::asReal(bool is_signed) double v = 0; for (size_t i = 0; i < val.bits.size(); i++) + // IEEE Std 1800-2012 Par 6.12.2: Individual bits that are x or z in + // the net or the variable shall be treated as zero upon conversion. if (val.bits.at(i) == RTLIL::State::S1) v += exp2(i); if (is_negative) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 80fd28d55..3f712510b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1625,6 +1625,15 @@ skip_dynamic_range_lvalue_expansion:; if (a.bits[i] != b.bits[i]) a.bits[i] = RTLIL::State::Sx; newNode = mkconst_bits(a.bits, sign_hint); + } else if (children[1]->isConst() && children[2]->isConst()) { + newNode = new AstNode(AST_REALVALUE); + if (children[1]->asReal(sign_hint) == children[2]->asReal(sign_hint)) + newNode->realvalue = children[1]->asReal(sign_hint); + else + // IEEE Std 1800-2012 Sec. 11.4.11 states that the entry in Table 7-1 for + // the data type in question should be returned if the ?: is ambiguous. The + // value in Table 7-1 for the 'real' type is 0.0. + newNode->realvalue = 0.0; } } break; -- cgit v1.2.3 From 6c17d4f242ae2acb1581869b3ca904a0adbddc13 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:12:24 +0200 Subject: Improved ternary support for real values --- frontends/ast/simplify.cc | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 3f712510b..7be287d19 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1588,31 +1588,42 @@ skip_dynamic_range_lvalue_expansion:; } break; case AST_TERNARY: - if (children[0]->isConst()) { + if (children[0]->isConst()) + { bool found_sure_true = false; bool found_maybe_true = false; - if (children[0]->type == AST_CONSTANT) { + + if (children[0]->type == AST_CONSTANT) for (auto &bit : children[0]->bits) { if (bit == RTLIL::State::S1) found_sure_true = true; if (bit > RTLIL::State::S1) found_maybe_true = true; } - } else { - found_sure_true = children[0]->asReal(false) != 0; - } - AstNode *choice = NULL; + else + found_sure_true = children[0]->asReal(sign_hint) != 0; + + AstNode *choice = NULL, *not_choice = NULL; if (found_sure_true) - choice = children[1]; + choice = children[1], not_choice = children[2]; else if (!found_maybe_true) - choice = children[2]; + choice = children[2], not_choice = children[1]; + if (choice != NULL) { if (choice->type == AST_CONSTANT) { - RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); - if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) - newNode = mkconst_str(y.bits); - else - newNode = mkconst_bits(y.bits, sign_hint); + int other_width_hint = width_hint; + bool other_sign_hint = sign_hint, other_real = false; + not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real); + if (other_real) { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = choice->asReal(sign_hint); + } else { + RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); + if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false) + newNode = mkconst_str(y.bits); + else + newNode = mkconst_bits(y.bits, sign_hint); + } } else if (choice->isConst()) { newNode = choice->clone(); -- cgit v1.2.3 From 88470283c995860c593bae03373a0b26408b0e94 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:21:08 +0200 Subject: 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 000000000..9c595a6fb --- /dev/null +++ b/tests/realmath/.gitignore @@ -0,0 +1 @@ +temp diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index 58cedf028..9e48755c5 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') -- cgit v1.2.3 From 798ff88855a6e9b8eb82a48fb4d39f78807200d9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 12:47:51 +0200 Subject: Improved handling of relational op of real values --- frontends/ast/simplify.cc | 17 +++++++++-------- 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 7be287d19..7a98e2712 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1538,15 +1538,16 @@ skip_dynamic_range_lvalue_expansion:; newNode = mkconst_bits(y.bits, false); } else if (children[0]->isConst() && children[1]->isConst()) { + bool cmp_signed = (children[0]->type == AST_REALVALUE || children[0]->is_signed) && (children[1]->type == AST_REALVALUE || children[1]->is_signed); switch (type) { - case AST_LT: newNode = mkconst_int(children[0]->asReal(sign_hint) < children[1]->asReal(sign_hint), false, 1); break; - case AST_LE: newNode = mkconst_int(children[0]->asReal(sign_hint) <= children[1]->asReal(sign_hint), false, 1); break; - case AST_EQ: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; - case AST_NE: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; - case AST_EQX: newNode = mkconst_int(children[0]->asReal(sign_hint) == children[1]->asReal(sign_hint), false, 1); break; - case AST_NEX: newNode = mkconst_int(children[0]->asReal(sign_hint) != children[1]->asReal(sign_hint), false, 1); break; - case AST_GE: newNode = mkconst_int(children[0]->asReal(sign_hint) >= children[1]->asReal(sign_hint), false, 1); break; - case AST_GT: newNode = mkconst_int(children[0]->asReal(sign_hint) > children[1]->asReal(sign_hint), false, 1); break; + case AST_LT: newNode = mkconst_int(children[0]->asReal(cmp_signed) < children[1]->asReal(cmp_signed), false, 1); break; + case AST_LE: newNode = mkconst_int(children[0]->asReal(cmp_signed) <= children[1]->asReal(cmp_signed), false, 1); break; + case AST_EQ: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; + case AST_NE: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; + case AST_EQX: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break; + case AST_NEX: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break; + case AST_GE: newNode = mkconst_int(children[0]->asReal(cmp_signed) >= children[1]->asReal(cmp_signed), false, 1); break; + case AST_GT: newNode = mkconst_int(children[0]->asReal(cmp_signed) > children[1]->asReal(cmp_signed), false, 1); break; default: log_abort(); } } diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py index 9e48755c5..53015381e 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') -- cgit v1.2.3 From 80e459469576b82975a5cf663b4aba2e044d9476 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 21:39:25 +0200 Subject: Added AstNode::MEM2REG_FL_CMPLX_LHS --- frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index f89af633e..8253a2052 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -188,6 +188,7 @@ namespace AST MEM2REG_FL_SET_ELSE = 0x00000400, MEM2REG_FL_SET_ASYNC = 0x00000800, MEM2REG_FL_EQ2 = 0x00001000, + MEM2REG_FL_CMPLX_LHS = 0x00002000, /* proc flags */ MEM2REG_FL_EQ1 = 0x01000000, diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7a98e2712..0b0e46f2c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -90,6 +90,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE)) goto verbose_activate; + if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS) + goto verbose_activate; + // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags)); continue; @@ -1757,6 +1760,21 @@ void AstNode::replace_ids(std::map &rules) child->replace_ids(rules); } +// helper function for mem2reg_as_needed_pass1 +static void mark_memories_assign_lhs_complex(std::map> &mem2reg_places, + std::map &mem2reg_candidates, AstNode *that) +{ + for (auto &child : that->children) + mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, child); + + if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) { + AstNode *mem = that->id2ast; + if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS)) + mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->linenum)); + mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS; + } +} + // find memories that should be replaced by registers void AstNode::mem2reg_as_needed_pass1(std::map> &mem2reg_places, std::map &mem2reg_candidates, std::map &proc_flags, uint32_t &flags) @@ -1766,6 +1784,10 @@ void AstNode::mem2reg_as_needed_pass1(std::map> if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) { + // mark all memories that are used in a complex expression on the left side of an assignment + for (auto &lhs_child : children[0]->children) + mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, lhs_child); + if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY) { AstNode *mem = children[0]->id2ast; -- cgit v1.2.3 From df76da8fd710394e7ea999e90994483da223f545 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jun 2014 21:49:59 +0200 Subject: 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 e2c136ddb..3630b57c7 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 + -- cgit v1.2.3 From 1c85584fe5843a43590de3927fe9bde74a04e72e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 19 Jun 2014 12:29:29 +0200 Subject: 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 2ec498fb2..c18446512 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"); -- cgit v1.2.3 From b18fa95d2f1f4118cdb7c16e3415059bd81e2325 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 16:33:33 +0200 Subject: 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 64c4af721..3f0749cdd 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. + +\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. -\begin{frame}{\subsubsecname} -TBD +\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} + +\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 + +# 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} -\subsubsection{TBD} +\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.) -\begin{frame}{\subsubsecname} -TBD +\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 a12beadad..4864d8d52 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 000000000..25a1feee4 --- /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 000000000..0be833f16 --- /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 000000000..19663ac77 --- /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 000000000..09a4045db --- /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 432ce3688..d1d8abe45 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 bcff48aad..c34eae3ff 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 64c0b87c5..4fd86e854 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; -- cgit v1.2.3 From 072604f30f58ab535bfd8d004163607900adf86e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 21:13:18 +0200 Subject: 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 3f0749cdd..9e7e9dc7f 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 -- cgit v1.2.3 From 65b2e9c0645c30d84a9d9be148430fd76d3e5f05 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 21:41:13 +0200 Subject: fixed signdness detection for expressions with reals --- frontends/ast/genrtlil.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 1f0ef4450..9f18efce0 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -594,6 +594,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun AstNode *range = NULL; AstNode *id_ast = NULL; + bool local_found_real = false; + if (found_real == NULL) + found_real = &local_found_real; + switch (type) { case AST_CONSTANT: @@ -603,8 +607,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; case AST_REALVALUE: - if (found_real) - *found_real = true; + *found_real = true; width_hint = std::max(width_hint, 32); break; @@ -787,6 +790,9 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun log_error("Don't know how to detect sign and width for %s node at %s:%d!\n", type2str(type).c_str(), filename.c_str(), linenum); } + + if (*found_real) + sign_hint = true; } // detect sign and width of an expression -- cgit v1.2.3 From 3345fa0bab5d343a9cd5a9dde6486e4e876fe8da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jun 2014 21:43:04 +0200 Subject: 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 53015381e..972021dc8 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 351661103..2adffe2dd 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 + -- cgit v1.2.3 From a7aea179599045feafcaf26f5ed334a7318a69b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 22 Jun 2014 12:50:29 +0200 Subject: 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 45f0cb0c6..1e7f697b1 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} + +\begin{frame}[t, fragile]{\subsubsecname} +The {\tt RTLIL::State} enum represents a simple 1-bit logic level: + +\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} -\subsection{RTLIL::Cell} +\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} -\begin{frame}{\subsecname} -TBD +\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 000000000..7fd560762 --- /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 000000000..8da6bcd63 --- /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 000000000..ca0a115a0 --- /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 000000000..cf8a4add8 --- /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 000000000..18dcf5eb7 --- /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 6771ba7c9..980e17723 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 -- cgit v1.2.3 From 4fc43d19324eabcfe3a3788743a212ae684509cd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 24 Jun 2014 15:08:48 +0200 Subject: More found_real-related fixes to AstNode::detectSignWidthWorker --- frontends/ast/genrtlil.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9f18efce0..787f4d2d8 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -713,7 +713,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_NEG: case AST_BIT_NOT: case AST_POS: - children[0]->detectSignWidthWorker(width_hint, sign_hint); + children[0]->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_BIT_AND: @@ -721,7 +721,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_BIT_XOR: case AST_BIT_XNOR: for (auto child : children) - child->detectSignWidthWorker(width_hint, sign_hint); + child->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_REDUCE_AND: @@ -738,7 +738,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_SHIFT_SLEFT: case AST_SHIFT_SRIGHT: case AST_POW: - children[0]->detectSignWidthWorker(width_hint, sign_hint); + children[0]->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_LT: @@ -759,7 +759,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_DIV: case AST_MOD: for (auto child : children) - child->detectSignWidthWorker(width_hint, sign_hint); + child->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_LOGIC_AND: @@ -770,8 +770,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; case AST_TERNARY: - children.at(1)->detectSignWidthWorker(width_hint, sign_hint); - children.at(2)->detectSignWidthWorker(width_hint, sign_hint); + children.at(1)->detectSignWidthWorker(width_hint, sign_hint, found_real); + children.at(2)->detectSignWidthWorker(width_hint, sign_hint, found_real); break; case AST_MEMRD: -- cgit v1.2.3 From 076182c34e34b5e59eb5d89d5001f7547102bb4d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 25 Jun 2014 10:05:36 +0200 Subject: Fixed handling of mixed real/int ternary expressions --- frontends/ast/simplify.cc | 16 ++++++++++++++++ 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 0b0e46f2c..db7f5ca34 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -247,6 +247,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, bool detect_width_simple = false; bool child_0_is_self_determined = false; bool child_1_is_self_determined = false; + bool child_2_is_self_determined = false; bool children_are_self_determined = false; bool reset_width_after_children = false; @@ -367,6 +368,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, detectSignWidth(width_hint, sign_hint); } + if (type == AST_TERNARY) { + int width_hint_left, width_hint_right; + bool sign_hint_left, sign_hint_right; + bool found_real_left, found_real_right; + children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left); + children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right); + if (found_real_left || found_real_right) { + child_1_is_self_determined = true; + child_2_is_self_determined = true; + } + } + // simplify all children first // (iterate by index as e.g. auto wires can add new children in the process) for (size_t i = 0; i < children.size(); i++) { @@ -402,6 +415,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint_here = -1, sign_hint_here = false; if (i == 1 && child_1_is_self_determined) width_hint_here = -1, sign_hint_here = false; + if (i == 2 && child_2_is_self_determined) + width_hint_here = -1, sign_hint_here = false; if (children_are_self_determined) width_hint_here = -1, sign_hint_here = false; did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here); @@ -1620,6 +1635,7 @@ skip_dynamic_range_lvalue_expansion:; not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real); if (other_real) { newNode = new AstNode(AST_REALVALUE); + choice->detectSignWidth(width_hint, sign_hint); newNode->realvalue = choice->asReal(sign_hint); } else { RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint); diff --git a/tests/simple/realexpr.v b/tests/simple/realexpr.v index 2adffe2dd..5b756e6be 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 -- cgit v1.2.3 From 3e96ce86809fa0a4ea737fa4a9d3e6261f40a191 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 26 Jun 2014 22:05:39 +0200 Subject: 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 7aa014242..471516b40 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 9e7e9dc7f..f86dcd7ac 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 d1d8abe45..f68b6f984 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 543fb41ed..40b3c2268 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 bcfe387e4..8b3390ed4 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 1e7f697b1..21a93d55c 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 35a409cbe..d098e815f 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} -- cgit v1.2.3 From 89c85cac419b7dc60e3776a250bcdc39dcb8980b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 28 Jun 2014 12:11:42 +0200 Subject: Added links to some liberty files to README --- README | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README b/README index ba90e72a6..4384cfbdd 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. -- cgit v1.2.3 From 3a3f5d5923840f44a6fb30fc7d70b6ed6ad7ccbb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 29 Jun 2014 09:14:49 +0200 Subject: 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 40b3c2268..7697266de 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 d098e815f..a76a1c00b 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. -- cgit v1.2.3 From d26561cc44d90bd83a7c55d5270bf4cbade0a8f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 29 Jun 2014 09:27:03 +0200 Subject: 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 a76a1c00b..cad9e9f15 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} -- cgit v1.2.3 From 1c81ab49e7b57f4c64e533a3617fe8bbe257cdb5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Jul 2014 06:16:31 +0200 Subject: 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 cad9e9f15..9a876de0c 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} -- cgit v1.2.3 From ee8ad72fd950e1ee204e5c97155a50b8b1445dec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Jul 2014 06:27:04 +0200 Subject: fixed parsing of constant with comment between size and value --- frontends/verilog/parser.y | 7 +++++++ tests/simple/macros.v | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 37c3232aa..ce7b99272 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -1140,6 +1140,13 @@ basic_expr: delete $1; delete $2; } | + TOK_CONST TOK_CONST { + $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back()); + if ($$ == NULL || (*$2)[0] != '\'') + log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str()); + delete $1; + delete $2; + } | TOK_CONST { $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back()); if ($$ == NULL) diff --git a/tests/simple/macros.v b/tests/simple/macros.v index cda46cb48..a3e8d70f8 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 -- cgit v1.2.3 From 3b52121d328d45a5d4269fd0e8de9af948c0216e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 5 Jul 2014 11:17:40 +0200 Subject: 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 87bff4c48..a9a00d8a2 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 000000000..5b661f8d6 --- /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 000000000..2079d2f34 --- /dev/null +++ b/tests/sat/initval.ys @@ -0,0 +1,4 @@ +read_verilog -sv initval.v +proc;; + +sat -seq 10 -prove-asserts -- cgit v1.2.3 From 55a1b8dbac91373979289c535bed61a32717f62b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 11 Jul 2014 13:05:53 +0200 Subject: Fixed processing of initial values for block-local variables --- frontends/ast/simplify.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index db7f5ca34..e547ede36 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -423,6 +423,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (did_something_here) did_something = true; } + if (stage == 2 && children[i]->type == AST_INITIAL && current_ast_mod != this) { + current_ast_mod->children.push_back(children[i]); + children.erase(children.begin() + (i--)); + did_something = true; + } } for (auto &attr : attributes) { while (attr.second->simplify(true, false, false, stage, -1, false, true)) -- cgit v1.2.3 From 847e2ee4a130559f7ee002542560a9fcbe1dfc71 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 11 Jul 2014 13:10:51 +0200 Subject: 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 da4962b82..577fbe3d9 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") -- cgit v1.2.3 From 0f9ca49dc6047ad5634782de23040ec57601debd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 12 Jul 2014 10:02:39 +0200 Subject: Added passing of various options to vhdl2verilog --- frontends/vhdl2verilog/vhdl2verilog.cc | 41 +++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 83035d329..4392ed444 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -45,13 +45,25 @@ struct Vhdl2verilogPass : public Pass { log(" specified file.\n"); log("\n"); log(" -vhdl2verilog_dir \n"); - log(" do use the specified vhdl2verilog installations. this is the directory\n"); + log(" do use the specified vhdl2verilog installation. this is the directory\n"); log(" that contains the setup_env.sh file. when this option is not present,\n"); log(" it is assumed that vhdl2verilog is in the PATH environment variable.\n"); log("\n"); log(" -top \n"); log(" The name of the top entity. This option is mandatory.\n"); log("\n"); + log("The following options are passed as-is to vhdl2verilog:\n"); + log("\n"); + log(" -arch \n"); + log(" -unroll_generate\n"); + log(" -nogenericeval\n"); + log(" -nouniquify\n"); + log(" -oldparser\n"); + log(" -suppress \n"); + log(" -quiet\n"); + log(" -nobanner\n"); + log(" -mapfile \n"); + log("\n"); log("vhdl2verilog can be obtained from:\n"); log("http://www.edautils.com/vhdl2verilog.html\n"); log("\n"); @@ -63,6 +75,7 @@ struct Vhdl2verilogPass : public Pass { std::string out_file, top_entity; std::string vhdl2verilog_dir; + std::string extra_opts; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -78,6 +91,24 @@ struct Vhdl2verilogPass : public Pass { vhdl2verilog_dir = args[++argidx]; continue; } + if ((args[argidx] == "-arch" || args[argidx] == "-suppress" || args[argidx] == "-mapfile") && argidx+1 < args.size()) { + if (args[argidx] == "-mapfile" && !args[argidx+1].empty() && args[argidx+1][0] != '/') { + char pwd[PATH_MAX]; + if (!getcwd(pwd, sizeof(pwd))) { + log_cmd_error("getcwd failed: %s", strerror(errno)); + log_abort(); + } + args[argidx+1] = pwd + ("/" + args[argidx+1]); + } + extra_opts += std::string(" ") + args[argidx]; + extra_opts += std::string(" '") + args[++argidx] + std::string("'"); + continue; + } + if (args[argidx] == "-unroll_generate" || args[argidx] == "-nogenericeval" || args[argidx] == "-nouniquify" || + args[argidx] == "-oldparser" || args[argidx] == "-quiet" || args[argidx] == "-nobanner") { + extra_opts += std::string(" ") + args[argidx]; + continue; + } break; } @@ -95,7 +126,7 @@ struct Vhdl2verilogPass : public Pass { log_error("For some reason mkdtemp() failed!\n"); if (!out_file.empty() && out_file[0] != '/') { - char pwd [PATH_MAX]; + char pwd[PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { log_cmd_error("getcwd failed: %s", strerror(errno)); log_abort(); @@ -109,7 +140,7 @@ struct Vhdl2verilogPass : public Pass { if (file.empty()) continue; if (file[0] != '/') { - char pwd [PATH_MAX]; + char pwd[PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { log_cmd_error("getcwd failed: %s", strerror(errno)); log_abort(); @@ -124,8 +155,8 @@ struct Vhdl2verilogPass : public Pass { std::string command = "exec 2>&1; "; if (!vhdl2verilog_dir.empty()) command += stringf("cd '%s'; . ./setup_env.sh; ", vhdl2verilog_dir.c_str()); - command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'", tempdir_name, - out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str()); + command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'%s", tempdir_name, + out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str(), extra_opts.c_str()); log("Running '%s'..\n", command.c_str()); -- cgit v1.2.3 From 964a67ac4194bb85fb3cb7a90a62dc1e4a685ea4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 10:03:07 +0200 Subject: 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 9153f55ff..a204360d7 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 199bb916e..89be6d052 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 a28863d31..b8e222ad6 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 3d00c7eb2..ec1802cbd 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 d459f988e..ff431eaf7 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 -- cgit v1.2.3 From 73e0e13d2f1b959a05d69ed715c8fdde84894d6f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 11:38:02 +0200 Subject: 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 028cd6d81..c4c08d5b8 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 e7895521a..f09c49298 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. -- cgit v1.2.3 From dcdd5c11b4ebbf983f3ab7fc5304d980cc47302d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 11:46:40 +0200 Subject: 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 be9d24f18..9c774deac 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 -- cgit v1.2.3 From 765f172211c8d7d8f14b6010193d8b53f5ec5e8f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 12:13:13 +0200 Subject: 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 6fe5e162c..028841f60 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 e0e3802d1..10ab6e2f4 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; - 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); + sig.replace(wr_offset, w); + wr_offset += wr_width; + } } 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 782c0cd79..bbd015833 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); -- cgit v1.2.3 From 543551b80a257ce0d55ce2d97fed165da7750360 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 12:23:47 +0200 Subject: changes in verilog frontend for new $mem/$memwr WR_EN interface --- frontends/ast/genrtlil.cc | 3 --- frontends/ast/simplify.cc | 10 ++++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 787f4d2d8..a2fdcf8b1 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1287,9 +1287,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->connections["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); cell->connections["\\EN"] = children[2]->genRTLIL(); - if (cell->connections["\\EN"].width > 1) - cell->connections["\\EN"] = uniop2rtlil(this, "$reduce_bool", 1, cell->connections["\\EN"], false); - cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); cell->parameters["\\WIDTH"] = RTLIL::Const(current_module->memories[str]->width); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e547ede36..ba0dca139 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1177,17 +1177,19 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire_data->str] = wire_data; while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } - AstNode *wire_en = new AstNode(AST_WIRE); + AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_en->str = id_en; current_ast_mod->children.push_back(wire_en); current_scope[wire_en->str] = wire_en; while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } - std::vector x_bits_addr, x_bits_data; + std::vector x_bits_addr, x_bits_data, set_bits_en; for (int i = 0; i < addr_bits; i++) x_bits_addr.push_back(RTLIL::State::Sx); for (int i = 0; i < mem_width; i++) x_bits_data.push_back(RTLIL::State::Sx); + for (int i = 0; i < mem_width; i++) + set_bits_en.push_back(RTLIL::State::S1); AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); assign_addr->children[0]->str = id_addr; @@ -1195,7 +1197,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); assign_data->children[0]->str = id_data; - AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1)); + AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); assign_en->children[0]->str = id_en; AstNode *default_signals = new AstNode(AST_BLOCK); @@ -1210,7 +1212,7 @@ skip_dynamic_range_lvalue_expansion:; assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone()); assign_data->children[0]->str = id_data; - assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1)); + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); assign_en->children[0]->str = id_en; newNode = new AstNode(AST_BLOCK); -- cgit v1.2.3 From d678b6533dfac431a36abd22c01e9df184b723a4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 13:37:41 +0200 Subject: 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 dfe214416..d5bcb7f00 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); } } -- cgit v1.2.3 From 73a345294a0c4639b6339ee20e5ca942c963f2f4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 13:46:27 +0200 Subject: 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 5f93914c1..820f89de4 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 -- cgit v1.2.3 From 24f58e57f3048f7f3e84115364b392389d124c7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:02:28 +0200 Subject: Fixed spelling of "direction" in read_liberty messages --- frontends/liberty/liberty.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 285491e06..7a74c5fcb 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -538,9 +538,9 @@ struct LibertyFrontend : public Frontend { { if (!flag_ignore_miss_dir) { - log_error("Missing or invalid dircetion for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); } else { - log("Ignoring cell %s with missing or invalid dircetion for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); + log("Ignoring cell %s with missing or invalid direction for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); delete module; goto skip_cell; } -- cgit v1.2.3 From 5057935722edca26b13cb3a158a443d16a6445da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:12:16 +0200 Subject: Set blackbox attribute in "read_liberty -lib" --- frontends/liberty/liberty.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 7a74c5fcb..398e7a30e 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -528,6 +528,9 @@ struct LibertyFrontend : public Frontend { RTLIL::Module *module = new RTLIL::Module; module->name = cell_name; + if (flag_lib) + module->set_bool_attribute("\\blackbox"); + for (auto &attr : attributes) module->attributes[attr] = 1; -- cgit v1.2.3 From b171a4c1bce1146c890f8238a723a277c8dc2efb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Jul 2014 18:12:46 +0200 Subject: Added "inout" ports support to read_liberty --- frontends/liberty/liberty.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 398e7a30e..e7af93720 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -537,7 +537,7 @@ struct LibertyFrontend : public Frontend { for (auto node : cell->children) if (node->id == "pin" && node->args.size() == 1) { LibertyAst *dir = node->find("direction"); - if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "internal")) + if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal")) { if (!flag_ignore_miss_dir) { @@ -570,6 +570,11 @@ struct LibertyFrontend : public Frontend { RTLIL::Wire *wire = module->wires.at(RTLIL::escape_id(node->args.at(0))); + if (dir && dir->value == "inout") { + wire->port_input = true; + wire->port_output = true; + } + if (dir && dir->value == "input") { wire->port_input = true; continue; -- cgit v1.2.3 From 64a6906cc448b90777591006786e8bb3a85d2c49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 08:58:51 +0200 Subject: 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 4c5a0febc..cb36c9e1f 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)); -- cgit v1.2.3 From b76bf05cda789219069c623d3f77cbc47c1eb57d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 08:59:07 +0200 Subject: 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 cc678516f..eb2757f66 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) -- cgit v1.2.3 From 274c51487937e3ca37c3520e98e996cb5918e982 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 12:10:57 +0200 Subject: 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 c4c08d5b8..c232dadd2 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) -- cgit v1.2.3 From 1b00861d0a3bba0b609eecde504d8a4f2f9d973d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 12:12:04 +0200 Subject: Improved opt_reduce handling of mem wr_en mux bits --- passes/opt/opt_reduce.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index d5bcb7f00..1e91d1601 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; + bool all_tuple_bits_same = true; + in_tuple.push_back(sig_a.at(i)); - for (int j = i; j < int(sig_b.size()); j += int(sig_a.size())) + 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 (consolidated_in_tuples_map.count(in_tuple)) + 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(); -- cgit v1.2.3 From 6d69d4aaa81f176ec97654b5103f6f59eb98c211 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 13:13:21 +0200 Subject: Added support for constant bit- or part-select for memory writes --- frontends/ast/simplify.cc | 45 ++++++++++++++++++++++++++++++++++++--------- 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 ba0dca139..320c80d72 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -607,9 +607,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } // split memory access with bit select to individual statements - if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE) + if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue) { - if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1 || in_lvalue) + if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1) log_error("Invalid bit-select on memory access at %s:%d!\n", filename.c_str(), linenum); int mem_width, mem_size, addr_bits; @@ -1150,9 +1150,9 @@ skip_dynamic_range_lvalue_expansion:; // assignment with memory in left-hand side expression -> replace with memory write port if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER && - children[0]->children.size() == 1 && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && - children[0]->id2ast->children.size() >= 2 && children[0]->id2ast->children[0]->range_valid && - children[0]->id2ast->children[1]->range_valid) + children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 && + children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid && + (children[0]->children.size() == 1 || children[0]->children.size() == 2)) { std::stringstream sstr; sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); @@ -1209,11 +1209,38 @@ skip_dynamic_range_lvalue_expansion:; assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; - assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone()); - assign_data->children[0]->str = id_data; + if (children[0]->children.size() == 2) + { + if (children[0]->children[1]->range_valid) + { + int offset = children[0]->children[1]->range_right; + int width = children[0]->children[1]->range_left - offset + 1; - assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); - assign_en->children[0]->str = id_en; + std::vector padding_x(offset, RTLIL::State::Sx); + + for (int i = 0; i < mem_width; i++) + set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0; + + assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone())); + assign_data->children[0]->str = id_data; + + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en->children[0]->str = id_en; + } + else + { + log_error("Writing to memories with dynamic bit- or part-select is not supported yet at %s:%d.\n", filename.c_str(), linenum); + } + } + else + { + assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone()); + assign_data->children[0]->str = id_data; + + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false)); + assign_en->children[0]->str = id_en; + } newNode = new AstNode(AST_BLOCK); newNode->children.push_back(assign_addr); diff --git a/tests/simple/memory.v b/tests/simple/memory.v index 927ee0438..aae3feace 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 -- cgit v1.2.3 From 5867f6bcdc10cbccc196a6889f5242c0f090a2f1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 13:49:32 +0200 Subject: Added support for bit/part select to mem2reg rewriter --- frontends/ast/simplify.cc | 9 +++++++++ tests/simple/memory.v | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 320c80d72..eee5a7b39 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1974,6 +1974,8 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * continue; AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK)); AstNode *assign_reg = new AstNode(type, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER)); + if (children[0]->children.size() == 2) + assign_reg->children[0]->children.push_back(children[0]->children[1]->clone()); assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i); assign_reg->children[1]->str = id_data; cond_node->children[1]->children.push_back(assign_reg); @@ -1990,6 +1992,10 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * if (type == AST_IDENTIFIER && id2ast && mem2reg_set.count(id2ast) > 0) { + AstNode *bit_part_sel = NULL; + if (children.size() == 2) + bit_part_sel = children[1]->clone(); + if (children[0]->children[0]->type == AST_CONSTANT) { int id = children[0]->children[0]->integer; @@ -2073,6 +2079,9 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * id2ast = NULL; str = id_data; } + + if (bit_part_sel) + children.push_back(bit_part_sel); } assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0); diff --git a/tests/simple/memory.v b/tests/simple/memory.v index aae3feace..21271b5e2 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 -- cgit v1.2.3 From f1ca93a0a37a4e5f7188af21d2696219329fadfd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 16:48:36 +0200 Subject: 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 9c774deac..1b50959c9 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 -- cgit v1.2.3 From 9b183539af4adf7d2a127042ca384806c7e73367 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 16:49:23 +0200 Subject: Implemented dynamic bit-/part-select for memory writes --- frontends/ast/simplify.cc | 28 ++++++++++++++++++++++++++-- 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 eee5a7b39..f819b2506 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1159,7 +1159,7 @@ skip_dynamic_range_lvalue_expansion:; std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN"; if (type == AST_ASSIGN_EQ) - log("Warining: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n", + log("Warning: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n", filename.c_str(), linenum); int mem_width, mem_size, addr_bits; @@ -1230,7 +1230,31 @@ skip_dynamic_range_lvalue_expansion:; } else { - log_error("Writing to memories with dynamic bit- or part-select is not supported yet at %s:%d.\n", filename.c_str(), linenum); + AstNode *the_range = children[0]->children[1]; + AstNode *left_at_zero_ast = the_range->children[0]->clone(); + AstNode *right_at_zero_ast = the_range->children.size() >= 2 ? the_range->children[1]->clone() : left_at_zero_ast->clone(); + AstNode *offset_ast = right_at_zero_ast->clone(); + + while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) + log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); + int width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1; + + for (int i = 0; i < mem_width; i++) + set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0; + + assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone())); + assign_data->children[0]->str = id_data; + + assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), + new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone())); + assign_en->children[0]->str = id_en; + + delete left_at_zero_ast; + delete right_at_zero_ast; + delete offset_ast; } } else diff --git a/tests/simple/memory.v b/tests/simple/memory.v index 21271b5e2..ae63e8a16 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 -- cgit v1.2.3 From ec3a798194342135d7aea21c334e6675701d66a6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jul 2014 16:53:52 +0200 Subject: 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 ff431eaf7..266691a64 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 -- cgit v1.2.3 From a8cedb225709171b97e31c35dcac52d13c47b94f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 10:26:01 +0200 Subject: 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 5fbd2fc68..3e280a6f6 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) -- cgit v1.2.3 From 2d69c309f9d4d3093eead620684a59e3804b3894 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 10:27:06 +0200 Subject: 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 c232dadd2..dea0e1050 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 b95a04422..17406d5d6 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 { -- cgit v1.2.3 From 309ae98246cf9ff115b7d95ae14991faf72a5a38 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 10:28:45 +0200 Subject: 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 1e91d1601..a0c7a027f 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; -- cgit v1.2.3 From a721f7d768feb3ce68cb384805ea7f1fde3e08ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 11:36:34 +0200 Subject: 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 17406d5d6..3a22d1371 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) { -- cgit v1.2.3 From ab4b26679ff4acdc5a86bc79faa5439c625c38f8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 12:40:01 +0200 Subject: 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 21f17db5b..026c5ff85 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 680657a79..a0c89a4d6 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 000000000..69f3e739c --- /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; + -- cgit v1.2.3 From 5d9127418b7272ae926e917ee0167ce58b81a83e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 13:25:19 +0200 Subject: 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 61fb5dc49..6d3d7d7c2 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 000000000..90a0983a6 --- /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 000000000..3554af887 --- /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: 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 eccd40100..c3b196188 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." -- cgit v1.2.3 From a3419319727ac1c2012602a702b62631570d7588 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 14:32:40 +0200 Subject: 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 69f3e739c..140a41849 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; -- cgit v1.2.3 From 44f13aff92146592fd9399bf96dfcb1f81fde708 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 16:44:45 +0200 Subject: 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 92fc5bd55..eab42e6ff 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()) { -- cgit v1.2.3 From e441f07d895a673c0bf40dcdc76781b50834fe44 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 18 Jul 2014 16:46:40 +0200 Subject: 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 a0c89a4d6..fc3095535 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 140a41849..e2fa168c3 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 000000000..cfce378b4 --- /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 -- cgit v1.2.3 From 26f982ac0b69deb3cb9eda69e5cf687a69de4606 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:32:14 +0200 Subject: 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 e2fa168c3..4af0ebdca 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 000000000..0e96e4ae1 --- /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 -- cgit v1.2.3 From 1c288adcc03db49375dd0e214bbbc0b8b9099436 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:32:39 +0200 Subject: 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 ae6a00f8e..56497bb83 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; -- cgit v1.2.3 From 35edac0b31ff826c60d864febefc294263613716 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:33:00 +0200 Subject: 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 000000000..6c3da5dd0 --- /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 -- cgit v1.2.3 From 297a0962ea399fcfa80656af2bc887c5725f5b82 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:33:55 +0200 Subject: 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 4af0ebdca..20ff16dea 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 000000000..94bad53e2 --- /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 -- cgit v1.2.3 From e0a819dbe507c90e201279db317c2251b3c691eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:34:14 +0200 Subject: 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 20ff16dea..cde5f2183 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"); -- cgit v1.2.3 From efd9604dfb92fda05c3efea67b7c32d812717fa8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 15:46:11 +0200 Subject: 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 cde5f2183..dc015f969 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; -- cgit v1.2.3 From 02f0acb3bce05f3af036495aa36049c67ffbdb52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 20:53:29 +0200 Subject: 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 b2c92e4e1..3108bddfe 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 3e280a6f6..2c3597c9a 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__) -- cgit v1.2.3 From 2278995bd8097558396ffdd3a5d24e324f22faa7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Jul 2014 20:54:32 +0200 Subject: 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 4fa6bf0d4..9aa806429 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 000000000..c04be7c8d --- /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; + -- cgit v1.2.3 From 0c67393313f125b6fca70614f10c2ec61116dd82 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 01:56:16 +0200 Subject: 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 d7fe4c4e2..6be26329a 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()); -- cgit v1.2.3 From a30e2857c730c1adc1c6af2c995059af904eec0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 02:16:30 +0200 Subject: 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 6be26329a..80ad7cb90 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; } -- cgit v1.2.3 From 3f9f0c047d46f8b84a5a73e6c9437d0ee3793324 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 02:19:44 +0200 Subject: 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 000000000..da1ffa41d --- /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 000000000..9bef44502 --- /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 + -- cgit v1.2.3 From 15fd615da5a119b4ee9cded9f44ae36fd66820f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 03:03:04 +0200 Subject: 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 c04be7c8d..aad53e13c 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; -- cgit v1.2.3 From a6174aaf5eec37f1d1713afa978ae16286fc0b74 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 10:35:47 +0200 Subject: 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 3108bddfe..949bf4327 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 2c3597c9a..f6dcc0ac2 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) -- cgit v1.2.3 From efa78840261871616f9af15e5ad9a5bc89f95857 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 10:36:14 +0200 Subject: Added SIZE() macro --- kernel/rtlil.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 3a22d1371..6290db21d 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 { -- cgit v1.2.3 From e57db5e9b256d801c1d4337e44e1a7173a115d07 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 11:00:09 +0200 Subject: 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 dea0e1050..748deae3e 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 6290db21d..64136de04 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; -- cgit v1.2.3 From 8819493db4e2a02cef5d0ee751ff56605db5995b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 10:36:46 +0200 Subject: 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 aad53e13c..a1510a599 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; - - if (modwalker.has_outputs(signal)) - goto signal_outside_mux_tree; + std::map p_bits; - 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; + 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; } - 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(); + p.first = RTLIL::SigSpec(); + p.second.bits.clear(); - 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:; - } + for (auto &it : p_bits) { + p.first.append_bit(it.first); + p.second.bits.push_back(it.second); } + + 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); + } + } + + for (auto c : driven_cells) + { + const std::set> &c_patterns = find_cell_activation_patterns(c); - follow_mux_data_cone(activation_patterns_cache[cell], state, cell_output_signal); - return activation_patterns_cache.at(cell); + 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"); -- cgit v1.2.3 From 7b98e46ac352e625be2d8da9b12e7252ed5179d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 11:41:57 +0200 Subject: 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 a1510a599..fd48b9012 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; + } + } } }; -- cgit v1.2.3 From 5b3ee7a072ad0bd7fb1245a2fb3560a0ca034457 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:00:18 +0200 Subject: 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 fd48b9012..9ad1d621a 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; } } -- cgit v1.2.3 From 6f450d0224a3ad09c61c5a150e3e7b3b6241338d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 14:55:10 +0200 Subject: 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 000000000..9c595a6fb --- /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 000000000..86be6b5ed --- /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 000000000..d511c9096 --- /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 + -- cgit v1.2.3 From 2e358bd6678aba687908fe4a359c82aa5dff110d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 13:20:52 +0200 Subject: 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 da1ffa41d..63db2fba3 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 000000000..dc8aec086 --- /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 9bef44502..6b3c26519 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 000000000..174dbbc2c --- /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 000000000..52b5a1428 --- /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 + -- cgit v1.2.3 From 8d04ca7d22e375fbe075dee1f189669046ee8906 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:16:10 +0200 Subject: 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 8da5a725f..84051948f 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 f3d3f70ae..b07c46177 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 7d0811254..55f5f0485 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 cb36c9e1f..3ceff279b 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; -- cgit v1.2.3 From 4c38ec1cc81c95b79fbd717dafd9f79708c123e8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:23:08 +0200 Subject: 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 6c8e2ff48..0ef9e9aaa 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 86be6b5ed..07821b721 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') -- cgit v1.2.3 From dd23e9a9dbe4db96423a797f2383e79093dd62bb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 15:24:04 +0200 Subject: Activated tests/share in "make test" --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 6d3d7d7c2..6f9daa04a 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 -- cgit v1.2.3 From 4af8d84f015edd229328a09c462c8ad81e06892f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 17:05:20 +0200 Subject: 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 6b3c26519..0e01fd646 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 -- cgit v1.2.3 From ff28029fdb4fe97dca0e93b175dd2d6411671cb0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 17:06:36 +0200 Subject: 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 9ad1d621a..27b21207e 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 (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 (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); -- cgit v1.2.3 From 7a6d578b81581f5217b717dcd601cfba2d4a4d0f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 17:06:57 +0200 Subject: 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 07821b721..fa17080f9 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) -- cgit v1.2.3 From e9506bb2da9640cebc325e33a678d352d36a909e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 18:54:06 +0200 Subject: 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 27b21207e..065496710 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 fa17080f9..9e5bef7ae 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 52b5a1428..88e042817 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 -- cgit v1.2.3 From 1ce5e835553a99c3333af00ead1d8f3e40c5538a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 20:15:49 +0200 Subject: 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 38d43f8df..9ef60a28f 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) -- cgit v1.2.3 From 04fcb07213291f469d208ceca2a32fb8c2fe3215 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 20:44:14 +0200 Subject: Added support for resource sharing in mux control logic --- passes/sat/share.cc | 241 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 155 insertions(+), 86 deletions(-) diff --git a/passes/sat/share.cc b/passes/sat/share.cc index 065496710..90daefc0a 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(); + modwalker.get_drivers(portbits, queue_bits); + queue_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]; + 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(); terminal_bits.insert(bits.begin(), bits.end()); - queue_strong_bits.insert(bits.begin(), bits.end()); + queue_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()); + 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; - - 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_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); - } + 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_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); + } + } + + 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()); } }; -- cgit v1.2.3 From 8836943693dcd6fc6e6b74141ca8c89e9b8c1f0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Jul 2014 20:45:01 +0200 Subject: 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 000000000..e06fc8f1e --- /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 000000000..f2f5d649d --- /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 + -- cgit v1.2.3 From c6b3f4e0896a4447bad94d816c8677d01cea1e75 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:00:39 +0200 Subject: 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 68c7c60ee..fa72ba213 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 -- cgit v1.2.3 From 92c9403249ba59e5f57b2adb8b8b0141c2c63f26 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:01:26 +0200 Subject: 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 7f7eac61f..ddb972e77 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 0de4f07ca..6591dcd55 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 383e894be..ccfa1c013 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 a75124627..057a3cdf2 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 61dd0f679..9a66315d1 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 93b6da31c..a6f832000 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 b1b3e31ba..1aff3fab2 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 7d140a1ff..d602769cf 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 7b2ddc554..1c9e7bf7b 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 1cae4f5ad..5ba50cd2b 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 cf7061014..ccb94c6ce 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 232368106..fd5774e0e 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 fc9bb4391..76d5aca1f 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 14aa39355..ab476853a 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 73fc7d4cf..62a12f3c7 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 a47c2ce83..a7df57858 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 4a25a9b49..cc96486d8 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 df4155af3..febe3b40f 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 eb8a7e4d3..ee92a6e08 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 2086e0bb2..6e398801f 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 { -- cgit v1.2.3 From ade659e617922171ad1b678a51765ba2046c27d8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:03:01 +0200 Subject: 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 e831cc6f0..1dcb5d15b 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 caee73f88..6a6c075f5 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) { -- cgit v1.2.3 From b1d520949bdb5357f31f43d9dc4f4579dda9f269 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 01:49:59 +0200 Subject: 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 1dcb5d15b..b1f864160 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 6a6c075f5..3f43f3ece 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 6da363fc1..4c0b624be 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 852405566..83e1b23c5 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 8332ad919..d20258c37 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"); } // ------------------------------------------------------------------------------------------------------------ -- cgit v1.2.3 From b49beab1f30d0a7567c2917a3387fa52c84350fd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 02:08:38 +0200 Subject: 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 90daefc0a..8ef3396e0 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; -- cgit v1.2.3 From caae6e19dffde4d76b30af3fd1f9751f4ec37fdc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:01:45 +0200 Subject: Added log_ping() --- kernel/log.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/log.h b/kernel/log.h index f6dcc0ac2..00265dbe0 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 -- cgit v1.2.3 From 54b0f2e659ac0c34c69b0c251c72b2a90fe8e6b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:02:55 +0200 Subject: 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 748deae3e..b16b62ca1 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 64136de04..19666481d 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); }; -- cgit v1.2.3 From c54d1f2ad1a781363f9c35e4f7266f4560a6aba8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:03:41 +0200 Subject: 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 81d029295..281d2b26f 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) -- cgit v1.2.3 From 3cb61d03f8722fddfa14877accae1b3ca51e3926 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:04:56 +0200 Subject: 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 8ef3396e0..852d80782 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 9e5bef7ae..e3b4bc969 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 d511c9096..203d6fcd7 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 -- cgit v1.2.3 From 1d88f1cf9f2088de7825f5292db5b40d4f73d036 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:35:06 +0200 Subject: Removed deprecated module->new_wire() --- frontends/liberty/liberty.cc | 10 +++++----- 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 e7af93720..cf243f63a 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -227,8 +227,8 @@ static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr) static void create_ff(RTLIL::Module *module, LibertyAst *node) { - RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); - RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1)))); RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig; bool clk_polarity = true, clear_polarity = true, preset_polarity = true; @@ -309,8 +309,8 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) static void create_latch(RTLIL::Module *module, LibertyAst *node) { - RTLIL::SigSpec iq_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(0)))); - RTLIL::SigSpec iqn_sig(module->new_wire(1, RTLIL::escape_id(node->args.at(1)))); + RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0)))); + RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1)))); RTLIL::SigSpec enable_sig, data_sig, clear_sig, preset_sig; bool enable_polarity = true, clear_polarity = true, preset_polarity = true; @@ -549,7 +549,7 @@ struct LibertyFrontend : public Frontend { } } if (!flag_lib || dir->value != "internal") - module->new_wire(1, RTLIL::escape_id(node->args.at(0))); + module->addWire(RTLIL::escape_id(node->args.at(0))); } for (auto node : cell->children) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b16b62ca1..d3d830d67 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 19666481d..3c6c97242 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 7da2b9517..f99cb9b50 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 1c02752c2..ce6ac4aff 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 6d920dbc5..a48a54a12 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 dc015f969..578007a01 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 d4b7b5c10..ac0415644 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 0ef9e9aaa..6e57fceb1 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 852d80782..42e59c475 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 e67b1e055..91f3b6124 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) -- cgit v1.2.3 From 361e0d62ffd90b87c94bfc98ed3cbee1a745cd8f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 12:41:29 +0200 Subject: Replaced depricated NEW_WIRE macro with module->addWire() calls --- frontends/liberty/liberty.cc | 20 ++++++++++---------- 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 cf243f63a..9000d7024 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -58,7 +58,7 @@ static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) cell->name = NEW_ID; cell->type = "$_INV_"; cell->connections["\\A"] = A; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -70,7 +70,7 @@ static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, R cell->type = "$_XOR_"; cell->connections["\\A"] = A; cell->connections["\\B"] = B; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -82,7 +82,7 @@ static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, R cell->type = "$_AND_"; cell->connections["\\A"] = A; cell->connections["\\B"] = B; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -94,7 +94,7 @@ static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RT cell->type = "$_OR_"; cell->connections["\\A"] = A; cell->connections["\\B"] = B; - cell->connections["\\Y"] = NEW_WIRE(module, 1); + cell->connections["\\Y"] = module->addWire(NEW_ID); module->add(cell); return cell->connections["\\Y"]; } @@ -370,7 +370,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) inv->name = NEW_ID; inv->type = "$_INV_"; inv->connections["\\A"] = clear_sig; - inv->connections["\\Y"] = NEW_WIRE(module, 1);; + inv->connections["\\Y"] = module->addWire(NEW_ID); module->add(inv); if (clear_polarity == true) @@ -384,7 +384,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) data_gate->type = "$_AND_"; data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = clear_negative; - data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(data_gate); RTLIL::Cell *enable_gate = new RTLIL::Cell; @@ -392,7 +392,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = clear_enable; - enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(enable_gate); } @@ -407,7 +407,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) inv->name = NEW_ID; inv->type = "$_INV_"; inv->connections["\\A"] = preset_sig; - inv->connections["\\Y"] = NEW_WIRE(module, 1);; + inv->connections["\\Y"] = module->addWire(NEW_ID); module->add(inv); if (preset_polarity == false) @@ -421,7 +421,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) data_gate->type = "$_OR_"; data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = preset_positive; - data_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(data_gate); RTLIL::Cell *enable_gate = new RTLIL::Cell; @@ -429,7 +429,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = preset_enable; - enable_gate->connections["\\Y"] = data_sig = NEW_WIRE(module, 1);; + enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); module->add(enable_gate); } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 3c6c97242..9b3e44179 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 c18446512..13e4e6606 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 bc5caa38c..d24f557e2 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); -- cgit v1.2.3 From 550ac3587302c6c95892c66db2cfa3788b2b5c42 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 13:28:12 +0200 Subject: 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 577fbe3d9..e365e67c3 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++) -- cgit v1.2.3 From 668306d00f47989d1f66d139351e63fe2465961c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 14:08:13 +0200 Subject: Various improvements in test/vloghtb --- tests/vloghtb/common.sh | 39 +++++++++++++++++++++++++++++++++++++-- tests/vloghtb/run-test.sh | 5 +++-- tests/vloghtb/test_mapopt.sh | 11 +++++++++++ tests/vloghtb/test_share.sh | 27 +-------------------------- 4 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 tests/vloghtb/test_mapopt.sh diff --git a/tests/vloghtb/common.sh b/tests/vloghtb/common.sh index dc8aec086..704afdd98 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 0e01fd646..3b8a3e9e2 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 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 000000000..9099e2b74 --- /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 88e042817..da2211624 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 - -- cgit v1.2.3 From e035f1d886b30329c1c061894146a5c6f92b4f7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 14:09:11 +0200 Subject: 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 da71ec30e..76948344e 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"]); -- cgit v1.2.3 From 4147b55c233013dd861172f13d0b9669598d234c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 15:15:18 +0200 Subject: Added "autoidx" statement to ilang file format --- 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 b3d96b28e..eaad78695 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 6557f98ab..c40b81af8 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -31,7 +31,6 @@ #include "kernel/rtlil.h" #include "parser.tab.h" -void update_autoidx(const char *p); %} @@ -44,6 +43,7 @@ void update_autoidx(const char *p); %% +"autoidx" { return TOK_AUTOIDX; } "module" { return TOK_MODULE; } "attribute" { return TOK_ATTRIBUTE; } "parameter" { return TOK_PARAMETER; } @@ -76,11 +76,11 @@ void update_autoidx(const char *p); [a-z]+ { return TOK_INVALID; } "\\"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } -"$"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); update_autoidx(yytext); return TOK_ID; } +"$"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } "."[0-9]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } [0-9]+'[01xzm-]* { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_VALUE; } -[0-9]+ { rtlil_frontend_ilang_yylval.integer = atoi(yytext); return TOK_INT; } +-?[0-9]+ { rtlil_frontend_ilang_yylval.integer = atoi(yytext); return TOK_INT; } \" { BEGIN(STRING); } \\. { yymore(); } @@ -124,27 +124,6 @@ void update_autoidx(const char *p); %% -void update_autoidx(const char *p) -{ - if (*p != '$') - return; - - while (*p) { - if (*(p++) != '$') - continue; - if ('0' <= *p && *p <= '9') { - const char *q = p; - while ('0' <= *q && *q <= '9') - q++; - if ((q - p) < 10) { - int idx = atoi(p); - if (idx >= RTLIL::autoidx) - RTLIL::autoidx = idx+1; - } - } - } -} - // this is a hack to avoid the 'yyinput defined but not used' error msgs void *rtlil_frontend_ilang_avoid_input_warnings() { return (void*)&yyinput; diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 6b41b0873..d8ecf37b7 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -50,7 +50,7 @@ using namespace ILANG_FRONTEND; %token TOK_ID TOK_VALUE TOK_STRING %token TOK_INT -%token TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT +%token TOK_AUTOIDX TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT %token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC %token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_INIT %token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET @@ -82,6 +82,7 @@ optional_eol: design: design module | design attr_stmt | + design autoidx_stmt | /* empty */; module: @@ -113,6 +114,11 @@ attr_stmt: free($2); }; +autoidx_stmt: + TOK_AUTOIDX TOK_INT EOL { + RTLIL::autoidx = std::max(RTLIL::autoidx, $2); + }; + wire_stmt: TOK_WIRE { current_wire = new RTLIL::Wire; -- cgit v1.2.3 From 1241a9fd5073d327d49f1af47db37214a4628ed8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 16:34:16 +0200 Subject: 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 8f4725e1c..62aa48bee 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 76948344e..a17ca6792 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 a0c7a027f..93945e49a 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 266691a64..c383e19f4 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 } -- cgit v1.2.3 From 1873480ca5f5ec9ec6aa1b80b91ae047a6982002 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 17:19:50 +0200 Subject: 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 a17ca6792..4cfee59d2 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 -- cgit v1.2.3 From 137dbf3cf7edbec8c31dfdb2c9c0bcc413c5786d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 21:38:55 +0200 Subject: 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 62aa48bee..33e1507bc 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 4cfee59d2..e855e45ee 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); } -- cgit v1.2.3 From 0229d68fc97276477b96cef4e2ba8604851ea9c6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 21 Jul 2014 21:39:59 +0200 Subject: 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 704afdd98..1c60d794f 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 9099e2b74..ad8b3ef61 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 -- cgit v1.2.3 From d6d0e08834560e824cc59027b720401a1c0b1fc7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:18:05 +0200 Subject: Fixed make rules for ilang parser --- frontends/ilang/Makefile.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc index 07ebf0856..f81c8de91 100644 --- a/frontends/ilang/Makefile.inc +++ b/frontends/ilang/Makefile.inc @@ -4,10 +4,12 @@ GENFILES += frontends/ilang/parser.tab.h GENFILES += frontends/ilang/parser.output GENFILES += frontends/ilang/lexer.cc -frontends/ilang/parser.tab.cc frontends/ilang/parser.tab.h: frontends/ilang/parser.y +frontends/ilang/parser.tab.cc: frontends/ilang/parser.y bison -d -r all -b frontends/ilang/parser frontends/ilang/parser.y mv frontends/ilang/parser.tab.c frontends/ilang/parser.tab.cc +frontends/ilang/parser.tab.h: frontends/ilang/parser.tab.cc + frontends/ilang/lexer.cc: frontends/ilang/lexer.l flex -o frontends/ilang/lexer.cc frontends/ilang/lexer.l -- cgit v1.2.3 From 3b5f4ff39c94a5a664043f35b95a50240ffe9d12 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:35:58 +0200 Subject: Fixed ilang parsing of process attributes --- frontends/ilang/parser.y | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index d8ecf37b7..cb438775f 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -225,6 +225,7 @@ proc_stmt: switch_stack.push_back(¤t_process->root_case.switches); case_stack.clear(); case_stack.push_back(¤t_process->root_case); + attrbuf.clear(); free($2); } case_body sync_list TOK_END EOL; -- cgit v1.2.3 From a233762a815fc180b371f699e865a7d7aed77bca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 19:56:17 +0200 Subject: SigSpec refactoring: renamed chunks and width to __chunks and __width --- 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 3e2fab006..e7fbfe7a5 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 498f13511..2d446610b 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 45f7b4143..428e9a880 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 8ac7cc7b2..c239ef306 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 eaad78695..e1a8bfd49 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 47c1125f7..049a2ce84 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 e7926e90e..c7f832c64 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 80ad7cb90..6aeb5084b 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 a2fdcf8b1..dc9f566c1 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -62,8 +62,8 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; if (gen_attributes) for (auto &attr : that->attributes) { @@ -74,7 +74,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.__width); cell->connections["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; @@ -85,7 +85,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) { - if (width <= sig.width) { + if (width <= sig.__width) { sig.extend(width, is_signed); return; } @@ -111,8 +111,8 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s chunk.offset = 0; RTLIL::SigSpec new_sig; - new_sig.chunks.push_back(chunk); - new_sig.width = chunk.width; + new_sig.__chunks.push_back(chunk); + new_sig.__width = chunk.width; if (that != NULL) for (auto &attr : that->attributes) { @@ -123,7 +123,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s } cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.__width); cell->connections["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; @@ -155,8 +155,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -168,8 +168,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\B_SIGNED"] = RTLIL::Const(that->children[1]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.width); - cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.__width); + cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.__width); cell->connections["\\A"] = left; cell->connections["\\B"] = right; @@ -182,7 +182,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi // helper function for creating RTLIL code for multiplexers static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - assert(cond.width == 1); + assert(cond.__width == 1); std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); @@ -196,7 +196,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::Wire *wire = new RTLIL::Wire; wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); wire->name = cell->name + "_Y"; - wire->width = left.width; + wire->width = left.__width; current_module->wires[wire->name] = wire; RTLIL::SigChunk chunk; @@ -205,8 +205,8 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const chunk.offset = 0; RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -215,7 +215,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->parameters["\\WIDTH"] = RTLIL::Const(left.width); + cell->parameters["\\WIDTH"] = RTLIL::Const(left.__width); cell->connections["\\A"] = right; cell->connections["\\B"] = left; @@ -311,7 +311,7 @@ struct AST_INTERNAL::ProcessGenerator // create initial assignments for the temporary signals if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) { subst_rvalue_from = subst_lvalue_from; - subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.width); + subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.__width); } else { addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from); } @@ -321,22 +321,22 @@ struct AST_INTERNAL::ProcessGenerator if (child->type == AST_BLOCK) processAst(child); - if (initSyncSignals.width > 0) + if (initSyncSignals.__width > 0) { RTLIL::SyncRule *sync = new RTLIL::SyncRule; sync->type = RTLIL::SyncType::STi; proc->syncs.push_back(sync); - assert(init_lvalue.width == init_rvalue.width); + assert(init_lvalue.__width == init_rvalue.__width); init_lvalue.optimize(); init_rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < init_lvalue.chunks.size(); i++) { - RTLIL::SigSpec lhs = init_lvalue.chunks[i]; - RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.chunks[i].width); + for (size_t i = 0; i < init_lvalue.__chunks.size(); i++) { + RTLIL::SigSpec lhs = init_lvalue.__chunks[i]; + RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.__chunks[i].width); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.width; + offset += lhs.__width; } } } @@ -345,9 +345,9 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { sig.optimize(); - for (size_t i = 0; i < sig.chunks.size(); i++) + for (size_t i = 0; i < sig.__chunks.size(); i++) { - RTLIL::SigChunk &chunk = sig.chunks[i]; + RTLIL::SigChunk &chunk = sig.__chunks[i]; if (chunk.wire == NULL) continue; @@ -426,23 +426,23 @@ struct AST_INTERNAL::ProcessGenerator // are avoided and the generated $mux cells have a more "natural" size. void addChunkActions(std::vector &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool inSyncRule = false) { - if (inSyncRule && initSyncSignals.width > 0) { + if (inSyncRule && initSyncSignals.__width > 0) { init_lvalue.append(lvalue.extract(initSyncSignals)); init_rvalue.append(lvalue.extract(initSyncSignals, &rvalue)); lvalue.remove2(initSyncSignals, &rvalue); } - assert(lvalue.width == rvalue.width); + assert(lvalue.__width == rvalue.__width); lvalue.optimize(); rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < lvalue.chunks.size(); i++) { - RTLIL::SigSpec lhs = lvalue.chunks[i]; - RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks[i].width); - if (inSyncRule && lvalue.chunks[i].wire && lvalue.chunks[i].wire->get_bool_attribute("\\nosync")) - rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.width); + for (size_t i = 0; i < lvalue.__chunks.size(); i++) { + RTLIL::SigSpec lhs = lvalue.__chunks[i]; + RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.__chunks[i].width); + if (inSyncRule && lvalue.__chunks[i].wire && lvalue.__chunks[i].wire->get_bool_attribute("\\nosync")) + rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.__width); actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.width; + offset += lhs.__width; } } @@ -460,7 +460,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_LE: { RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.width, &subst_rvalue_from, &subst_rvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.__width, &subst_rvalue_from, &subst_rvalue_to); lvalue.replace(subst_lvalue_from, subst_lvalue_to); if (ast->type == AST_ASSIGN_EQ) { @@ -533,7 +533,7 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.width, &subst_rvalue_from, &subst_rvalue_to)); + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.__width, &subst_rvalue_from, &subst_rvalue_to)); } if (default_case != current_case) sw->cases.push_back(current_case); @@ -1002,8 +1002,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } RTLIL::SigSpec sig; - sig.chunks.push_back(chunk); - sig.width = chunk.width; + sig.__chunks.push_back(chunk); + sig.__width = chunk.width; if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); @@ -1016,7 +1016,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_TO_SIGNED: case AST_TO_UNSIGNED: { RTLIL::SigSpec sig = children[0]->genRTLIL(); - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, sign_hint); is_signed = sign_hint; return sig; @@ -1025,15 +1025,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // concatenation of signals can be done directly using RTLIL::SigSpec case AST_CONCAT: { RTLIL::SigSpec sig; - sig.width = 0; + sig.__width = 0; for (auto it = children.begin(); it != children.end(); it++) { RTLIL::SigSpec s = (*it)->genRTLIL(); - for (size_t i = 0; i < s.chunks.size(); i++) { - sig.chunks.push_back(s.chunks[i]); - sig.width += s.chunks[i].width; + for (size_t i = 0; i < s.__chunks.size(); i++) { + sig.__chunks.push_back(s.__chunks[i]); + sig.__width += s.__chunks[i].width; } } - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, false); return sig; } @@ -1048,7 +1048,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec sig; for (int i = 0; i < count; i++) sig.append(right); - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, false); is_signed = false; return sig; @@ -1061,7 +1061,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint); is_signed = children[0]->is_signed; - int width = arg.width; + int width = arg.__width; if (width_hint > 0) { width = width_hint; widthExtend(this, arg, width, is_signed, "$pos"); @@ -1079,7 +1079,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); - int width = std::max(left.width, right.width); + int width = std::max(left.__width, right.__width); if (width_hint > 0) width = width_hint; is_signed = children[0]->is_signed && children[1]->is_signed; @@ -1102,7 +1102,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (0) { case AST_REDUCE_BOOL: type_name = "$reduce_bool"; } { RTLIL::SigSpec arg = children[0]->genRTLIL(); - RTLIL::SigSpec sig = arg.width > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; + RTLIL::SigSpec sig = arg.__width > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; return sig; } @@ -1116,7 +1116,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(); - int width = width_hint > 0 ? width_hint : left.width; + int width = width_hint > 0 ? width_hint : left.__width; is_signed = children[0]->is_signed; return binop2rtlil(this, type_name, width, left, right); } @@ -1131,10 +1131,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(right_width, right_signed); - int width = width_hint > 0 ? width_hint : left.width; + int width = width_hint > 0 ? width_hint : left.__width; is_signed = children[0]->is_signed; if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed) - return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.width), right); + return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.__width), right); return binop2rtlil(this, "$pow", width, left, right); } @@ -1170,7 +1170,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); #if 0 - int width = std::max(left.width, right.width); + int width = std::max(left.__width, right.__width); if (width > width_hint && width_hint > 0) width = width_hint; if (width < width_hint) { @@ -1179,10 +1179,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (type == AST_SUB && (!children[0]->is_signed || !children[1]->is_signed)) width = width_hint; if (type == AST_MUL) - width = std::min(left.width + right.width, width_hint); + width = std::min(left.__width + right.__width, width_hint); } #else - int width = std::max(std::max(left.width, right.width), width_hint); + int width = std::max(std::max(left.__width, right.__width), width_hint); #endif is_signed = children[0]->is_signed && children[1]->is_signed; return binop2rtlil(this, type_name, width, left, right); @@ -1214,17 +1214,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); - if (cond.width > 1) + if (cond.__width > 1) cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); - int width = std::max(val1.width, val2.width); + int width = std::max(val1.__width, val2.__width); is_signed = children[1]->is_signed && children[2]->is_signed; widthExtend(this, val1, width, is_signed, "$bu0"); widthExtend(this, val2, width, is_signed, "$bu0"); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); - if (sig.width < width_hint) + if (sig.__width < width_hint) sig.extend_u0(width_hint, sign_hint); return sig; } @@ -1304,10 +1304,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(children.size() == 2); RTLIL::SigSpec check = children[0]->genRTLIL(); - log_assert(check.width == 1); + log_assert(check.__width == 1); RTLIL::SigSpec en = children[1]->genRTLIL(); - log_assert(en.width == 1); + log_assert(en.__width == 1); std::stringstream sstr; sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); @@ -1335,11 +1335,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); - RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.width); + RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.__width); current_module->connections.push_back(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); - RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.width); + RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.__width); current_module->connections.push_back(RTLIL::SigSig(left, right)); } } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index cb438775f..e6d3d4c5b 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -363,8 +363,8 @@ sigspec: chunk.offset = 0; chunk.data = *$1; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = chunk.width; + $$->__chunks.push_back(chunk); + $$->__width = chunk.width; delete $1; } | TOK_ID { @@ -375,8 +375,8 @@ sigspec: chunk.width = current_module->wires[$1]->width; chunk.offset = 0; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = chunk.width; + $$->__chunks.push_back(chunk); + $$->__width = chunk.width; free($1); } | TOK_ID '[' TOK_INT ']' { @@ -387,8 +387,8 @@ sigspec: chunk.offset = $3; chunk.width = 1; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = 1; + $$->__chunks.push_back(chunk); + $$->__width = 1; free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { @@ -399,8 +399,8 @@ sigspec: chunk.width = $3 - $5 + 1; chunk.offset = $5; $$ = new RTLIL::SigSpec; - $$->chunks.push_back(chunk); - $$->width = chunk.width; + $$->__chunks.push_back(chunk); + $$->__width = chunk.width; free($1); } | '{' sigspec_list '}' { @@ -410,13 +410,13 @@ sigspec: sigspec_list: sigspec_list sigspec { $$ = new RTLIL::SigSpec; - for (auto it = $2->chunks.begin(); it != $2->chunks.end(); it++) { - $$->chunks.push_back(*it); - $$->width += it->width; + for (auto it = $2->__chunks.begin(); it != $2->__chunks.end(); it++) { + $$->__chunks.push_back(*it); + $$->__width += it->width; } - for (auto it = $1->chunks.begin(); it != $1->chunks.end(); it++) { - $$->chunks.push_back(*it); - $$->width += it->width; + for (auto it = $1->__chunks.begin(); it != $1->__chunks.end(); it++) { + $$->__chunks.push_back(*it); + $$->__width += it->width; } delete $1; delete $2; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 9000d7024..c449a5936 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -244,7 +244,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (clk_sig.width == 0 || data_sig.width == 0) + if (clk_sig.__width == 0 || data_sig.__width == 0) log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -284,21 +284,21 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) cell->connections["\\C"] = clk_sig; module->add(cell); - if (clear_sig.width == 0 && preset_sig.width == 0) { + if (clear_sig.__width == 0 && preset_sig.__width == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); } - if (clear_sig.width == 1 && preset_sig.width == 0) { + if (clear_sig.__width == 1 && preset_sig.__width == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\R"] = clear_sig; } - if (clear_sig.width == 0 && preset_sig.width == 1) { + if (clear_sig.__width == 0 && preset_sig.__width == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); cell->connections["\\R"] = preset_sig; } - if (clear_sig.width == 1 && preset_sig.width == 1) { + if (clear_sig.__width == 1 && preset_sig.__width == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\S"] = preset_sig; cell->connections["\\R"] = clear_sig; @@ -326,7 +326,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (enable_sig.width == 0 || data_sig.width == 0) + if (enable_sig.__width == 0 || data_sig.__width == 0) log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -359,7 +359,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) cell->connections["\\Y"] = iqn_sig; module->add(cell); - if (clear_sig.width == 1) + if (clear_sig.__width == 1) { RTLIL::SigSpec clear_negative = clear_sig; RTLIL::SigSpec clear_enable = clear_sig; @@ -396,7 +396,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) module->add(enable_gate); } - if (preset_sig.width == 1) + if (preset_sig.__width == 1) { RTLIL::SigSpec preset_positive = preset_sig; RTLIL::SigSpec preset_enable = preset_sig; diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index aaefa50fc..0ca26bb34 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 10116ccfe..fa079e14e 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 d3d830d67..3a646dc62 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 9b3e44179..0919b3926 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 281d2b26f..012b6ab89 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 56497bb83..c886ff168 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 30e78e588..e21be30b8 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 1d4da19ad..65ebe541d 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 f99cb9b50..f8f9e0590 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 dd8b4fede..426d2b624 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 ce6ac4aff..16828e4fb 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 e5f78830e..da36c7821 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 f8c351a43..d668bc3a4 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 9ef60a28f..068162eb1 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 9d59834c2..3a99c0cec 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 eab42e6ff..0006a3ff4 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 a48a54a12..80a7f90c0 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 7e043bcff..7572baa35 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 a8ec19126..523feae92 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 5756b10c7..e4d20077c 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 9cba904a7..c0b5857f0 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 c30cf1fe7..f11d78b39 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 242a505e9..6732d2abd 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 225f34a9d..6b1753060 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 d8a23c727..5d9dc18a4 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 55f5f0485..f8f2b596b 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 028841f60..6c9e1b773 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 e8da6d642..174417bd6 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 10ab6e2f4..b848e09e4 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 578007a01..e56d14b68 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 d330fb7bd..8a097916d 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 e855e45ee..bee86771c 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 3292a46c8..e844a4209 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 93945e49a..4f1176d97 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 9a438537c..879f7ddc6 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 eb639d8ab..07e512cba 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 057378e7c..a773e5e72 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 83554df90..768660686 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 13e4e6606..d3dff8efc 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 fca20fda2..0ef17b22d 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 9b2f83885..2e24e786b 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 5c38cc2cf..5369617be 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 831a43aa5..4308e7364 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 ac0415644..8cc59b291 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 6e57fceb1..1cd794b56 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 a9a00d8a2..161449324 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 42e59c475..95f35bb3e 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 d2193c7b1..7e57aa0f5 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 d24f557e2..22f4c7d1d 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 91f3b6124..cef5cc89e 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 3ceff279b..f7d5efa0a 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 -- cgit v1.2.3 From 16e5ae0b92ac4b7568cb11a769e612e152c0042e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:12:15 +0200 Subject: 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 3a646dc62..043323095 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 0919b3926..7fb416f1f 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); -- cgit v1.2.3 From 4b4048bc5feba1ab05c7a63f12c0a17879cb7e04 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:15:14 +0200 Subject: SigSpec refactoring: using the accessor functions everywhere --- 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 e7fbfe7a5..028d1f37a 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 2d446610b..90d1b3fc4 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 428e9a880..7853160e2 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 c239ef306..bb2b26e26 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 e1a8bfd49..a312b02ce 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 049a2ce84..832922def 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 c7f832c64..8e894cafd 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 6aeb5084b..4b60f0fbd 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 dc9f566c1..681b34860 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -62,8 +62,8 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; if (gen_attributes) for (auto &attr : that->attributes) { @@ -74,7 +74,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); cell->connections["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; @@ -85,7 +85,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) { - if (width <= sig.__width) { + if (width <= sig.size()) { sig.extend(width, is_signed); return; } @@ -111,8 +111,8 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s chunk.offset = 0; RTLIL::SigSpec new_sig; - new_sig.__chunks.push_back(chunk); - new_sig.__width = chunk.width; + new_sig.chunks().push_back(chunk); + new_sig.size() = chunk.width; if (that != NULL) for (auto &attr : that->attributes) { @@ -123,7 +123,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s } cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); cell->connections["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; @@ -155,8 +155,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi chunk.offset = 0; RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -168,8 +168,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\B_SIGNED"] = RTLIL::Const(that->children[1]->is_signed); - cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.__width); - cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.__width); + cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); + cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); cell->connections["\\A"] = left; cell->connections["\\B"] = right; @@ -182,7 +182,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi // helper function for creating RTLIL code for multiplexers static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - assert(cond.__width == 1); + assert(cond.size() == 1); std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); @@ -196,7 +196,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::Wire *wire = new RTLIL::Wire; wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); wire->name = cell->name + "_Y"; - wire->width = left.__width; + wire->width = left.size(); current_module->wires[wire->name] = wire; RTLIL::SigChunk chunk; @@ -205,8 +205,8 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const chunk.offset = 0; RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -215,7 +215,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->parameters["\\WIDTH"] = RTLIL::Const(left.__width); + cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); cell->connections["\\A"] = right; cell->connections["\\B"] = left; @@ -311,7 +311,7 @@ struct AST_INTERNAL::ProcessGenerator // create initial assignments for the temporary signals if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) { subst_rvalue_from = subst_lvalue_from; - subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.__width); + subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.size()); } else { addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from); } @@ -321,22 +321,22 @@ struct AST_INTERNAL::ProcessGenerator if (child->type == AST_BLOCK) processAst(child); - if (initSyncSignals.__width > 0) + if (initSyncSignals.size() > 0) { RTLIL::SyncRule *sync = new RTLIL::SyncRule; sync->type = RTLIL::SyncType::STi; proc->syncs.push_back(sync); - assert(init_lvalue.__width == init_rvalue.__width); + assert(init_lvalue.size() == init_rvalue.size()); init_lvalue.optimize(); init_rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < init_lvalue.__chunks.size(); i++) { - RTLIL::SigSpec lhs = init_lvalue.__chunks[i]; - RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.__chunks[i].width); + for (size_t i = 0; i < init_lvalue.chunks().size(); i++) { + RTLIL::SigSpec lhs = init_lvalue.chunks()[i]; + RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.chunks()[i].width); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.__width; + offset += lhs.size(); } } } @@ -345,9 +345,9 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { sig.optimize(); - for (size_t i = 0; i < sig.__chunks.size(); i++) + for (size_t i = 0; i < sig.chunks().size(); i++) { - RTLIL::SigChunk &chunk = sig.__chunks[i]; + RTLIL::SigChunk &chunk = sig.chunks()[i]; if (chunk.wire == NULL) continue; @@ -426,23 +426,23 @@ struct AST_INTERNAL::ProcessGenerator // are avoided and the generated $mux cells have a more "natural" size. void addChunkActions(std::vector &actions, RTLIL::SigSpec lvalue, RTLIL::SigSpec rvalue, bool inSyncRule = false) { - if (inSyncRule && initSyncSignals.__width > 0) { + if (inSyncRule && initSyncSignals.size() > 0) { init_lvalue.append(lvalue.extract(initSyncSignals)); init_rvalue.append(lvalue.extract(initSyncSignals, &rvalue)); lvalue.remove2(initSyncSignals, &rvalue); } - assert(lvalue.__width == rvalue.__width); + assert(lvalue.size() == rvalue.size()); lvalue.optimize(); rvalue.optimize(); int offset = 0; - for (size_t i = 0; i < lvalue.__chunks.size(); i++) { - RTLIL::SigSpec lhs = lvalue.__chunks[i]; - RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.__chunks[i].width); - if (inSyncRule && lvalue.__chunks[i].wire && lvalue.__chunks[i].wire->get_bool_attribute("\\nosync")) - rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.__width); + for (size_t i = 0; i < lvalue.chunks().size(); i++) { + RTLIL::SigSpec lhs = lvalue.chunks()[i]; + RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks()[i].width); + if (inSyncRule && lvalue.chunks()[i].wire && lvalue.chunks()[i].wire->get_bool_attribute("\\nosync")) + rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size()); actions.push_back(RTLIL::SigSig(lhs, rhs)); - offset += lhs.__width; + offset += lhs.size(); } } @@ -460,7 +460,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_LE: { RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.__width, &subst_rvalue_from, &subst_rvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_from, &subst_rvalue_to); lvalue.replace(subst_lvalue_from, subst_lvalue_to); if (ast->type == AST_ASSIGN_EQ) { @@ -533,7 +533,7 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.__width, &subst_rvalue_from, &subst_rvalue_to)); + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_from, &subst_rvalue_to)); } if (default_case != current_case) sw->cases.push_back(current_case); @@ -1002,8 +1002,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } RTLIL::SigSpec sig; - sig.__chunks.push_back(chunk); - sig.__width = chunk.width; + sig.chunks().push_back(chunk); + sig.size() = chunk.width; if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); @@ -1016,7 +1016,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_TO_SIGNED: case AST_TO_UNSIGNED: { RTLIL::SigSpec sig = children[0]->genRTLIL(); - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, sign_hint); is_signed = sign_hint; return sig; @@ -1025,15 +1025,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // concatenation of signals can be done directly using RTLIL::SigSpec case AST_CONCAT: { RTLIL::SigSpec sig; - sig.__width = 0; + sig.size() = 0; for (auto it = children.begin(); it != children.end(); it++) { RTLIL::SigSpec s = (*it)->genRTLIL(); - for (size_t i = 0; i < s.__chunks.size(); i++) { - sig.__chunks.push_back(s.__chunks[i]); - sig.__width += s.__chunks[i].width; + for (size_t i = 0; i < s.chunks().size(); i++) { + sig.chunks().push_back(s.chunks()[i]); + sig.size() += s.chunks()[i].width; } } - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, false); return sig; } @@ -1048,7 +1048,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec sig; for (int i = 0; i < count; i++) sig.append(right); - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, false); is_signed = false; return sig; @@ -1061,7 +1061,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint); is_signed = children[0]->is_signed; - int width = arg.__width; + int width = arg.size(); if (width_hint > 0) { width = width_hint; widthExtend(this, arg, width, is_signed, "$pos"); @@ -1079,7 +1079,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); - int width = std::max(left.__width, right.__width); + int width = std::max(left.size(), right.size()); if (width_hint > 0) width = width_hint; is_signed = children[0]->is_signed && children[1]->is_signed; @@ -1102,7 +1102,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (0) { case AST_REDUCE_BOOL: type_name = "$reduce_bool"; } { RTLIL::SigSpec arg = children[0]->genRTLIL(); - RTLIL::SigSpec sig = arg.__width > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; + RTLIL::SigSpec sig = arg.size() > 1 ? uniop2rtlil(this, type_name, std::max(width_hint, 1), arg) : arg; return sig; } @@ -1116,7 +1116,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(); - int width = width_hint > 0 ? width_hint : left.__width; + int width = width_hint > 0 ? width_hint : left.size(); is_signed = children[0]->is_signed; return binop2rtlil(this, type_name, width, left, right); } @@ -1131,10 +1131,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) detectSignWidth(width_hint, sign_hint); RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(right_width, right_signed); - int width = width_hint > 0 ? width_hint : left.__width; + int width = width_hint > 0 ? width_hint : left.size(); is_signed = children[0]->is_signed; if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed) - return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.__width), right); + return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.size()), right); return binop2rtlil(this, "$pow", width, left, right); } @@ -1170,7 +1170,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint); #if 0 - int width = std::max(left.__width, right.__width); + int width = std::max(left.size(), right.size()); if (width > width_hint && width_hint > 0) width = width_hint; if (width < width_hint) { @@ -1179,10 +1179,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (type == AST_SUB && (!children[0]->is_signed || !children[1]->is_signed)) width = width_hint; if (type == AST_MUL) - width = std::min(left.__width + right.__width, width_hint); + width = std::min(left.size() + right.size(), width_hint); } #else - int width = std::max(std::max(left.__width, right.__width), width_hint); + int width = std::max(std::max(left.size(), right.size()), width_hint); #endif is_signed = children[0]->is_signed && children[1]->is_signed; return binop2rtlil(this, type_name, width, left, right); @@ -1214,17 +1214,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); - if (cond.__width > 1) + if (cond.size() > 1) cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); - int width = std::max(val1.__width, val2.__width); + int width = std::max(val1.size(), val2.size()); is_signed = children[1]->is_signed && children[2]->is_signed; widthExtend(this, val1, width, is_signed, "$bu0"); widthExtend(this, val2, width, is_signed, "$bu0"); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); - if (sig.__width < width_hint) + if (sig.size() < width_hint) sig.extend_u0(width_hint, sign_hint); return sig; } @@ -1304,10 +1304,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(children.size() == 2); RTLIL::SigSpec check = children[0]->genRTLIL(); - log_assert(check.__width == 1); + log_assert(check.size() == 1); RTLIL::SigSpec en = children[1]->genRTLIL(); - log_assert(en.__width == 1); + log_assert(en.size() == 1); std::stringstream sstr; sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); @@ -1335,11 +1335,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) { if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); - RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.__width); + RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.size()); current_module->connections.push_back(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); - RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.__width); + RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); current_module->connections.push_back(RTLIL::SigSig(left, right)); } } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e6d3d4c5b..e8af447ba 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -363,8 +363,8 @@ sigspec: chunk.offset = 0; chunk.data = *$1; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = chunk.width; + $$->chunks().push_back(chunk); + $$->size() = chunk.width; delete $1; } | TOK_ID { @@ -375,8 +375,8 @@ sigspec: chunk.width = current_module->wires[$1]->width; chunk.offset = 0; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = chunk.width; + $$->chunks().push_back(chunk); + $$->size() = chunk.width; free($1); } | TOK_ID '[' TOK_INT ']' { @@ -387,8 +387,8 @@ sigspec: chunk.offset = $3; chunk.width = 1; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = 1; + $$->chunks().push_back(chunk); + $$->size() = 1; free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { @@ -399,8 +399,8 @@ sigspec: chunk.width = $3 - $5 + 1; chunk.offset = $5; $$ = new RTLIL::SigSpec; - $$->__chunks.push_back(chunk); - $$->__width = chunk.width; + $$->chunks().push_back(chunk); + $$->size() = chunk.width; free($1); } | '{' sigspec_list '}' { @@ -410,13 +410,13 @@ sigspec: sigspec_list: sigspec_list sigspec { $$ = new RTLIL::SigSpec; - for (auto it = $2->__chunks.begin(); it != $2->__chunks.end(); it++) { - $$->__chunks.push_back(*it); - $$->__width += it->width; + for (auto it = $2->chunks().begin(); it != $2->chunks().end(); it++) { + $$->chunks().push_back(*it); + $$->size() += it->width; } - for (auto it = $1->__chunks.begin(); it != $1->__chunks.end(); it++) { - $$->__chunks.push_back(*it); - $$->__width += it->width; + for (auto it = $1->chunks().begin(); it != $1->chunks().end(); it++) { + $$->chunks().push_back(*it); + $$->size() += it->width; } delete $1; delete $2; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index c449a5936..3fe227bec 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -244,7 +244,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (clk_sig.__width == 0 || data_sig.__width == 0) + if (clk_sig.size() == 0 || data_sig.size() == 0) log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -284,21 +284,21 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) cell->connections["\\C"] = clk_sig; module->add(cell); - if (clear_sig.__width == 0 && preset_sig.__width == 0) { + if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); } - if (clear_sig.__width == 1 && preset_sig.__width == 0) { + if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\R"] = clear_sig; } - if (clear_sig.__width == 0 && preset_sig.__width == 1) { + if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); cell->connections["\\R"] = preset_sig; } - if (clear_sig.__width == 1 && preset_sig.__width == 1) { + if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); cell->connections["\\S"] = preset_sig; cell->connections["\\R"] = clear_sig; @@ -326,7 +326,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) preset_sig = parse_func_expr(module, child->value.c_str()); } - if (enable_sig.__width == 0 || data_sig.__width == 0) + if (enable_sig.size() == 0 || data_sig.size() == 0) log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) @@ -359,7 +359,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) cell->connections["\\Y"] = iqn_sig; module->add(cell); - if (clear_sig.__width == 1) + if (clear_sig.size() == 1) { RTLIL::SigSpec clear_negative = clear_sig; RTLIL::SigSpec clear_enable = clear_sig; @@ -396,7 +396,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) module->add(enable_gate); } - if (preset_sig.__width == 1) + if (preset_sig.size() == 1) { RTLIL::SigSpec preset_positive = preset_sig; RTLIL::SigSpec preset_enable = preset_sig; diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 0ca26bb34..934796d24 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 fa079e14e..564098c6a 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 043323095..43511304e 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 7fb416f1f..88ed2f6a2 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 012b6ab89..9e2277076 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 c886ff168..27abd8670 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 e21be30b8..2d921b7be 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 65ebe541d..47fa0f821 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 f8f9e0590..dcd5fc96b 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 426d2b624..6cb2a892c 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 16828e4fb..c5aa196c6 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 da36c7821..d5976dcb0 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 d668bc3a4..49e79bd4d 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 068162eb1..123483a3a 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 3a99c0cec..7558a4e9a 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 0006a3ff4..fde96d537 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 80a7f90c0..aed9c076e 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 7572baa35..8cc6a5152 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 523feae92..2ba4c72b8 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 e4d20077c..0dd328db3 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 c0b5857f0..701b09bd8 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 f11d78b39..f8ffee523 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 6732d2abd..367b38eb1 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 6b1753060..718b97043 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 5d9dc18a4..90f377e0d 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 f8f2b596b..fa8043c89 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 6c9e1b773..5f06438f0 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 174417bd6..8bae24cff 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 b848e09e4..e605e6e51 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 e56d14b68..5c349f702 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 8a097916d..68fb2e72c 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 bee86771c..1a1f0fe42 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 e844a4209..61147f67a 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 4f1176d97..7ab7233c6 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 879f7ddc6..4215a7b54 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 07e512cba..819a0e460 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 a773e5e72..b5763508a 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 768660686..682515c5e 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 d3dff8efc..8e5fbe8f4 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 0ef17b22d..ba1fb5ab9 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 2e24e786b..cd459d949 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 5369617be..03a86246c 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 4308e7364..c9363f4bf 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 8cc59b291..1e47e7de2 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 1cd794b56..79857c5ea 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 161449324..24968aa2c 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 95f35bb3e..738b0bd6d 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 7e57aa0f5..a960f2bae 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 22f4c7d1d..ac41e47ca 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 cef5cc89e..1eb5c063b 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 f7d5efa0a..d3e7e20fc 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 -- cgit v1.2.3 From 7bffde6abdaf6fc2ed090946442f90b2438e6126 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:39:13 +0200 Subject: SigSpec refactoring: change RTLIL::SigSpec::size() to be read-only --- frontends/ast/genrtlil.cc | 66 ++++++++--------------------------------------- frontends/ilang/parser.y | 43 +++++------------------------- kernel/rtlil.h | 3 +-- 3 files changed, 18 insertions(+), 94 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 681b34860..34a3f1ba9 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -56,15 +56,6 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi wire->width = result_width; current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; - if (gen_attributes) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -78,8 +69,8 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->connections["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = sig; - return sig; + cell->connections["\\Y"] = wire; + return wire; } // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) @@ -105,15 +96,6 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s wire->width = width; current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec new_sig; - new_sig.chunks().push_back(chunk); - new_sig.size() = chunk.width; - if (that != NULL) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -127,8 +109,8 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->connections["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; - cell->connections["\\Y"] = new_sig; - sig = new_sig; + cell->connections["\\Y"] = wire; + sig = wire; } // helper function for creating RTLIL code for binary operations @@ -149,15 +131,6 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi wire->width = result_width; current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; - for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -175,8 +148,8 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->connections["\\B"] = right; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = sig; - return sig; + cell->connections["\\Y"] = wire; + return wire; } // helper function for creating RTLIL code for multiplexers @@ -199,15 +172,6 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const wire->width = left.size(); current_module->wires[wire->name] = wire; - RTLIL::SigChunk chunk; - chunk.wire = wire; - chunk.width = wire->width; - chunk.offset = 0; - - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; - for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -220,9 +184,9 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->connections["\\A"] = right; cell->connections["\\B"] = left; cell->connections["\\S"] = cond; - cell->connections["\\Y"] = sig; + cell->connections["\\Y"] = wire; - return sig; + return wire; } // helper class for converting AST always nodes to RTLIL processes @@ -1001,9 +965,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } } - RTLIL::SigSpec sig; - sig.chunks().push_back(chunk); - sig.size() = chunk.width; + RTLIL::SigSpec sig(chunk); if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); @@ -1025,14 +987,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // concatenation of signals can be done directly using RTLIL::SigSpec case AST_CONCAT: { RTLIL::SigSpec sig; - sig.size() = 0; - for (auto it = children.begin(); it != children.end(); it++) { - RTLIL::SigSpec s = (*it)->genRTLIL(); - for (size_t i = 0; i < s.chunks().size(); i++) { - sig.chunks().push_back(s.chunks()[i]); - sig.size() += s.chunks()[i].width; - } - } + for (auto it = children.begin(); it != children.end(); it++) + sig.append((*it)->genRTLIL()); if (sig.size() < width_hint) sig.extend_u0(width_hint, false); return sig; diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e8af447ba..e4d12f3a1 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -357,50 +357,25 @@ constant: sigspec: constant { - RTLIL::SigChunk chunk; - chunk.wire = NULL; - chunk.width = $1->bits.size(); - chunk.offset = 0; - chunk.data = *$1; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = chunk.width; + $$ = new RTLIL::SigSpec(*$1); delete $1; } | TOK_ID { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - RTLIL::SigChunk chunk; - chunk.wire = current_module->wires[$1]; - chunk.width = current_module->wires[$1]->width; - chunk.offset = 0; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = chunk.width; + $$ = new RTLIL::SigSpec(current_module->wires[$1]); free($1); } | TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - RTLIL::SigChunk chunk; - chunk.wire = current_module->wires[$1]; - chunk.offset = $3; - chunk.width = 1; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = 1; + $$ = new RTLIL::SigSpec(current_module->wires[$1], 1, $3); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - RTLIL::SigChunk chunk; - chunk.wire = current_module->wires[$1]; - chunk.width = $3 - $5 + 1; - chunk.offset = $5; - $$ = new RTLIL::SigSpec; - $$->chunks().push_back(chunk); - $$->size() = chunk.width; + $$ = new RTLIL::SigSpec(current_module->wires[$1], $3 - $5 + 1, $5); free($1); } | '{' sigspec_list '}' { @@ -410,14 +385,8 @@ sigspec: sigspec_list: sigspec_list sigspec { $$ = new RTLIL::SigSpec; - for (auto it = $2->chunks().begin(); it != $2->chunks().end(); it++) { - $$->chunks().push_back(*it); - $$->size() += it->width; - } - for (auto it = $1->chunks().begin(); it != $1->chunks().end(); it++) { - $$->chunks().push_back(*it); - $$->size() += it->width; - } + $$->append(*$2); + $$->append(*$1); delete $1; delete $2; } | diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 88ed2f6a2..6bbf69602 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); -- cgit v1.2.3 From 28b3fd05fa9cf6d469fdec95e247a7ffe5bc001d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 20:58:44 +0200 Subject: SigSpec refactoring: change RTLIL::SigSpec::chunks() to be read-only, created interim RTLIL::SigSpec::chunks_rw() --- 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 7853160e2..9139749c0 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 4b60f0fbd..160835087 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 34a3f1ba9..a51064c3e 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -311,7 +311,7 @@ struct AST_INTERNAL::ProcessGenerator sig.optimize(); for (size_t i = 0; i < sig.chunks().size(); i++) { - RTLIL::SigChunk &chunk = sig.chunks()[i]; + RTLIL::SigChunk &chunk = sig.chunks_rw()[i]; if (chunk.wire == NULL) continue; diff --git a/kernel/consteval.h b/kernel/consteval.h index 564098c6a..5836cdd5b 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 43511304e..361cd5f04 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 6bbf69602..9d5b3b304 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 27abd8670..826f84179 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 c5aa196c6..f433c4b4a 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 7558a4e9a..619930b3a 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 fde96d537..37fe44047 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 8cc6a5152..d71e9727c 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 701b09bd8..c3bb1933a 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 fa8043c89..b983a840e 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 8bae24cff..dee48597f 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 1a1f0fe42..9b89291b1 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 b5763508a..6cb560f5c 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 03a86246c..73235e930 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 a960f2bae..5a7298087 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 ac41e47ca..53c5d1044 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 d3e7e20fc..f3b1a0ef7 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]; } } -- cgit v1.2.3 From 08e1e251698edfec7e0634a8ccdc321f42e8f27f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 21:33:52 +0200 Subject: 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 361cd5f04..8058f69cf 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 9d5b3b304..1d84dd3bb 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_; -public: - std::vector &chunks_rw() { return chunks_; } - const std::vector &chunks() const { return chunks_; } - - int size() const { return width_; } + void pack() const; + void unpack() const; + bool packed() const; +public: 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) { -- cgit v1.2.3 From a97be0828a3998d1eb5128e8e24c75af2016f27b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 21:40:52 +0200 Subject: 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 8058f69cf..937dcbce5 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 1d84dd3bb..facd43db4 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 { -- cgit v1.2.3 From fd4cbe627527561fb08bc77467f2b6a250d5dc4d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:26:30 +0200 Subject: SigSpec refactoring: rewrote some RTLIL::SigSpec methods to use unpacked form --- kernel/rtlil.cc | 295 ++++++++++++++++++++++---------------------------------- 1 file changed, 113 insertions(+), 182 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 937dcbce5..d46014050 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(); + if (other != NULL) { + assert(width_ == other->width_); + other->unpack(); + } - 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; + 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 -- cgit v1.2.3 From e7e30f1c86d978131a5f4c6e62b5b8d822696cd1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:52:57 +0200 Subject: 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 367b38eb1..d5a9b71fa 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); -- cgit v1.2.3 From f80da7b41dd9c12d3bd65ceab6c0c6748a70a78c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:54:03 +0200 Subject: 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 facd43db4..da3a2661e 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); -- cgit v1.2.3 From 65a939cb2767623b95adcd2ec5e783b828c1f9eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 22:54:39 +0200 Subject: 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 cd459d949..50ba8fa1e 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)) { -- cgit v1.2.3 From 4a6d234ec7acff085e3c923d3872d0863c766ad1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 23:07:42 +0200 Subject: 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 c3bb1933a..dfd025a51 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 d5a9b71fa..efa61245a 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 718b97043..d0be71c5b 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)); } -- cgit v1.2.3 From 9e94f41b89bca54f8a3ce2e8e54c0467a7e8c43d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 23:49:26 +0200 Subject: 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 da3a2661e..53770088b 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]); -- cgit v1.2.3 From 115dd959d9dbf68aa30f8374df0e62fba8646f1e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 22 Jul 2014 23:50:21 +0200 Subject: SigSpec refactoring: More cleanups of old SigSpec use pattern --- frontends/ast/genrtlil.cc | 9 +++-- 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 a51064c3e..18ae008cb 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -309,9 +309,11 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { sig.optimize(); - for (size_t i = 0; i < sig.chunks().size(); i++) + std::vector chunks = sig.chunks(); + + for (int i = 0; i < SIZE(chunks); i++) { - RTLIL::SigChunk &chunk = sig.chunks_rw()[i]; + RTLIL::SigChunk &chunk = chunks[i]; if (chunk.wire == NULL) continue; @@ -329,7 +331,8 @@ struct AST_INTERNAL::ProcessGenerator chunk.wire = wire; chunk.offset = 0; } - return sig; + + return chunks; } // recursively traverse the AST an collect all assigned signals diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d46014050..6757d5dc3 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 826f84179..e93780b49 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 -- cgit v1.2.3 From c61467a32c4bd3ec4b9e0cb6d36d602f0e4dea81 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 08:59:54 +0200 Subject: 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 6757d5dc3..2ab4a8c6e 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 53770088b..0e74c958a 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); -- cgit v1.2.3 From 260c19ec5a3adb292158658dd69a352b9325ab64 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 09:00:16 +0200 Subject: 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 2ab4a8c6e..acfba057f 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 0e74c958a..542e685de 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 2d921b7be..e7371ec52 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 738b0bd6d..724bc3f98 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)); -- cgit v1.2.3 From a8d3a68971ccc4e47c54a906aae374a9a54b1415 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 08:40:31 +0200 Subject: Refactoring {SigSpec|SigChunk}(RTLIL::Wire *wire, ..) constructor -- step 2/3 --- 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 90d1b3fc4..edb6809ee 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 bb2b26e26..f003c750d 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 e4d12f3a1..dcb51d44d 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -369,13 +369,13 @@ sigspec: TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], 1, $3); + $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $3)); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], $3 - $5 + 1, $5); + $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $5, $3 - $5 + 1)); free($1); } | '{' sigspec_list '}' { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index acfba057f..f5b84bc66 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 e93780b49..d011b0ef5 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 e7371ec52..fa2c49604 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 f8ffee523..1ac9664ad 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 5c349f702..45c01f74a 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 68fb2e72c..165bb25c9 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 50ba8fa1e..0fe765732 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 73235e930..91b428126 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 79857c5ea..51cf3ae0d 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 724bc3f98..c209e8ed7 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 5a7298087..988917b17 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 eb2757f66..2cb76014c 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()) -- cgit v1.2.3 From ec923652e2eb721aa16657e54a67666f855c3d65 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 09:48:26 +0200 Subject: Refactoring {SigSpec|SigChunk}(RTLIL::Wire *wire, ..) constructor -- step 3/3 --- 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 edb6809ee..a240d2a26 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 f003c750d..74cf24997 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 dcb51d44d..3fe5199f3 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -369,13 +369,13 @@ sigspec: TOK_ID '[' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $3)); + $$ = new RTLIL::SigSpec(current_module->wires[$1], $3); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { if (current_module->wires.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(RTLIL::SigSpec::grml(current_module->wires[$1], $5, $3 - $5 + 1)); + $$ = new RTLIL::SigSpec(current_module->wires[$1], $5, $3 - $5 + 1); free($1); } | '{' sigspec_list '}' { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f5b84bc66..6bb3e6126 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 542e685de..832146594 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 d011b0ef5..cd179ebf0 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 fa2c49604..8cdd39b7a 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 1ac9664ad..9dda2ba89 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 45c01f74a..38eff9961 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 165bb25c9..23fc48d5d 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 0fe765732..804c51fd3 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 91b428126..902dedb62 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 51cf3ae0d..12384e2cc 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 c209e8ed7..ede2fa88c 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 988917b17..1687a1ffb 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 2cb76014c..09147383a 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()) -- cgit v1.2.3 From 85db102e13bbd6decda3f99ef640d0991ee24b33 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 15:35:09 +0200 Subject: 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 6bb3e6126..f907ff642 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 832146594..80007ab8c 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; -- cgit v1.2.3 From 4e802eb7f6fe5858f8657be7cd3e6638cc0f2ece Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 15:36:09 +0200 Subject: Fixed all users of SigSpec::chunks_rw() and removed it --- kernel/rtlil.h | 4 ++-- passes/cmds/delete.cc | 5 ++-- passes/cmds/setundef.cc | 57 ++++++++++++++++++++++----------------------- 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, 77 insertions(+), 88 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 80007ab8c..e1c5b1a6b 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 f433c4b4a..7fe95b0a9 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 619930b3a..63d5bb9af 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() +struct SetundefWorker { - if (next_bit_mode == 0) - return RTLIL::State::S0; + int next_bit_mode; + uint32_t next_bit_state; - if (next_bit_mode == 1) - return RTLIL::State::S1; + RTLIL::State next_bit() + { + if (next_bit_mode == 0) + return RTLIL::State::S0; - // 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); + if (next_bit_mode == 1) + return RTLIL::State::S1; - return ((next_bit_state >> (next_bit_state & 15)) & 16) ? RTLIL::State::S0 : 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 -{ 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 d71e9727c..c40ff2c4a 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 b983a840e..257301880 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 dee48597f..b1f1e22b5 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 6cb560f5c..145abfa43 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 902dedb62..090f7463a 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 1687a1ffb..e5055c9c4 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 53c5d1044..51b8802c4 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 f3b1a0ef7..8d7b21e0f 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 -- cgit v1.2.3 From 54552f680938fd933b07fa38597937ba6d367be7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 19:30:21 +0200 Subject: Added eclipse .setting folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f251d2b6d..bb50d357b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .*.swp /.cproject /.project +/.settings /qtcreator.files /qtcreator.includes /qtcreator.config -- cgit v1.2.3 From a62c21c9c64ad5b3e0dae5d4ee4857425f73068e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 16:09:27 +0200 Subject: 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 74cf24997..3b9a43370 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 5836cdd5b..3a8ef44a0 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 f907ff642..7dcf32b7e 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 e1c5b1a6b..6c0a7b66f 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 9e2277076..ea04cb409 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 cd179ebf0..1a84194ee 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 1c71f78b8..efb3ca958 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 8cdd39b7a..ba27a3fc6 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 23fc48d5d..0be36606d 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 9b89291b1..ff139854f 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 61147f67a..dfcd55126 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 7ab7233c6..913855f48 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 090f7463a..9b8c35361 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 24968aa2c..34becaee8 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 e5055c9c4..4c3aec31d 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 1eb5c063b..034677d3b 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); } } -- cgit v1.2.3 From 3ec785b881a7bbceb5ac4db1e761b75c07f8642a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 19:36:43 +0200 Subject: 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 efb3ca958..3f8d553ad 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) -- cgit v1.2.3 From 8fd8e4a468fb650fe5dcbe892c07010f627e2c2b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:11:55 +0200 Subject: 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 7dcf32b7e..32a6b2775 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; + } + + if (packed() != signal.packed()) { + pack(); + signal.pack(); } - // check(); + 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); -- cgit v1.2.3 From c094c53de83707a5bf1b268640283f1dde235873 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:32:28 +0200 Subject: Removed RTLIL::SigSpec::optimize() --- 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 a240d2a26..d0c250790 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 3b9a43370..8f36f4090 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 832922def..a4cad5add 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 160835087..1dcc3003a 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 18ae008cb..3d848e823 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -292,8 +292,6 @@ struct AST_INTERNAL::ProcessGenerator proc->syncs.push_back(sync); assert(init_lvalue.size() == init_rvalue.size()); - init_lvalue.optimize(); - init_rvalue.optimize(); int offset = 0; for (size_t i = 0; i < init_lvalue.chunks().size(); i++) { @@ -308,7 +306,6 @@ struct AST_INTERNAL::ProcessGenerator // create new temporary signals RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { - sig.optimize(); std::vector chunks = sig.chunks(); for (int i = 0; i < SIZE(chunks); i++) @@ -399,8 +396,6 @@ struct AST_INTERNAL::ProcessGenerator lvalue.remove2(initSyncSignals, &rvalue); } assert(lvalue.size() == rvalue.size()); - lvalue.optimize(); - rvalue.optimize(); int offset = 0; for (size_t i = 0; i < lvalue.chunks().size(); i++) { @@ -433,9 +428,7 @@ struct AST_INTERNAL::ProcessGenerator if (ast->type == AST_ASSIGN_EQ) { subst_rvalue_from.remove2(unmapped_lvalue, &subst_rvalue_to); subst_rvalue_from.append(unmapped_lvalue); - subst_rvalue_from.optimize(); subst_rvalue_to.append(rvalue); - subst_rvalue_to.optimize(); } removeSignalFromCaseTree(lvalue, current_case); @@ -486,9 +479,7 @@ struct AST_INTERNAL::ProcessGenerator subst_lvalue_from.remove2(this_case_eq_lvalue, &subst_lvalue_to); subst_lvalue_from.append(this_case_eq_lvalue); - subst_lvalue_from.optimize(); subst_lvalue_to.append(this_case_eq_ltemp); - subst_lvalue_to.optimize(); RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; @@ -527,9 +518,7 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_from.remove2(this_case_eq_lvalue, &subst_rvalue_to); subst_rvalue_from.append(this_case_eq_lvalue); - subst_rvalue_from.optimize(); subst_rvalue_to.append(this_case_eq_ltemp); - subst_rvalue_to.optimize(); this_case_eq_lvalue.replace(subst_lvalue_from, subst_lvalue_to); removeSignalFromCaseTree(this_case_eq_lvalue, current_case); diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 934796d24..4f4bc37a0 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 32a6b2775..7d031e174 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 6c0a7b66f..a13164c37 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 47fa0f821..04977b369 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 63d5bb9af..6c4bb16c0 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 37fe44047..6b37b7bb1 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 aed9c076e..68e8951ff 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 c40ff2c4a..c65b6a5f8 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 9dda2ba89..cee267629 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 b1f1e22b5..56915776e 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 38eff9961..dd2a32cad 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 0be36606d..ba0aadc6b 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 ff139854f..800fbf109 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 8e5fbe8f4..a8aba903a 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 ba1fb5ab9..4c9b6bcd2 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 9b8c35361..6949b76db 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 1e47e7de2..ba01bc322 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 34becaee8..4b6b1b719 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)); } -- cgit v1.2.3 From 20a7965f61a43b8c367b1042081a57b5a4005b33 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 20:45:27 +0200 Subject: Various small fixes (from gcc compiler warnings) --- frontends/ast/simplify.cc | 2 +- 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 f819b2506..d86bfb3f0 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2259,7 +2259,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) log_error("Non-constant range in %s:%d (called from %s:%d).\n", range->filename.c_str(), range->linenum, fcall->filename.c_str(), fcall->linenum); int offset = std::min(range->range_left, range->range_right); - int width = std::min(std::abs(range->range_left - range->range_right) + 1, width); + int width = std::abs(range->range_left - range->range_right) + 1; varinfo_t &v = variables[stmt->children.at(0)->str]; RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size()); for (int i = 0; i < width; i++) diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h index d0be71c5b..ae9569ed7 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"); -- cgit v1.2.3 From 2a41afb7b2415f824ea1f60337050c9f41c0e33f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:34:14 +0200 Subject: 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 7d031e174..d2f37cec4 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 a13164c37..95de5f8c6 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); } -- cgit v1.2.3 From 375aa71dfe53217ef4dd6273b96f53061b5c8e8c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:35:01 +0200 Subject: Various fixes in Verific frontend for new RTLIL API --- frontends/verific/build_amd64.txt | 33 ++++++++++++++++++++++++++ frontends/verific/verific.cc | 49 ++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 27 deletions(-) create mode 100644 frontends/verific/build_amd64.txt diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt new file mode 100644 index 000000000..49debe0f0 --- /dev/null +++ b/frontends/verific/build_amd64.txt @@ -0,0 +1,33 @@ + +Notes on buildin yosys with verific support on amd64 when you only have the +i386 eval version of Verific: + + +1.) Use a Makefile.conf like the following one: + +--snip-- +CONFIG := clang-debug +ENABLE_TCL := 0 +ENABLE_QT4 := 0 +ENABLE_ABC := 0 +ENABLE_VERIFIC := 1 +CXXFLAGS += -m32 +LDFLAGS += -m32 +--snap-- + + +2.) Install the neccessary multilib packages. + +Hint: On debian/ubuntu the multilib packages have names such as +libreadline-dev:amd64 or lib32readline6-dev, depending on the version +of the system you are working with. + +Hint: On Ubuntu 14.04 there is a problem with the 32bit libz +package. A workaround is running the following command in the +yosys source directory: + + ln -s /usr/include/x86_64-linux-gnu/zconf.h . + + +3.) Run 'make' and 'make install' as usual. + diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 7411e9434..c973988bb 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -82,7 +82,6 @@ static RTLIL::SigSpec operatorInput(Instance *inst, std::mapGetInputBit(i))); else sig.append(RTLIL::State::Sz); - sig.optimize(); return sig; } @@ -94,7 +93,6 @@ static RTLIL::SigSpec operatorInput1(Instance *inst, std::mapGetInput1Bit(i))); else sig.append(RTLIL::State::Sz); - sig.optimize(); return sig; } @@ -106,7 +104,6 @@ static RTLIL::SigSpec operatorInput2(Instance *inst, std::mapGetInput2Bit(i))); else sig.append(RTLIL::State::Sz); - sig.optimize(); return sig; } @@ -127,7 +124,6 @@ static RTLIL::SigSpec operatorInport(Instance *inst, const char *portname, std:: } else sig.append(RTLIL::State::Sz); } - sig.optimize(); return sig; } else { Port *port = inst->View()->GetPort(portname); @@ -147,12 +143,11 @@ static RTLIL::SigSpec operatorOutput(Instance *inst, std::mapnew_wire(1, NEW_ID); + dummy_wire = module->addWire(NEW_ID); else dummy_wire->width++; - sig.append(RTLIL::SigSpec(dummy_wire, 1, dummy_wire->width - 1)); + sig.append(RTLIL::SigSpec(dummy_wire, dummy_wire->width - 1)); } - sig.optimize(); return sig; } @@ -164,7 +159,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NAND) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addAndGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -176,7 +171,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NOR) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addOrGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -205,11 +200,11 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_FADD) { RTLIL::SigSpec a = net_map.at(inst->GetInput1()), b = net_map.at(inst->GetInput2()), c = net_map.at(inst->GetCin()); - RTLIL::SigSpec x = inst->GetCout() ? net_map.at(inst->GetCout()) : module->new_wire(1, NEW_ID); - RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp1 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp2 = module->new_wire(1, NEW_ID); - RTLIL::SigSpec tmp3 = module->new_wire(1, NEW_ID); + RTLIL::SigSpec x = inst->GetCout() ? net_map.at(inst->GetCout()) : module->addWire(NEW_ID); + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->addWire(NEW_ID); + RTLIL::SigSpec tmp1 = module->addWire(NEW_ID); + RTLIL::SigSpec tmp2 = module->addWire(NEW_ID); + RTLIL::SigSpec tmp3 = module->addWire(NEW_ID); module->addXorGate(NEW_ID, a, b, tmp1); module->addXorGate(RTLIL::escape_id(inst->Name()), tmp1, c, y); module->addAndGate(NEW_ID, tmp1, c, tmp2); @@ -245,7 +240,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_NAND) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addAnd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -257,7 +252,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_NOR) { - RTLIL::SigSpec tmp = module->new_wire(1, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addOr(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); module->addNot(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; @@ -290,8 +285,8 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapType() == PRIM_FADD) { - RTLIL::SigSpec a_plus_b = module->new_wire(2, NEW_ID); - RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->new_wire(1, NEW_ID); + RTLIL::SigSpec a_plus_b = module->addWire(NEW_ID, 2); + RTLIL::SigSpec y = inst->GetOutput() ? net_map.at(inst->GetOutput()) : module->addWire(NEW_ID); if (inst->GetCout()) y.append(net_map.at(inst->GetCout())); module->addAdd(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), a_plus_b); @@ -328,7 +323,7 @@ static bool import_netlist_instance_cells(RTLIL::Module *module, std::mapGetCin()->IsGnd()) { module->addAdd(RTLIL::escape_id(inst->Name()), IN1, IN2, out, SIGNED); } else { - RTLIL::SigSpec tmp = module->new_wire(out.width, NEW_ID); + RTLIL::SigSpec tmp = module->addWire(NEW_ID, SIZE(out)); module->addAdd(NEW_ID, IN1, IN2, tmp, SIGNED); module->addAdd(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetCin()), out, false); } @@ -705,8 +700,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\TRANSPARENT"] = false; - cell->parameters["\\ABITS"] = addr.width; - cell->parameters["\\WIDTH"] = data.width; + cell->parameters["\\ABITS"] = SIZE(addr); + cell->parameters["\\WIDTH"] = SIZE(data); cell->connections["\\CLK"] = RTLIL::State::S0; cell->connections["\\ADDR"] = addr; cell->connections["\\DATA"] = data; @@ -730,9 +725,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\PRIORITY"] = 0; - cell->parameters["\\ABITS"] = addr.width; - cell->parameters["\\WIDTH"] = data.width; - cell->connections["\\EN"] = net_map.at(inst->GetControl()); + cell->parameters["\\ABITS"] = SIZE(addr); + cell->parameters["\\WIDTH"] = SIZE(data); + cell->connections["\\EN"] = RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data)); cell->connections["\\CLK"] = RTLIL::State::S0; cell->connections["\\ADDR"] = addr; cell->connections["\\DATA"] = data; @@ -749,7 +744,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator()) - log("Warning: Unsupported Verific operator: %s\n", inst->View()->Owner()->Name()); + log("Warning: Unsupported Verific operator: %s (fallback to gate level implementation provided by verific)\n", inst->View()->Owner()->Name()); } else { if (import_netlist_instance_gates(module, net_map, inst)) continue; @@ -775,9 +770,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; - while (conn.width <= port_offset) { + while (SIZE(conn) <= port_offset) { if (pr->GetPort()->GetDir() != DIR_IN) - conn.append(module->new_wire(port_offset - conn.width, NEW_ID)); + conn.append(module->addWire(NEW_ID, port_offset - SIZE(conn))); conn.append(RTLIL::State::Sz); } conn.replace(port_offset, net_map.at(pr->GetNet())); -- cgit v1.2.3 From 95ac484548d4a4550568de09343964150806042d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:38:18 +0200 Subject: Fixed release build --- kernel/rtlil.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index d2f37cec4..7d630b352 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() -- cgit v1.2.3 From f368d792fbe6a4430dbf710b11e89cbf58439542 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 21:42:44 +0200 Subject: 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 7d630b352..b0958bd0d 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 -- cgit v1.2.3 From 82fa3560372bd89ad0985644a76cdd14f6701ec2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 23 Jul 2014 23:58:03 +0200 Subject: Added hashing to RTLIL::SigSpec relational and equal operators --- kernel/rtlil.cc | 79 ++++++++++++++++++++++++++++++++++++++++++++++----------- kernel/rtlil.h | 9 +++++-- 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b0958bd0d..87c9cd04c 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 (chunks_.size() != other.chunks_.size()) + return chunks_.size() < other.chunks_.size(); + + hash(); + other.hash(); - if (a.chunks_.size() != b.chunks_.size()) - return a.chunks_.size() < b.chunks_.size(); + if (hash_ != other.hash_) + return hash_ < other.hash_; - 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 < 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 { + if (this == &other) + return true; + + if (width_ != other.width_) + return false; + pack(); other.pack(); - if (width_ != other.width_) + if (chunks_.size() != chunks_.size()) return false; - RTLIL::SigSpec a = *this, b = other; + hash(); + other.hash(); - if (a.chunks_.size() != b.chunks_.size()) + if (hash_ != other.hash_) 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 < chunks_.size(); i++) + if (chunks_[i] != other.chunks_[i]) return false; return true; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 95de5f8c6..c25f71855 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()) -- cgit v1.2.3 From fa71ae89acf319696975a79472272aa30975af7f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 02:11:12 +0200 Subject: Added "make vloghtb" --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 6f9daa04a..94b8ad4a6 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/ -- cgit v1.2.3 From 2267db58341ccd5beed74da61e8830faa004af69 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 02:12:24 +0200 Subject: Added "make config-gcc-4.7" --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index 94b8ad4a6..10bd9407e 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 -- cgit v1.2.3 From b31762d158f4c9fb406cd787361254330f4ec03e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 02:13:37 +0200 Subject: 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 000000000..bb12932df --- /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+" + -- cgit v1.2.3 From 6b1018314c130ffa12df2e8c73f1c0cd5853b6f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 03:48:38 +0200 Subject: 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 949bf4327..26414d493 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 00265dbe0..517808061 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 -- cgit v1.2.3 From 9cf12570ba639ca23e1d611a27160fb46b3c46d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 03:49:32 +0200 Subject: 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 e365e67c3..4992686bd 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(); -- cgit v1.2.3 From 1b0d5fc22d1a1e590cb8f2252956ef1b0a38dda0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 03:50:28 +0200 Subject: 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 87c9cd04c..4a0ac60f0 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; } } -- cgit v1.2.3 From 798f71362975c625f4e24b0c981b15b5684ab33d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 04:16:32 +0200 Subject: 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 4992686bd..9749ff305 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 4a0ac60f0..ca8e9b6d8 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; } -- cgit v1.2.3 From 3a2c5357771df05f80bff55e8ab3e467308c57d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 04:24:47 +0200 Subject: Renamed RELEASE_CHECKLIST -> CHECKLIST --- CHECKLIST | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ RELEASE_CHECKLIST | 87 ---------------------------------------------------- 2 files changed, 92 insertions(+), 87 deletions(-) create mode 100644 CHECKLIST delete mode 100644 RELEASE_CHECKLIST diff --git a/CHECKLIST b/CHECKLIST new file mode 100644 index 000000000..c621b7156 --- /dev/null +++ b/CHECKLIST @@ -0,0 +1,92 @@ + + +Checklist for creating Yosys releases +===================================== + + +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+" + diff --git a/RELEASE_CHECKLIST b/RELEASE_CHECKLIST deleted file mode 100644 index bb12932df..000000000 --- a/RELEASE_CHECKLIST +++ /dev/null @@ -1,87 +0,0 @@ - -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+" - -- cgit v1.2.3 From 22ede43b3f5016784b2e22c0ea95b7f718d7598e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 04:46:36 +0200 Subject: 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 ca8e9b6d8..5194b5f7d 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 c25f71855..68eee46ea 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 { -- cgit v1.2.3 From 7679000673f7a5c07037dfd3373162cbbcdb0624 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 15:05:05 +0200 Subject: 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 9749ff305..64165737e 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 26414d493..949bf4327 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 517808061..804175909 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 -- cgit v1.2.3 From e589289df7662f076d12f7237321b429401952e2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 15:05:41 +0200 Subject: 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 5194b5f7d..8e509f360 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"); -- cgit v1.2.3 From 2f54345cff3aea768bb89754654127a3b0ee58e9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 15:06:45 +0200 Subject: 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 10bd9407e..272161ef4 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 64165737e..a4556fb1b 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 804175909..0e8d08272 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 84051948f..e7ad7ef05 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 b07c46177..fd073cbe7 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 3a4b2da71..6ae4495a8 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 000000000..ebbdc7c4c --- /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 dd9591954..e2f69e599 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) -- cgit v1.2.3 From b17d6531c833f9064c5888c694aa24e8a395b72a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:15:01 +0200 Subject: Added "make PRETTY=1" --- 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 272161ef4..d57d02b28 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 f81c8de91..e832cfed8 100644 --- a/frontends/ilang/Makefile.inc +++ b/frontends/ilang/Makefile.inc @@ -5,13 +5,13 @@ GENFILES += frontends/ilang/parser.output GENFILES += frontends/ilang/lexer.cc frontends/ilang/parser.tab.cc: frontends/ilang/parser.y - bison -d -r all -b frontends/ilang/parser frontends/ilang/parser.y - mv frontends/ilang/parser.tab.c frontends/ilang/parser.tab.cc + $(P) bison -d -r all -b frontends/ilang/parser frontends/ilang/parser.y + $(Q) mv frontends/ilang/parser.tab.c frontends/ilang/parser.tab.cc frontends/ilang/parser.tab.h: frontends/ilang/parser.tab.cc frontends/ilang/lexer.cc: frontends/ilang/lexer.l - flex -o frontends/ilang/lexer.cc frontends/ilang/lexer.l + $(P) flex -o frontends/ilang/lexer.cc frontends/ilang/lexer.l OBJS += frontends/ilang/parser.tab.o frontends/ilang/lexer.o OBJS += frontends/ilang/ilang_frontend.o diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc index 5586b4cc2..49eb320ec 100644 --- a/frontends/verilog/Makefile.inc +++ b/frontends/verilog/Makefile.inc @@ -5,13 +5,13 @@ GENFILES += frontends/verilog/parser.output GENFILES += frontends/verilog/lexer.cc frontends/verilog/parser.tab.cc: frontends/verilog/parser.y - bison -d -r all -b frontends/verilog/parser frontends/verilog/parser.y - mv frontends/verilog/parser.tab.c frontends/verilog/parser.tab.cc + $(P) bison -d -r all -b frontends/verilog/parser frontends/verilog/parser.y + $(Q) mv frontends/verilog/parser.tab.c frontends/verilog/parser.tab.cc frontends/verilog/parser.tab.h: frontends/verilog/parser.tab.cc frontends/verilog/lexer.cc: frontends/verilog/lexer.l - flex -o frontends/verilog/lexer.cc frontends/verilog/lexer.l + $(P) flex -o frontends/verilog/lexer.cc frontends/verilog/lexer.l OBJS += frontends/verilog/parser.tab.o OBJS += frontends/verilog/lexer.o diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 85d580ce8..c901da1c9 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 c68b13f6c..a76d1a079 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 f88390f73..cd19f10e7 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 -- cgit v1.2.3 From 38afbe62ef61bd9b1aa92575cad7ff1785ce5e0e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:53:11 +0200 Subject: Added percentage display to "make PRETTY=1" --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d57d02b28..a962c7e3a 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 -- cgit v1.2.3 From 34ea9e3f098925a7e107f2da265ff27b6b9985be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:55:55 +0200 Subject: Now "make PRETTY=1" is the default setting --- Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index a962c7e3a..e061b9c7a 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 -- cgit v1.2.3 From 45b4154b3799178a432d1f14dcaf51787b86f35d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 19:03:57 +0200 Subject: 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 e061b9c7a..e4e0287e7 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 c901da1c9..e54c018aa 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 -- cgit v1.2.3 From 10d2402e2f3cd49bd8c4e0cddb01c90c5615bb05 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 19:36:20 +0200 Subject: 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 949bf4327..63a0a84dd 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 0e8d08272..18ea528a0 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; -- cgit v1.2.3 From 9962384d3ed26ea0707f1ed8ebef91593d1a42a4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 19:36:43 +0200 Subject: 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 800fbf109..e2bf7004f 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); -- cgit v1.2.3 From 7a608437c65e9646ed229055d61b310e7d93e37e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 20:57:21 +0200 Subject: Updated ABC to hg id "b1e63d18768d" --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e4e0287e7..3919b3f1c 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 -- cgit v1.2.3 From 6aa792c864444324a1b140c2b63bd860f0cc3914 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 22:47:57 +0200 Subject: Replaced more old SigChunk programming patterns --- 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 028d1f37a..db49880ae 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 d0c250790..fc090cfe0 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 8f36f4090..a3ae9649e 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 a312b02ce..e3093e378 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 a4cad5add..b2e472bf3 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 8e894cafd..e548df361 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 3d848e823..e74f36abe 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -294,9 +294,9 @@ struct AST_INTERNAL::ProcessGenerator assert(init_lvalue.size() == init_rvalue.size()); int offset = 0; - for (size_t i = 0; i < init_lvalue.chunks().size(); i++) { - RTLIL::SigSpec lhs = init_lvalue.chunks()[i]; - RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue.chunks()[i].width); + for (auto &init_lvalue_c : init_lvalue.chunks()) { + RTLIL::SigSpec lhs = init_lvalue_c; + RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue_c.width); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); } @@ -398,10 +398,10 @@ struct AST_INTERNAL::ProcessGenerator assert(lvalue.size() == rvalue.size()); int offset = 0; - for (size_t i = 0; i < lvalue.chunks().size(); i++) { - RTLIL::SigSpec lhs = lvalue.chunks()[i]; - RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue.chunks()[i].width); - if (inSyncRule && lvalue.chunks()[i].wire && lvalue.chunks()[i].wire->get_bool_attribute("\\nosync")) + for (auto &lvalue_c : lvalue.chunks()) { + RTLIL::SigSpec lhs = lvalue_c; + RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue_c.width); + if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute("\\nosync")) rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size()); actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 4f4bc37a0..05b2bbc24 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 3a8ef44a0..7b1b798c8 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 8e509f360..f741e2a34 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 68eee46ea..a4b7e8492 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 ba27a3fc6..d25f88c0d 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 6b37b7bb1..0a1d584ca 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 fec0b407d..3ceb5da36 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 ba0aadc6b..02efabf72 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 a8aba903a..5982fd8e4 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 4c9b6bcd2..5976c2162 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; } } } -- cgit v1.2.3 From 01dbf12ac9227f7aac92b1fa7af056ad2a1f24e3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:12:14 +0200 Subject: Further improved "make" prettiness --- Makefile | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 3919b3f1c..c96cdeabb 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) -- cgit v1.2.3 From cd699254377b08729342026056f97d9d6bc1e2f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:17:06 +0200 Subject: Added "make clean-abc" --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index c96cdeabb..29c6113ff 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 -- cgit v1.2.3 From 7f1789ad1bb978132e8e09fee54ded81b370fcb3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:17:35 +0200 Subject: 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 f741e2a34..6bb395ec2 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(); -- cgit v1.2.3 From e4a0ab9bedcf357551c0faf548317e0998d5a4d1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:18:16 +0200 Subject: Added more stuff to the checklist --- CHECKLIST | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CHECKLIST b/CHECKLIST index c621b7156..7fcdd8e9e 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 -- cgit v1.2.3 From 6789e3002aadb78623b9205492d14bbafb3e39eb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 03:31:16 +0200 Subject: Removed Minisat dependency on zlib --- libs/ezsat/ezminisat.cc | 1 + libs/minisat/00_PATCH_mkLit_default_arg.patch | 20 ++++++++++++++ libs/minisat/00_PATCH_remove_zlib.patch | 38 +++++++++++++++++++++++++++ libs/minisat/00_UPDATE.sh | 17 ++++++++++++ libs/minisat/PATCH_mkLit_default_arg.patch | 20 -------------- libs/minisat/ParseUtils.h | 14 ++-------- libs/minisat/UPDATE.sh | 16 ----------- 7 files changed, 78 insertions(+), 48 deletions(-) create mode 100644 libs/minisat/00_PATCH_mkLit_default_arg.patch create mode 100644 libs/minisat/00_PATCH_remove_zlib.patch create mode 100644 libs/minisat/00_UPDATE.sh delete mode 100644 libs/minisat/PATCH_mkLit_default_arg.patch delete mode 100644 libs/minisat/UPDATE.sh diff --git a/libs/ezsat/ezminisat.cc b/libs/ezsat/ezminisat.cc index 3f43f3ece..dc4e5d283 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/00_PATCH_mkLit_default_arg.patch b/libs/minisat/00_PATCH_mkLit_default_arg.patch new file mode 100644 index 000000000..e21683f98 --- /dev/null +++ b/libs/minisat/00_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/00_PATCH_remove_zlib.patch b/libs/minisat/00_PATCH_remove_zlib.patch new file mode 100644 index 000000000..61a36f7e5 --- /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/00_UPDATE.sh b/libs/minisat/00_UPDATE.sh new file mode 100644 index 000000000..96a34ec93 --- /dev/null +++ b/libs/minisat/00_UPDATE.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +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} . +rm -rf minisat_upstream + +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 +sed -i -e '1 i #define __STDC_FORMAT_MACROS' *.cc + +patch -p0 < 00_PATCH_mkLit_default_arg.patch +patch -p0 < 00_PATCH_remove_zlib.patch + diff --git a/libs/minisat/PATCH_mkLit_default_arg.patch b/libs/minisat/PATCH_mkLit_default_arg.patch deleted file mode 100644 index e21683f98..000000000 --- a/libs/minisat/PATCH_mkLit_default_arg.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- 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/ParseUtils.h b/libs/minisat/ParseUtils.h index 1c9e7bf7b..04911c70a 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(); } diff --git a/libs/minisat/UPDATE.sh b/libs/minisat/UPDATE.sh deleted file mode 100644 index fa72ba213..000000000 --- a/libs/minisat/UPDATE.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -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} . -rm -rf minisat_upstream - -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 -sed -i -e '1 i #define __STDC_FORMAT_MACROS' *.cc - -patch -p0 < PATCH_mkLit_default_arg.patch - -- cgit v1.2.3 From 91bf0c90c86f5f857f440bec012b085d9f218ef0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:04:40 +0200 Subject: 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 ebbdc7c4c..0a96c0b23 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("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("\n"); - log("It is also possible to instruct Yosys to print the coverage counters to a file\n"); - log("using environment variables.\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(" 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) -- cgit v1.2.3 From 1488bc0c4f80b32cabd096232830b7fdfc400bbf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:16:03 +0200 Subject: Updated verific build/test instructions --- frontends/verific/build_amd64.txt | 20 +++++++++----------- frontends/verific/test_navre.ys | 4 ++-- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 49debe0f0..2f325e515 100644 --- a/frontends/verific/build_amd64.txt +++ b/frontends/verific/build_amd64.txt @@ -1,6 +1,6 @@ -Notes on buildin yosys with verific support on amd64 when you only have the -i386 eval version of Verific: +Notes on building yosys with verific support on amd64 when you +only have the i386 eval version of Verific: 1.) Use a Makefile.conf like the following one: @@ -13,21 +13,19 @@ ENABLE_ABC := 0 ENABLE_VERIFIC := 1 CXXFLAGS += -m32 LDFLAGS += -m32 +VERIFIC_DIR = /usr/local/src/verific_lib_eval --snap-- -2.) Install the neccessary multilib packages. +2.) Install the neccessary multilib packages Hint: On debian/ubuntu the multilib packages have names such as -libreadline-dev:amd64 or lib32readline6-dev, depending on the version -of the system you are working with. +libreadline-dev:amd64 or lib32readline6-dev, depending on the +exact version of debian/ubuntu you are working with. -Hint: On Ubuntu 14.04 there is a problem with the 32bit libz -package. A workaround is running the following command in the -yosys source directory: - ln -s /usr/include/x86_64-linux-gnu/zconf.h . +3.) Build and test - -3.) Run 'make' and 'make install' as usual. +make -j8 +./yosys frontends/verific/test_navre.ys diff --git a/frontends/verific/test_navre.ys b/frontends/verific/test_navre.ys index 6f63761ab..a56b725ac 100644 --- a/frontends/verific/test_navre.ys +++ b/frontends/verific/test_navre.ys @@ -1,11 +1,11 @@ -verific -vlog2k ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +verific -vlog2k ../yosys-bigsim/softusb_navre/rtl/softusb_navre.v verific -import softusb_navre memory softusb_navre flatten softusb_navre rename softusb_navre gate -read_verilog ../../../yosys-bigsim/softusb_navre/rtl/softusb_navre.v +read_verilog ../yosys-bigsim/softusb_navre/rtl/softusb_navre.v cd softusb_navre; proc; opt; memory; opt; cd .. rename softusb_navre gold -- cgit v1.2.3 From a8706b73a2c14c6b34e4fb7136866c0bc959acbb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:16:23 +0200 Subject: Added more stuff to checklist --- CHECKLIST | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHECKLIST b/CHECKLIST index 7fcdd8e9e..35de389be 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 -- cgit v1.2.3 From c4e4f79a2a2fd5530fa2677245f9361c7b04df70 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:22:37 +0200 Subject: 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 a4556fb1b..3c185e44b 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 18ea528a0..1658800dd 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 0a96c0b23..ac72ba53a 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) -- cgit v1.2.3 From 0520bfea892291a131134411d587034fcd36bf1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 12:49:51 +0200 Subject: 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 913855f48..0cc16ee67 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")))) -- cgit v1.2.3 From 50f22ff30c921c90f686879455117c7c2c9f96d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 13:01:45 +0200 Subject: 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 +- tests/simple/usb_phy_tests.v | 36 ++++++++++++++++++++++++++++++++++++ tests/simple/usb_phy_tetsts.v | 36 ------------------------------------ 16 files changed, 65 insertions(+), 65 deletions(-) create mode 100644 tests/simple/usb_phy_tests.v delete mode 100644 tests/simple/usb_phy_tetsts.v diff --git a/tests/simple/arraycells.v b/tests/simple/arraycells.v index ad5098000..704ca3fda 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 79ca041dd..2dba14bb0 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 39e573a73..24eb4462c 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 f8f564085..3aa596632 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 a3e8d70f8..7b4d616ea 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 3630b57c7..bed5528d4 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 ae63e8a16..9fed1bf3b 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 7439101c8..2f0fdb820 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 8d0134a67..23cb276f2 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 acfc1ca5d..9b1a99859 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 cde37c563..5d0c75fa6 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 3eb5e93df..8bba4a4b1 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 3a09cbc35..8dbc90c56 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 63912a2fa..b0178677b 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_tests.v b/tests/simple/usb_phy_tests.v new file mode 100644 index 000000000..bc45e71a5 --- /dev/null +++ b/tests/simple/usb_phy_tests.v @@ -0,0 +1,36 @@ + +// from usb_rx_phy +module usb_phy_test01(clk, rst, rx_en, fs_ce); + +input clk, rst; +input rx_en; +output reg fs_ce; +reg [1:0] dpll_next_state; +reg [1:0] dpll_state; + +always @(posedge clk) + dpll_state <= rst ? 0 : dpll_next_state; + +always @* + begin + fs_ce = 1'b0; + case(dpll_state) + 2'h0: + if(rx_en) dpll_next_state = 2'h0; + else dpll_next_state = 2'h1; + 2'h1:begin + fs_ce = 1'b1; + if(rx_en) dpll_next_state = 2'h3; + else dpll_next_state = 2'h2; + end + 2'h2: + if(rx_en) dpll_next_state = 2'h0; + else dpll_next_state = 2'h3; + 2'h3: + if(rx_en) dpll_next_state = 2'h0; + else dpll_next_state = 2'h0; + endcase + end + +endmodule + diff --git a/tests/simple/usb_phy_tetsts.v b/tests/simple/usb_phy_tetsts.v deleted file mode 100644 index 2375183d8..000000000 --- a/tests/simple/usb_phy_tetsts.v +++ /dev/null @@ -1,36 +0,0 @@ - -// from usb_rx_phy -module test01(clk, rst, rx_en, fs_ce); - -input clk, rst; -input rx_en; -output reg fs_ce; -reg [1:0] dpll_next_state; -reg [1:0] dpll_state; - -always @(posedge clk) - dpll_state <= rst ? 0 : dpll_next_state; - -always @* - begin - fs_ce = 1'b0; - case(dpll_state) - 2'h0: - if(rx_en) dpll_next_state = 2'h0; - else dpll_next_state = 2'h1; - 2'h1:begin - fs_ce = 1'b1; - if(rx_en) dpll_next_state = 2'h3; - else dpll_next_state = 2'h2; - end - 2'h2: - if(rx_en) dpll_next_state = 2'h0; - else dpll_next_state = 2'h3; - 2'h3: - if(rx_en) dpll_next_state = 2'h0; - else dpll_next_state = 2'h0; - endcase - end - -endmodule - -- cgit v1.2.3 From 309d64d46a7ca7390ccb27b06ecb78228c8b54f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 13:07:31 +0200 Subject: Fixed two memory leaks in ast simplify --- frontends/ast/simplify.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d86bfb3f0..6302260a5 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -895,7 +895,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_error("Expression in generate case at %s:%d is not constant!\n", filename.c_str(), linenum); } - if (RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool()) { + bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool(); + delete buf; + + if (is_selected) { selected_case = this_genblock; i = children.size(); break; @@ -1301,6 +1304,8 @@ skip_dynamic_range_lvalue_expansion:; log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); RTLIL::Const arg_value = buf->bitsAsConst(); + delete buf; + uint32_t result = 0; for (size_t i = 0; i < arg_value.bits.size(); i++) if (arg_value.bits.at(i) == RTLIL::State::S1) -- cgit v1.2.3 From 1834af5e5382de67860f5714746566123c4d6b53 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 13:15:46 +0200 Subject: Added "make vgtest" --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 29c6113ff..6dde27a9f 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 -- cgit v1.2.3 From c762050e7fc2c733210f8cd2b147e6084af0afe1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 14:23:10 +0200 Subject: 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 6bb395ec2..83524d796 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 a4b7e8492..59db099fb 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; -- cgit v1.2.3 From 5826670009e1018734de49aaf1554cb8a43d09d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 14:23:31 +0200 Subject: 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 9139749c0..096c60293 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 e3093e378..3c8e805b2 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 1dcc3003a..a22035edb 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 0a1d584ca..8ff068999 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)); -- cgit v1.2.3 From 2bec47a4045d23d46e7d300cbf80b2dce1a549a9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 25 Jul 2014 15:05:18 +0200 Subject: Use only module->addCell() and module->remove() to create and delete cells --- frontends/ast/genrtlil.cc | 73 +++++++++++---------------------------- frontends/ilang/parser.y | 5 +-- frontends/liberty/liberty.cc | 69 ++++++++----------------------------- 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 e74f36abe..c121a8694 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -44,17 +44,11 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi std::stringstream sstr; sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = type; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = result_width; - current_module->wires[wire->name] = wire; if (gen_attributes) for (auto &attr : that->attributes) { @@ -84,17 +78,11 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s std::stringstream sstr; sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = celltype; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = width; - current_module->wires[wire->name] = wire; if (that != NULL) for (auto &attr : that->attributes) { @@ -119,17 +107,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi std::stringstream sstr; sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = type; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = result_width; - current_module->wires[wire->name] = wire; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -160,17 +142,11 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - cell->name = sstr.str(); - cell->type = "$mux"; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", left.size()); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - wire->name = cell->name + "_Y"; - wire->width = left.size(); - current_module->wires[wire->name] = wire; for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) @@ -1183,17 +1159,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::stringstream sstr; sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = sstr.str(); - cell->type = "$memrd"; - current_module->cells[cell->name] = cell; - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(cell->name + "_DATA", current_module->memories[str]->width); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - wire->name = cell->name + "_DATA"; - wire->width = current_module->memories[str]->width; - current_module->wires[wire->name] = wire; int addr_bits = 1; while ((1 << addr_bits) < current_module->memories[str]->size) @@ -1220,11 +1190,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::stringstream sstr; sstr << "$memwr$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memwr"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = sstr.str(); - cell->type = "$memwr"; - current_module->cells[cell->name] = cell; int addr_bits = 1; while ((1 << addr_bits) < current_module->memories[str]->size) @@ -1260,11 +1227,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) std::stringstream sstr; sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); - RTLIL::Cell *cell = new RTLIL::Cell; + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$assert"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = sstr.str(); - cell->type = "$assert"; - current_module->cells[cell->name] = cell; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) @@ -1297,9 +1261,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_CELL: { int port_counter = 0, para_counter = 0; - RTLIL::Cell *cell = new RTLIL::Cell; + + if (current_module->count_id(str) != 0) + log_error("Re-definition of cell `%s' at %s:%d!\n", + str.c_str(), filename.c_str(), linenum); + + RTLIL::Cell *cell = current_module->addCell(str, ""); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - cell->name = str; + for (auto it = children.begin(); it != children.end(); it++) { AstNode *child = *it; if (child->type == AST_CELLTYPE) { @@ -1342,10 +1311,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) attr.first.c_str(), filename.c_str(), linenum); cell->attributes[attr.first] = attr.second->asAttrConst(); } - if (current_module->cells.count(cell->name) != 0) - log_error("Re-definition of cell `%s' at %s:%d!\n", - str.c_str(), filename.c_str(), linenum); - current_module->cells[str] = cell; } break; diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 3fe5199f3..82826a35a 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -182,11 +182,8 @@ cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { if (current_module->cells.count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); - current_cell = new RTLIL::Cell; - current_cell->type = $2; - current_cell->name = $3; + current_cell = current_module->addCell($3, $2); current_cell->attributes = attrbuf; - current_module->cells[$3] = current_cell; attrbuf.clear(); free($2); free($3); diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 3fe227bec..74524792b 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -54,48 +54,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_INV_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); cell->connections["\\A"] = A; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_XOR_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); cell->connections["\\A"] = A; cell->connections["\\B"] = B; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_AND_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); cell->connections["\\A"] = A; cell->connections["\\B"] = B; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_OR_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); cell->connections["\\A"] = A; cell->connections["\\B"] = B; cell->connections["\\Y"] = module->addWire(NEW_ID); - module->add(cell); return cell->connections["\\Y"]; } @@ -270,19 +258,14 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_INV_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); cell->connections["\\A"] = iq_sig; cell->connections["\\Y"] = iqn_sig; - module->add(cell); - cell = new RTLIL::Cell; - cell->name = NEW_ID; + cell = module->addCell(NEW_ID, ""); cell->connections["\\D"] = data_sig; cell->connections["\\Q"] = iq_sig; cell->connections["\\C"] = clk_sig; - module->add(cell); if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -352,12 +335,9 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = "$_INV_"; + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); cell->connections["\\A"] = iq_sig; cell->connections["\\Y"] = iqn_sig; - module->add(cell); if (clear_sig.size() == 1) { @@ -366,12 +346,9 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { - RTLIL::Cell *inv = new RTLIL::Cell; - inv->name = NEW_ID; - inv->type = "$_INV_"; + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); inv->connections["\\A"] = clear_sig; inv->connections["\\Y"] = module->addWire(NEW_ID); - module->add(inv); if (clear_polarity == true) clear_negative = inv->connections["\\Y"]; @@ -379,21 +356,15 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) clear_enable = inv->connections["\\Y"]; } - RTLIL::Cell *data_gate = new RTLIL::Cell; - data_gate->name = NEW_ID; - data_gate->type = "$_AND_"; + RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = clear_negative; data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(data_gate); - RTLIL::Cell *enable_gate = new RTLIL::Cell; - enable_gate->name = NEW_ID; - enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = clear_enable; enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(enable_gate); } if (preset_sig.size() == 1) @@ -403,12 +374,9 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { - RTLIL::Cell *inv = new RTLIL::Cell; - inv->name = NEW_ID; - inv->type = "$_INV_"; + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); inv->connections["\\A"] = preset_sig; inv->connections["\\Y"] = module->addWire(NEW_ID); - module->add(inv); if (preset_polarity == false) preset_positive = inv->connections["\\Y"]; @@ -416,30 +384,21 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) preset_enable = inv->connections["\\Y"]; } - RTLIL::Cell *data_gate = new RTLIL::Cell; - data_gate->name = NEW_ID; - data_gate->type = "$_OR_"; + RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); data_gate->connections["\\A"] = data_sig; data_gate->connections["\\B"] = preset_positive; data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(data_gate); - RTLIL::Cell *enable_gate = new RTLIL::Cell; - enable_gate->name = NEW_ID; - enable_gate->type = enable_polarity ? "$_OR_" : "$_AND_"; + RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); enable_gate->connections["\\A"] = enable_sig; enable_gate->connections["\\B"] = preset_enable; enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); - module->add(enable_gate); } - cell = new RTLIL::Cell; - cell->name = NEW_ID; - cell->type = stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N'); + cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); cell->connections["\\D"] = data_sig; cell->connections["\\Q"] = iq_sig; cell->connections["\\E"] = enable_sig; - module->add(cell); } struct LibertyFrontend : public Frontend { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 83524d796..17e4a2733 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 59db099fb..e1e4a54bc 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 d25f88c0d..980e69aa2 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 04977b369..e7feb1877 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 7fe95b0a9..79b7c3c30 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 68e8951ff..a470aed00 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 0dd328db3..f3b6c998d 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 dfd025a51..1b5ea1bc0 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 cee267629..78248eb6d 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 257301880..204f899a0 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 3ceb5da36..116b704e3 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 e605e6e51..b5f0520a4 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 dd2a32cad..63f6b14f8 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 bbd015833..97cda1443 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 02efabf72..00fa6031f 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 e2bf7004f..e1b6c598f 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 dfcd55126..750a9d417 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 0cc16ee67..073af3087 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 4215a7b54..6a35cb618 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 819a0e460..e3e9511fd 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 5982fd8e4..876adb0db 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 804c51fd3..5bb1ab948 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 c9363f4bf..29ce899ef 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 ba01bc322..79dec3b54 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 12384e2cc..aff664242 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 ede2fa88c..7e24e1f04 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 4bf73358b..c047e418a 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 4c3aec31d..e52c8fe52 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 51b8802c4..e41536707 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 09147383a..7b2484d84 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 034677d3b..8489e7fd9 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 8d7b21e0f..e8385844d 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; -- cgit v1.2.3 From 4755e14e7b9ba57ea21bec4c0d0b3ac6080307e4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 00:38:44 +0200 Subject: 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 17e4a2733..1a6e386ff 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 e1e4a54bc..fbd6e719d 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 204f899a0..be580ca04 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 e8385844d..94cb1e8dd 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); -- cgit v1.2.3 From f8a68b8f55ed61c6046e11b60587c840f0ba1879 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:23:43 +0200 Subject: Added "Checklist for adding internal cell types" --- CHECKLIST | 108 -------------------------------------------------- CHECKLISTS | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 108 deletions(-) delete mode 100644 CHECKLIST create mode 100644 CHECKLISTS diff --git a/CHECKLIST b/CHECKLIST deleted file mode 100644 index 35de389be..000000000 --- a/CHECKLIST +++ /dev/null @@ -1,108 +0,0 @@ - - -Checklist for creating Yosys releases -===================================== - - -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 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 - - if there are any odd things -> investigate - - 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 - 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+" - diff --git a/CHECKLISTS b/CHECKLISTS new file mode 100644 index 000000000..3f824fc28 --- /dev/null +++ b/CHECKLISTS @@ -0,0 +1,132 @@ + +This file contains checklists for various tasks. + + +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: + + 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 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 + - if there are any odd things -> investigate + - 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 + 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+" + + +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 + -- cgit v1.2.3 From 665759fceee4a0db3e776b7912e976eea2ff29a3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:55:58 +0200 Subject: Cosmetic fixes for "make abc" --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 6dde27a9f..da4d7fac9 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 -- cgit v1.2.3 From cc4f10883bcc5f0a3c1b4f0937e60be3c6a1b121 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 11:58:03 +0200 Subject: Renamed RTLIL::{Module,Cell}::connections to connections_ --- 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 fc090cfe0..8d80eccd0 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 096c60293..46edec9c0 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 a3ae9649e..13ab4dc62 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 3c8e805b2..0e329fc9e 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 b2e472bf3..8231f1d81 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 e548df361..a3784f115 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 a22035edb..d3b5d52db 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 c121a8694..c70b79a5b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -60,10 +60,10 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); - cell->connections["\\A"] = arg; + cell->connections_["\\A"] = arg; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = wire; + cell->connections_["\\Y"] = wire; return wire; } @@ -94,10 +94,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); - cell->connections["\\A"] = sig; + cell->connections_["\\A"] = sig; cell->parameters["\\Y_WIDTH"] = width; - cell->connections["\\Y"] = wire; + cell->connections_["\\Y"] = wire; sig = wire; } @@ -126,11 +126,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); - cell->connections["\\A"] = left; - cell->connections["\\B"] = right; + cell->connections_["\\A"] = left; + cell->connections_["\\B"] = right; cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections["\\Y"] = wire; + cell->connections_["\\Y"] = wire; return wire; } @@ -157,10 +157,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); - cell->connections["\\A"] = right; - cell->connections["\\B"] = left; - cell->connections["\\S"] = cond; - cell->connections["\\Y"] = wire; + cell->connections_["\\A"] = right; + cell->connections_["\\B"] = left; + cell->connections_["\\S"] = cond; + cell->connections_["\\Y"] = wire; return wire; } @@ -1169,9 +1169,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections["\\DATA"] = RTLIL::SigSpec(wire); + cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); + cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); + cell->connections_["\\DATA"] = RTLIL::SigSpec(wire); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1197,10 +1197,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); - cell->connections["\\EN"] = children[2]->genRTLIL(); + cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); + cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); + cell->connections_["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); + cell->connections_["\\EN"] = children[2]->genRTLIL(); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1237,8 +1237,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->connections["\\A"] = check; - cell->connections["\\EN"] = en; + cell->connections_["\\A"] = check; + cell->connections_["\\EN"] = en; } break; @@ -1248,11 +1248,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.size()); - current_module->connections.push_back(RTLIL::SigSig(left, right)); + current_module->connections_.push_back(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); - current_module->connections.push_back(RTLIL::SigSig(left, right)); + current_module->connections_.push_back(RTLIL::SigSig(left, right)); } } break; @@ -1297,9 +1297,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->connections[buf] = sig; + cell->connections_[buf] = sig; } else { - cell->connections[child->str] = sig; + cell->connections_[child->str] = sig; } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 82826a35a..bb42c5ec7 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -202,9 +202,9 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->connections.count($3) != 0) + if (current_cell->connections_.count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->connections[$3] = *$4; + current_cell->connections_[$3] = *$4; delete $4; free($3); } | @@ -395,7 +395,7 @@ conn_stmt: TOK_CONNECT sigspec sigspec EOL { if (attrbuf.size() != 0) rtlil_frontend_ilang_yyerror("dangling attribute"); - current_module->connections.push_back(RTLIL::SigSig(*$2, *$3)); + current_module->connect(*$2, *$3); delete $2; delete $3; }; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 74524792b..ec96fbdd4 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -55,36 +55,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections["\\A"] = A; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); - cell->connections["\\A"] = A; - cell->connections["\\B"] = B; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\B"] = B; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); - cell->connections["\\A"] = A; - cell->connections["\\B"] = B; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\B"] = B; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); - cell->connections["\\A"] = A; - cell->connections["\\B"] = B; - cell->connections["\\Y"] = module->addWire(NEW_ID); - return cell->connections["\\Y"]; + cell->connections_["\\A"] = A; + cell->connections_["\\B"] = B; + cell->connections_["\\Y"] = module->addWire(NEW_ID); + return cell->connections_["\\Y"]; } static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) @@ -240,18 +240,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clk_sig) { - clk_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clk_sig) { + clk_sig = it.second->connections_.at("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { - clear_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { + clear_sig = it.second->connections_.at("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { - preset_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { + preset_sig = it.second->connections_.at("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -259,13 +259,13 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections["\\A"] = iq_sig; - cell->connections["\\Y"] = iqn_sig; + cell->connections_["\\A"] = iq_sig; + cell->connections_["\\Y"] = iqn_sig; cell = module->addCell(NEW_ID, ""); - cell->connections["\\D"] = data_sig; - cell->connections["\\Q"] = iq_sig; - cell->connections["\\C"] = clk_sig; + cell->connections_["\\D"] = data_sig; + cell->connections_["\\Q"] = iq_sig; + cell->connections_["\\C"] = clk_sig; if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -273,18 +273,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections["\\R"] = clear_sig; + cell->connections_["\\R"] = clear_sig; } if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); - cell->connections["\\R"] = preset_sig; + cell->connections_["\\R"] = preset_sig; } if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections["\\S"] = preset_sig; - cell->connections["\\R"] = clear_sig; + cell->connections_["\\S"] = preset_sig; + cell->connections_["\\R"] = clear_sig; } log_assert(!cell->type.empty()); @@ -317,18 +317,18 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == enable_sig) { - enable_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == enable_sig) { + enable_sig = it.second->connections_.at("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == clear_sig) { - clear_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { + clear_sig = it.second->connections_.at("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections.at("\\Y") == preset_sig) { - preset_sig = it.second->connections.at("\\A"); + if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { + preset_sig = it.second->connections_.at("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -336,8 +336,8 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections["\\A"] = iq_sig; - cell->connections["\\Y"] = iqn_sig; + cell->connections_["\\A"] = iq_sig; + cell->connections_["\\Y"] = iqn_sig; if (clear_sig.size() == 1) { @@ -347,24 +347,24 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections["\\A"] = clear_sig; - inv->connections["\\Y"] = module->addWire(NEW_ID); + inv->connections_["\\A"] = clear_sig; + inv->connections_["\\Y"] = module->addWire(NEW_ID); if (clear_polarity == true) - clear_negative = inv->connections["\\Y"]; + clear_negative = inv->connections_["\\Y"]; if (clear_polarity != enable_polarity) - clear_enable = inv->connections["\\Y"]; + clear_enable = inv->connections_["\\Y"]; } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); - data_gate->connections["\\A"] = data_sig; - data_gate->connections["\\B"] = clear_negative; - data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->connections_["\\A"] = data_sig; + data_gate->connections_["\\B"] = clear_negative; + data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections["\\A"] = enable_sig; - enable_gate->connections["\\B"] = clear_enable; - enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->connections_["\\A"] = enable_sig; + enable_gate->connections_["\\B"] = clear_enable; + enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); } if (preset_sig.size() == 1) @@ -375,30 +375,30 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections["\\A"] = preset_sig; - inv->connections["\\Y"] = module->addWire(NEW_ID); + inv->connections_["\\A"] = preset_sig; + inv->connections_["\\Y"] = module->addWire(NEW_ID); if (preset_polarity == false) - preset_positive = inv->connections["\\Y"]; + preset_positive = inv->connections_["\\Y"]; if (preset_polarity != enable_polarity) - preset_enable = inv->connections["\\Y"]; + preset_enable = inv->connections_["\\Y"]; } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); - data_gate->connections["\\A"] = data_sig; - data_gate->connections["\\B"] = preset_positive; - data_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->connections_["\\A"] = data_sig; + data_gate->connections_["\\B"] = preset_positive; + data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections["\\A"] = enable_sig; - enable_gate->connections["\\B"] = preset_enable; - enable_gate->connections["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->connections_["\\A"] = enable_sig; + enable_gate->connections_["\\B"] = preset_enable; + enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); } cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); - cell->connections["\\D"] = data_sig; - cell->connections["\\Q"] = iq_sig; - cell->connections["\\E"] = enable_sig; + cell->connections_["\\D"] = data_sig; + cell->connections_["\\Q"] = iq_sig; + cell->connections_["\\E"] = enable_sig; } struct LibertyFrontend : public Frontend { @@ -559,7 +559,7 @@ struct LibertyFrontend : public Frontend { } RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); - module->connections.push_back(RTLIL::SigSig(wire, out_sig)); + module->connections_.push_back(RTLIL::SigSig(wire, out_sig)); } } diff --git a/kernel/consteval.h b/kernel/consteval.h index 7b1b798c8..5469fa80f 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 6c3da5dd0..efd97379c 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 1a6e386ff..4d0aadbb5 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 fbd6e719d..96bda7530 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 ea04cb409..ec4480c36 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 1a84194ee..ea95e06ee 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 3f8d553ad..f6c1528ee 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 980e69aa2..80828e153 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 e7feb1877..122f78454 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 acee4c46f..ce8ecc32d 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 dcd5fc96b..ea05026f3 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 6cb2a892c..87ed3d856 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 d5976dcb0..0028f7ead 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 49e79bd4d..40a2e48cb 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 123483a3a..5d991d038 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 6c4bb16c0..e1005a270 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 8ff068999..29b83a9aa 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 a470aed00..c8b3d0b0c 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 c65b6a5f8..497d0a2a7 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 2ba4c72b8..e59676599 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 f3b6c998d..431f086d2 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 1b5ea1bc0..b0e1c903b 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 78248eb6d..cf482d6df 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 efa61245a..3fde534da 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 ae9569ed7..a336d23f7 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 90f377e0d..4306c29eb 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 be580ca04..df5fd8e37 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 116b704e3..b4242f250 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 56915776e..63f7d0527 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 b5f0520a4..a626b5aff 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 63f6b14f8..919e24a4a 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 97cda1443..9c457ad5d 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 00fa6031f..30ab88146 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 e1b6c598f..2a5ec8bea 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 750a9d417..33e66e077 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 073af3087..7a7f02f6d 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 6a35cb618..4ece182f4 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 e3e9511fd..b3a37209b 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 145abfa43..ce3133601 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 876adb0db..9d2c897ee 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 5bb1ab948..2cde749a5 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 29ce899ef..22b724d53 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 79dec3b54..517e6713c 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 aff664242..9e151cdfc 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 4b6b1b719..cc041391b 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 7e24e1f04..01acf50df 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 c047e418a..ac0064f70 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 e52c8fe52..5dfcd63d1 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 e41536707..286ad8ac0 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 7b2484d84..ba9bf51d3 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 8489e7fd9..df7592cef 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 94cb1e8dd..ab95c003a 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()) { -- cgit v1.2.3 From e75e495c2bddb62634c6d50f90e09e0ff358faa5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 12:22:58 +0200 Subject: 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 4d0aadbb5..27063aeac 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 96bda7530..0b92405e8 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); }; -- cgit v1.2.3 From 3719281ed44aa9d8b2ac11eb936b750c4642be38 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 13:59:30 +0200 Subject: Automatically pack SigSpec on copy/assign --- kernel/rtlil.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++------------- kernel/rtlil.h | 3 +++ 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 27063aeac..2378e95c5 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; - - 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; + RTLIL::SigChunk *last = NULL; + int last_end_offset = 0; + + 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 0b92405e8..a2320873a 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); -- cgit v1.2.3 From b90f443338460f1f906fc8e342130ab428e343ad Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:08:20 +0200 Subject: Added "passed" message to make test targets --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index da4d7fac9..b87a7474e 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 -- cgit v1.2.3 From 027819c7e8ba3b1f9c7eb4864fa221a4f3b01092 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:08:43 +0200 Subject: 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 3b8a3e9e2..b1b205a22 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 -- cgit v1.2.3 From b03aec6e3212a387e3d255583476d472d16663f1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:31:47 +0200 Subject: 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 2378e95c5..ce4ecea6f 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 a2320873a..4f91b720d 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(); -- cgit v1.2.3 From 7ac9dc7f6eab40b3853583848933c4a8a94df9c9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:38:33 +0200 Subject: 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 ce4ecea6f..1638682c1 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 4f91b720d..1775975d5 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); -- cgit v1.2.3 From cd6574ecf652901573cbc6b89e1a59dd383ec496 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 15:57:27 +0200 Subject: 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 1638682c1..73f5d71f9 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 1775975d5..25d0a8309 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); -- cgit v1.2.3 From b7dda723022ad00c6c0089be888eab319953faa8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 14:32:50 +0200 Subject: Changed users of cell->connections_ to the new API (sed command) git grep -l 'connections_' | xargs sed -i -r -e ' s/(->|\.)connections_\["([^"]*)"\] = (.*);/\1set("\2", \3);/g; s/(->|\.)connections_\["([^"]*)"\]/\1get("\2")/g; s/(->|\.)connections_.at\("([^"]*)"\)/\1get("\2")/g; s/(->|\.)connections_.push_back/\1connect/g; s/(->|\.)connections_/\1connections()/g;' --- 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 8d80eccd0..cb40834b3 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 46edec9c0..0316f7ab8 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 13ab4dc62..fc2f4a7e4 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 0e329fc9e..6678f19d2 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 8231f1d81..8c08747c3 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 a3784f115..4bc8710e9 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 d3b5d52db..aa2f88fa4 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 c70b79a5b..861df3fde 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -60,10 +60,10 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); - cell->connections_["\\A"] = arg; + cell->set("\\A", arg); cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections_["\\Y"] = wire; + cell->set("\\Y", wire); return wire; } @@ -94,10 +94,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); - cell->connections_["\\A"] = sig; + cell->set("\\A", sig); cell->parameters["\\Y_WIDTH"] = width; - cell->connections_["\\Y"] = wire; + cell->set("\\Y", wire); sig = wire; } @@ -126,11 +126,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); - cell->connections_["\\A"] = left; - cell->connections_["\\B"] = right; + cell->set("\\A", left); + cell->set("\\B", right); cell->parameters["\\Y_WIDTH"] = result_width; - cell->connections_["\\Y"] = wire; + cell->set("\\Y", wire); return wire; } @@ -157,10 +157,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); - cell->connections_["\\A"] = right; - cell->connections_["\\B"] = left; - cell->connections_["\\S"] = cond; - cell->connections_["\\Y"] = wire; + cell->set("\\A", right); + cell->set("\\B", left); + cell->set("\\S", cond); + cell->set("\\Y", wire); return wire; } @@ -1169,9 +1169,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections_["\\DATA"] = RTLIL::SigSpec(wire); + cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->set("\\DATA", RTLIL::SigSpec(wire)); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1197,10 +1197,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->connections_["\\CLK"] = RTLIL::SigSpec(RTLIL::State::Sx, 1); - cell->connections_["\\ADDR"] = children[0]->genWidthRTLIL(addr_bits); - cell->connections_["\\DATA"] = children[1]->genWidthRTLIL(current_module->memories[str]->width); - cell->connections_["\\EN"] = children[2]->genRTLIL(); + cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->set("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width)); + cell->set("\\EN", children[2]->genRTLIL()); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1237,8 +1237,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->connections_["\\A"] = check; - cell->connections_["\\EN"] = en; + cell->set("\\A", check); + cell->set("\\EN", en); } break; @@ -1248,11 +1248,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_AUTOWIRE) { RTLIL::SigSpec right = children[1]->genRTLIL(); RTLIL::SigSpec left = children[0]->genWidthRTLIL(right.size()); - current_module->connections_.push_back(RTLIL::SigSig(left, right)); + current_module->connect(RTLIL::SigSig(left, right)); } else { RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genWidthRTLIL(left.size()); - current_module->connections_.push_back(RTLIL::SigSig(left, right)); + current_module->connect(RTLIL::SigSig(left, right)); } } break; @@ -1297,9 +1297,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->connections_[buf] = sig; + cell->connections()[buf] = sig; } else { - cell->connections_[child->str] = sig; + cell->connections()[child->str] = sig; } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index bb42c5ec7..a7ce4bc7a 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -202,9 +202,9 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->connections_.count($3) != 0) + if (current_cell->connections().count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->connections_[$3] = *$4; + current_cell->connections()[$3] = *$4; delete $4; free($3); } | diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index ec96fbdd4..d7068d468 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -55,36 +55,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections_["\\A"] = A; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); - cell->connections_["\\A"] = A; - cell->connections_["\\B"] = B; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\B", B); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); - cell->connections_["\\A"] = A; - cell->connections_["\\B"] = B; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\B", B); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); - cell->connections_["\\A"] = A; - cell->connections_["\\B"] = B; - cell->connections_["\\Y"] = module->addWire(NEW_ID); - return cell->connections_["\\Y"]; + cell->set("\\A", A); + cell->set("\\B", B); + cell->set("\\Y", module->addWire(NEW_ID)); + return cell->get("\\Y"); } static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) @@ -240,18 +240,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clk_sig) { - clk_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == clk_sig) { + clk_sig = it.second->get("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { - clear_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { + clear_sig = it.second->get("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { - preset_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { + preset_sig = it.second->get("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -259,13 +259,13 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections_["\\A"] = iq_sig; - cell->connections_["\\Y"] = iqn_sig; + cell->set("\\A", iq_sig); + cell->set("\\Y", iqn_sig); cell = module->addCell(NEW_ID, ""); - cell->connections_["\\D"] = data_sig; - cell->connections_["\\Q"] = iq_sig; - cell->connections_["\\C"] = clk_sig; + cell->set("\\D", data_sig); + cell->set("\\Q", iq_sig); + cell->set("\\C", clk_sig); if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -273,18 +273,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections_["\\R"] = clear_sig; + cell->set("\\R", clear_sig); } if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); - cell->connections_["\\R"] = preset_sig; + cell->set("\\R", preset_sig); } if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->connections_["\\S"] = preset_sig; - cell->connections_["\\R"] = clear_sig; + cell->set("\\S", preset_sig); + cell->set("\\R", clear_sig); } log_assert(!cell->type.empty()); @@ -317,18 +317,18 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells) { - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == enable_sig) { - enable_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == enable_sig) { + enable_sig = it.second->get("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == clear_sig) { - clear_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { + clear_sig = it.second->get("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->connections_.at("\\Y") == preset_sig) { - preset_sig = it.second->connections_.at("\\A"); + if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { + preset_sig = it.second->get("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -336,8 +336,8 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->connections_["\\A"] = iq_sig; - cell->connections_["\\Y"] = iqn_sig; + cell->set("\\A", iq_sig); + cell->set("\\Y", iqn_sig); if (clear_sig.size() == 1) { @@ -347,24 +347,24 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections_["\\A"] = clear_sig; - inv->connections_["\\Y"] = module->addWire(NEW_ID); + inv->set("\\A", clear_sig); + inv->set("\\Y", module->addWire(NEW_ID)); if (clear_polarity == true) - clear_negative = inv->connections_["\\Y"]; + clear_negative = inv->get("\\Y"); if (clear_polarity != enable_polarity) - clear_enable = inv->connections_["\\Y"]; + clear_enable = inv->get("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); - data_gate->connections_["\\A"] = data_sig; - data_gate->connections_["\\B"] = clear_negative; - data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->set("\\A", data_sig); + data_gate->set("\\B", clear_negative); + data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections_["\\A"] = enable_sig; - enable_gate->connections_["\\B"] = clear_enable; - enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->set("\\A", enable_sig); + enable_gate->set("\\B", clear_enable); + enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); } if (preset_sig.size() == 1) @@ -375,30 +375,30 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->connections_["\\A"] = preset_sig; - inv->connections_["\\Y"] = module->addWire(NEW_ID); + inv->set("\\A", preset_sig); + inv->set("\\Y", module->addWire(NEW_ID)); if (preset_polarity == false) - preset_positive = inv->connections_["\\Y"]; + preset_positive = inv->get("\\Y"); if (preset_polarity != enable_polarity) - preset_enable = inv->connections_["\\Y"]; + preset_enable = inv->get("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); - data_gate->connections_["\\A"] = data_sig; - data_gate->connections_["\\B"] = preset_positive; - data_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + data_gate->set("\\A", data_sig); + data_gate->set("\\B", preset_positive); + data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->connections_["\\A"] = enable_sig; - enable_gate->connections_["\\B"] = preset_enable; - enable_gate->connections_["\\Y"] = data_sig = module->addWire(NEW_ID); + enable_gate->set("\\A", enable_sig); + enable_gate->set("\\B", preset_enable); + enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); } cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); - cell->connections_["\\D"] = data_sig; - cell->connections_["\\Q"] = iq_sig; - cell->connections_["\\E"] = enable_sig; + cell->set("\\D", data_sig); + cell->set("\\Q", iq_sig); + cell->set("\\E", enable_sig); } struct LibertyFrontend : public Frontend { @@ -559,7 +559,7 @@ struct LibertyFrontend : public Frontend { } RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str()); - module->connections_.push_back(RTLIL::SigSig(wire, out_sig)); + module->connect(RTLIL::SigSig(wire, out_sig)); } } diff --git a/kernel/consteval.h b/kernel/consteval.h index 5469fa80f..4050d2dcf 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 efd97379c..a3983a2c1 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 73f5d71f9..9781fa32b 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 ec4480c36..6a288a8da 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 ea95e06ee..7035db73d 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 f6c1528ee..f67ffe1e8 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 80828e153..c53c44503 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 122f78454..e5bfb98b4 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 ce8ecc32d..9004bf75b 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 ea05026f3..ffe7a5efa 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 87ed3d856..d7560ab1a 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 0028f7ead..1a780466a 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 40a2e48cb..3380a935a 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 5d991d038..e0f1a6d69 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 e1005a270..e26106103 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 29b83a9aa..441268ee9 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 c8b3d0b0c..94f8365bc 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 497d0a2a7..28575e7b4 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 e59676599..be851afa6 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 431f086d2..126c4866a 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 b0e1c903b..3ded8aca7 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 cf482d6df..a22441b4a 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 3fde534da..e82b53631 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 a336d23f7..8f0e5d621 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 4306c29eb..5937373fa 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 df5fd8e37..d72ebb127 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 b4242f250..a8caf883f 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 63f7d0527..0513aa3d2 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 a626b5aff..5b180db62 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 919e24a4a..8b4eb0d0e 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 9c457ad5d..f08350768 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 30ab88146..fa5d8f189 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 2a5ec8bea..7f420ec34 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 33e66e077..8487152ff 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 7a7f02f6d..8c281b342 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 4ece182f4..8c09f5414 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 b3a37209b..8412f929f 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 ce3133601..114f2567e 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 9d2c897ee..2e2d4701f 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 2cde749a5..2ff755aef 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 22b724d53..58dcf915f 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 517e6713c..da9345855 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 9e151cdfc..34355122a 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 cc041391b..71eba2f7f 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 01acf50df..13ef695e7 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 ac0064f70..1dce39f69 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 5dfcd63d1..0d8f6ab0d 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 286ad8ac0..2e5dd7dca 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 ba9bf51d3..199fd6029 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 df7592cef..f8851400f 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 ab95c003a..4c8f92505 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()) { -- cgit v1.2.3 From f8fdc47d3361c1a3445a9357ca26cfe75907d6b0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 15:57:57 +0200 Subject: Manual fixes for new cell connections API --- 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 0316f7ab8..bbfbc0f90 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 aa2f88fa4..6bef90e38 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 861df3fde..dba301f46 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1297,9 +1297,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->connections()[buf] = sig; + cell->set(buf, sig); } else { - cell->connections()[child->str] = sig; + cell->set(child->str, sig); } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index a7ce4bc7a..952dd6a3a 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -204,7 +204,7 @@ cell_body: cell_body TOK_CONNECT TOK_ID sigspec EOL { if (current_cell->connections().count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->connections()[$3] = *$4; + current_cell->set($3, *$4); delete $4; free($3); } | diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9781fa32b..ceb2b0f52 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 c53c44503..4d9a6c136 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 e5bfb98b4..45a9ac765 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 9004bf75b..1401193fd 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 ffe7a5efa..99a28d4a0 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 d7560ab1a..9faeffafa 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 1a780466a..35ce0a110 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 441268ee9..d63d98972 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 94f8365bc..8b7e04062 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 126c4866a..ed80d7c31 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 3ded8aca7..e89bba893 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 e82b53631..1441378a0 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 5937373fa..76b667b86 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 d72ebb127..ef4a9f16d 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 0513aa3d2..999c969b5 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 8b4eb0d0e..df1a2697a 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 fa5d8f189..e279c0209 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 7f420ec34..e52882316 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 8c281b342..1f8648c45 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 8412f929f..4f733a373 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 2e2d4701f..cfd2eb7a7 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 2ff755aef..30e7b748b 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 58dcf915f..a84faf792 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 da9345855..d5336ca01 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 34355122a..96aa10ba3 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 13ef695e7..0ee5af186 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 1dce39f69..eabc56bd2 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 0d8f6ab0d..6439302cd 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 2e5dd7dca..309777876 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 199fd6029..114d28e25 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 f8851400f..355c07c84 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 4c8f92505..9dcd6a45b 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); } -- cgit v1.2.3 From 97a59851a6c411ccb06162d4b31725bf89262378 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 16:11:28 +0200 Subject: Added RTLIL::Cell::has(portname) --- 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 4bc8710e9..653a9f22d 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 6bef90e38..d9186c043 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 952dd6a3a..09437a0aa 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -202,7 +202,7 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->connections().count($3) != 0) + if (current_cell->has($3)) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); current_cell->set($3, *$4); delete $4; diff --git a/kernel/consteval.h b/kernel/consteval.h index 4050d2dcf..3a5c5347c 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 ceb2b0f52..059357d21 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 25d0a8309..73d3727ce 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 1401193fd..f94ea639b 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 be851afa6..55fe336f4 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 ed80d7c31..186ea2fd4 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 e89bba893..ff3ac7608 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 e52882316..000a9ec2b 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 a84faf792..198f83477 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) -- cgit v1.2.3 From 3f4e3ca8ad480c2e73e2072ada77078ffd95e08f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 16:14:02 +0200 Subject: 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 bbfbc0f90..f731e17e2 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 653a9f22d..077368771 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 000a9ec2b..672186006 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 198f83477..9ce3b43d3 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 6439302cd..b8c349f5c 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); -- cgit v1.2.3 From 267c61564047f8768c29040f898633d9444a5404 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 17:21:40 +0200 Subject: 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 3c185e44b..97910aa98 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,26 +117,37 @@ 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); + 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()); } + Frontend::current_script_file = backup_script_file; + if (filename != "-") fclose(f); diff --git a/kernel/register.cc b/kernel/register.cc index e7ad7ef05..59667ac97 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 fd073cbe7..73875e968 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(); -- cgit v1.2.3 From b21ebe1859df2f9bd1791de34633a85918651c13 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 17:22:18 +0200 Subject: 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 b87a7474e..6809ffd01 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 000000000..67e1beb23 --- /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 000000000..8d11c21d3 --- /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 -- cgit v1.2.3 From d49dec1f861ce11a87c48cc21c8edc1755802a5f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 17:43:41 +0200 Subject: 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 000000000..397b4a762 --- /dev/null +++ b/tests/various/.gitignore @@ -0,0 +1 @@ +*.log -- cgit v1.2.3 From 946ddff9cef3ea0b4dad8664319fb13074133775 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 20:12:50 +0200 Subject: Changed a lot of code to the new RTLIL::Wire constructors --- frontends/ast/genrtlil.cc | 22 ++++++++---------- frontends/ilang/parser.y | 5 ++-- 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 | 38 +++++++++++++++---------------- passes/fsm/fsm_extract.cc | 5 +--- passes/fsm/fsm_map.cc | 20 ++++------------ passes/hierarchy/hierarchy.cc | 5 +--- passes/hierarchy/submod.cc | 39 +++++++++++++++++-------------- 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, 150 insertions(+), 218 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index dba301f46..3bc9b06ee 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -290,16 +290,16 @@ struct AST_INTERNAL::ProcessGenerator if (chunk.wire == NULL) continue; - RTLIL::Wire *wire = new RTLIL::Wire; - wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); + std::string wire_name; do { - wire->name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, + wire_name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, chunk.wire->name.c_str(), chunk.width+chunk.offset-1, chunk.offset);; if (chunk.wire->name.find('$') != std::string::npos) - wire->name += stringf("$%d", RTLIL::autoidx++); - } while (current_module->wires.count(wire->name) > 0); - wire->width = chunk.width; - current_module->wires[wire->name] = wire; + wire_name += stringf("$%d", RTLIL::autoidx++); + } while (current_module->wires.count(wire_name) > 0); + + RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); + wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); chunk.wire = wire; chunk.offset = 0; @@ -792,15 +792,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) range_right = tmp; } - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - wire->name = str; - wire->width = range_left - range_right + 1; wire->start_offset = range_right; wire->port_id = port_id; wire->port_input = is_input; wire->port_output = is_output; - current_module->wires[wire->name] = wire; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) @@ -873,14 +870,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigChunk chunk; if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires.count(str) == 0) { - RTLIL::Wire *wire = new RTLIL::Wire; + RTLIL::Wire *wire = current_module->addWire(str); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); wire->name = str; if (flag_autowire) log("Warning: Identifier `%s' is implicitly declared at %s:%d.\n", str.c_str(), filename.c_str(), linenum); else log_error("Identifier `%s' is implicitly declared at %s:%d and `default_nettype is set to none.\n", str.c_str(), filename.c_str(), linenum); - current_module->wires[str] = wire; } else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) { if (id2ast->children[0]->type != AST_CONSTANT) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 09437a0aa..20490e0d2 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -121,14 +121,13 @@ autoidx_stmt: wire_stmt: TOK_WIRE { - current_wire = new RTLIL::Wire; + current_wire = current_module->addWire("$__ilang_frontend_tmp__"); current_wire->attributes = attrbuf; attrbuf.clear(); } wire_options TOK_ID EOL { if (current_module->wires.count($4) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); - current_wire->name = $4; - current_module->wires[$4] = current_wire; + current_module->rename(current_wire, $4); free($4); }; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 059357d21..930e8a719 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 73d3727ce..f43e7b670 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 4d9a6c136..41cfe88f6 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 45a9ac765..e86afa1b7 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 f94ea639b..7e9ba97ec 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 79b7c3c30..df5a3d4b9 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 35ce0a110..0b95fe024 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 28575e7b4..6bffba622 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; - - 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; + std::string new_wire_name = wire->name; if (format.size() > 0) - new_wire->name += format.substr(0, 1); + new_wire_name += format.substr(0, 1); if (width > 1) { - new_wire->name += stringf("%d", offset+width-1); + new_wire_name += stringf("%d", offset+width-1); if (format.size() > 2) - new_wire->name += format.substr(2, 1); + new_wire_name += format.substr(2, 1); else - new_wire->name += ":"; + new_wire_name += ":"; } - new_wire->name += stringf("%d", offset); + new_wire_name += stringf("%d", offset); if (format.size() > 1) - new_wire->name += format.substr(1, 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); + 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; 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 ff3ac7608..51a4a75e7 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 a22441b4a..7ab159540 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 76b667b86..8c09d2eaa 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 ef4a9f16d..e39f96ca8 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; - - 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; + new_wire_port_input = true, new_wire_port_output = true; + + 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 999c969b5..b63b3aec6 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 5b180db62..32c7e63a0 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 e279c0209..63d03b205 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 30e7b748b..67113a682 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 96aa10ba3..0c5989b10 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(); -- cgit v1.2.3 From d68c993ed2ea384db4d6af5161b3b36096828499 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 21:16:05 +0200 Subject: 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 930e8a719..240bbc6be 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 f43e7b670..cbb612473 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 519dce452..721d5c987 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 8b7e04062..61de44066 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 9ce3b43d3..21af63a36 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 b8c349f5c..92bcafc00 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 114d28e25..ab3bb3ed0 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 9dcd6a45b..bee1df406 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); -- cgit v1.2.3 From d7916a49aff3c47b7c1ce07abe3b6e3d5714079b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 26 Jul 2014 21:34:19 +0200 Subject: New message for completion of build --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6809ffd01..462861c8a 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) -- cgit v1.2.3 From f9946232adf887e5aa4a48c64f88eaa17e424009 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 01:49:51 +0200 Subject: Refactoring: Renamed RTLIL::Module::wires to wires_ --- 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 db49880ae..06b2c2a93 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 cb40834b3..7ae9965d5 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 f731e17e2..f1e95ee15 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 fc2f4a7e4..e99d094f7 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 6678f19d2..c0b7dab9a 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 8c08747c3..4e8c321bb 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 077368771..ef31e06a9 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 d9186c043..5e98a4c54 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 3bc9b06ee..064aec93f 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -296,7 +296,7 @@ struct AST_INTERNAL::ProcessGenerator chunk.wire->name.c_str(), chunk.width+chunk.offset-1, chunk.offset);; if (chunk.wire->name.find('$') != std::string::npos) wire_name += stringf("$%d", RTLIL::autoidx++); - } while (current_module->wires.count(wire_name) > 0); + } while (current_module->wires_.count(wire_name) > 0); RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); wire->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); @@ -779,7 +779,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // create an RTLIL::Wire for an AST_WIRE node case AST_WIRE: { - if (current_module->wires.count(str) != 0) + if (current_module->wires_.count(str) != 0) log_error("Re-definition of signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); if (!range_valid) @@ -869,7 +869,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Wire *wire = NULL; RTLIL::SigChunk chunk; - if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires.count(str) == 0) { + if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) { RTLIL::Wire *wire = current_module->addWire(str); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); wire->name = str; @@ -886,7 +886,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) goto use_const_chunk; } else if (!id2ast || (id2ast->type != AST_WIRE && id2ast->type != AST_AUTOWIRE && - id2ast->type != AST_MEMORY) || current_module->wires.count(str) == 0) + id2ast->type != AST_MEMORY) || current_module->wires_.count(str) == 0) log_error("Identifier `%s' doesn't map to any signal at %s:%d!\n", str.c_str(), filename.c_str(), linenum); @@ -894,7 +894,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Identifier `%s' does map to an unexpanded memory at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - wire = current_module->wires[str]; + wire = current_module->wires_[str]; chunk.wire = wire; chunk.width = wire->width; chunk.offset = 0; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index d7068d468..c476de87a 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -45,11 +45,11 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1; std::string id = RTLIL::escape_id(std::string(expr, id_len)); - if (!module->wires.count(id)) + if (!module->wires_.count(id)) log_error("Can't resolve wire name %s.\n", RTLIL::id2cstr(id)); expr += id_len; - return module->wires.at(id); + return module->wires_.at(id); } static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) @@ -527,7 +527,7 @@ struct LibertyFrontend : public Frontend { if (flag_lib && dir->value == "internal") continue; - RTLIL::Wire *wire = module->wires.at(RTLIL::escape_id(node->args.at(0))); + RTLIL::Wire *wire = module->wires_.at(RTLIL::escape_id(node->args.at(0))); if (dir && dir->value == "inout") { wire->port_input = true; diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 769145838..d3c848f46 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 97910aa98..3fbb96580 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 a3983a2c1..a90d739eb 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 240bbc6be..0cfcf018c 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 cbb612473..1d040975b 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 f67ffe1e8..9eacfbcb5 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 cf8a4add8..0cd1da808 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 41cfe88f6..184f143a1 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 e86afa1b7..773bbe5d2 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 7e9ba97ec..e97bf8fc1 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 df5a3d4b9..460dd9663 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 721d5c987..e163e7243 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 3380a935a..7e2b2fc9f 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 e0f1a6d69..0cabdc06b 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 8d98df719..0b4f2a8a2 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 e26106103..82dc1d999 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 d63d98972..1feb90afb 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 61de44066..691d972cf 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 6bffba622..accb178ba 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 834770071..fabf1a73f 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 55fe336f4..cb420f90a 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 51a4a75e7..85ff4af2a 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 8c09d2eaa..a266c3445 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 e39f96ca8..774aabae1 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 32c7e63a0..4f1666533 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 df1a2697a..35a28d17d 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 63d03b205..9542e10df 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 672186006..290d4ffd9 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 8487152ff..16dedef58 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 8c09f5414..b26e8b37e 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 4f733a373..c91f037d4 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 114f2567e..565d86a72 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 6949b76db..d4ff2a86c 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 21af63a36..c30e6e0c8 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 d5336ca01..5d23318ce 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 0c5989b10..248f934c5 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 71eba2f7f..90c671165 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 92bcafc00..813e0e3e1 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 ab3bb3ed0..6f7427f03 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 bee1df406..03aac6693 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); -- cgit v1.2.3 From 4c4b6021562c598c4510831bd547edaa97d14dac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 01:51:45 +0200 Subject: Refactoring: Renamed RTLIL::Module::cells to cells_ --- 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 7ae9965d5..936dea023 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 f1e95ee15..ef0f0dd8c 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 e99d094f7..d23e99e7e 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 c0b7dab9a..be4e2777c 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 4e8c321bb..a463f5ece 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 ef31e06a9..c58e4bec5 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 5e98a4c54..098e29f92 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 c476de87a..0107b974a 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -239,7 +239,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) { rerun_invert_rollback = false; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (it.second->type == "$_INV_" && it.second->get("\\Y") == clk_sig) { clk_sig = it.second->get("\\A"); clk_polarity = !clk_polarity; @@ -316,7 +316,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) { rerun_invert_rollback = false; - for (auto &it : module->cells) { + for (auto &it : module->cells_) { if (it.second->type == "$_INV_" && it.second->get("\\Y") == enable_sig) { enable_sig = it.second->get("\\A"); enable_polarity = !enable_polarity; diff --git a/kernel/consteval.h b/kernel/consteval.h index 3a5c5347c..1727d91cf 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 3fbb96580..edf23cd20 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 a90d739eb..09f815b83 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 0cfcf018c..f307be43e 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 1d040975b..f8d2892f8 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 9eacfbcb5..a57907435 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 0cd1da808..c724ce375 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 184f143a1..7ba9424e8 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 e97bf8fc1..49aa7c98d 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 99a28d4a0..6494ea6f6 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 9faeffafa..cc8147c53 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 460dd9663..2c2c370dd 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 e163e7243..c8b8160f1 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 0b95fe024..a1c12f1ee 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 7e2b2fc9f..c95043417 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 0cabdc06b..306b7a5b1 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 0b4f2a8a2..ea5221f6d 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 82dc1d999..e7779415d 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 1feb90afb..18af8dfce 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 691d972cf..dcd2f819f 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 accb178ba..0998a1622 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 fabf1a73f..153226ab5 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 cb420f90a..e1528f31d 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 186ea2fd4..40ec55c11 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 cc328ce34..129e7f9a6 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 85ff4af2a..64b01064a 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 f2d0c1a81..4526939ce 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 7ab159540..f6ef12a7a 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 1441378a0..165b09747 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 b02287962..1b2eeb237 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 a266c3445..550ec39f0 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 774aabae1..374102756 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 a8caf883f..d5995ee0e 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 b63b3aec6..bb8b052dc 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 4f1666533..4bb0c8ccd 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 35a28d17d..b25cf73a7 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 f08350768..48b83f5fa 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 9542e10df..4cc5fc89a 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 290d4ffd9..39e2254e0 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 16dedef58..1d4916b56 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 1f8648c45..d7de72353 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 b26e8b37e..14b734d7d 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 c91f037d4..304ba9f83 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 565d86a72..63d04d351 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 d4ff2a86c..454233267 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 c30e6e0c8..24b812bb2 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 5d23318ce..f8d5cf6c4 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 90c671165..3e1c72224 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 0ee5af186..facacf196 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 eabc56bd2..01284656d 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 813e0e3e1..b66a11b85 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 355c07c84..8c7f64230 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 03aac6693..86d9e73ae 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; -- cgit v1.2.3 From c91570bde32d59679ea8b72ed041ef8f6bb0d51a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 02:00:04 +0200 Subject: 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 f8d2892f8..f235b1de5 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); -- cgit v1.2.3 From 7f3dc86ecd00a9ed5f5b7f09e02a6fe584259f79 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 02:11:57 +0200 Subject: 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 f235b1de5..97d01617a 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_; } -- cgit v1.2.3 From ddc5b4184836e795e143fc00786b4b87a6e69bc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 09:20:59 +0200 Subject: 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 97d01617a..91c9a1baa 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; } -- cgit v1.2.3 From 1c8fdaeef86d6e33668e325556380bfa67ec0a6f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:13:22 +0200 Subject: 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 f307be43e..5fdcb025a 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 91c9a1baa..be2822706 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++; } }; -- cgit v1.2.3 From d088854b47f5f77c6a62be2ba4b895164938d7a2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:41:06 +0200 Subject: 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 be2822706..2fbfe8049 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; + } }; }; -- cgit v1.2.3 From 10e5791c5e5660cb784503d36439ee90d61eb06b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:18:00 +0200 Subject: Refactoring: Renamed RTLIL::Design::modules to modules_ --- 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 06b2c2a93..3bb0f9d66 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 936dea023..2b783e734 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 ef0f0dd8c..4af121005 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 d23e99e7e..5eff4598a 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 be4e2777c..d45e94a09 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 a463f5ece..2f94e290d 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 c58e4bec5..283448c3b 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 098e29f92..f7f0ecaf4 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 3f704bea4..170416869 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -931,7 +931,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str = (*it)->str.substr(1); if (defer) (*it)->str = "$abstract" + (*it)->str; - if (design->modules.count((*it)->str)) { + if (design->modules_.count((*it)->str)) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -939,7 +939,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - design->modules[(*it)->str] = process_module(*it, defer); + design->modules_[(*it)->str] = process_module(*it, defer); } } @@ -1036,10 +1036,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapmodules.count(modname) == 0) { + if (design->modules_.count(modname) == 0) { new_ast->str = modname; - design->modules[modname] = process_module(new_ast, false); - design->modules[modname]->check(); + design->modules_[modname] = process_module(new_ast, false); + design->modules_[modname]->check(); } else { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); } diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 0107b974a..d5f172f03 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -476,7 +476,7 @@ struct LibertyFrontend : public Frontend { std::string cell_name = RTLIL::escape_id(cell->args.at(0)); - if (design->modules.count(cell_name)) { + if (design->modules_.count(cell_name)) { if (flag_ignore_redef) continue; log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); @@ -564,7 +564,7 @@ struct LibertyFrontend : public Frontend { } module->fixup_ports(); - design->modules[module->name] = module; + design->modules_[module->name] = module; cell_count++; skip_cell:; } diff --git a/kernel/celltypes.h b/kernel/celltypes.h index d3c848f46..20d68d559 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 edf23cd20..7a1c7ed16 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 5fdcb025a..5709875ec 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 2fbfe8049..7249f0cad 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 a57907435..4d1452c97 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 c724ce375..8dc72c750 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 7ba9424e8..03fc9f937 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 773bbe5d2..4bcbc0131 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 49aa7c98d..62995a49d 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 6494ea6f6..3e13fd4d4 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 cc8147c53..5125ff5e2 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 4b1a8db81..fc801f61f 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 2c2c370dd..67b4d939f 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 7b8889d60..bd1ee68f2 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 c8b8160f1..3a6008721 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 a1c12f1ee..e09c00123 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 c95043417..1fa1b4c9c 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 306b7a5b1..85c52277c 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 ea5221f6d..029c0ec79 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 e7779415d..c72e64b80 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 18af8dfce..7ab1daf00 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 dcd2f819f..5fce2d6cb 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 0998a1622..6b1dbe13c 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 153226ab5..fabc80ec0 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 e1528f31d..a619cf57d 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 40ec55c11..f107366d6 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 129e7f9a6..f84f372ac 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 64b01064a..99352b10a 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 4526939ce..45d68a906 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 f6ef12a7a..8b9ad6be7 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 165b09747..9d9156ae3 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 1b2eeb237..40fed130e 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 550ec39f0..8aec25eba 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 374102756..d32b5e1d3 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 d5995ee0e..d2803ae78 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 bb8b052dc..9a1e96796 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 4bb0c8ccd..53394b19a 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 b25cf73a7..e61661a20 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 48b83f5fa..d2b9c0eeb 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 4cc5fc89a..c219bc047 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 39e2254e0..bfd0161bf 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 1d4916b56..82cc78bed 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 d7de72353..b2b7cc8b9 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 14b734d7d..b01778b5e 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 304ba9f83..45130229f 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 63d04d351..e84394770 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 682515c5e..678d620be 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 cfd2eb7a7..7bd909a68 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 5976c2162..3607905f5 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 67113a682..bcbee6cfc 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 d5fbef0d2..e7e4bbc54 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 454233267..8a2dd929b 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 24b812bb2..f2b89b000 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 f8d5cf6c4..ad304c723 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 248f934c5..0f00e71a6 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 3e1c72224..dce312065 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 facacf196..671a631dd 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 01284656d..ffe241182 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 b66a11b85..8587f53b0 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 309777876..a3261dccd 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 6f7427f03..10627cd12 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 8c7f64230..6def10081 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 86d9e73ae..32e18e08b 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(); -- cgit v1.2.3 From 0bd8fafbd2f36f59327289e52abf962c166dab8b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:40:31 +0200 Subject: Added RTLIL::Design::modules() --- kernel/rtlil.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7249f0cad..6eb52cf2d 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(); -- cgit v1.2.3 From 675cb93da9e67f5c2fe8a3760de5893176ea906d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 11:03:56 +0200 Subject: 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 5709875ec..db85f9e3d 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 6eb52cf2d..7c69ff64c 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); -- cgit v1.2.3 From 49f72421d5ec499da5da713466e058aae2a67436 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 10:41:42 +0200 Subject: 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 9a1e96796..85249142e 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 82cc78bed..73baaf900 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 e84394770..676469fe2 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 678d620be..e4c526632 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 7bd909a68..dc310bde0 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 3607905f5..99498505f 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 bcbee6cfc..fb49182c2 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 e7e4bbc54..9e5f413a2 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 6def10081..b327ba832 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 32e18e08b..bcae44091 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); } -- cgit v1.2.3 From 6b34215efde97fe4f1e6ecffb398455f609a9a49 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 11:56:35 +0200 Subject: Fixed ilang parser for new RTLIL API --- frontends/ilang/parser.y | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 20490e0d2..a594adfb5 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -87,12 +87,12 @@ design: module: TOK_MODULE TOK_ID EOL { - if (current_design->modules.count($2) != 0) + if (current_design->modules_.count($2) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); current_module = new RTLIL::Module; current_module->name = $2; current_module->attributes = attrbuf; - current_design->modules[$2] = current_module; + current_design->modules_[$2] = current_module; attrbuf.clear(); free($2); } module_body TOK_END { @@ -125,7 +125,7 @@ wire_stmt: current_wire->attributes = attrbuf; attrbuf.clear(); } wire_options TOK_ID EOL { - if (current_module->wires.count($4) != 0) + if (current_module->wires_.count($4) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); current_module->rename(current_wire, $4); free($4); @@ -179,7 +179,7 @@ memory_options: cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { - if (current_module->cells.count($3) != 0) + if (current_module->cells_.count($3) != 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); current_cell = current_module->addCell($3, $2); current_cell->attributes = attrbuf; @@ -357,21 +357,21 @@ sigspec: delete $1; } | TOK_ID { - if (current_module->wires.count($1) == 0) + if (current_module->wires_.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1]); + $$ = new RTLIL::SigSpec(current_module->wires_[$1]); free($1); } | TOK_ID '[' TOK_INT ']' { - if (current_module->wires.count($1) == 0) + if (current_module->wires_.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], $3); + $$ = new RTLIL::SigSpec(current_module->wires_[$1], $3); free($1); } | TOK_ID '[' TOK_INT ':' TOK_INT ']' { - if (current_module->wires.count($1) == 0) + if (current_module->wires_.count($1) == 0) rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); - $$ = new RTLIL::SigSpec(current_module->wires[$1], $5, $3 - $5 + 1); + $$ = new RTLIL::SigSpec(current_module->wires_[$1], $5, $3 - $5 + 1); free($1); } | '{' sigspec_list '}' { -- cgit v1.2.3 From 7661ded8ddf85e8cd80ccce0bec211d9bf46e56b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 12:00:28 +0200 Subject: Fixed verific bindings for new RTLIL api --- frontends/verific/Makefile.inc | 10 ++--- frontends/verific/verific.cc | 87 ++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 55 deletions(-) diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index eca23e58c..13f242c4b 100644 --- a/frontends/verific/Makefile.inc +++ b/frontends/verific/Makefile.inc @@ -6,11 +6,11 @@ ifeq ($(ENABLE_VERIFIC),1) EXTRA_TARGETS += share/verific share/verific: - rm -rf share/verific.new - mkdir -p share/verific.new - cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs share/verific.new/vhdl_vdbs_1993 - cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008 share/verific.new/vhdl_vdbs_2008 - mv share/verific.new share/verific + $(P) rm -rf share/verific.new + $(Q) mkdir -p share/verific.new + $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs share/verific.new/vhdl_vdbs_1993 + $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008 share/verific.new/vhdl_vdbs_2008 + $(Q) mv share/verific.new share/verific endif diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c973988bb..aee38703b 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -481,7 +481,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator() ? std::string("$verific$") + nl->Owner()->Name() : RTLIL::escape_id(nl->Owner()->Name()); - if (design->modules.count(module_name)) { + if (design->modules_.count(module_name)) { if (!nl->IsOperator()) log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); return; @@ -489,7 +489,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = module_name; - design->modules[module->name] = module; + design->modules_[module->name] = module; log("Importing module %s.\n", RTLIL::id2cstr(module->name)); @@ -511,10 +511,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(port->Name()); + RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(port->Name())); import_attributes(wire->attributes, port); - module->add(wire); wire->port_id = nl->IndexOf(port) + 1; @@ -528,9 +526,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setport_input) - module->connections.push_back(RTLIL::SigSig(net_map.at(net), wire)); + module->connect(net_map.at(net), wire); else - module->connections.push_back(RTLIL::SigSig(wire, net_map.at(net))); + module->connect(wire, net_map.at(net)); } } @@ -538,12 +536,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(portbus->Name()); - wire->width = portbus->Size(); + RTLIL::Wire *wire = module->addWire(RTLIL::escape_id(portbus->Name()), portbus->Size()); wire->start_offset = std::min(portbus->LeftIndex(), portbus->RightIndex()); import_attributes(wire->attributes, portbus); - module->add(wire); if (portbus->GetDir() == DIR_INOUT || portbus->GetDir() == DIR_IN) wire->port_input = true; @@ -557,9 +552,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setport_input) - module->connections.push_back(RTLIL::SigSig(net_map.at(net), bit)); + module->connect(net_map.at(net), bit); else - module->connections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + module->connect(bit, net_map.at(net)); } if (i == portbus->RightIndex()) break; @@ -607,12 +602,11 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(net->Name()); - while (module->count_id(wire->name)) - wire->name += "_"; + std::string wire_name = RTLIL::escape_id(net->Name()); + while (module->count_id(wire_name)) + wire_name += "_"; + RTLIL::Wire *wire = module->addWire(wire_name); import_attributes(wire->attributes, net); - module->add(wire); net_map[net] = wire; } @@ -632,14 +626,12 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - RTLIL::Wire *wire = new RTLIL::Wire; - wire->name = RTLIL::escape_id(netbus->Name()); - wire->width = netbus->Size(); + std::string wire_name = RTLIL::escape_id(netbus->Name()); + while (module->count_id(wire_name)) + wire_name += "_"; + RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size()); wire->start_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); - while (module->count_id(wire->name)) - wire->name += "_"; import_attributes(wire->attributes, netbus); - module->add(wire); for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { if (netbus->ElementAtIndex(i)) { @@ -648,7 +640,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setconnections.push_back(RTLIL::SigSig(bit, net_map.at(net))); + module->connect(bit, net_map.at(net)); } if (i == netbus->RightIndex()) break; @@ -665,22 +657,22 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName(), inst->View()->Owner()->Name()); if (inst->Type() == PRIM_PWR) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S1)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::S1); continue; } if (inst->Type() == PRIM_GND) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::S0)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::S0); continue; } if (inst->Type() == PRIM_X) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sx)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::Sx); continue; } if (inst->Type() == PRIM_Z) { - module->connections.push_back(RTLIL::SigSig(net_map.at(inst->GetOutput()), RTLIL::State::Sz)); + module->connect(net_map.at(inst->GetOutput()), RTLIL::State::Sz); continue; } @@ -693,19 +685,16 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(inst->Name()); - cell->type = "$memrd"; + RTLIL::Cell *cell = module->addCell(RTLIL::escape_id(inst->Name()), "$memrd"); cell->parameters["\\MEMID"] = memory->name; cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\TRANSPARENT"] = false; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->connections["\\CLK"] = RTLIL::State::S0; - cell->connections["\\ADDR"] = addr; - cell->connections["\\DATA"] = data; - module->add(cell); + cell->set("\\CLK", RTLIL::State::S0); + cell->set("\\ADDR", addr); + cell->set("\\DATA", data); continue; } @@ -718,24 +707,21 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = RTLIL::escape_id(inst->Name()); - cell->type = "$memwr"; + RTLIL::Cell *cell = module->addCell(RTLIL::escape_id(inst->Name()), "$memwr"); cell->parameters["\\MEMID"] = memory->name; cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\PRIORITY"] = 0; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->connections["\\EN"] = RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data)); - cell->connections["\\CLK"] = RTLIL::State::S0; - cell->connections["\\ADDR"] = addr; - cell->connections["\\DATA"] = data; - module->add(cell); + cell->set("\\EN", RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data))); + cell->set("\\CLK", RTLIL::State::S0); + cell->set("\\ADDR", addr); + cell->set("\\DATA", data); if (inst->Type() == OPER_CLOCKED_WRITE_PORT) { cell->parameters["\\CLK_ENABLE"] = true; - cell->connections["\\CLK"] = net_map.at(inst->GetClock()); + cell->set("\\CLK", net_map.at(inst->GetClock())); } continue; } @@ -755,10 +741,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setView()); - RTLIL::Cell *cell = new RTLIL::Cell; - cell->name = RTLIL::escape_id(inst->Name()); - cell->type = inst->IsOperator() ? std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()); - module->add(cell); + RTLIL::Cell *cell = module->addCell(RTLIL::escape_id(inst->Name()), inst->IsOperator() ? + std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name())); FOREACH_PORTREF_OF_INST(inst, mi2, pr) { // log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name()); @@ -769,13 +753,16 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->IndexOf(pr->GetPort()) - std::min(pr->GetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } - RTLIL::SigSpec &conn = cell->connections[RTLIL::escape_id(port_name)]; + RTLIL::SigSpec conn; + if (cell->has(RTLIL::escape_id(port_name))) + conn = cell->get(RTLIL::escape_id(port_name)); while (SIZE(conn) <= port_offset) { if (pr->GetPort()->GetDir() != DIR_IN) conn.append(module->addWire(NEW_ID, port_offset - SIZE(conn))); conn.append(RTLIL::State::Sz); } conn.replace(port_offset, net_map.at(pr->GetNet())); + cell->set(RTLIL::escape_id(port_name), conn); } } } -- cgit v1.2.3 From d878fcbdc76f4b612ba8578213f73f27585fc792 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 12:04:12 +0200 Subject: 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 7a1c7ed16..380315e7c 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 63a0a84dd..b8a47e1cf 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 1658800dd..abfb810f7 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 f84f372ac..f6f9faa9b 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(); } -- cgit v1.2.3 From dbb3556e3f1e82a6b69d5e8714a0266c1d461c7c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 13:19:05 +0200 Subject: 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 c219bc047..21bda6e4e 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 bfd0161bf..9a21bdcaf 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); -- cgit v1.2.3 From cbc3a46a9717f0f6e90b20b29c9003c3720a5aa0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 14:47:23 +0200 Subject: Added RTLIL::SigSpecConstIterator --- kernel/rtlil.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7c69ff64c..4341e0676 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()); -- cgit v1.2.3 From 4be645860bf83de75cdd00fbe615f3fe05221d54 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 14:47:48 +0200 Subject: 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 db85f9e3d..9f9bd7e03 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_)); + + width_ = 0; + for (auto &chunk : chunks_) + if (chunk.wire != NULL) { + new_chunks.push_back(chunk); + width_ += chunk.width; + } + + chunks_.swap(new_chunks); + } + else + { + cover("kernel.rtlil.sigspec.remove_const.unpacked"); - std::vector new_bits; - new_bits.reserve(width_); + std::vector new_bits; + new_bits.reserve(width_); - for (auto &bit : bits_) - if (bit.wire != NULL) - new_bits.push_back(bit); + for (auto &bit : bits_) + if (bit.wire != NULL) + new_bits.push_back(bit); - bits_.swap(new_bits); - width_ = bits_.size(); + bits_.swap(new_bits); + width_ = bits_.size(); + } check(); } -- cgit v1.2.3 From d07a871d35401b6b8628dd3f1df3b91149e827d5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 14:50:25 +0200 Subject: 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 000000000..7e978c1e2 --- /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 9a21bdcaf..7578f1927 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); } -- cgit v1.2.3 From 77a1462f2d6602d5c46a2a15ca534550ec5bb9a4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 15:13:29 +0200 Subject: 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 21bda6e4e..76a905b2c 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); -- cgit v1.2.3 From ddd31a0b66259a458f7bfb3475f53c30aa859bc8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 15:14:02 +0200 Subject: 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 abfb810f7..ca1e7c67c 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 -- cgit v1.2.3 From 0c86d6106c3ff4cd7628b1206281eb6080f8bf51 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 15:38:02 +0200 Subject: 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 7035db73d..52e4aa0fb 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 76a905b2c..6c20bddbb 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) -- cgit v1.2.3 From 5da343b7de8c4fd45695af68aaba3d5091d8e670 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 16:19:24 +0200 Subject: 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 7e978c1e2..4226e270e 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 bcae44091..3595b7b53 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) - { - if (module->cells_.count(cell_name) == 0) - continue; - - RTLIL::Cell *cell = module->cells_[cell_name]; + TopoSort cells; + std::map> cell_to_inbit; + std::map> outbit_to_cell; + for (auto cell : module->cells()) + { 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"); -- cgit v1.2.3 From c4bdba78cb88df6628d975aad7a92c8cebc5d95f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 21:12:09 +0200 Subject: Added proper Design->addModule interface --- frontends/ast/ast.cc | 1 + 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 170416869..d38cb5e3f 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1051,6 +1051,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapname = name; cloneInto(new_mod); new_mod->ast = ast->clone(); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9f9bd7e03..aec0a045f 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 4341e0676..cd00b43d8 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(); -- cgit v1.2.3 From 8b0f50792c404d70ae91e623f80c4e7f06d39429 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 27 Jul 2014 21:13:23 +0200 Subject: 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 3595b7b53..79e70a59c 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 1c60d794f..3f7fc258d 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 ad8b3ef61..ba39adb31 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 -- cgit v1.2.3 From c469be883b80137c9d3d79287b72d05aaaa17128 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 09:15:40 +0200 Subject: 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 3f7fc258d..3965b04ca 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 ba39adb31..61528c2b4 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 -- cgit v1.2.3 From ee65dea738fefbf44b91a2ac10f9a93b35115af6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 10:10:08 +0200 Subject: Fixed signdness detection of expressions with bit- and part-selects --- frontends/ast/genrtlil.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 064aec93f..95e15903b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -599,6 +599,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun delete right_at_zero_ast; } else this_width = range->range_left - range->range_right + 1; + sign_hint = false; } else width_hint = std::max(width_hint, this_width); if (!id_ast->is_signed) -- cgit v1.2.3 From f99495a895eda0b1de6c1d7e8e1d5b1074316b34 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 10:52:30 +0200 Subject: 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 aec0a045f..610ab6a83 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) -- cgit v1.2.3 From d86a25f145012ccb6b2048af3aae22f13b97b505 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 10:52:58 +0200 Subject: 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 610ab6a83..753c40090 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 cd00b43d8..331ea3770 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); -- cgit v1.2.3 From 7bd2d1064f2eceddc3c93c121c4154a2f594a040 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 11:08:55 +0200 Subject: Using log_assert() instead of assert() --- 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 2b783e734..d167c3f4e 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 4af121005..f721fdc99 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 5eff4598a..49f719a4a 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 d45e94a09..87a3d6cb3 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 2f94e290d..9faed77c9 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 283448c3b..ab5316ec3 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 f7f0ecaf4..fe2c2b247 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 d38cb5e3f..cec199b63 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -820,7 +820,7 @@ RTLIL::Const AstNode::realAsConst(int width) // create a new AstModule from an AST_MODULE AST node static AstModule* process_module(AstNode *ast, bool defer) { - assert(ast->type == AST_MODULE); + log_assert(ast->type == AST_MODULE); if (defer) log("Storing AST representation for module `%s'.\n", ast->str.c_str()); @@ -925,7 +925,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_icells = icells; flag_autowire = autowire; - assert(current_ast->type == AST_DESIGN); + log_assert(current_ast->type == AST_DESIGN); for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { if (flag_icells && (*it)->str.substr(0, 2) == "\\$") (*it)->str = (*it)->str.substr(1); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 95e15903b..25881d639 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -32,7 +32,6 @@ #include #include -#include #include using namespace AST; @@ -137,7 +136,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi // helper function for creating RTLIL code for multiplexers static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - assert(cond.size() == 1); + log_assert(cond.size() == 1); std::stringstream sstr; sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); @@ -267,7 +266,7 @@ struct AST_INTERNAL::ProcessGenerator sync->type = RTLIL::SyncType::STi; proc->syncs.push_back(sync); - assert(init_lvalue.size() == init_rvalue.size()); + log_assert(init_lvalue.size() == init_rvalue.size()); int offset = 0; for (auto &init_lvalue_c : init_lvalue.chunks()) { @@ -316,7 +315,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: for (auto child : ast->children) if (child != ast->children[0]) { - assert(child->type == AST_COND); + log_assert(child->type == AST_COND); collect_lvalues(reg, child, type_eq, type_le, false); } break; @@ -341,7 +340,7 @@ struct AST_INTERNAL::ProcessGenerator break; default: - assert(0); + log_abort(); } if (run_sort_and_unify) @@ -371,7 +370,7 @@ struct AST_INTERNAL::ProcessGenerator init_rvalue.append(lvalue.extract(initSyncSignals, &rvalue)); lvalue.remove2(initSyncSignals, &rvalue); } - assert(lvalue.size() == rvalue.size()); + log_assert(lvalue.size() == rvalue.size()); int offset = 0; for (auto &lvalue_c : lvalue.chunks()) { @@ -445,7 +444,7 @@ struct AST_INTERNAL::ProcessGenerator { if (child == ast->children[0]) continue; - assert(child->type == AST_COND); + log_assert(child->type == AST_COND); subst_lvalue_from = backup_subst_lvalue_from; subst_lvalue_to = backup_subst_lvalue_to; @@ -815,9 +814,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Re-definition of memory `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - assert(children.size() >= 2); - assert(children[0]->type == AST_RANGE); - assert(children[1]->type == AST_RANGE); + log_assert(children.size() >= 2); + log_assert(children[0]->type == AST_RANGE); + log_assert(children[1]->type == AST_RANGE); if (!children[0]->range_valid || !children[1]->range_valid) log_error("Memory `%s' with non-constant width or size at %s:%d!\n", @@ -902,7 +901,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) use_const_chunk: if (children.size() != 0) { - assert(children[0]->type == AST_RANGE); + log_assert(children[0]->type == AST_RANGE); if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); @@ -1300,7 +1299,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } continue; } - assert(0); + log_abort(); } for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 6302260a5..2a55adeff 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -57,7 +57,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (stage == 0) { - assert(type == AST_MODULE); + log_assert(type == AST_MODULE); while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { } @@ -73,7 +73,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { AstNode *mem = it.first; uint32_t memflags = it.second; - assert((memflags & ~0x00ffff00) == 0); + log_assert((memflags & ~0x00ffff00) == 0); if (mem->get_bool_attribute("\\nomem2reg")) continue; @@ -480,7 +480,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // dumpAst(NULL, "> "); log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum); } - assert(children[1]->type == AST_IDENTIFIER); + log_assert(children[1]->type == AST_IDENTIFIER); newNode = children[1]->clone(); const char *second_part = children[1]->str.c_str(); if (second_part[0] == '\\') @@ -506,7 +506,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, range_valid = false; range_left = -1; range_right = 0; - assert(children.size() >= 1); + log_assert(children.size() >= 1); if (children[0]->type == AST_CONSTANT) { range_valid = true; range_left = children[0]->integer; @@ -963,8 +963,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::vector children_list; for (auto child : children) { - assert(child->type == AST_ARGUMENT); - assert(child->children.size() == 1); + log_assert(child->type == AST_ARGUMENT); + log_assert(child->children.size() == 1); children_list.push_back(child->children[0]); child->children.clear(); delete child; @@ -1019,7 +1019,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, op_type = AST_POS; if (str == "not") op_type = AST_POS, invert_results = true; - assert(op_type != AST_NONE); + log_assert(op_type != AST_NONE); AstNode *node = children_list[1]; if (op_type != AST_POS) @@ -1423,13 +1423,13 @@ skip_dynamic_range_lvalue_expansion:; if (current_block == NULL) { - assert(type == AST_FCALL); + log_assert(type == AST_FCALL); AstNode *wire = NULL; for (auto child : decl->children) if (child->type == AST_WIRE && child->str == str) wire = child->clone(); - assert(wire != NULL); + log_assert(wire != NULL); wire->str = prefix + str; wire->port_id = 0; @@ -1714,7 +1714,7 @@ skip_dynamic_range_lvalue_expansion:; } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) { RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint); RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint); - assert(a.bits.size() == b.bits.size()); + log_assert(a.bits.size() == b.bits.size()); for (size_t i = 0; i < a.bits.size(); i++) if (a.bits[i] != b.bits[i]) a.bits[i] = RTLIL::State::Sx; @@ -1761,7 +1761,7 @@ apply_newNode: // fprintf(stderr, "----\n"); // dumpAst(stderr, "- "); // newNode->dumpAst(stderr, "+ "); - assert(newNode != NULL); + log_assert(newNode != NULL); newNode->filename = filename; newNode->linenum = linenum; newNode->cloneInto(this); @@ -1937,7 +1937,7 @@ void AstNode::mem2reg_as_needed_pass1(std::map> uint32_t backup_flags = flags; flags |= children_flags; - assert((flags & ~0x000000ff) == 0); + log_assert((flags & ~0x000000ff) == 0); for (auto child : children) if (ignore_children_counter > 0) @@ -1986,11 +1986,11 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * mod->children.push_back(wire_data); while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } - assert(block != NULL); + log_assert(block != NULL); size_t assign_idx = 0; while (assign_idx < block->children.size() && block->children[assign_idx] != this) assign_idx++; - assert(assign_idx < block->children.size()); + log_assert(assign_idx < block->children.size()); AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; @@ -2091,7 +2091,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * size_t assign_idx = 0; while (assign_idx < block->children.size() && !block->children[assign_idx]->contains(this)) assign_idx++; - assert(assign_idx < block->children.size()); + log_assert(assign_idx < block->children.size()); block->children.insert(block->children.begin()+assign_idx, case_node); block->children.insert(block->children.begin()+assign_idx, assign_addr); } @@ -2113,7 +2113,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * children.push_back(bit_part_sel); } - assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0); + log_assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0); auto children_list = children; for (size_t i = 0; i < children_list.size(); i++) @@ -2123,7 +2123,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * // calulate memory dimensions void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) { - assert(type == AST_MEMORY); + log_assert(type == AST_MEMORY); mem_width = children[0]->range_left - children[0]->range_right + 1; mem_size = children[1]->range_left - children[1]->range_right; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index aee38703b..80170394e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -22,7 +22,6 @@ #include "kernel/log.h" #include #include -#include #include #include #include diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 8491a6b47..446f5e50c 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -36,7 +36,6 @@ #include "verilog_frontend.h" #include "kernel/log.h" -#include #include #include @@ -47,7 +46,7 @@ static int my_decimal_div_by_two(std::vector &digits) { int carry = 0; for (size_t i = 0; i < digits.size(); i++) { - assert(digits[i] < 10); + log_assert(digits[i] < 10); digits[i] += carry * 10; carry = digits[i] % 2; digits[i] /= 2; diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 873ae3d51..67b2ffa7c 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -37,7 +37,6 @@ #include #include #include -#include static std::list output_code; static std::list input_buffer; @@ -65,7 +64,7 @@ static char next_char() if (input_buffer.empty()) return 0; - assert(input_buffer_charp <= input_buffer.front().size()); + log_assert(input_buffer_charp <= input_buffer.front().size()); if (input_buffer_charp == input_buffer.front().size()) { input_buffer_charp = 0; input_buffer.pop_front(); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 437fc3ec0..cbc594e86 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -33,7 +33,6 @@ #include "libs/sha1/sha1.h" #include #include -#include using namespace VERILOG_FRONTEND; diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 4392ed444..63dc85acc 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -22,7 +22,6 @@ #include "kernel/log.h" #include #include -#include #include #include #include diff --git a/kernel/bitpattern.h b/kernel/bitpattern.h index 05b2bbc24..91f54593f 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 749589f20..b413760d1 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 20d68d559..43c23add3 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 1727d91cf..e5cae1022 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 380315e7c..a55fbbed5 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 b8a47e1cf..8036b2360 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 ca1e7c67c..3152fc5af 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 59667ac97..da3569831 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 753c40090..783286182 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 331ea3770..d78a6df22 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 6a288a8da..27a29cb57 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 52e4aa0fb..79a9fb238 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 03fc9f937..d2be7dcf1 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 1fa1b4c9c..8c039e3e9 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 85c52277c..bbfa396ba 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 7ab1daf00..a2dd8051b 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 f107366d6..2da4794eb 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 99352b10a..6da468321 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 8aec25eba..c869ec729 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 d32b5e1d3..84c6b9161 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 d2803ae78..40c68abc1 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 85249142e..325056170 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 53394b19a..49291656c 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 d2b9c0eeb..cdf7db04b 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 6c20bddbb..4182c6f5d 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 7578f1927..254fe5bb4 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 73baaf900..de12542dc 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 b2b7cc8b9..8aadd1f23 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 45130229f..ad6e1a746 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 dc310bde0..91cafe3be 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 99498505f..c72840c02 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 fb49182c2..e7661245e 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 9e5f413a2..61844d5eb 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 dce312065..430628e46 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 8587f53b0..9c5fa7f71 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 b327ba832..5c3e4c68f 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 79e70a59c..5a69baca5 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 += "_"; -- cgit v1.2.3 From 3c45277ee0f5822181c6058f679de632f834e7d2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 12:12:13 +0200 Subject: Added wire->upto flag for signals such as "wire [0:7] x;" --- 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 87a3d6cb3..c055c1334 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 25881d639..8ee46eb85 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -786,10 +786,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Signal `%s' with non-constant width at %s:%d!\n", str.c_str(), filename.c_str(), linenum); + bool wire_upto = false; if (range_left < range_right && (range_left != -1 || range_right != 0)) { int tmp = range_left; range_left = range_right; range_right = tmp; + wire_upto = true; } RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); @@ -798,6 +800,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) wire->port_id = port_id; wire->port_input = is_input; wire->port_output = is_output; + wire->upto = wire_upto; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index c40b81af8..f3bdeb1a4 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -51,6 +51,7 @@ "wire" { return TOK_WIRE; } "memory" { return TOK_MEMORY; } "width" { return TOK_WIDTH; } +"upto" { return TOK_UPTO; } "offset" { return TOK_OFFSET; } "size" { return TOK_SIZE; } "input" { return TOK_INPUT; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index a594adfb5..38d3054b2 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -54,7 +54,7 @@ using namespace ILANG_FRONTEND; %token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC %token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_INIT %token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET -%token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED +%token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED TOK_UPTO %type sigspec sigspec_list %type sync_type @@ -135,6 +135,9 @@ wire_options: wire_options TOK_WIDTH TOK_INT { current_wire->width = $3; } | + wire_options TOK_UPTO { + current_wire->upto = true; + } | wire_options TOK_OFFSET TOK_INT { current_wire->start_offset = $3; } | diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 783286182..b562e2afb 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 d78a6df22..097af9d28 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 }; -- cgit v1.2.3 From 27a872d1e7041be4894bc643a420587ff5894125 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 14:25:03 +0200 Subject: Added support for "upto" wires to Verilog front- and back-end --- 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 fe2c2b247..5826aea87 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 cec199b63..5b3214f5c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -181,6 +181,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2) is_signed = false; is_string = false; range_valid = false; + range_swapped = false; port_id = 0; range_left = -1; range_right = 0; @@ -276,7 +277,7 @@ void AstNode::dumpAst(FILE *f, std::string indent) if (port_id > 0) fprintf(f, " port=%d", port_id); if (range_valid || range_left != -1 || range_right != 0) - fprintf(f, " range=[%d:%d]%s", range_left, range_right, range_valid ? "" : "!"); + fprintf(f, " %srange=[%d:%d]%s", range_swapped ? "swapped_" : "", range_left, range_right, range_valid ? "" : "!"); if (integer != 0) fprintf(f, " int=%u", (int)integer); if (realvalue != 0) @@ -620,6 +621,8 @@ bool AstNode::operator==(const AstNode &other) const return false; if (range_valid != other.range_valid) return false; + if (range_swapped != other.range_swapped) + return false; if (port_id != other.port_id) return false; if (range_left != other.range_left) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8253a2052..6c15c03ab 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -151,7 +151,7 @@ namespace AST // node content - most of it is unused in most node types std::string str; std::vector bits; - bool is_input, is_output, is_reg, is_signed, is_string, range_valid; + bool is_input, is_output, is_reg, is_signed, is_string, range_valid, range_swapped; int port_id, range_left, range_right; uint32_t integer; double realvalue; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 8ee46eb85..5545fc169 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -786,13 +786,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_error("Signal `%s' with non-constant width at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - bool wire_upto = false; - if (range_left < range_right && (range_left != -1 || range_right != 0)) { - int tmp = range_left; - range_left = range_right; - range_right = tmp; - wire_upto = true; - } + log_assert(range_left >= range_right || (range_left == -1 && range_right == 0)); RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -800,7 +794,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) wire->port_id = port_id; wire->port_input = is_input; wire->port_output = is_output; - wire->upto = wire_upto; + wire->upto = range_swapped; for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) @@ -918,17 +912,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, - fake_ast->children[0]->genRTLIL(), fake_ast->children[1]->genRTLIL()); + fake_ast->children[0]->genRTLIL(), !wire->upto ? fake_ast->children[1]->genRTLIL() : + current_module->Sub(NEW_ID, RTLIL::SigSpec(wire->width - width), fake_ast->children[1]->genRTLIL())); delete left_at_zero_ast; delete right_at_zero_ast; delete fake_ast; return sig; } else { - chunk.offset = children[0]->range_right - id2ast->range_right; - chunk.width = children[0]->range_left - children[0]->range_right + 1; if (children[0]->range_left > id2ast->range_left || id2ast->range_right > children[0]->range_right) log_error("Range select out of bounds on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); + chunk.width = children[0]->range_left - children[0]->range_right + 1; + chunk.offset = children[0]->range_right - id2ast->range_right; + if (wire->upto) + chunk.offset = wire->width - (chunk.offset + chunk.width); } } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2a55adeff..7aa6d24c3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -504,6 +504,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_RANGE) { bool old_range_valid = range_valid; range_valid = false; + range_swapped = false; range_left = -1; range_right = 0; log_assert(children.size() >= 1); @@ -525,6 +526,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int tmp = range_right; range_right = range_left; range_left = tmp; + range_swapped = true; } } @@ -535,6 +537,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (!range_valid) did_something = true; range_valid = true; + range_swapped = children[0]->range_swapped; range_left = children[0]->range_left; range_right = children[0]->range_right; } @@ -542,6 +545,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (!range_valid) did_something = true; range_valid = true; + range_swapped = false; range_left = 0; range_right = 0; } diff --git a/tests/simple/partsel.v b/tests/simple/partsel.v index 9b1a99859..7461358ad 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 -- cgit v1.2.3 From 0598bc8708d942a0e533ddeba6a4f7b5effe7f39 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 15:19:34 +0200 Subject: Fixed width detection for part selects --- frontends/ast/genrtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 5545fc169..9e1866832 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -599,8 +599,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun } else this_width = range->range_left - range->range_right + 1; sign_hint = false; - } else - width_hint = std::max(width_hint, this_width); + } + width_hint = std::max(width_hint, this_width); if (!id_ast->is_signed) sign_hint = false; break; -- cgit v1.2.3 From 55521c085ae1ec735d3cffb80a9880b3cb3e8bca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 15:31:19 +0200 Subject: Fixed RTLIL code generator for part select of parameter --- frontends/ast/genrtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9e1866832..ca61cb39b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -912,7 +912,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, - fake_ast->children[0]->genRTLIL(), !wire->upto ? fake_ast->children[1]->genRTLIL() : + fake_ast->children[0]->genRTLIL(), !id2ast->range_swapped ? fake_ast->children[1]->genRTLIL() : current_module->Sub(NEW_ID, RTLIL::SigSpec(wire->width - width), fake_ast->children[1]->genRTLIL())); delete left_at_zero_ast; delete right_at_zero_ast; @@ -924,7 +924,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) str.c_str(), filename.c_str(), linenum); chunk.width = children[0]->range_left - children[0]->range_right + 1; chunk.offset = children[0]->range_right - id2ast->range_right; - if (wire->upto) + if (id2ast->range_swapped) chunk.offset = wire->width - (chunk.offset + chunk.width); } } -- cgit v1.2.3 From a03297a7df6c729bc13f629412ae020eb05f7c64 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 16:09:50 +0200 Subject: Set results of out-of-bounds static bit/part select to undef --- frontends/ast/genrtlil.cc | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index ca61cb39b..b4115f0cd 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -866,6 +866,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Wire *wire = NULL; RTLIL::SigChunk chunk; + int add_undef_bits_msb = 0; + int add_undef_bits_lsb = 0; + if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) { RTLIL::Wire *wire = current_module->addWire(str); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -919,17 +922,40 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) delete fake_ast; return sig; } else { - if (children[0]->range_left > id2ast->range_left || id2ast->range_right > children[0]->range_right) - log_error("Range select out of bounds on signal `%s' at %s:%d!\n", - str.c_str(), filename.c_str(), linenum); + int source_width = id2ast->range_left - id2ast->range_right + 1; chunk.width = children[0]->range_left - children[0]->range_right + 1; chunk.offset = children[0]->range_right - id2ast->range_right; if (id2ast->range_swapped) - chunk.offset = wire->width - (chunk.offset + chunk.width); + chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width); + if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) { + if (chunk.width == 1) + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting result bit to undef.\n", + str.c_str(), filename.c_str(), linenum); + else + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting all %d result bits to undef.\n", + str.c_str(), filename.c_str(), linenum, chunk.width); + chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width); + } else { + if (chunk.width + chunk.offset > source_width) { + add_undef_bits_msb = (chunk.width + chunk.offset) - source_width; + chunk.width -= add_undef_bits_msb; + } + if (chunk.offset < 0) { + add_undef_bits_lsb = -chunk.offset; + chunk.width -= add_undef_bits_lsb; + chunk.offset += add_undef_bits_lsb; + } + if (add_undef_bits_lsb) + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d LSB bits to undef.\n", + str.c_str(), filename.c_str(), linenum, add_undef_bits_lsb); + if (add_undef_bits_msb) + log("Warning: Range select out of bounds on signal `%s' at %s:%d: Setting %d MSB bits to undef.\n", + str.c_str(), filename.c_str(), linenum, add_undef_bits_msb); + } } } - RTLIL::SigSpec sig(chunk); + RTLIL::SigSpec sig = { RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_msb), chunk, RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_lsb) }; if (genRTLIL_subst_from && genRTLIL_subst_to) sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); -- cgit v1.2.3 From ec589659674ba9699b5dc73129ad69f25738e87e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 16:45:26 +0200 Subject: Fixed part selects of parameters --- frontends/ast/genrtlil.cc | 15 ++++++++++----- frontends/ast/simplify.cc | 23 +++++++++++++++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b4115f0cd..9b8e0faa4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -902,6 +902,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) use_const_chunk: if (children.size() != 0) { log_assert(children[0]->type == AST_RANGE); + int source_width = id2ast->range_left - id2ast->range_right + 1; + int source_offset = id2ast->range_right; if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); @@ -914,17 +916,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); - RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, - fake_ast->children[0]->genRTLIL(), !id2ast->range_swapped ? fake_ast->children[1]->genRTLIL() : - current_module->Sub(NEW_ID, RTLIL::SigSpec(wire->width - width), fake_ast->children[1]->genRTLIL())); + RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(); + log_dump(width, shift_val, id2ast->range_swapped, source_width, id2ast->range_left, id2ast->range_right); + if (id2ast->range_right != 0) + shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right); + if (id2ast->range_swapped) + shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val); + RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, fake_ast->children[0]->genRTLIL(), shift_val); delete left_at_zero_ast; delete right_at_zero_ast; delete fake_ast; return sig; } else { - int source_width = id2ast->range_left - id2ast->range_right + 1; chunk.width = children[0]->range_left - children[0]->range_right + 1; - chunk.offset = children[0]->range_right - id2ast->range_right; + chunk.offset = children[0]->range_right - source_offset; if (id2ast->range_swapped) chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width); if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) { diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7aa6d24c3..d47bfb5e6 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -575,6 +575,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } children[0]->is_signed = is_signed; } + range_valid = true; + range_swapped = children[1]->range_swapped; + range_left = children[1]->range_left; + range_right = children[1]->range_right; } else if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) { double as_realvalue = children[0]->asReal(sign_hint); @@ -1522,8 +1526,23 @@ skip_dynamic_range_lvalue_expansion:; if (current_scope[str]->children[0]->type == AST_CONSTANT) { if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) { std::vector data; - for (int i = children[0]->range_right; i <= children[0]->range_left; i++) - data.push_back(current_scope[str]->children[0]->bits[i]); + bool param_upto = current_scope[str]->range_valid && current_scope[str]->range_swapped; + int param_offset = current_scope[str]->range_valid ? current_scope[str]->range_right : 0; + int param_width = current_scope[str]->range_valid ? current_scope[str]->range_left - current_scope[str]->range_right + 1 : + SIZE(current_scope[str]->children[0]->bits); + int tmp_range_left = children[0]->range_left, tmp_range_right = children[0]->range_right; + if (param_upto) { + tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1; + tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1; + } + log_dump(param_upto, param_offset, param_width, children[0]->range_left, children[0]->range_right, tmp_range_left, tmp_range_right); + for (int i = tmp_range_right; i <= tmp_range_left; i++) { + int index = i - param_offset; + if (0 <= index && index < param_width) + data.push_back(current_scope[str]->children[0]->bits[index]); + else + data.push_back(RTLIL::State::Sx); + } newNode = mkconst_bits(data, false); } else if (children.size() == 0) -- cgit v1.2.3 From 48822e79a34880c5f0b07e9889e463e7b6d7111b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 19:38:30 +0200 Subject: Removed left over debug code --- frontends/ast/genrtlil.cc | 1 - frontends/ast/simplify.cc | 1 - 2 files changed, 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9b8e0faa4..cb666679b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -917,7 +917,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(); - log_dump(width, shift_val, id2ast->range_swapped, source_width, id2ast->range_left, id2ast->range_right); if (id2ast->range_right != 0) shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right); if (id2ast->range_swapped) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d47bfb5e6..5665cd43c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1535,7 +1535,6 @@ skip_dynamic_range_lvalue_expansion:; tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1; tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1; } - log_dump(param_upto, param_offset, param_width, children[0]->range_left, children[0]->range_right, tmp_range_left, tmp_range_right); for (int i = tmp_range_right; i <= tmp_range_left; i++) { int index = i - param_offset; if (0 <= index && index < param_width) -- cgit v1.2.3 From 397b00252dc0c4af725614bd12fc299147ba8efa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 14:42:33 +0200 Subject: Added $shift and $shiftx cell types (needed for correct part select behavior) --- 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 3f824fc28..8a149a539 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 f721fdc99..43c036690 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 cb666679b..b7f336354 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -917,11 +917,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(); - if (id2ast->range_right != 0) - shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right); - if (id2ast->range_swapped) - shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val); - RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, fake_ast->children[0]->genRTLIL(), shift_val); + if (id2ast->range_right != 0) { + shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right, fake_ast->children[1]->is_signed); + fake_ast->children[1]->is_signed = true; + } + if (id2ast->range_swapped) { + shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val, fake_ast->children[1]->is_signed); + fake_ast->children[1]->is_signed = true; + } + if (SIZE(shift_val) >= 32) + fake_ast->children[1]->is_signed = true; + RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shiftx", width, fake_ast->children[0]->genRTLIL(), shift_val); delete left_at_zero_ast; delete right_at_zero_ast; delete fake_ast; diff --git a/kernel/calc.cc b/kernel/calc.cc index b413760d1..b3ff3cf2a 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 43c23add3..e1a1110d3 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 b562e2afb..83bbd7b17 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 097af9d28..e8d05e7e4 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 27a29cb57..a079b42f0 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 e61661a20..b1629b7c4 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 254fe5bb4..3e7487c39 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 1b50959c9..76aa4a52d 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 a05ea2786..ee59048c3 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 -- cgit v1.2.3 From 03c96f9ce7120adf1c9bab93485a3b4bf6493ae9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 16:06:27 +0200 Subject: 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 83bbd7b17..f864d88c0 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 e8d05e7e4..1f25542f3 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 9c5fa7f71..19d323341 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 5a69baca5..0ae5220e0 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_) { -- cgit v1.2.3 From 77e2d39cd079ba98340f55f57e8a6462fb709442 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 16:33:56 +0200 Subject: 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 c869ec729..a1361c680 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)) -- cgit v1.2.3 From 2145e57ef08784484e875e64cb43b6d1f4dbe50c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 19:23:31 +0200 Subject: 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 76aa4a52d..c2f6cb278 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 -- cgit v1.2.3 From e605af8a4937533b35068071e14f5bd92c2e5b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 20:14:25 +0200 Subject: Fixed Verilog pre-processor for files with no trailing newline --- frontends/verilog/preproc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 67b2ffa7c..9ff68822e 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -198,7 +198,7 @@ static void input_file(FILE *f, std::string filename) buffer[rc] = 0; input_buffer.insert(it, buffer); } - input_buffer.insert(it, "`file_pop\n"); + input_buffer.insert(it, "\n`file_pop\n"); } std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) -- cgit v1.2.3 From e6df25bf740b259027541db3543a769ecfc92d4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 21:12:50 +0200 Subject: Renamed "write_autotest" to "test_autotb" and moved to passes/tests/ --- backends/autotest/Makefile.inc | 3 - backends/autotest/autotest.cc | 335 ----------------------------------------- kernel/register.cc | 4 +- passes/tests/Makefile.inc | 3 + passes/tests/test_autotb.cc | 335 +++++++++++++++++++++++++++++++++++++++++ tests/tools/autotest.sh | 2 +- 6 files changed, 342 insertions(+), 340 deletions(-) delete mode 100644 backends/autotest/Makefile.inc delete mode 100644 backends/autotest/autotest.cc create mode 100644 passes/tests/Makefile.inc create mode 100644 passes/tests/test_autotb.cc diff --git a/backends/autotest/Makefile.inc b/backends/autotest/Makefile.inc deleted file mode 100644 index 9308dcd47..000000000 --- a/backends/autotest/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ - -OBJS += backends/autotest/autotest.o - diff --git a/backends/autotest/autotest.cc b/backends/autotest/autotest.cc deleted file mode 100644 index 3bb0f9d66..000000000 --- a/backends/autotest/autotest.cc +++ /dev/null @@ -1,335 +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. - * - */ - -#include "kernel/register.h" -#include "kernel/log.h" -#include -#include - -#define NUM_ITER 1000 - -static std::string id(std::string internal_id) -{ - const char *str = internal_id.c_str(); - bool do_escape = false; - - if (*str == '\\') - str++; - - if ('0' <= *str && *str <= '9') - do_escape = true; - - for (int i = 0; str[i]; i++) { - if ('0' <= str[i] && str[i] <= '9') - continue; - if ('a' <= str[i] && str[i] <= 'z') - continue; - if ('A' <= str[i] && str[i] <= 'Z') - continue; - if (str[i] == '_') - continue; - do_escape = true; - break; - } - - if (do_escape) - return "\\" + std::string(str) + " "; - return std::string(str); -} - -static std::string idx(std::string str) -{ - if (str[0] == '\\') - return str.substr(1); - return str; -} - -static std::string idy(std::string str1, std::string str2 = std::string(), std::string str3 = std::string()) -{ - str1 = idx(str1); - if (!str2.empty()) - str1 += "_" + idx(str2); - if (!str3.empty()) - str1 += "_" + idx(str3); - return id(str1); -} - -static void autotest(FILE *f, RTLIL::Design *design) -{ - fprintf(f, "module testbench;\n\n"); - - fprintf(f, "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 = 88675123;\n"); - 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"); - - for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) - { - std::map signal_in; - std::map signal_const; - std::map signal_clk; - std::map signal_out; - - RTLIL::Module *mod = it->second; - - if (mod->get_bool_attribute("\\gentb_skip")) - continue; - - 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++) { - 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()); - } else if (wire->port_input) { - count_ports++; - bool is_clksignal = wire->get_bool_attribute("\\gentb_clock"); - for (auto it3 = mod->processes.begin(); it3 != mod->processes.end(); it3++) - for (auto it4 = it3->second->syncs.begin(); it4 != it3->second->syncs.end(); it4++) { - if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1) - continue; - RTLIL::SigSpec &signal = (*it4)->signal; - 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; - } else { - signal_in[idy("sig", mod->name, wire->name)] = wire->width; - if (wire->attributes.count("\\gentb_constant") != 0) - signal_const[idy("sig", mod->name, wire->name)] = 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, "%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++) { - 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, ");\n\n"); - - fprintf(f, "task %s;\n", idy(mod->name, "reset").c_str()); - fprintf(f, "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); - 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); - 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()); - } - 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); - 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()); - } - 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()); - } - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); - - fprintf(f, "task %s;\n", idy(mod->name, "update_data").c_str()); - fprintf(f, "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); - } - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); - - fprintf(f, "task %s;\n", idy(mod->name, "update_clock").c_str()); - fprintf(f, "begin\n"); - if (signal_clk.size()) { - fprintf(f, "\txorshift128;\n"); - fprintf(f, "\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()); - total_clock_bits += it->second; - } - fprintf(f, " } = {"); - 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); - } - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); - - char shorthand = 'A'; - std::vector header1; - std::string header2 = ""; - - fprintf(f, "task %s;\n", idy(mod->name, "print_status").c_str()); - fprintf(f, "begin\n"); - fprintf(f, "\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()); - int len = it->second; - if (len > 1) - header2 += "/", len--; - while (len > 1) - header2 += "-", len--; - if (len > 0) - header2 += shorthand, len--; - header1.push_back(" " + it->first); - header1.back()[0] = shorthand++; - } - else { - fprintf(f, " 1'bx"); - header2 += "#"; - } - fprintf(f, " }, {"); - 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()); - int len = it->second; - if (len > 1) - header2 += "/", len--; - while (len > 1) - header2 += "-", len--; - if (len > 0) - header2 += shorthand, len--; - header1.push_back(" " + it->first); - header1.back()[0] = shorthand++; - } - } else { - fprintf(f, " 1'bx"); - header2 += "#"; - } - fprintf(f, " }, {"); - 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()); - int len = it->second; - if (len > 1) - header2 += "/", len--; - while (len > 1) - header2 += "-", len--; - if (len > 0) - header2 += shorthand, len--; - header1.push_back(" " + it->first); - header1.back()[0] = shorthand++; - } - } else { - fprintf(f, " 1'bx"); - header2 += "#"; - } - fprintf(f, " }, $time, i);\n"); - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); - - fprintf(f, "task %s;\n", idy(mod->name, "print_header").c_str()); - fprintf(f, "begin\n"); - fprintf(f, "\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"); - - fprintf(f, "task %s;\n", idy(mod->name, "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, "\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, "\tend\n"); - fprintf(f, "end\n"); - fprintf(f, "endtask\n\n"); - } - - 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++) - if (!it->second->get_bool_attribute("\\gentb_skip")) - fprintf(f, "\t%s;\n", idy(it->first, "test").c_str()); - fprintf(f, "\t$finish;\n"); - fprintf(f, "end\n\n"); - - fprintf(f, "endmodule\n"); -} - -struct AutotestBackend : public Backend { - AutotestBackend() : Backend("autotest", "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("\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"); - log("a semi-random manner and dumps the resulting output signals.\n"); - log("\n"); - log("This can be used to check the synthesis results for simple circuits by\n"); - log("comparing the testbench output for the input files and the synthesis results.\n"); - log("\n"); - log("The backend automatically detects clock signals. Additionally a signal can\n"); - log("be forced to be interpreted as clock signal by setting the attribute\n"); - log("'gentb_clock' on the signal.\n"); - log("\n"); - log("The attribute 'gentb_constant' can be used to force a signal to a constant\n"); - 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"); - } - 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"); - extra_args(f, filename, args, 1); - autotest(f, design); - } -} AutotestBackend; - diff --git a/kernel/register.cc b/kernel/register.cc index da3569831..4569481fa 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 000000000..6497f86e9 --- /dev/null +++ b/passes/tests/Makefile.inc @@ -0,0 +1,3 @@ + +OBJS += passes/tests/test_autotb.o + diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc new file mode 100644 index 000000000..f121089b1 --- /dev/null +++ b/passes/tests/test_autotb.cc @@ -0,0 +1,335 @@ +/* + * 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/log.h" +#include +#include + +#define NUM_ITER 1000 + +static std::string id(std::string internal_id) +{ + const char *str = internal_id.c_str(); + bool do_escape = false; + + if (*str == '\\') + str++; + + if ('0' <= *str && *str <= '9') + do_escape = true; + + for (int i = 0; str[i]; i++) { + if ('0' <= str[i] && str[i] <= '9') + continue; + if ('a' <= str[i] && str[i] <= 'z') + continue; + if ('A' <= str[i] && str[i] <= 'Z') + continue; + if (str[i] == '_') + continue; + do_escape = true; + break; + } + + if (do_escape) + return "\\" + std::string(str) + " "; + return std::string(str); +} + +static std::string idx(std::string str) +{ + if (str[0] == '\\') + return str.substr(1); + return str; +} + +static std::string idy(std::string str1, std::string str2 = std::string(), std::string str3 = std::string()) +{ + str1 = idx(str1); + if (!str2.empty()) + str1 += "_" + idx(str2); + if (!str3.empty()) + str1 += "_" + idx(str3); + return id(str1); +} + +static void autotest(FILE *f, RTLIL::Design *design) +{ + fprintf(f, "module testbench;\n\n"); + + fprintf(f, "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 = 88675123;\n"); + 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"); + + for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) + { + std::map signal_in; + std::map signal_const; + std::map signal_clk; + std::map signal_out; + + RTLIL::Module *mod = it->second; + + if (mod->get_bool_attribute("\\gentb_skip")) + continue; + + 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++) { + 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()); + } else if (wire->port_input) { + count_ports++; + bool is_clksignal = wire->get_bool_attribute("\\gentb_clock"); + for (auto it3 = mod->processes.begin(); it3 != mod->processes.end(); it3++) + for (auto it4 = it3->second->syncs.begin(); it4 != it3->second->syncs.end(); it4++) { + if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1) + continue; + RTLIL::SigSpec &signal = (*it4)->signal; + 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; + } else { + signal_in[idy("sig", mod->name, wire->name)] = wire->width; + if (wire->attributes.count("\\gentb_constant") != 0) + signal_const[idy("sig", mod->name, wire->name)] = 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, "%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++) { + 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, ");\n\n"); + + fprintf(f, "task %s;\n", idy(mod->name, "reset").c_str()); + fprintf(f, "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); + 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); + 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()); + } + 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); + 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()); + } + 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()); + } + fprintf(f, "end\n"); + fprintf(f, "endtask\n\n"); + + fprintf(f, "task %s;\n", idy(mod->name, "update_data").c_str()); + fprintf(f, "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); + } + fprintf(f, "end\n"); + fprintf(f, "endtask\n\n"); + + fprintf(f, "task %s;\n", idy(mod->name, "update_clock").c_str()); + fprintf(f, "begin\n"); + if (signal_clk.size()) { + fprintf(f, "\txorshift128;\n"); + fprintf(f, "\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()); + total_clock_bits += it->second; + } + fprintf(f, " } = {"); + 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); + } + fprintf(f, "end\n"); + fprintf(f, "endtask\n\n"); + + char shorthand = 'A'; + std::vector header1; + std::string header2 = ""; + + fprintf(f, "task %s;\n", idy(mod->name, "print_status").c_str()); + fprintf(f, "begin\n"); + fprintf(f, "\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()); + int len = it->second; + if (len > 1) + header2 += "/", len--; + while (len > 1) + header2 += "-", len--; + if (len > 0) + header2 += shorthand, len--; + header1.push_back(" " + it->first); + header1.back()[0] = shorthand++; + } + else { + fprintf(f, " 1'bx"); + header2 += "#"; + } + fprintf(f, " }, {"); + 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()); + int len = it->second; + if (len > 1) + header2 += "/", len--; + while (len > 1) + header2 += "-", len--; + if (len > 0) + header2 += shorthand, len--; + header1.push_back(" " + it->first); + header1.back()[0] = shorthand++; + } + } else { + fprintf(f, " 1'bx"); + header2 += "#"; + } + fprintf(f, " }, {"); + 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()); + int len = it->second; + if (len > 1) + header2 += "/", len--; + while (len > 1) + header2 += "-", len--; + if (len > 0) + header2 += shorthand, len--; + header1.push_back(" " + it->first); + header1.back()[0] = shorthand++; + } + } else { + fprintf(f, " 1'bx"); + header2 += "#"; + } + fprintf(f, " }, $time, i);\n"); + fprintf(f, "end\n"); + fprintf(f, "endtask\n\n"); + + fprintf(f, "task %s;\n", idy(mod->name, "print_header").c_str()); + fprintf(f, "begin\n"); + fprintf(f, "\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"); + + fprintf(f, "task %s;\n", idy(mod->name, "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, "\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, "\tend\n"); + fprintf(f, "end\n"); + fprintf(f, "endtask\n\n"); + } + + 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++) + if (!it->second->get_bool_attribute("\\gentb_skip")) + fprintf(f, "\t%s;\n", idy(it->first, "test").c_str()); + fprintf(f, "\t$finish;\n"); + fprintf(f, "end\n\n"); + + fprintf(f, "endmodule\n"); +} + +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(" 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"); + log("a semi-random manner and dumps the resulting output signals.\n"); + log("\n"); + log("This can be used to check the synthesis results for simple circuits by\n"); + log("comparing the testbench output for the input files and the synthesis results.\n"); + log("\n"); + log("The backend automatically detects clock signals. Additionally a signal can\n"); + log("be forced to be interpreted as clock signal by setting the attribute\n"); + log("'gentb_clock' on the signal.\n"); + log("\n"); + log("The attribute 'gentb_constant' can be used to force a signal to a constant\n"); + 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"); + } + virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + { + log_header("Executing TEST_AUTOTB backend (auto-generate pseudo-random test benches).\n"); + extra_args(f, filename, args, 1); + autotest(f, design); + } +} TestAutotbBackend; + diff --git a/tests/tools/autotest.sh b/tests/tools/autotest.sh index c383e19f4..1130bbb70 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 -- cgit v1.2.3 From 273383692a50490f02a51d0c44ba63b9f557da4e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 22:05:00 +0200 Subject: 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 a55fbbed5..2e56f9a33 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 6497f86e9..a60cfe66a 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 000000000..41671a8e6 --- /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; + -- cgit v1.2.3 From a7c6b37abf3e4628dd921bb12f77987d1f94c45f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 14:10:15 +0200 Subject: 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 462861c8a..73d448337 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 2e56f9a33..c20be1dc1 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 8036b2360..5fe0d0863 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 3152fc5af..803365b39 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 73875e968..68f09c822 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 1f25542f3..d6acb5bcc 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 000000000..d25443826 --- /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 000000000..67629d9b1 --- /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 -- cgit v1.2.3 From e2a029b5d583c3268df4d798f8e79874919eb601 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 14:10:49 +0200 Subject: 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 000000000..e076cbd89 --- /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. + -- cgit v1.2.3 From 45fd26b76e1ca72927ab0a8ce207aab0d024eba3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 15:58:21 +0200 Subject: 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 803365b39..a491d067d 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()); } -- cgit v1.2.3 From 9b566a7efa9813b0dd343bc96fe145f9e3e68d4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 17:17:31 +0200 Subject: 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 4c0b624be..13ed112ed 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 83e1b23c5..c5ef6b0a2 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); -- cgit v1.2.3 From 3f0a5746ef0940accb5fd14d97804c75c0531c0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 17:18:31 +0200 Subject: Using native ezSAT shift ops in satgen, fixed $shift and $shiftx SAT models --- kernel/satgen.h | 75 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/kernel/satgen.h b/kernel/satgen.h index a079b42f0..ce2c90280 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; - - 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 == "$shl" || cell->type == "$sshl") + shifted_a = ez->vec_shift_left(a, b, false, ez->FALSE, ez->FALSE); + + 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; - - 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 == "$shl" || cell->type == "$sshl") + undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->FALSE, ez->FALSE); + + 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; -- cgit v1.2.3 From 6c05badc43f7c1691932d1c38869492311f9bd44 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 15:59:05 +0200 Subject: New techmap default rules for $shr $sshr $shl $sshl --- techlibs/common/stdcells.v | 344 ++++++++------------------------------------- 1 file changed, 62 insertions(+), 282 deletions(-) diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index ee59048c3..a2fce1313 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,8 @@ endmodule // -------------------------------------------------------- -module \$__shift (XL, XR, A, Y); - -parameter WIDTH = 1; -parameter SHIFT = 0; - -input XL, XR; -input [WIDTH-1:0] A; -output [WIDTH-1:0] Y; - -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; - end - end -endgenerate - -endmodule - -// -------------------------------------------------------- - -module \$shl (A, B, Y); +(* techmap_celltype = "$shr $shl $sshl $sshr" *) +module shift_ops_shr_shl_sshl_sshr (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; @@ -164,119 +141,46 @@ 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; +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; -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 - -// -------------------------------------------------------- +localparam WIDTH = `MAX(A_WIDTH, Y_WIDTH); +localparam BB_WIDTH = `MIN($clog2(shift_left ? Y_WIDTH : A_SIGNED ? WIDTH : A_WIDTH) + 1, B_WIDTH); -module \$shr (A, B, Y); +wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; +integer i; +reg [WIDTH-1:0] buffer; +reg overflow; -localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; +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}; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; + 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 -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 +assign Y = buffer; endmodule // -------------------------------------------------------- -module \$sshl (A, B, Y); +(* techmap_celltype = "$shift $shiftx" *) +module shift_shiftx (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; @@ -284,174 +188,50 @@ 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 +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); -// -------------------------------------------------------- - -module \$sshr (A, B, Y); +parameter _TECHMAP_CELLTYPE_ = ""; +localparam extbit = _TECHMAP_CELLTYPE_ == "$shift" ? 1'b0 : 1'bx; -parameter A_SIGNED = 0; -parameter B_SIGNED = 0; -parameter A_WIDTH = 1; -parameter B_WIDTH = 1; -parameter Y_WIDTH = 1; +wire [1023:0] _TECHMAP_DO_ = "proc; opt_muxtree; opt_const -mux_undef -mux_bool -fine;;;"; -localparam WIDTH = A_WIDTH > Y_WIDTH ? A_WIDTH : Y_WIDTH; -localparam BB_WIDTH = $clog2(WIDTH) + 2 < B_WIDTH ? $clog2(WIDTH) + 2 : B_WIDTH; +integer i; +reg [WIDTH-1:0] buffer; +reg overflow; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y; +always @* begin + overflow = 0; + buffer = {WIDTH{extbit}}; + buffer[`MAX(A_WIDTH, Y_WIDTH)-1:0] = A; -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; - 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 - -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; + overflow = |B[B_WIDTH-1:BB_WIDTH]; + if (overflow) + buffer = {WIDTH{extbit}}; 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; + 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 -\$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 -- cgit v1.2.3 From ceecf5b1535cf2e567c144bdbe143c8ba66c69d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 15:59:38 +0200 Subject: Improvements in test_cell --- passes/tests/test_cell.cc | 124 +++++++++++++++++++++++++++++++++------------- 1 file changed, 89 insertions(+), 35 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 41671a8e6..d504cea94 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; - } + for (; argidx < SIZE(args); argidx++) + { + 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[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); + 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()); } - log_cmd_error("This cell type is currently not supported. Try one of these:%s\n", 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]); } - 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; + 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; -- cgit v1.2.3 From 7d98645fe8efcb446079a8a3cd8721ef5e27ee79 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 19:21:52 +0200 Subject: 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 73d448337..4436be3de 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 a204360d7..2477181a6 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 89be6d052..410f9b4d7 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 ec1802cbd..6531d51ae 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 000000000..f65002cef --- /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 1130bbb70..781dc1671 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 b1b205a22..ad99226e7 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 -- cgit v1.2.3 From 6400ae36489a7ada5419d7bc502934f6d05e69bb Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 19:59:29 +0200 Subject: 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 4569481fa..c7bd2cce7 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 68f09c822..41780bfb9 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 6ae4495a8..26c0ef8a9 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 000000000..a7cd7b438 --- /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; + -- cgit v1.2.3 From 7daad40ca408732786d46fee8b5485bf45595807 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 20:18:48 +0200 Subject: Fixed counting verilog line numbers for "// synopsys translate_off" sections --- frontends/verilog/lexer.l | 6 +++--- frontends/verilog/preproc.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 0839f5cf9..00deeb0b4 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -74,21 +74,21 @@ namespace VERILOG_FRONTEND { %% -"`file_push "[^\n]* { +"`file_push "[^\n]* { fn_stack.push_back(current_filename); ln_stack.push_back(frontend_verilog_yyget_lineno()); current_filename = yytext+11; frontend_verilog_yyset_lineno(0); } -"`file_pop"[^\n]*\n { +"`file_pop"[^\n]*\n { current_filename = fn_stack.back(); fn_stack.pop_back(); frontend_verilog_yyset_lineno(ln_stack.back()); ln_stack.pop_back(); } -"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { +"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { char *p = yytext + 5; while (*p == ' ' || *p == '\t') p++; frontend_verilog_yyset_lineno(atoi(p)); diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 9ff68822e..2cfa8ca76 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -300,7 +300,7 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m input_file(fp, fn); fclose(fp); } else - output_code.push_back("`file_notfound " + fn + "\n"); + output_code.push_back("`file_notfound " + fn); continue; } -- cgit v1.2.3 From 254148910556d057ec296e4f8c44e92bdb8c09a3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 22:04:30 +0200 Subject: 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 d6acb5bcc..7bd75bd1d 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 0ae5220e0..75b9dee9b 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 a2fce1313..7ee2771e6 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; -- cgit v1.2.3 From e5c245df9d086595063978298139a9aaed68979d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 00:53:21 +0200 Subject: 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 c20be1dc1..ab8ecba9d 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()) { -- cgit v1.2.3 From 6166c768313f6a2dee774f0ba0a531816b24502d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 01:05:27 +0200 Subject: 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 ab8ecba9d..d9ef22238 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()) { -- cgit v1.2.3 From 41555cde1026ecc269071ede4f99d86ff61f7078 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 02:21:06 +0200 Subject: Reorganized stdcells.v (no actual code change, just moved and indented stuff) --- techlibs/common/stdcells.v | 1337 +++++++++++++++++++------------------------- 1 file changed, 590 insertions(+), 747 deletions(-) diff --git a/techlibs/common/stdcells.v b/techlibs/common/stdcells.v index 7ee2771e6..54652868a 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)) -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$not ; -endmodule // -------------------------------------------------------- - -(* techmap_simplemap *) -module \$pos ; -endmodule - +// Use simplemap for trivial cell types // -------------------------------------------------------- (* techmap_simplemap *) -module \$bu0 ; +(* techmap_celltype = "$pos $bu0" *) +module simplemap_buffers; endmodule -// -------------------------------------------------------- - -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 - -// -------------------------------------------------------- - (* techmap_simplemap *) -module \$and ; +(* techmap_celltype = "$not $and $or $xor $xnor" *) +module simplemap_bool_ops; endmodule -// -------------------------------------------------------- - (* techmap_simplemap *) -module \$or ; +(* techmap_celltype = "$reduce_and $reduce_or $reduce_xor $reduce_xnor $reduce_bool" *) +module simplemap_reduce_ops; endmodule -// -------------------------------------------------------- - (* techmap_simplemap *) -module \$xor ; +(* techmap_celltype = "$logic_not $logic_and $logic_or" *) +module simplemap_logic_ops; endmodule -// -------------------------------------------------------- - (* techmap_simplemap *) -module \$xnor ; +(* techmap_celltype = "$slice $concat $mux" *) +module simplemap_various; endmodule -// -------------------------------------------------------- - (* techmap_simplemap *) -module \$reduce_and ; +(* techmap_celltype = "$sr $dff $adff $dffsr $dlatch" *) +module simplemap_registers; endmodule -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$reduce_or ; -endmodule +// -------------------------------------------------------- +// Trivial substitutions // -------------------------------------------------------- -(* techmap_simplemap *) -module \$reduce_xor ; +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 -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$reduce_xnor ; +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; -(* techmap_simplemap *) -module \$reduce_bool ; + 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 + +// -------------------------------------------------------- +// 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 _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; + + 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;;;"; + + 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 -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"; - -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_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; - -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; - + 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; - -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); - -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;;;"; - -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; - - 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 + 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; + + 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; + + 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; + + 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 -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; - -\$_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) ); + // {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 - -// -------------------------------------------------------- - 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 - + 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; - -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 - + 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 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 - + 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 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 - +// Add and Subtract // -------------------------------------------------------- -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) -); - +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) + ); 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; -module \$gt (A, B, Y); + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] 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) -); + 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 -// -------------------------------------------------------- - -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) -); - -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) -); - -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; - -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 + wire [WIDTH*WIDTH-1:0] partials; -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; - -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output [Y_WIDTH-1:0] Y, R; + localparam WIDTH = + A_WIDTH >= B_WIDTH && A_WIDTH >= Y_WIDTH ? A_WIDTH : + B_WIDTH >= A_WIDTH && B_WIDTH >= Y_WIDTH ? B_WIDTH : Y_WIDTH; -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)); + 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_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, 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)); -\$__div_mod_u #( - .WIDTH(WIDTH) -) div_mod_u ( - .A(A_buf_u), - .B(B_buf_u), - .Y(Y_u), - .R(R_u) -); + 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; -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; - -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) -); - + 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) + ); 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 // -------------------------------------------------------- - -(* techmap_simplemap *) -module \$logic_and ; -endmodule - +// Equal and Not-Equal // -------------------------------------------------------- -(* techmap_simplemap *) -module \$logic_or ; -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; -(* techmap_simplemap *) -module \$slice ; -endmodule + 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)); -(* techmap_simplemap *) -module \$concat ; + assign Y = ~|(A_buf ^ B_buf); endmodule -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$mux ; -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; -module \$pmux (A, B, S, Y); + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] 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 [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; + 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; -module \$safe_pmux (A, B, S, Y); + localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; -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) -); + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; -endmodule + 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)); -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$sr ; + assign Y = ~|(A_buf ^ B_buf); endmodule -// -------------------------------------------------------- - -(* techmap_simplemap *) -module \$dff ; -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; -(* techmap_simplemap *) -module \$adff ; -endmodule + 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)); -(* techmap_simplemap *) -module \$dffsr ; + assign Y = |(A_buf ^ B_buf); endmodule + +// -------------------------------------------------------- +// Parallel Multiplexers // -------------------------------------------------------- -(* techmap_simplemap *) -module \$dlatch ; +module \$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 [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; 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 -- cgit v1.2.3 From 6ca0c569d92883b6eac1725204de90aee4af31bc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 02:21:41 +0200 Subject: 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 75b9dee9b..50936af0e 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 d504cea94..4034f120e 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; -- cgit v1.2.3 From 1202f7aa4bb0f9afde157ebc4701d64e7e38abd8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 02:32:00 +0200 Subject: 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 | 785 ------------------------------------------- techlibs/common/techmap.v | 785 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 800 insertions(+), 797 deletions(-) delete mode 100644 techlibs/common/stdcells.v create mode 100644 techlibs/common/techmap.v diff --git a/CHECKLISTS b/CHECKLISTS index 8a149a539..3a06e61e0 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 4384cfbdd..1e0ade91c 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 be74c3567..26632d0b5 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 ca9d3942c..e6dcc6bc0 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 e54c018aa..b49259a8a 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 50936af0e..2aa59e61b 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 a76d1a079..2be27b920 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 5ecec7891..d492c2f15 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/stdcells.v deleted file mode 100644 index 54652868a..000000000 --- a/techlibs/common/stdcells.v +++ /dev/null @@ -1,785 +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. - * - * --- - * - * 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_ - * gate). Usually this logic network is then mapped to the actual technology - * using e.g. the "abc" pass. - * - * Note that this library does not map $mem cells. They must be mapped to logic - * and $dff cells using the "memory_map" pass first. (Or map it to custom cells, - * which is of course highly recommended for larger memories.) - * - */ - -`define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -`define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) - - -// -------------------------------------------------------- -// Use simplemap for trivial cell types -// -------------------------------------------------------- - -(* techmap_simplemap *) -(* techmap_celltype = "$pos $bu0" *) -module simplemap_buffers; -endmodule - -(* techmap_simplemap *) -(* techmap_celltype = "$not $and $or $xor $xnor" *) -module simplemap_bool_ops; -endmodule - -(* techmap_simplemap *) -(* 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; - - 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 - - -// -------------------------------------------------------- -// 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 _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; - - 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;;;"; - - 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 - - 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; - - 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); - - 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;;;"; - - 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; - - 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 - 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; - - // {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 - -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; - - 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 -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 -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; - - 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) - ); -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) - ); -endmodule - - -// -------------------------------------------------------- -// Multiply -// -------------------------------------------------------- - -module \$__arraymul (A, B, Y); - parameter WIDTH = 8; - input [WIDTH-1:0] A, B; - output [WIDTH-1:0] Y; - - 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)]; -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 [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; - - 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)]; - - 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 - - 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 -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; - - 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; - - 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; - - \$__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; - - 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; - - 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; - - input [A_WIDTH-1:0] A; - input [B_WIDTH-1:0] B; - output [Y_WIDTH-1:0] Y; - - wire _TECHMAP_FAIL_ = 1; -endmodule - - -// -------------------------------------------------------- -// Equal and Not-Equal -// -------------------------------------------------------- - -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 - - -// -------------------------------------------------------- -// Parallel Multiplexers -// -------------------------------------------------------- - -module \$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 [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; -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 - diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v new file mode 100644 index 000000000..54652868a --- /dev/null +++ b/techlibs/common/techmap.v @@ -0,0 +1,785 @@ +/* + * 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. + * + * --- + * + * 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_ + * gate). Usually this logic network is then mapped to the actual technology + * using e.g. the "abc" pass. + * + * Note that this library does not map $mem cells. They must be mapped to logic + * and $dff cells using the "memory_map" pass first. (Or map it to custom cells, + * which is of course highly recommended for larger memories.) + * + */ + +`define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +`define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) + + +// -------------------------------------------------------- +// Use simplemap for trivial cell types +// -------------------------------------------------------- + +(* techmap_simplemap *) +(* techmap_celltype = "$pos $bu0" *) +module simplemap_buffers; +endmodule + +(* techmap_simplemap *) +(* techmap_celltype = "$not $and $or $xor $xnor" *) +module simplemap_bool_ops; +endmodule + +(* techmap_simplemap *) +(* 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; + + 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 + + +// -------------------------------------------------------- +// 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 _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; + + 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;;;"; + + 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 + + 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; + + 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); + + 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;;;"; + + 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; + + 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 + 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; + + // {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 + +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; + + 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 +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 +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; + + 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) + ); +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) + ); +endmodule + + +// -------------------------------------------------------- +// Multiply +// -------------------------------------------------------- + +module \$__arraymul (A, B, Y); + parameter WIDTH = 8; + input [WIDTH-1:0] A, B; + output [WIDTH-1:0] Y; + + 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)]; +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 [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; + + 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)]; + + 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 + + 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 +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; + + 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; + + 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; + + \$__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; + + 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; + + 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; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] Y; + + wire _TECHMAP_FAIL_ = 1; +endmodule + + +// -------------------------------------------------------- +// Equal and Not-Equal +// -------------------------------------------------------- + +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 + + +// -------------------------------------------------------- +// Parallel Multiplexers +// -------------------------------------------------------- + +module \$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 [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; +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 + -- cgit v1.2.3 From 1cb25c05b37b0172dbc50e140fe20f25d973dd8a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 13:19:47 +0200 Subject: Moved some stuff to kernel/yosys.{h,cc}, using Yosys:: namespace --- backends/ilang/ilang_backend.cc | 6 +- backends/ilang/ilang_backend.h | 6 +- frontends/ast/ast.cc | 6 +- frontends/ast/ast.h | 4 + frontends/ast/genrtlil.cc | 24 +- frontends/ast/simplify.cc | 60 ++-- frontends/ilang/ilang_frontend.cc | 4 + frontends/ilang/ilang_frontend.h | 6 +- frontends/ilang/parser.y | 9 +- frontends/liberty/liberty.cc | 3 + frontends/verific/verific.cc | 8 +- frontends/verilog/const2ast.cc | 4 + frontends/verilog/lexer.l | 3 + frontends/verilog/parser.y | 7 +- frontends/verilog/preproc.cc | 4 + frontends/verilog/verilog_frontend.cc | 3 + frontends/verilog/verilog_frontend.h | 6 +- frontends/vhdl2verilog/vhdl2verilog.cc | 4 + kernel/calc.cc | 7 +- kernel/driver.cc | 546 +------------------------------ kernel/log.cc | 6 +- kernel/log.h | 6 +- kernel/register.cc | 34 +- kernel/register.h | 14 +- kernel/rtlil.cc | 8 +- kernel/rtlil.h | 18 +- kernel/sigtools.h | 8 +- kernel/yosys.cc | 565 +++++++++++++++++++++++++++++++++ kernel/yosys.h | 38 ++- libs/subcircuit/subcircuit.cc | 4 +- passes/abc/abc.cc | 4 +- passes/cmds/design.cc | 4 + passes/fsm/fsm_extract.cc | 4 +- passes/memory/memory_collect.cc | 2 +- passes/memory/memory_dff.cc | 2 +- passes/memory/memory_map.cc | 2 +- passes/memory/memory_unpack.cc | 2 +- passes/proc/proc_dff.cc | 6 +- passes/proc/proc_mux.cc | 4 +- passes/techmap/extract.cc | 2 +- passes/techmap/techmap.cc | 2 +- 41 files changed, 790 insertions(+), 665 deletions(-) diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index c055c1334..b7088f599 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -336,7 +336,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { - int init_autoidx = RTLIL::autoidx; + int init_autoidx = autoidx; if (!flag_m) { int count_selected_mods = 0; @@ -353,7 +353,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ if (!only_selected || flag_m) { if (only_selected) fprintf(f, "\n"); - fprintf(f, "autoidx %d\n", RTLIL::autoidx); + fprintf(f, "autoidx %d\n", autoidx); } for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) { @@ -364,7 +364,7 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_ } } - log_assert(init_autoidx == RTLIL::autoidx); + log_assert(init_autoidx == autoidx); } struct IlangBackend : public Backend { diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h index fecbcc1fe..b0fec4889 100644 --- a/backends/ilang/ilang_backend.h +++ b/backends/ilang/ilang_backend.h @@ -25,9 +25,11 @@ #ifndef ILANG_BACKEND_H #define ILANG_BACKEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include +YOSYS_NAMESPACE_BEGIN + namespace ILANG_BACKEND { void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint = true); @@ -44,4 +46,6 @@ namespace ILANG_BACKEND { void dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); } +YOSYS_NAMESPACE_END + #endif diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5b3214f5c..d548a679c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -34,6 +34,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; using namespace AST_INTERNAL; @@ -806,7 +808,7 @@ RTLIL::Const AstNode::realAsConst(int width) { double v = round(realvalue); RTLIL::Const result; - if (!isfinite(v)) { + if (!std::isfinite(v)) { result.bits = std::vector(width, RTLIL::State::Sx); } else { bool is_negative = v < 0; @@ -1087,3 +1089,5 @@ void AST::use_internal_line_num() get_line_num = &internal_get_line_num; } +YOSYS_NAMESPACE_END + diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6c15c03ab..83798edf0 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -33,6 +33,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + namespace AST { // all node types, type2str() must be extended @@ -285,4 +287,6 @@ namespace AST_INTERNAL struct ProcessGenerator; } +YOSYS_NAMESPACE_END + #endif diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b7f336354..0cc4f4c47 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -34,6 +34,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; using namespace AST_INTERNAL; @@ -41,7 +43,7 @@ using namespace AST_INTERNAL; static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true) { std::stringstream sstr; - sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -75,7 +77,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s } std::stringstream sstr; - sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -104,7 +106,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { std::stringstream sstr; - sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << type << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -139,7 +141,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const log_assert(cond.size() == 1); std::stringstream sstr; - sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (RTLIL::autoidx++); + sstr << "$ternary$" << that->filename << ":" << that->linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); @@ -201,7 +203,7 @@ struct AST_INTERNAL::ProcessGenerator // generate process and simple root case proc = new RTLIL::Process; proc->attributes["\\src"] = stringf("%s:%d", always->filename.c_str(), always->linenum); - proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->linenum, RTLIL::autoidx++); + proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->linenum, autoidx++); for (auto &attr : always->attributes) { if (attr.second->type != AST_CONSTANT) log_error("Attribute `%s' with non-constant value at %s:%d!\n", @@ -294,7 +296,7 @@ struct AST_INTERNAL::ProcessGenerator wire_name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, chunk.wire->name.c_str(), chunk.width+chunk.offset-1, chunk.offset);; if (chunk.wire->name.find('$') != std::string::npos) - wire_name += stringf("$%d", RTLIL::autoidx++); + wire_name += stringf("$%d", autoidx++); } while (current_module->wires_.count(wire_name) > 0); RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); @@ -1189,7 +1191,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMRD: { std::stringstream sstr; - sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$memrd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1220,7 +1222,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_MEMWR: { std::stringstream sstr; - sstr << "$memwr$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$memwr$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memwr"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1241,7 +1243,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0); cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0); - cell->parameters["\\PRIORITY"] = RTLIL::Const(RTLIL::autoidx-1); + cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1); } break; @@ -1257,7 +1259,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(en.size() == 1); std::stringstream sstr; - sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$assert$" << filename << ":" << linenum << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$assert"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); @@ -1399,3 +1401,5 @@ RTLIL::SigSpec AstNode::genWidthRTLIL(int width, RTLIL::SigSpec *subst_from, RT return sig; } +YOSYS_NAMESPACE_END + diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5665cd43c..c51692f12 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -34,6 +34,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; using namespace AST_INTERNAL; @@ -624,7 +626,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, id2ast->meminfo(mem_width, mem_size, addr_bits); std::stringstream sstr; - sstr << "$mem2bits$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$mem2bits$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string wire_id = sstr.str(); AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); @@ -744,7 +746,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, buf = new AstNode(AST_GENBLOCK, body_ast->clone()); if (buf->str.empty()) { std::stringstream sstr; - sstr << "$genblock$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$genblock$" << filename << ":" << linenum << "$" << (autoidx++); buf->str = sstr.str(); } std::map name_map; @@ -1091,7 +1093,7 @@ skip_dynamic_range_lvalue_expansion:; if (stage > 1 && type == AST_ASSERT && current_block != NULL) { std::stringstream sstr; - sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$assert$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN"; AstNode *wire_check = new AstNode(AST_WIRE); @@ -1166,7 +1168,7 @@ skip_dynamic_range_lvalue_expansion:; (children[0]->children.size() == 1 || children[0]->children.size() == 2)) { std::stringstream sstr; - sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN"; if (type == AST_ASSIGN_EQ) @@ -1364,27 +1366,27 @@ skip_dynamic_range_lvalue_expansion:; } newNode = new AstNode(AST_REALVALUE); - if (str == "\\$ln") newNode->realvalue = log(x); - else if (str == "\\$log10") newNode->realvalue = log10(x); - else if (str == "\\$exp") newNode->realvalue = exp(x); - else if (str == "\\$sqrt") newNode->realvalue = sqrt(x); - else if (str == "\\$pow") newNode->realvalue = pow(x, y); - else if (str == "\\$floor") newNode->realvalue = floor(x); - else if (str == "\\$ceil") newNode->realvalue = ceil(x); - else if (str == "\\$sin") newNode->realvalue = sin(x); - else if (str == "\\$cos") newNode->realvalue = cos(x); - else if (str == "\\$tan") newNode->realvalue = tan(x); - else if (str == "\\$asin") newNode->realvalue = asin(x); - else if (str == "\\$acos") newNode->realvalue = acos(x); - else if (str == "\\$atan") newNode->realvalue = atan(x); - else if (str == "\\$atan2") newNode->realvalue = atan2(x, y); - else if (str == "\\$hypot") newNode->realvalue = hypot(x, y); - else if (str == "\\$sinh") newNode->realvalue = sinh(x); - else if (str == "\\$cosh") newNode->realvalue = cosh(x); - else if (str == "\\$tanh") newNode->realvalue = tanh(x); - else if (str == "\\$asinh") newNode->realvalue = asinh(x); - else if (str == "\\$acosh") newNode->realvalue = acosh(x); - else if (str == "\\$atanh") newNode->realvalue = atanh(x); + if (str == "\\$ln") newNode->realvalue = ::log(x); + else if (str == "\\$log10") newNode->realvalue = ::log10(x); + else if (str == "\\$exp") newNode->realvalue = ::exp(x); + else if (str == "\\$sqrt") newNode->realvalue = ::sqrt(x); + else if (str == "\\$pow") newNode->realvalue = ::pow(x, y); + else if (str == "\\$floor") newNode->realvalue = ::floor(x); + else if (str == "\\$ceil") newNode->realvalue = ::ceil(x); + else if (str == "\\$sin") newNode->realvalue = ::sin(x); + else if (str == "\\$cos") newNode->realvalue = ::cos(x); + else if (str == "\\$tan") newNode->realvalue = ::tan(x); + else if (str == "\\$asin") newNode->realvalue = ::asin(x); + else if (str == "\\$acos") newNode->realvalue = ::acos(x); + else if (str == "\\$atan") newNode->realvalue = ::atan(x); + else if (str == "\\$atan2") newNode->realvalue = ::atan2(x, y); + else if (str == "\\$hypot") newNode->realvalue = ::hypot(x, y); + else if (str == "\\$sinh") newNode->realvalue = ::sinh(x); + else if (str == "\\$cosh") newNode->realvalue = ::cosh(x); + else if (str == "\\$tanh") newNode->realvalue = ::tanh(x); + else if (str == "\\$asinh") newNode->realvalue = ::asinh(x); + else if (str == "\\$acosh") newNode->realvalue = ::acosh(x); + else if (str == "\\$atanh") newNode->realvalue = ::atanh(x); else log_abort(); goto apply_newNode; } @@ -1423,7 +1425,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *decl = current_scope[str]; std::stringstream sstr; - sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++) << "$"; + sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; std::string prefix = sstr.str(); size_t arg_count = 0; @@ -1988,7 +1990,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * mem2reg_set.count(children[0]->id2ast) > 0 && children[0]->children[0]->children[0]->type != AST_CONSTANT) { std::stringstream sstr; - sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; @@ -2059,7 +2061,7 @@ void AstNode::mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode * else { std::stringstream sstr; - sstr << "$mem2reg_rd$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++); + sstr << "$mem2reg_rd$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA"; int mem_width, mem_size, addr_bits; @@ -2421,3 +2423,5 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed); } +YOSYS_NAMESPACE_END + diff --git a/frontends/ilang/ilang_frontend.cc b/frontends/ilang/ilang_frontend.cc index 572a35720..2d4b99c52 100644 --- a/frontends/ilang/ilang_frontend.cc +++ b/frontends/ilang/ilang_frontend.cc @@ -26,6 +26,8 @@ #include "kernel/register.h" #include "kernel/log.h" +YOSYS_NAMESPACE_BEGIN + void rtlil_frontend_ilang_yyerror(char const *s) { log_error("Parser error in line %d: %s\n", rtlil_frontend_ilang_yyget_lineno(), s); @@ -57,3 +59,5 @@ struct IlangFrontend : public Frontend { } } IlangFrontend; +YOSYS_NAMESPACE_END + diff --git a/frontends/ilang/ilang_frontend.h b/frontends/ilang/ilang_frontend.h index 5e768c3b9..317ec0d51 100644 --- a/frontends/ilang/ilang_frontend.h +++ b/frontends/ilang/ilang_frontend.h @@ -25,14 +25,18 @@ #ifndef ILANG_FRONTEND_H #define ILANG_FRONTEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include +YOSYS_NAMESPACE_BEGIN + namespace ILANG_FRONTEND { void ilang_frontend(FILE *f, RTLIL::Design *design); extern RTLIL::Design *current_design; } +YOSYS_NAMESPACE_END + extern int rtlil_frontend_ilang_yydebug; int rtlil_frontend_ilang_yylex(void); void rtlil_frontend_ilang_yyerror(char const *s); diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 38d3054b2..ab763b2b1 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -25,6 +25,7 @@ %{ #include #include "ilang_frontend.h" +YOSYS_NAMESPACE_BEGIN namespace ILANG_FRONTEND { RTLIL::Design *current_design; RTLIL::Module *current_module; @@ -37,6 +38,8 @@ namespace ILANG_FRONTEND { std::map attrbuf; } using namespace ILANG_FRONTEND; +YOSYS_NAMESPACE_END +USING_YOSYS_NAMESPACE %} %name-prefix "rtlil_frontend_ilang_yy" @@ -44,8 +47,8 @@ using namespace ILANG_FRONTEND; %union { char *string; int integer; - RTLIL::Const *data; - RTLIL::SigSpec *sigspec; + YOSYS_NAMESPACE_PREFIX RTLIL::Const *data; + YOSYS_NAMESPACE_PREFIX RTLIL::SigSpec *sigspec; } %token TOK_ID TOK_VALUE TOK_STRING @@ -116,7 +119,7 @@ attr_stmt: autoidx_stmt: TOK_AUTOIDX TOK_INT EOL { - RTLIL::autoidx = std::max(RTLIL::autoidx, $2); + autoidx = std::max(autoidx, $2); }; wire_stmt: diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index d5f172f03..da16ab33f 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -21,6 +21,7 @@ #include "kernel/register.h" #include "kernel/log.h" +YOSYS_NAMESPACE_BEGIN using namespace PASS_DFFLIBMAP; struct token_t { @@ -573,3 +574,5 @@ skip_cell:; } } LibertyFrontend; +YOSYS_NAMESPACE_END + diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 80170394e..6e692c5a1 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -17,7 +17,7 @@ * */ -#include "kernel/register.h" +#include "kernel/yosys.h" #include "kernel/sigtools.h" #include "kernel/log.h" #include @@ -26,6 +26,8 @@ #include #include +USING_YOSYS_NAMESPACE + #ifdef YOSYS_ENABLE_VERIFIC #pragma clang diagnostic push @@ -768,6 +770,8 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::set #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; // divide an arbitrary length decimal number by two and return the rest @@ -210,3 +212,5 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) return NULL; } +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 00deeb0b4..fdb9bb02c 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -44,13 +44,16 @@ #include "frontends/ast/ast.h" #include "parser.tab.h" +USING_YOSYS_NAMESPACE using namespace AST; using namespace VERILOG_FRONTEND; +YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { std::vector fn_stack; std::vector ln_stack; } +YOSYS_NAMESPACE_END #define SV_KEYWORD(_tok) \ if (sv_mode) return _tok; \ diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index ce7b99272..c62e761e2 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -39,9 +39,11 @@ #include "verilog_frontend.h" #include "kernel/log.h" +USING_YOSYS_NAMESPACE using namespace AST; using namespace VERILOG_FRONTEND; +YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { int port_counter; std::map port_stubs; @@ -56,6 +58,7 @@ namespace VERILOG_FRONTEND { bool default_nettype_wire; bool sv_mode; } +YOSYS_NAMESPACE_END static void append_attr(AstNode *ast, std::map *al) { @@ -89,8 +92,8 @@ static void free_attr(std::map *al) %union { std::string *string; - struct AstNode *ast; - std::map *al; + struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast; + std::map *al; bool boolean; } diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 2cfa8ca76..8efd4d7c3 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -38,6 +38,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + static std::list output_code; static std::list input_buffer; static size_t input_buffer_charp; @@ -427,3 +429,5 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m return output; } +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index cbc594e86..4466e1cb6 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -34,6 +34,7 @@ #include #include +YOSYS_NAMESPACE_BEGIN using namespace VERILOG_FRONTEND; // use the Verilog bison/flex parser to generate an AST and use AST::process() to convert it to RTLIL @@ -376,3 +377,5 @@ struct VerilogDefaults : public Pass { } } VerilogDefaults; +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 6d01a1532..dac5b3d02 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -29,12 +29,14 @@ #ifndef VERILOG_FRONTEND_H #define VERILOG_FRONTEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "frontends/ast/ast.h" #include #include #include +YOSYS_NAMESPACE_BEGIN + namespace VERILOG_FRONTEND { // this variable is set to a new AST_DESIGN node and then filled with the AST by the bison parser @@ -53,6 +55,8 @@ namespace VERILOG_FRONTEND // the pre-processor std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); +YOSYS_NAMESPACE_END + // the usual bison/flex stuff extern int frontend_verilog_yydebug; int frontend_verilog_yylex(void); diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 63dc85acc..f0545700a 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + struct Vhdl2verilogPass : public Pass { Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { } virtual void help() @@ -190,3 +192,5 @@ struct Vhdl2verilogPass : public Pass { } } Vhdl2verilogPass; +YOSYS_NAMESPACE_END + diff --git a/kernel/calc.cc b/kernel/calc.cc index b3ff3cf2a..29717aad5 100644 --- a/kernel/calc.cc +++ b/kernel/calc.cc @@ -21,10 +21,11 @@ // Schneier, Bruce (1996). Applied Cryptography: Protocols, Algorithms, and Source Code in C, // Second Edition (2nd ed.). Wiley. ISBN 978-0-471-11709-4, page 244 -#include "kernel/log.h" -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "libs/bigint/BigIntegerLibrary.hh" +YOSYS_NAMESPACE_BEGIN + static void extend(RTLIL::Const &arg, int width, bool is_signed) { RTLIL::State padding = RTLIL::State::S0; @@ -592,3 +593,5 @@ RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, boo return RTLIL::const_sub(zero, arg1_ext, false, signed1, result_len); } +YOSYS_NAMESPACE_END + diff --git a/kernel/driver.cc b/kernel/driver.cc index d9ef22238..01ade7d46 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -17,9 +17,12 @@ * */ -#include +#include "kernel/yosys.h" + #include #include + +#include #include #include #include @@ -27,523 +30,7 @@ #include #include -#include -#include - -#include "kernel/yosys.h" - -bool fgetline(FILE *f, std::string &buffer) -{ - buffer = ""; - char block[4096]; - while (1) { - if (fgets(block, 4096, f) == NULL) - return false; - buffer += block; - if (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) { - while (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) - buffer.resize(buffer.size()-1); - return true; - } - } -} - -static void handle_label(std::string &command, bool &from_to_active, const std::string &run_from, const std::string &run_to) -{ - int pos = 0; - std::string label; - - while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) - pos++; - - while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') - label += command[pos++]; - - if (label.back() == ':' && SIZE(label) > 1) - { - label = label.substr(0, SIZE(label)-1); - command = command.substr(pos); - - if (label == run_from) - from_to_active = true; - else if (label == run_to || (run_from == run_to && !run_from.empty())) - from_to_active = false; - } -} - -static void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) -{ - if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") - command = "verilog"; - else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") - command = "verilog -sv"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") - command = "ilang"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") - command = "script"; - else if (filename == "-") - command = "script"; - else - log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str()); - } - - if (command == "script") - { - std::string run_from, run_to; - bool from_to_active = true; - - if (from_to_label != NULL) { - size_t pos = from_to_label->find(':'); - if (pos == std::string::npos) { - run_from = *from_to_label; - run_to = *from_to_label; - } else { - run_from = from_to_label->substr(0, pos); - run_to = from_to_label->substr(pos+1); - } - from_to_active = run_from.empty(); - } - - log("\n-- Executing script file `%s' --\n", filename.c_str()); - - FILE *f = stdin; - - if (filename != "-") - f = fopen(filename.c_str(), "r"); - - if (f == NULL) - log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); - - FILE *backup_script_file = Frontend::current_script_file; - Frontend::current_script_file = f; - - try { - std::string command; - while (fgetline(f, command)) { - while (!command.empty() && command[command.size()-1] == '\\') { - std::string next_line; - if (!fgetline(f, next_line)) - break; - command.resize(command.size()-1); - command += next_line; - } - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); - } - - if (!command.empty()) { - handle_label(command, from_to_active, run_from, run_to); - if (from_to_active) - Pass::call(design, command); - } - } - catch (log_cmd_error_expection) { - Frontend::current_script_file = backup_script_file; - throw log_cmd_error_expection(); - } - - Frontend::current_script_file = backup_script_file; - - if (filename != "-") - fclose(f); - - if (backend_command != NULL && *backend_command == "auto") - *backend_command = ""; - - return; - } - - if (filename == "-") { - log("\n-- Parsing stdin using frontend `%s' --\n", command.c_str()); - } else { - log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str()); - } - - Frontend::frontend_call(design, NULL, filename, command); -} - -static void run_pass(std::string command, RTLIL::Design *design) -{ - log("\n-- Running pass `%s' --\n", command.c_str()); - - Pass::call(design, command); -} - -static void run_backend(std::string filename, std::string command, RTLIL::Design *design) -{ - if (command == "auto") { - if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") - command = "verilog"; - else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") - command = "ilang"; - else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") - command = "blif"; - else if (filename == "-") - command = "ilang"; - else if (filename.empty()) - return; - else - log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename.c_str()); - } - - if (filename.empty()) - filename = "-"; - - if (filename == "-") { - log("\n-- Writing to stdout using backend `%s' --\n", command.c_str()); - } else { - log("\n-- Writing to `%s' using backend `%s' --\n", filename.c_str(), command.c_str()); - } - - Backend::backend_call(design, NULL, filename, command); -} - -static char *readline_cmd_generator(const char *text, int state) -{ - static std::map::iterator it; - static int len; - - if (!state) { - it = REGISTER_INTERN::pass_register.begin(); - len = strlen(text); - } - - for (; it != REGISTER_INTERN::pass_register.end(); it++) { - if (it->first.substr(0, len) == text) - return strdup((it++)->first.c_str()); - } - return NULL; -} - -static char *readline_obj_generator(const char *text, int state) -{ - static std::vector obj_names; - static size_t idx; - - if (!state) - { - idx = 0; - obj_names.clear(); - - RTLIL::Design *design = yosys_get_design(); - int len = strlen(text); - - if (design->selected_active_module.empty()) - { - for (auto &it : design->modules_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - } - else - if (design->modules_.count(design->selected_active_module) > 0) - { - RTLIL::Module *module = design->modules_.at(design->selected_active_module); - - for (auto &it : module->wires_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->memories) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->cells_) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - - for (auto &it : module->processes) - if (RTLIL::unescape_id(it.first).substr(0, len) == text) - obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); - } - - std::sort(obj_names.begin(), obj_names.end()); - } - - if (idx < obj_names.size()) - return strdup(obj_names[idx++]); - - idx = 0; - obj_names.clear(); - return NULL; -} - -static char **readline_completion(const char *text, int start, int) -{ - if (start == 0) - return rl_completion_matches(text, readline_cmd_generator); - if (strncmp(rl_line_buffer, "read_", 5) && strncmp(rl_line_buffer, "write_", 6)) - return rl_completion_matches(text, readline_obj_generator); - return NULL; -} - -const char *create_prompt(RTLIL::Design *design, int recursion_counter) -{ - static char buffer[100]; - std::string str = "\n"; - if (recursion_counter > 1) - str += stringf("(%d) ", recursion_counter); - str += "yosys"; - if (!design->selected_active_module.empty()) - str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); - if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { - if (design->selected_active_module.empty()) - str += "*"; - else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || - design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) - str += "*"; - } - snprintf(buffer, 100, "%s> ", str.c_str()); - return buffer; -} - -static void shell(RTLIL::Design *design) -{ - static int recursion_counter = 0; - - recursion_counter++; - log_cmd_error_throw = true; - - rl_readline_name = "yosys"; - rl_attempted_completion_function = readline_completion; - rl_basic_word_break_characters = " \t\n"; - - char *command = NULL; - while ((command = readline(create_prompt(design, recursion_counter))) != NULL) - { - if (command[strspn(command, " \t\r\n")] == 0) - continue; - add_history(command); - - char *p = command + strspn(command, " \t\r\n"); - if (!strncmp(p, "exit", 4)) { - p += 4; - p += strspn(p, " \t\r\n"); - if (*p == 0) - break; - } - - try { - log_assert(design->selection_stack.size() == 1); - Pass::call(design, command); - } catch (log_cmd_error_expection) { - while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); - log_reset_stack(); - } - } - if (command == NULL) - printf("exit\n"); - - recursion_counter--; - log_cmd_error_throw = false; -} - -struct ShellPass : public Pass { - ShellPass() : Pass("shell", "enter interactive command mode") { } - virtual void help() { - log("\n"); - log(" shell\n"); - log("\n"); - log("This command enters the interactive command mode. This can be useful\n"); - log("in a script to interrupt the script at a certain point and allow for\n"); - log("interactive inspection or manual synthesis of the design at this point.\n"); - log("\n"); - log("The command prompt of the interactive shell indicates the current\n"); - log("selection (see 'help select'):\n"); - log("\n"); - log(" yosys>\n"); - log(" the entire design is selected\n"); - log("\n"); - log(" yosys*>\n"); - log(" only part of the design is selected\n"); - log("\n"); - log(" yosys [modname]>\n"); - log(" the entire module 'modname' is selected using 'select -module modname'\n"); - log("\n"); - log(" yosys [modname]*>\n"); - log(" only part of current module 'modname' is selected\n"); - log("\n"); - log("When in interactive shell, some errors (e.g. invalid command arguments)\n"); - log("do not terminate yosys but return to the command prompt.\n"); - log("\n"); - log("This command is the default action if nothing else has been specified\n"); - log("on the command line.\n"); - log("\n"); - log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - extra_args(args, 1, design, false); - shell(design); - } -} ShellPass; - -struct HistoryPass : public Pass { - HistoryPass() : Pass("history", "show last interactive commands") { } - virtual void help() { - log("\n"); - log(" history\n"); - log("\n"); - log("This command prints all commands in the shell history buffer. This are\n"); - log("all commands executed in an interactive session, but not the commands\n"); - log("from executed scripts.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - extra_args(args, 1, design, false); - for(HIST_ENTRY **list = history_list(); *list != NULL; list++) - log("%s\n", (*list)->line); - } -} HistoryPass; - -struct ScriptPass : public Pass { - ScriptPass() : Pass("script", "execute commands from script file") { } - virtual void help() { - log("\n"); - log(" script [:]\n"); - log("\n"); - log("This command executes the yosys commands in the specified file.\n"); - log("\n"); - log("The 2nd argument can be used to only execute the section of the\n"); - log("file between the specified labels. An empty from label is synonymous\n"); - log("for the beginning of the file and an empty to label is synonymous\n"); - log("for the end of the file.\n"); - log("\n"); - log("If only one label is specified (without ':') then only the block\n"); - log("marked with that label (until the next label) is executed.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - if (args.size() < 2) - log_cmd_error("Missing script file.\n"); - else if (args.size() == 2) - run_frontend(args[1], "script", design, NULL, NULL); - else if (args.size() == 3) - run_frontend(args[1], "script", design, NULL, &args[2]); - else - extra_args(args, 2, design, false); - } -} ScriptPass; - -#ifdef YOSYS_ENABLE_TCL -static Tcl_Interp *yosys_tcl_interp = NULL; - -static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[]) -{ - std::vector args; - for (int i = 1; i < argc; i++) - args.push_back(argv[i]); - - if (args.size() >= 1 && args[0] == "-import") { - for (auto &it : REGISTER_INTERN::pass_register) { - std::string tcl_command_name = it.first; - if (tcl_command_name == "proc") - tcl_command_name = "procs"; - Tcl_CmdInfo info; - if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) { - log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str()); - } else { - std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name.c_str(), it.first.c_str()); - Tcl_Eval(interp, tcl_script.c_str()); - } - } - return TCL_OK; - } - - if (args.size() == 1) { - Pass::call(yosys_get_design(), args[0]); - return TCL_OK; - } - - Pass::call(yosys_get_design(), args); - return TCL_OK; -} - -extern Tcl_Interp *yosys_get_tcl_interp() -{ - if (yosys_tcl_interp == NULL) { - yosys_tcl_interp = Tcl_CreateInterp(); - Tcl_CreateCommand(yosys_tcl_interp, "yosys", tcl_yosys_cmd, NULL, NULL); - } - return yosys_tcl_interp; -} - -struct TclPass : public Pass { - TclPass() : Pass("tcl", "execute a TCL script file") { } - virtual void help() { - log("\n"); - log(" tcl \n"); - log("\n"); - log("This command executes the tcl commands in the specified file.\n"); - log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); - log("\n"); - log("The tcl command 'yosys -import' can be used to import all yosys\n"); - log("commands directly as tcl commands to the tcl shell. The yosys\n"); - log("command 'proc' is wrapped using the tcl command 'procs' in order\n"); - log("to avoid a name collision with the tcl builting command 'proc'.\n"); - log("\n"); - } - virtual void execute(std::vector args, RTLIL::Design *design) { - if (args.size() < 2) - log_cmd_error("Missing script file.\n"); - if (args.size() > 2) - extra_args(args, 1, design, false); - if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK) - log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); - } -} TclPass; -#endif - -static RTLIL::Design *yosys_design = NULL; - -extern RTLIL::Design *yosys_get_design() -{ - return yosys_design; -} - -#if defined(__linux__) -std::string proc_self_dirname () -{ - char path [PATH_MAX]; - ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); - if (buflen < 0) { - log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); - log_abort(); - } - while (buflen > 0 && path[buflen-1] != '/') - buflen--; - return std::string(path, buflen); -} -#elif defined(__APPLE__) -#include -std::string proc_self_dirname () -{ - char * path = NULL; - uint32_t buflen = 0; - while (_NSGetExecutablePath(path, &buflen) != 0) - path = (char *) realloc((void *) path, buflen); - while (buflen > 0 && path[buflen-1] != '/') - buflen--; - return std::string(path, buflen); -} -#else - #error Dont know how to determine process executable base path! -#endif - -std::string proc_share_dirname () -{ - std::string proc_self_path = proc_self_dirname(); - std::string proc_share_path = proc_self_path + "share/"; - if (access(proc_share_path.c_str(), X_OK) == 0) - return proc_share_path; - proc_share_path = proc_self_path + "../share/yosys/"; - if (access(proc_share_path.c_str(), X_OK) == 0) - return proc_share_path; - log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); - log_abort(); -} +USING_YOSYS_NAMESPACE int main(int argc, char **argv) { @@ -739,11 +226,7 @@ int main(int argc, char **argv) log("\n"); } - Pass::init_register(); - - yosys_design = new RTLIL::Design; - yosys_design->selection_stack.push_back(RTLIL::Selection()); - log_push(); + yosys_setup(); if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) { if (!got_output_filename) @@ -804,7 +287,6 @@ int main(int argc, char **argv) log("\nEnd of script.\n"); if (call_abort) abort(); - log_pop(); if (!history_file.empty()) { if (history_offset > 0) { @@ -819,25 +301,11 @@ int main(int argc, char **argv) if (hist_list != NULL) free(hist_list); - for (auto f : log_files) - if (f != stderr) - fclose(f); - log_errfile = NULL; - log_files.clear(); - - Pass::done_register(); + yosys_shutdown(); for (auto mod : loaded_modules) dlclose(mod); -#ifdef YOSYS_ENABLE_TCL - if (yosys_tcl_interp != NULL) { - Tcl_DeleteInterp(yosys_tcl_interp); - Tcl_Finalize(); - yosys_tcl_interp = NULL; - } -#endif - return 0; } diff --git a/kernel/log.cc b/kernel/log.cc index 5fe0d0863..64dd7a92a 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; @@ -233,7 +235,7 @@ std::map> get_coverage_data() { std::map> coverage_data; - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { std::string key = stringf("passes.%s", it.first.c_str()); coverage_data[key].first = stringf("%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); coverage_data[key].second += it.second->call_counter; @@ -260,3 +262,5 @@ std::map> get_coverage_data() return coverage_data; } +YOSYS_NAMESPACE_END + diff --git a/kernel/log.h b/kernel/log.h index a491d067d..0109faf62 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -28,6 +28,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + #define S__LINE__sub2(x) #x #define S__LINE__sub1(x) S__LINE__sub2(x) #define S__LINE__ S__LINE__sub1(__LINE__) @@ -40,8 +42,6 @@ extern bool log_time; extern bool log_cmd_error_throw; extern int log_verbose_level; -std::string stringf(const char *fmt, ...); - void logv(const char *format, va_list ap); void logv_header(const char *format, va_list ap); void logv_error(const char *format, va_list ap) __attribute__ ((noreturn)); @@ -246,4 +246,6 @@ void log_dump_args_worker(const char *p, T first, Args ... args) log("\n"); \ } while (0) +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/register.cc b/kernel/register.cc index c7bd2cce7..7469b3e81 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -17,26 +17,22 @@ * */ -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include #include #include #include -using namespace REGISTER_INTERN; +YOSYS_NAMESPACE_BEGIN + #define MAX_REG_COUNT 1000 -namespace REGISTER_INTERN -{ - bool echo_mode = false; - Pass *first_queued_pass; +bool echo_mode = false; +Pass *first_queued_pass; - std::map frontend_register; - std::map pass_register; - std::map backend_register; -} +std::map frontend_register; +std::map pass_register; +std::map backend_register; std::vector Frontend::next_args; @@ -552,7 +548,7 @@ struct HelpPass : public Pass { { if (args.size() == 1) { log("\n"); - for (auto &it : REGISTER_INTERN::pass_register) + for (auto &it : pass_register) log(" %-20s %s\n", it.first.c_str(), it.second->short_help.c_str()); log("\n"); log("Type 'help ' for more information on a command.\n"); @@ -562,7 +558,7 @@ struct HelpPass : public Pass { if (args.size() == 2) { if (args[1] == "-all") { - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { log("\n\n"); log("%s -- %s\n", it.first.c_str(), it.second->short_help.c_str()); for (size_t i = 0; i < it.first.size() + it.second->short_help.size() + 6; i++) @@ -575,7 +571,7 @@ struct HelpPass : public Pass { else if (args[1] == "-write-tex-command-reference-manual") { FILE *f = fopen("command-reference-manual.tex", "wt"); fprintf(f, "%% Generated using the yosys 'help -write-tex-command-reference-manual' command.\n\n"); - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { size_t memsize; char *memptr; FILE *memf = open_memstream(&memptr, &memsize); @@ -591,7 +587,7 @@ struct HelpPass : public Pass { // this option is undocumented as it is for internal use only else if (args[1] == "-write-web-command-reference-manual") { FILE *f = fopen("templates/cmd_index.in", "wt"); - for (auto &it : REGISTER_INTERN::pass_register) { + for (auto &it : pass_register) { size_t memsize; char *memptr; FILE *memf = open_memstream(&memptr, &memsize); @@ -604,10 +600,10 @@ struct HelpPass : public Pass { } fclose(f); } - else if (REGISTER_INTERN::pass_register.count(args[1]) == 0) + else if (pass_register.count(args[1]) == 0) log("No such command: %s\n", args[1].c_str()); else - REGISTER_INTERN::pass_register.at(args[1])->help(); + pass_register.at(args[1])->help(); return; } @@ -648,3 +644,5 @@ struct EchoPass : public Pass { } } EchoPass; +YOSYS_NAMESPACE_END + diff --git a/kernel/register.h b/kernel/register.h index 41780bfb9..17942ca96 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -20,12 +20,14 @@ #ifndef REGISTER_H #define REGISTER_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include #include #include #include +YOSYS_NAMESPACE_BEGIN + struct Pass { std::string pass_name, short_help; @@ -94,10 +96,10 @@ struct Backend : Pass // implemented in passes/cmds/select.cc extern void handle_extra_select_args(Pass *pass, std::vector args, size_t argidx, size_t args_size, RTLIL::Design *design); -namespace REGISTER_INTERN { - extern std::map pass_register; - extern std::map frontend_register; - extern std::map backend_register; -} +extern std::map pass_register; +extern std::map frontend_register; +extern std::map backend_register; + +YOSYS_NAMESPACE_END #endif diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index f864d88c0..82fa7aec2 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -17,16 +17,14 @@ * */ -#include "kernel/compatibility.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include "frontends/verilog/verilog_frontend.h" #include "backends/ilang/ilang_backend.h" #include #include -int RTLIL::autoidx = 1; +YOSYS_NAMESPACE_BEGIN RTLIL::Const::Const() { @@ -2736,3 +2734,5 @@ RTLIL::Process *RTLIL::Process::clone() const return new_proc; } +YOSYS_NAMESPACE_END + diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7bd75bd1d..4d8581c72 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -22,6 +22,8 @@ #ifndef RTLIL_H #define RTLIL_H +YOSYS_NAMESPACE_BEGIN + namespace RTLIL { enum State : unsigned char { @@ -50,8 +52,6 @@ namespace RTLIL CONST_FLAG_REAL = 4 // unused -- to be used for parameters }; - extern int autoidx; - struct Const; struct Selection; struct Design; @@ -123,18 +123,6 @@ namespace RTLIL return str.c_str(); } - static IdString new_id(std::string file, int line, std::string func) __attribute__((unused)); - static IdString new_id(std::string file, int line, std::string func) { - std::string str = "$auto$"; - size_t pos = file.find_last_of('/'); - str += pos != std::string::npos ? file.substr(pos+1) : file; - str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++); - return str; - } - -#define NEW_ID \ - RTLIL::new_id(__FILE__, __LINE__, __FUNCTION__) - template struct sort_by_name { bool operator()(T *a, T *b) const { return a->name < b->name; @@ -969,4 +957,6 @@ void RTLIL::Process::rewrite_sigspecs(T functor) it->rewrite_sigspecs(functor); } +YOSYS_NAMESPACE_END + #endif diff --git a/kernel/sigtools.h b/kernel/sigtools.h index 79a9fb238..b691749a8 100644 --- a/kernel/sigtools.h +++ b/kernel/sigtools.h @@ -20,9 +20,9 @@ #ifndef SIGTOOLS_H #define SIGTOOLS_H -#include "kernel/rtlil.h" -#include "kernel/log.h" -#include +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN struct SigPool { @@ -398,4 +398,6 @@ struct SigMap } }; +YOSYS_NAMESPACE_END + #endif /* SIGTOOLS_H */ diff --git a/kernel/yosys.cc b/kernel/yosys.cc index d25443826..34800ce8e 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -19,6 +19,21 @@ #include "kernel/yosys.h" +#include +#include + +#include +#include + +YOSYS_NAMESPACE_BEGIN + +int autoidx = 1; +RTLIL::Design *yosys_design = NULL; + +#ifdef YOSYS_ENABLE_TCL +Tcl_Interp *yosys_tcl_interp = NULL; +#endif + std::string stringf(const char *fmt, ...) { std::string string; @@ -38,3 +53,553 @@ std::string stringf(const char *fmt, ...) return string; } +void yosys_setup() +{ + Pass::init_register(); + + yosys_design = new RTLIL::Design; + yosys_design->selection_stack.push_back(RTLIL::Selection()); + log_push(); +} + +void yosys_shutdown() +{ + log_pop(); + + for (auto f : log_files) + if (f != stderr) + fclose(f); + log_errfile = NULL; + log_files.clear(); + + Pass::done_register(); + +#ifdef YOSYS_ENABLE_TCL + if (yosys_tcl_interp != NULL) { + Tcl_DeleteInterp(yosys_tcl_interp); + Tcl_Finalize(); + yosys_tcl_interp = NULL; + } +#endif +} + +RTLIL::IdString new_id(std::string file, int line, std::string func) +{ + std::string str = "$auto$"; + size_t pos = file.find_last_of('/'); + str += pos != std::string::npos ? file.substr(pos+1) : file; + str += stringf(":%d:%s$%d", line, func.c_str(), autoidx++); + return str; +} + +RTLIL::Design *yosys_get_design() +{ + return yosys_design; +} + +const char *create_prompt(RTLIL::Design *design, int recursion_counter) +{ + static char buffer[100]; + std::string str = "\n"; + if (recursion_counter > 1) + str += stringf("(%d) ", recursion_counter); + str += "yosys"; + if (!design->selected_active_module.empty()) + str += stringf(" [%s]", RTLIL::id2cstr(design->selected_active_module)); + if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { + if (design->selected_active_module.empty()) + str += "*"; + else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || + design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) + str += "*"; + } + snprintf(buffer, 100, "%s> ", str.c_str()); + return buffer; +} + +#ifdef YOSYS_ENABLE_TCL +static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[]) +{ + std::vector args; + for (int i = 1; i < argc; i++) + args.push_back(argv[i]); + + if (args.size() >= 1 && args[0] == "-import") { + for (auto &it : pass_register) { + std::string tcl_command_name = it.first; + if (tcl_command_name == "proc") + tcl_command_name = "procs"; + Tcl_CmdInfo info; + if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) { + log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str()); + } else { + std::string tcl_script = stringf("proc %s args { yosys %s {*}$args }", tcl_command_name.c_str(), it.first.c_str()); + Tcl_Eval(interp, tcl_script.c_str()); + } + } + return TCL_OK; + } + + if (args.size() == 1) { + Pass::call(yosys_get_design(), args[0]); + return TCL_OK; + } + + Pass::call(yosys_get_design(), args); + return TCL_OK; +} + +extern Tcl_Interp *yosys_get_tcl_interp() +{ + if (yosys_tcl_interp == NULL) { + yosys_tcl_interp = Tcl_CreateInterp(); + Tcl_CreateCommand(yosys_tcl_interp, "yosys", tcl_yosys_cmd, NULL, NULL); + } + return yosys_tcl_interp; +} + +struct TclPass : public Pass { + TclPass() : Pass("tcl", "execute a TCL script file") { } + virtual void help() { + log("\n"); + log(" tcl \n"); + log("\n"); + log("This command executes the tcl commands in the specified file.\n"); + log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n"); + log("\n"); + log("The tcl command 'yosys -import' can be used to import all yosys\n"); + log("commands directly as tcl commands to the tcl shell. The yosys\n"); + log("command 'proc' is wrapped using the tcl command 'procs' in order\n"); + log("to avoid a name collision with the tcl builting command 'proc'.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + if (args.size() > 2) + extra_args(args, 1, design, false); + if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK) + log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp())); + } +} TclPass; +#endif + +#if defined(__linux__) +std::string proc_self_dirname () +{ + char path [PATH_MAX]; + ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); + if (buflen < 0) { + log_cmd_error("readlink(\"/proc/self/exe\") failed: %s", strerror(errno)); + log_abort(); + } + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#elif defined(__APPLE__) +#include +std::string proc_self_dirname () +{ + char * path = NULL; + uint32_t buflen = 0; + while (_NSGetExecutablePath(path, &buflen) != 0) + path = (char *) realloc((void *) path, buflen); + while (buflen > 0 && path[buflen-1] != '/') + buflen--; + return std::string(path, buflen); +} +#else + #error Dont know how to determine process executable base path! +#endif + +std::string proc_share_dirname () +{ + std::string proc_self_path = proc_self_dirname(); + std::string proc_share_path = proc_self_path + "share/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + proc_share_path = proc_self_path + "../share/yosys/"; + if (access(proc_share_path.c_str(), X_OK) == 0) + return proc_share_path; + log_cmd_error("proc_share_dirname: unable to determine share/ directory!"); + log_abort(); +} + +bool fgetline(FILE *f, std::string &buffer) +{ + buffer = ""; + char block[4096]; + while (1) { + if (fgets(block, 4096, f) == NULL) + return false; + buffer += block; + if (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) { + while (buffer.size() > 0 && (buffer[buffer.size()-1] == '\n' || buffer[buffer.size()-1] == '\r')) + buffer.resize(buffer.size()-1); + return true; + } + } +} + +static void handle_label(std::string &command, bool &from_to_active, const std::string &run_from, const std::string &run_to) +{ + int pos = 0; + std::string label; + + while (pos < SIZE(command) && (command[pos] == ' ' || command[pos] == '\t')) + pos++; + + while (pos < SIZE(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n') + label += command[pos++]; + + if (label.back() == ':' && SIZE(label) > 1) + { + label = label.substr(0, SIZE(label)-1); + command = command.substr(pos); + + if (label == run_from) + from_to_active = true; + else if (label == run_to || (run_from == run_to && !run_from.empty())) + from_to_active = false; + } +} + +void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label) +{ + if (command == "auto") { + if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + command = "verilog"; + else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") + command = "verilog -sv"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + command = "ilang"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") + command = "script"; + else if (filename == "-") + command = "script"; + else + log_error("Can't guess frontend for input file `%s' (missing -f option)!\n", filename.c_str()); + } + + if (command == "script") + { + std::string run_from, run_to; + bool from_to_active = true; + + if (from_to_label != NULL) { + size_t pos = from_to_label->find(':'); + if (pos == std::string::npos) { + run_from = *from_to_label; + run_to = *from_to_label; + } else { + run_from = from_to_label->substr(0, pos); + run_to = from_to_label->substr(pos+1); + } + from_to_active = run_from.empty(); + } + + log("\n-- Executing script file `%s' --\n", filename.c_str()); + + FILE *f = stdin; + + if (filename != "-") + f = fopen(filename.c_str(), "r"); + + if (f == NULL) + log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno)); + + FILE *backup_script_file = Frontend::current_script_file; + Frontend::current_script_file = f; + + try { + std::string command; + while (fgetline(f, command)) { + while (!command.empty() && command[command.size()-1] == '\\') { + std::string next_line; + if (!fgetline(f, next_line)) + break; + command.resize(command.size()-1); + command += next_line; + } + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + + if (!command.empty()) { + handle_label(command, from_to_active, run_from, run_to); + if (from_to_active) + Pass::call(design, command); + } + } + catch (log_cmd_error_expection) { + Frontend::current_script_file = backup_script_file; + throw log_cmd_error_expection(); + } + + Frontend::current_script_file = backup_script_file; + + if (filename != "-") + fclose(f); + + if (backend_command != NULL && *backend_command == "auto") + *backend_command = ""; + + return; + } + + if (filename == "-") { + log("\n-- Parsing stdin using frontend `%s' --\n", command.c_str()); + } else { + log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str()); + } + + Frontend::frontend_call(design, NULL, filename, command); +} + +void run_pass(std::string command, RTLIL::Design *design) +{ + log("\n-- Running pass `%s' --\n", command.c_str()); + + Pass::call(design, command); +} + +void run_backend(std::string filename, std::string command, RTLIL::Design *design) +{ + if (command == "auto") { + if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") + command = "verilog"; + else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") + command = "ilang"; + else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") + command = "blif"; + else if (filename == "-") + command = "ilang"; + else if (filename.empty()) + return; + else + log_error("Can't guess backend for output file `%s' (missing -b option)!\n", filename.c_str()); + } + + if (filename.empty()) + filename = "-"; + + if (filename == "-") { + log("\n-- Writing to stdout using backend `%s' --\n", command.c_str()); + } else { + log("\n-- Writing to `%s' using backend `%s' --\n", filename.c_str(), command.c_str()); + } + + Backend::backend_call(design, NULL, filename, command); +} + +static char *readline_cmd_generator(const char *text, int state) +{ + static std::map::iterator it; + static int len; + + if (!state) { + it = pass_register.begin(); + len = strlen(text); + } + + for (; it != pass_register.end(); it++) { + if (it->first.substr(0, len) == text) + return strdup((it++)->first.c_str()); + } + return NULL; +} + +static char *readline_obj_generator(const char *text, int state) +{ + static std::vector obj_names; + static size_t idx; + + if (!state) + { + idx = 0; + obj_names.clear(); + + RTLIL::Design *design = yosys_get_design(); + int len = strlen(text); + + if (design->selected_active_module.empty()) + { + for (auto &it : design->modules_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + } + else + if (design->modules_.count(design->selected_active_module) > 0) + { + RTLIL::Module *module = design->modules_.at(design->selected_active_module); + + for (auto &it : module->wires_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->memories) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->cells_) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + + for (auto &it : module->processes) + if (RTLIL::unescape_id(it.first).substr(0, len) == text) + obj_names.push_back(strdup(RTLIL::id2cstr(it.first.c_str()))); + } + + std::sort(obj_names.begin(), obj_names.end()); + } + + if (idx < obj_names.size()) + return strdup(obj_names[idx++]); + + idx = 0; + obj_names.clear(); + return NULL; +} + +static char **readline_completion(const char *text, int start, int) +{ + if (start == 0) + return rl_completion_matches(text, readline_cmd_generator); + if (strncmp(rl_line_buffer, "read_", 5) && strncmp(rl_line_buffer, "write_", 6)) + return rl_completion_matches(text, readline_obj_generator); + return NULL; +} + +void shell(RTLIL::Design *design) +{ + static int recursion_counter = 0; + + recursion_counter++; + log_cmd_error_throw = true; + + rl_readline_name = "yosys"; + rl_attempted_completion_function = readline_completion; + rl_basic_word_break_characters = " \t\n"; + + char *command = NULL; + while ((command = readline(create_prompt(design, recursion_counter))) != NULL) + { + if (command[strspn(command, " \t\r\n")] == 0) + continue; + add_history(command); + + char *p = command + strspn(command, " \t\r\n"); + if (!strncmp(p, "exit", 4)) { + p += 4; + p += strspn(p, " \t\r\n"); + if (*p == 0) + break; + } + + try { + log_assert(design->selection_stack.size() == 1); + Pass::call(design, command); + } catch (log_cmd_error_expection) { + while (design->selection_stack.size() > 1) + design->selection_stack.pop_back(); + log_reset_stack(); + } + } + if (command == NULL) + printf("exit\n"); + + recursion_counter--; + log_cmd_error_throw = false; +} + +struct ShellPass : public Pass { + ShellPass() : Pass("shell", "enter interactive command mode") { } + virtual void help() { + log("\n"); + log(" shell\n"); + log("\n"); + log("This command enters the interactive command mode. This can be useful\n"); + log("in a script to interrupt the script at a certain point and allow for\n"); + log("interactive inspection or manual synthesis of the design at this point.\n"); + log("\n"); + log("The command prompt of the interactive shell indicates the current\n"); + log("selection (see 'help select'):\n"); + log("\n"); + log(" yosys>\n"); + log(" the entire design is selected\n"); + log("\n"); + log(" yosys*>\n"); + log(" only part of the design is selected\n"); + log("\n"); + log(" yosys [modname]>\n"); + log(" the entire module 'modname' is selected using 'select -module modname'\n"); + log("\n"); + log(" yosys [modname]*>\n"); + log(" only part of current module 'modname' is selected\n"); + log("\n"); + log("When in interactive shell, some errors (e.g. invalid command arguments)\n"); + log("do not terminate yosys but return to the command prompt.\n"); + log("\n"); + log("This command is the default action if nothing else has been specified\n"); + log("on the command line.\n"); + log("\n"); + log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + extra_args(args, 1, design, false); + shell(design); + } +} ShellPass; + +struct HistoryPass : public Pass { + HistoryPass() : Pass("history", "show last interactive commands") { } + virtual void help() { + log("\n"); + log(" history\n"); + log("\n"); + log("This command prints all commands in the shell history buffer. This are\n"); + log("all commands executed in an interactive session, but not the commands\n"); + log("from executed scripts.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + extra_args(args, 1, design, false); + for(HIST_ENTRY **list = history_list(); *list != NULL; list++) + log("%s\n", (*list)->line); + } +} HistoryPass; + +struct ScriptPass : public Pass { + ScriptPass() : Pass("script", "execute commands from script file") { } + virtual void help() { + log("\n"); + log(" script [:]\n"); + log("\n"); + log("This command executes the yosys commands in the specified file.\n"); + log("\n"); + log("The 2nd argument can be used to only execute the section of the\n"); + log("file between the specified labels. An empty from label is synonymous\n"); + log("for the beginning of the file and an empty to label is synonymous\n"); + log("for the end of the file.\n"); + log("\n"); + log("If only one label is specified (without ':') then only the block\n"); + log("marked with that label (until the next label) is executed.\n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) { + if (args.size() < 2) + log_cmd_error("Missing script file.\n"); + else if (args.size() == 2) + run_frontend(args[1], "script", design, NULL, NULL); + else if (args.size() == 3) + run_frontend(args[1], "script", design, NULL, &args[2]); + else + extra_args(args, 2, design, false); + } +} ScriptPass; + +YOSYS_NAMESPACE_END + diff --git a/kernel/yosys.h b/kernel/yosys.h index 67629d9b1..9b36ebcc9 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -29,6 +29,9 @@ // If you want to know how to register a command with Yosys, you could read // "kernel/register.h", but it would be easier to just look at a simple // example instead. A simple one would be "passes/cmds/log.cc". +// +// This header is very boring. It just defines some general things that +// belong nowhere else and includes the interesting headers. #ifndef YOSYS_H @@ -38,20 +41,24 @@ #include #include #include +#include #include #if 0 # define YOSYS_NAMESPACE_BEGIN namespace Yosys { # define YOSYS_NAMESPACE_END } +# define YOSYS_NAMESPACE_PREFIX Yosys:: +# define USING_YOSYS_NAMESPACE using namespace Yosys; #else # define YOSYS_NAMESPACE_BEGIN # define YOSYS_NAMESPACE_END +# define YOSYS_NAMESPACE_PREFIX +# define USING_YOSYS_NAMESPACE #endif YOSYS_NAMESPACE_BEGIN std::string stringf(const char *fmt, ...); - #define SIZE(__obj) int(__obj.size()) YOSYS_NAMESPACE_END @@ -63,20 +70,35 @@ YOSYS_NAMESPACE_END YOSYS_NAMESPACE_BEGIN +void yosys_setup(); +void yosys_shutdown(); + #ifdef YOSYS_ENABLE_TCL #include -extern Tcl_Interp *yosys_get_tcl_interp(); +Tcl_Interp *yosys_get_tcl_interp(); #endif +extern int autoidx; +extern RTLIL::Design *yosys_design; + +RTLIL::IdString new_id(std::string file, int line, std::string func); + +#define NEW_ID \ + YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) + +RTLIL::Design *yosys_get_design(); +std::string proc_self_dirname(); +std::string proc_share_dirname(); +const char *create_prompt(RTLIL::Design *design, int recursion_counter); + +void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label); +void run_pass(std::string command, RTLIL::Design *design); +void run_backend(std::string filename, std::string command, RTLIL::Design *design); +void shell(RTLIL::Design *design); + // from kernel/version_*.o (cc source generated from Makefile) extern const char *yosys_version_str; -// implemented in driver.cc -extern RTLIL::Design *yosys_get_design(); -extern std::string proc_self_dirname(); -extern std::string proc_share_dirname(); -extern const char *create_prompt(RTLIL::Design *design, int recursion_counter); - // from passes/cmds/design.cc extern std::map saved_designs; extern std::vector pushed_designs; diff --git a/libs/subcircuit/subcircuit.cc b/libs/subcircuit/subcircuit.cc index da2638792..84f23d636 100644 --- a/libs/subcircuit/subcircuit.cc +++ b/libs/subcircuit/subcircuit.cc @@ -26,8 +26,8 @@ #include #ifdef _YOSYS_ -# include "kernel/log.h" -# define my_printf log +# include "kernel/yosys.h" +# define my_printf YOSYS_NAMESPACE_PREFIX log #else # define my_printf printf #endif diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index d2be7dcf1..d204e93c6 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -313,7 +313,7 @@ static void handle_loops() } std::stringstream sstr; - sstr << "$abcloop$" << (RTLIL::autoidx++); + sstr << "$abcloop$" << (autoidx++); RTLIL::Wire *wire = module->addWire(sstr.str()); bool first_line = true; @@ -400,7 +400,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, bool dff_mode, std::string clk_str, bool keepff) { module = current_module; - map_autoidx = RTLIL::autoidx++; + map_autoidx = autoidx++; signal_map.clear(); signal_list.clear(); diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index bd1ee68f2..79695c635 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -22,6 +22,8 @@ #include "kernel/rtlil.h" #include "kernel/log.h" +YOSYS_NAMESPACE_BEGIN + std::map saved_designs; std::vector pushed_designs; @@ -249,3 +251,5 @@ struct DesignPass : public Pass { } } DesignPass; +YOSYS_NAMESPACE_END + diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 6da468321..718f779b6 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -270,7 +270,7 @@ static void extract_fsm(RTLIL::Wire *wire) // create fsm cell - RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), RTLIL::autoidx++), "$fsm"); + RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm"); fsm_cell->set("\\CLK", clk); fsm_cell->set("\\ARST", arst); fsm_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity ? 1 : 0, 1); @@ -296,7 +296,7 @@ static void extract_fsm(RTLIL::Wire *wire) RTLIL::Cell *cell = module->cells_.at(cellport.first); RTLIL::SigSpec port_sig = assign_map(cell->get(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); - RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), RTLIL::autoidx++), unconn_sig.size()); + RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%s$%d", log_signal(unconn_sig), autoidx++), unconn_sig.size()); port_sig.replace(unconn_sig, RTLIL::SigSpec(unconn_wire), &cell->connections_[cellport.second]); } } diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc index 40c68abc1..aecb7bd6c 100644 --- a/passes/memory/memory_collect.cc +++ b/passes/memory/memory_collect.cc @@ -126,7 +126,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Memory *memory) } std::stringstream sstr; - sstr << "$mem$" << memory->name << "$" << (RTLIL::autoidx++); + sstr << "$mem$" << memory->name << "$" << (autoidx++); RTLIL::Cell *mem = module->addCell(sstr.str(), "$mem"); mem->parameters["\\MEMID"] = RTLIL::Const(memory->name); diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc index 325056170..6cbce781f 100644 --- a/passes/memory/memory_dff.cc +++ b/passes/memory/memory_dff.cc @@ -113,7 +113,7 @@ static void disconnect_dff(RTLIL::Module *module, RTLIL::SigSpec sig) sig.sort_and_unify(); std::stringstream sstr; - sstr << "$memory_dff_disconnected$" << (RTLIL::autoidx++); + sstr << "$memory_dff_disconnected$" << (autoidx++); RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size()); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 49291656c..0000bd507 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -41,7 +41,7 @@ static std::string genid(std::string name, std::string token1 = "", int i = -1, if (k >= 0) sstr << "[" << k << "]"; - sstr << token4 << "$" << (RTLIL::autoidx++); + sstr << token4 << "$" << (autoidx++); return sstr.str(); } diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc index cdf7db04b..3f675edea 100644 --- a/passes/memory/memory_unpack.cc +++ b/passes/memory/memory_unpack.cc @@ -31,7 +31,7 @@ static void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory) RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at("\\MEMID").decode_string()); while (module->memories.count(mem_name) != 0) - mem_name += stringf("_%d", RTLIL::autoidx++); + mem_name += stringf("_%d", autoidx++); RTLIL::Memory *mem = new RTLIL::Memory; mem->name = mem_name; diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index 91cafe3be..d894b442b 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -122,7 +122,7 @@ static void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::S } std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr"); cell->attributes = proc->attributes; @@ -144,7 +144,7 @@ static void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec bool clk_polarity, bool set_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec set, RTLIL::Process *proc) { std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::SigSpec sig_set_inv = mod->addWire(NEW_ID, sig_in.size()); RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size()); @@ -191,7 +191,7 @@ static void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_ bool clk_polarity, bool arst_polarity, RTLIL::SigSpec clk, RTLIL::SigSpec *arst, RTLIL::Process *proc) { std::stringstream sstr; - sstr << "$procdff$" << (RTLIL::autoidx++); + sstr << "$procdff$" << (autoidx++); RTLIL::Cell *cell = mod->addCell(sstr.str(), arst ? "$adff" : "$dff"); cell->attributes = proc->attributes; diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc index e7661245e..b18ce4925 100644 --- a/passes/proc/proc_mux.cc +++ b/passes/proc/proc_mux.cc @@ -57,7 +57,7 @@ static void extract_core_signal(const RTLIL::CaseRule *cs, RTLIL::SigSpec &sig) static RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector &compare, RTLIL::SwitchRule *sw) { std::stringstream sstr; - sstr << "$procmux$" << (RTLIL::autoidx++); + sstr << "$procmux$" << (autoidx++); RTLIL::Wire *cmp_wire = mod->addWire(sstr.str() + "_CMP", 0); @@ -127,7 +127,7 @@ static RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, log_assert(when_signal.size() == else_signal.size()); std::stringstream sstr; - sstr << "$procmux$" << (RTLIL::autoidx++); + sstr << "$procmux$" << (autoidx++); // the trivial cases if (compare.size() == 0 || when_signal == else_signal) diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index 19d323341..ed389f2fb 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -296,7 +296,7 @@ namespace SigSet> sig2port; // create new cell - RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), RTLIL::autoidx++), needle->name); + RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), autoidx++), needle->name); // create cell ports for (auto &it : needle->wires_) { diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 2aa59e61b..c2e5960ff 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -161,7 +161,7 @@ struct TechmapWorker for (auto &it : tpl->cells_) if (it.first == "\\_TECHMAP_REPLACE_") { orig_cell_name = cell->name; - module->rename(cell, stringf("$techmap%d", RTLIL::autoidx++) + cell->name); + module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name); break; } -- cgit v1.2.3 From e6d33513a5b809facc6e3e5e75d2248bfa94f82b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 14:11:39 +0200 Subject: Added module->design and cell->module, wire->module pointers --- frontends/ast/ast.cc | 10 ++--- frontends/ilang/parser.y | 4 +- frontends/liberty/liberty.cc | 4 +- frontends/verific/verific.cc | 4 +- 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 d548a679c..46b717ce0 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -936,7 +936,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str = (*it)->str.substr(1); if (defer) (*it)->str = "$abstract" + (*it)->str; - if (design->modules_.count((*it)->str)) { + if (design->has((*it)->str)) { if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); @@ -944,7 +944,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } - design->modules_[(*it)->str] = process_module(*it, defer); + design->add(process_module(*it, defer)); } } @@ -1041,10 +1041,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapmodules_.count(modname) == 0) { + if (!design->has(modname)) { new_ast->str = modname; - design->modules_[modname] = process_module(new_ast, false); - design->modules_[modname]->check(); + design->add(process_module(new_ast, false)); + design->module(modname)->check(); } else { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index ab763b2b1..67cc7da78 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -90,12 +90,12 @@ design: module: TOK_MODULE TOK_ID EOL { - if (current_design->modules_.count($2) != 0) + if (current_design->has($2)) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); current_module = new RTLIL::Module; current_module->name = $2; current_module->attributes = attrbuf; - current_design->modules_[$2] = current_module; + current_design->add(current_module); attrbuf.clear(); free($2); } module_body TOK_END { diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index da16ab33f..d3168ab8e 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -477,7 +477,7 @@ struct LibertyFrontend : public Frontend { std::string cell_name = RTLIL::escape_id(cell->args.at(0)); - if (design->modules_.count(cell_name)) { + if (design->has(cell_name)) { if (flag_ignore_redef) continue; log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); @@ -565,7 +565,7 @@ struct LibertyFrontend : public Frontend { } module->fixup_ports(); - design->modules_[module->name] = module; + design->add(module); cell_count++; skip_cell:; } diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6e692c5a1..c7b99c7a9 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -482,7 +482,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setIsOperator() ? std::string("$verific$") + nl->Owner()->Name() : RTLIL::escape_id(nl->Owner()->Name()); - if (design->modules_.count(module_name)) { + if (design->has(module_name)) { if (!nl->IsOperator()) log_cmd_error("Re-definition of module `%s'.\n", nl->Owner()->Name()); return; @@ -490,7 +490,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setname = module_name; - design->modules_[module->name] = module; + design->add(module); log("Importing module %s.\n", RTLIL::id2cstr(module->name)); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 82fa7aec2..9f10b5d82 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 4d8581c72..1163dccef 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 8da6bcd63..794f5c12c 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 8dc72c750..381b05871 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); - - 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)); + module->addMux(NEW_ID, a, a_inv, RTLIL::SigSpec(a, 3), y); - 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 4bcbc0131..e10cb109f 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 fc801f61f..be7758200 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 79695c635..41548f621 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 a1361c680..67b57a94d 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 84c6b9161..d0c9f4b5a 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 0f00e71a6..ffd9f1b62 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 ed389f2fb..060a87407 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) { -- cgit v1.2.3 From cd9407404a7bf3a5b8735af00c8f13ff97ac1495 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 14:34:12 +0200 Subject: 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 9f10b5d82..28de216cd 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 1163dccef..5107e5f2b 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; -- cgit v1.2.3 From b5a9e51b966abdfedc9309defa79b5141928e84a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 15:02:16 +0200 Subject: 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 9b36ebcc9..119e7e8a6 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 26c0ef8a9..b55af9958 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 e2f69e599..6f80ef72c 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 000000000..b4bc45c20 --- /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 + -- cgit v1.2.3 From cdae8abe16847c533171fed111beea7b52202cce Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 16:38:54 +0200 Subject: Renamed port access function on RTLIL::Cell, added param access functions --- 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 d167c3f4e..b31d6ce6f 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 43c036690..d8a542347 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 ab5316ec3..a445e9cc9 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 5826aea87..4bba32a63 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 0cc4f4c47..f4f82823b 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -61,10 +61,10 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size()); - cell->set("\\A", arg); + cell->setPort("\\A", arg); cell->parameters["\\Y_WIDTH"] = result_width; - cell->set("\\Y", wire); + cell->setPort("\\Y", wire); return wire; } @@ -95,10 +95,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed); cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size()); - cell->set("\\A", sig); + cell->setPort("\\A", sig); cell->parameters["\\Y_WIDTH"] = width; - cell->set("\\Y", wire); + cell->setPort("\\Y", wire); sig = wire; } @@ -127,11 +127,11 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size()); cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size()); - cell->set("\\A", left); - cell->set("\\B", right); + cell->setPort("\\A", left); + cell->setPort("\\B", right); cell->parameters["\\Y_WIDTH"] = result_width; - cell->set("\\Y", wire); + cell->setPort("\\Y", wire); return wire; } @@ -158,10 +158,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const cell->parameters["\\WIDTH"] = RTLIL::Const(left.size()); - cell->set("\\A", right); - cell->set("\\B", left); - cell->set("\\S", cond); - cell->set("\\Y", wire); + cell->setPort("\\A", right); + cell->setPort("\\B", left); + cell->setPort("\\S", cond); + cell->setPort("\\Y", wire); return wire; } @@ -1203,9 +1203,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); - cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); - cell->set("\\DATA", RTLIL::SigSpec(wire)); + cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->setPort("\\DATA", RTLIL::SigSpec(wire)); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1231,10 +1231,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while ((1 << addr_bits) < current_module->memories[str]->size) addr_bits++; - cell->set("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); - cell->set("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); - cell->set("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width)); - cell->set("\\EN", children[2]->genRTLIL()); + cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1)); + cell->setPort("\\ADDR", children[0]->genWidthRTLIL(addr_bits)); + cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width)); + cell->setPort("\\EN", children[2]->genRTLIL()); cell->parameters["\\MEMID"] = RTLIL::Const(str); cell->parameters["\\ABITS"] = RTLIL::Const(addr_bits); @@ -1271,8 +1271,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) cell->attributes[attr.first] = attr.second->asAttrConst(); } - cell->set("\\A", check); - cell->set("\\EN", en); + cell->setPort("\\A", check); + cell->setPort("\\EN", en); } break; @@ -1331,9 +1331,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (child->str.size() == 0) { char buf[100]; snprintf(buf, 100, "$%d", ++port_counter); - cell->set(buf, sig); + cell->setPort(buf, sig); } else { - cell->set(child->str, sig); + cell->setPort(child->str, sig); } continue; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index 67cc7da78..f696140eb 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -207,9 +207,9 @@ cell_body: delete $5; } | cell_body TOK_CONNECT TOK_ID sigspec EOL { - if (current_cell->has($3)) + if (current_cell->hasPort($3)) rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); - current_cell->set($3, *$4); + current_cell->setPort($3, *$4); delete $4; free($3); } | diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index d3168ab8e..72e370b94 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -56,36 +56,36 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->set("\\A", A); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_"); - cell->set("\\A", A); - cell->set("\\B", B); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\B", B); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_"); - cell->set("\\A", A); - cell->set("\\B", B); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\B", B); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B) { RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_"); - cell->set("\\A", A); - cell->set("\\B", B); - cell->set("\\Y", module->addWire(NEW_ID)); - return cell->get("\\Y"); + cell->setPort("\\A", A); + cell->setPort("\\B", B); + cell->setPort("\\Y", module->addWire(NEW_ID)); + return cell->getPort("\\Y"); } static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) @@ -241,18 +241,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->get("\\Y") == clk_sig) { - clk_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clk_sig) { + clk_sig = it.second->getPort("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { - clear_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { - preset_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -260,13 +260,13 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->set("\\A", iq_sig); - cell->set("\\Y", iqn_sig); + cell->setPort("\\A", iq_sig); + cell->setPort("\\Y", iqn_sig); cell = module->addCell(NEW_ID, ""); - cell->set("\\D", data_sig); - cell->set("\\Q", iq_sig); - cell->set("\\C", clk_sig); + cell->setPort("\\D", data_sig); + cell->setPort("\\Q", iq_sig); + cell->setPort("\\C", clk_sig); if (clear_sig.size() == 0 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'); @@ -274,18 +274,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) if (clear_sig.size() == 1 && preset_sig.size() == 0) { cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->set("\\R", clear_sig); + cell->setPort("\\R", clear_sig); } if (clear_sig.size() == 0 && preset_sig.size() == 1) { cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N'); - cell->set("\\R", preset_sig); + cell->setPort("\\R", preset_sig); } if (clear_sig.size() == 1 && preset_sig.size() == 1) { cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N'); - cell->set("\\S", preset_sig); - cell->set("\\R", clear_sig); + cell->setPort("\\S", preset_sig); + cell->setPort("\\R", clear_sig); } log_assert(!cell->type.empty()); @@ -318,18 +318,18 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->get("\\Y") == enable_sig) { - enable_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == enable_sig) { + enable_sig = it.second->getPort("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == clear_sig) { - clear_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->get("\\Y") == preset_sig) { - preset_sig = it.second->get("\\A"); + if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; } @@ -337,8 +337,8 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); - cell->set("\\A", iq_sig); - cell->set("\\Y", iqn_sig); + cell->setPort("\\A", iq_sig); + cell->setPort("\\Y", iqn_sig); if (clear_sig.size() == 1) { @@ -348,24 +348,24 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->set("\\A", clear_sig); - inv->set("\\Y", module->addWire(NEW_ID)); + inv->setPort("\\A", clear_sig); + inv->setPort("\\Y", module->addWire(NEW_ID)); if (clear_polarity == true) - clear_negative = inv->get("\\Y"); + clear_negative = inv->getPort("\\Y"); if (clear_polarity != enable_polarity) - clear_enable = inv->get("\\Y"); + clear_enable = inv->getPort("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_"); - data_gate->set("\\A", data_sig); - data_gate->set("\\B", clear_negative); - data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + data_gate->setPort("\\A", data_sig); + data_gate->setPort("\\B", clear_negative); + data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->set("\\A", enable_sig); - enable_gate->set("\\B", clear_enable); - enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + enable_gate->setPort("\\A", enable_sig); + enable_gate->setPort("\\B", clear_enable); + enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); } if (preset_sig.size() == 1) @@ -376,30 +376,30 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); - inv->set("\\A", preset_sig); - inv->set("\\Y", module->addWire(NEW_ID)); + inv->setPort("\\A", preset_sig); + inv->setPort("\\Y", module->addWire(NEW_ID)); if (preset_polarity == false) - preset_positive = inv->get("\\Y"); + preset_positive = inv->getPort("\\Y"); if (preset_polarity != enable_polarity) - preset_enable = inv->get("\\Y"); + preset_enable = inv->getPort("\\Y"); } RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_"); - data_gate->set("\\A", data_sig); - data_gate->set("\\B", preset_positive); - data_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + data_gate->setPort("\\A", data_sig); + data_gate->setPort("\\B", preset_positive); + data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_"); - enable_gate->set("\\A", enable_sig); - enable_gate->set("\\B", preset_enable); - enable_gate->set("\\Y", data_sig = module->addWire(NEW_ID)); + enable_gate->setPort("\\A", enable_sig); + enable_gate->setPort("\\B", preset_enable); + enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID)); } cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N')); - cell->set("\\D", data_sig); - cell->set("\\Q", iq_sig); - cell->set("\\E", enable_sig); + cell->setPort("\\D", data_sig); + cell->setPort("\\Q", iq_sig); + cell->setPort("\\E", enable_sig); } struct LibertyFrontend : public Frontend { diff --git a/kernel/consteval.h b/kernel/consteval.h index e5cae1022..529d8962d 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 28de216cd..012253144 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 5107e5f2b..796d45df1 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 ce2c90280..1ada1e16a 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 d204e93c6..4b2e82ca7 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 e10cb109f..1891a7450 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 62995a49d..e3fde8559 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 3e13fd4d4..30c80f732 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 5fce2d6cb..07c6150cc 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 a619cf57d..6025de15b 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 2da4794eb..670fae1d9 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 718f779b6..cf2075fba 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 8b9ad6be7..99b736c1b 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 9d9156ae3..bcaa89bf0 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 8f0e5d621..7a44dd452 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 d0c9f4b5a..2a47002ef 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 aecb7bd6c..8887d1952 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 6cbce781f..e92d726cc 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 0000bd507..f1917b972 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 b1629b7c4..b6e7cc835 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 3f675edea..68e9a9697 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 3e7487c39..5dab5ecab 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 de12542dc..2660b33d4 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 8aadd1f23..80ec89744 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 b01778b5e..c1e33caf3 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 ad6e1a746..26d19414a 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 676469fe2..f11b328f0 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 d894b442b..e69e8023d 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 b18ce4925..c00b00a2a 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 f2b89b000..25b9e1d11 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 ad304c723..7b9fb2072 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 ffd9f1b62..1475b855e 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 671a631dd..1041227ed 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 ffe241182..7712d18b9 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 060a87407..53bc00daf 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 a3261dccd..784c4cf31 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 10627cd12..194e06a4a 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 5c3e4c68f..f1f334f6e 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 4034f120e..946490135 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(); -- cgit v1.2.3 From c6fd82c70be33c566cdf312e3ad21401b5b8171b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 16:45:23 +0200 Subject: Fixed build of verific bindings --- frontends/verific/verific.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c7b99c7a9..30f452181 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -693,9 +693,9 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\TRANSPARENT"] = false; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->set("\\CLK", RTLIL::State::S0); - cell->set("\\ADDR", addr); - cell->set("\\DATA", data); + cell->setPort("\\CLK", RTLIL::State::S0); + cell->setPort("\\ADDR", addr); + cell->setPort("\\DATA", data); continue; } @@ -715,14 +715,14 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setparameters["\\PRIORITY"] = 0; cell->parameters["\\ABITS"] = SIZE(addr); cell->parameters["\\WIDTH"] = SIZE(data); - cell->set("\\EN", RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data))); - cell->set("\\CLK", RTLIL::State::S0); - cell->set("\\ADDR", addr); - cell->set("\\DATA", data); + cell->setPort("\\EN", RTLIL::SigSpec(net_map.at(inst->GetControl())).repeat(SIZE(data))); + cell->setPort("\\CLK", RTLIL::State::S0); + cell->setPort("\\ADDR", addr); + cell->setPort("\\DATA", data); if (inst->Type() == OPER_CLOCKED_WRITE_PORT) { cell->parameters["\\CLK_ENABLE"] = true; - cell->set("\\CLK", net_map.at(inst->GetClock())); + cell->setPort("\\CLK", net_map.at(inst->GetClock())); } continue; } @@ -755,15 +755,15 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setGetPort()->Bus()->LeftIndex(), pr->GetPort()->Bus()->RightIndex()); } RTLIL::SigSpec conn; - if (cell->has(RTLIL::escape_id(port_name))) - conn = cell->get(RTLIL::escape_id(port_name)); + if (cell->hasPort(RTLIL::escape_id(port_name))) + conn = cell->getPort(RTLIL::escape_id(port_name)); while (SIZE(conn) <= port_offset) { if (pr->GetPort()->GetDir() != DIR_IN) conn.append(module->addWire(NEW_ID, port_offset - SIZE(conn))); conn.append(RTLIL::State::Sz); } conn.replace(port_offset, net_map.at(pr->GetNet())); - cell->set(RTLIL::escape_id(port_name), conn); + cell->setPort(RTLIL::escape_id(port_name), conn); } } } -- cgit v1.2.3 From 069fe0db4265aeed23b37bec252e81308daf8c65 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 23:07:00 +0200 Subject: 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 4436be3de..40eff3d0e 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),;' \ -- cgit v1.2.3 From 62c8a7152551519d6e876319b1068a1987a14f3c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 23:14:17 +0200 Subject: Various cleanups in Makefile, Renamed default configurations --- Makefile | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 40eff3d0e..41569f6c1 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 -- cgit v1.2.3 From 32a1cc3efdad7953af1805b245f2a0292698633a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 23:30:18 +0200 Subject: Renamed modwalker.h to modtools.h --- kernel/modtools.h | 298 ++++++++++++++++++++++++++++++++++++++++++ kernel/modwalker.h | 298 ------------------------------------------ passes/memory/memory_share.cc | 11 +- passes/sat/share.cc | 11 +- 4 files changed, 310 insertions(+), 308 deletions(-) create mode 100644 kernel/modtools.h delete mode 100644 kernel/modwalker.h diff --git a/kernel/modtools.h b/kernel/modtools.h new file mode 100644 index 000000000..06e96246f --- /dev/null +++ b/kernel/modtools.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 MODTOOLS_H +#define MODTOOLS_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 diff --git a/kernel/modwalker.h b/kernel/modwalker.h deleted file mode 100644 index 09f815b83..000000000 --- a/kernel/modwalker.h +++ /dev/null @@ -1,298 +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 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 diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index b6e7cc835..fde6ea007 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 1041227ed..ea7a9f631 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 + -- cgit v1.2.3 From 03ef9a75c64f79596d6c931a1401184c33f9346b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 03:55:51 +0200 Subject: 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 f121089b1..844bcbc9c 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 781dc1671..2d97e46fd 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 -- cgit v1.2.3 From 5e641acc905a5c99d037378f6b7a481c43eb7de0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 03:57:37 +0200 Subject: 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 +++++++++++++++++++++ tests/hana/test_intermout_always_comb_1_test.v | 13 - tests/hana/test_intermout_always_comb_3_test.v | 10 - tests/hana/test_intermout_always_comb_4_test.v | 9 - tests/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 - tests/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 - tests/hana/test_intermout_exprs_binlogic_test.v | 13 - tests/hana/test_intermout_exprs_bitwiseneg_test.v | 5 - tests/hana/test_intermout_exprs_buffer_test.v | 9 - .../hana/test_intermout_exprs_condexpr_mux_test.v | 11 - .../test_intermout_exprs_condexpr_tribuf_test.v | 9 - tests/hana/test_intermout_exprs_const_test.v | 7 - tests/hana/test_intermout_exprs_constshift_test.v | 12 - tests/hana/test_intermout_exprs_div_test.v | 10 - tests/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 - tests/hana/test_intermout_exprs_unaryminus_test.v | 5 - tests/hana/test_intermout_exprs_unaryplus_test.v | 4 - tests/hana/test_intermout_exprs_varshift_test.v | 10 - tests/hana/test_parse2synthtrans.v | 117 ++++++ tests/hana/test_parse2synthtrans_behavopt_1_test.v | 22 -- tests/hana/test_parse2synthtrans_case_1_test.v | 26 -- .../hana/test_parse2synthtrans_contassign_1_test.v | 7 - .../test_parse2synthtrans_module_basic0_test.v | 2 - .../hana/test_parse2synthtrans_operators_1_test.v | 11 - tests/hana/test_parse2synthtrans_param_1_test.v | 7 - .../test_parse2synthtrans_port_scalar_1_test.v | 6 - .../test_parse2synthtrans_port_vector_1_test.v | 9 - ...arse2synthtrans_v2k_comb_logic_sens_list_test.v | 9 - tests/hana/test_parser.v | 87 +++++ .../test_parser_constructs_module_basic1_test.v | 2 - .../test_parser_constructs_param_basic0_test.v | 10 - .../hana/test_parser_constructs_port_basic0_test.v | 8 - .../test_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_always_31_tt.v | 50 --- 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 - tests/hana/test_simulation_decoder.v | 219 +++++++++++ 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_decoder_8_test.v | 76 ---- 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 - ...st_simulation_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 +++ tests/hana/test_simulation_shifter_left_16_test.v | 4 - tests/hana/test_simulation_shifter_left_32_test.v | 4 - tests/hana/test_simulation_shifter_left_4_test.v | 4 - tests/hana/test_simulation_shifter_left_64_test.v | 4 - tests/hana/test_simulation_shifter_left_8_test.v | 4 - tests/hana/test_simulation_shifter_right_16_test.v | 4 - tests/hana/test_simulation_shifter_right_32_test.v | 4 - tests/hana/test_simulation_shifter_right_4_test.v | 4 - tests/hana/test_simulation_shifter_right_64_test.v | 4 - tests/hana/test_simulation_shifter_right_8_test.v | 4 - tests/hana/test_simulation_sop.v | 65 ++++ tests/hana/test_simulation_sop_basic_10_test.v | 8 - tests/hana/test_simulation_sop_basic_11_test.v | 10 - tests/hana/test_simulation_sop_basic_12_test.v | 14 - tests/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 - tests/hana/test_simulation_techmap.v | 172 +++++++++ tests/hana/test_simulation_techmap_and_19_tech.v | 7 - tests/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 - tests/hana/test_simulation_techmap_mux_0_test.v | 8 - tests/hana/test_simulation_techmap_mux_128_test.v | 134 ------- tests/hana/test_simulation_techmap_mux_8_test.v | 14 - tests/hana/test_simulation_techmap_nand_19_tech.v | 11 - tests/hana/test_simulation_techmap_nand_2_tech.v | 11 - tests/hana/test_simulation_techmap_nand_5_tech.v | 11 - tests/hana/test_simulation_techmap_nor_19_tech.v | 11 - tests/hana/test_simulation_techmap_nor_2_tech.v | 11 - tests/hana/test_simulation_techmap_nor_5_tech.v | 11 - tests/hana/test_simulation_techmap_or_19_tech.v | 7 - tests/hana/test_simulation_techmap_or_5_tech.v | 3 - tests/hana/test_simulation_techmap_tech.v | 143 +++++++ tests/hana/test_simulation_techmap_xnor_2_tech.v | 6 - tests/hana/test_simulation_techmap_xnor_5_tech.v | 6 - tests/hana/test_simulation_techmap_xor_19_tech.v | 3 - tests/hana/test_simulation_techmap_xor_2_tech.v | 6 - tests/hana/test_simulation_techmap_xor_5_tech.v | 6 - tests/hana/test_simulation_tribuf_2_test.v | 3 - tests/hana/test_simulation_vlib.v | 65 ++++ 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 - 178 files changed, 1879 insertions(+), 1589 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 delete mode 100644 tests/hana/test_simulation_always_31_tt.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 create mode 100644 tests/hana/test_simulation_decoder.v 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 delete mode 100644 tests/hana/test_simulation_decoder_8_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 create mode 100644 tests/hana/test_simulation_techmap.v 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_128_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 create mode 100644 tests/hana/test_simulation_vlib.v 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 37049405d..b2a08fd47 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 410f9b4d7..d719c46bd 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 000000000..88b91ee4d --- /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 2d5abc4a6..000000000 --- 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 234407efd..000000000 --- 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 b0a94f299..000000000 --- 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 5152781df..000000000 --- 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 ed8630c37..000000000 --- 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 cac420a47..000000000 --- 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 669b2a5f9..000000000 --- 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 ad0a0df6e..000000000 --- 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 0f29ea0a4..000000000 --- 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 f1f13bbe7..000000000 --- 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 a83be20d1..000000000 --- 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 8e3d4222e..000000000 --- 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 853f1dc9a..000000000 --- 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 d4f3878d5..000000000 --- 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 7b651302a..000000000 --- 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 ec70f347b..000000000 --- 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 eec8c4b1a..000000000 --- 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 5b62bef09..000000000 --- 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 2b4cbc3ed..000000000 --- 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 11006e8b3..000000000 --- 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 5b778fe98..000000000 --- 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 484d81032..000000000 --- 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 eb21315d7..000000000 --- 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 21765fcdf..000000000 --- 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 b45b32b9c..000000000 --- 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 cea6b02d7..000000000 --- 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 f9973dadc..000000000 --- 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 35fdf73ac..000000000 --- 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 93fdb2e57..000000000 --- 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 06e3a8149..000000000 --- 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 ee3f229a8..000000000 --- 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 07be5b240..000000000 --- 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 2ca35c091..000000000 --- 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 000000000..a1c0bfdb8 --- /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 c825739c6..000000000 --- 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 348c566ad..000000000 --- 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 78bf00775..000000000 --- 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 67a272df0..000000000 --- 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 93b5691f3..000000000 --- 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 146eedf42..000000000 --- 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 8cdf495a0..000000000 --- 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 a740282b3..000000000 --- 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 50f1d3531..000000000 --- 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 000000000..c7305356a --- /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 67a272df0..000000000 --- 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 fd679230e..000000000 --- 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 8478e31da..000000000 --- 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 4a5d2345c..000000000 --- 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 8fe8e7bad..000000000 --- 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 099585b56..000000000 --- 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 50f1d3531..000000000 --- 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 000000000..3ee75313a --- /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 5c5fed5b6..000000000 --- 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 2d5abc4a6..000000000 --- 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 234407efd..000000000 --- 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 5152781df..000000000 --- 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 211369cb6..000000000 --- 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 6b3e861dc..000000000 --- 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 6c47b4bdf..000000000 --- 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 8d91f8154..000000000 --- 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 f1f13bbe7..000000000 --- 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 577378fd6..000000000 --- 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 55606832a..000000000 --- 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_always_31_tt.v b/tests/hana/test_simulation_always_31_tt.v deleted file mode 100644 index 299c0ca46..000000000 --- a/tests/hana/test_simulation_always_31_tt.v +++ /dev/null @@ -1,50 +0,0 @@ -module test(clk, cond, data); -input cond; -input clk; -output data; - -wire synth_net; -wire synth_net_0; -wire synth_net_1; -wire synth_net_2; - -wire synth_net_3; -wire synth_net_4; -wire synth_net_5; -wire synth_net_6; - -wire synth_net_7; -wire synth_net_8; -wire synth_net_9; -wire synth_net_10; - -wire synth_net_11; -wire tmp; -AND2 synth_AND(.in({synth_net_0, synth_net_1}), . - out(synth_net_2)); -AND2 synth_AND_0(.in({synth_net_3, synth_net_4}), .out( - synth_net_5)); -AND2 synth_AND_1(.in({synth_net_6, synth_net_7}), .out( - synth_net_8)); -AND2 synth_AND_2(.in({synth_net_9, synth_net_10}), .out( - synth_net_11)); -BUF synth_BUF(.in(synth_net), .out(synth_net_0)); -BUF - synth_BUF_0(.in(data), .out(synth_net_3)); -BUF synth_BUF_1(.in(synth_net_8) - , .out(tmp)); -BUF synth_BUF_2(.in(tmp), .out(synth_net_9)); -MUX2 synth_MUX(. - in({synth_net_2, synth_net_5}), .select(cond), .out(synth_net_6)); -MUX2 - synth_MUX_0(.in({synth_net_1, synth_net_4}), .select(cond), .out(synth_net_7 - )); -FF synth_FF(.d(synth_net_11), .clk(clk), .q(data)); -VCC synth_VCC(.out( - synth_net)); -VCC synth_VCC_0(.out(synth_net_1)); -VCC synth_VCC_1(.out( - synth_net_4)); -VCC synth_VCC_2(.out(synth_net_10)); -endmodule - diff --git a/tests/hana/test_simulation_and.v b/tests/hana/test_simulation_and.v new file mode 100644 index 000000000..480e733d1 --- /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 fba639ca8..000000000 --- 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 715bc7ca6..000000000 --- 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 74dccabf8..000000000 --- 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 48ed9102a..000000000 --- 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 29a355786..000000000 --- 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 ebce4eebf..000000000 --- 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 d394adad7..000000000 --- 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 000000000..d674b05ca --- /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 e9bb7f617..000000000 --- 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 9a3f5aa3a..000000000 --- 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 9bca426d1..000000000 --- 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.v b/tests/hana/test_simulation_decoder.v new file mode 100644 index 000000000..ef9045aad --- /dev/null +++ b/tests/hana/test_simulation_decoder.v @@ -0,0 +1,219 @@ + +// 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) + out = 64'b0000000000000000000000000000000000000000000000000000000000000000; + else begin + case (in) + 6'b000000 : out = 64'b0000000000000000000000000000000000000000000000000000000000000001; + 6'b000001 : out = 64'b0000000000000000000000000000000000000000000000000000000000000010; + 6'b000010 : out = 64'b0000000000000000000000000000000000000000000000000000000000000100; + 6'b000011 : out = 64'b0000000000000000000000000000000000000000000000000000000000001000; + 6'b000100 : out = 64'b0000000000000000000000000000000000000000000000000000000000010000; + 6'b000101 : out = 64'b0000000000000000000000000000000000000000000000000000000000100000; + 6'b000110 : out = 64'b0000000000000000000000000000000000000000000000000000000001000000; + 6'b000111 : out = 64'b0000000000000000000000000000000000000000000000000000000010000000; + 6'b001000 : out = 64'b0000000000000000000000000000000000000000000000000000000100000000; + 6'b001001 : out = 64'b0000000000000000000000000000000000000000000000000000001000000000; + 6'b001010 : out = 64'b0000000000000000000000000000000000000000000000000000010000000000; + 6'b001011 : out = 64'b0000000000000000000000000000000000000000000000000000100000000000; + 6'b001100 : out = 64'b0000000000000000000000000000000000000000000000000001000000000000; + 6'b001101 : out = 64'b0000000000000000000000000000000000000000000000000010000000000000; + 6'b001110 : out = 64'b0000000000000000000000000000000000000000000000000100000000000000; + 6'b001111 : out = 64'b0000000000000000000000000000000000000000000000001000000000000000; + 6'b010000 : out = 64'b0000000000000000000000000000000000000000000000010000000000000000; + 6'b010001 : out = 64'b0000000000000000000000000000000000000000000000100000000000000000; + 6'b010010 : out = 64'b0000000000000000000000000000000000000000000001000000000000000000; + 6'b010011 : out = 64'b0000000000000000000000000000000000000000000010000000000000000000; + 6'b010100 : out = 64'b0000000000000000000000000000000000000000000100000000000000000000; + 6'b010101 : out = 64'b0000000000000000000000000000000000000000001000000000000000000000; + 6'b010110 : out = 64'b0000000000000000000000000000000000000000010000000000000000000000; + 6'b010111 : out = 64'b0000000000000000000000000000000000000000100000000000000000000000; + 6'b011000 : out = 64'b0000000000000000000000000000000000000001000000000000000000000000; + 6'b011001 : out = 64'b0000000000000000000000000000000000000010000000000000000000000000; + 6'b011010 : out = 64'b0000000000000000000000000000000000000100000000000000000000000000; + 6'b011011 : out = 64'b0000000000000000000000000000000000001000000000000000000000000000; + 6'b011100 : out = 64'b0000000000000000000000000000000000010000000000000000000000000000; + 6'b011101 : out = 64'b0000000000000000000000000000000000100000000000000000000000000000; + 6'b011110 : out = 64'b0000000000000000000000000000000001000000000000000000000000000000; + 6'b011111 : out = 64'b0000000000000000000000000000000010000000000000000000000000000000; + + 6'b100000 : out = 64'b0000000000000000000000000000000100000000000000000000000000000000; + 6'b100001 : out = 64'b0000000000000000000000000000001000000000000000000000000000000000; + 6'b100010 : out = 64'b0000000000000000000000000000010000000000000000000000000000000000; + 6'b100011 : out = 64'b0000000000000000000000000000100000000000000000000000000000000000; + 6'b100100 : out = 64'b0000000000000000000000000001000000000000000000000000000000000000; + 6'b100101 : out = 64'b0000000000000000000000000010000000000000000000000000000000000000; + 6'b100110 : out = 64'b0000000000000000000000000100000000000000000000000000000000000000; + 6'b100111 : out = 64'b0000000000000000000000001000000000000000000000000000000000000000; + 6'b101000 : out = 64'b0000000000000000000000010000000000000000000000000000000000000000; + 6'b101001 : out = 64'b0000000000000000000000100000000000000000000000000000000000000000; + 6'b101010 : out = 64'b0000000000000000000001000000000000000000000000000000000000000000; + 6'b101011 : out = 64'b0000000000000000000010000000000000000000000000000000000000000000; + 6'b101100 : out = 64'b0000000000000000000100000000000000000000000000000000000000000000; + 6'b101101 : out = 64'b0000000000000000001000000000000000000000000000000000000000000000; + 6'b101110 : out = 64'b0000000000000000010000000000000000000000000000000000000000000000; + 6'b101111 : out = 64'b0000000000000000100000000000000000000000000000000000000000000000; + 6'b110000 : out = 64'b0000000000000001000000000000000000000000000000000000000000000000; + 6'b110001 : out = 64'b0000000000000010000000000000000000000000000000000000000000000000; + 6'b110010 : out = 64'b0000000000000100000000000000000000000000000000000000000000000000; + 6'b110011 : out = 64'b0000000000001000000000000000000000000000000000000000000000000000; + 6'b110100 : out = 64'b0000000000010000000000000000000000000000000000000000000000000000; + 6'b110101 : out = 64'b0000000000100000000000000000000000000000000000000000000000000000; + 6'b110110 : out = 64'b0000000001000000000000000000000000000000000000000000000000000000; + 6'b110111 : out = 64'b0000000010000000000000000000000000000000000000000000000000000000; + 6'b111000 : out = 64'b0000000100000000000000000000000000000000000000000000000000000000; + 6'b111001 : out = 64'b0000001000000000000000000000000000000000000000000000000000000000; + 6'b111010 : out = 64'b0000010000000000000000000000000000000000000000000000000000000000; + 6'b111011 : out = 64'b0000100000000000000000000000000000000000000000000000000000000000; + 6'b111100 : out = 64'b0001000000000000000000000000000000000000000000000000000000000000; + 6'b111101 : out = 64'b0010000000000000000000000000000000000000000000000000000000000000; + 6'b111110 : out = 64'b0100000000000000000000000000000000000000000000000000000000000000; + 6'b111111 : out = 64'b1000000000000000000000000000000000000000000000000000000000000000; + endcase + end +endmodule + 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 5bdf19717..000000000 --- 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 44f5de12b..000000000 --- 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 871a5bbfd..000000000 --- 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 497fa4bfd..000000000 --- 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 fd19ad609..000000000 --- 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 462e94199..000000000 --- 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_decoder_8_test.v b/tests/hana/test_simulation_decoder_8_test.v deleted file mode 100644 index 751d60f67..000000000 --- a/tests/hana/test_simulation_decoder_8_test.v +++ /dev/null @@ -1,76 +0,0 @@ -module test (input [5:0] in, input enable, output reg [63:0] out); - -always @(in or enable) - if(!enable) - out = 64'b0000000000000000000000000000000000000000000000000000000000000000; - else begin - case (in) - 6'b000000 : out = 64'b0000000000000000000000000000000000000000000000000000000000000001; - 6'b000001 : out = 64'b0000000000000000000000000000000000000000000000000000000000000010; - 6'b000010 : out = 64'b0000000000000000000000000000000000000000000000000000000000000100; - 6'b000011 : out = 64'b0000000000000000000000000000000000000000000000000000000000001000; - 6'b000100 : out = 64'b0000000000000000000000000000000000000000000000000000000000010000; - 6'b000101 : out = 64'b0000000000000000000000000000000000000000000000000000000000100000; - 6'b000110 : out = 64'b0000000000000000000000000000000000000000000000000000000001000000; - 6'b000111 : out = 64'b0000000000000000000000000000000000000000000000000000000010000000; - 6'b001000 : out = 64'b0000000000000000000000000000000000000000000000000000000100000000; - 6'b001001 : out = 64'b0000000000000000000000000000000000000000000000000000001000000000; - 6'b001010 : out = 64'b0000000000000000000000000000000000000000000000000000010000000000; - 6'b001011 : out = 64'b0000000000000000000000000000000000000000000000000000100000000000; - 6'b001100 : out = 64'b0000000000000000000000000000000000000000000000000001000000000000; - 6'b001101 : out = 64'b0000000000000000000000000000000000000000000000000010000000000000; - 6'b001110 : out = 64'b0000000000000000000000000000000000000000000000000100000000000000; - 6'b001111 : out = 64'b0000000000000000000000000000000000000000000000001000000000000000; - 6'b010000 : out = 64'b0000000000000000000000000000000000000000000000010000000000000000; - 6'b010001 : out = 64'b0000000000000000000000000000000000000000000000100000000000000000; - 6'b010010 : out = 64'b0000000000000000000000000000000000000000000001000000000000000000; - 6'b010011 : out = 64'b0000000000000000000000000000000000000000000010000000000000000000; - 6'b010100 : out = 64'b0000000000000000000000000000000000000000000100000000000000000000; - 6'b010101 : out = 64'b0000000000000000000000000000000000000000001000000000000000000000; - 6'b010110 : out = 64'b0000000000000000000000000000000000000000010000000000000000000000; - 6'b010111 : out = 64'b0000000000000000000000000000000000000000100000000000000000000000; - 6'b011000 : out = 64'b0000000000000000000000000000000000000001000000000000000000000000; - 6'b011001 : out = 64'b0000000000000000000000000000000000000010000000000000000000000000; - 6'b011010 : out = 64'b0000000000000000000000000000000000000100000000000000000000000000; - 6'b011011 : out = 64'b0000000000000000000000000000000000001000000000000000000000000000; - 6'b011100 : out = 64'b0000000000000000000000000000000000010000000000000000000000000000; - 6'b011101 : out = 64'b0000000000000000000000000000000000100000000000000000000000000000; - 6'b011110 : out = 64'b0000000000000000000000000000000001000000000000000000000000000000; - 6'b011111 : out = 64'b0000000000000000000000000000000010000000000000000000000000000000; - - 6'b100000 : out = 64'b0000000000000000000000000000000100000000000000000000000000000000; - 6'b100001 : out = 64'b0000000000000000000000000000001000000000000000000000000000000000; - 6'b100010 : out = 64'b0000000000000000000000000000010000000000000000000000000000000000; - 6'b100011 : out = 64'b0000000000000000000000000000100000000000000000000000000000000000; - 6'b100100 : out = 64'b0000000000000000000000000001000000000000000000000000000000000000; - 6'b100101 : out = 64'b0000000000000000000000000010000000000000000000000000000000000000; - 6'b100110 : out = 64'b0000000000000000000000000100000000000000000000000000000000000000; - 6'b100111 : out = 64'b0000000000000000000000001000000000000000000000000000000000000000; - 6'b101000 : out = 64'b0000000000000000000000010000000000000000000000000000000000000000; - 6'b101001 : out = 64'b0000000000000000000000100000000000000000000000000000000000000000; - 6'b101010 : out = 64'b0000000000000000000001000000000000000000000000000000000000000000; - 6'b101011 : out = 64'b0000000000000000000010000000000000000000000000000000000000000000; - 6'b101100 : out = 64'b0000000000000000000100000000000000000000000000000000000000000000; - 6'b101101 : out = 64'b0000000000000000001000000000000000000000000000000000000000000000; - 6'b101110 : out = 64'b0000000000000000010000000000000000000000000000000000000000000000; - 6'b101111 : out = 64'b0000000000000000100000000000000000000000000000000000000000000000; - 6'b110000 : out = 64'b0000000000000001000000000000000000000000000000000000000000000000; - 6'b110001 : out = 64'b0000000000000010000000000000000000000000000000000000000000000000; - 6'b110010 : out = 64'b0000000000000100000000000000000000000000000000000000000000000000; - 6'b110011 : out = 64'b0000000000001000000000000000000000000000000000000000000000000000; - 6'b110100 : out = 64'b0000000000010000000000000000000000000000000000000000000000000000; - 6'b110101 : out = 64'b0000000000100000000000000000000000000000000000000000000000000000; - 6'b110110 : out = 64'b0000000001000000000000000000000000000000000000000000000000000000; - 6'b110111 : out = 64'b0000000010000000000000000000000000000000000000000000000000000000; - 6'b111000 : out = 64'b0000000100000000000000000000000000000000000000000000000000000000; - 6'b111001 : out = 64'b0000001000000000000000000000000000000000000000000000000000000000; - 6'b111010 : out = 64'b0000010000000000000000000000000000000000000000000000000000000000; - 6'b111011 : out = 64'b0000100000000000000000000000000000000000000000000000000000000000; - 6'b111100 : out = 64'b0001000000000000000000000000000000000000000000000000000000000000; - 6'b111101 : out = 64'b0010000000000000000000000000000000000000000000000000000000000000; - 6'b111110 : out = 64'b0100000000000000000000000000000000000000000000000000000000000000; - 6'b111111 : out = 64'b1000000000000000000000000000000000000000000000000000000000000000; - endcase - end -endmodule - diff --git a/tests/hana/test_simulation_inc.v b/tests/hana/test_simulation_inc.v new file mode 100644 index 000000000..f8f548705 --- /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 7ff42ff50..000000000 --- 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 02bec2c27..000000000 --- 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 b96e05a2d..000000000 --- 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 5700d0ce7..000000000 --- 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 34940d63e..000000000 --- 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 c36d69f07..000000000 --- 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 75144a8e5..000000000 --- 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 000000000..085387eff --- /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 de4b6f8e9..000000000 --- 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 bc676c70b..000000000 --- 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 16de4d7f7..000000000 --- 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 6a112c6a9..000000000 --- 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 420239c6e..000000000 --- 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 f53a2c570..000000000 --- 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 000000000..5e6e0f1f5 --- /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 d8f34ee1f..000000000 --- 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 8926cebb9..000000000 --- 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 703a2de45..000000000 --- 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 adef3c903..000000000 --- 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 a2136f211..000000000 --- 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 000000000..d7d2bc0ec --- /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 df4e8bfaa..000000000 --- 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 2cfffc45f..000000000 --- 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 9f1ef8fec..000000000 --- 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 d8e685049..000000000 --- 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 a39b58b42..000000000 --- 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 000000000..9217db808 --- /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 bdfffd3d7..000000000 --- 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 291c8c765..000000000 --- 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 ad00c7084..000000000 --- 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 2ec57fa93..000000000 --- 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 f6a2d14d4..000000000 --- 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 ecd85c363..000000000 --- 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 000000000..eba4e88ea --- /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 5aac49c03..000000000 --- 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 f1d2b7b42..000000000 --- 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 000000000..8864fb0e7 --- /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 a57dac499..000000000 --- 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 672938ace..000000000 --- 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 c525401f1..000000000 --- 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 276a7c5a8..000000000 --- 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 c17277001..000000000 --- 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 6152adc06..000000000 --- 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 e910cdd6d..000000000 --- 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 608c196de..000000000 --- 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 c26d5938e..000000000 --- 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 a91c594e5..000000000 --- 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 000000000..79870cf0c --- /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 bc676c70b..000000000 --- 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 6a112c6a9..000000000 --- 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 f53a2c570..000000000 --- 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 03fc35b32..000000000 --- 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 81759c25d..000000000 --- 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 e9bb7f617..000000000 --- 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 a51ead0b2..000000000 --- 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 81759c25d..000000000 --- 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.v b/tests/hana/test_simulation_techmap.v new file mode 100644 index 000000000..88e24d0e7 --- /dev/null +++ b/tests/hana/test_simulation_techmap.v @@ -0,0 +1,172 @@ + +// 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) + 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]; + 64: out = in[64]; + 65: out = in[65]; + 66: out = in[66]; + 67: out = in[67]; + 68: out = in[68]; + 69: out = in[69]; + 70: out = in[70]; + 71: out = in[71]; + 72: out = in[72]; + 73: out = in[73]; + 74: out = in[74]; + 75: out = in[75]; + 76: out = in[76]; + 77: out = in[77]; + 78: out = in[78]; + 79: out = in[79]; + 80: out = in[80]; + 81: out = in[81]; + 82: out = in[82]; + 83: out = in[83]; + 84: out = in[84]; + 85: out = in[85]; + 86: out = in[86]; + 87: out = in[87]; + 88: out = in[88]; + 89: out = in[89]; + 90: out = in[90]; + 91: out = in[91]; + 92: out = in[92]; + 93: out = in[93]; + 94: out = in[94]; + 95: out = in[95]; + 96: out = in[96]; + 97: out = in[97]; + 98: out = in[98]; + 99: out = in[99]; + 100: out = in[100]; + 101: out = in[101]; + 102: out = in[102]; + 103: out = in[103]; + 104: out = in[104]; + 105: out = in[105]; + 106: out = in[106]; + 107: out = in[107]; + 108: out = in[108]; + 109: out = in[109]; + 110: out = in[110]; + 111: out = in[111]; + 112: out = in[112]; + 113: out = in[113]; + 114: out = in[114]; + 115: out = in[115]; + 116: out = in[116]; + 117: out = in[117]; + 118: out = in[118]; + 119: out = in[119]; + 120: out = in[120]; + 121: out = in[121]; + 122: out = in[122]; + 123: out = in[123]; + 124: out = in[124]; + 125: out = in[125]; + 126: out = in[126]; + 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 2491087cd..000000000 --- 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 6ec6a61c4..000000000 --- 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 e9bb7f617..000000000 --- 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 81759c25d..000000000 --- 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 bc676c70b..000000000 --- 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_128_test.v b/tests/hana/test_simulation_techmap_mux_128_test.v deleted file mode 100644 index 544c016a8..000000000 --- a/tests/hana/test_simulation_techmap_mux_128_test.v +++ /dev/null @@ -1,134 +0,0 @@ -module test(input [127:0] in, input [6: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]; - 64: out = in[64]; - 65: out = in[65]; - 66: out = in[66]; - 67: out = in[67]; - 68: out = in[68]; - 69: out = in[69]; - 70: out = in[70]; - 71: out = in[71]; - 72: out = in[72]; - 73: out = in[73]; - 74: out = in[74]; - 75: out = in[75]; - 76: out = in[76]; - 77: out = in[77]; - 78: out = in[78]; - 79: out = in[79]; - 80: out = in[80]; - 81: out = in[81]; - 82: out = in[82]; - 83: out = in[83]; - 84: out = in[84]; - 85: out = in[85]; - 86: out = in[86]; - 87: out = in[87]; - 88: out = in[88]; - 89: out = in[89]; - 90: out = in[90]; - 91: out = in[91]; - 92: out = in[92]; - 93: out = in[93]; - 94: out = in[94]; - 95: out = in[95]; - 96: out = in[96]; - 97: out = in[97]; - 98: out = in[98]; - 99: out = in[99]; - 100: out = in[100]; - 101: out = in[101]; - 102: out = in[102]; - 103: out = in[103]; - 104: out = in[104]; - 105: out = in[105]; - 106: out = in[106]; - 107: out = in[107]; - 108: out = in[108]; - 109: out = in[109]; - 110: out = in[110]; - 111: out = in[111]; - 112: out = in[112]; - 113: out = in[113]; - 114: out = in[114]; - 115: out = in[115]; - 116: out = in[116]; - 117: out = in[117]; - 118: out = in[118]; - 119: out = in[119]; - 120: out = in[120]; - 121: out = in[121]; - 122: out = in[122]; - 123: out = in[123]; - 124: out = in[124]; - 125: out = in[125]; - 126: out = in[126]; - 127: out = in[127]; - 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 f53a2c570..000000000 --- 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 6a119e1ee..000000000 --- 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 6a119e1ee..000000000 --- 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 6a119e1ee..000000000 --- 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 89fb2c7e8..000000000 --- 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 89fb2c7e8..000000000 --- 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 89fb2c7e8..000000000 --- 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 745d7b71c..000000000 --- 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 05c38b670..000000000 --- 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 000000000..60aeca5c1 --- /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 4eb05683f..000000000 --- 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 4eb05683f..000000000 --- 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 2042a0ad0..000000000 --- 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 4eb05683f..000000000 --- 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 4eb05683f..000000000 --- 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 1e82aaf04..000000000 --- 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_vlib.v b/tests/hana/test_simulation_vlib.v new file mode 100644 index 000000000..7d3af09c2 --- /dev/null +++ b/tests/hana/test_simulation_vlib.v @@ -0,0 +1,65 @@ +// 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; + +wire synth_net; +wire synth_net_0; +wire synth_net_1; +wire synth_net_2; + +wire synth_net_3; +wire synth_net_4; +wire synth_net_5; +wire synth_net_6; + +wire synth_net_7; +wire synth_net_8; +wire synth_net_9; +wire synth_net_10; + +wire synth_net_11; +wire tmp; +AND2 synth_AND(.in({synth_net_0, synth_net_1}), . + out(synth_net_2)); +AND2 synth_AND_0(.in({synth_net_3, synth_net_4}), .out( + synth_net_5)); +AND2 synth_AND_1(.in({synth_net_6, synth_net_7}), .out( + synth_net_8)); +AND2 synth_AND_2(.in({synth_net_9, synth_net_10}), .out( + synth_net_11)); +BUF synth_BUF(.in(synth_net), .out(synth_net_0)); +BUF + synth_BUF_0(.in(data), .out(synth_net_3)); +BUF synth_BUF_1(.in(synth_net_8) + , .out(tmp)); +BUF synth_BUF_2(.in(tmp), .out(synth_net_9)); +MUX2 synth_MUX(. + in({synth_net_2, synth_net_5}), .select(cond), .out(synth_net_6)); +MUX2 + synth_MUX_0(.in({synth_net_1, synth_net_4}), .select(cond), .out(synth_net_7 + )); +FF synth_FF(.d(synth_net_11), .clk(clk), .q(data)); +VCC synth_VCC(.out( + synth_net)); +VCC synth_VCC_0(.out(synth_net_1)); +VCC synth_VCC_1(.out( + synth_net_4)); +VCC synth_VCC_2(.out(synth_net_10)); +endmodule + diff --git a/tests/hana/test_simulation_xnor.v b/tests/hana/test_simulation_xnor.v new file mode 100644 index 000000000..7286d1341 --- /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 adc6ae5ca..000000000 --- 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 701bcc775..000000000 --- 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 a8c87cc62..000000000 --- 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 fa671ff93..000000000 --- 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 000000000..e181dd83a --- /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 f6447f817..000000000 --- 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 d94081df7..000000000 --- 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 cfa13187f..000000000 --- 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 be6cab633..000000000 --- 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 -- cgit v1.2.3 From 97a17d39e2f0088e02ed8496d905528722115674 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 15:25:42 +0200 Subject: Packed SigBit::data and SigBit::offset in a union --- kernel/rtlil.cc | 4 +++- kernel/rtlil.h | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 012253144..79ddd2e02 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 796d45df1..43c7e1050 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; - - 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) { } + union { + RTLIL::State data; + int offset; + }; + + 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 { -- cgit v1.2.3 From d13eb7e0999def2da03eb6ddef805145f7fd9c9a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 16:53:15 +0200 Subject: 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 0109faf62..9fc83800c 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 06e96246f..09f2ae65e 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 79ddd2e02..137058522 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 43c7e1050..0685f1ea2 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 b691749a8..32ef444aa 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 34800ce8e..671945631 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 119e7e8a6..d9db57c51 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 b4bc45c20..6a5ea346e 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 fde6ea007..ace6eeaf1 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; -- cgit v1.2.3 From 1e224506be6d824ea9ed1855fa46d039e5ffefd5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 18:42:10 +0200 Subject: 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 01ade7d46..273be7ce1 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 9fc83800c..8e46ad493 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 7469b3e81..4d204069c 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 17942ca96..93a3308ad 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); -- cgit v1.2.3 From bd74ed7da467de11128c57c4c424febe4a7e2f39 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 19:01:10 +0200 Subject: Replaced sha1 implementation --- frontends/ast/ast.cc | 29 +-- 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 46b717ce0..85b67b65e 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -979,10 +979,6 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map hash_data; - hash_data.insert(hash_data.end(), stripped_name.begin(), stripped_name.end()); - hash_data.push_back(0); - AstNode *new_ast = ast->clone(); int para_counter = 0; @@ -999,10 +995,6 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::mapstr.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); delete child->children.at(0); child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); - hash_data.insert(hash_data.end(), child->str.begin(), child->str.end()); - hash_data.push_back(0); - hash_data.insert(hash_data.end(), parameters[para_id].bits.begin(), parameters[para_id].bits.end()); - hash_data.push_back(0xff); parameters.erase(para_id); continue; } @@ -1018,28 +1010,11 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map 60) - { - unsigned char hash[20]; - unsigned char *hash_data2 = new unsigned char[hash_data.size()]; - for (size_t i = 0; i < hash_data.size(); i++) - hash_data2[i] = hash_data[i]; - sha1::calc(hash_data2, hash_data.size(), hash); - delete[] hash_data2; - - char hexstring[41]; - sha1::toHexString(hash, hexstring); - - modname = "$paramod$" + std::string(hexstring) + stripped_name; - } + else if (para_info.size() > 60) + modname = "$paramod$" + sha1(para_info) + stripped_name; else - { modname = "$paramod" + stripped_name + para_info; - } if (!design->has(modname)) { new_ast->str = modname; diff --git a/libs/sha1/sha1.cpp b/libs/sha1/sha1.cpp index fb7bfed6f..dc86b2ce2 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 540c156d1..15edee12e 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 0726e031f..8d3ed7430 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 9b6032edb..5215a6ca3 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 80ec89744..f947e9724 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 26d19414a..3532b124e 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 c2e5960ff..1f812e52f 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) -- cgit v1.2.3 From 75ffd1643c97321255bc591edf0c1a7097b8dce9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Aug 2014 19:43:28 +0200 Subject: Added logfile hash to statistics footer --- kernel/driver.cc | 68 ++++++++++++++++++++++++++++++-------------------------- kernel/log.cc | 36 ++++++++++++++++++++---------- kernel/log.h | 2 ++ kernel/yosys.cc | 16 +++++++++++-- kernel/yosys.h | 2 ++ 5 files changed, 79 insertions(+), 45 deletions(-) diff --git a/kernel/driver.cc b/kernel/driver.cc index 273be7ce1..6f9764238 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,43 +266,18 @@ int main(int argc, char **argv) if (!backend_command.empty()) run_backend(output_filename, backend_command, yosys_design); - delete yosys_design; - yosys_design = NULL; - -#ifdef COVER_ACTIVE - if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) - { - char filename_buffer[4096]; - 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, "a+"); - } - - if (f == NULL) - log_error("Can't create coverage file `%s'.\n", filename_buffer); - - log("\n", filename_buffer); - - for (auto &it : get_coverage_data()) - fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); - - fclose(f); - } -#endif - 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: xxxxxxxxxx, CPU: user %.2fs system %.2fs\n", + 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\nTime spent:", yosys_version_str); + log("%s\n", yosys_version_str); int64_t total_ns = 0; std::set> timedat; @@ -310,6 +289,7 @@ int main(int argc, char **argv) } 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(", ..."); @@ -321,6 +301,32 @@ int main(int argc, char **argv) log("%s\n", out_count ? "" : " no commands executed"); } +#ifdef COVER_ACTIVE + if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE")) + { + char filename_buffer[4096]; + 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, "a+"); + } + + if (f == NULL) + log_error("Can't create coverage file `%s'.\n", filename_buffer); + + log("\n", filename_buffer); + + for (auto &it : get_coverage_data()) + fprintf(f, "%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str()); + + fclose(f); + } +#endif + if (call_abort) abort(); diff --git a/kernel/log.cc b/kernel/log.cc index 64dd7a92a..10eb2563c 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) { - va_list aq; - va_copy(aq, ap); - vfprintf(f, format, aq); - va_end(aq); + for (auto f : log_files) + fputs(time_str.c_str(), f); } + + 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 8e46ad493..2e968039f 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 671945631..89a9cdf7f 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 d9db57c51..e90dcc46e 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); -- cgit v1.2.3 From 14412e6c957a34381c33740426b35f7b90a446be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 00:45:25 +0200 Subject: Preparations for RTLIL::IdString redesign: cleanup of existing code --- frontends/ast/ast.cc | 4 ++-- frontends/ast/simplify.cc | 2 +- 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 85b67b65e..5815fb0d4 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -325,7 +325,7 @@ void AstNode::dumpVlog(FILE *f, std::string indent) } for (auto &it : attributes) { - fprintf(f, "%s" "(* %s = ", indent.c_str(), id2vl(it.first).c_str()); + fprintf(f, "%s" "(* %s = ", indent.c_str(), id2vl(it.first.str()).c_str()); it.second->dumpVlog(f, ""); fprintf(f, " *)%s", indent.empty() ? "" : "\n"); } @@ -958,7 +958,7 @@ AstModule::~AstModule() // create a new parametric module (when needed) and return the name of the generated module RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map parameters) { - std::string stripped_name = name; + std::string stripped_name = name.str(); if (stripped_name.substr(0, 9) == "$abstract") stripped_name = stripped_name.substr(9); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index c51692f12..4d71bb394 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -465,7 +465,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, size_t pos = str.rfind('.'); if (pos == std::string::npos) log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n", - RTLIL::id2cstr(str.c_str()), filename.c_str(), linenum); + RTLIL::id2cstr(str), filename.c_str(), linenum); std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1); if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL) log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname), RTLIL::id2cstr(paraname), filename.c_str(), linenum); diff --git a/kernel/celltypes.h b/kernel/celltypes.h index e1a1110d3..993863827 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 10eb2563c..1595596ac 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 2e968039f..118ff69ba 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 0685f1ea2..b423b1bc9 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 89a9cdf7f..b5873d188 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 e90dcc46e..f9c1848ee 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 4b2e82ca7..196643578 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 67b4d939f..2a91bc9ea 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 41548f621..260e7b5d9 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 bbfa396ba..35ca2f474 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)) -- cgit v1.2.3 From b9bd22b8c8d46284fba4d4c1cbd09092a9ccc5c3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 13:11:01 +0200 Subject: More cleanups related to RTLIL::IdString usage --- 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 b31d6ce6f..ecde8b5a3 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 d8a542347..201be0cf5 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 49f719a4a..bf1efc4ae 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 4bba32a63..e3c930c8b 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 f4f82823b..bea99d8d4 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -48,7 +48,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); if (gen_attributes) @@ -82,7 +82,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); if (that != NULL) @@ -111,7 +111,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi RTLIL::Cell *cell = current_module->addCell(sstr.str(), type); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", result_width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); for (auto &attr : that->attributes) { @@ -146,7 +146,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_Y", left.size()); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size()); wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); for (auto &attr : that->attributes) { @@ -295,7 +295,7 @@ struct AST_INTERNAL::ProcessGenerator do { wire_name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, chunk.wire->name.c_str(), chunk.width+chunk.offset-1, chunk.offset);; - if (chunk.wire->name.find('$') != std::string::npos) + if (chunk.wire->name.str().find('$') != std::string::npos) wire_name += stringf("$%d", autoidx++); } while (current_module->wires_.count(wire_name) > 0); @@ -1196,7 +1196,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd"); cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); - RTLIL::Wire *wire = current_module->addWire(cell->name + "_DATA", current_module->memories[str]->width); + RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width); wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); int addr_bits = 1; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 137058522..af652a9d6 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 b423b1bc9..70e01b721 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -72,70 +72,43 @@ 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; - } - }; -#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(); + 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(); } }; -#endif - static inline std::string escape_id(std::string str) { if (str.size() > 0 && str[0] != '\\' && str[0] != '$') return "\\" + str; diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 5125ff5e2..aac117169 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 a2dd8051b..bbc0ff44f 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 07c6150cc..ca71f7d8d 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 6b1dbe13c..a3daf2398 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 6025de15b..5675dff50 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 f6f9faa9b..97ccf91ea 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 cf2075fba..5e71c1f0c 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 67b57a94d..28b4ad990 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 2a47002ef..89f45e025 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 8887d1952..471a7d53a 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 f1917b972..8dc66f2cd 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 68e9a9697..5a4c4eac9 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 4182c6f5d..c620531e3 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 5dab5ecab..a13bb09cb 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 c1e33caf3..bbf94d3b4 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 3532b124e..eb970329d 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 e4c526632..13be0ddb6 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 8a2dd929b..f07ad943c 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 25b9e1d11..affd685e4 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 430628e46..fd3d405a7 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 ea7a9f631..4484d6771 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 7712d18b9..16518b7df 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 53bc00daf..6ebac265c 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 f1f334f6e..960578b06 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 1f812e52f..2bcd3003e 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 844bcbc9c..d26002277 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"); -- cgit v1.2.3 From 97ad0623dfd772e8bea0728b439a8cd1f7493b7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 13:34:07 +0200 Subject: 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 70e01b721..daf888b79 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()); } -- cgit v1.2.3 From 60f3dc99237afc051560d18f38625337dc80ac80 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:11:35 +0200 Subject: 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 af652a9d6..80f63ce74 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 daf888b79..d95cf11f2 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; } -- cgit v1.2.3 From 8fd1c269ac7322f21408c1f99e7e4c275789c056 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:12:16 +0200 Subject: 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 f947e9724..5f3c4d29e 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); -- cgit v1.2.3 From e590ffc84dac1cb1ea833c5e7a71e958b63f7352 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:44:10 +0200 Subject: 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 1595596ac..f67d64c25 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 118ff69ba..037a62a3b 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 80f63ce74..9ee8123ff 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 d95cf11f2..9430da311 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 f9c1848ee..34777c9a4 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 } -- cgit v1.2.3 From 08392aad8f8e7c5bbcfa010c19786b1f318028b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 15:52:21 +0200 Subject: 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 f67d64c25..9cabc6a83 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 9430da311..7b989385e 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_; -- cgit v1.2.3 From 768eb846c4473040dc07bf62ce631c8a21474ae8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 16:03:18 +0200 Subject: More bugfixes related to new RTLIL::IdString --- frontends/ast/simplify.cc | 14 +++++++------- frontends/liberty/liberty.cc | 18 +++++++++--------- 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 4d71bb394..694f1d4d8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -465,10 +465,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, size_t pos = str.rfind('.'); if (pos == std::string::npos) log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n", - RTLIL::id2cstr(str), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1); if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL) - log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname), RTLIL::id2cstr(paraname), filename.c_str(), linenum); + log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paraname).c_str(), filename.c_str(), linenum); AstNode *cell = current_scope.at(modname), *paraset = clone(); cell->children.insert(cell->children.begin() + 1, paraset); paraset->type = AST_PARASET; @@ -1306,7 +1306,7 @@ skip_dynamic_range_lvalue_expansion:; { if (children.size() != 1) log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", - RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); AstNode *buf = children[0]->clone(); while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } @@ -1336,18 +1336,18 @@ skip_dynamic_range_lvalue_expansion:; if (func_with_two_arguments) { if (children.size() != 2) log_error("System function %s got %d arguments, expected 2 at %s:%d.\n", - RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); } else { if (children.size() != 1) log_error("System function %s got %d arguments, expected 1 at %s:%d.\n", - RTLIL::id2cstr(str), int(children.size()), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum); } if (children.size() >= 1) { while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (!children[0]->isConst()) log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", - RTLIL::id2cstr(str), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; children[0]->detectSignWidth(child_width_hint, child_sign_hint); @@ -1358,7 +1358,7 @@ skip_dynamic_range_lvalue_expansion:; while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (!children[1]->isConst()) log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n", - RTLIL::id2cstr(str), filename.c_str(), linenum); + RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; children[1]->detectSignWidth(child_width_hint, child_sign_hint); diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 72e370b94..504b8d1e4 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -47,7 +47,7 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& std::string id = RTLIL::escape_id(std::string(expr, id_len)); if (!module->wires_.count(id)) - log_error("Can't resolve wire name %s.\n", RTLIL::id2cstr(id)); + log_error("Can't resolve wire name %s.\n", RTLIL::unescape_id(id).c_str()); expr += id_len; return module->wires_.at(id); @@ -234,7 +234,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } if (clk_sig.size() == 0 || data_sig.size() == 0) - log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", RTLIL::id2cstr(module->name)); + log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", log_id(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) { @@ -311,7 +311,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } if (enable_sig.size() == 0 || data_sig.size() == 0) - log_error("Latch cell %s has no data_in and/or enable attribute.\n", RTLIL::id2cstr(module->name)); + log_error("Latch cell %s has no data_in and/or enable attribute.\n", log_id(module->name)); for (bool rerun_invert_rollback = true; rerun_invert_rollback;) { @@ -480,10 +480,10 @@ struct LibertyFrontend : public Frontend { if (design->has(cell_name)) { if (flag_ignore_redef) continue; - log_error("Duplicate definition of cell/module %s.\n", RTLIL::id2cstr(cell_name)); + log_error("Duplicate definition of cell/module %s.\n", RTLIL::unescape_id(cell_name).c_str()); } - // log("Processing cell type %s.\n", RTLIL::id2cstr(cell_name)); + // log("Processing cell type %s.\n", RTLIL::unescape_id(cell_name).c_str()); RTLIL::Module *module = new RTLIL::Module; module->name = cell_name; @@ -501,9 +501,9 @@ struct LibertyFrontend : public Frontend { { if (!flag_ignore_miss_dir) { - log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), RTLIL::id2cstr(module->name)); + log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), log_id(module->name)); } else { - log("Ignoring cell %s with missing or invalid direction for pin %s.\n", RTLIL::id2cstr(module->name), node->args.at(0).c_str()); + log("Ignoring cell %s with missing or invalid direction for pin %s.\n", log_id(module->name), node->args.at(0).c_str()); delete module; goto skip_cell; } @@ -551,9 +551,9 @@ struct LibertyFrontend : public Frontend { { if (!flag_ignore_miss_func) { - log_error("Missing function on output %s of cell %s.\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name)); + log_error("Missing function on output %s of cell %s.\n", log_id(wire->name), log_id(module->name)); } else { - log("Ignoring cell %s with missing function on output %s.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(wire->name)); + log("Ignoring cell %s with missing function on output %s.\n", log_id(module->name), log_id(wire->name)); delete module; goto skip_cell; } diff --git a/kernel/log.cc b/kernel/log.cc index 9cabc6a83..01f6207ec 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 7b989385e..6529603eb 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 b5873d188..dff31db07 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 35ca2f474..b4f4d26ae 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 28b4ad990..50b4989df 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 1475b855e..e51c92f9f 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 6ebac265c..06af2923b 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 2bcd3003e..374fa9bf2 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(); -- cgit v1.2.3 From 04727c7e0fb4c00b38999da192e4ada2a6f9474a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 18:58:40 +0200 Subject: 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 ecde8b5a3..5daab6691 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 201be0cf5..a81d8f159 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 bf1efc4ae..ecdfaabfc 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 a445e9cc9..be0086ffd 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 01f6207ec..81cc26da3 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 4d204069c..868dbb949 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 9ee8123ff..2838449bb 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 6529603eb..502969a1f 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 196643578..77419e616 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 260e7b5d9..9f800c31f 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 b4f4d26ae..2d49e85ed 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 bbc0ff44f..cbc4725f7 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 97ccf91ea..cb762dc1a 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 471a7d53a..9c670f00f 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 06af2923b..985d51e50 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 374fa9bf2..c639cc48d 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; } -- cgit v1.2.3 From 8e7361f128ce00a742412931efcf7cbe5795a39a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 19:08:02 +0200 Subject: 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 2838449bb..56c631f3b 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 502969a1f..ab15024e0 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 affd685e4..e856fdf76 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; } -- cgit v1.2.3 From b6acbc82e6a2954d453188a9997da2a30731ddac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 20:54:30 +0200 Subject: 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 56c631f3b..792474af4 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 c639cc48d..74a515506 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); -- cgit v1.2.3 From ca1b5d50e0e577a88ae265b71679b81e71980db8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:10:08 +0200 Subject: 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 e3c930c8b..c691eae60 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++) { -- cgit v1.2.3 From 88cf00ce7874ec7951b09d85e959dd2c6ed261b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:54:02 +0200 Subject: 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 c691eae60..605616b31 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" : ""); -- cgit v1.2.3 From bc947d4c7b9b7691e2aeab608c78c4658314cec2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:54:30 +0200 Subject: 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 81cc26da3..09673dc2e 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); } -- cgit v1.2.3 From 08ec33a5e573e0a59d2c1375e4e302a8485a6302 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 2 Aug 2014 21:55:13 +0200 Subject: 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 74a515506..4a9a78918 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); -- cgit v1.2.3 From 9bb5298c104e83fef52d345772175be40301c7e3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 12:40:23 +0200 Subject: 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 cbc4725f7..c15feb7b5 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()) -- cgit v1.2.3 From 014a41fcf3463fae881413b4b366c2c2a6fb20de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 12:40:43 +0200 Subject: 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 4a9a78918..29ce96766 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 54652868a..7f3855ce8 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; -- cgit v1.2.3 From 75423169c59022b3680aa3bf7de0877bc43a8082 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 14:59:13 +0200 Subject: 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 34777c9a4..f9bbc0e44 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(); -- cgit v1.2.3 From 653edd7a2f857d09bd8cecc48cc9ac76aea33098 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 15:00:38 +0200 Subject: 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 09f2ae65e..56bc1882d 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 -- cgit v1.2.3 From 0b02f6ca30a7bb5c3c8c34908aab8b8aa821c113 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 15:02:05 +0200 Subject: 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 b55af9958..d6e45f2d1 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 000000000..39881a831 --- /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 + -- cgit v1.2.3 From 027376515ac56251c82eedd961a9ffb2cc15a5a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 20:02:42 +0200 Subject: 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 39881a831..bd0b315e7 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++) { -- cgit v1.2.3 From 358bf70a2111d476d9d209f216fdd087356ec0d9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 20:03:16 +0200 Subject: 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 e3b4bc969..a06a642d8 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 2d97e46fd..9ae1c1555 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 da2211624..67cfe44e8 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 -- cgit v1.2.3 From c7f99be3be828606cafc7d35b3612f5344065736 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 3 Aug 2014 20:19:50 +0200 Subject: 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 4484d6771..0c88b4d3c 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(); } -- cgit v1.2.3 From ebbbe7fc8360ca0bd8f840d3df1b77ab2fb569b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:08:35 +0200 Subject: 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 ab15024e0..8dfcbcaa0 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 bd0b315e7..9cef14f48 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(); -- cgit v1.2.3 From b5a3419ac2c6f367b90f062c4e2252029910cdb9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:19:24 +0200 Subject: Added support for non-standard "module mod_name(...);" syntax --- README | 5 +++++ frontends/verilog/parser.y | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/README b/README index 1e0ade91c..63d692297 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 c62e761e2..1e0168a5f 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -55,6 +55,7 @@ namespace VERILOG_FRONTEND { struct AstNode *current_ast, *current_ast_mod; int current_function_or_task_port_id; std::vector case_type_stack; + bool do_not_require_port_stubs; bool default_nettype_wire; bool sv_mode; } @@ -210,6 +211,7 @@ hierarchical_id: module: attr TOK_MODULE TOK_ID { + do_not_require_port_stubs = false; AstNode *mod = new AstNode(AST_MODULE); current_ast->children.push_back(mod); current_ast_mod = mod; @@ -244,7 +246,8 @@ single_module_para: }; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')'; + '(' ')' | /* empty */ | '(' module_args optional_comma ')' | + '(' '.' '.' '.' ')' { do_not_require_port_stubs = true; }; module_args: module_arg | module_args ',' module_arg; @@ -582,6 +585,9 @@ wire_name: node->children.push_back($2); } if (current_function_or_task == NULL) { + if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) { + port_stubs[*$1] = ++port_counter; + } if (port_stubs.count(*$1) != 0) { if (!node->is_input && !node->is_output) frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $1->c_str()); -- cgit v1.2.3 From 0bb694221832f250977437f29365bc5e17c4cd09 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:33:51 +0200 Subject: 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 c15feb7b5..4f6b811bc 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) -- cgit v1.2.3 From 0129d41efad623ee95878a673c1c1190261ba3ef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 08:35:51 +0200 Subject: Fixed AST handling of variables declared inside a functions main block --- frontends/ast/simplify.cc | 6 +++--- 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 694f1d4d8..20edc1739 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1460,7 +1460,6 @@ skip_dynamic_range_lvalue_expansion:; } for (auto child : decl->children) - { if (child->type == AST_WIRE) { AstNode *wire = child->clone(); @@ -1488,7 +1487,9 @@ skip_dynamic_range_lvalue_expansion:; } } } - else + + for (auto child : decl->children) + if (child->type != AST_WIRE) { AstNode *stmt = child->clone(); stmt->replace_ids(replace_rules); @@ -1500,7 +1501,6 @@ skip_dynamic_range_lvalue_expansion:; break; } } - } replace_fcall_with_id: if (type == AST_FCALL) { diff --git a/tests/simple/task_func.v b/tests/simple/task_func.v index 8dbc90c56..51e31015f 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 -- cgit v1.2.3 From 91dd87e60b120119ee34a9961a7b5f33f340282e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 12:15:53 +0200 Subject: Improved scope resolution of local regs in Verilog+AST frontend --- frontends/ast/ast.h | 2 +- frontends/ast/simplify.cc | 31 ++++++++++++++++++----- frontends/verilog/parser.y | 3 +-- 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 83798edf0..00b044bc4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -200,7 +200,7 @@ namespace AST // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); void expand_genblock(std::string index_var, std::string prefix, std::map &name_map); - void replace_ids(std::map &rules); + void replace_ids(const std::string &prefix, const std::map &rules); void mem2reg_as_needed_pass1(std::map> &mem2reg_places, std::map &mem2reg_flags, std::map &proc_flags, uint32_t &status_flags); void mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode *mod, AstNode *block); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 20edc1739..29d00be96 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -794,6 +794,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (children[i]->type == AST_WIRE) { children[i]->simplify(false, false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); + current_scope[children[i]->str] = children[i]; } else new_children.push_back(children[i]); @@ -1492,7 +1493,7 @@ skip_dynamic_range_lvalue_expansion:; if (child->type != AST_WIRE) { AstNode *stmt = child->clone(); - stmt->replace_ids(replace_rules); + stmt->replace_ids(prefix, replace_rules); for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { if (*it != current_block_child) @@ -1855,12 +1856,30 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma } // rename stuff (used when tasks of functions are instanciated) -void AstNode::replace_ids(std::map &rules) +void AstNode::replace_ids(const std::string &prefix, const std::map &rules) { - if (type == AST_IDENTIFIER && rules.count(str) > 0) - str = rules[str]; - for (auto child : children) - child->replace_ids(rules); + if (type == AST_BLOCK) + { + std::map new_rules = rules; + std::string new_prefix = prefix + str; + + for (auto child : children) + if (child->type == AST_WIRE) { + new_rules[child->str] = new_prefix + child->str; + child->str = new_prefix + child->str; + } + + for (auto child : children) + if (child->type != AST_WIRE) + child->replace_ids(new_prefix, new_rules); + } + else + { + if (type == AST_IDENTIFIER && rules.count(str) > 0) + str = rules.at(str); + for (auto child : children) + child->replace_ids(prefix, rules); + } } // helper function for mem2reg_as_needed_pass1 diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 1e0168a5f..26e2ddc34 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -599,12 +599,11 @@ wire_name: if (node->is_input || node->is_output) frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str()); } - ast_stack.back()->children.push_back(node); } else { if (node->is_input || node->is_output) node->port_id = current_function_or_task_port_id++; - current_function_or_task->children.push_back(node); } + ast_stack.back()->children.push_back(node); delete $1; }; diff --git a/tests/simple/scopes.v b/tests/simple/scopes.v new file mode 100644 index 000000000..eecc1a0b2 --- /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 -- cgit v1.2.3 From 1c182cedb7a42174d6eafbbc84951a27775da15d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 12:49:53 +0200 Subject: 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 9cef14f48..b90843ef9 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); -- cgit v1.2.3 From d3b1a29708fc9cfd793180763484125a5f978d1a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 13:11:04 +0200 Subject: Cleanups and improvements in wreduce pass --- passes/cmds/wreduce.cc | 124 ++++++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 47 deletions(-) diff --git a/passes/cmds/wreduce.cc b/passes/cmds/wreduce.cc index b90843ef9..ce24e09b2 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); + 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)); + } - cell->setPort("\\A", new_sig_a); - cell->setPort("\\B", new_sig_b); - cell->setPort("\\Y", new_sig_y); - cell->fixup_parameters(); + for (auto bit : new_work_queue_bits) + work_queue_bits.insert(bit); - module->connect(sig_y.extract(n_kept, n_removed), sig_removed); - } + 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) { + bool did_something = false; + if (!cell->type.in(config->supported_cell_types)) - return; + return false; + + if (cell->type.in("$mux", "$pmux", "$safe_pmux")) + return run_cell_mux(cell); + - if (cell->type.in("$mux", "$pmux", "$safe_pmux")) { - run_cell_mux(cell); - return; + // 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 (max_port_b_size >= 0) + did_something = run_reduce_inport(cell, 'B', max_port_b_size) || did_something; - if (cell->hasParam("\\A_SIGNED")) - run_reduce_inport(cell, 'A'); - 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) -- cgit v1.2.3 From 523df7314502e2674df5287289dcf8eb204c17ac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 14:47:03 +0200 Subject: 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 56bc1882d..fde59d142 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 792474af4..8ff564515 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 8dfcbcaa0..8ec599417 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 ce24e09b2..27571eb0d 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) -- cgit v1.2.3 From 5b3dc07b9a571771afbe356e30046633037b9814 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 16:53:53 +0200 Subject: 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 27571eb0d..1d296da54 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++; } -- cgit v1.2.3 From 2501abe1ee47610e5fb2b541c1fc0c648617da20 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 19:01:41 +0200 Subject: 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 1d296da54..6723a57fe 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) -- cgit v1.2.3 From b4f10e342cf400bd2f392a588f28de069ba0f9d8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Aug 2014 14:31:38 +0200 Subject: 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 e92d726cc..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; -- cgit v1.2.3 From d259abbda2b9d568228dc8d0bed2d0b0d88d7b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Aug 2014 15:43:46 +0200 Subject: Added AST_MULTIRANGE (arrays with more than 1 dimension) --- 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 63d692297..0c8425f37 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 5815fb0d4..f18124e28 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -78,6 +78,7 @@ std::string AST::type2str(AstNodeType type) X(AST_PARASET) X(AST_ARGUMENT) X(AST_RANGE) + X(AST_MULTIRANGE) X(AST_CONSTANT) X(AST_REALVALUE) X(AST_CELLTYPE) @@ -284,6 +285,12 @@ void AstNode::dumpAst(FILE *f, std::string indent) fprintf(f, " int=%u", (int)integer); if (realvalue != 0) fprintf(f, " real=%e", realvalue); + if (!multirange_dimensions.empty()) { + fprintf(f, " multirange=["); + for (int v : multirange_dimensions) + fprintf(f, " %d", v); + fprintf(f, " ]"); + } fprintf(f, "\n"); for (auto &it : attributes) { diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 00b044bc4..5fb1f0a73 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -56,6 +56,7 @@ namespace AST AST_PARASET, AST_ARGUMENT, AST_RANGE, + AST_MULTIRANGE, AST_CONSTANT, AST_REALVALUE, AST_CELLTYPE, @@ -158,6 +159,9 @@ namespace AST uint32_t integer; double realvalue; + // if this is a multirange memory then this vector contains offset and length of each dimension + std::vector multirange_dimensions; + // this is set by simplify and used during RTLIL generation AstNode *id2ast; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 29d00be96..39c472621 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -553,6 +553,56 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } + // resolve multiranges on memory decl + if (type == AST_MEMORY && children.size() > 1 && children[1]->type == AST_MULTIRANGE) + { + int total_size = 1; + multirange_dimensions.clear(); + for (auto range : children[1]->children) { + if (!range->range_valid) + log_error("Non-constant range on memory decl at %s:%d.\n", filename.c_str(), linenum); + multirange_dimensions.push_back(std::min(range->range_left, range->range_right)); + multirange_dimensions.push_back(std::max(range->range_left, range->range_right) - std::min(range->range_left, range->range_right) + 1); + total_size *= multirange_dimensions.back(); + } + delete children[1]; + children[1] = new AstNode(AST_RANGE, AstNode::mkconst_int(0, true), AstNode::mkconst_int(total_size-1, true)); + did_something = true; + } + + // resolve multiranges on memory access + if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY && children.size() > 0 && children[0]->type == AST_MULTIRANGE) + { + AstNode *index_expr = nullptr; + + for (int i = 0; 2*i < SIZE(id2ast->multirange_dimensions); i++) + { + if (SIZE(children[0]->children) < i) + log_error("Insufficient number of array indices for %s at %s:%d.\n", log_id(str), filename.c_str(), linenum); + + AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone(); + + if (id2ast->multirange_dimensions[2*i]) + new_index_expr = new AstNode(AST_SUB, new_index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i], true)); + + if (i == 0) + index_expr = new_index_expr; + else + index_expr = new AstNode(AST_ADD, new AstNode(AST_MUL, index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i-1], true)), new_index_expr); + } + + for (int i = SIZE(id2ast->multirange_dimensions)/1; i < SIZE(children[0]->children); i++) + children.push_back(children[0]->children[i]->clone()); + + delete children[0]; + if (index_expr == nullptr) + children.erase(children.begin()); + else + children[0] = new AstNode(AST_RANGE, index_expr); + + did_something = true; + } + // trim/extend parameters if (type == AST_PARAMETER || type == AST_LOCALPARAM) { if (children.size() > 1 && children[1]->type == AST_RANGE) { @@ -1166,7 +1216,7 @@ skip_dynamic_range_lvalue_expansion:; if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 && children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid && - (children[0]->children.size() == 1 || children[0]->children.size() == 2)) + (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE) { std::stringstream sstr; sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++); diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 26e2ddc34..95d7f3935 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -112,7 +112,8 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY -%type wire_type range non_opt_range range_or_signed_int expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int +%type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -361,6 +362,15 @@ non_opt_range: $$->children.push_back($2); }; +non_opt_multirange: + non_opt_range non_opt_range { + $$ = new AstNode(AST_MULTIRANGE, $1, $2); + } | + non_opt_multirange non_opt_range { + $$ = $1; + $$->children.push_back($2); + }; + range: non_opt_range { $$ = $1; @@ -369,6 +379,10 @@ range: $$ = NULL; }; +range_or_multirange: + range { $$ = $1; } | + non_opt_multirange { $$ = $1; }; + range_or_signed_int: range { $$ = $1; @@ -566,7 +580,7 @@ wire_name_and_opt_assign: }; wire_name: - TOK_ID range { + TOK_ID range_or_multirange { AstNode *node = astbuf1->clone(); node->str = *$1; append_attr_clone(node, albuf); @@ -1007,8 +1021,8 @@ rvalue: $$->str = *$1; delete $1; } | - hierarchical_id non_opt_range non_opt_range { - $$ = new AstNode(AST_IDENTIFIER, $2, $3); + hierarchical_id non_opt_multirange { + $$ = new AstNode(AST_IDENTIFIER, $2); $$->str = *$1; delete $1; }; -- cgit v1.2.3 From 312ee00c9e279a91f336acef26dd064c25f42ed5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:14:38 +0200 Subject: 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 2be27b920..461c1cb44 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 000000000..86744d415 --- /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 -- cgit v1.2.3 From 2dc33337346ea53a654af3d80bdf056c7ccfa43c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:41:27 +0200 Subject: Also allow "module foobar(input foo, output bar, ...);" syntax --- frontends/verilog/parser.y | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 95d7f3935..f619d3c2b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -247,8 +247,7 @@ single_module_para: }; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')' | - '(' '.' '.' '.' ')' { do_not_require_port_stubs = true; }; + '(' ')' | /* empty */ | '(' module_args optional_comma ')'; module_args: module_arg | module_args ',' module_arg; @@ -297,7 +296,10 @@ module_arg: ast_stack.back()->children.push_back(node); append_attr(node, $1); delete $4; - } module_arg_opt_assignment; + } module_arg_opt_assignment | + '.' '.' '.' { + do_not_require_port_stubs = true; + }; wire_type: { -- cgit v1.2.3 From c55eb8f8a6c83514c5d46c6992c6c6fa1069a889 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:42:35 +0200 Subject: 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 e51c92f9f..b3adefb92 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) -- cgit v1.2.3 From 0b8b8d41eb07fd048cbe68acfe4b724e314bbb41 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 22:37:01 +0200 Subject: 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 3a06e61e0..4a4216512 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 41569f6c1..cd43e53ba 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 fde59d142..58cdd5b0e 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 93a3308ad..d7e4281c2 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 f9bbc0e44..e12069b4c 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 6a5ea346e..09293a86b 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)); } -- cgit v1.2.3 From 622ebab6710815324fa7250554b56f673862b479 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 13:11:54 +0200 Subject: 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 fd3d405a7..c6da4bb42 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))); -- cgit v1.2.3 From c07774b0b674805014b3ea16b28a01d40ba83d11 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 13:12:18 +0200 Subject: 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 000000000..0d000f04e --- /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 000000000..697ed9350 --- /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 -- cgit v1.2.3 From 7c94024fc32778cb6c789fc46a7bfbbcc7109e89 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 13:47:20 +0200 Subject: 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 5e71c1f0c..7533b4a33 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; } } -- cgit v1.2.3 From cb6ca08a53bfaa1b76798e6220bb1b267d49b235 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:24:09 +0200 Subject: 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 0c88b4d3c..7141cea2a 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; -- cgit v1.2.3 From 7067c43ec09cca176ad72378aa9ad868171c2471 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:49:06 +0200 Subject: 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 13e90910b..2fae76091 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 cb762dc1a..b4a6b3f7b 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"); -- cgit v1.2.3 From 58ac605470aed3b2a537b4f99ac17a199f8b5233 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:55:11 +0200 Subject: 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 7533b4a33..ebe3073de 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 -- cgit v1.2.3 From 51aa5544fbda97c6b49bfba55696083ba47d4cef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 8 Aug 2014 14:30:45 +0200 Subject: 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 cd43e53ba..0e3a88a70 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 000000000..9c595a6fb --- /dev/null +++ b/tests/fsm/.gitignore @@ -0,0 +1 @@ +temp diff --git a/tests/fsm/generate.py b/tests/fsm/generate.py index 0d000f04e..722bd62af 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 697ed9350..f5299c092 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" -- cgit v1.2.3 From 2faef8973830e553b1730c07d327c8d76d412e1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 9 Aug 2014 14:49:51 +0200 Subject: Some improvements in fsm_opt and fsm_map for FSM with unreachable states --- passes/fsm/fsm_map.cc | 107 +++++++++++++++++++++++++++----------------------- passes/fsm/fsm_opt.cc | 44 +++++++++++++++++++++ tests/fsm/run-test.sh | 3 +- 3 files changed, 103 insertions(+), 51 deletions(-) diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 99b736c1b..b3750de08 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; + module->connect(next_state_wire, fsm_data.state_table.front()); + } + else + { + RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size()); - for (size_t j = 0; j < fsm_data.state_table.size(); j++) - fullstate_cache.insert(j); + for (size_t i = 0; i < fsm_data.state_table.size(); i++) + { + std::map> pattern_cache; + std::set fullstate_cache; - 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); - } + for (size_t j = 0; j < fsm_data.state_table.size(); j++) + fullstate_cache.insert(j); - implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, RTLIL::SigSpec(next_state_onehot, i)); - } + 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); + } - 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)); + implement_pattern_cache(module, pattern_cache, fullstate_cache, fsm_data.state_table.size(), state_onehot, ctrl_in, 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)); + + 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()); + 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 bcaa89bf0..a0e1885ec 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 f5299c092..3d0ff7573 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 -- cgit v1.2.3 From b9811d5aff7ca31daa214386a041af0865813813 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 9 Aug 2014 15:17:54 +0200 Subject: 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 7141cea2a..065b90d3e 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"); -- cgit v1.2.3 From 9d4362990f514ffd2aad3170ec7382f21b8bca67 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 9 Aug 2014 17:07:20 +0200 Subject: 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 065b90d3e..5f3cf4214 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; -- cgit v1.2.3 From 788bd02f970859bb67c5dbb7b503f23904257f7b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 10 Aug 2014 12:04:02 +0200 Subject: 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 b3750de08..048cf7e5f 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 722bd62af..ca0718b27 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')) -- cgit v1.2.3 From 5215723c64037ba1ee7884423aee1b9c307b5850 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 11 Aug 2014 15:55:41 +0200 Subject: 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 09673dc2e..1f0826039 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 -- cgit v1.2.3 From cad98bcd89cd9747f3ea9e35eed8d9bbedd64d7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 10:37:47 +0200 Subject: 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 9fed1bf3b..db06c56d2 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 + -- cgit v1.2.3 From 593264e9edce8b1df1d5b691353fa592261d4f3b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 15:21:06 +0200 Subject: Fixed building verific bindings --- frontends/verific/build_amd64.txt | 2 +- frontends/verific/verific.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 2f325e515..2c3ba7b4d 100644 --- a/frontends/verific/build_amd64.txt +++ b/frontends/verific/build_amd64.txt @@ -6,7 +6,7 @@ only have the i386 eval version of Verific: 1.) Use a Makefile.conf like the following one: --snip-- -CONFIG := clang-debug +CONFIG := clang ENABLE_TCL := 0 ENABLE_QT4 := 0 ENABLE_ABC := 0 diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 30f452181..1ffcc4229 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -687,7 +687,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setaddCell(RTLIL::escape_id(inst->Name()), "$memrd"); - cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\MEMID"] = memory->name.str(); cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\TRANSPARENT"] = false; @@ -709,7 +709,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setaddCell(RTLIL::escape_id(inst->Name()), "$memwr"); - cell->parameters["\\MEMID"] = memory->name; + cell->parameters["\\MEMID"] = memory->name.str(); cell->parameters["\\CLK_ENABLE"] = false; cell->parameters["\\CLK_POLARITY"] = true; cell->parameters["\\PRIORITY"] = 0; -- cgit v1.2.3 From e5ac8fdf2bf9d4bed41daf420aa8a94018c0ded4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 15:39:48 +0200 Subject: 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 8ec599417..1e967f26c 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]; } -- cgit v1.2.3 From 1dd8252169654c2bc8cb96a90141a333d3ccd4f6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 15:43:30 +0200 Subject: 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 ca0718b27..66ca2af5e 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')) -- cgit v1.2.3 From 9d353fc543295db7d6f4b4ba60c2b66a509b3ee2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Aug 2014 17:35:22 +0200 Subject: 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 13be0ddb6..1e3dd9ce7 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 61844d5eb..fe3532da8 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]; -- cgit v1.2.3 From f53984795d38946ee71684d88883cafd9f58f603 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:03:38 +0200 Subject: Added support for non-standard """ macro bodies --- README | 9 +++++++++ frontends/verilog/preproc.cc | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README b/README index 0c8425f37..1ecaa07df 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 8efd4d7c3..7935fbc34 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -131,6 +131,12 @@ static std::string next_token(bool pass_newline = false) token += ch; } } + if (token == "\"\"" && (ch = next_char()) != 0) { + if (ch == '"') + token += ch; + else + return_char(ch); + } } else if (ch == '/') { @@ -311,12 +317,17 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m std::map args; skip_spaces(); name = next_token(true); + bool here_doc_mode = false; int newline_count = 0; int state = 0; if (skip_spaces() != "") state = 3; while (!tok.empty()) { tok = next_token(); + if (tok == "\"\"\"") { + here_doc_mode = !here_doc_mode; + continue; + } if (state == 0 && tok == "(") { state = 1; skip_spaces(); @@ -332,7 +343,7 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } else { if (state != 2) state = 3; - if (tok == "\n") { + if (tok == "\n" && !here_doc_mode) { return_char('\n'); break; } -- cgit v1.2.3 From c27120fcbc69f7b942788d72677f34e4a96ab48a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:04:28 +0200 Subject: New interface for $__alu in techmap.v --- techlibs/common/techmap.v | 191 +++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 129 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 7f3855ce8..a03ff8ebe 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -266,127 +266,98 @@ 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; - - 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); +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; - 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)); + // carry in, sub, carry out, carry sign + input CI, S; + output CO, CS; - \$__alu #( - .WIDTH(WIDTH) - ) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign) - ); + 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 flags - wire cf, of, zf, sf; - assign cf = !carry; - assign of = carry ^ carry_sign; - assign zf = ~|Y_buf; - assign sf = Y_buf[WIDTH-1]; + wire [Y_WIDTH:0] carry; + assign carry[0] = CI; + assign CO = carry[Y_WIDTH]; + assign CS = carry[Y_WIDTH-1]; + genvar i; generate - if (A_SIGNED && B_SIGNED) begin - assign Y = of != sf; - end else begin - assign Y = cf; + 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 endmodule -module \$le (A, B, Y); +`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 = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH; + localparam WIDTH = _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)); + wire alu_co, alu_cs; + wire [WIDTH-1:0] alu_y; \$__alu #( - .WIDTH(WIDTH) + .A_SIGNED(A_SIGNED), + .B_SIGNED(B_SIGNED), + .A_WIDTH(A_WIDTH), + .B_WIDTH(B_WIDTH), + .Y_WIDTH(WIDTH) ) alu ( - .A(A_buf), - .B(~B_buf), - .Cin(1'b1), - .Y(Y_buf), - .Cout(carry), - .Csign(carry_sign) + .A(A), + .B(B), + .CI(_ci), + .S(_s), + .Y(alu_y), + .CO(alu_co), + .CS(alu_cs) ); - // 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]; + assign cf = !alu_co; + assign of = alu_co ^ alu_cs; + assign zf = ~|alu_y; + assign sf = alu_y[WIDTH-1]; +""" - generate - if (A_SIGNED && B_SIGNED) begin - assign Y = zf || (of != sf); - end else begin - assign Y = zf || cf; - end - endgenerate + +// -------------------------------------------------------- +// Compare cells +// -------------------------------------------------------- + +module \$lt (A, B, Y); + 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); + 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 -- cgit v1.2.3 From 28bc7aeb9345377d7815ad5ae9a941e55409bc4b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:40:29 +0200 Subject: 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 77419e616..b9baea38b 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; -- cgit v1.2.3 From 9a065509acd53d4fdbfe2e98ab0aba5e6851d8e8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 16:36:30 +0200 Subject: 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 a03ff8ebe..59f91bc53 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; + + input [WIDTH-1:0] A, B; + output [WIDTH-1:0] Y; + + 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; - // {t1, t2} = A + B - wire t1, t2, t3; + 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(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) ); + \$_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) """ -- cgit v1.2.3 From 7e758d5fbba4769ba268229bece7b5c486c61223 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 18:40:57 +0200 Subject: 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 59f91bc53..3670bd69f 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 -- cgit v1.2.3 From a878095b465d73df7b347dddb25c3627024b3d7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 10:19:12 +0200 Subject: Updated ABC to 4935c2b946de --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0e3a88a70..cf176fde5 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 -- cgit v1.2.3 From 996c06f64dcb1619584c88d101c5ba258b2b26af Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 11:05:25 +0200 Subject: 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 b9baea38b..e7da6ed4a 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(); -- cgit v1.2.3 From 28cf48e31f049f8343023de46cd916ac47fcfc5d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 11:22:45 +0200 Subject: 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 048cf7e5f..60580eb46 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 40fed130e..9c0da0a37 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 66ca2af5e..b5b4626df 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) -- cgit v1.2.3 From 13f2f36884fa3e4a8329dab2556af7000cb085df Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 11:39:46 +0200 Subject: 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 993863827..23d06f820 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 529d8962d..dbe13ea7e 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 8ff564515..201c717e4 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 1e967f26c..10da74636 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 1ada1e16a..8284cdeb2 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 21a93d55c..3b2145444 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 6723a57fe..2269859d1 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 5675dff50..2c846a4cf 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 670fae1d9..77821326d 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 ebe3073de..871478dee 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 2660b33d4..daa063812 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 5f3c4d29e..e2b4243d1 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 eb970329d..e9a5e7fde 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 946490135..94d5d27b1 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 c2f6cb278..4b3317a76 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 3670bd69f..e1d5bd82f 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 - -- cgit v1.2.3 From 746aac540b815099c6a63077010555369d7fdd5a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 15:46:51 +0200 Subject: 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 605616b31..cafc1f3f0 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 23d06f820..6beaa3fed 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) + { + 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) { - designs.push_back(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 201c717e4..fdb33ed82 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")); -- cgit v1.2.3 From 1bf7a18fec76cf46a5b8710a75371e23b68d147d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 16:13:42 +0200 Subject: Added module->ports --- frontends/ast/ast.cc | 1 + frontends/ilang/parser.y | 1 + 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 f18124e28..9f17f3bfb 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -919,6 +919,7 @@ static AstModule* process_module(AstNode *ast, bool defer) current_module->noopt = flag_noopt; current_module->icells = flag_icells; current_module->autowire = flag_autowire; + current_module->fixup_ports(); return current_module; } diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index f696140eb..e1ef39a55 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -101,6 +101,7 @@ module: } module_body TOK_END { if (attrbuf.size() != 0) rtlil_frontend_ilang_yyerror("dangling attribute"); + current_module->fixup_ports(); } EOL; module_body: diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 6beaa3fed..5486f6acb 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 fdb33ed82..96ae0f97a 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 10da74636..0093b8a1b 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 1891a7450..bc8f343a5 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 50b4989df..2f28afb25 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 89f45e025..1b03ab555 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 985d51e50..ebf4d77fc 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; -- cgit v1.2.3 From 5602cbde9f9f86197511036d8873c0f8fb1ca5d7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 20:53:21 +0200 Subject: 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 e1d5bd82f..7a4f6b272 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; + + 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 = partials[WIDTH*WIDTH-1 : WIDTH*(WIDTH-1)]; + assign Y = y; endmodule module \$mul (A, B, Y); -- cgit v1.2.3 From 85e3cc12ac44c44178185b918aa2a7fe9ca89918 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:26:10 +0200 Subject: Fixed handling of task outputs --- frontends/ast/simplify.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 39c472621..76d1f8270 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1523,12 +1523,14 @@ skip_dynamic_range_lvalue_expansion:; replace_rules[child->str] = wire->str; - if (child->is_input && arg_count < children.size()) + if ((child->is_input || child->is_output) && arg_count < children.size()) { AstNode *arg = children[arg_count++]->clone(); AstNode *wire_id = new AstNode(AST_IDENTIFIER); wire_id->str = wire->str; - AstNode *assign = new AstNode(AST_ASSIGN_EQ, wire_id, arg); + AstNode *assign = child->is_input ? + new AstNode(AST_ASSIGN_EQ, wire_id, arg) : + new AstNode(AST_ASSIGN_EQ, arg, wire_id); for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { if (*it != current_block_child) -- cgit v1.2.3 From 6d56172c0d16f80742c1c4588929d1805e3dd650 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:26:30 +0200 Subject: Fixed line numbers when using here-doc macros --- frontends/verilog/preproc.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 7935fbc34..ae139741a 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -343,10 +343,15 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } else { if (state != 2) state = 3; - if (tok == "\n" && !here_doc_mode) { - return_char('\n'); - break; - } + if (tok == "\n") { + if (here_doc_mode) { + value += " "; + newline_count++; + } else { + return_char('\n'); + break; + } + } else if (tok == "\\") { char ch = next_char(); if (ch == '\n') { -- cgit v1.2.3 From 2f44d8ccf853870a661b5e528c7e3ad3e17ca21e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:32:18 +0200 Subject: 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 96ae0f97a..297537f00 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(); - - log_assert(pattern.width_ == with.width_); + std::map rules; - 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]; + + replace(rules, other); +} - for (int i = 0; i < SIZE(bits_); i++) - if (pattern_map.count(bits_[i])) - other->bits_[i] = pattern_map.at(bits_[i]); +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 0093b8a1b..8f780c822 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); -- cgit v1.2.3 From c83b9904582b81e71c4c510ffdc26f9796f5da21 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 23:02:07 +0200 Subject: Changed the AST genWidthRTLIL subst interface to use a std::map --- frontends/ast/ast.cc | 3 +-- frontends/ast/ast.h | 5 +++-- frontends/ast/genrtlil.cc | 44 +++++++++++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 9f17f3bfb..551859ebf 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,8 +51,7 @@ namespace AST_INTERNAL { bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map current_scope; - RTLIL::SigSpec *genRTLIL_subst_from = NULL; - RTLIL::SigSpec *genRTLIL_subst_to = NULL; + std::map *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; AstNode *current_top_block, *current_block, *current_block_child; AstModule *current_module; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 5fb1f0a73..e7b075486 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -228,7 +228,7 @@ namespace AST // for expressions the resulting signal vector is returned // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false); - RTLIL::SigSpec genWidthRTLIL(int width, RTLIL::SigSpec *subst_from = NULL, RTLIL::SigSpec *subst_to = NULL); + RTLIL::SigSpec genWidthRTLIL(int width, std::map *new_subst_ptr = NULL); // compare AST nodes bool operator==(const AstNode &other) const; @@ -285,7 +285,8 @@ namespace AST_INTERNAL extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; extern AST::AstNode *current_ast, *current_ast_mod; extern std::map current_scope; - extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial; + extern std::map *genRTLIL_subst_ptr; + extern RTLIL::SigSpec ignoreThisSignalsInInitial; extern AST::AstNode *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; struct ProcessGenerator; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index bea99d8d4..242514863 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -173,7 +173,7 @@ struct AST_INTERNAL::ProcessGenerator AstNode *always; RTLIL::SigSpec initSyncSignals; RTLIL::Process *proc; - const RTLIL::SigSpec &outputSignals; + RTLIL::SigSpec outputSignals; // This always points to the RTLIL::CaseRule beeing filled at the moment RTLIL::CaseRule *current_case; @@ -198,7 +198,7 @@ struct AST_INTERNAL::ProcessGenerator // Buffer for generating the init action RTLIL::SigSpec init_lvalue, init_rvalue; - ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), outputSignals(subst_lvalue_from) + ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg) { // generate process and simple root case proc = new RTLIL::Process; @@ -278,6 +278,8 @@ struct AST_INTERNAL::ProcessGenerator offset += lhs.size(); } } + + outputSignals = RTLIL::SigSpec(subst_lvalue_from); } // create new temporary signals @@ -398,8 +400,12 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_EQ: case AST_ASSIGN_LE: { + std::map new_subst_rvalue_map; + for (int i = 0; i < SIZE(subst_rvalue_to); i++) + new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_from, &subst_rvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map); lvalue.replace(subst_lvalue_from, subst_lvalue_to); if (ast->type == AST_ASSIGN_EQ) { @@ -415,8 +421,12 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { + std::map new_subst_rvalue_map; + for (int i = 0; i < SIZE(subst_rvalue_to); i++) + new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_from, &subst_rvalue_to); + sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { @@ -467,8 +477,12 @@ struct AST_INTERNAL::ProcessGenerator default_case = current_case; else if (node->type == AST_BLOCK) processAst(node); - else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_from, &subst_rvalue_to)); + else { + std::map new_subst_rvalue_map; + for (int i = 0; i < SIZE(subst_rvalue_to); i++) + new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map)); + } } if (default_case != current_case) sw->cases.push_back(current_case); @@ -969,8 +983,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec sig = { RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_msb), chunk, RTLIL::SigSpec(RTLIL::State::Sx, add_undef_bits_lsb) }; - if (genRTLIL_subst_from && genRTLIL_subst_to) - sig.replace(*genRTLIL_subst_from, *genRTLIL_subst_to); + if (genRTLIL_subst_ptr) + sig.replace(*genRTLIL_subst_ptr); is_signed = children.size() > 0 ? false : id2ast->is_signed && sign_hint; return sig; @@ -1377,23 +1391,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // this is a wrapper for AstNode::genRTLIL() when a specific signal width is requested and/or // signals must be substituted before beeing used as input values (used by ProcessGenerator) // note that this is using some global variables to communicate this special settings to AstNode::genRTLIL(). -RTLIL::SigSpec AstNode::genWidthRTLIL(int width, RTLIL::SigSpec *subst_from, RTLIL::SigSpec *subst_to) +RTLIL::SigSpec AstNode::genWidthRTLIL(int width, std::map *new_subst_ptr) { - RTLIL::SigSpec *backup_subst_from = genRTLIL_subst_from; - RTLIL::SigSpec *backup_subst_to = genRTLIL_subst_to; + std::map *backup_subst_ptr = genRTLIL_subst_ptr; - if (subst_from) - genRTLIL_subst_from = subst_from; - if (subst_to) - genRTLIL_subst_to = subst_to; + if (new_subst_ptr) + genRTLIL_subst_ptr = new_subst_ptr; bool sign_hint = true; int width_hint = width; detectSignWidthWorker(width_hint, sign_hint); RTLIL::SigSpec sig = genRTLIL(width_hint, sign_hint); - genRTLIL_subst_from = backup_subst_from; - genRTLIL_subst_to = backup_subst_to; + genRTLIL_subst_ptr = backup_subst_ptr; if (width >= 0) sig.extend_u0(width, is_signed); -- cgit v1.2.3 From 978a933b6af8863200096bd3a56780e3378e4848 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 23:14:47 +0200 Subject: Added RTLIL::SigSpec::to_sigbit_map() --- frontends/ast/genrtlil.cc | 14 +++----------- 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 242514863..3c8f1fa16 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -400,10 +400,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_EQ: case AST_ASSIGN_LE: { - std::map new_subst_rvalue_map; - for (int i = 0; i < SIZE(subst_rvalue_to); i++) - new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; - + std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map); lvalue.replace(subst_lvalue_from, subst_lvalue_to); @@ -421,10 +418,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { - std::map new_subst_rvalue_map; - for (int i = 0; i < SIZE(subst_rvalue_to); i++) - new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; - + std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map); current_case->switches.push_back(sw); @@ -478,9 +472,7 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else { - std::map new_subst_rvalue_map; - for (int i = 0; i < SIZE(subst_rvalue_to); i++) - new_subst_rvalue_map[subst_rvalue_from[i]] = subst_rvalue_to[i]; + std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map)); } } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 297537f00..f4f32f600 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 8f780c822..3a0f0ff8c 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); -- cgit v1.2.3 From c7afbd9d8efcf3045d9e4244600ce8d8e0d40b6d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 01:53:22 +0200 Subject: Fixed bug in "read_verilog -ignore_redef" --- frontends/ast/ast.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 551859ebf..ec9616be3 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -947,7 +947,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (!ignore_redef) log_error("Re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - log_error("Ignoring re-definition of module `%s' at %s:%d!\n", + log("Ignoring re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); continue; } -- cgit v1.2.3 From d320e750877a6cf8d5993da6d2cd121fe5b4d78e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 02:00:53 +0200 Subject: 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 29ce96766..a7f91e862 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"); -- cgit v1.2.3 From 8ff71b5ae506306d7981eb118874cd4f407b2bf8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 02:08:02 +0200 Subject: 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 868dbb949..a9e21e6dd 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: 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 3a0f0ff8c..2c4b26f53 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 77821326d..d13643911 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 c620531e3..d47e4513e 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 a7f91e862..59173393c 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); -- cgit v1.2.3 From bf486002d9a6d976b3d086700ccdcfb0fb70ba0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:04:35 +0200 Subject: 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 f09c49298..f05c1b7ad 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 c562650b8..af8e22497 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. -- cgit v1.2.3 From f092b5014895dc5dc62b8103fcedf94cfa9f85a8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:11:40 +0200 Subject: Renamed $_INV_ cell type to $_NOT_ --- 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 5daab6691..386d68d8b 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 cafc1f3f0..81c938bdd 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 504b8d1e4..83bfce371 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -55,7 +55,7 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A) { - RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_"); cell->setPort("\\A", A); cell->setPort("\\Y", module->addWire(NEW_ID)); return cell->getPort("\\Y"); @@ -241,17 +241,17 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clk_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clk_sig) { clk_sig = it.second->getPort("\\A"); clk_polarity = !clk_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) { clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) { preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; @@ -259,7 +259,7 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_"); cell->setPort("\\A", iq_sig); cell->setPort("\\Y", iqn_sig); @@ -318,17 +318,17 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) rerun_invert_rollback = false; for (auto &it : module->cells_) { - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == enable_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == enable_sig) { enable_sig = it.second->getPort("\\A"); enable_polarity = !enable_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == clear_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) { clear_sig = it.second->getPort("\\A"); clear_polarity = !clear_polarity; rerun_invert_rollback = true; } - if (it.second->type == "$_INV_" && it.second->getPort("\\Y") == preset_sig) { + if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) { preset_sig = it.second->getPort("\\A"); preset_polarity = !preset_polarity; rerun_invert_rollback = true; @@ -336,7 +336,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) } } - RTLIL::Cell *cell = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_"); cell->setPort("\\A", iq_sig); cell->setPort("\\Y", iqn_sig); @@ -347,7 +347,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (clear_polarity == true || clear_polarity != enable_polarity) { - RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_"); inv->setPort("\\A", clear_sig); inv->setPort("\\Y", module->addWire(NEW_ID)); @@ -375,7 +375,7 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node) if (preset_polarity == false || preset_polarity != enable_polarity) { - RTLIL::Cell *inv = module->addCell(NEW_ID, "$_INV_"); + RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_"); inv->setPort("\\A", preset_sig); inv->setPort("\\Y", module->addWire(NEW_ID)); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 1ffcc4229..95b3c407e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -162,7 +162,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NAND) { RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addAndGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); - module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + module->addNotGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } @@ -174,7 +174,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_NOR) { RTLIL::SigSpec tmp = module->addWire(NEW_ID); module->addOrGate(NEW_ID, net_map.at(inst->GetInput1()), net_map.at(inst->GetInput2()), tmp); - module->addInvGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); + module->addNotGate(RTLIL::escape_id(inst->Name()), tmp, net_map.at(inst->GetOutput())); return true; } @@ -184,7 +184,7 @@ static bool import_netlist_instance_gates(RTLIL::Module *module, std::mapType() == PRIM_INV) { - module->addInvGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); + module->addNotGate(RTLIL::escape_id(inst->Name()), net_map.at(inst->GetInput()), net_map.at(inst->GetOutput())); return true; } diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 5486f6acb..e30ceb8b1 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 f4f32f600..614ea770b 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 2c4b26f53..43e36cbde 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 8284cdeb2..b57edd9fe 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 f05c1b7ad..ea4ae8d40 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 a2df8f648..54c076614 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 f68b6f984..803982295 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 3b2145444..4e9f4b21e 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 e7da6ed4a..2b1d49810 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 a13bb09cb..9af1e6bdf 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 7b9fb2072..bfed0005d 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 16518b7df..6ce771ac4 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 960578b06..f5d9bbeef 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 d492c2f15..7c8a47ddd 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 7a4f6b272..190002c01 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. * -- cgit v1.2.3 From b64b38eea2e9a7de30d6045f069c86bf4446134f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:18:40 +0200 Subject: 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 386d68d8b..b9b68b979 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 e30ceb8b1..402d6ea76 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 614ea770b..d118b6257 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 bc8f343a5..1fbb5720d 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 4b3317a76..8c0a54e4e 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 5bf8ccd86..d19be0db7 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 -- cgit v1.2.3 From 674f421b476295d3376ec00644181fc9be02ccaf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 15 Aug 2014 14:29:42 +0200 Subject: 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 194e06a4a..9cd23ce6f 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) { -- cgit v1.2.3 From dbdf89c7054a3f249d7579cb50d10b72b1ac592d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 15:34:00 +0200 Subject: 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 6f9764238..d59e68a50 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 1f0826039..b742a5495 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 037a62a3b..b1c44b46b 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(); -- cgit v1.2.3 From eb17fbade5ef89983993d1e9d47da5f8a2fb32c3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 15:34:15 +0200 Subject: 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 33e1507bc..b6d36f0e3 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; -- cgit v1.2.3 From 1ddf150c35aa32f2f6eb35d678feb76b612d7c47 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 16:01:58 +0200 Subject: 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 190002c01..9b733c6f0 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); -- cgit v1.2.3 From 56a30cf42c6a40f265a67df6e2c5fa74657fbf5b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 16:12:14 +0200 Subject: Added CellTypes::cell_evaluable() --- kernel/celltypes.h | 68 +++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 402d6ea76..ad5eae2e8 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("$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); + 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"}); + 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"}); } 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) -- cgit v1.2.3 From 47c2637a961839f1eb1a0386f7e54d94be50bc10 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 18:18:30 +0200 Subject: 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 81c938bdd..0fcd60cdd 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 ad5eae2e8..8c2e9a48e 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 dbe13ea7e..d42c2b0f1 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 d118b6257..3df7d83c4 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 b57edd9fe..c02900a6c 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 ea4ae8d40..3eb2f9469 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 2b1d49810..fd56668cf 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 7c8a47ddd..a2a377350 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; -- cgit v1.2.3 From 83e2698e10065a27afcc0f0db3818ed3b4a5942e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 19:31:59 +0200 Subject: AST ProcessGenerator: replaced subst_*_{from,to} with subst_*_map --- frontends/ast/genrtlil.cc | 67 ++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3c8f1fa16..b519f9c59 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -178,18 +178,18 @@ struct AST_INTERNAL::ProcessGenerator // This always points to the RTLIL::CaseRule beeing filled at the moment RTLIL::CaseRule *current_case; - // This two variables contain the replacement pattern to be used in the right hand side + // This map contains the replacement pattern to be used in the right hand side // of an assignment. E.g. in the code "foo = bar; foo = func(foo);" the foo in the right // hand side of the 2nd assignment needs to be replace with the temporary signal holding // the value assigned in the first assignment. So when the first assignement is processed // the according information is appended to subst_rvalue_from and subst_rvalue_to. - RTLIL::SigSpec subst_rvalue_from, subst_rvalue_to; + std::map subst_rvalue_map; - // This two variables contain the replacement pattern to be used in the left hand side + // This map contains the replacement pattern to be used in the left hand side // of an assignment. E.g. in the code "always @(posedge clk) foo <= bar" the signal bar // should not be connected to the signal foo. Instead it must be connected to the temporary // signal that is used as input for the register that drives the signal foo. - RTLIL::SigSpec subst_lvalue_from, subst_lvalue_to; + std::map subst_lvalue_map; // The code here generates a number of temprorary signal for each output register. This // map helps generating nice numbered names for all this temporary signals. @@ -214,8 +214,10 @@ struct AST_INTERNAL::ProcessGenerator current_case = &proc->root_case; // create initial temporary signal for all output registers + RTLIL::SigSpec subst_lvalue_from, subst_lvalue_to; collect_lvalues(subst_lvalue_from, always, true, true); subst_lvalue_to = new_temp_signal(subst_lvalue_from); + subst_lvalue_map = subst_lvalue_from.to_sigbit_map(subst_lvalue_to); bool found_anyedge_syncs = false; for (auto child : always->children) @@ -251,8 +253,7 @@ struct AST_INTERNAL::ProcessGenerator // create initial assignments for the temporary signals if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) { - subst_rvalue_from = subst_lvalue_from; - subst_rvalue_to = RTLIL::SigSpec(RTLIL::State::Sx, subst_rvalue_from.size()); + subst_rvalue_map = subst_lvalue_from.to_sigbit_map(RTLIL::SigSpec(RTLIL::State::Sx, SIZE(subst_lvalue_from))); } else { addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from); } @@ -400,15 +401,13 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_EQ: case AST_ASSIGN_LE: { - std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &new_subst_rvalue_map); - lvalue.replace(subst_lvalue_from, subst_lvalue_to); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map); + lvalue.replace(subst_lvalue_map); if (ast->type == AST_ASSIGN_EQ) { - subst_rvalue_from.remove2(unmapped_lvalue, &subst_rvalue_to); - subst_rvalue_from.append(unmapped_lvalue); - subst_rvalue_to.append(rvalue); + for (int i = 0; i < SIZE(unmapped_lvalue); i++) + subst_rvalue_map[unmapped_lvalue[i]] = rvalue[i]; } removeSignalFromCaseTree(lvalue, current_case); @@ -418,9 +417,8 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { - std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->signal = ast->children[0]->genWidthRTLIL(-1, &new_subst_rvalue_map); + sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { @@ -436,13 +434,10 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec this_case_eq_ltemp = new_temp_signal(this_case_eq_lvalue); RTLIL::SigSpec this_case_eq_rvalue = this_case_eq_lvalue; - this_case_eq_rvalue.replace(subst_rvalue_from, subst_rvalue_to); + this_case_eq_rvalue.replace(subst_rvalue_map); - RTLIL::SigSpec backup_subst_lvalue_from = subst_lvalue_from; - RTLIL::SigSpec backup_subst_lvalue_to = subst_lvalue_to; - - RTLIL::SigSpec backup_subst_rvalue_from = subst_rvalue_from; - RTLIL::SigSpec backup_subst_rvalue_to = subst_rvalue_to; + std::map backup_subst_lvalue_map = subst_lvalue_map; + std::map backup_subst_rvalue_map = subst_rvalue_map; RTLIL::CaseRule *default_case = NULL; RTLIL::CaseRule *last_generated_case = NULL; @@ -452,15 +447,11 @@ struct AST_INTERNAL::ProcessGenerator continue; log_assert(child->type == AST_COND); - subst_lvalue_from = backup_subst_lvalue_from; - subst_lvalue_to = backup_subst_lvalue_to; - - subst_rvalue_from = backup_subst_rvalue_from; - subst_rvalue_to = backup_subst_rvalue_to; + subst_lvalue_map = backup_subst_lvalue_map; + subst_rvalue_map = backup_subst_rvalue_map; - subst_lvalue_from.remove2(this_case_eq_lvalue, &subst_lvalue_to); - subst_lvalue_from.append(this_case_eq_lvalue); - subst_lvalue_to.append(this_case_eq_ltemp); + for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) + subst_lvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; @@ -471,10 +462,8 @@ struct AST_INTERNAL::ProcessGenerator default_case = current_case; else if (node->type == AST_BLOCK) processAst(node); - else { - std::map new_subst_rvalue_map = subst_rvalue_from.to_sigbit_map(subst_rvalue_to); - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &new_subst_rvalue_map)); - } + else + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map)); } if (default_case != current_case) sw->cases.push_back(current_case); @@ -493,17 +482,13 @@ struct AST_INTERNAL::ProcessGenerator sw->cases.push_back(default_case); } - subst_lvalue_from = backup_subst_lvalue_from; - subst_lvalue_to = backup_subst_lvalue_to; - - subst_rvalue_from = backup_subst_rvalue_from; - subst_rvalue_to = backup_subst_rvalue_to; + subst_lvalue_map = backup_subst_lvalue_map; + subst_rvalue_map = backup_subst_rvalue_map; - subst_rvalue_from.remove2(this_case_eq_lvalue, &subst_rvalue_to); - subst_rvalue_from.append(this_case_eq_lvalue); - subst_rvalue_to.append(this_case_eq_ltemp); + for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) + subst_rvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; - this_case_eq_lvalue.replace(subst_lvalue_from, subst_lvalue_to); + this_case_eq_lvalue.replace(subst_lvalue_map); removeSignalFromCaseTree(this_case_eq_lvalue, current_case); addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp); } -- cgit v1.2.3 From 3b9157f9a605b5ae2f535c4da932891e504dc57e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 19:44:31 +0200 Subject: 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 94d5d27b1..a4b8be0c1 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; -- cgit v1.2.3 From 976bda71029b9d25ffad9ec8fbf3ceed2d1287e1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 21:07:29 +0200 Subject: 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 9b733c6f0..9bdff4f33 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); -- cgit v1.2.3 From f82c978e08604c596b034fb6e74ac34c78b9364b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 22:05:09 +0200 Subject: 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 0fcd60cdd..f6095a5aa 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; } -- cgit v1.2.3 From 7f734ecc098a2a113ced835cefc9d4e1982f08d0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 16 Aug 2014 23:50:36 +0200 Subject: Added module->uniquify() --- frontends/verific/verific.cc | 8 ++------ 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 95b3c407e..0440f88e5 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -603,9 +603,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - std::string wire_name = RTLIL::escape_id(net->Name()); - while (module->count_id(wire_name)) - wire_name += "_"; + RTLIL::IdString wire_name = module->uniquify(RTLIL::escape_id(net->Name())); RTLIL::Wire *wire = module->addWire(wire_name); import_attributes(wire->attributes, net); @@ -627,9 +625,7 @@ static void import_netlist(RTLIL::Design *design, Netlist *nl, std::setName()); - std::string wire_name = RTLIL::escape_id(netbus->Name()); - while (module->count_id(wire_name)) - wire_name += "_"; + RTLIL::IdString wire_name = module->uniquify(RTLIL::escape_id(netbus->Name())); RTLIL::Wire *wire = module->addWire(wire_name, netbus->Size()); wire->start_offset = std::min(netbus->LeftIndex(), netbus->RightIndex()); import_attributes(wire->attributes, netbus); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3df7d83c4..60c514d19 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 43e36cbde..7e052b091 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 a3daf2398..cef0a272e 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 60580eb46..ab6d5671d 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, ""); -- cgit v1.2.3 From 410d043dd86a2ca1f6c56a3e2a4d175dc0af8739 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 00:55:35 +0200 Subject: Renamed toposort.h to utils.h --- kernel/toposort.h | 104 ---------------------------------------------- kernel/utils.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++ passes/opt/opt_const.cc | 2 +- passes/techmap/techmap.cc | 2 +- 4 files changed, 106 insertions(+), 106 deletions(-) delete mode 100644 kernel/toposort.h create mode 100644 kernel/utils.h diff --git a/kernel/toposort.h b/kernel/toposort.h deleted file mode 100644 index 4226e270e..000000000 --- a/kernel/toposort.h +++ /dev/null @@ -1,104 +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 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(const 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); - - log_assert(SIZE(sorted) == SIZE(database)); - return !found_loops; - } -}; - -#endif diff --git a/kernel/utils.h b/kernel/utils.h new file mode 100644 index 000000000..4226e270e --- /dev/null +++ b/kernel/utils.h @@ -0,0 +1,104 @@ +/* + * 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(const 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); + + log_assert(SIZE(sorted) == SIZE(database)); + return !found_loops; + } +}; + +#endif diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 9af1e6bdf..58a7f7dfd 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 59173393c..d9d8ddd6a 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" -- cgit v1.2.3 From 9bacc0b54c0901dfd34c2230d3295720653c0a7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 00:56:47 +0200 Subject: 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 4226e270e..7f10619bc 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 e12069b4c..79c90628c 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From d491fd8c19cddb49d2feed2a873a328825c7b8f4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 00:57:24 +0200 Subject: Use stackmap<> in AST ProcessGenerator --- frontends/ast/ast.cc | 2 +- frontends/ast/ast.h | 4 ++-- frontends/ast/genrtlil.cc | 40 +++++++++++++++++++--------------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index ec9616be3..6ac771447 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -51,7 +51,7 @@ namespace AST_INTERNAL { bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; AstNode *current_ast, *current_ast_mod; std::map current_scope; - std::map *genRTLIL_subst_ptr = NULL; + const std::map *genRTLIL_subst_ptr = NULL; RTLIL::SigSpec ignoreThisSignalsInInitial; AstNode *current_top_block, *current_block, *current_block_child; AstModule *current_module; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index e7b075486..6ea241fa9 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -228,7 +228,7 @@ namespace AST // for expressions the resulting signal vector is returned // all generated cell instances, etc. are written to the RTLIL::Module pointed to by AST_INTERNAL::current_module RTLIL::SigSpec genRTLIL(int width_hint = -1, bool sign_hint = false); - RTLIL::SigSpec genWidthRTLIL(int width, std::map *new_subst_ptr = NULL); + RTLIL::SigSpec genWidthRTLIL(int width, const std::map *new_subst_ptr = NULL); // compare AST nodes bool operator==(const AstNode &other) const; @@ -285,7 +285,7 @@ namespace AST_INTERNAL extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; extern AST::AstNode *current_ast, *current_ast_mod; extern std::map current_scope; - extern std::map *genRTLIL_subst_ptr; + extern const std::map *genRTLIL_subst_ptr; extern RTLIL::SigSpec ignoreThisSignalsInInitial; extern AST::AstNode *current_top_block, *current_block, *current_block_child; extern AST::AstModule *current_module; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b519f9c59..4eb4f6c44 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -27,6 +27,7 @@ */ #include "kernel/log.h" +#include "kernel/utils.h" #include "libs/sha1/sha1.h" #include "ast.h" @@ -183,13 +184,13 @@ struct AST_INTERNAL::ProcessGenerator // hand side of the 2nd assignment needs to be replace with the temporary signal holding // the value assigned in the first assignment. So when the first assignement is processed // the according information is appended to subst_rvalue_from and subst_rvalue_to. - std::map subst_rvalue_map; + stackmap subst_rvalue_map; // This map contains the replacement pattern to be used in the left hand side // of an assignment. E.g. in the code "always @(posedge clk) foo <= bar" the signal bar // should not be connected to the signal foo. Instead it must be connected to the temporary // signal that is used as input for the register that drives the signal foo. - std::map subst_lvalue_map; + stackmap subst_lvalue_map; // The code here generates a number of temprorary signal for each output register. This // map helps generating nice numbered names for all this temporary signals. @@ -402,12 +403,12 @@ struct AST_INTERNAL::ProcessGenerator case AST_ASSIGN_LE: { RTLIL::SigSpec unmapped_lvalue = ast->children[0]->genRTLIL(), lvalue = unmapped_lvalue; - RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map); - lvalue.replace(subst_lvalue_map); + RTLIL::SigSpec rvalue = ast->children[1]->genWidthRTLIL(lvalue.size(), &subst_rvalue_map.stdmap()); + lvalue.replace(subst_lvalue_map.stdmap()); if (ast->type == AST_ASSIGN_EQ) { for (int i = 0; i < SIZE(unmapped_lvalue); i++) - subst_rvalue_map[unmapped_lvalue[i]] = rvalue[i]; + subst_rvalue_map.set(unmapped_lvalue[i], rvalue[i]); } removeSignalFromCaseTree(lvalue, current_case); @@ -418,7 +419,7 @@ struct AST_INTERNAL::ProcessGenerator case AST_CASE: { RTLIL::SwitchRule *sw = new RTLIL::SwitchRule; - sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map); + sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap()); current_case->switches.push_back(sw); for (auto &attr : ast->attributes) { @@ -434,10 +435,7 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec this_case_eq_ltemp = new_temp_signal(this_case_eq_lvalue); RTLIL::SigSpec this_case_eq_rvalue = this_case_eq_lvalue; - this_case_eq_rvalue.replace(subst_rvalue_map); - - std::map backup_subst_lvalue_map = subst_lvalue_map; - std::map backup_subst_rvalue_map = subst_rvalue_map; + this_case_eq_rvalue.replace(subst_rvalue_map.stdmap()); RTLIL::CaseRule *default_case = NULL; RTLIL::CaseRule *last_generated_case = NULL; @@ -447,11 +445,11 @@ struct AST_INTERNAL::ProcessGenerator continue; log_assert(child->type == AST_COND); - subst_lvalue_map = backup_subst_lvalue_map; - subst_rvalue_map = backup_subst_rvalue_map; + subst_lvalue_map.save(); + subst_rvalue_map.save(); for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) - subst_lvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; + subst_lvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]); RTLIL::CaseRule *backup_case = current_case; current_case = new RTLIL::CaseRule; @@ -463,13 +461,16 @@ struct AST_INTERNAL::ProcessGenerator else if (node->type == AST_BLOCK) processAst(node); else - current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map)); + current_case->compare.push_back(node->genWidthRTLIL(sw->signal.size(), &subst_rvalue_map.stdmap())); } if (default_case != current_case) sw->cases.push_back(current_case); else log_assert(current_case->compare.size() == 0); current_case = backup_case; + + subst_lvalue_map.restore(); + subst_rvalue_map.restore(); } if (last_generated_case != NULL && ast->get_bool_attribute("\\full_case") && default_case == NULL) { @@ -482,13 +483,10 @@ struct AST_INTERNAL::ProcessGenerator sw->cases.push_back(default_case); } - subst_lvalue_map = backup_subst_lvalue_map; - subst_rvalue_map = backup_subst_rvalue_map; - for (int i = 0; i < SIZE(this_case_eq_lvalue); i++) - subst_rvalue_map[this_case_eq_lvalue[i]] = this_case_eq_ltemp[i]; + subst_rvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]); - this_case_eq_lvalue.replace(subst_lvalue_map); + this_case_eq_lvalue.replace(subst_lvalue_map.stdmap()); removeSignalFromCaseTree(this_case_eq_lvalue, current_case); addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp); } @@ -1368,9 +1366,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // this is a wrapper for AstNode::genRTLIL() when a specific signal width is requested and/or // signals must be substituted before beeing used as input values (used by ProcessGenerator) // note that this is using some global variables to communicate this special settings to AstNode::genRTLIL(). -RTLIL::SigSpec AstNode::genWidthRTLIL(int width, std::map *new_subst_ptr) +RTLIL::SigSpec AstNode::genWidthRTLIL(int width, const std::map *new_subst_ptr) { - std::map *backup_subst_ptr = genRTLIL_subst_ptr; + const std::map *backup_subst_ptr = genRTLIL_subst_ptr; if (new_subst_ptr) genRTLIL_subst_ptr = new_subst_ptr; -- cgit v1.2.3 From f3326a642178b66ba98b6371245077ff93ffe215 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:16:56 +0200 Subject: 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 60c514d19..e4bf4f9f3 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_); -- cgit v1.2.3 From 64713647a966e8a14dff39f9ac18aafe9c882f46 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:17:49 +0200 Subject: Improved AST ProcessGenerator performance --- frontends/ast/genrtlil.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 4eb4f6c44..1936146b3 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -357,7 +357,7 @@ struct AST_INTERNAL::ProcessGenerator // e.g. when the last statement in the code "a = 23; if (b) a = 42; a = 0;" is processed this // function is called to clean up the first two assignments as they are overwritten by // the third assignment. - void removeSignalFromCaseTree(RTLIL::SigSpec pattern, RTLIL::CaseRule *cs) + void removeSignalFromCaseTree(const std::set &pattern, RTLIL::CaseRule *cs) { for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) it->first.remove2(pattern, &it->second); @@ -411,7 +411,7 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_map.set(unmapped_lvalue[i], rvalue[i]); } - removeSignalFromCaseTree(lvalue, current_case); + removeSignalFromCaseTree(lvalue.to_sigbit_set(), current_case); current_case->actions.push_back(RTLIL::SigSig(lvalue, rvalue)); } break; @@ -487,7 +487,7 @@ struct AST_INTERNAL::ProcessGenerator subst_rvalue_map.set(this_case_eq_lvalue[i], this_case_eq_ltemp[i]); this_case_eq_lvalue.replace(subst_lvalue_map.stdmap()); - removeSignalFromCaseTree(this_case_eq_lvalue, current_case); + removeSignalFromCaseTree(this_case_eq_lvalue.to_sigbit_set(), current_case); addChunkActions(current_case->actions, this_case_eq_lvalue, this_case_eq_ltemp); } break; -- cgit v1.2.3 From aa3a6663e2e9a63b88cfb1d008e3e246dc9fa677 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:24:53 +0200 Subject: Makefile fixes --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cf176fde5..4d86a8c91 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) -- cgit v1.2.3 From aa7a3ed83f0972bd6da3b272e7bbc9efb1409067 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 17 Aug 2014 02:25:59 +0200 Subject: 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 dff31db07..599c92d52 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) -- cgit v1.2.3 From acb435b6cf583b6c18f405a9c92566c4e9fb85e5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:02:30 +0200 Subject: Added const folding of AST_CASE to AST simplifier --- frontends/ast/ast.cc | 8 ++++++++ frontends/ast/ast.h | 1 + frontends/ast/simplify.cc | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 6ac771447..0ea38b506 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -722,6 +722,14 @@ AstNode *AstNode::mkconst_str(const std::string &str) return node; } +bool AstNode::bits_only_01() +{ + for (auto bit : bits) + if (bit != RTLIL::S0 && bit != RTLIL::S1) + return false; + return true; +} + RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed) { std::vector bits = this->bits; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6ea241fa9..ef54d76f4 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -246,6 +246,7 @@ namespace AST RTLIL::Const bitsAsConst(int width = -1); RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); + bool bits_only_01(); bool asBool(); // helper functions for real valued const eval diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 76d1f8270..85671213d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1567,7 +1567,7 @@ skip_dynamic_range_lvalue_expansion:; } // perform const folding when activated - if (const_fold && newNode == NULL) + if (const_fold) { bool string_op; std::vector tmp_bits; @@ -1746,6 +1746,37 @@ skip_dynamic_range_lvalue_expansion:; newNode->realvalue = -children[0]->asReal(sign_hint); } break; + case AST_CASE: + if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) { + std::vector new_children; + new_children.push_back(children[0]); + for (int i = 1; i < SIZE(children); i++) { + AstNode *child = children[i]; + log_assert(child->type == AST_COND); + for (auto v : child->children) { + if (v->type == AST_DEFAULT) + goto keep_const_cond; + if (v->type == AST_BLOCK) + continue; + if (v->type == AST_CONSTANT && v->bits_only_01()) { + if (v->bits == children[0]->bits) { + while (i+1 < SIZE(children)) + delete children[++i]; + goto keep_const_cond; + } + continue; + } + goto keep_const_cond; + } + if (0) + keep_const_cond: + new_children.push_back(child); + else + delete child; + } + new_children.swap(children); + } + break; case AST_TERNARY: if (children[0]->isConst()) { -- cgit v1.2.3 From 4b3834e0cc3c34b6845ab50ffd7e9fe396173e8d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:03:33 +0200 Subject: Replaced recursive lcu scheme with bk adder --- techlibs/common/techmap.v | 92 ++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 61 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 9bdff4f33..5bbe883ef 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 - - 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; + p = P; + g = G; + + // in almost all cases CI will be constant zero + g[0] = g[0] | (p[0] & CI); + + // [[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 + + // 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 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]; + // 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 - - \$__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 + end + + assign CO = {g, CI}; endmodule module \$__alu_lookahead (A, B, CI, X, Y, CO, CS); -- cgit v1.2.3 From 6f33fc3e87f5d0429f2236662eb31954e51a71ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 00:27:54 +0200 Subject: 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 5bbe883ef..366351ec0 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 -- cgit v1.2.3 From 640d9fc551c546b511f8d64c0ccfc438937164a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 14:29:30 +0200 Subject: Added "via_celltype" attribute on task/func --- 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 1ecaa07df..a0e67e8a4 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 85671213d..2572fa4a9 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1450,9 +1450,15 @@ skip_dynamic_range_lvalue_expansion:; log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } + AstNode *decl = current_scope[str]; + + std::stringstream sstr; + sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; + std::string prefix = sstr.str(); + bool recommend_const_eval = false; bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval); - if (in_param || recommend_const_eval || require_const_eval) + if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count("\\via_celltype")) { bool all_args_const = true; for (auto child : children) { @@ -1474,11 +1480,6 @@ skip_dynamic_range_lvalue_expansion:; log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } - AstNode *decl = current_scope[str]; - std::stringstream sstr; - sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$"; - std::string prefix = sstr.str(); - size_t arg_count = 0; std::map replace_rules; @@ -1510,6 +1511,68 @@ skip_dynamic_range_lvalue_expansion:; goto replace_fcall_with_id; } + if (decl->attributes.count("\\via_celltype")) + { + std::string celltype = decl->attributes.at("\\via_celltype")->asAttrConst().decode_string(); + std::string outport = str; + + if (celltype.find(' ') != std::string::npos) { + int pos = celltype.find(' '); + outport = RTLIL::escape_id(celltype.substr(pos+1)); + celltype = RTLIL::escape_id(celltype.substr(0, pos)); + } else + celltype = RTLIL::escape_id(celltype); + + AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE)); + cell->str = prefix.substr(0, SIZE(prefix)-1); + cell->children[0]->str = celltype; + + for (auto attr : decl->attributes) + if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0) + { + AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone()); + cell_arg->str = RTLIL::escape_id(attr.first.str().substr(strlen("\\via_celltype_defparam_"))); + cell->children.push_back(cell_arg); + } + + for (auto child : decl->children) + if (child->type == AST_WIRE && (child->is_input || child->is_output || (type == AST_FCALL && child->str == str))) + { + AstNode *wire = child->clone(); + wire->str = prefix + wire->str; + wire->port_id = 0; + wire->is_input = false; + wire->is_output = false; + current_ast_mod->children.push_back(wire); + while (wire->simplify(true, false, false, 1, -1, false, false)) { } + + AstNode *wire_id = new AstNode(AST_IDENTIFIER); + wire_id->str = wire->str; + + if ((child->is_input || child->is_output) && arg_count < children.size()) + { + AstNode *arg = children[arg_count++]->clone(); + AstNode *assign = child->is_input ? + new AstNode(AST_ASSIGN_EQ, wire_id, arg) : + new AstNode(AST_ASSIGN_EQ, arg, wire_id); + + for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { + if (*it != current_block_child) + continue; + current_block->children.insert(it, assign); + break; + } + } + + AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id->clone()); + cell_arg->str = child->str == str ? outport : child->str; + cell->children.push_back(cell_arg); + } + + current_ast_mod->children.push_back(cell); + goto replace_fcall_with_id; + } + for (auto child : decl->children) if (child->type == AST_WIRE) { diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index f619d3c2b..bf9b21bb6 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -407,33 +407,35 @@ module_body_stmt: always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: - TOK_TASK TOK_ID ';' { + attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); - current_function_or_task->str = *$2; + current_function_or_task->str = *$3; + append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); current_function_or_task_port_id = 1; - delete $2; + delete $3; } task_func_body TOK_ENDTASK { current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { + attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); - current_function_or_task->str = *$4; + current_function_or_task->str = *$5; + append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); AstNode *outreg = new AstNode(AST_WIRE); - outreg->str = *$4; - outreg->is_signed = $2; - if ($3 != NULL) { - outreg->children.push_back($3); - outreg->is_signed = $2 || $3->is_signed; - $3->is_signed = false; + outreg->str = *$5; + outreg->is_signed = $3; + if ($4 != NULL) { + outreg->children.push_back($4); + outreg->is_signed = $3 || $4->is_signed; + $4->is_signed = false; } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; - delete $4; + delete $5; } task_func_body TOK_ENDFUNCTION { current_function_or_task = NULL; ast_stack.pop_back(); -- cgit v1.2.3 From a92a68ce521c1e86c0666b9add0c88d59154325e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 14:30:20 +0200 Subject: 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 366351ec0..1486b801e 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) -- cgit v1.2.3 From b37d70dfd7fbc7cacc2b5fc9f3915e27da5eec07 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 19 Aug 2014 13:44:56 +0200 Subject: 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 e4bf4f9f3..24cce6b8b 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::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; \ + } +#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::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) { \ + 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(OrGate, "$_OR_", A, B, Y) -DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y) -DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y) +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 7e052b091..8b3306f6f 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 -- cgit v1.2.3 From 38addd4c67905e3d1514ba839f07d94058e42560 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:42:28 +0200 Subject: Added support for global tasks and functions --- frontends/ast/ast.cc | 38 ++++++++++++++++++++++++----------- frontends/verilog/parser.y | 30 +++++++++++++++++---------- frontends/verilog/verilog_frontend.cc | 8 ++++---- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 0ea38b506..d59ff1bb6 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -945,21 +945,35 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump flag_icells = icells; flag_autowire = autowire; + std::vector global_decls; + log_assert(current_ast->type == AST_DESIGN); - for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) { - if (flag_icells && (*it)->str.substr(0, 2) == "\\$") - (*it)->str = (*it)->str.substr(1); - if (defer) - (*it)->str = "$abstract" + (*it)->str; - if (design->has((*it)->str)) { - if (!ignore_redef) - log_error("Re-definition of module `%s' at %s:%d!\n", + for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) + { + if ((*it)->type == AST_MODULE) + { + for (auto n : global_decls) + (*it)->children.push_back(n->clone()); + + if (flag_icells && (*it)->str.substr(0, 2) == "\\$") + (*it)->str = (*it)->str.substr(1); + + if (defer) + (*it)->str = "$abstract" + (*it)->str; + + if (design->has((*it)->str)) { + if (!ignore_redef) + log_error("Re-definition of module `%s' at %s:%d!\n", + (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); + log("Ignoring re-definition of module `%s' at %s:%d!\n", (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - log("Ignoring re-definition of module `%s' at %s:%d!\n", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); - continue; + continue; + } + + design->add(process_module(*it, defer)); } - design->add(process_module(*it, defer)); + else + global_decls.push_back(*it); } } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index bf9b21bb6..acd904e55 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -137,14 +137,21 @@ static void free_attr(std::map *al) %% -input: - module input | - defattr input | - /* empty */ { - for (auto &it : default_attr_list) - delete it.second; - default_attr_list.clear(); - }; +input: { + ast_stack.push_back(current_ast); +} design { + ast_stack.pop_back(); + log_assert(SIZE(ast_stack) == 0); + for (auto &it : default_attr_list) + delete it.second; + default_attr_list.clear(); +}; + +design: + module design | + defattr design | + task_func_decl design | + /* empty */; attr: { @@ -214,9 +221,9 @@ module: attr TOK_MODULE TOK_ID { do_not_require_port_stubs = false; AstNode *mod = new AstNode(AST_MODULE); - current_ast->children.push_back(mod); - current_ast_mod = mod; + ast_stack.back()->children.push_back(mod); ast_stack.push_back(mod); + current_ast_mod = mod; port_stubs.clear(); port_counter = 0; mod->str = *$3; @@ -227,7 +234,8 @@ module: frontend_verilog_yyerror("Missing details for module port `%s'.", port_stubs.begin()->first.c_str()); ast_stack.pop_back(); - log_assert(ast_stack.size() == 0); + log_assert(ast_stack.size() == 1); + current_ast_mod = NULL; }; module_para_opt: diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 4466e1cb6..195789086 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -285,10 +285,10 @@ struct VerilogFrontend : public Frontend { frontend_verilog_yylex_destroy(); for (auto &child : current_ast->children) { - log_assert(child->type == AST::AST_MODULE); - for (auto &attr : attributes) - if (child->attributes.count(attr) == 0) - child->attributes[attr] = AST::AstNode::mkconst_int(1, false); + if (child->type == AST::AST_MODULE) + for (auto &attr : attributes) + if (child->attributes.count(attr) == 0) + child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire); -- cgit v1.2.3 From 7bfc4ae12030648cd73686d3779c6d412a3c33c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:43:51 +0200 Subject: Added Verilog/AST support for DPI functions (dpi_call() still unimplemented) --- frontends/ast/Makefile.inc | 1 + frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 4 ++++ frontends/ast/dpicall.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++ frontends/ast/genrtlil.cc | 1 + frontends/ast/simplify.cc | 32 ++++++++++++++++++++++++++++++-- frontends/verilog/lexer.l | 22 ++++++++++++++++++++++ frontends/verilog/parser.y | 33 ++++++++++++++++++++++++++++++++- 8 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 frontends/ast/dpicall.cc diff --git a/frontends/ast/Makefile.inc b/frontends/ast/Makefile.inc index 993ead928..91d917c91 100644 --- a/frontends/ast/Makefile.inc +++ b/frontends/ast/Makefile.inc @@ -2,4 +2,5 @@ OBJS += frontends/ast/ast.o OBJS += frontends/ast/simplify.o OBJS += frontends/ast/genrtlil.o +OBJS += frontends/ast/dpicall.o diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d59ff1bb6..de38eff6c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -68,6 +68,7 @@ std::string AST::type2str(AstNodeType type) X(AST_MODULE) X(AST_TASK) X(AST_FUNCTION) + X(AST_DPI_FUNCTION) X(AST_WIRE) X(AST_MEMORY) X(AST_AUTOWIRE) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index ef54d76f4..88917c64b 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -46,6 +46,7 @@ namespace AST AST_MODULE, AST_TASK, AST_FUNCTION, + AST_DPI_FUNCTION, AST_WIRE, AST_MEMORY, @@ -278,6 +279,9 @@ namespace AST // set set_line_num and get_line_num to internal dummy functions (done by simplify() and AstModule::derive // to control the filename and linenum properties of new nodes not generated by a frontend parser) void use_internal_line_num(); + + // call a DPI function + AstNode *dpi_call(const std::string &rtype, const std::string &fname, const std::vector &argtypes, const std::vector &args); } namespace AST_INTERNAL diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc new file mode 100644 index 000000000..a1954dabf --- /dev/null +++ b/frontends/ast/dpicall.cc @@ -0,0 +1,44 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "ast.h" + +AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, const std::vector &argtypes, const std::vector &args) +{ + AST::AstNode *newNode = nullptr; + + log("Calling DPI function `%s' and returning `%s':\n", fname.c_str(), rtype.c_str()); + + log_assert(SIZE(args) == SIZE(argtypes)); + for (int i = 0; i < SIZE(args); i++) + if (argtypes[i] == "real" || argtypes[i] == "shortreal") + log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); + else + log(" arg %d (%s): %d\n", i, argtypes[i].c_str(), args[i]->bitsAsConst().as_int()); + + if (rtype == "real" || rtype == "shortreal") { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = 1234; + } else { + newNode = AstNode::mkconst_int(1234, false); + } + + return newNode; +} + diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 1936146b3..506c2bb25 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -753,6 +753,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // and are only accessed here thru this references case AST_TASK: case AST_FUNCTION: + case AST_DPI_FUNCTION: case AST_AUTOWIRE: case AST_LOCALPARAM: case AST_DEFPARAM: diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2572fa4a9..19f1d0554 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -226,7 +226,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, this_wire_scope[node->str] = node; } if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR || - node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_CELL) { + node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) { backup_scope[node->str] = current_scope[node->str]; current_scope[node->str] = node; } @@ -646,7 +646,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (current_scope.count(str) == 0) { for (auto node : current_ast_mod->children) { if ((node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR || - node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK) && str == node->str) { + node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION) && str == node->str) { current_scope[node->str] = node; break; } @@ -1442,6 +1442,34 @@ skip_dynamic_range_lvalue_expansion:; goto apply_newNode; } + if (current_scope.count(str) != 0 && current_scope[str]->type == AST_DPI_FUNCTION) + { + AstNode *dpi_decl = current_scope[str]; + + std::string rtype, fname; + std::vector argtypes; + std::vector args; + + rtype = RTLIL::unescape_id(dpi_decl->children.at(0)->str); + fname = RTLIL::unescape_id(dpi_decl->str); + + for (int i = 1; i < SIZE(dpi_decl->children); i++) + { + if (i-1 >= SIZE(children)) + log_error("Insufficient number of arguments in DPI function call at %s:%d.\n", filename.c_str(), linenum); + + argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str)); + args.push_back(children.at(i-1)->clone()); + while (args.back()->simplify(true, false, false, stage, -1, false, true)) { } + + if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) + log_error("Failed to evaluate DPI function with non-constant argument at %s:%d.\n", filename.c_str(), linenum); + } + + newNode = dpi_call(rtype, fname, argtypes, args); + goto apply_newNode; + } + if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum); } diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index fdb9bb02c..cf51aac82 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -74,6 +74,7 @@ YOSYS_NAMESPACE_END %x STRING %x SYNOPSYS_TRANSLATE_OFF %x SYNOPSYS_FLAGS +%x IMPORT_DPI %% @@ -274,6 +275,27 @@ supply1 { return TOK_SUPPLY1; } . /* ignore everything else */ "*/" { BEGIN(0); } +import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { + BEGIN(IMPORT_DPI); + return TOK_DPI_FUNCTION; +} + +[(),] { + return *yytext; +} + +[a-zA-Z_$][a-zA-Z0-9_$]* { + frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); + return TOK_ID; +} + +[ \t\r\n] /* ignore whitespaces */ + +";" { + BEGIN(0); + return *yytext; +} + "\\"[^ \t\r\n]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_ID; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index acd904e55..1d62bc3be 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -104,7 +104,7 @@ static void free_attr(std::map *al) %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT -%token TOK_POSEDGE TOK_NEGEDGE TOK_OR +%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL @@ -415,6 +415,16 @@ module_body_stmt: always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: + attr TOK_DPI_FUNCTION TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3)); + current_function_or_task->str = *$4; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $4; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; @@ -449,6 +459,27 @@ task_func_decl: ast_stack.pop_back(); }; +dpi_function_arg: + TOK_ID TOK_ID { + current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + delete $1; + delete $2; + } | + TOK_ID { + current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + delete $1; + }; + +opt_dpi_function_args: + '(' dpi_function_args ')' | + /* empty */; + +dpi_function_args: + dpi_function_args ',' dpi_function_arg | + dpi_function_args ',' | + dpi_function_arg | + /* empty */; + opt_signed: TOK_SIGNED { $$ = true; -- cgit v1.2.3 From 490d7a5bf2062481dfda656de86bfbeca83c080d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 13:09:47 +0200 Subject: Fixed memory leak in DPI function calls --- frontends/ast/simplify.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 19f1d0554..5cf64310b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1467,6 +1467,10 @@ skip_dynamic_range_lvalue_expansion:; } newNode = dpi_call(rtype, fname, argtypes, args); + + for (auto arg : args) + delete arg; + goto apply_newNode; } -- cgit v1.2.3 From 085c8e873d4d90129a952eba85836891635a7f8c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:11:51 +0200 Subject: Added AstNode::asInt() --- frontends/ast/ast.cc | 23 ++++++++++++++++++++++- frontends/ast/ast.h | 1 + frontends/ast/dpicall.cc | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index de38eff6c..2fc8f9835 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -792,9 +792,30 @@ int AstNode::isConst() return 0; } +uint64_t AstNode::asInt(bool is_signed) +{ + if (type == AST_CONSTANT) + { + RTLIL::Const v = bitsAsConst(64, is_signed); + uint64_t ret = 0; + + for (int i = 0; i < 64; i++) + if (v.bits.at(i) == RTLIL::State::S1) + ret |= uint64_t(1) << i; + + return ret; + } + + if (type == AST_REALVALUE) + return realvalue; + + log_abort(); +} + double AstNode::asReal(bool is_signed) { - if (type == AST_CONSTANT) { + if (type == AST_CONSTANT) + { RTLIL::Const val(bits); bool is_negative = is_signed && val.bits.back() == RTLIL::State::S1; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 88917c64b..0a4016736 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -247,6 +247,7 @@ namespace AST RTLIL::Const bitsAsConst(int width = -1); RTLIL::Const asAttrConst(); RTLIL::Const asParaConst(); + uint64_t asInt(bool is_signed); bool bits_only_01(); bool asBool(); diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index a1954dabf..965645cde 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -30,7 +30,7 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, if (argtypes[i] == "real" || argtypes[i] == "shortreal") log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); else - log(" arg %d (%s): %d\n", i, argtypes[i].c_str(), args[i]->bitsAsConst().as_int()); + log(" arg %d (%s): %lld\n", i, argtypes[i].c_str(), (long long)args[i]->asInt(args[i]->is_signed)); if (rtype == "real" || rtype == "shortreal") { newNode = new AstNode(AST_REALVALUE); -- cgit v1.2.3 From 6c5cafcd8bf4d6b12b4d510480a0ccc1adee7212 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:22:04 +0200 Subject: Added support for DPI function with different names in C and Verilog --- frontends/ast/simplify.cc | 8 ++++---- frontends/verilog/lexer.l | 8 ++++---- frontends/verilog/parser.y | 13 ++++++++++++- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5cf64310b..859058cb9 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1451,15 +1451,15 @@ skip_dynamic_range_lvalue_expansion:; std::vector args; rtype = RTLIL::unescape_id(dpi_decl->children.at(0)->str); - fname = RTLIL::unescape_id(dpi_decl->str); + fname = RTLIL::unescape_id(dpi_decl->children.at(1)->str); - for (int i = 1; i < SIZE(dpi_decl->children); i++) + for (int i = 2; i < SIZE(dpi_decl->children); i++) { - if (i-1 >= SIZE(children)) + if (i-2 >= SIZE(children)) log_error("Insufficient number of arguments in DPI function call at %s:%d.\n", filename.c_str(), linenum); argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str)); - args.push_back(children.at(i-1)->clone()); + args.push_back(children.at(i-2)->clone()); while (args.back()->simplify(true, false, false, stage, -1, false, true)) { } if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index cf51aac82..f79f81a9c 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -280,10 +280,6 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { return TOK_DPI_FUNCTION; } -[(),] { - return *yytext; -} - [a-zA-Z_$][a-zA-Z0-9_$]* { frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); return TOK_ID; @@ -296,6 +292,10 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { return *yytext; } +. { + return *yytext; +} + "\\"[^ \t\r\n]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_ID; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 1d62bc3be..22312c6d1 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -416,7 +416,7 @@ module_body_stmt: task_func_decl: attr TOK_DPI_FUNCTION TOK_ID TOK_ID { - current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3)); + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3), AstNode::mkconst_str(*$4)); current_function_or_task->str = *$4; append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); @@ -425,6 +425,17 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | + attr TOK_DPI_FUNCTION TOK_ID '=' TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$5), AstNode::mkconst_str(*$3)); + current_function_or_task->str = *$6; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $5; + delete $6; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; -- cgit v1.2.3 From ad146c25823505e8f9b3cb2b67ba00821a755375 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:33:40 +0200 Subject: Fixed small memory leak in ast simplify --- frontends/ast/simplify.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 859058cb9..68c17271c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1585,8 +1585,8 @@ skip_dynamic_range_lvalue_expansion:; { AstNode *arg = children[arg_count++]->clone(); AstNode *assign = child->is_input ? - new AstNode(AST_ASSIGN_EQ, wire_id, arg) : - new AstNode(AST_ASSIGN_EQ, arg, wire_id); + new AstNode(AST_ASSIGN_EQ, wire_id->clone(), arg) : + new AstNode(AST_ASSIGN_EQ, arg, wire_id->clone()); for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) { if (*it != current_block_child) @@ -1596,7 +1596,7 @@ skip_dynamic_range_lvalue_expansion:; } } - AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id->clone()); + AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id); cell_arg->str = child->str == str ? outport : child->str; cell->children.push_back(cell_arg); } -- cgit v1.2.3 From c2df5b9175fb11e054ffb8426287b82f2bb2582b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:40:49 +0200 Subject: 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 3d0ff7573..57c2a5b12 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 -- cgit v1.2.3 From 752650a062cb262b37f1c5ea62663e5c8c9c7928 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 12:20:23 +0200 Subject: Updated ABC to 4d547a5e065b --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4d86a8c91..a64c628ef 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 -- cgit v1.2.3 From a3494fa9ed32d7ff2b826dfc921e3a0139158880 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 13:58:36 +0200 Subject: 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 a64c628ef..e74175394 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 d59e68a50..6bd60d7b5 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 599c92d52..ce2487314 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 79c90628c..c6cbcabc9 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 d6e45f2d1..4cf61150e 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 000000000..c73684f1b --- /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 + -- cgit v1.2.3 From 74af3a2b7086acad45d15b590a0d23572e8c8734 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:22:09 +0200 Subject: Archibald Rust and Clifford Wolf: ffi-based dpi_call() --- Makefile | 2 +- README | 4 +- frontends/ast/dpicall.cc | 96 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index e74175394..8d7f2f8dd 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 a0e67e8a4..5c3286c20 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 965645cde..b79bd59eb 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -17,26 +17,110 @@ * */ +#include +#include #include "ast.h" +typedef void (*ffi_fptr) (); + +static ffi_fptr resolve_fn (std::string symbol_name) +{ + if (symbol_name.find(':') != std::string::npos) + { + int pos = symbol_name.find(':'); + std::string plugin_name = symbol_name.substr(0, pos); + std::string real_symbol_name = symbol_name.substr(pos+1); + + while (loaded_plugin_aliases.count(plugin_name)) + plugin_name = loaded_plugin_aliases.at(plugin_name); + + if (loaded_plugins.count(plugin_name) == 0) + log_error("unable to resolve '%s': can't find plugin `%s'\n", symbol_name.c_str(), plugin_name.c_str()); + + void *symbol = dlsym(loaded_plugins.at(plugin_name), real_symbol_name.c_str()); + + if (symbol == nullptr) + log_error("unable to resolve '%s': can't find symbol `%s' in plugin `%s'\n", + symbol_name.c_str(), real_symbol_name.c_str(), plugin_name.c_str()); + + return (ffi_fptr) symbol; + } + + for (auto &it : loaded_plugins) { + void *symbol = dlsym(it.second, symbol_name.c_str()); + if (symbol != nullptr) + return (ffi_fptr) symbol; + } + + void *symbol = dlsym(RTLD_DEFAULT, symbol_name.c_str()); + if (symbol != nullptr) + return (ffi_fptr) symbol; + + log_error("unable to resolve '%s'.\n", symbol_name.c_str()); +} + AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, const std::vector &argtypes, const std::vector &args) { AST::AstNode *newNode = nullptr; + union { double f64; float f32; int32_t i32; } value_store [args.size() + 1]; + ffi_type *types [args.size() + 1]; + void *values [args.size() + 1]; + ffi_cif cif; + int status; log("Calling DPI function `%s' and returning `%s':\n", fname.c_str(), rtype.c_str()); log_assert(SIZE(args) == SIZE(argtypes)); - for (int i = 0; i < SIZE(args); i++) - if (argtypes[i] == "real" || argtypes[i] == "shortreal") + for (int i = 0; i < SIZE(args); i++) { + if (argtypes[i] == "real") { + log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); + value_store[i].f64 = args[i]->asReal(args[i]->is_signed); + values[i] = &value_store[i].f64; + types[i] = &ffi_type_double; + } else if (argtypes[i] == "shortreal") { log(" arg %d (%s): %f\n", i, argtypes[i].c_str(), args[i]->asReal(args[i]->is_signed)); - else + value_store[i].f32 = args[i]->asReal(args[i]->is_signed); + values[i] = &value_store[i].f32; + types[i] = &ffi_type_double; + } else if (argtypes[i] == "integer") { log(" arg %d (%s): %lld\n", i, argtypes[i].c_str(), (long long)args[i]->asInt(args[i]->is_signed)); + value_store[i].i32 = args[i]->asInt(args[i]->is_signed); + values[i] = &value_store[i].i32; + types[i] = &ffi_type_sint32; + } else { + log_error("invalid argtype '%s' for argument %d.\n", argtypes[i].c_str(), i); + } + } + + if (rtype == "integer") { + types[args.size()] = &ffi_type_slong; + values[args.size()] = &value_store[args.size()].i32; + } else if (rtype == "shortreal") { + types[args.size()] = &ffi_type_float; + values[args.size()] = &value_store[args.size()].f32; + } else if (rtype == "real") { + types[args.size()] = &ffi_type_double; + values[args.size()] = &value_store[args.size()].f64; + } else { + log_error("invalid rtype '%s'.\n", rtype.c_str()); + } + + if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, args.size(), types[args.size()], types)) != FFI_OK) + log_error("ffi_prep_cif failed: status %d.\n", status); - if (rtype == "real" || rtype == "shortreal") { + ffi_call(&cif, resolve_fn(fname.c_str()), values[args.size()], values); + + if (rtype == "real") { + newNode = new AstNode(AST_REALVALUE); + newNode->realvalue = value_store[args.size()].f64; + log(" return realvalue: %g\n", newNode->asReal(true)); + } else if (rtype == "shortreal") { newNode = new AstNode(AST_REALVALUE); - newNode->realvalue = 1234; + newNode->realvalue = value_store[args.size()].f32; + log(" return realvalue: %g\n", newNode->asReal(true)); } else { - newNode = AstNode::mkconst_int(1234, false); + newNode = AstNode::mkconst_int(value_store[args.size()].i32, false); + log(" return integer: %lld\n", (long long)newNode->asInt(true)); } return newNode; -- cgit v1.2.3 From e218f0eacf7cbcfa0736cb2d66bba0010e8e6799 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:30:29 +0200 Subject: Added support for non-standard : DPI syntax --- frontends/verilog/parser.y | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 22312c6d1..3512538ca 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -436,6 +436,18 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | + attr TOK_DPI_FUNCTION TOK_ID ':' TOK_ID '=' TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$7), AstNode::mkconst_str(*$3 + ":" + RTLIL::unescape_id(*$5))); + current_function_or_task->str = *$8; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $5; + delete $7; + delete $8; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; -- cgit v1.2.3 From ba83a7bdc641c68344b41f407323c76b8c62c674 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:37:14 +0200 Subject: Added DPI-C documentation to README file --- README | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README b/README index 5c3286c20..2e713ffef 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 -- cgit v1.2.3 From 98442e019d745f1d61983c071decfa3ebc1ff0cf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 16:09:13 +0200 Subject: Added emscripten (emcc) support to build system and some build fixes --- 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 8d7f2f8dd..ca595d9cd 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 2fc8f9835..1e43875ae 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -844,7 +844,11 @@ RTLIL::Const AstNode::realAsConst(int width) { double v = round(realvalue); RTLIL::Const result; +#ifdef EMSCRIPTEN + if (!isfinite(v)) { +#else if (!std::isfinite(v)) { +#endif result.bits = std::vector(width, RTLIL::State::Sx); } else { bool is_negative = v < 0; diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc index b79bd59eb..2eb104fa0 100644 --- a/frontends/ast/dpicall.cc +++ b/frontends/ast/dpicall.cc @@ -17,9 +17,12 @@ * */ +#include "ast.h" + +#ifdef YOSYS_ENABLE_PLUGINS + #include #include -#include "ast.h" typedef void (*ffi_fptr) (); @@ -126,3 +129,12 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, return newNode; } +#else /* YOSYS_ENABLE_PLUGINS */ + +AST::AstNode *AST::dpi_call(const std::string&, const std::string &fname, const std::vector&, const std::vector&) +{ + log_error("Can't call DPI function `%s': this version of yosys is built without plugin support\n", fname.c_str()); +} + +#endif /* YOSYS_ENABLE_PLUGINS */ + diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 8c2e9a48e..515da25ce 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 2ef023eb3..4c4cbd6de 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 6bd60d7b5..e778e1389 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 24cce6b8b..22bff7bdb 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 8b3306f6f..ebfe4ca29 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 ce2487314..7b8173b6a 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 c73684f1b..4e8234d16 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 4f6b811bc..fc6e972ee 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(); -- cgit v1.2.3 From fff12c719fc2d61e36e85f27080a4043078b0929 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 17:20:28 +0200 Subject: 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 fabc80ec0..dea24227f 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"); -- cgit v1.2.3 From 5dce303a2a2c27d50e99856b6f33467798e13020 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 13:54:21 +0200 Subject: Changed backend-api from FILE to std::ostream --- backends/blif/blif.cc | 96 ++++---- backends/btor/btor.cc | 130 +++++----- backends/edif/edif.cc | 138 +++++------ 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, 713 insertions(+), 728 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index b9b68b979..919022abe 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 a81d8f159..9b770518b 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 ecdfaabfc..ccedd91d2 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); - - fprintf(f, " (external LIB\n"); - fprintf(f, " (edifLevel 0)\n"); - fprintf(f, " (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"); - - 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("(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); + + *f << stringf(" (external LIB\n"); + *f << stringf(" (edifLevel 0)\n"); + *f << stringf(" (technology (numberDefinition))\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"); + + *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 b7088f599..13d3a8e42 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); - - fclose(f); + ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n); - 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 b0fec4889..138e10efb 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 9faed77c9..97ead3c64 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 be0086ffd..b057063cd 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 f6095a5aa..d1fa55b94 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 c40830ef2..7e6ef5ab9 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 b742a5495..2b4b5db5b 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 a9e21e6dd..95ed0cbd1 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 d7e4281c2..f2c6ad29e 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 22bff7bdb..28a451345 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 c6cbcabc9..bfadb5ffc 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 ebf4d77fc..eaa0f9fa3 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 d26002277..eed0f75f9 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; -- cgit v1.2.3 From 19cff41eb4261b20374058f16807a229af46f304 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:03:55 +0200 Subject: Changed frontend-api from FILE to std::istream --- 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 97ead3c64..8502d90fc 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 2d4b99c52..f6f926db1 100644 --- a/frontends/ilang/ilang_frontend.cc +++ b/frontends/ilang/ilang_frontend.cc @@ -45,15 +45,16 @@ struct IlangFrontend : public Frontend { log("representation of a design in yosys's internal format.)\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { log_header("Executing ILANG frontend.\n"); extra_args(f, filename, args, 1); log("Input filename: %s\n", filename.c_str()); + ILANG_FRONTEND::lexin = f; ILANG_FRONTEND::current_design = design; rtlil_frontend_ilang_yydebug = false; - rtlil_frontend_ilang_yyrestart(f); + rtlil_frontend_ilang_yyrestart(NULL); rtlil_frontend_ilang_yyparse(); rtlil_frontend_ilang_yylex_destroy(); } diff --git a/frontends/ilang/ilang_frontend.h b/frontends/ilang/ilang_frontend.h index 317ec0d51..b04d6c512 100644 --- a/frontends/ilang/ilang_frontend.h +++ b/frontends/ilang/ilang_frontend.h @@ -26,12 +26,11 @@ #define ILANG_FRONTEND_H #include "kernel/yosys.h" -#include YOSYS_NAMESPACE_BEGIN namespace ILANG_FRONTEND { - void ilang_frontend(FILE *f, RTLIL::Design *design); + extern std::istream *lexin; extern RTLIL::Design *current_design; } @@ -42,7 +41,7 @@ int rtlil_frontend_ilang_yylex(void); void rtlil_frontend_ilang_yyerror(char const *s); void rtlil_frontend_ilang_yyrestart(FILE *f); int rtlil_frontend_ilang_yyparse(void); -void rtlil_frontend_ilang_yylex_destroy(void); +int rtlil_frontend_ilang_yylex_destroy(void); int rtlil_frontend_ilang_yyget_lineno(void); #endif diff --git a/frontends/ilang/lexer.l b/frontends/ilang/lexer.l index f3bdeb1a4..4109cd4bc 100644 --- a/frontends/ilang/lexer.l +++ b/frontends/ilang/lexer.l @@ -29,9 +29,12 @@ #pragma clang diagnostic ignored "-Wdeprecated-register" #endif -#include "kernel/rtlil.h" +#include "ilang_frontend.h" #include "parser.tab.h" +#define YY_INPUT(buf,result,max_size) \ + result = ILANG_FRONTEND::lexin->readsome(buf, max_size); + %} %option yylineno diff --git a/frontends/ilang/parser.y b/frontends/ilang/parser.y index e1ef39a55..a5cc06898 100644 --- a/frontends/ilang/parser.y +++ b/frontends/ilang/parser.y @@ -27,6 +27,7 @@ #include "ilang_frontend.h" YOSYS_NAMESPACE_BEGIN namespace ILANG_FRONTEND { + std::istream *lexin; RTLIL::Design *current_design; RTLIL::Module *current_module; RTLIL::Wire *current_wire; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 83bfce371..a9ab022a4 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -430,7 +430,7 @@ struct LibertyFrontend : public Frontend { log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { bool flag_lib = false; bool flag_ignore_redef = false; @@ -467,7 +467,7 @@ struct LibertyFrontend : public Frontend { } extra_args(f, filename, args, argidx); - LibertyParser parser(f); + LibertyParser parser(*f); int cell_count = 0; for (auto cell : parser.ast->children) diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index f79f81a9c..c9302aba8 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -63,6 +63,9 @@ YOSYS_NAMESPACE_END frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \ return TOK_ID; +#define YY_INPUT(buf,result,max_size) \ + result = lexin->readsome(buf, max_size); + %} %option yylineno diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 3512538ca..a9f69a49c 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -58,6 +58,7 @@ namespace VERILOG_FRONTEND { bool do_not_require_port_stubs; bool default_nettype_wire; bool sv_mode; + std::istream *lexin; } YOSYS_NAMESPACE_END diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index ae139741a..f83433219 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -193,7 +193,7 @@ static std::string next_token(bool pass_newline = false) return token; } -static void input_file(FILE *f, std::string filename) +static void input_file(std::istream &f, std::string filename) { char buffer[513]; int rc; @@ -202,14 +202,14 @@ static void input_file(FILE *f, std::string filename) auto it = input_buffer.begin(); input_buffer.insert(it, "`file_push " + filename + "\n"); - while ((rc = fread(buffer, 1, sizeof(buffer)-1, f)) > 0) { + while ((rc = f.readsome(buffer, sizeof(buffer)-1)) > 0) { buffer[rc] = 0; input_buffer.insert(it, buffer); } input_buffer.insert(it, "\n`file_pop\n"); } -std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) +std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) { std::set defines_with_args; std::map defines_map(pre_defines_map); @@ -288,27 +288,28 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m else fn = fn.substr(0, pos) + fn.substr(pos+1); } - FILE *fp = fopen(fn.c_str(), "r"); - if (fp == NULL && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) { + std::ifstream ff; + ff.clear(); + ff.open(fn.c_str()); + if (ff.fail() && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) { // if the include file was not found, it is not given with an absolute path, and the // currently read file is given with a path, then try again relative to its directory - std::string fn2 = filename.substr(0, filename.rfind('/')+1) + fn; - fp = fopen(fn2.c_str(), "r"); + ff.clear(); + ff.open(filename.substr(0, filename.rfind('/')+1) + fn); } - if (fp == NULL && fn.size() > 0 && fn[0] != '/') { + if (ff.fail() && fn.size() > 0 && fn[0] != '/') { // if the include file was not found and it is not given with an absolute path, then // search it in the include path for (auto incdir : include_dirs) { - std::string fn2 = incdir + '/' + fn; - fp = fopen(fn2.c_str(), "r"); - if (fp != NULL) break; + ff.clear(); + ff.open(incdir + '/' + fn); + if (!ff.fail()) break; } } - if (fp != NULL) { - input_file(fp, fn); - fclose(fp); - } else + if (ff.fail()) output_code.push_back("`file_notfound " + fn); + else + input_file(ff, fn); continue; } diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 195789086..c63fbb08a 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -136,7 +136,7 @@ struct VerilogFrontend : public Frontend { log("the syntax of the code, rather than to rely on read_verilog for that.\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { bool flag_dump_ast1 = false; bool flag_dump_ast2 = false; @@ -269,18 +269,18 @@ struct VerilogFrontend : public Frontend { current_ast = new AST::AstNode(AST::AST_DESIGN); default_nettype_wire = true; - FILE *fp = f; + lexin = f; std::string code_after_preproc; if (!flag_nopp) { - code_after_preproc = frontend_verilog_preproc(f, filename, defines_map, include_dirs); + code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, include_dirs); if (flag_ppdump) log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str()); - fp = fmemopen((void*)code_after_preproc.c_str(), code_after_preproc.size(), "r"); + lexin = new std::istringstream(code_after_preproc); } frontend_verilog_yyset_lineno(1); - frontend_verilog_yyrestart(fp); + frontend_verilog_yyrestart(NULL); frontend_verilog_yyparse(); frontend_verilog_yylex_destroy(); @@ -294,7 +294,7 @@ struct VerilogFrontend : public Frontend { AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire); if (!flag_nopp) - fclose(fp); + delete lexin; delete current_ast; current_ast = NULL; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index dac5b3d02..af6495f8f 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -50,10 +50,13 @@ namespace VERILOG_FRONTEND // running in SystemVerilog mode extern bool sv_mode; + + // lexer input stream + extern std::istream *lexin; } // the pre-processor -std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); +std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); YOSYS_NAMESPACE_END diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index f0545700a..8b6f62a63 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -177,11 +177,11 @@ struct Vhdl2verilogPass : public Pass { log_error("Execution of command \"%s\" failed: the shell returned %d\n", command.c_str(), WEXITSTATUS(ret)); if (out_file.empty()) { - f = fopen(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str(), "rt"); - if (f == NULL) + std::ifstream ff; + ff.open(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str()); + if (ff.fail()) log_error("Can't open vhdl2verilog output file `vhdl2verilog_output.v'.\n"); - Frontend::frontend_call(design, f, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog"); - fclose(f); + Frontend::frontend_call(design, &ff, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog"); } log_header("Removing temp directory `%s':\n", tempdir_name); diff --git a/kernel/register.cc b/kernel/register.cc index 95ed0cbd1..5f4e71d1f 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 f2c6ad29e..a49675ed2 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 bfadb5ffc..87c99d1f6 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 fc6e972ee..3468eae78 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 a7cd7b438..813e215ba 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 6ce771ac4..7e39040c4 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 eaa0f9fa3..221e9e49d 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 2ff551537..612fa1117 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 eff268bbb..247487424 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 d9d8ddd6a..beacdfa6f 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; -- cgit v1.2.3 From 58367cd87a5d2bac1de81512f60939c080b3b9ef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:14:58 +0200 Subject: Removed compatbility.{h,cc}: Not using open_memstream/fmemopen anymore --- 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 ca595d9cd..327570631 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 c63fbb08a..c6d4a0b79 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -27,11 +27,8 @@ */ #include "verilog_frontend.h" -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include "libs/sha1/sha1.h" -#include #include YOSYS_NAMESPACE_BEGIN diff --git a/kernel/compatibility.cc b/kernel/compatibility.cc deleted file mode 100644 index 4c4cbd6de..000000000 --- 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 c7603c8a5..000000000 --- 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 2b4b5db5b..1b0eb6649 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 b1c44b46b..e2b4db87b 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 5f4e71d1f..a53bd84c7 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 87c99d1f6..9a4826caa 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 -- cgit v1.2.3 From c642dd0b3eb1390b6c1acd39c1f19797da27b190 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:32:00 +0200 Subject: 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 beacdfa6f..660f1b388 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()) { -- cgit v1.2.3 From 9c5a63c52c24f0570557b4bf7340b41666cf44b6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 13:27:40 +0200 Subject: 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 c6da4bb42..08ae9e929 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: -- cgit v1.2.3 From eda603105e2aa72441bfc07662774a20f3b978fe Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 15:14:00 +0200 Subject: 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 28a451345..df4d8b092 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 ebfe4ca29..d58873570 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; -- cgit v1.2.3 From 641501203c534b00a0ae3ad6844f8759d6bc8549 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 15:14:45 +0200 Subject: 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 58a7f7dfd..c4f4bba3f 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); -- cgit v1.2.3 From 7bbbe3580d249d8abab55ab4ef2703bf3dc51a3c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 24 Aug 2014 17:08:07 +0200 Subject: 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 c4f4bba3f..a602cf5fd 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; -- cgit v1.2.3 From 672b2c6db1feb252e3fe907f1e24ae273156638a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 25 Aug 2014 12:48:20 +0200 Subject: Checking for valid CONFIG value in Makefile --- Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 327570631..09b2adbc3 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) -- cgit v1.2.3 From e70480655e8d1326bc4828ccada20e7669fa719f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 26 Aug 2014 10:11:46 +0200 Subject: Print Makefile.conf as make info message --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 09b2adbc3..fa42cf7d0 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 -- cgit v1.2.3 From 084685f4805e643c4799abcbfe114ab8c1138b72 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 26 Aug 2014 12:51:08 +0200 Subject: 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 3a6008721..91de364fe 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; } -- cgit v1.2.3 From cfb43383198aeb59e461bc0565a9a178d2ae6f01 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 27 Aug 2014 12:13:53 +0200 Subject: Fixed printing of multi-line Makefile.conf --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fa42cf7d0..49a387263 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 -- cgit v1.2.3 From d148b0af0d5d1a039b13b9e610859a2e55da945e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 27 Aug 2014 19:44:12 +0200 Subject: 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 7e39040c4..07993b868 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); -- cgit v1.2.3 From ab019b0bd505ccd63ba1d45013fa163134f6e13b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 14:11:57 +0200 Subject: 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 871478dee..d1d73db6d 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_) -- cgit v1.2.3 From f910481f35109d7333088ac79bb25729e516fa00 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 14:34:49 +0200 Subject: 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 d1d73db6d..451f00fcb 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); -- cgit v1.2.3 From 3a7d5d188d4b9cfeb225e0f5dea07ee7a40eceed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 14:43:06 +0200 Subject: 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 9c0da0a37..ea10cdf80 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()); -- cgit v1.2.3 From eb571cba6a8a2a53b179578d07798517addac7c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 15:12:39 +0200 Subject: 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 1486b801e..452b64b8f 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 -- cgit v1.2.3 From 66763fad4e3f93b11fbc72acd94174a56084ad17 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 17:39:08 +0200 Subject: Using worker class in memory_map --- passes/memory/memory_map.cc | 457 ++++++++++++++++++++++---------------------- 1 file changed, 231 insertions(+), 226 deletions(-) diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 8dc66f2cd..878994679 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; + 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; + } } - } - log("Mapping memory cell %s in module %s:\n", cell->name.c_str(), module->name.c_str()); + 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; + std::vector data_reg_in; + std::vector data_reg_out; - int count_static = 0; + int count_static = 0; - for (int i = 0; i < mem_size; i++) - { - if (static_cells_map.count(i) > 0) + for (int i = 0; i < mem_size; i++) { - 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 (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)); + } - 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()); + 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"); + 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; + 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()); + 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); + log(" created %d $dff cells and %d static cells of width %d.\n", mem_size-count_static, count_static, mem_width); - std::vector rd_signals; - rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width)); + int count_dff = 0, count_mux = 0, count_wrmux = 0; - if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1) + for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++) { - if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1) - { - 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::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits); - RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits); + std::vector rd_signals; + rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width)); - c->setPort("\\Q", RTLIL::SigSpec(w)); - rd_addr = RTLIL::SigSpec(w); - } - else + if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1) { - 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++; + if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1) + { + 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, "$d"), mem_width); + RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits); - rd_signals.clear(); - rd_signals.push_back(RTLIL::SigSpec(w)); - c->setPort("\\D", rd_signals.back()); + 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++) + for (int j = 0; j < mem_abits; j++) { - 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++; + std::vector next_rd_signals; - 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")); - } + 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++; - next_rd_signals.swap(rd_signals); - } + 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)); - for (int j = 0; j < mem_size; j++) - module->connect(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); - } + next_rd_signals.push_back(c->getPort("\\A")); + next_rd_signals.push_back(c->getPort("\\B")); + } - log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); + next_rd_signals.swap(rd_signals); + } - for (int i = 0; i < mem_size; i++) - { - if (static_cells_map.count(i) > 0) - continue; + for (int j = 0; j < mem_size; j++) + module->connect(RTLIL::SigSig(rd_signals[j], data_reg_out[j])); + } - RTLIL::SigSpec sig = data_reg_out[i]; + log(" read interface: %d $dff and %d $mux cells.\n", count_dff, count_mux); - for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++) + for (int i = 0; i < mem_size; i++) { - 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 (static_cells_map.count(i) > 0) + continue; - RTLIL::Wire *w = w_seladdr; + RTLIL::SigSpec sig = data_reg_out[i]; - if (wr_bit != RTLIL::SigSpec(1, 1)) + 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()) { - 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)); + 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; } - - 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)); - } + 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 blocks of $eq, $and and $mux cells.\n", count_wrmux); - module->remove(cell); -} + 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; -- cgit v1.2.3 From dfbd7dd15a1520ce0c01d2722aaacbf7b7be71fa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:17:22 +0200 Subject: Fixed module->addPmux() --- kernel/rtlil.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index df4d8b092..7ba6911a2 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); \ -- cgit v1.2.3 From 6ff46323a30d710a9518cffb8c2ae9a5621b7bfc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:18:15 +0200 Subject: 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 878994679..eecb6f35d 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); } -- cgit v1.2.3 From 88db09255baa92facbe2736937ef113dc1503e9b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:34:07 +0200 Subject: 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 2477181a6..24983f1a5 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 d719c46bd..fb766eec9 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 9ae1c1555..5003280ef 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 -- cgit v1.2.3 From 4724d94fbce587b39cd7343dc8de3b859311f55c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:59:05 +0200 Subject: 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 515da25ce..c1bb1d036 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 7ba6911a2..96b651d89 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 3eb2f9469..82473f6a2 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 8c0a54e4e..09ffa9a68 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 452b64b8f..d6b249456 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), -- cgit v1.2.3 From 2a1b08aeb34b7d5f2df1a43c9ef1f99abacb9cae Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 19:37:12 +0200 Subject: 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 96b651d89..72eced914 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 d58873570..e35c3c681 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 b6d36f0e3..b20521d1e 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 d47e4513e..cc4fe4cc8 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 a602cf5fd..ad6961872 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 daa063812..2c5dcf668 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 e2b4243d1..e9e2bb399 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 bbf94d3b4..48f406f65 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 e9a5e7fde..66f5e630c 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 3d12baa7d..000000000 --- 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 - -- cgit v1.2.3 From 8649b57b6f4c3a4322acaf73f5c02d5119629c1e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 17:06:36 +0200 Subject: 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 72eced914..403bb6d28 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 c02900a6c..5d1c11c9e 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 a4b8be0c1..4a2af304d 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 d6b249456..c0645267d 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 + -- cgit v1.2.3 From 0b6769af3f7578dfb31c801014413174bd230208 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 17:07:07 +0200 Subject: 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 e35c3c681..907600408 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); -- cgit v1.2.3 From a1c7d4a8e24c14eae7f1f7e383f18b25a190875b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 17:42:38 +0200 Subject: 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 c1bb1d036..4a8be04d3 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; -- cgit v1.2.3 From be44157c0f07c3bcca2363b5ce95a71fe7ad6dd9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 18:07:48 +0200 Subject: Added RTLIL::Const::size() --- kernel/rtlil.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 907600408..935329384 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 -- cgit v1.2.3 From 83ec3fa2045cac1f29ea4bfb2c8c052c31b083a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 18:08:26 +0200 Subject: 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 29717aad5..7bfdb8955 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); } -- cgit v1.2.3 From e3664066d5684af444c5a1edb02b9e7543cba38d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 31 Aug 2014 18:08:42 +0200 Subject: 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 4a2af304d..d9554bcf7 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; } } -- cgit v1.2.3 From e07698818dfe3c8e5f87b13090c7e70d22189e2a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 11:36:02 +0200 Subject: 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 9b770518b..3482faa70 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 403bb6d28..f237f57ef 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 935329384..b8733c4ec 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 66f5e630c..4b76a5a2d 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"; } -- cgit v1.2.3 From d5148f2e013a7c0e4cced043d0a01a7fb0d3f069 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 11:45:26 +0200 Subject: Moved "share" and "wreduce" to passes/opt/ --- passes/cmds/Makefile.inc | 1 - passes/cmds/wreduce.cc | 353 ----------------- passes/opt/Makefile.inc | 2 + passes/opt/share.cc | 987 +++++++++++++++++++++++++++++++++++++++++++++++ passes/opt/wreduce.cc | 353 +++++++++++++++++ passes/sat/Makefile.inc | 1 - passes/sat/share.cc | 987 ----------------------------------------------- 7 files changed, 1342 insertions(+), 1342 deletions(-) delete mode 100644 passes/cmds/wreduce.cc create mode 100644 passes/opt/share.cc create mode 100644 passes/opt/wreduce.cc delete mode 100644 passes/sat/share.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 4cf61150e..eba61d1df 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/cmds/wreduce.cc b/passes/cmds/wreduce.cc deleted file mode 100644 index 2269859d1..000000000 --- a/passes/cmds/wreduce.cc +++ /dev/null @@ -1,353 +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. - * - */ - -#include "kernel/yosys.h" -#include "kernel/sigtools.h" -#include "kernel/modtools.h" - -USING_YOSYS_NAMESPACE -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" << "$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"; - } -}; - -struct WreduceWorker -{ - WreduceConfig *config; - Module *module; - ModIndex mi; - - std::set> work_queue_cells; - std::set work_queue_bits; - - WreduceWorker(WreduceConfig *config, Module *module) : - config(config), module(module), mi(module) { } - - 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 - - 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()) - 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)); - - 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, int max_port_size, bool &port_signed, bool &did_something) - { - 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")) - port_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 (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 { - while (SIZE(sig) > 1 && 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); - did_something = true; - } - } - - void run_cell(Cell *cell) - { - bool did_something = false; - - if (!cell->type.in(config->supported_cell_types)) - return; - - if (cell->type.in("$mux", "$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"))); - } - - bool port_a_signed = false; - bool port_b_signed = false; - - if (max_port_a_size >= 0) - run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something); - - if (max_port_b_size >= 0) - 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 - - SigSpec sig = mi.sigmap(cell->getPort("\\Y")); - - int bits_removed = 0; - 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; - - sig.remove(SIZE(sig)-1); - bits_removed++; - } - } - - if (cell->type.in("$pos", "$bu0", "$add", "$mul", "$and", "$or", "$xor")) - { - 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")); - - 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++; - } - } - - 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)); - cell->setPort("\\Y", sig); - did_something = true; - } - - if (did_something) { - cell->fixup_parameters(); - run_cell(cell); - } - } - - 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()) - 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)) - 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); - } - } - } -}; - -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. 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) - { - WreduceConfig config; - - log_header("Executing WREDUCE pass (reducing word size of cells).\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 - diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index 9dfb32c87..3a8d27f93 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/opt/share.cc b/passes/opt/share.cc new file mode 100644 index 000000000..5f3cf4214 --- /dev/null +++ b/passes/opt/share.cc @@ -0,0 +1,987 @@ +/* + * 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/satgen.h" +#include "kernel/sigtools.h" +#include "kernel/modtools.h" + +PRIVATE_NAMESPACE_BEGIN + +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; + + CellTypes fwd_ct, cone_ct; + ModWalker modwalker; + + std::set cells_to_remove; + std::set recursion_state; + + + // ------------------------------------------------------------------------------ + // 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_bits; + std::set visited_cells; + + queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end()); + + 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()); + } + + terminal_bits.insert(queue_bits.begin(), queue_bits.end()); + + while (!queue_bits.empty()) + { + std::set portbits; + modwalker.get_drivers(portbits, queue_bits); + queue_bits.clear(); + + for (auto &pbit : portbits) { + if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { + 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); + } + 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_bits.insert(bits.begin(), bits.end()); + visited_cells.insert(pbit.cell); + } + } + } + } + + + // --------------------------------------------------- + // Find shareable cells and compatible groups of cells + // --------------------------------------------------- + + std::set shareable_cells; + + void find_shareable_cells() + { + for (auto &it : module->cells_) + { + RTLIL::Cell *cell = it.second; + + 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) { + shareable_cells.insert(cell); + continue; + } + + if (cell->type == "$memrd") { + if (!cell->parameters.at("\\CLK_ENABLE").as_bool()) + 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) + 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) + shareable_cells.insert(cell); + continue; + } + + if (generic_ops.count(cell->type)) { + if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 10) + shareable_cells.insert(cell); + continue; + } + } + } + + 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 (config.generic_uni_ops.count(c1->type)) + { + if (!config.opt_aggressive) + { + int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); + int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); + + 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(); + 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; + } + + 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; + + 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); + } + + + // ----------------------- + // Create replacement cell + // ----------------------- + + RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act) + { + log_assert(c1->type == c2->type); + + if (config.generic_uni_ops.count(c1->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->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->getPort("\\A"); + new_a.append_bit(RTLIL::State::S0); + unsigned_cell->setPort("\\A", new_a); + } + 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->getPort("\\A"); + RTLIL::SigSpec y1 = c1->getPort("\\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)->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); + + 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->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)); + + 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) + { + 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")); + 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->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->getPort("\\A"); + new_a.append_bit(RTLIL::State::S0); + unsigned_cell->setPort("\\A", new_a); + } + 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->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->getPort("\\B"); + new_b.append_bit(RTLIL::State::S0); + unsigned_cell->setPort("\\B", new_b); + } + 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(); + + 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->getPort("\\A"); + RTLIL::SigSpec b1 = c1->getPort("\\B"); + RTLIL::SigSpec y1 = c1->getPort("\\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()); + 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.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)->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)->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)->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); + RTLIL::Wire *y = module->addWire(NEW_ID, y_width); + + 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; + supercell->parameters["\\B_WIDTH"] = b_width; + supercell->parameters["\\Y_WIDTH"] = y_width; + supercell->setPort("\\A", a); + supercell->setPort("\\B", b); + 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)); + + 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(); + } + + + // ------------------------------------------- + // 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->getPort("\\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 + // -------------------------------------------------------- + + std::map>> activation_patterns_cache; + + bool sort_check_activation_pattern(std::pair &p) + { + std::map p_bits; + + 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; + } + + 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); + } + + return true; + } + + 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 (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, driven_data_muxes; + + 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)); + 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); + } + } + + recursion_state.insert(cell); + + for (auto c : driven_data_muxes) + { + const std::set> &c_patterns = find_cell_activation_patterns(c, indent); + + 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->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)) + 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_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); + } + } + + 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)); + RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; + module->connect(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); + cells_to_remove.insert(cell); + } + + return activation_patterns_cache[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; + } + + 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->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)); + } + if (all_cases_wire->width == 1) + return all_cases_wire; + return module->ReduceOr(NEW_ID, all_cases_wire); + } + + + // ------------- + // Setup and run + // ------------- + + 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(); + 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_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", + SIZE(shareable_cells), 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)); + + 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"); + cells_to_remove.insert(cell); + continue; + } + + 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); + + if (candidates.empty()) { + log(" No candidates found.\n"); + continue; + } + + log(" Found %d candidates:", SIZE(candidates)); + for (auto c : candidates) + log(" %s", log_id(c)); + log("\n"); + + 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); + + if (other_cell_activation_patterns.empty()) { + 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"); + shareable_cells.erase(other_cell); + continue; + } + + 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); + + std::set sat_cells; + std::set bits_queue; + + std::vector cell_active, other_cell_active; + RTLIL::SigSpec all_ctrl_signals; + + 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 : 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); + } + + 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)) { + 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); + } + + if (config.opt_fast && sat_cells.size() > 100) + 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; + + 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", + 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), 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; + } + + log(" According to the SAT solver this pair of cells can be shared.\n"); + shareable_cells.erase(other_cell); + + int cell_select_score = 0; + int other_cell_select_score = 0; + + for (auto &p : filtered_cell_activation_patterns) + cell_select_score += p.first.size(); + + for (auto &p : filtered_other_cell_activation_patterns) + other_cell_select_score += p.first.size(); + + RTLIL::Cell *supercell; + 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); + 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); + 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(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); + + cells_to_remove.insert(cell); + cells_to_remove.insert(other_cell); + 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->remove(c); + } + } + + log_assert(recursion_state.empty()); + } +}; + +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(" -force\n"); + log(" Per default the selection of cells that is considered for sharing is\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 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"); + } + 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_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; + for (argidx = 1; argidx < args.size(); argidx++) { + 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; + } + extra_args(args, argidx, design); + + for (auto &mod_it : design->modules_) + if (design->selected(mod_it.second)) + ShareWorker(config, design, mod_it.second); + } +} SharePass; + +PRIVATE_NAMESPACE_END + diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc new file mode 100644 index 000000000..2269859d1 --- /dev/null +++ b/passes/opt/wreduce.cc @@ -0,0 +1,353 @@ +/* + * 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" + +USING_YOSYS_NAMESPACE +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" << "$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"; + } +}; + +struct WreduceWorker +{ + WreduceConfig *config; + Module *module; + ModIndex mi; + + std::set> work_queue_cells; + std::set work_queue_bits; + + WreduceWorker(WreduceConfig *config, Module *module) : + config(config), module(module), mi(module) { } + + 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 + + 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()) + 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)); + + 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, int max_port_size, bool &port_signed, bool &did_something) + { + 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")) + port_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 (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 { + while (SIZE(sig) > 1 && 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); + did_something = true; + } + } + + void run_cell(Cell *cell) + { + bool did_something = false; + + if (!cell->type.in(config->supported_cell_types)) + return; + + if (cell->type.in("$mux", "$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"))); + } + + bool port_a_signed = false; + bool port_b_signed = false; + + if (max_port_a_size >= 0) + run_reduce_inport(cell, 'A', max_port_a_size, port_a_signed, did_something); + + if (max_port_b_size >= 0) + 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 + + SigSpec sig = mi.sigmap(cell->getPort("\\Y")); + + int bits_removed = 0; + 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; + + sig.remove(SIZE(sig)-1); + bits_removed++; + } + } + + if (cell->type.in("$pos", "$bu0", "$add", "$mul", "$and", "$or", "$xor")) + { + 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")); + + 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++; + } + } + + 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)); + cell->setPort("\\Y", sig); + did_something = true; + } + + if (did_something) { + cell->fixup_parameters(); + run_cell(cell); + } + } + + 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()) + 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)) + 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); + } + } + } +}; + +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. 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) + { + WreduceConfig config; + + log_header("Executing WREDUCE pass (reducing word size of cells).\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 + diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index 9aa806429..4fa6bf0d4 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 diff --git a/passes/sat/share.cc b/passes/sat/share.cc deleted file mode 100644 index 5f3cf4214..000000000 --- a/passes/sat/share.cc +++ /dev/null @@ -1,987 +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. - * - */ - -#include "kernel/yosys.h" -#include "kernel/satgen.h" -#include "kernel/sigtools.h" -#include "kernel/modtools.h" - -PRIVATE_NAMESPACE_BEGIN - -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; - - CellTypes fwd_ct, cone_ct; - ModWalker modwalker; - - std::set cells_to_remove; - std::set recursion_state; - - - // ------------------------------------------------------------------------------ - // 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_bits; - std::set visited_cells; - - queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end()); - - 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()); - } - - terminal_bits.insert(queue_bits.begin(), queue_bits.end()); - - while (!queue_bits.empty()) - { - std::set portbits; - modwalker.get_drivers(portbits, queue_bits); - queue_bits.clear(); - - for (auto &pbit : portbits) { - if (pbit.cell->type == "$mux" || pbit.cell->type == "$pmux") { - 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); - } - 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_bits.insert(bits.begin(), bits.end()); - visited_cells.insert(pbit.cell); - } - } - } - } - - - // --------------------------------------------------- - // Find shareable cells and compatible groups of cells - // --------------------------------------------------- - - std::set shareable_cells; - - void find_shareable_cells() - { - for (auto &it : module->cells_) - { - RTLIL::Cell *cell = it.second; - - 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) { - shareable_cells.insert(cell); - continue; - } - - if (cell->type == "$memrd") { - if (!cell->parameters.at("\\CLK_ENABLE").as_bool()) - 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) - 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) - shareable_cells.insert(cell); - continue; - } - - if (generic_ops.count(cell->type)) { - if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 10) - shareable_cells.insert(cell); - continue; - } - } - } - - 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 (config.generic_uni_ops.count(c1->type)) - { - if (!config.opt_aggressive) - { - int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); - int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); - - 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(); - 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; - } - - 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; - - 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); - } - - - // ----------------------- - // Create replacement cell - // ----------------------- - - RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act) - { - log_assert(c1->type == c2->type); - - if (config.generic_uni_ops.count(c1->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->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->getPort("\\A"); - new_a.append_bit(RTLIL::State::S0); - unsigned_cell->setPort("\\A", new_a); - } - 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->getPort("\\A"); - RTLIL::SigSpec y1 = c1->getPort("\\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)->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); - - 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->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)); - - 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) - { - 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")); - 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->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->getPort("\\A"); - new_a.append_bit(RTLIL::State::S0); - unsigned_cell->setPort("\\A", new_a); - } - 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->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->getPort("\\B"); - new_b.append_bit(RTLIL::State::S0); - unsigned_cell->setPort("\\B", new_b); - } - 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(); - - 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->getPort("\\A"); - RTLIL::SigSpec b1 = c1->getPort("\\B"); - RTLIL::SigSpec y1 = c1->getPort("\\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()); - 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.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)->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)->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)->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); - RTLIL::Wire *y = module->addWire(NEW_ID, y_width); - - 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; - supercell->parameters["\\B_WIDTH"] = b_width; - supercell->parameters["\\Y_WIDTH"] = y_width; - supercell->setPort("\\A", a); - supercell->setPort("\\B", b); - 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)); - - 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(); - } - - - // ------------------------------------------- - // 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->getPort("\\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 - // -------------------------------------------------------- - - std::map>> activation_patterns_cache; - - bool sort_check_activation_pattern(std::pair &p) - { - std::map p_bits; - - 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; - } - - 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); - } - - return true; - } - - 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 (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, driven_data_muxes; - - 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)); - 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); - } - } - - recursion_state.insert(cell); - - for (auto c : driven_data_muxes) - { - const std::set> &c_patterns = find_cell_activation_patterns(c, indent); - - 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->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)) - 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_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); - } - } - - 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)); - RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell]; - module->connect(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size()))); - cells_to_remove.insert(cell); - } - - return activation_patterns_cache[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; - } - - 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->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)); - } - if (all_cases_wire->width == 1) - return all_cases_wire; - return module->ReduceOr(NEW_ID, all_cases_wire); - } - - - // ------------- - // Setup and run - // ------------- - - 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(); - 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_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", - SIZE(shareable_cells), 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)); - - 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"); - cells_to_remove.insert(cell); - continue; - } - - 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); - - if (candidates.empty()) { - log(" No candidates found.\n"); - continue; - } - - log(" Found %d candidates:", SIZE(candidates)); - for (auto c : candidates) - log(" %s", log_id(c)); - log("\n"); - - 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); - - if (other_cell_activation_patterns.empty()) { - 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"); - shareable_cells.erase(other_cell); - continue; - } - - 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); - - std::set sat_cells; - std::set bits_queue; - - std::vector cell_active, other_cell_active; - RTLIL::SigSpec all_ctrl_signals; - - 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 : 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); - } - - 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)) { - 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); - } - - if (config.opt_fast && sat_cells.size() > 100) - 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; - - 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", - 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), 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; - } - - log(" According to the SAT solver this pair of cells can be shared.\n"); - shareable_cells.erase(other_cell); - - int cell_select_score = 0; - int other_cell_select_score = 0; - - for (auto &p : filtered_cell_activation_patterns) - cell_select_score += p.first.size(); - - for (auto &p : filtered_other_cell_activation_patterns) - other_cell_select_score += p.first.size(); - - RTLIL::Cell *supercell; - 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); - 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); - 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(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); - - cells_to_remove.insert(cell); - cells_to_remove.insert(other_cell); - 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->remove(c); - } - } - - log_assert(recursion_state.empty()); - } -}; - -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(" -force\n"); - log(" Per default the selection of cells that is considered for sharing is\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 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"); - } - 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_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; - for (argidx = 1; argidx < args.size(); argidx++) { - 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; - } - extra_args(args, argidx, design); - - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - ShareWorker(config, design, mod_it.second); - } -} SharePass; - -PRIVATE_NAMESPACE_END - -- cgit v1.2.3 From 27a1bfbec62c8467cd14a8d44cf4a8a046576b91 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 11:45:47 +0200 Subject: 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 11f5b924b..cc72faac0 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 -- cgit v1.2.3 From 826fdb34d8933120f022e92bfec508588b9191de Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 15:36:29 +0200 Subject: 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 660f1b388..43a94d976 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); -- cgit v1.2.3 From c7f81e4e49b3c2be1280cd0895170a5d89d9c444 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 15:37:21 +0200 Subject: 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 d9554bcf7..7f9f1f9b8 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; } } -- cgit v1.2.3 From 9923762461d2bc0822daef76bf0b58e772045bc8 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 15:37:56 +0200 Subject: 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 09ffa9a68..3c931c813 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 -- cgit v1.2.3 From bae09dca2ba4d582bf7258b6419d4268f65f1476 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 16:35:25 +0200 Subject: 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 5d1c11c9e..beb037686 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"); -- cgit v1.2.3 From 2fcf66b91d324758eb58807592702b6844bd37ab Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 16:35:46 +0200 Subject: 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 d42c2b0f1..fb54b72f6 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; -- cgit v1.2.3 From 630befdf6d58ab5f7c4ca1ea77c86df7b88ee259 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 1 Sep 2014 16:36:04 +0200 Subject: 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 7f9f1f9b8..7c7d6b7fd 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++) { -- cgit v1.2.3 From 9f00a0cd2d972a5fc4a75f8c1bdba723a5f66b7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 03:28:46 +0200 Subject: 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 2e713ffef..2c7703a15 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 3468eae78..6ab0e1ba1 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"); -- cgit v1.2.3 From ee29ae2206b913fbb8cd41782001eed24c53b39d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 03:52:46 +0200 Subject: Removed yosys-svgviewer --- Makefile | 11 -- README | 37 ++++--- 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, 18 insertions(+), 1121 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 49a387263..ce4a68c55 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 2c7703a15..7e8a42a86 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: - - $ yosys_deps="git g++ clang make bison flex libreadline-dev - tcl8.5-dev zlib1g-dev libqt4-dev libffi-dev - mercurial iverilog graphviz xdot" +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="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 b46f84a66..000000000 --- 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 51730124a..000000000 --- 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 492bb72b8..000000000 --- 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 b23164bce..000000000 --- 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 34866f854..000000000 --- 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 70da140eb..000000000 --- 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 dfb5586d4..000000000 --- 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 5a1a5ab29..000000000 --- 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 833bb52e0..000000000 --- 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 477ef789d..000000000 --- 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 488c62fd5..000000000 --- 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 db611f51f..000000000 --- a/libs/svgviewer/svgviewer.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - files/bubbles.svg - - - -- cgit v1.2.3 From 37fe7c7bdfd65071311049ce4287ef235797096e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 04:03:06 +0200 Subject: 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 bb50d357b..803e13026 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 c04811864..504ab7ec6 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 eefd36970..cce3741c2 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 6ab0e1ba1..0451ebc29 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"); -- cgit v1.2.3 From acd7a99aef0f698580dc6a6d202a79f36fdf5360 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 17:28:13 +0200 Subject: 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 7c7d6b7fd..de68ee7ec 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"); } } -- cgit v1.2.3 From c38283dbd033ba95554600bbaa850de707ab2a78 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 17:48:41 +0200 Subject: 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 7bfdb8955..4048e4a1f 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 beb037686..3685cd6e6 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 3c931c813..09ffa9a68 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 -- cgit v1.2.3 From da360771a193707b59eac9b95b3bfe1652a057aa Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 22:49:24 +0200 Subject: 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 f237f57ef..35cd54b46 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 7b8173b6a..0ecb4cdaf 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(); } -- cgit v1.2.3 From 66bf2bb92eb102dbb6b942c0c09b90f3925621a7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 22:49:43 +0200 Subject: 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 de68ee7ec..aead7b46f 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; -- cgit v1.2.3 From f1869667cac35e897c0531c05074f3c77bfa5db9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 23:21:15 +0200 Subject: 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 aead7b46f..627c2f7d4 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()); } -- cgit v1.2.3 From 635b922afeabea8c69ac4e749881b10aeda7448b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 2 Sep 2014 23:21:59 +0200 Subject: 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 09ffa9a68..61215f59e 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 -- cgit v1.2.3 From 50ac2848239cf5969b80c427a95b6098fd1e2f1c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 3 Sep 2014 13:39:46 +0200 Subject: 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 fb54b72f6..c73a0b351 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 3685cd6e6..c7f1680d4 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; } -- cgit v1.2.3 From 5733f4a39d56388e531b6c1471f56c3efb023f31 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 3 Sep 2014 13:43:37 +0200 Subject: 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 627c2f7d4..dce768048 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"; } -- cgit v1.2.3 From b9cb483f3e2a498ee75a422e09164a920918362b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 3 Sep 2014 21:20:59 +0200 Subject: 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 d1fa55b94..79672540b 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 4048e4a1f..da03f6164 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 c7f1680d4..eed3adaad 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)); -- cgit v1.2.3 From 8927aa6148f5575b2da9bfb76afb4af076fe18f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 4 Sep 2014 02:07:52 +0200 Subject: Removed $bu0 cell type --- 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 79672540b..82a2c519e 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 506c2bb25..0c7be1f54 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -70,7 +70,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi } // helper function for extending bit width (preferred over SigSpec::extend() because of correct undef propagation in ConstEval) -static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed, std::string celltype) +static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_signed) { if (width <= sig.size()) { sig.extend(width, is_signed); @@ -80,7 +80,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s std::stringstream sstr; sstr << "$extend" << "$" << that->filename << ":" << that->linenum << "$" << (autoidx++); - RTLIL::Cell *cell = current_module->addCell(sstr.str(), celltype); + RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$pos"); cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->linenum); RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width); @@ -1012,7 +1012,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = arg.size(); if (width_hint > 0) { width = width_hint; - widthExtend(this, arg, width, is_signed, "$pos"); + widthExtend(this, arg, width, is_signed); } return uniop2rtlil(this, type_name, width, arg); } @@ -1167,8 +1167,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = std::max(val1.size(), val2.size()); is_signed = children[1]->is_signed && children[2]->is_signed; - widthExtend(this, val1, width, is_signed, "$bu0"); - widthExtend(this, val2, width, is_signed, "$bu0"); + widthExtend(this, val1, width, is_signed); + widthExtend(this, val2, width, is_signed); RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); diff --git a/kernel/calc.cc b/kernel/calc.cc index da03f6164..41179d045 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 4a8be04d3..a8d88603e 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 35cd54b46..08c79beae 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 b8733c4ec..c48837691 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 eed3adaad..ae155a2eb 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 82473f6a2..5045960cb 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 4e9f4b21e..590451be0 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 54fec542a..9d9665c1e 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 dea24227f..19cdaa621 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 ad6961872..d315dba35 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 5f3cf4214..c372ed78a 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 2269859d1..321a1aa55 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 f5d9bbeef..f8d5d4584 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: 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 d315dba35..f9b78c053 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") -- cgit v1.2.3 From 01ef34c147dd3e3e3d13864f9c726727a4013207 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 4 Sep 2014 15:07:30 +0200 Subject: 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 000000000..0d0e58fef --- /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 000000000..ce36efc35 --- /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 000000000..fab1b1bbc --- /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 -- cgit v1.2.3 From 79cbf9067c07ed810b3466174278d77b9a05b46d Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Sat, 6 Sep 2014 08:47:06 +0200 Subject: Corrected spelling mistakes found by lintian --- 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 ce4a68c55..a499157ac 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 919022abe..ee12546ce 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 68c17271c..1998c12e4 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -464,7 +464,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_DEFPARAM && !str.empty()) { size_t pos = str.rfind('.'); if (pos == std::string::npos) - log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n", + log_error("Defparam `%s' does not contain a dot (module/parameter separator) at %s:%d!\n", RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum); std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1); if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL) diff --git a/frontends/verific/build_amd64.txt b/frontends/verific/build_amd64.txt index 2c3ba7b4d..94615d38d 100644 --- a/frontends/verific/build_amd64.txt +++ b/frontends/verific/build_amd64.txt @@ -17,7 +17,7 @@ VERIFIC_DIR = /usr/local/src/verific_lib_eval --snap-- -2.) Install the neccessary multilib packages +2.) Install the necessary multilib packages Hint: On debian/ubuntu the multilib packages have names such as libreadline-dev:amd64 or lib32readline6-dev, depending on the diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 0440f88e5..d0f148386 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -887,7 +887,7 @@ struct VerificPass : public Pass { } if (argidx > args.size() && args[argidx].substr(0, 1) == "-") - cmd_error(args, argidx, "unkown option"); + cmd_error(args, argidx, "unknown option"); if (mode_all) { diff --git a/frontends/vhdl2verilog/vhdl2verilog.cc b/frontends/vhdl2verilog/vhdl2verilog.cc index 8b6f62a63..b408d621b 100644 --- a/frontends/vhdl2verilog/vhdl2verilog.cc +++ b/frontends/vhdl2verilog/vhdl2verilog.cc @@ -116,7 +116,7 @@ struct Vhdl2verilogPass : public Pass { if (argidx == args.size()) cmd_error(args, argidx, "Missing filenames."); if (args[argidx].substr(0, 1) == "-") - cmd_error(args, argidx, "Unkown option."); + cmd_error(args, argidx, "Unknown option."); if (top_entity.empty()) log_cmd_error("Missing -top option.\n"); diff --git a/kernel/register.cc b/kernel/register.cc index a53bd84c7..2f7b89ffd 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 26632d0b5..e5c7456c4 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 960747747..485b4f357 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 9d9665c1e..35249ed88 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 c305ecb05..19d3b7b2f 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 8c039e3e9..5224f5bc9 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 2d49e85ed..4c540ca67 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 ca71f7d8d..d03aaf3b5 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 cef0a272e..344b03fc2 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 ea10cdf80..873ee7a16 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 2f28afb25..14bf8d1bd 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 ace6eeaf1..3ae0cd2c7 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 cc4fe4cc8..5046752f9 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 08ae9e929..fd0abf4a5 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"); -- cgit v1.2.3 From e1743b3bac8c86f3cf857892dabf66bec5573a7a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 11:46:07 +0200 Subject: 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 f82bbfeb3..26aad4354 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"); -- cgit v1.2.3 From 76f8128123a546c06dcb4624e8c8ed4255a030c5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 12:10:57 +0200 Subject: 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 5003280ef..102c021e0 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 -- cgit v1.2.3 From b847ec8a0bfb3b729278f1132ae2819676498ee7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 15:47:46 +0200 Subject: 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 a8d88603e..74e9f1fd5 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 000000000..362acab29 --- /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 08c79beae..97a2946a6 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 26aad4354..96f08de4b 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++) { -- cgit v1.2.3 From deff416ea7d60b490b0e4f8d70abdb1ad8d4d0f3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 17:58:27 +0200 Subject: Fixed assignment of out-of bounds array element --- frontends/ast/genrtlil.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 0c7be1f54..f87a68f67 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -276,6 +276,7 @@ struct AST_INTERNAL::ProcessGenerator for (auto &init_lvalue_c : init_lvalue.chunks()) { RTLIL::SigSpec lhs = init_lvalue_c; RTLIL::SigSpec rhs = init_rvalue.extract(offset, init_lvalue_c.width); + remove_unwanted_lvalue_bits(lhs, rhs); sync->actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); } @@ -284,6 +285,22 @@ struct AST_INTERNAL::ProcessGenerator outputSignals = RTLIL::SigSpec(subst_lvalue_from); } + void remove_unwanted_lvalue_bits(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) + { + RTLIL::SigSpec new_lhs, new_rhs; + + log_assert(SIZE(lhs) == SIZE(rhs)); + for (int i = 0; i < SIZE(lhs); i++) { + if (lhs[i].wire == nullptr) + continue; + new_lhs.append(lhs[i]); + new_rhs.append(rhs[i]); + } + + lhs = new_lhs; + rhs = new_rhs; + } + // create new temporary signals RTLIL::SigSpec new_temp_signal(RTLIL::SigSpec sig) { @@ -349,8 +366,13 @@ struct AST_INTERNAL::ProcessGenerator log_abort(); } - if (run_sort_and_unify) - reg.sort_and_unify(); + if (run_sort_and_unify) { + std::set sorted_reg; + for (auto bit : reg) + if (bit.wire) + sorted_reg.insert(bit); + reg = RTLIL::SigSpec(sorted_reg); + } } // remove all assignments to the given signal pattern in a case and all its children. @@ -384,6 +406,7 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue_c.width); if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute("\\nosync")) rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size()); + remove_unwanted_lvalue_bits(lhs, rhs); actions.push_back(RTLIL::SigSig(lhs, rhs)); offset += lhs.size(); } @@ -412,6 +435,7 @@ struct AST_INTERNAL::ProcessGenerator } removeSignalFromCaseTree(lvalue.to_sigbit_set(), current_case); + remove_unwanted_lvalue_bits(lvalue, rvalue); current_case->actions.push_back(RTLIL::SigSig(lvalue, rvalue)); } break; -- cgit v1.2.3 From bff4706b62ca73ba0a627eda2ad903b487634cae Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 17:59:12 +0200 Subject: 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 17700a61e..eabd65951 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 fccbe2f81..8237a7372 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 -- cgit v1.2.3 From 680eaaac41bc64000faa483955279155b0fc0a6b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 19:31:04 +0200 Subject: Fixed $clog2 (off by one error) --- frontends/ast/simplify.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 1998c12e4..9e797573c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1123,7 +1123,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum); - result_width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1; + result_width = abs(left_at_zero_ast->integer - right_at_zero_ast->integer) + 1; } did_something = true; newNode = new AstNode(AST_CASE, shift_expr); @@ -1370,7 +1370,7 @@ skip_dynamic_range_lvalue_expansion:; uint32_t result = 0; for (size_t i = 0; i < arg_value.bits.size(); i++) if (arg_value.bits.at(i) == RTLIL::State::S1) - result = i; + result = i + 1; newNode = mkconst_int(result, false); goto apply_newNode; -- cgit v1.2.3 From fa64942018a39085301d7f24832ad0ad7b0d22f1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 19:44:11 +0200 Subject: 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 ae155a2eb..3429f8239 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 96f08de4b..edab51eb2 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 eabd65951..b1f871d9b 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 8237a7372..f0397858f 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 -- cgit v1.2.3 From 98e6463ca78d8c0a342c9b86d9223dbeb45c093c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 19:44:28 +0200 Subject: Added $macc eval model --- kernel/consteval.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/kernel/consteval.h b/kernel/consteval.h index c73a0b351..f995c9cc2 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; -- cgit v1.2.3 From 9329a768181d3765a08c3b264c8b0031b732c0d4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 6 Sep 2014 20:30:46 +0200 Subject: 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 82a2c519e..bbdbbbfaf 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 edab51eb2..c69bd123b 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 b1f871d9b..465efc0a7 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 f0397858f..3fc6ccb8e 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; -- cgit v1.2.3 From 15b3c54fea80b7ccfd02c66c28ed38c610e23254 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 17:05:41 +0200 Subject: Added "test_cell -nosat" --- passes/tests/test_cell.cc | 132 +++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 59 deletions(-) diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index c69bd123b..a38023d14 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"); - } + 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_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_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_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; + 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; + 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 (!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"); - } + 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; + 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; } -- cgit v1.2.3 From 015dcdc84c5d0f9c899b520c9718ce32c9d2c8f7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 18:23:04 +0200 Subject: 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 b49259a8a..da527ccfe 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 000000000..49850c0a0 --- /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; + -- cgit v1.2.3 From c50b841b292f82d2da1f106b4e56c5c05ac9fede Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 18:23:37 +0200 Subject: 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 43a94d976..93ba7c40b 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(); + + 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); + } - 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); + 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"); -- cgit v1.2.3 From dd887cc02544e76f4ff9e57547231391388c1fa1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 7 Sep 2014 18:24:08 +0200 Subject: Using maccmap for $macc and $mul techmap --- techlibs/common/techmap.v | 206 ++++------------------------------------------ 1 file changed, 16 insertions(+), 190 deletions(-) diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 3fc6ccb8e..dc52ca5fa 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)); - - \$__acc_mul #( - .WIDTH(Y_WIDTH) + 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(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 -- cgit v1.2.3 From 6747a7047e105b7dae79ed8b8e1111d1ff8888d2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 11:12:39 +0200 Subject: 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 a38023d14..310c3bdfe 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"); -- cgit v1.2.3 From 1a88e47396305bd6b5ee2a7a91a1d014ebd37c10 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 11:21:58 +0200 Subject: 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 49850c0a0..a9c223fa8 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) -- cgit v1.2.3 From d46bac330520f91ee5bf8027abe98a8f9389f696 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 12:15:39 +0200 Subject: Added "$fa" cell type --- kernel/celltypes.h | 1 + kernel/consteval.h | 25 ++++++++++++++++++++++++ kernel/rtlil.cc | 15 +++++++++++++++ kernel/satgen.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++ passes/techmap/maccmap.cc | 22 +++++++++++++++------ passes/tests/test_cell.cc | 31 ++++++++++++++++++++++++++++++ techlibs/common/simlib.v | 16 ++++++++++++++++ techlibs/common/techmap.v | 12 ++++++++++++ 8 files changed, 165 insertions(+), 6 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 74e9f1fd5..b42cf4e9a 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 f995c9cc2..7423f950f 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 97a2946a6..b5cede8b2 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 3429f8239..4aabe4378 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 a9c223fa8..c2dc9aa8a 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}; - - 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 width = SIZE(in1); + RTLIL::Wire *w1 = module->addWire(NEW_ID, width); + RTLIL::Wire *w2 = module->addWire(NEW_ID, width); + + 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 310c3bdfe..72fb74d3a 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 465efc0a7..c170945ea 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 dc52ca5fa..050746376 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; -- cgit v1.2.3 From 48b00dcceab8bb046258cd6f0912636a6e5b232c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 12:25:23 +0200 Subject: Another $clog2 bugfix --- frontends/ast/simplify.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 9e797573c..969cc2302 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1365,6 +1365,8 @@ skip_dynamic_range_lvalue_expansion:; log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum); RTLIL::Const arg_value = buf->bitsAsConst(); + if (arg_value.as_bool()) + arg_value = const_sub(arg_value, 1, false, false, SIZE(arg_value)); delete buf; uint32_t result = 0; -- cgit v1.2.3 From af0c8873bbc13eea10b3d705061b4cf68fe27c17 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 13:28:23 +0200 Subject: 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 b42cf4e9a..85c21ef3c 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 7423f950f..6e507bd51 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 b5cede8b2..ec4375f2f 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 4aabe4378..91f8ab40d 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 5045960cb..64d3633e9 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 72fb74d3a..1fa90b540 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 c170945ea..1b67f3257 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 050746376..491511dbc 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 -- cgit v1.2.3 From 6dc07eb1f23757b17b6d856c95d0901d751eeb25 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 13:29:13 +0200 Subject: Fixes and cleanups for blackbox.v --- techlibs/common/blackbox.sed | 5 +- techlibs/common/simlib.v | 138 ++++++++++++++++++++++--------------------- 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/techlibs/common/blackbox.sed b/techlibs/common/blackbox.sed index 21693ecdd..db8900344 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 1b67f3257..da745b5e0 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; - - 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 + +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) > 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 - endfunction + end +endfunction - localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG); +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]) +`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; +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; +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]; + 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]; + 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]; + 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_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_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 + 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 // -------------------------------------------------------- -- cgit v1.2.3 From fcb46138cebd57587d35489cef3a3a48ebe40bcf Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 16:59:39 +0200 Subject: 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 6e507bd51..2d29d3f7e 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 91f8ab40d..692c6e7fb 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 da745b5e0..dd12bd39f 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 -- cgit v1.2.3 From 44b5bd4b631874e5ed083d5de75f5b87431f935f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 8 Sep 2014 17:09:39 +0200 Subject: 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 dd12bd39f..0ad8d14b2 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; -- cgit v1.2.3 From 3ae96f85a5528414eee458e8aa992aae90ceba7d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 13 Sep 2014 17:28:15 +0200 Subject: Using pkg-config to find libffi --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a499157ac..3ec89916a 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) -- cgit v1.2.3 From aab0e3bf702640806c6e81d42e922f938b0e0085 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 10:01:30 +0200 Subject: 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 321a1aa55..9e43bb902 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" + }; } }; -- cgit v1.2.3 From ff157fb74fc1b46408c075a0827adbca1b8c496e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 10:02:00 +0200 Subject: 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 da527ccfe..72998f87b 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 000000000..0e2fe4e7f --- /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; + -- cgit v1.2.3 From 0b72f0acb13e14d329cf408d22b636d61174eb8e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 10:45:28 +0200 Subject: 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 0e2fe4e7f..757dc7cf2 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; -- cgit v1.2.3 From 7b16c63101d46274cb3b93907489c8403e5d9bc5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 11:21:37 +0200 Subject: 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 757dc7cf2..5a15e8258 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(); } }; -- cgit v1.2.3 From 0df1d9ad72ad16af6c1d2d0c5f412914f322e326 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 13:23:44 +0200 Subject: 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 5a15e8258..2a4f8178a 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); } }; -- cgit v1.2.3 From b34ca151853aa2b5052afd56269a53079e17429d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:00:14 +0200 Subject: 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 2a4f8178a..d6ee9e66c 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; -- cgit v1.2.3 From 124e759280fecf9e8698b7e09c5d9e87d8fb3f96 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:49:26 +0200 Subject: Added techmap_wrap attribute --- passes/techmap/techmap.cc | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 93ba7c40b..8332e988f 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; + } } - 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(); + + 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)); } 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"); -- cgit v1.2.3 From 014bb34e0ecd058545fafbf1dbb0ba5064714c1d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:49:53 +0200 Subject: 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 d6ee9e66c..3fddcef13 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 c2dc9aa8a..e17231cb5 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"); } }; -- cgit v1.2.3 From 923bbbeaf049d2c5386765cb4fe62014a1770204 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 14:50:15 +0200 Subject: 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 491511dbc..b6c075b67 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,49 +410,8 @@ endmodule // Equal and Not-Equal // -------------------------------------------------------- -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; - \$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 \$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); +(* techmap_celltype = "$eq $eqx" *) +module _90_eq_eqx (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 1; @@ -639,7 +432,8 @@ module \$eqx (A, B, Y); 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; -- cgit v1.2.3 From 7e156a541909ec857fbaa4a08940d0aaf0d27d4b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 15:34:36 +0200 Subject: 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 8332e988f..ed466faa1 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) { -- cgit v1.2.3 From 7815f81c320a025c5b92677e375c12951dcbd14b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 16:09:06 +0200 Subject: 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 3ec89916a..7e8c7042b 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 7e8a42a86..d7f5aaa4b 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 e778e1389..f26d9ef82 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 461c1cb44..7c8cc2f66 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 000000000..95221afa9 --- /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 102c021e0..50f5cb580 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 } -- cgit v1.2.3 From 2442eb38327f42e1e786f7dd9ddf1838bf2bf4b4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 14 Sep 2014 17:04:39 +0200 Subject: 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 ec4375f2f..6556b82ee 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); -- cgit v1.2.3 From 2cbdbaad1f81f76422455901f1987d886fa10d19 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 11:29:09 +0200 Subject: 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 9e43bb902..58a6d1b0d 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) -- cgit v1.2.3 From fcbda0741166bfbc3244f05f92e9cc5f925160e6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 12:00:19 +0200 Subject: 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 e17231cb5..2d625eefe 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"); } }; -- cgit v1.2.3 From b470c480e97fe112810d04a6051d1029ce1e8c29 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 12:22:03 +0200 Subject: 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 362acab29..271141112 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 3fddcef13..c52e0e4ca 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(); -- cgit v1.2.3 From b86410b2ab902b587cbd8f6b14c13caf684af725 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Sep 2014 12:42:11 +0200 Subject: 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 c52e0e4ca..1115eead5 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)); -- cgit v1.2.3 From 6644e27cd4112070eca0958c19b71e97ba29a80d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 08:19:35 +0200 Subject: 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 0ad8d14b2..2d8088adb 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; -- cgit v1.2.3 From fa96cf4a1694afb1ac83e9fc9b894420fc210b97 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 11:26:44 +0200 Subject: Added new CodingReadme file (replaces CodingStyle and CHECKLISTS) --- CHECKLISTS | 134 --------------------------------------- CodingReadme | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CodingStyle | 43 ------------- kernel/yosys.h | 2 + 4 files changed, 196 insertions(+), 177 deletions(-) delete mode 100644 CHECKLISTS create mode 100644 CodingReadme delete mode 100644 CodingStyle diff --git a/CHECKLISTS b/CHECKLISTS deleted file mode 100644 index 4a4216512..000000000 --- a/CHECKLISTS +++ /dev/null @@ -1,134 +0,0 @@ - -This file contains checklists for various tasks. - - -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: - - cd ~yosys - gitk & - vi CHANGELOG - - -Run all tests with "make config-{clang-debug,gcc-debug,gcc-4.6,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 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 - - if there are any odd things -> investigate - - 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 - 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+" - - -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/CodingReadme b/CodingReadme new file mode 100644 index 000000000..8f515e1f4 --- /dev/null +++ b/CodingReadme @@ -0,0 +1,194 @@ + + +Getting Started +=============== + + +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: + + cd ~yosys + gitk & + vi CHANGELOG + + +Run all tests with "make config-{clang-debug,gcc-debug,gcc-4.6,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 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 + - if there are any odd things -> investigate + - 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 + 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+" + + diff --git a/CodingStyle b/CodingStyle deleted file mode 100644 index e076cbd89..000000000 --- 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 9a4826caa..b571e177f 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 -- cgit v1.2.3 From ae02d9cb9a990bfbe76d056fd341d88a9a5f129c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 12:40:58 +0200 Subject: 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..302ab3abf 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 { -- cgit v1.2.3 From 9ae559b9909a5042cb60b44b020d87b3d5b60b8b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 16 Sep 2014 12:45:05 +0200 Subject: 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 fd56668cf..b18f88352 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"); -- cgit v1.2.3 From ba61925071ec2da067226183d18964b4b215fea5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 17 Sep 2014 07:19:34 +0200 Subject: Added commit count to devel version number --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7e8c7042b..5a75320c3 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 -- cgit v1.2.3 From 815fab9d7136506aec0d38300e68bd88810195d3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 18 Sep 2014 12:57:37 +0200 Subject: 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 b18f88352..11818bf15 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(); -- cgit v1.2.3 From 4888d61c651e1230c592cff7c0d8143bcc8394e1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 18 Sep 2014 12:57:55 +0200 Subject: 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 95221afa9..4ccacd30b 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(); -- cgit v1.2.3 From f56b92818b05c898740df76e0a15bf94ce533e17 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 18 Sep 2014 19:00:21 +0200 Subject: 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 11818bf15..d99eff7d7 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" -- cgit v1.2.3 From f7bb8f244beff135aa2ef6c771bece45ce240c5d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 11:13:10 +0200 Subject: 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 0451ebc29..2218eded2 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) -- cgit v1.2.3 From 3aa003c8e9c207758797e533cb85514cdb0db2c6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 13:15:31 +0200 Subject: 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 d99eff7d7..75368e3ce 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)])); -- cgit v1.2.3 From 5827826098fd827c7ac964ed45e99f92d63d9267 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 14:05:41 +0200 Subject: 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 75368e3ce..f1d56b23a 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()); -- cgit v1.2.3 From 309623ff177f2538a4c529dbc025374008d85880 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 15:50:34 +0200 Subject: 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 13d3a8e42..48d818d76 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 138e10efb..159cd7192 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 -- cgit v1.2.3 From 00964f2f618d241a2e5cd32f4e7dbbcf55de4fb4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 15:50:55 +0200 Subject: 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 6556b82ee..00be796f8 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 c48837691..a0ae8f082 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; -- cgit v1.2.3 From a7758ef953eccff9295ec9f152ec1b6bef831f89 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 19 Sep 2014 15:51:34 +0200 Subject: 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 a60cfe66a..531943d78 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 000000000..0a0ceb1d1 --- /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; + -- cgit v1.2.3 From edf11c635a40c2cfb291089be509b2f31737958b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 12:57:33 +0200 Subject: 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 7f10619bc..a03caf804 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 c372ed78a..02e845846 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); } }; -- cgit v1.2.3 From 8d60754aefbded7b5742ceae2b34fb6b4dcda93d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 13:52:39 +0200 Subject: 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 02e845846..af2966bca 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; } } -- cgit v1.2.3 From a6c08b40fe281a69e1e6cb369b73c55ab6192f45 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 14:51:07 +0200 Subject: 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 af2966bca..cdda29349 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); } }; -- cgit v1.2.3 From b28be0759f46326d4d2a7ac74f1d1f79477435da Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 15:13:06 +0200 Subject: 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 cdda29349..5ed9af009 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); -- cgit v1.2.3 From d6e2ace95be79274f8707a897e3ac265ab85b11a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 15:13:44 +0200 Subject: 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 5ed9af009..b91a67ee0 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; } } -- cgit v1.2.3 From 96e821dc6cf170168218fa4cddc7c9ddafd6f439 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 19:36:56 +0200 Subject: 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 b91a67ee0..e3b0159c0 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); -- cgit v1.2.3 From 13117bb346dd02d2345f716b4403239aebe3d0e2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 21 Sep 2014 19:44:08 +0200 Subject: 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 e3b0159c0..74b049bb6 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); } }; -- cgit v1.2.3