Enabled AST/Verilog front-end optimizations per default
authorClifford Wolf <clifford@clifford.at>
Mon, 10 Jun 2013 11:19:04 +0000 (13:19 +0200)
committerClifford Wolf <clifford@clifford.at>
Mon, 10 Jun 2013 11:19:04 +0000 (13:19 +0200)
frontends/ast/ast.cc
frontends/ast/ast.h
frontends/ast/genrtlil.cc
frontends/ast/simplify.cc
frontends/verilog/verilog_frontend.cc

index f4231395960733e6208438d7f5495c2c5b44c179..a14297b62f95c57edd06b2f8547e3b4097d9b254 100644 (file)
@@ -46,7 +46,7 @@ namespace AST {
 
 // instanciate global variables (private API)
 namespace AST_INTERNAL {
-       bool flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib;
+       bool flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt;
        AstNode *current_ast, *current_ast_mod;
        std::map<std::string, AstNode*> current_scope;
        RTLIL::SigSpec *genRTLIL_subst_from = NULL;
@@ -674,7 +674,7 @@ static AstModule* process_module(AstNode *ast)
        current_ast_mod = ast;
        AstNode *ast_before_simplify = ast->clone();
 
-       while (ast->simplify(false, false, false, 0)) { }
+       while (ast->simplify(!flag_noopt, false, false, 0)) { }
 
        if (flag_dump_ast) {
                log("Dumping verilog AST (as requested by %s option):\n", flag_dump_ast_diff ? "dump_ast_diff" : "dump_ast");
@@ -740,11 +740,12 @@ static AstModule* process_module(AstNode *ast)
        current_module->nomem2reg = flag_nomem2reg;
        current_module->mem2reg = flag_mem2reg;
        current_module->lib = flag_lib;
+       current_module->noopt = flag_noopt;
        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_ast, bool dump_ast_diff, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib)
+void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_ast_diff, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt)
 {
        current_ast = ast;
        flag_dump_ast = dump_ast;
@@ -754,6 +755,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast, bool dump_
        flag_nomem2reg = nomem2reg;
        flag_mem2reg = mem2reg;
        flag_lib = lib;
+       flag_noopt = noopt;
 
        assert(current_ast->type == AST_DESIGN);
        for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) {
@@ -784,6 +786,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdStrin
        flag_nomem2reg = nomem2reg;
        flag_mem2reg = mem2reg;
        flag_lib = lib;
+       flag_noopt = noopt;
        use_internal_line_num();
 
        std::string para_info;
@@ -868,6 +871,7 @@ void AstModule::update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes)
        flag_nomem2reg = nomem2reg;
        flag_mem2reg = mem2reg;
        flag_lib = lib;
+       flag_noopt = noopt;
        use_internal_line_num();
 
        for (auto it = auto_sizes.begin(); it != auto_sizes.end(); it++) {
index acf10f9ad91443ac91863b336729c87a4a8c742c..c8de580e39b9c9850405aa81a1b4bf71258052d9 100644 (file)
@@ -190,13 +190,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_ast = false, bool dump_ast_diff = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false);
+       void process(RTLIL::Design *design, AstNode *ast, bool dump_ast = false, bool dump_ast_diff = false, bool dump_vlog = false, bool nolatches = false, bool nomem2reg = false, bool mem2reg = false, bool lib = false, bool noopt = false);
 
        // 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;
+               bool nolatches, nomem2reg, mem2reg, lib, noopt;
                virtual ~AstModule();
                virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters);
                virtual void update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes);
@@ -218,7 +218,7 @@ namespace AST
 namespace AST_INTERNAL
 {
        // internal state variables
-       extern bool flag_dump_ast, flag_dump_ast_diff, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib;
+       extern bool flag_dump_ast, flag_dump_ast_diff, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt;
        extern AST::AstNode *current_ast, *current_ast_mod;
        extern std::map<std::string, AST::AstNode*> current_scope;
        extern RTLIL::SigSpec *genRTLIL_subst_from, *genRTLIL_subst_to, ignoreThisSignalsInInitial;
index cb57bbab794399a712bf0d84a53049cad5160545..1fb762fc1b31ff29c550c2f2069cbf941f1f3d17 100644 (file)
@@ -628,6 +628,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint)
        // shifter cell is created and the output signal of this cell is returned
        case AST_IDENTIFIER:
                {
+                       RTLIL::Wire *wire = NULL;
+                       RTLIL::SigChunk chunk;
+
                        if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires.count(str) == 0) {
                                RTLIL::Wire *wire = new RTLIL::Wire;
                                wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
@@ -643,6 +646,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint)
                                wire->auto_width = true;
                                current_module->wires[str] = wire;
                        }
+                       else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM) {
+                               chunk = RTLIL::Const(id2ast->bits);
+                               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)
                                log_error("Identifier `%s' doesn't map to any signal at %s:%d!\n",
@@ -652,13 +659,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint)
                                log_error("Identifier `%s' does map to an unexpanded memory at %s:%d!\n",
                                                str.c_str(), filename.c_str(), linenum);
 
-                       RTLIL::Wire *wire = current_module->wires[str];
-
-                       RTLIL::SigChunk chunk;
+                       wire = current_module->wires[str];
                        chunk.wire = wire;
                        chunk.width = wire->width;
                        chunk.offset = 0;
 
+               use_const_chunk:
                        if (children.size() != 0) {
                                assert(children[0]->type == AST_RANGE);
                                if (!children[0]->range_valid) {
index bf0f9e63fbc9140372a98a2aaf9e6e28e6516605..9035d547875148e3d5a020b5306654c29f98398c 100644 (file)
@@ -797,7 +797,7 @@ skip_dynamic_range_lvalue_expansion:;
                if (0) { case AST_REDUCE_XOR:  const_func = RTLIL::const_reduce_xor;  }
                if (0) { case AST_REDUCE_XNOR: const_func = RTLIL::const_reduce_xnor; }
                if (0) { case AST_REDUCE_BOOL: const_func = RTLIL::const_reduce_bool; }
-                       if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
+                       if (children[0]->type == AST_CONSTANT) {
                                RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1);
                                newNode = mkconst_bits(y.bits, false);
                        }
index d14783c58793afb2c9c3643f8895253c2e100d5d..1311c3c3a1da4c5f0da91732732088cc13d32d74 100644 (file)
@@ -92,6 +92,10 @@ struct VerilogFrontend : public Frontend {
                log("    -lib\n");
                log("        only create empty placeholder modules\n");
                log("\n");
+               log("    -noopt\n");
+               log("        don't perform basic optimizations (such as const folding) in the\n");
+               log("        high-level front-end.\n");
+               log("\n");
                log("    -Dname[=definition]\n");
                log("        define the preprocessor symbol 'name' and set its optional value\n");
                log("        'definition'\n");
@@ -108,6 +112,7 @@ struct VerilogFrontend : public Frontend {
                bool flag_ppdump = false;
                bool flag_nopp = false;
                bool flag_lib = false;
+               bool flag_noopt = false;
                std::map<std::string, std::string> defines_map;
                frontend_verilog_yydebug = false;
 
@@ -157,6 +162,10 @@ struct VerilogFrontend : public Frontend {
                                flag_lib = true;
                                continue;
                        }
+                       if (arg == "-noopt") {
+                               flag_noopt = true;
+                               continue;
+                       }
                        if (arg.compare(0,2,"-D") == 0) {
                                size_t equal = arg.find('=',2);   // returns string::npos it not found
                                std::string name = arg.substr(2,equal-2);
@@ -196,7 +205,7 @@ struct VerilogFrontend : public Frontend {
                frontend_verilog_yyparse();
                frontend_verilog_yylex_destroy();
 
-               AST::process(design, current_ast, flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib);
+               AST::process(design, current_ast, flag_dump_ast, flag_dump_ast_diff, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt);
 
                if (!flag_nopp)
                        fclose(fp);