diff options
| author | Jim Lawson <ucbjrl@berkeley.edu> | 2019-04-30 13:19:27 -0700 | 
|---|---|---|
| committer | Jim Lawson <ucbjrl@berkeley.edu> | 2019-04-30 13:19:27 -0700 | 
| commit | 58650ffe876d1caedd8ffc9b0207f5cf75eef97b (patch) | |
| tree | 5389584f1c3ad8c9e9003e78d4b6e22dca5e3a83 /frontends | |
| parent | 354ba5ba83f7b1fc3bb07aa6bf26dde7a00201d1 (diff) | |
| parent | e35fe1344dd4c8f11632ed2a7f5b0463352a1ee4 (diff) | |
| download | yosys-58650ffe876d1caedd8ffc9b0207f5cf75eef97b.tar.gz yosys-58650ffe876d1caedd8ffc9b0207f5cf75eef97b.tar.bz2 yosys-58650ffe876d1caedd8ffc9b0207f5cf75eef97b.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'frontends')
| -rw-r--r-- | frontends/aiger/aigerparse.cc | 2 | ||||
| -rw-r--r-- | frontends/ast/ast.cc | 88 | ||||
| -rw-r--r-- | frontends/ast/ast.h | 4 | ||||
| -rw-r--r-- | frontends/ast/simplify.cc | 51 | ||||
| -rw-r--r-- | frontends/verilog/verilog_frontend.cc | 27 | ||||
| -rw-r--r-- | frontends/verilog/verilog_frontend.h | 6 | ||||
| -rw-r--r-- | frontends/verilog/verilog_parser.y | 2 | 
7 files changed, 164 insertions, 16 deletions
| diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index cf7950c85..2e4774dfd 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -33,8 +33,6 @@  YOSYS_NAMESPACE_BEGIN -#define log_debug log -  AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name)      : design(design), f(f), clk_name(clk_name)  { diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index d48996167..9f88b08c1 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -46,7 +46,7 @@ namespace AST {  // instantiate global variables (private API)  namespace AST_INTERNAL {  	bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, flag_nomeminit; -	bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire; +	bool flag_nomem2reg, flag_mem2reg, flag_noblackbox, flag_lib, flag_nowb, 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; @@ -942,6 +942,20 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast  	if (!defer)  	{ +		bool blackbox_module = flag_lib; + +		if (!blackbox_module && !flag_noblackbox) { +			blackbox_module = true; +			for (auto child : ast->children) { +				if (child->type == AST_WIRE && (child->is_input || child->is_output)) +					continue; +				if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM) +					continue; +				blackbox_module = false; +				break; +			} +		} +  		while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { }  		if (flag_dump_ast2) { @@ -956,7 +970,63 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast  			log("--- END OF AST DUMP ---\n");  		} -		if (flag_lib) { +		if (flag_nowb && ast->attributes.count("\\whitebox")) { +			delete ast->attributes.at("\\whitebox"); +			ast->attributes.erase("\\whitebox"); +		} + +		if (ast->attributes.count("\\lib_whitebox")) { +			if (!flag_lib || flag_nowb) { +				delete ast->attributes.at("\\lib_whitebox"); +				ast->attributes.erase("\\lib_whitebox"); +			} else { +				if (ast->attributes.count("\\whitebox")) { +					delete ast->attributes.at("\\whitebox"); +					ast->attributes.erase("\\whitebox"); +				} +				AstNode *n = ast->attributes.at("\\lib_whitebox"); +				ast->attributes["\\whitebox"] = n; +				ast->attributes.erase("\\lib_whitebox"); +			} +		} + +		if (!blackbox_module && ast->attributes.count("\\blackbox")) { +			AstNode *n = ast->attributes.at("\\blackbox"); +			if (n->type != AST_CONSTANT) +				log_file_error(ast->filename, ast->linenum, "Got blackbox attribute with non-constant value!\n"); +			blackbox_module = n->asBool(); +		} + +		if (blackbox_module && ast->attributes.count("\\whitebox")) { +			AstNode *n = ast->attributes.at("\\whitebox"); +			if (n->type != AST_CONSTANT) +				log_file_error(ast->filename, ast->linenum, "Got whitebox attribute with non-constant value!\n"); +			blackbox_module = !n->asBool(); +		} + +		if (ast->attributes.count("\\noblackbox")) { +			if (blackbox_module) { +				AstNode *n = ast->attributes.at("\\noblackbox"); +				if (n->type != AST_CONSTANT) +					log_file_error(ast->filename, ast->linenum, "Got noblackbox attribute with non-constant value!\n"); +				blackbox_module = !n->asBool(); +			} +			delete ast->attributes.at("\\noblackbox"); +			ast->attributes.erase("\\noblackbox"); +		} + +		if (blackbox_module) +		{ +			if (ast->attributes.count("\\whitebox")) { +				delete ast->attributes.at("\\whitebox"); +				ast->attributes.erase("\\whitebox"); +			} + +			if (ast->attributes.count("\\lib_whitebox")) { +				delete ast->attributes.at("\\lib_whitebox"); +				ast->attributes.erase("\\lib_whitebox"); +			} +  			std::vector<AstNode*> new_children;  			for (auto child : ast->children) {  				if (child->type == AST_WIRE && (child->is_input || child->is_output)) { @@ -969,8 +1039,12 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast  					delete child;  				}  			} +  			ast->children.swap(new_children); -			ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); + +			if (ast->attributes.count("\\blackbox") == 0) { +				ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); +			}  		}  		ignoreThisSignalsInInitial = RTLIL::SigSpec(); @@ -1009,7 +1083,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast  	current_module->nomeminit = flag_nomeminit;  	current_module->nomem2reg = flag_nomem2reg;  	current_module->mem2reg = flag_mem2reg; +	current_module->noblackbox = flag_noblackbox;  	current_module->lib = flag_lib; +	current_module->nowb = flag_nowb;  	current_module->noopt = flag_noopt;  	current_module->icells = flag_icells;  	current_module->autowire = flag_autowire; @@ -1026,7 +1102,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_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 no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, -		bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire) +		bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire)  {  	current_ast = ast;  	flag_dump_ast1 = dump_ast1; @@ -1039,7 +1115,9 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump  	flag_nomeminit = nomeminit;  	flag_nomem2reg = nomem2reg;  	flag_mem2reg = mem2reg; +	flag_noblackbox = noblackbox;  	flag_lib = lib; +	flag_nowb = nowb;  	flag_noopt = noopt;  	flag_icells = icells;  	flag_autowire = autowire; @@ -1373,7 +1451,9 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString  	flag_nomeminit = nomeminit;  	flag_nomem2reg = nomem2reg;  	flag_mem2reg = mem2reg; +	flag_noblackbox = noblackbox;  	flag_lib = lib; +	flag_nowb = nowb;  	flag_noopt = noopt;  	flag_icells = icells;  	flag_autowire = autowire; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index ddd59d4be..281cbe086 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -283,13 +283,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 no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, bool nolatches, bool nomeminit, -			bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire); +			bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire);  	// parametric modules are supported directly by the AST library  	// therefore we need our own derivate of RTLIL::Module with overloaded virtual functions  	struct AstModule : RTLIL::Module {  		AstNode *ast; -		bool nolatches, nomeminit, nomem2reg, mem2reg, lib, noopt, icells, autowire; +		bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, autowire;  		~AstModule() YS_OVERRIDE;  		RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE;  		RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 63b71b800..4d4b9dfe1 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1030,7 +1030,26 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  		log_file_error(filename, linenum, "While loops are only allowed in constant functions!\n");  	if (type == AST_REPEAT) -		log_file_error(filename, linenum, "Repeat loops are only allowed in constant functions!\n"); +	{ +		AstNode *count = children[0]; +		AstNode *body = children[1]; + +		// eval count expression +		while (count->simplify(true, false, false, stage, 32, true, false)) { } + +		if (count->type != AST_CONSTANT) +			log_file_error(filename, linenum, "Repeat loops outside must have constant repeat counts!\n"); + +		// convert to a block with the body repeated n times +		type = AST_BLOCK; +		children.clear(); +		for (int i = 0; i < count->bitsAsConst().as_int(); i++) +			children.insert(children.begin(), body->clone()); + +		delete count; +		delete body; +		did_something = true; +	}  	// unroll for loops and generate-for blocks  	if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0) @@ -1066,7 +1085,12 @@ 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, 32, true, false)) { } +		{ +			int expr_width_hint = -1; +			bool expr_sign_hint = true; +			varbuf->detectSignWidth(expr_width_hint, expr_sign_hint); +			while (varbuf->simplify(true, false, false, stage, 32, true, false)) { } +		}  		if (varbuf->type != AST_CONSTANT)  			log_file_error(filename, linenum, "Right hand side of 1st expression of generate for-loop is not constant!\n"); @@ -1088,7 +1112,12 @@ 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, false)) { } +			{ +				int expr_width_hint = -1; +				bool expr_sign_hint = true; +				buf->detectSignWidth(expr_width_hint, expr_sign_hint); +				while (buf->simplify(true, false, false, stage, expr_width_hint, expr_sign_hint, false)) { } +			}  			if (buf->type != AST_CONSTANT)  				log_file_error(filename, linenum, "2nd expression of generate for-loop is not constant!\n"); @@ -1129,7 +1158,12 @@ 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, 32, true, false)) { } +			{ +				int expr_width_hint = -1; +				bool expr_sign_hint = true; +				buf->detectSignWidth(expr_width_hint, expr_sign_hint); +				while (buf->simplify(true, false, false, stage, expr_width_hint, expr_sign_hint, true)) { } +			}  			if (buf->type != AST_CONSTANT)  				log_file_error(filename, linenum, "Right hand side of 3rd expression of generate for-loop is not constant!\n"); @@ -1138,6 +1172,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,  			varbuf->children[0] = buf;  		} +#if 0 +		if (type == AST_FOR) { +			AstNode *buf = next_ast->clone(); +			delete buf->children[1]; +			buf->children[1] = varbuf->children[0]->clone(); +			current_block->children.insert(current_block->children.begin() + current_block_idx++, buf); +		} +#endif +  		current_scope[varbuf->str] = backup_scope_varbuf;  		delete varbuf;  		delete_children(); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 504f8b3f3..9e624d355 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -145,8 +145,18 @@ struct VerilogFrontend : public Frontend {  		log("    -nodpi\n");  		log("        disable DPI-C support\n");  		log("\n"); +		log("    -noblackbox\n"); +		log("        do not automatically add a (* blackbox *) attribute to an\n"); +		log("        empty module.\n"); +		log("\n");  		log("    -lib\n");  		log("        only create empty blackbox modules. This implies -DBLACKBOX.\n"); +		log("        modules with the (* whitebox *) attribute will be preserved.\n"); +		log("        (* lib_whitebox *) will be treated like (* whitebox *).\n"); +		log("\n"); +		log("    -nowb\n"); +		log("        delete (* whitebox *) and (* lib_whitebox *) attributes from\n"); +		log("        all modules.\n");  		log("\n");  		log("    -noopt\n");  		log("        don't perform basic optimizations (such as const folding) in the\n"); @@ -227,11 +237,11 @@ struct VerilogFrontend : public Frontend {  		formal_mode = false;  		norestrict_mode = false;  		assume_asserts_mode = false; +		noblackbox_mode = false;  		lib_mode = false; +		nowb_mode = false;  		default_nettype_wire = true; -		log_header(design, "Executing Verilog-2005 frontend.\n"); -  		args.insert(args.begin()+1, verilog_defaults.begin(), verilog_defaults.end());  		size_t argidx; @@ -329,11 +339,19 @@ struct VerilogFrontend : public Frontend {  				flag_nodpi = true;  				continue;  			} +			if (arg == "-noblackbox") { +				noblackbox_mode = true; +				continue; +			}  			if (arg == "-lib") {  				lib_mode = true;  				defines_map["BLACKBOX"] = string();  				continue;  			} +			if (arg == "-nowb") { +				nowb_mode = true; +				continue; +			}  			if (arg == "-noopt") {  				flag_noopt = true;  				continue; @@ -395,6 +413,8 @@ struct VerilogFrontend : public Frontend {  		}  		extra_args(f, filename, args, argidx); +		log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str()); +  		log("Parsing %s%s input from `%s' to AST representation.\n",  				formal_mode ? "formal " : "", sv_mode ? "SystemVerilog" : "Verilog", filename.c_str()); @@ -429,7 +449,8 @@ struct VerilogFrontend : public Frontend {  		if (flag_nodpi)  			error_on_dpi_function(current_ast); -		AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, flag_nomeminit, flag_nomem2reg, flag_mem2reg, lib_mode, flag_noopt, flag_icells, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire); +		AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, +				flag_nomeminit, flag_nomem2reg, flag_mem2reg, noblackbox_mode, lib_mode, nowb_mode, flag_noopt, flag_icells, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);  		if (!flag_nopp)  			delete lexin; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 523bbc897..ca40946cb 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -69,9 +69,15 @@ namespace VERILOG_FRONTEND  	// running in -assert-assumes mode  	extern bool assert_assumes_mode; +	// running in -noblackbox mode +	extern bool noblackbox_mode; +  	// running in -lib mode  	extern bool lib_mode; +	// running in -nowb mode +	extern bool nowb_mode; +  	// lexer input stream  	extern std::istream *lexin;  } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 52685f637..40968d17a 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -59,7 +59,7 @@ namespace VERILOG_FRONTEND {  	std::vector<char> case_type_stack;  	bool do_not_require_port_stubs;  	bool default_nettype_wire; -	bool sv_mode, formal_mode, lib_mode; +	bool sv_mode, formal_mode, noblackbox_mode, lib_mode, nowb_mode;  	bool noassert_mode, noassume_mode, norestrict_mode;  	bool assume_asserts_mode, assert_assumes_mode;  	bool current_wire_rand, current_wire_const; | 
