diff options
Diffstat (limited to 'passes')
| -rw-r--r-- | passes/cmds/bugpoint.cc | 118 | ||||
| -rw-r--r-- | passes/cmds/check.cc | 77 | ||||
| -rw-r--r-- | passes/cmds/plugin.cc | 6 | ||||
| -rw-r--r-- | passes/cmds/scc.cc | 77 | ||||
| -rw-r--r-- | passes/hierarchy/hierarchy.cc | 8 | ||||
| -rw-r--r-- | passes/opt/opt_lut.cc | 6 | ||||
| -rw-r--r-- | passes/opt/opt_share.cc | 4 | ||||
| -rw-r--r-- | passes/pmgen/pmgen.py | 8 | ||||
| -rw-r--r-- | passes/sat/freduce.cc | 1 | ||||
| -rw-r--r-- | passes/sat/sim.cc | 4 | ||||
| -rw-r--r-- | passes/techmap/abc.cc | 37 | ||||
| -rw-r--r-- | passes/techmap/abc9.cc | 2 | ||||
| -rw-r--r-- | passes/techmap/flatten.cc | 7 | 
13 files changed, 270 insertions, 85 deletions
diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 81d7a34bb..da81e7f09 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -30,7 +30,7 @@ struct BugpointPass : public Pass {  	{  		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|  		log("\n"); -		log("    bugpoint [options] -script <filename>\n"); +		log("    bugpoint [options] [-script <filename> | -command \"<command>\"]\n");  		log("\n");  		log("This command minimizes the current design that is known to crash Yosys with the\n");  		log("given script into a smaller testcase. It does this by removing an arbitrary part\n"); @@ -39,13 +39,13 @@ struct BugpointPass : public Pass {  		log("still causes a crash. Once this command finishes, it replaces the current design\n");  		log("with the smallest testcase it was able to produce.\n");  		log("\n"); -		log("    -script <filename>\n"); -		log("        use this script to crash Yosys. required.\n"); +		log("    -script <filename> | -command \"<command>\"\n"); +		log("        use this script file or command to crash Yosys. required.\n");  		log("\n");  		log("    -yosys <filename>\n");  		log("        use this Yosys binary. if not specified, `yosys` is used.\n");  		log("\n"); -		log("    -grep <string>\n"); +		log("    -grep \"<string>\"\n");  		log("        only consider crashes that place this string in the log file.\n");  		log("\n");  		log("    -fast\n"); @@ -77,6 +77,10 @@ struct BugpointPass : public Pass {  		log("    -connections\n");  		log("        try to reconnect ports to 'x.\n");  		log("\n"); +		log("    -processes\n"); +		log("        try to remove processes. processes with a (* bugpoint_keep *) attribute\n"); +		log("        will be skipped.\n"); +		log("\n");  		log("    -assigns\n");  		log("        try to remove process assigns from cases.\n");  		log("\n"); @@ -85,7 +89,7 @@ struct BugpointPass : public Pass {  		log("\n");  	} -	bool run_yosys(RTLIL::Design *design, string yosys_cmd, string script) +	bool run_yosys(RTLIL::Design *design, string yosys_cmd, string yosys_arg)  	{  		design->sort(); @@ -93,7 +97,7 @@ struct BugpointPass : public Pass {  		RTLIL_BACKEND::dump_design(f, design, /*only_selected=*/false, /*flag_m=*/true, /*flag_n=*/false);  		f.close(); -		string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log -s %s bugpoint-case.il", yosys_cmd.c_str(), script.c_str()); +		string yosys_cmdline = stringf("%s -qq -L bugpoint-case.log %s bugpoint-case.il", yosys_cmd.c_str(), yosys_arg.c_str());  		return run_command(yosys_cmdline) == 0;  	} @@ -102,6 +106,9 @@ struct BugpointPass : public Pass {  		if (grep.empty())  			return true; +		if (grep.size() > 2 && grep.front() == '"' && grep.back() == '"') +			grep = grep.substr(1, grep.size() - 2); +  		std::ifstream f("bugpoint-case.log");  		while (!f.eof())  		{ @@ -129,7 +136,7 @@ struct BugpointPass : public Pass {  		return design_copy;  	} -	RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool assigns, bool updates) +	RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool processes, bool assigns, bool updates, bool wires)  	{  		RTLIL::Design *design_copy = new RTLIL::Design;  		for (auto module : design->modules()) @@ -194,7 +201,6 @@ struct BugpointPass : public Pass {  				if (mod->get_blackbox_attribute())  					continue; -  				Cell *removed_cell = nullptr;  				for (auto cell : mod->cells())  				{ @@ -257,6 +263,33 @@ struct BugpointPass : public Pass {  				}  			}  		} +		if (processes) +		{ +			for (auto mod : design_copy->modules()) +			{ +				if (mod->get_blackbox_attribute()) +					continue; + +				RTLIL::IdString removed_process; +				for (auto process : mod->processes) +				{ +					if (process.second->get_bool_attribute(ID::bugpoint_keep)) +						continue; + +					if (index++ == seed) +					{ +						log_header(design, "Trying to remove process %s.%s.\n", log_id(mod), log_id(process.first)); +						removed_process = process.first; +						break; +					} +				} +				if (!removed_process.empty()) { +					delete mod->processes[removed_process]; +					mod->processes.erase(removed_process); +					return design_copy; +				} +			} +		}  		if (assigns)  		{  			for (auto mod : design_copy->modules()) @@ -310,14 +343,43 @@ struct BugpointPass : public Pass {  				}  			}  		} +		if (wires) +		{ +			for (auto mod : design_copy->modules()) +			{ +				if (mod->get_blackbox_attribute()) +					continue; + +				Wire *removed_wire = nullptr; +				for (auto wire : mod->wires()) +				{ +					if (wire->get_bool_attribute(ID::bugpoint_keep)) +						continue; + +					if (wire->name.begins_with("$delete_wire")) +						continue; + +					if (index++ == seed) +					{ +						log_header(design, "Trying to remove wire %s.%s.\n", log_id(mod), log_id(wire)); +						removed_wire = wire; +						break; +					} +				} +				if (removed_wire) { +					mod->remove({removed_wire}); +					return design_copy; +				} +			} +		}  		return nullptr;  	}  	void execute(std::vector<std::string> args, RTLIL::Design *design) override  	{ -		string yosys_cmd = "yosys", script, grep; +		string yosys_cmd = "yosys", yosys_arg, grep;  		bool fast = false, clean = false; -		bool modules = false, ports = false, cells = false, connections = false, assigns = false, updates = false, has_part = false; +		bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false;  		log_header(design, "Executing BUGPOINT pass (minimize testcases).\n");  		log_push(); @@ -330,7 +392,15 @@ struct BugpointPass : public Pass {  				continue;  			}  			if (args[argidx] == "-script" && argidx + 1 < args.size()) { -				script = args[++argidx]; +				if (!yosys_arg.empty()) +					log_cmd_error("A -script or -command option can be only provided once!\n"); +				yosys_arg = stringf("-s %s", args[++argidx].c_str()); +				continue; +			} +			if (args[argidx] == "-command" && argidx + 1 < args.size()) { +				if (!yosys_arg.empty()) +					log_cmd_error("A -script or -command option can be only provided once!\n"); +				yosys_arg = stringf("-p %s", args[++argidx].c_str());  				continue;  			}  			if (args[argidx] == "-grep" && argidx + 1 < args.size()) { @@ -365,6 +435,11 @@ struct BugpointPass : public Pass {  				has_part = true;  				continue;  			} +			if (args[argidx] == "-processes") { +				processes = true; +				has_part = true; +				continue; +			}  			if (args[argidx] == "-assigns") {  				assigns = true;  				has_part = true; @@ -375,12 +450,17 @@ struct BugpointPass : public Pass {  				has_part = true;  				continue;  			} +			if (args[argidx] == "-wires") { +				wires = true; +				has_part = true; +				continue; +			}  			break;  		}  		extra_args(args, argidx, design); -		if (script.empty()) -			log_cmd_error("Missing -script option.\n"); +		if (yosys_arg.empty()) +			log_cmd_error("Missing -script or -command option.\n");  		if (!has_part)  		{ @@ -388,16 +468,18 @@ struct BugpointPass : public Pass {  			ports = true;  			cells = true;  			connections = true; +			processes = true;  			assigns = true;  			updates = true; +			wires = true;  		}  		if (!design->full_selection())  			log_cmd_error("This command only operates on fully selected designs!\n");  		RTLIL::Design *crashing_design = clean_design(design, clean); -		if (run_yosys(crashing_design, yosys_cmd, script)) -			log_cmd_error("The provided script file and Yosys binary do not crash on this design!\n"); +		if (run_yosys(crashing_design, yosys_cmd, yosys_arg)) +			log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n");  		if (!check_logfile(grep))  			log_cmd_error("The provided grep string is not found in the log file!\n"); @@ -405,7 +487,7 @@ struct BugpointPass : public Pass {  		bool found_something = false, stage2 = false;  		while (true)  		{ -			if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, assigns, updates)) +			if (RTLIL::Design *simplified = simplify_something(crashing_design, seed, stage2, modules, ports, cells, connections, processes, assigns, updates, wires))  			{  				simplified = clean_design(simplified, fast, /*do_delete=*/true); @@ -413,12 +495,12 @@ struct BugpointPass : public Pass {  				if (clean)  				{  					RTLIL::Design *testcase = clean_design(simplified); -					crashes = !run_yosys(testcase, yosys_cmd, script); +					crashes = !run_yosys(testcase, yosys_cmd, yosys_arg);  					delete testcase;  				}  				else  				{ -					crashes = !run_yosys(simplified, yosys_cmd, script); +					crashes = !run_yosys(simplified, yosys_cmd, yosys_arg);  				}  				if (crashes && check_logfile(grep)) diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index a8b5362b3..36febb98a 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -35,30 +35,28 @@ struct CheckPass : public Pass {  		log("\n");  		log("This pass identifies the following problems in the current design:\n");  		log("\n"); -		log(" - combinatorial loops\n"); -		log("\n"); -		log(" - two or more conflicting drivers for one wire\n"); -		log("\n"); -		log(" - used wires that do not have a driver\n"); +		log("  - combinatorial loops\n"); +		log("  - two or more conflicting drivers for one wire\n"); +		log("  - used wires that do not have a driver\n");  		log("\n");  		log("Options:\n");  		log("\n"); -		log("  -noinit\n"); -		log("    Also check for wires which have the 'init' attribute set.\n"); +		log("    -noinit\n"); +		log("        also check for wires which have the 'init' attribute set\n");  		log("\n"); -		log("  -initdrv\n"); -		log("    Also check for wires that have the 'init' attribute set and are not\n"); -		log("    driven by an FF cell type.\n"); +		log("    -initdrv\n"); +		log("        also check for wires that have the 'init' attribute set and are not\n"); +		log("        driven by an FF cell type\n");  		log("\n"); -		log("  -mapped\n"); -		log("    Also check for internal cells that have not been mapped to cells of the\n"); -		log("    target architecture.\n"); +		log("    -mapped\n"); +		log("        also check for internal cells that have not been mapped to cells of the\n"); +		log("        target architecture\n");  		log("\n"); -		log("  -allow-tbuf\n"); -		log("    Modify the -mapped behavior to still allow $_TBUF_ cells.\n"); +		log("    -allow-tbuf\n"); +		log("        modify the -mapped behavior to still allow $_TBUF_ cells\n");  		log("\n"); -		log("  -assert\n"); -		log("    Produce a runtime error if any problems are found in the current design.\n"); +		log("    -assert\n"); +		log("        produce a runtime error if any problems are found in the current design\n");  		log("\n");  	}  	void execute(std::vector<std::string> args, RTLIL::Design *design) override @@ -100,10 +98,7 @@ struct CheckPass : public Pass {  		for (auto module : design->selected_whole_modules_warn())  		{ -			if (module->has_processes_warn()) -				continue; - -			log("checking module %s..\n", log_id(module)); +			log("Checking module %s...\n", log_id(module));  			SigMap sigmap(module);  			dict<SigBit, vector<string>> wire_drivers; @@ -111,6 +106,44 @@ struct CheckPass : public Pass {  			pool<SigBit> used_wires;  			TopoSort<string> topo; +			for (auto &proc_it : module->processes) +			{ +				std::vector<RTLIL::CaseRule*> all_cases = {&proc_it.second->root_case}; +				for (size_t i = 0; i < all_cases.size(); i++) { +					for (auto action : all_cases[i]->actions) { +						for (auto bit : sigmap(action.first)) +							if (bit.wire) { +								wire_drivers[bit].push_back( +									stringf("action %s <= %s (case rule) in process %s", +									        log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); +							} +						for (auto bit : sigmap(action.second)) +							if (bit.wire) used_wires.insert(bit); +					} +					for (auto switch_ : all_cases[i]->switches) { +						for (auto case_ : switch_->cases) { +							all_cases.push_back(case_); +							for (auto compare : case_->compare) +								for (auto bit : sigmap(compare)) +									if (bit.wire) used_wires.insert(bit); +						} +					} +				} +				for (auto &sync : proc_it.second->syncs) { +					for (auto bit : sigmap(sync->signal)) +						if (bit.wire) used_wires.insert(bit); +					for (auto action : sync->actions) { +						for (auto bit : sigmap(action.first)) +							if (bit.wire) +								wire_drivers[bit].push_back( +									stringf("action %s <= %s (sync rule) in process %s", +									        log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); +						for (auto bit : sigmap(action.second)) +							if (bit.wire) used_wires.insert(bit); +					} +				} +			} +  			for (auto cell : module->cells())  			{  				if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) { @@ -216,7 +249,7 @@ struct CheckPass : public Pass {  			}  		} -		log("found and reported %d problems.\n", counter); +		log("Found and reported %d problems.\n", counter);  		if (assert_mode && counter > 0)  			log_error("Found %d problems in 'check -assert'.\n", counter); diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 3ed19497d..a94769bcd 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -93,7 +93,11 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)  #else  void load_plugin(std::string, std::vector<std::string>)  { -	log_error("This version of yosys is built without plugin support.\n"); +	log_error( +		"\n  This version of Yosys cannot load plugins at runtime.\n" +		"  Some plugins may have been included at build time.\n" +		"  Use option `-H' to see the available built-in and plugin commands.\n" +	);  }  #endif diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 8e7f3f990..7aa9a484f 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -37,7 +37,7 @@ struct SccWorker  	RTLIL::Design *design;  	RTLIL::Module *module;  	SigMap sigmap; -	CellTypes ct; +	CellTypes ct, specifyCells;  	std::set<RTLIL::Cell*> workQueue;  	std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> cellToNextCell; @@ -100,7 +100,7 @@ struct SccWorker  		}  	} -	SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, int maxDepth) : +	SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, bool specifyMode, int maxDepth) :  			design(design), module(module), sigmap(module)  	{  		if (module->processes.size() > 0) { @@ -115,6 +115,18 @@ struct SccWorker  			ct.setup_stdcells();  		} +		// Discover boxes with specify rules in them, for special handling. +		if (specifyMode) { +			for (auto mod : design->modules()) +				if (mod->get_blackbox_attribute(false)) +					for (auto cell : mod->cells()) +						if (cell->type == ID($specify2)) +						{ +							specifyCells.setup_module(mod); +							break; +						} +		} +  		SigPool selectedSignals;  		SigSet<RTLIL::Cell*> sigToNextCells; @@ -129,29 +141,52 @@ struct SccWorker  			if (!design->selected(module, cell))  				continue; -			if (!allCellTypes && !ct.cell_known(cell->type)) +			if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type))  				continue;  			workQueue.insert(cell);  			RTLIL::SigSpec inputSignals, outputSignals; -			for (auto &conn : cell->connections()) -			{ -				bool isInput = true, isOutput = true; +			if (specifyCells.cell_known(cell->type)) { +				// Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes. +				for (auto subcell : design->module(cell->type)->cells()) +				{ +					if (subcell->type != ID($specify2)) +						continue; -				if (ct.cell_known(cell->type)) { -					isInput = ct.cell_input(cell->type, conn.first); -					isOutput = ct.cell_output(cell->type, conn.first); +					for (auto bit : subcell->getPort(ID::SRC)) +					{ +						if (!bit.wire || !cell->hasPort(bit.wire->name)) +							continue; +						inputSignals.append(sigmap(cell->getPort(bit.wire->name))); +					} + +					for (auto bit : subcell->getPort(ID::DST)) +					{ +						if (!bit.wire || !cell->hasPort(bit.wire->name)) +							continue; +						outputSignals.append(sigmap(cell->getPort(bit.wire->name))); +					}  				} +			} else { +				for (auto &conn : cell->connections()) +				{ +					bool isInput = true, isOutput = true; + +					if (ct.cell_known(cell->type)) { +						isInput = ct.cell_input(cell->type, conn.first); +						isOutput = ct.cell_output(cell->type, conn.first); +					} -				RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); -				sig.sort_and_unify(); +					RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); +					sig.sort_and_unify(); -				if (isInput) -					inputSignals.append(sig); -				if (isOutput) -					outputSignals.append(sig); +					if (isInput) +						inputSignals.append(sig); +					if (isOutput) +						outputSignals.append(sig); +				}  			}  			inputSignals.sort_and_unify(); @@ -228,7 +263,7 @@ struct SccPass : public Pass {  		log("design.\n");  		log("\n");  		log("    -expect <num>\n"); -		log("        expect to find exactly <num> SSCs. A different number of SSCs will\n"); +		log("        expect to find exactly <num> SCCs. A different number of SCCs will\n");  		log("        produce an error.\n");  		log("\n");  		log("    -max_depth <num>\n"); @@ -254,6 +289,9 @@ struct SccPass : public Pass {  		log("        replace the current selection with a selection of all cells and wires\n");  		log("        that are part of a found logic loop\n");  		log("\n"); +		log("    -specify\n"); +		log("        examine specify rules to detect logic loops in whitebox/blackbox cells\n"); +		log("\n");  	}  	void execute(std::vector<std::string> args, RTLIL::Design *design) override  	{ @@ -261,6 +299,7 @@ struct SccPass : public Pass {  		bool allCellTypes = false;  		bool selectMode = false;  		bool nofeedbackMode = false; +		bool specifyMode = false;  		int maxDepth = -1;  		int expect = -1; @@ -293,6 +332,10 @@ struct SccPass : public Pass {  				selectMode = true;  				continue;  			} +			if (args[argidx] == "-specify") { +				specifyMode = true; +				continue; +			}  			break;  		}  		int origSelectPos = design->selection_stack.size() - 1; @@ -303,7 +346,7 @@ struct SccPass : public Pass {  		for (auto mod : design->selected_modules())  		{ -			SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); +			SccWorker worker(design, mod, nofeedbackMode, allCellTypes, specifyMode, maxDepth);  			if (!setAttr.empty())  			{ diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 225e1feae..3372687e1 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -1233,14 +1233,18 @@ struct HierarchyPass : public Pass {  						{  							int n = GetSize(conn.second) - GetSize(w);  							if (!w->port_input && w->port_output) -								module->connect(sig.extract(GetSize(w), n), Const(0, n)); +							{ +								RTLIL::SigSpec out = sig.extract(0, GetSize(w)); +								out.extend_u0(GetSize(sig), w->is_signed); +								module->connect(sig.extract(GetSize(w), n), out.extract(GetSize(w), n)); +							}  							sig.remove(GetSize(w), n);  						}  						else  						{  							int n = GetSize(w) - GetSize(conn.second);  							if (w->port_input && !w->port_output) -								sig.append(Const(0, n)); +								sig.extend_u0(GetSize(w), sig.is_wire() && sig.as_wire()->is_signed);  							else  								sig.append(module->addWire(NEW_ID, n));  						} diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 07a91af8a..623101016 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -277,12 +277,13 @@ struct OptLutWorker  					module->connect(lut_output, value);  					sigmap.add(lut_output, value); -					module->remove(lut);  					luts.erase(lut);  					luts_arity.erase(lut);  					luts_dlogics.erase(lut);  					luts_dlogic_inputs.erase(lut); +					module->remove(lut); +					  					eliminated_count++;  					if (limit > 0)  						limit--; @@ -493,11 +494,12 @@ struct OptLutWorker  					luts_arity[lutM] = lutM_arity;  					luts.erase(lutR);  					luts_arity.erase(lutR); -					lutR->module->remove(lutR);  					worklist.insert(lutM);  					worklist.erase(lutR); +					lutR->module->remove(lutR); +  					combined_count++;  					if (limit > 0)  						limit--; diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 53296699c..62a478673 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -244,8 +244,8 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<  	}  	if (shared_op->type.in(ID($alu))) { -		shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_sig_out))); -		shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_sig_out))); +		shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_out))); +		shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_out)));  	}  	bool is_fine = shared_op->type.in(FINE_BITWISE_OPS); diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 592a26fa6..6e2fabeeb 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -451,7 +451,9 @@ with open(outfile, "w") as f:      current_pattern = None      print("  SigSpec port(Cell *cell, IdString portname) {", file=f) -    print("    return sigmap(cell->getPort(portname));", file=f) +    print("    try {", file=f) +    print("      return sigmap(cell->getPort(portname));", file=f) +    print("    } catch(std::out_of_range&) { log_error(\"Accessing non existing port %s\\n\",portname.c_str()); }", file=f)      print("  }", file=f)      print("", file=f)      print("  SigSpec port(Cell *cell, IdString portname, const SigSpec& defval) {", file=f) @@ -460,7 +462,9 @@ with open(outfile, "w") as f:      print("", file=f)      print("  Const param(Cell *cell, IdString paramname) {", file=f) -    print("    return cell->getParam(paramname);", file=f) +    print("    try {", file=f) +    print("      return cell->getParam(paramname);", file=f) +    print("    } catch(std::out_of_range&) { log_error(\"Accessing non existing parameter %s\\n\",paramname.c_str()); }", file=f)      print("  }", file=f)      print("", file=f)      print("  Const param(Cell *cell, IdString paramname, const Const& defval) {", file=f) diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index 762edfdfb..f87b85da9 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -27,6 +27,7 @@  #include <stdio.h>  #include <string.h>  #include <algorithm> +#include <limits>  USING_YOSYS_NAMESPACE  PRIVATE_NAMESPACE_BEGIN diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 75f922dba..3ba66bd33 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -810,7 +810,9 @@ struct SimPass : public Pass {  		size_t argidx;  		for (argidx = 1; argidx < args.size(); argidx++) {  			if (args[argidx] == "-vcd" && argidx+1 < args.size()) { -				worker.vcdfile.open(args[++argidx].c_str()); +				std::string vcd_filename = args[++argidx]; +				rewrite_filename(vcd_filename); +				worker.vcdfile.open(vcd_filename.c_str());  				continue;  			}  			if (args[argidx] == "-n" && argidx+1 < args.size()) { diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 192e39372..1169e3da0 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -54,6 +54,7 @@  #include <cerrno>  #include <sstream>  #include <climits> +#include <vector>  #ifndef _WIN32  #  include <unistd.h> @@ -654,7 +655,7 @@ struct abc_output_filter  };  void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, -		std::string liberty_file, std::string constr_file, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str, +		std::vector<std::string> &liberty_files, std::string constr_file, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str,  		bool keepff, std::string delay_target, std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode,  		const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress)  { @@ -709,8 +710,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin  	std::string abc_script = stringf("read_blif %s/input.blif; ", tempdir_name.c_str()); -	if (!liberty_file.empty()) { -		abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); +	if (!liberty_files.empty()) { +		for (std::string liberty_file : liberty_files) abc_script += stringf("read_lib -w %s; ", liberty_file.c_str());  		if (!constr_file.empty())  			abc_script += stringf("read_constr -v %s; ", constr_file.c_str());  	} else @@ -738,7 +739,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin  		abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT;  		if (all_luts_cost_same && !fast_mode)  			abc_script += "; lutpack {S}"; -	} else if (!liberty_file.empty()) +	} else if (!liberty_files.empty())  		abc_script += constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR);  	else if (sop_mode)  		abc_script += fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP; @@ -1019,7 +1020,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin  		if (ifs.fail())  			log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); -		bool builtin_lib = liberty_file.empty(); +		bool builtin_lib = liberty_files.empty();  		RTLIL::Design *mapped_design = new RTLIL::Design;  		parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, sop_mode); @@ -1471,7 +1472,8 @@ struct AbcPass : public Pass {  		po_map.clear();  		std::string exe_file = yosys_abc_executable; -		std::string script_file, liberty_file, constr_file, clk_str; +		std::string script_file, default_liberty_file, constr_file, clk_str; +		std::vector<std::string> liberty_files;  		std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1";  		bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true;  		bool show_tempdir = false, sop_mode = false; @@ -1489,7 +1491,7 @@ struct AbcPass : public Pass {  		std::string lut_arg, luts_arg, g_arg;  		exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */);  		script_file = design->scratchpad_get_string("abc.script", script_file); -		liberty_file = design->scratchpad_get_string("abc.liberty", liberty_file); +		default_liberty_file = design->scratchpad_get_string("abc.liberty", default_liberty_file);  		constr_file = design->scratchpad_get_string("abc.constr", constr_file);  		if (design->scratchpad.count("abc.D")) {  			delay_target = "-D " + design->scratchpad_get_string("abc.D"); @@ -1551,7 +1553,7 @@ struct AbcPass : public Pass {  				continue;  			}  			if (arg == "-liberty" && argidx+1 < args.size()) { -				liberty_file = args[++argidx]; +				liberty_files.push_back(args[++argidx]);  				continue;  			}  			if (arg == "-constr" && argidx+1 < args.size()) { @@ -1643,12 +1645,16 @@ struct AbcPass : public Pass {  		}  		extra_args(args, argidx, design); +		if (liberty_files.empty() && !default_liberty_file.empty()) liberty_files.push_back(default_liberty_file); +  		rewrite_filename(script_file);  		if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+')  			script_file = std::string(pwd) + "/" + script_file; -		rewrite_filename(liberty_file); -		if (!liberty_file.empty() && !is_absolute_path(liberty_file)) -			liberty_file = std::string(pwd) + "/" + liberty_file; +		for (int i = 0; i < GetSize(liberty_files); i++) { +			rewrite_filename(liberty_files[i]); +			if (!liberty_files[i].empty() && !is_absolute_path(liberty_files[i])) +				liberty_files[i] = std::string(pwd) + "/" + liberty_files[i]; +		}  		rewrite_filename(constr_file);  		if (!constr_file.empty() && !is_absolute_path(constr_file))  			constr_file = std::string(pwd) + "/" + constr_file; @@ -1794,6 +1800,7 @@ struct AbcPass : public Pass {  					gate_list.push_back("OAI4");  					gate_list.push_back("MUX");  					gate_list.push_back("NMUX"); +					goto ok_alias;  				}  				if (g_arg_from_cmd)  					cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str())); @@ -1811,9 +1818,9 @@ struct AbcPass : public Pass {  			}  		} -		if (!lut_costs.empty() && !liberty_file.empty()) +		if (!lut_costs.empty() && !liberty_files.empty())  			log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n"); -		if (!constr_file.empty() && liberty_file.empty()) +		if (!constr_file.empty() && liberty_files.empty())  			log_cmd_error("Got -constr but no -liberty!\n");  		if (enabled_gates.empty()) { @@ -1844,7 +1851,7 @@ struct AbcPass : public Pass {  			initvals.set(&assign_map, mod);  			if (!dff_mode || !clk_str.empty()) { -				abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, +				abc_module(design, mod, script_file, exe_file, liberty_files, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff,  						delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress);  				continue;  			} @@ -1989,7 +1996,7 @@ struct AbcPass : public Pass {  				clk_sig = assign_map(std::get<1>(it.first));  				en_polarity = std::get<2>(it.first);  				en_sig = assign_map(std::get<3>(it.first)); -				abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", +				abc_module(design, mod, script_file, exe_file, liberty_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$",  						keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress);  				assign_map.set(mod);  			} diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7d017ac40..56bb15495 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -339,7 +339,7 @@ struct Abc9Pass : public ScriptPass  		if (check_label("pre")) {  			run("read_verilog -icells -lib -specify +/abc9_model.v"); -			run("scc -set_attr abc9_scc_id {}"); +			run("scc -specify -set_attr abc9_scc_id {}");  			if (help_mode)  				run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)");  			else diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index 08978f446..f35b7ff60 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -180,12 +180,15 @@ struct FlattenWorker  			RTLIL::Wire *tpl_wire = tpl->wire(port_name);  			RTLIL::SigSig new_conn; +			bool is_signed = false;  			if (tpl_wire->port_output && !tpl_wire->port_input) {  				new_conn.first = port_it.second;  				new_conn.second = tpl_wire; +				is_signed = tpl_wire->is_signed;  			} else if (!tpl_wire->port_output && tpl_wire->port_input) {  				new_conn.first = tpl_wire;  				new_conn.second = port_it.second; +				is_signed = new_conn.second.is_wire() && new_conn.second.as_wire()->is_signed;  			} else {  				SigSpec sig_tpl = tpl_wire, sig_mod = port_it.second;  				for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) { @@ -204,11 +207,11 @@ struct FlattenWorker  			if (new_conn.second.size() > new_conn.first.size())  				new_conn.second.remove(new_conn.first.size(), new_conn.second.size() - new_conn.first.size());  			if (new_conn.second.size() < new_conn.first.size()) -				new_conn.second.append(RTLIL::SigSpec(RTLIL::State::S0, new_conn.first.size() - new_conn.second.size())); +				new_conn.second.extend_u0(new_conn.first.size(), is_signed);  			log_assert(new_conn.first.size() == new_conn.second.size());  			if (sigmap(new_conn.first).has_const()) -				log_error("Mismatch in directionality for cell port %s.%s.%s: %s <= %s\n", +				log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n",  					log_id(module), log_id(cell), log_id(port_it.first), log_signal(new_conn.first), log_signal(new_conn.second));  			module->connect(new_conn);  | 
