mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Merge pull request #943 from YosysHQ/clifford/whitebox
[WIP] Add "whitebox" attribute, add "read_verilog -wb"
This commit is contained in:
		
						commit
						f84a84e3f1
					
				
					 27 changed files with 157 additions and 55 deletions
				
			
		| 
						 | 
				
			
			@ -312,6 +312,10 @@ Verilog Attributes and non-standard features
 | 
			
		|||
  passes to identify input and output ports of cells. The Verilog backend
 | 
			
		||||
  also does not output blackbox modules on default.
 | 
			
		||||
 | 
			
		||||
- The ``whitebox`` attribute on modules triggers the same behavior as
 | 
			
		||||
  ``blackbox``, but is for whitebox modules, i.e. library modules that
 | 
			
		||||
  contain a behavioral model of the cell type.
 | 
			
		||||
 | 
			
		||||
- The ``dynports`` attribute is used by the Verilog front-end to mark modules
 | 
			
		||||
  that have ports with a width that depends on a parameter.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ struct BlifDumper
 | 
			
		|||
			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"))
 | 
			
		||||
		if (design->modules_.at(RTLIL::escape_id(cell_type))->get_blackbox_attribute())
 | 
			
		||||
			return "gate";
 | 
			
		||||
		return "subckt";
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -196,7 +196,7 @@ struct BlifDumper
 | 
			
		|||
		}
 | 
			
		||||
		f << stringf("\n");
 | 
			
		||||
 | 
			
		||||
		if (module->get_bool_attribute("\\blackbox")) {
 | 
			
		||||
		if (module->get_blackbox_attribute()) {
 | 
			
		||||
			f << stringf(".blackbox\n");
 | 
			
		||||
			f << stringf(".end\n");
 | 
			
		||||
			return;
 | 
			
		||||
| 
						 | 
				
			
			@ -640,7 +640,7 @@ struct BlifBackend : public Backend {
 | 
			
		|||
		for (auto module_it : design->modules_)
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::Module *module = module_it.second;
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox") && !config.blackbox_mode)
 | 
			
		||||
			if (module->get_blackbox_attribute() && !config.blackbox_mode)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (module->processes.size() != 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,7 +178,7 @@ struct EdifBackend : public Backend {
 | 
			
		|||
		for (auto module_it : design->modules_)
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::Module *module = module_it.second;
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (module->get_blackbox_attribute())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (top_module_name.empty())
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +192,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_blackbox_attribute()) {
 | 
			
		||||
					lib_cell_ports[cell->type];
 | 
			
		||||
					for (auto p : cell->connections())
 | 
			
		||||
						lib_cell_ports[cell->type][p.first] = GetSize(p.second);
 | 
			
		||||
| 
						 | 
				
			
			@ -302,7 +302,7 @@ struct EdifBackend : public Backend {
 | 
			
		|||
		*f << stringf("    (technology (numberDefinition))\n");
 | 
			
		||||
		for (auto module : sorted_modules)
 | 
			
		||||
		{
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (module->get_blackbox_attribute())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			SigMap sigmap(module);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ struct IntersynthBackend : public Backend {
 | 
			
		|||
			RTLIL::Module *module = module_it.second;
 | 
			
		||||
			SigMap sigmap(module);
 | 
			
		||||
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (module->get_blackbox_attribute())
 | 
			
		||||
				continue;
 | 
			
		||||
			if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells_.size() == 0)
 | 
			
		||||
				continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1543,7 +1543,7 @@ struct Smt2Backend : public Backend {
 | 
			
		|||
 | 
			
		||||
		for (auto module : sorted_modules)
 | 
			
		||||
		{
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox") || module->has_memories_warn() || module->has_processes_warn())
 | 
			
		||||
			if (module->get_blackbox_attribute() || module->has_memories_warn() || module->has_processes_warn())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			log("Creating SMT-LIBv2 representation of module %s.\n", log_id(module));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -739,7 +739,7 @@ struct SmvBackend : public Backend {
 | 
			
		|||
		pool<Module*> modules;
 | 
			
		||||
 | 
			
		||||
		for (auto module : design->modules())
 | 
			
		||||
			if (!module->get_bool_attribute("\\blackbox") && !module->has_memories_warn() && !module->has_processes_warn())
 | 
			
		||||
			if (!module->get_blackbox_attribute() && !module->has_memories_warn() && !module->has_processes_warn())
 | 
			
		||||
				modules.insert(module);
 | 
			
		||||
 | 
			
		||||
		if (template_f.is_open())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,7 +212,7 @@ struct SpiceBackend : public Backend {
 | 
			
		|||
		for (auto module_it : design->modules_)
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::Module *module = module_it.second;
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (module->get_blackbox_attribute())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (module->processes.size() != 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ struct TableBackend : public Backend {
 | 
			
		|||
 | 
			
		||||
		for (auto module : design->modules())
 | 
			
		||||
		{
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (module->get_blackbox_attribute())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			SigMap sigmap(module);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1770,7 +1770,7 @@ struct VerilogBackend : public Backend {
 | 
			
		|||
 | 
			
		||||
		*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)
 | 
			
		||||
			if (it->second->get_blackbox_attribute() != blackboxes)
 | 
			
		||||
				continue;
 | 
			
		||||
			if (selected && !design->selected_whole_module(it->first)) {
 | 
			
		||||
				if (design->selected_module(it->first))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_lib, flag_wb, 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -956,7 +956,18 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
 | 
			
		|||
			log("--- END OF AST DUMP ---\n");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (flag_wb) {
 | 
			
		||||
			if (!ast->attributes.count("\\whitebox"))
 | 
			
		||||
				goto blackbox_module;
 | 
			
		||||
			AstNode *n = ast->attributes.at("\\whitebox");
 | 
			
		||||
			if (n->type != AST_CONSTANT)
 | 
			
		||||
				log_file_error(ast->filename, ast->linenum, "Whitebox attribute with non-constant value!\n");
 | 
			
		||||
			if (!n->asBool())
 | 
			
		||||
				goto blackbox_module;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (flag_lib) {
 | 
			
		||||
	blackbox_module:
 | 
			
		||||
			std::vector<AstNode*> new_children;
 | 
			
		||||
			for (auto child : ast->children) {
 | 
			
		||||
				if (child->type == AST_WIRE && (child->is_input || child->is_output)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -970,6 +981,10 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
			ast->children.swap(new_children);
 | 
			
		||||
			if (ast->attributes.count("\\whitebox")) {
 | 
			
		||||
				delete ast->attributes.at("\\whitebox");
 | 
			
		||||
				ast->attributes.erase("\\whitebox");
 | 
			
		||||
			}
 | 
			
		||||
			ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1010,6 +1025,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
 | 
			
		|||
	current_module->nomem2reg = flag_nomem2reg;
 | 
			
		||||
	current_module->mem2reg = flag_mem2reg;
 | 
			
		||||
	current_module->lib = flag_lib;
 | 
			
		||||
	current_module->wb = flag_wb;
 | 
			
		||||
	current_module->noopt = flag_noopt;
 | 
			
		||||
	current_module->icells = flag_icells;
 | 
			
		||||
	current_module->autowire = flag_autowire;
 | 
			
		||||
| 
						 | 
				
			
			@ -1026,7 +1042,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 lib, bool wb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire)
 | 
			
		||||
{
 | 
			
		||||
	current_ast = ast;
 | 
			
		||||
	flag_dump_ast1 = dump_ast1;
 | 
			
		||||
| 
						 | 
				
			
			@ -1040,6 +1056,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
 | 
			
		|||
	flag_nomem2reg = nomem2reg;
 | 
			
		||||
	flag_mem2reg = mem2reg;
 | 
			
		||||
	flag_lib = lib;
 | 
			
		||||
	flag_wb = wb;
 | 
			
		||||
	flag_noopt = noopt;
 | 
			
		||||
	flag_icells = icells;
 | 
			
		||||
	flag_autowire = autowire;
 | 
			
		||||
| 
						 | 
				
			
			@ -1374,6 +1391,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
 | 
			
		|||
	flag_nomem2reg = nomem2reg;
 | 
			
		||||
	flag_mem2reg = mem2reg;
 | 
			
		||||
	flag_lib = lib;
 | 
			
		||||
	flag_wb = wb;
 | 
			
		||||
	flag_noopt = noopt;
 | 
			
		||||
	flag_icells = icells;
 | 
			
		||||
	flag_autowire = autowire;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 lib, bool wb, 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, lib, wb, 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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,6 +148,10 @@ struct VerilogFrontend : public Frontend {
 | 
			
		|||
		log("    -lib\n");
 | 
			
		||||
		log("        only create empty blackbox modules. This implies -DBLACKBOX.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -wb\n");
 | 
			
		||||
		log("        like -lib, except do not touch modules with the whitebox\n");
 | 
			
		||||
		log("        attribute set. This also implies -DBLACKBOX.\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");
 | 
			
		||||
| 
						 | 
				
			
			@ -228,6 +232,7 @@ struct VerilogFrontend : public Frontend {
 | 
			
		|||
		norestrict_mode = false;
 | 
			
		||||
		assume_asserts_mode = false;
 | 
			
		||||
		lib_mode = false;
 | 
			
		||||
		wb_mode = false;
 | 
			
		||||
		default_nettype_wire = true;
 | 
			
		||||
 | 
			
		||||
		log_header(design, "Executing Verilog-2005 frontend.\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -329,11 +334,16 @@ struct VerilogFrontend : public Frontend {
 | 
			
		|||
				flag_nodpi = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (arg == "-lib") {
 | 
			
		||||
			if (arg == "-lib" && !wb_mode) {
 | 
			
		||||
				lib_mode = true;
 | 
			
		||||
				defines_map["BLACKBOX"] = string();
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (arg == "-wb" && !lib_mode) {
 | 
			
		||||
				wb_mode = true;
 | 
			
		||||
				defines_map["BLACKBOX"] = string();
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (arg == "-noopt") {
 | 
			
		||||
				flag_noopt = true;
 | 
			
		||||
				continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -429,7 +439,7 @@ 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, lib_mode, wb_mode, flag_noopt, flag_icells, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
 | 
			
		||||
 | 
			
		||||
		if (!flag_nopp)
 | 
			
		||||
			delete lexin;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,9 @@ namespace VERILOG_FRONTEND
 | 
			
		|||
	// running in -lib mode
 | 
			
		||||
	extern bool lib_mode;
 | 
			
		||||
 | 
			
		||||
	// running in -wb mode
 | 
			
		||||
	extern bool wb_mode;
 | 
			
		||||
 | 
			
		||||
	// lexer input stream
 | 
			
		||||
	extern std::istream *lexin;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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, lib_mode, wb_mode;
 | 
			
		||||
	bool noassert_mode, noassume_mode, norestrict_mode;
 | 
			
		||||
	bool assume_asserts_mode, assert_assumes_mode;
 | 
			
		||||
	bool current_wire_rand, current_wire_const;
 | 
			
		||||
| 
						 | 
				
			
			@ -1906,7 +1906,7 @@ basic_expr:
 | 
			
		|||
		if ($4->substr(0, 1) != "'")
 | 
			
		||||
			frontend_verilog_yyerror("Cast operation must be applied on sized constants e.g. (<expr>)<constval> , while %s is not a sized constant.", $4->c_str());
 | 
			
		||||
		AstNode *bits = $2;
 | 
			
		||||
		AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
 | 
			
		||||
		AstNode *val = const2ast(*$4, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
 | 
			
		||||
		if (val == NULL)
 | 
			
		||||
			log_error("Value conversion failed: `%s'\n", $4->c_str());
 | 
			
		||||
		$$ = new AstNode(AST_TO_BITS, bits, val);
 | 
			
		||||
| 
						 | 
				
			
			@ -1917,7 +1917,7 @@ basic_expr:
 | 
			
		|||
			frontend_verilog_yyerror("Cast operation must be applied on sized constants, e.g. <ID>\'d0, while %s is not a sized constant.", $2->c_str());
 | 
			
		||||
		AstNode *bits = new AstNode(AST_IDENTIFIER);
 | 
			
		||||
		bits->str = *$1;
 | 
			
		||||
		AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
 | 
			
		||||
		AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
 | 
			
		||||
		if (val == NULL)
 | 
			
		||||
			log_error("Value conversion failed: `%s'\n", $2->c_str());
 | 
			
		||||
		$$ = new AstNode(AST_TO_BITS, bits, val);
 | 
			
		||||
| 
						 | 
				
			
			@ -1925,14 +1925,14 @@ basic_expr:
 | 
			
		|||
		delete $2;
 | 
			
		||||
	} |
 | 
			
		||||
	TOK_CONSTVAL TOK_CONSTVAL {
 | 
			
		||||
		$$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
 | 
			
		||||
		$$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
 | 
			
		||||
		if ($$ == NULL || (*$2)[0] != '\'')
 | 
			
		||||
			log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str());
 | 
			
		||||
		delete $1;
 | 
			
		||||
		delete $2;
 | 
			
		||||
	} |
 | 
			
		||||
	TOK_CONSTVAL {
 | 
			
		||||
		$$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode);
 | 
			
		||||
		$$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode && !wb_mode);
 | 
			
		||||
		if ($$ == NULL)
 | 
			
		||||
			log_error("Value conversion failed: `%s'\n", $1->c_str());
 | 
			
		||||
		delete $1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -207,9 +207,12 @@ bool RTLIL::Const::is_fully_undef() const
 | 
			
		|||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id)
 | 
			
		||||
void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value)
 | 
			
		||||
{
 | 
			
		||||
	if (value)
 | 
			
		||||
		attributes[id] = RTLIL::Const(1);
 | 
			
		||||
	else if (attributes.count(id))
 | 
			
		||||
		attributes.erase(id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const
 | 
			
		||||
| 
						 | 
				
			
			@ -589,7 +592,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const
 | 
			
		|||
	std::vector<RTLIL::Module*> result;
 | 
			
		||||
	result.reserve(modules_.size());
 | 
			
		||||
	for (auto &it : modules_)
 | 
			
		||||
		if (selected_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
 | 
			
		||||
		if (selected_module(it.first) && !it.second->get_blackbox_attribute())
 | 
			
		||||
			result.push_back(it.second);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -599,7 +602,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const
 | 
			
		|||
	std::vector<RTLIL::Module*> result;
 | 
			
		||||
	result.reserve(modules_.size());
 | 
			
		||||
	for (auto &it : modules_)
 | 
			
		||||
		if (selected_whole_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
 | 
			
		||||
		if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute())
 | 
			
		||||
			result.push_back(it.second);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -609,7 +612,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn() const
 | 
			
		|||
	std::vector<RTLIL::Module*> result;
 | 
			
		||||
	result.reserve(modules_.size());
 | 
			
		||||
	for (auto &it : modules_)
 | 
			
		||||
		if (it.second->get_bool_attribute("\\blackbox"))
 | 
			
		||||
		if (it.second->get_blackbox_attribute())
 | 
			
		||||
			continue;
 | 
			
		||||
		else if (selected_whole_module(it.first))
 | 
			
		||||
			result.push_back(it.second);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -566,9 +566,13 @@ struct RTLIL::AttrObject
 | 
			
		|||
{
 | 
			
		||||
	dict<RTLIL::IdString, RTLIL::Const> attributes;
 | 
			
		||||
 | 
			
		||||
	void set_bool_attribute(RTLIL::IdString id);
 | 
			
		||||
	void set_bool_attribute(RTLIL::IdString id, bool value=true);
 | 
			
		||||
	bool get_bool_attribute(RTLIL::IdString id) const;
 | 
			
		||||
 | 
			
		||||
	bool get_blackbox_attribute(bool ignore_wb=false) const {
 | 
			
		||||
		return get_bool_attribute("\\blackbox") || (!ignore_wb && get_bool_attribute("\\whitebox"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
 | 
			
		||||
	void add_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
 | 
			
		||||
	pool<string> get_strpool_attribute(RTLIL::IdString id) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,7 +71,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
 | 
			
		|||
		RTLIL::Module *mod = design->modules_.at(it.second->type);
 | 
			
		||||
		if (!design->selected_whole_module(mod->name))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (mod->get_bool_attribute("\\blackbox"))
 | 
			
		||||
		if (mod->get_blackbox_attribute())
 | 
			
		||||
			continue;
 | 
			
		||||
		if (it.second->hasPort(name))
 | 
			
		||||
			continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ struct BugpointPass : public Pass {
 | 
			
		|||
		{
 | 
			
		||||
			for (auto &it : design_copy->modules_)
 | 
			
		||||
			{
 | 
			
		||||
				if (it.second->get_bool_attribute("\\blackbox"))
 | 
			
		||||
				if (it.second->get_blackbox_attribute())
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				if (index++ == seed)
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +143,7 @@ struct BugpointPass : public Pass {
 | 
			
		|||
		{
 | 
			
		||||
			for (auto mod : design_copy->modules())
 | 
			
		||||
			{
 | 
			
		||||
				if (mod->get_bool_attribute("\\blackbox"))
 | 
			
		||||
				if (mod->get_blackbox_attribute())
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				for (auto wire : mod->wires())
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ struct BugpointPass : public Pass {
 | 
			
		|||
		{
 | 
			
		||||
			for (auto mod : design_copy->modules())
 | 
			
		||||
			{
 | 
			
		||||
				if (mod->get_bool_attribute("\\blackbox"))
 | 
			
		||||
				if (mod->get_blackbox_attribute())
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				for (auto &it : mod->cells_)
 | 
			
		||||
| 
						 | 
				
			
			@ -186,7 +186,7 @@ struct BugpointPass : public Pass {
 | 
			
		|||
		{
 | 
			
		||||
			for (auto mod : design_copy->modules())
 | 
			
		||||
			{
 | 
			
		||||
				if (mod->get_bool_attribute("\\blackbox"))
 | 
			
		||||
				if (mod->get_blackbox_attribute())
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				for (auto cell : mod->cells())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,6 +128,45 @@ struct SetattrPass : public Pass {
 | 
			
		|||
	}
 | 
			
		||||
} SetattrPass;
 | 
			
		||||
 | 
			
		||||
struct WbflipPass : public Pass {
 | 
			
		||||
	WbflipPass() : Pass("wbflip", "flip the whitebox attribute") { }
 | 
			
		||||
	void help() YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    wbflip [selection]\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("Flip the whitebox attribute on selected cells. I.e. if it's set, unset it, and\n");
 | 
			
		||||
		log("vice-versa. Blackbox cells are not effected by this command.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		size_t argidx;
 | 
			
		||||
		for (argidx = 1; argidx < args.size(); argidx++)
 | 
			
		||||
		{
 | 
			
		||||
			std::string arg = args[argidx];
 | 
			
		||||
			// if (arg == "-mod") {
 | 
			
		||||
			// 	flag_mod = true;
 | 
			
		||||
			// 	continue;
 | 
			
		||||
			// }
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		for (Module *module : design->modules())
 | 
			
		||||
		{
 | 
			
		||||
			if (!design->selected(module))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			module->set_bool_attribute("\\whitebox", !module->get_bool_attribute("\\whitebox"));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} WbflipPass;
 | 
			
		||||
 | 
			
		||||
struct SetparamPass : public Pass {
 | 
			
		||||
	SetparamPass() : Pass("setparam", "set/unset parameters on objects") { }
 | 
			
		||||
	void help() YS_OVERRIDE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -574,7 +574,7 @@ struct ShowWorker
 | 
			
		|||
			if (!design->selected_module(module->name))
 | 
			
		||||
				continue;
 | 
			
		||||
			if (design->selected_whole_module(module->name)) {
 | 
			
		||||
				if (module->get_bool_attribute("\\blackbox")) {
 | 
			
		||||
				if (module->get_blackbox_attribute()) {
 | 
			
		||||
					// log("Skipping blackbox module %s.\n", id2cstr(module->name));
 | 
			
		||||
					continue;
 | 
			
		||||
				} else
 | 
			
		||||
| 
						 | 
				
			
			@ -790,7 +790,7 @@ struct ShowPass : public Pass {
 | 
			
		|||
		if (format != "ps" && format != "dot") {
 | 
			
		||||
			int modcount = 0;
 | 
			
		||||
			for (auto &mod_it : design->modules_) {
 | 
			
		||||
				if (mod_it.second->get_bool_attribute("\\blackbox"))
 | 
			
		||||
				if (mod_it.second->get_blackbox_attribute())
 | 
			
		||||
					continue;
 | 
			
		||||
				if (mod_it.second->cells_.empty() && mod_it.second->connections().empty())
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,7 +134,7 @@ struct EquivOptPass:public ScriptPass
 | 
			
		|||
				opts = " -map <filename> ...";
 | 
			
		||||
			else
 | 
			
		||||
				opts = techmap_opts;
 | 
			
		||||
			run("techmap -D EQUIV -autoproc" + opts);
 | 
			
		||||
			run("techmap -wb -D EQUIV -autoproc" + opts);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("prove")) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -346,9 +346,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
 | 
			
		|||
		}
 | 
			
		||||
		RTLIL::Module *mod = design->modules_[cell->type];
 | 
			
		||||
 | 
			
		||||
		if (design->modules_.at(cell->type)->get_bool_attribute("\\blackbox")) {
 | 
			
		||||
		if (design->modules_.at(cell->type)->get_blackbox_attribute()) {
 | 
			
		||||
			if (flag_simcheck)
 | 
			
		||||
				log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox module.\n",
 | 
			
		||||
				log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n",
 | 
			
		||||
						cell->type.c_str(), module->name.c_str(), cell->name.c_str());
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -451,7 +451,7 @@ void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*, IdString::
 | 
			
		|||
 | 
			
		||||
	if (indent == 0)
 | 
			
		||||
		log("Top module:  %s\n", mod->name.c_str());
 | 
			
		||||
	else if (!mod->get_bool_attribute("\\blackbox"))
 | 
			
		||||
	else if (!mod->get_blackbox_attribute())
 | 
			
		||||
		log("Used module: %*s%s\n", indent, "", mod->name.c_str());
 | 
			
		||||
	used.insert(mod);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -491,7 +491,7 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
 | 
			
		|||
 | 
			
		||||
	int del_counter = 0;
 | 
			
		||||
	for (auto mod : del_modules) {
 | 
			
		||||
		if (!purge_lib && mod->get_bool_attribute("\\blackbox"))
 | 
			
		||||
		if (!purge_lib && mod->get_blackbox_attribute())
 | 
			
		||||
			continue;
 | 
			
		||||
		log("Removing unused module `%s'.\n", mod->name.c_str());
 | 
			
		||||
		design->modules_.erase(mod->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -910,7 +910,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
			if (m == nullptr)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
 | 
			
		||||
			if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
 | 
			
		||||
				IdString new_m_name = m->derive(design, cell->parameters, true);
 | 
			
		||||
				if (new_m_name.empty())
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ struct UniquifyPass : public Pass {
 | 
			
		|||
					if (tmod == nullptr)
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					if (tmod->get_bool_attribute("\\blackbox"))
 | 
			
		||||
					if (tmod->get_blackbox_attribute())
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					if (tmod->get_bool_attribute("\\unique") && newname == tmod->name)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -254,7 +254,7 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
 | 
			
		|||
 | 
			
		||||
	if (flag_flatten) {
 | 
			
		||||
		log_push();
 | 
			
		||||
		Pass::call_on_module(design, miter_module, "flatten; opt_expr -keepdc -undriven;;");
 | 
			
		||||
		Pass::call_on_module(design, miter_module, "flatten -wb; opt_expr -keepdc -undriven;;");
 | 
			
		||||
		log_pop();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -308,7 +308,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
 | 
			
		|||
 | 
			
		||||
	if (flag_flatten) {
 | 
			
		||||
		log_push();
 | 
			
		||||
		Pass::call_on_module(design, module, "flatten;;");
 | 
			
		||||
		Pass::call_on_module(design, module, "flatten -wb;;");
 | 
			
		||||
		log_pop();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -385,7 +385,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_expr -keepdc -undriven;;' on the miter circuit.\n");
 | 
			
		||||
		log("        call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    miter -assert [options] module [miter_name]\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +399,7 @@ struct MiterPass : public Pass {
 | 
			
		|||
		log("        keep module output ports.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -flatten\n");
 | 
			
		||||
		log("        call 'flatten; opt_expr -keepdc -undriven;;' on the miter circuit.\n");
 | 
			
		||||
		log("        call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -664,7 +664,7 @@ struct DfflibmapPass : public Pass {
 | 
			
		|||
		logmap_all();
 | 
			
		||||
 | 
			
		||||
		for (auto &it : design->modules_)
 | 
			
		||||
			if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (design->selected(it.second) && !it.second->get_blackbox_attribute())
 | 
			
		||||
				dfflibmap(design, it.second, prepare_mode);
 | 
			
		||||
 | 
			
		||||
		cell_mappings.clear();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -599,7 +599,7 @@ struct SimplemapPass : public Pass {
 | 
			
		|||
		simplemap_get_mappers(mappers);
 | 
			
		||||
 | 
			
		||||
		for (auto mod : design->modules()) {
 | 
			
		||||
			if (!design->selected(mod))
 | 
			
		||||
			if (!design->selected(mod) || mod->get_blackbox_attribute())
 | 
			
		||||
				continue;
 | 
			
		||||
			std::vector<RTLIL::Cell*> cells = mod->cells();
 | 
			
		||||
			for (auto cell : cells) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,6 +84,7 @@ struct TechmapWorker
 | 
			
		|||
	bool flatten_mode;
 | 
			
		||||
	bool recursive_mode;
 | 
			
		||||
	bool autoproc_mode;
 | 
			
		||||
	bool ignore_wb;
 | 
			
		||||
 | 
			
		||||
	TechmapWorker()
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +93,7 @@ struct TechmapWorker
 | 
			
		|||
		flatten_mode = false;
 | 
			
		||||
		recursive_mode = false;
 | 
			
		||||
		autoproc_mode = false;
 | 
			
		||||
		ignore_wb = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
 | 
			
		||||
| 
						 | 
				
			
			@ -383,7 +385,7 @@ struct TechmapWorker
 | 
			
		|||
	{
 | 
			
		||||
		std::string mapmsg_prefix = in_recursion ? "Recursively mapping" : "Mapping";
 | 
			
		||||
 | 
			
		||||
		if (!design->selected(module))
 | 
			
		||||
		if (!design->selected(module) || module->get_blackbox_attribute(ignore_wb))
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		bool log_continue = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -472,7 +474,7 @@ struct TechmapWorker
 | 
			
		|||
				RTLIL::Module *tpl = map->modules_[tpl_name];
 | 
			
		||||
				std::map<RTLIL::IdString, RTLIL::Const> parameters(cell->parameters.begin(), cell->parameters.end());
 | 
			
		||||
 | 
			
		||||
				if (tpl->get_bool_attribute("\\blackbox"))
 | 
			
		||||
				if (tpl->get_blackbox_attribute(ignore_wb))
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				if (!flatten_mode)
 | 
			
		||||
| 
						 | 
				
			
			@ -925,6 +927,9 @@ struct TechmapPass : public Pass {
 | 
			
		|||
		log("    -autoproc\n");
 | 
			
		||||
		log("        Automatically call \"proc\" on implementations that contain processes.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -wb\n");
 | 
			
		||||
		log("        Ignore the 'whitebox' attribute on cell implementations.\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");
 | 
			
		||||
| 
						 | 
				
			
			@ -1068,6 +1073,10 @@ struct TechmapPass : public Pass {
 | 
			
		|||
				worker.autoproc_mode = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-wb") {
 | 
			
		||||
				worker.ignore_wb = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
| 
						 | 
				
			
			@ -1145,7 +1154,7 @@ struct FlattenPass : public Pass {
 | 
			
		|||
	{
 | 
			
		||||
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    flatten [selection]\n");
 | 
			
		||||
		log("    flatten [options] [selection]\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("This pass flattens the design by replacing cells by their implementation. This\n");
 | 
			
		||||
		log("pass is very similar to the 'techmap' pass. The only difference is that this\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -1154,17 +1163,29 @@ struct FlattenPass : public Pass {
 | 
			
		|||
		log("Cells and/or modules with the 'keep_hierarchy' attribute set will not be\n");
 | 
			
		||||
		log("flattened by this command.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -wb\n");
 | 
			
		||||
		log("        Ignore the 'whitebox' attribute on cell implementations.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		log_header(design, "Executing FLATTEN pass (flatten design).\n");
 | 
			
		||||
		log_push();
 | 
			
		||||
 | 
			
		||||
		extra_args(args, 1, design);
 | 
			
		||||
 | 
			
		||||
		TechmapWorker worker;
 | 
			
		||||
		worker.flatten_mode = true;
 | 
			
		||||
 | 
			
		||||
		size_t argidx;
 | 
			
		||||
		for (argidx = 1; argidx < args.size(); argidx++) {
 | 
			
		||||
			if (args[argidx] == "-wb") {
 | 
			
		||||
				worker.ignore_wb = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
 | 
			
		||||
		for (auto module : design->modules())
 | 
			
		||||
			celltypeMap[module->name].insert(module->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -1209,7 +1230,7 @@ struct FlattenPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			dict<RTLIL::IdString, RTLIL::Module*> new_modules;
 | 
			
		||||
			for (auto mod : vector<Module*>(design->modules()))
 | 
			
		||||
				if (used_modules[mod->name] || mod->get_bool_attribute("\\blackbox")) {
 | 
			
		||||
				if (used_modules[mod->name] || mod->get_blackbox_attribute(worker.ignore_wb)) {
 | 
			
		||||
					new_modules[mod->name] = mod;
 | 
			
		||||
				} else {
 | 
			
		||||
					log("Deleting now unused module %s.\n", log_id(mod));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue