mirror of https://github.com/YosysHQ/yosys.git
Added "read_verilog -nomeminit" and "nomeminit" attribute
This commit is contained in:
parent
a8e9d37c14
commit
7f1a1759d7
5
README
5
README
|
@ -257,6 +257,11 @@ Verilog Attributes and non-standard features
|
|||
- The "mem2reg" attribute on modules or arrays forces the early
|
||||
conversion of arrays to separate registers.
|
||||
|
||||
- The "nomeminit" attribute on modules or arrays prohibits the
|
||||
creation of initialized memories. This effectively puts "mem2reg"
|
||||
on all memories that are written to in an "initial" block and
|
||||
are not ROMs.
|
||||
|
||||
- The "nolatches" attribute on modules or always-blocks
|
||||
prohibits the generation of logic-loops for latches. Instead
|
||||
all not explicitly assigned values default to x-bits. This does
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue