summaryrefslogtreecommitdiff
path: root/frontends
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-02-14 11:21:12 +0100
committerClifford Wolf <clifford@clifford.at>2015-02-14 11:21:12 +0100
commit7f1a1759d7cdbbb528c451bf8fc8baf3b7e72893 (patch)
tree24088155e5c9b3d64e8d65dfa1a3298cd714caf6 /frontends
parenta8e9d37c14427527c9a810d83e183309cc5ca503 (diff)
Added "read_verilog -nomeminit" and "nomeminit" attribute
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.cc8
-rw-r--r--frontends/ast/ast.h6
-rw-r--r--frontends/ast/simplify.cc6
-rw-r--r--frontends/verilog/verilog_frontend.cc16
4 files changed, 29 insertions, 7 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 589b08e1..0de24013 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -53,7 +53,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, flag_autowire;
+ bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;
AstNode *current_ast, *current_ast_mod;
std::map<std::string, AstNode*> current_scope;
const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL;
@@ -958,6 +958,7 @@ static AstModule* process_module(AstNode *ast, bool defer)
current_module->ast = ast_before_simplify;
current_module->nolatches = flag_nolatches;
+ current_module->nomeminit = flag_nomeminit;
current_module->nomem2reg = flag_nomem2reg;
current_module->mem2reg = flag_mem2reg;
current_module->lib = flag_lib;
@@ -969,13 +970,14 @@ static AstModule* process_module(AstNode *ast, bool defer)
}
// 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, bool autowire)
+void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomeminit, 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;
flag_dump_ast2 = dump_ast2;
flag_dump_vlog = dump_vlog;
flag_nolatches = nolatches;
+ flag_nomeminit = nomeminit;
flag_nomem2reg = nomem2reg;
flag_mem2reg = mem2reg;
flag_lib = lib;
@@ -1037,6 +1039,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
flag_dump_ast2 = false;
flag_dump_vlog = false;
flag_nolatches = nolatches;
+ flag_nomeminit = nomeminit;
flag_nomem2reg = nomem2reg;
flag_mem2reg = mem2reg;
flag_lib = lib;
@@ -1103,6 +1106,7 @@ RTLIL::Module *AstModule::clone() const
new_mod->ast = ast->clone();
new_mod->nolatches = nolatches;
+ new_mod->nomeminit = nomeminit;
new_mod->nomem2reg = nomem2reg;
new_mod->mem2reg = mem2reg;
new_mod->lib = lib;
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 3523d075..0c113562 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -265,13 +265,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, 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);
+ void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomeminit, 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, autowire;
+ bool nolatches, nomeminit, nomem2reg, mem2reg, lib, noopt, icells, autowire;
virtual ~AstModule();
virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters);
virtual RTLIL::Module *clone() const;
@@ -295,7 +295,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, flag_autowire;
+ extern bool flag_dump_ast1, flag_dump_ast2, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;
extern AST::AstNode *current_ast, *current_ast_mod;
extern std::map<std::string, AST::AstNode*> current_scope;
extern const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr;
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 6e569201..10b65100 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -83,11 +83,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
{
AstNode *mem = it.first;
uint32_t memflags = it.second;
+ bool this_nomeminit = flag_nomeminit;
log_assert((memflags & ~0x00ffff00) == 0);
if (mem->get_bool_attribute("\\nomem2reg"))
continue;
+ if (mem->get_bool_attribute("\\nomeminit") || get_bool_attribute("\\nomeminit"))
+ this_nomeminit = true;
+
if (memflags & AstNode::MEM2REG_FL_FORCED)
goto silent_activate;
@@ -97,7 +101,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (memflags & AstNode::MEM2REG_FL_SET_ASYNC)
goto verbose_activate;
- if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE))
+ if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE) && this_nomeminit)
goto verbose_activate;
if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS)
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 23d35f68..41561e80 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -83,11 +83,20 @@ struct VerilogFrontend : public Frontend {
log(" this can also be achieved by setting the 'nomem2reg'\n");
log(" attribute on the respective module or register.\n");
log("\n");
+ log(" This is potentially dangerous. Usually the front-end has good\n");
+ log(" reasons for converting an array to a list of registers.\n");
+ log(" Prohibiting this step will likely result in incorrect synthesis\n");
+ log(" results.\n");
+ log("\n");
log(" -mem2reg\n");
log(" always convert memories to registers. this can also be\n");
log(" achieved by setting the 'mem2reg' attribute on the respective\n");
log(" module or register.\n");
log("\n");
+ log(" -nomeminit\n");
+ log(" do not infer $meminit cells and instead convert initialized\n");
+ log(" memories to registers directly in the front-end.\n");
+ log("\n");
log(" -ppdump\n");
log(" dump verilog code after pre-processor\n");
log("\n");
@@ -139,6 +148,7 @@ struct VerilogFrontend : public Frontend {
bool flag_dump_ast2 = false;
bool flag_dump_vlog = false;
bool flag_nolatches = false;
+ bool flag_nomeminit = false;
bool flag_nomem2reg = false;
bool flag_mem2reg = false;
bool flag_ppdump = false;
@@ -186,6 +196,10 @@ struct VerilogFrontend : public Frontend {
flag_nolatches = true;
continue;
}
+ if (arg == "-nomeminit") {
+ flag_nomeminit = true;
+ continue;
+ }
if (arg == "-nomem2reg") {
flag_nomem2reg = true;
continue;
@@ -288,7 +302,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, default_nettype_wire);
+ AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire);
if (!flag_nopp)
delete lexin;