mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Selective boolopt
This commit is contained in:
		
							parent
							
								
									e9b0f73cb3
								
							
						
					
					
						commit
						c32d0a412c
					
				
					 8 changed files with 297 additions and 36 deletions
				
			
		|  | @ -17,8 +17,6 @@ | |||
|  * | ||||
|  */ | ||||
| #ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS | ||||
| #include <stack> | ||||
| 
 | ||||
| /*
 | ||||
|     This Visitor decorates the AST with a loop ID attribute for all outer for loops. | ||||
|     All AST nodes contained within the subtree of an outer for-loop | ||||
|  | @ -41,7 +39,7 @@ class DecorateLoopsVisitor : public VeriVisitor | |||
| 			// We increase the loop count when we enter a new set of imbricated loops,
 | ||||
| 			// That way we have a loop index for the outermost loop as we want to identify and group
 | ||||
| 			// logic generated by imbricated loops
 | ||||
| 			outerLoopId++; | ||||
| 			outerLoopId = node.Linefile(); | ||||
| 		} | ||||
| 		loopStack.push((VeriLoop *)&node); | ||||
| 	} | ||||
|  | @ -58,7 +56,7 @@ class DecorateLoopsVisitor : public VeriVisitor | |||
| 		if (loopStack.size()) { | ||||
| 			if (loopStack.top() == (VeriLoop *)&node) { | ||||
| 				loopStack.pop(); | ||||
| 				std::cout << "Loop out: " << (VeriFor *)&node << std::endl; | ||||
| 				// std::cout << "Loop out: " << (VeriFor *)&node << std::endl;
 | ||||
| 				return; | ||||
| 			} | ||||
| 			Verific::linefile_type linefile = (Verific::linefile_type)node.Linefile(); | ||||
|  | @ -73,6 +71,6 @@ class DecorateLoopsVisitor : public VeriVisitor | |||
| 
 | ||||
|       private: | ||||
| 	std::stack<VeriLoop *> loopStack; | ||||
| 	uint32_t outerLoopId = 0; | ||||
| 	linefile_type outerLoopId = nullptr; | ||||
| }; | ||||
| #endif | ||||
|  |  | |||
|  | @ -55,6 +55,7 @@ USING_YOSYS_NAMESPACE | |||
| #include "VeriLibrary.h" | ||||
| #include "VeriExpression.h" | ||||
| #ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS | ||||
| #include "VeriStatement.h" | ||||
| #include "VeriConstVal.h" | ||||
| #endif | ||||
| #endif | ||||
|  | @ -430,8 +431,8 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att | |||
| 	if (obj->Linefile()) { | ||||
| 		attributes[ID::src] = stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol()); | ||||
| #ifdef VERIFIC_LINEFILE_INCLUDES_LOOPS | ||||
| 		if (uint32_t loopid = obj->Linefile()->GetInLoop()) { | ||||
| 			attributes[RTLIL::escape_id("in_loop_" + std::to_string(loopid))] = std::to_string(loopid); | ||||
| 		if (linefile_type loopid = obj->Linefile()->GetInLoop()) { | ||||
| 			attributes[RTLIL::escape_id("in_for_loop")] = stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(loopid), loopid->GetLeftLine(), loopid->GetLeftCol(), loopid->GetRightLine(), loopid->GetRightCol()); | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
|  |  | |||
							
								
								
									
										214
									
								
								passes/cmds/longloop_select.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								passes/cmds/longloop_select.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,214 @@ | |||
| /*
 | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "kernel/celltypes.h" | ||||
| #include "kernel/sigtools.h" | ||||
| #include "kernel/utils.h" | ||||
| #include "kernel/yosys.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| struct LongLoopSelect : public ScriptPass { | ||||
| 	LongLoopSelect() | ||||
| 	    : ScriptPass("longloop_select", "Selects long for-loops (Creating logic above a certain logic depth) for further optimization") | ||||
| 	{ | ||||
| 	} | ||||
| 	void script() override {} | ||||
| 
 | ||||
| 	// Adapted from the torder pass
 | ||||
| 	void toposorting(std::vector<Cell *> &cells, SigMap &sigmap, | ||||
| 			 TopoSort<RTLIL::Cell *, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> &toposort, bool debug) | ||||
| 	{ | ||||
| 		if (debug) { | ||||
| 			log("  Collecting design data\n"); | ||||
| 			log_flush(); | ||||
| 		} | ||||
| 		dict<SigBit, pool<Cell *>> bit_drivers, bit_users; | ||||
| 		for (Cell *cell : cells) { | ||||
| 			for (auto conn : cell->connections()) { | ||||
| 				bool noautostop = false; | ||||
| 				if (!noautostop && yosys_celltypes.cell_known(cell->type)) { | ||||
| 					if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA)) | ||||
| 						continue; | ||||
| 					if (cell->type.in(ID($memrd), ID($memrd_v2)) && conn.first == ID::DATA) | ||||
| 						continue; | ||||
| 				} | ||||
| 
 | ||||
| 				if (cell->input(conn.first)) | ||||
| 					for (auto bit : sigmap(conn.second)) | ||||
| 						bit_users[bit].insert(cell); | ||||
| 
 | ||||
| 				if (cell->output(conn.first)) | ||||
| 					for (auto bit : sigmap(conn.second)) | ||||
| 						bit_drivers[bit].insert(cell); | ||||
| 
 | ||||
| 				toposort.node(cell); | ||||
| 			} | ||||
| 		} | ||||
| 		if (debug) { | ||||
| 			log("  Creating sorting data structure\n"); | ||||
| 			log_flush(); | ||||
| 		} | ||||
| 		for (auto &it : bit_users) | ||||
| 			if (bit_drivers.count(it.first)) | ||||
| 				for (auto driver_cell : bit_drivers.at(it.first)) | ||||
| 					for (auto user_cell : it.second) | ||||
| 						toposort.edge(driver_cell, user_cell); | ||||
| 
 | ||||
| 		toposort.analyze_loops = false; | ||||
| 		if (debug) { | ||||
| 			log("  Sorting\n"); | ||||
| 			log_flush(); | ||||
| 		} | ||||
| 		toposort.sort(); | ||||
| 	} | ||||
| 
 | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) override | ||||
| 	{ | ||||
| 		if (design == nullptr) { | ||||
| 			log_error("No design object"); | ||||
| 			return; | ||||
| 		} | ||||
| 		uint32_t threshold_depth = 100; | ||||
| 		bool debug = false; | ||||
| 		size_t argidx; | ||||
| 		std::string abc_script; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) { | ||||
| 			if (args[argidx] == "-depth") { | ||||
| 				argidx++; | ||||
| 				threshold_depth = std::stoul(args[argidx], nullptr, 10); | ||||
| 			} else if (args[argidx] == "-debug") { | ||||
| 				debug = true; | ||||
| 			} else if (args[argidx] == "-abc") { | ||||
| 				argidx++; | ||||
| 				abc_script = args[argidx]; | ||||
| 			} else { | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		if (std::getenv("DEBUG_LONGLOOPS")) { | ||||
| 			debug = true; | ||||
| 		} | ||||
| 		log("Running longloop_select pass\n"); | ||||
| 		log_flush(); | ||||
| 		for (auto module : design->modules()) { | ||||
| 			if (debug) { | ||||
| 				log("Module %s\n", log_id(module)); | ||||
| 				log_flush(); | ||||
| 			} | ||||
| 			if (debug) { | ||||
| 				log("  Creating sigmap\n"); | ||||
| 				log_flush(); | ||||
| 			} | ||||
| 			SigMap sigmap(module); | ||||
| 			std::map<std::string, std::vector<Cell *>> loopIndexCellMap; | ||||
| 			if (debug) { | ||||
| 				log("  Creating sorting datastructures\n"); | ||||
| 				log_flush(); | ||||
| 			} | ||||
| 			for (auto cell : module->cells()) { | ||||
| 				std::string loopIndex = cell->get_string_attribute("\\in_for_loop"); | ||||
| 				if (!loopIndex.empty()) { | ||||
| 					std::map<std::string, std::vector<Cell *>>::iterator itr = loopIndexCellMap.find(loopIndex); | ||||
| 					if (itr == loopIndexCellMap.end()) { | ||||
| 						std::vector<Cell *> cellSet; | ||||
| 						cellSet.push_back(cell); | ||||
| 						loopIndexCellMap.emplace(loopIndex, cellSet); | ||||
| 					} else { | ||||
| 						itr->second.push_back(cell); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if (!loopIndexCellMap.empty()) { | ||||
| 				log("  Found %ld for-loop clusters in module %s\n", loopIndexCellMap.size(), module->name.c_str()); | ||||
| 				log_flush(); | ||||
| 			} | ||||
| 			 | ||||
| 			for (std::map<std::string, std::vector<Cell *>>::iterator itrCluster = loopIndexCellMap.begin(); | ||||
| 			     itrCluster != loopIndexCellMap.end(); itrCluster++) { | ||||
| 				std::string loopInd = itrCluster->first; | ||||
| 				if (itrCluster->second.size() < threshold_depth) { | ||||
| 					if (debug) { | ||||
| 						log("  Skipping loop id %s as it contains only %ld cells\n", loopInd.c_str(), itrCluster->second.size()); | ||||
| 						log_flush(); | ||||
| 					} | ||||
| 					continue; | ||||
| 				} | ||||
| 				if (debug) { | ||||
| 					log("  Analyzing loop id %s containing %ld cells\n", loopInd.c_str(), itrCluster->second.size()); | ||||
| 					log_flush(); | ||||
| 				} | ||||
| 				// For a given for-loop cell group, perform topological sorting to get the logic depth of the ending cell in
 | ||||
| 				// the group
 | ||||
| 				TopoSort<RTLIL::Cell *, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> toposort; | ||||
| 				toposorting(itrCluster->second, sigmap, toposort, debug); | ||||
| 				std::vector<Cell *>::reverse_iterator itrLastCell = toposort.sorted.rbegin(); | ||||
| 				int logicdepth = toposort.node_to_index.find((*itrLastCell))->second; | ||||
| 				if (debug) { | ||||
| 					log("  Logic depth: %d\n", logicdepth); | ||||
| 					log_flush(); | ||||
| 				} | ||||
| 				if (logicdepth > (int)threshold_depth) { | ||||
| 					log("  Selecting %ld cells in for-loop id %s of depth %d ending with cell %s\n", itrCluster->second.size(), | ||||
| 					    loopInd.c_str(), logicdepth, log_id((*itrLastCell))); | ||||
| 					log_flush(); | ||||
| 					std::string src_info = (*itrLastCell)->get_src_attribute(); | ||||
| 					if (!(*itrLastCell)->get_string_attribute("\\in_for_loop").empty()) { | ||||
| 						src_info = (*itrLastCell)->get_string_attribute("\\in_for_loop"); | ||||
| 					} | ||||
| 					// Select all cells in the loop cluster
 | ||||
| 					if (!abc_script.empty()) { | ||||
| 						Pass::call(design, "select -none"); | ||||
| 					} | ||||
| 					for (auto cell : itrCluster->second) { | ||||
| 						design->select(module, cell); | ||||
| 						if (cell->get_string_attribute("\\in_for_loop").empty()) { | ||||
| 							cell->set_string_attribute("\\in_for_loop", src_info); | ||||
| 						} else { | ||||
| 							src_info = cell->get_string_attribute("\\in_for_loop"); | ||||
| 						} | ||||
| 					} | ||||
| 					if (!abc_script.empty()) { | ||||
| 						if (abc_script.find("map") == std::string::npos) { | ||||
| 							abc_script.erase(std::remove(abc_script.begin(), abc_script.end(), '"'), abc_script.end()); | ||||
| 							std::string command =  "abc -map_src " + src_info + " " + abc_script; | ||||
| 							log("  Executing: %s\n", command.c_str()); | ||||
| 							log_flush(); | ||||
| 							Pass::call(design, command); | ||||
| 						} else { | ||||
| 							std::string command = "abc -map_src " + src_info+ src_info + " -script " + abc_script; | ||||
| 							log("  Executing: %s\n", command.c_str()); | ||||
| 							log_flush(); | ||||
|          	  	Pass::call(design, command); | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		log("End longloop_select pass\n"); | ||||
| 		log_flush(); | ||||
| 	} | ||||
| } LongLoopSelect; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
|  | @ -707,7 +707,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 		std::vector<std::string> &liberty_files, std::vector<std::string> &genlib_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, std::vector<std::string> &dont_use_cells) | ||||
| 		const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector<std::string> &dont_use_cells, const std::string& map_src) | ||||
| { | ||||
| 	module = current_module; | ||||
| 	map_autoidx = autoidx++; | ||||
|  | @ -1212,6 +1212,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				if (c->type == ID(NOT)) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_)); | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					for (auto name : {ID::A, ID::Y}) { | ||||
| 						RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); | ||||
| 						cell->setPort(name, module->wire(remapped_name)); | ||||
|  | @ -1221,6 +1223,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				} | ||||
| 				if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					for (auto name : {ID::A, ID::B, ID::Y}) { | ||||
| 						RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); | ||||
|  | @ -1231,6 +1235,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				} | ||||
| 				if (c->type.in(ID(MUX), ID(NMUX))) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					for (auto name : {ID::A, ID::B, ID::S, ID::Y}) { | ||||
| 						RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); | ||||
|  | @ -1241,6 +1247,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				} | ||||
| 				if (c->type == ID(MUX4)) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_)); | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T, ID::Y}) { | ||||
| 						RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); | ||||
|  | @ -1251,6 +1259,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				} | ||||
| 				if (c->type == ID(MUX8)) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_)); | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U, ID::Y}) { | ||||
| 						RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); | ||||
|  | @ -1261,6 +1271,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				} | ||||
| 				if (c->type == ID(MUX16)) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_)); | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K, | ||||
| 							ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V, ID::Y}) { | ||||
|  | @ -1272,6 +1284,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				} | ||||
| 				if (c->type.in(ID(AOI3), ID(OAI3))) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					for (auto name : {ID::A, ID::B, ID::C, ID::Y}) { | ||||
| 						RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); | ||||
|  | @ -1282,6 +1296,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 				} | ||||
| 				if (c->type.in(ID(AOI4), ID(OAI4))) { | ||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1)); | ||||
| 					if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 					for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::Y}) { | ||||
| 						RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name); | ||||
|  | @ -1388,6 +1404,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 			} | ||||
| 
 | ||||
| 			RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type); | ||||
| 			if (!map_src.empty()) | ||||
| 						 cell->attributes[ID::src] = map_src; | ||||
| 			if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx; | ||||
| 			cell->parameters = c->parameters; | ||||
| 			for (auto &conn : c->connections()) { | ||||
|  | @ -1667,7 +1685,7 @@ struct AbcPass : public Pass { | |||
| 		bool abc_dress = false; | ||||
| 		vector<int> lut_costs; | ||||
| 		markgroups = false; | ||||
| 
 | ||||
|     std::string map_src; | ||||
| 		map_mux4 = false; | ||||
| 		map_mux8 = false; | ||||
| 		map_mux16 = false; | ||||
|  | @ -1775,6 +1793,10 @@ struct AbcPass : public Pass { | |||
| 				lut_arg = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-map_src" && argidx+1 < args.size()) { | ||||
| 				map_src = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-luts" && argidx+1 < args.size()) { | ||||
| 				luts_arg = args[++argidx]; | ||||
| 				continue; | ||||
|  | @ -2053,7 +2075,7 @@ struct AbcPass : public Pass { | |||
| 
 | ||||
| 			if (!dff_mode || !clk_str.empty()) { | ||||
| 				abc_module(design, mod, script_file, exe_file, liberty_files, genlib_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, dont_use_cells); | ||||
| 						delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress, dont_use_cells, map_src); | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
|  | @ -2215,7 +2237,7 @@ struct AbcPass : public Pass { | |||
| 				srst_polarity = std::get<6>(it.first); | ||||
| 				srst_sig = assign_map(std::get<7>(it.first)); | ||||
| 				abc_module(design, mod, script_file, exe_file, liberty_files, genlib_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, dont_use_cells); | ||||
| 						keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress, dont_use_cells, map_src); | ||||
| 				assign_map.set(mod); | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
|  | @ -110,6 +110,8 @@ struct AigmapPass : public Pass { | |||
| 						if (nand_mode && node.inverter) { | ||||
| 							bit = module->addWire(NEW_ID2_SUFFIX("bit")); | ||||
| 							auto gate = module->addNandGate(NEW_ID2_SUFFIX("nand"), A, B, bit); | ||||
| 							for (auto attr : cell->attributes) | ||||
| 								gate->attributes[attr.first] = attr.second;  | ||||
| 							if (select_mode) | ||||
| 								new_sel.insert(gate->name); | ||||
| 
 | ||||
|  | @ -121,6 +123,8 @@ struct AigmapPass : public Pass { | |||
| 							else { | ||||
| 								bit = module->addWire(NEW_ID2_SUFFIX("bit")); | ||||
| 								auto gate = module->addAndGate(NEW_ID2_SUFFIX("and"), A, B, bit); | ||||
| 								for (auto attr : cell->attributes) | ||||
| 									gate->attributes[attr.first] = attr.second;  | ||||
| 								if (select_mode) | ||||
| 									new_sel.insert(gate->name); | ||||
| 							} | ||||
|  | @ -130,6 +134,8 @@ struct AigmapPass : public Pass { | |||
| 					if (node.inverter) { | ||||
| 						SigBit new_bit = module->addWire(NEW_ID2_SUFFIX("new_bit")); | ||||
| 						auto gate = module->addNotGate(NEW_ID2_SUFFIX("inv"), bit, new_bit); | ||||
| 						for (auto attr : cell->attributes) | ||||
| 								gate->attributes[attr.first] = attr.second;  | ||||
| 						bit = new_bit; | ||||
| 						if (select_mode) | ||||
| 							new_sel.insert(gate->name); | ||||
|  |  | |||
|  | @ -368,8 +368,9 @@ struct AlumaccWorker | |||
| 
 | ||||
| 			log("  creating $macc cell for %s: %s\n", log_id(n->cell), log_id(cell)); | ||||
| 
 | ||||
| 			cell->set_src_attribute(n->cell->get_src_attribute()); | ||||
| 
 | ||||
| 			for (auto attr: n->cell->attributes) { | ||||
| 				cell->attributes[attr.first] = attr.second; | ||||
| 			} | ||||
| 			n->macc.optimize(GetSize(n->y)); | ||||
| 			n->macc.to_cell(cell); | ||||
| 			cell->setPort(ID::Y, n->y); | ||||
|  | @ -473,6 +474,10 @@ struct AlumaccWorker | |||
| 			if (GetSize(n->b) == 0 && GetSize(n->c) == 0 && GetSize(n->cmp) == 0) | ||||
| 			{ | ||||
| 				n->alu_cell = module->addPos(NEW_ID, n->a, n->y, n->is_signed); | ||||
| 				if (n->cells.size() > 0) { | ||||
| 					for (auto attr : n->cells[0]->attributes) | ||||
| 						n->alu_cell->attributes[attr.first] = attr.second;  | ||||
| 				} | ||||
| 
 | ||||
| 				log("  creating $pos cell for "); | ||||
| 				for (int i = 0; i < GetSize(n->cells); i++) | ||||
|  | @ -490,8 +495,10 @@ struct AlumaccWorker | |||
| 				log("%s%s", i ? ", ": "", log_id(n->cells[i])); | ||||
| 			log(": %s\n", log_id(n->alu_cell)); | ||||
| 
 | ||||
| 			if (n->cells.size() > 0) | ||||
| 				n->alu_cell->set_src_attribute(n->cells[0]->get_src_attribute()); | ||||
| 			if (n->cells.size() > 0) { | ||||
| 				for (auto attr : n->cells[0]->attributes) | ||||
| 					n->alu_cell->attributes[attr.first] = attr.second;  | ||||
| 			} | ||||
| 
 | ||||
| 			n->alu_cell->setPort(ID::A, n->a); | ||||
| 			n->alu_cell->setPort(ID::B, n->b); | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_NOT_)); // SILIMATE: Improve the naming
 | ||||
| 		gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 		gate->attributes = cell->attributes; | ||||
| 		gate->setPort(ID::A, sig_a[i]); | ||||
| 		gate->setPort(ID::Y, sig_y[i]); | ||||
| 	} | ||||
|  | @ -73,7 +73,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID2, gate_type); // SILIMATE: Improve the naming
 | ||||
| 		gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 		gate->attributes = cell->attributes; | ||||
| 		gate->setPort(ID::A, sig_a[i]); | ||||
| 		gate->setPort(ID::B, sig_b[i]); | ||||
| 		gate->setPort(ID::Y, sig_y[i]); | ||||
|  | @ -124,7 +124,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 			} | ||||
| 
 | ||||
| 			RTLIL::Cell *gate = module->addCell(NEW_ID2, gate_type); // SILIMATE: Improve the naming
 | ||||
| 			gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 			gate->attributes = cell->attributes; | ||||
| 			gate->setPort(ID::A, sig_a[i]); | ||||
| 			gate->setPort(ID::B, sig_a[i+1]); | ||||
| 			gate->setPort(ID::Y, sig_t[i/2]); | ||||
|  | @ -137,7 +137,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 	if (cell->type == ID($reduce_xnor)) { | ||||
| 		RTLIL::SigSpec sig_t = module->addWire(NEW_ID2_SUFFIX("sig_t")); // SILIMATE: Improve the naming
 | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_NOT_)); // SILIMATE: Improve the naming
 | ||||
| 		gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 		gate->attributes = cell->attributes; | ||||
| 		gate->setPort(ID::A, sig_a); | ||||
| 		gate->setPort(ID::Y, sig_t); | ||||
| 		last_output_cell = gate; | ||||
|  | @ -165,7 +165,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell | |||
| 			} | ||||
| 
 | ||||
| 			RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_OR_)); // SILIMATE: Improve the naming
 | ||||
| 			gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 			gate->attributes = cell->attributes; | ||||
| 			gate->setPort(ID::A, sig[i]); | ||||
| 			gate->setPort(ID::B, sig[i+1]); | ||||
| 			gate->setPort(ID::Y, sig_t[i/2]); | ||||
|  | @ -194,7 +194,7 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 	} | ||||
| 
 | ||||
| 	RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_NOT_)); // SILIMATE: Improve the naming
 | ||||
| 	gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 	gate->attributes = cell->attributes; | ||||
| 	gate->setPort(ID::A, sig_a); | ||||
| 	gate->setPort(ID::Y, sig_y); | ||||
| } | ||||
|  | @ -223,7 +223,7 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 	log_assert(!gate_type.empty()); | ||||
| 
 | ||||
| 	RTLIL::Cell *gate = module->addCell(NEW_ID2, gate_type); // SILIMATE: Improve the naming
 | ||||
| 	gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 	gate->attributes = cell->attributes; | ||||
| 	gate->setPort(ID::A, sig_a); | ||||
| 	gate->setPort(ID::B, sig_b); | ||||
| 	gate->setPort(ID::Y, sig_y); | ||||
|  | @ -239,19 +239,19 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	RTLIL::SigSpec xor_out = module->addWire(NEW_ID2_SUFFIX("xor_out"), max(GetSize(sig_a), GetSize(sig_b))); // SILIMATE: Improve the naming
 | ||||
| 	RTLIL::Cell *xor_cell = module->addXor(NEW_ID2, sig_a, sig_b, xor_out, is_signed, cell->get_src_attribute()); // SILIMATE: Improve the naming
 | ||||
| 	xor_cell->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 	xor_cell->attributes = cell->attributes; | ||||
| 	simplemap_bitop(module, xor_cell); | ||||
| 	module->remove(xor_cell); | ||||
| 
 | ||||
| 	RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID2_SUFFIX("reduce_out")); // SILIMATE: Improve the naming
 | ||||
| 	RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), xor_out, reduce_out, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
 | ||||
| 	reduce_cell->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 	reduce_cell->attributes = cell->attributes; | ||||
| 	simplemap_reduce(module, reduce_cell); | ||||
| 	module->remove(reduce_cell); | ||||
| 
 | ||||
| 	if (!is_ne) { | ||||
| 		RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID2_SUFFIX("not"), reduce_out, sig_y, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
 | ||||
| 		not_cell->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 		not_cell->attributes = cell->attributes; | ||||
|                 simplemap_lognot(module, not_cell); | ||||
| 		module->remove(not_cell); | ||||
| 	} | ||||
|  | @ -265,7 +265,7 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming
 | ||||
| 		gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 		gate->attributes = cell->attributes; | ||||
| 		gate->setPort(ID::A, sig_a[i]); | ||||
| 		gate->setPort(ID::B, sig_b[i]); | ||||
| 		gate->setPort(ID::S, cell->getPort(ID::S)); | ||||
|  | @ -282,7 +282,7 @@ void simplemap_bwmux(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming
 | ||||
| 		gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 		gate->attributes = cell->attributes; | ||||
| 		gate->setPort(ID::A, sig_a[i]); | ||||
| 		gate->setPort(ID::B, sig_b[i]); | ||||
| 		gate->setPort(ID::S, sig_s[i]); | ||||
|  | @ -298,7 +298,7 @@ void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 
 | ||||
| 	for (int i = 0; i < GetSize(sig_y); i++) { | ||||
| 		RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_TBUF_)); // SILIMATE: Improve the naming
 | ||||
| 		gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 		gate->attributes = cell->attributes; | ||||
| 		gate->setPort(ID::A, sig_a[i]); | ||||
| 		gate->setPort(ID::E, sig_e); | ||||
| 		gate->setPort(ID::Y, sig_y[i]); | ||||
|  | @ -316,7 +316,7 @@ void simplemap_bmux(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 		for (int i = 0; i < GetSize(new_data); i += width) { | ||||
| 			for (int k = 0; k < width; k++) { | ||||
| 				RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming
 | ||||
| 				gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 				gate->attributes = cell->attributes; | ||||
| 				gate->setPort(ID::A, data[i*2+k]); | ||||
| 				gate->setPort(ID::B, data[i*2+width+k]); | ||||
| 				gate->setPort(ID::S, sel[idx]); | ||||
|  | @ -339,7 +339,7 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 		SigSpec new_lut_data = module->addWire(NEW_ID2_SUFFIX("data"), GetSize(lut_data)/2); // SILIMATE: Improve the naming
 | ||||
| 		for (int i = 0; i < GetSize(lut_data); i += 2) { | ||||
| 			RTLIL::Cell *gate = module->addCell(NEW_ID2, ID($_MUX_)); // SILIMATE: Improve the naming
 | ||||
| 			gate->attributes[ID::src] = cell->attributes[ID::src]; | ||||
| 			gate->attributes = cell->attributes; | ||||
| 			gate->setPort(ID::A, lut_data[i]); | ||||
| 			gate->setPort(ID::B, lut_data[i+1]); | ||||
| 			gate->setPort(ID::S, lut_ctrl[idx]); | ||||
|  | @ -374,11 +374,16 @@ void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) | |||
| 				pat.append(State::S1); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		products.append(GetSize(in) > 0 ? module->Eq(NEW_ID2_SUFFIX("eq"), in, pat, false, cell->get_src_attribute()) : State::S1); // SILIMATE: Improve the naming
 | ||||
| 		SigSpec eq_y = module->addWire(NEW_ID2_SUFFIX("eq_out"), max(GetSize(in), GetSize(pat))); // SILIMATE: Improve the naming
 | ||||
| 		Cell* eq = module->addEq(NEW_ID2_SUFFIX("eq"), in, pat, eq_y, false, cell->get_src_attribute()); | ||||
| 		eq->attributes = cell->attributes; | ||||
| 		products.append(GetSize(in) > 0 ? eq_y : State::S1); // SILIMATE: Improve the naming
 | ||||
| 	} | ||||
| 
 | ||||
| 	module->connect(cell->getPort(ID::Y), module->ReduceOr(NEW_ID2_SUFFIX("reduce_or"), products, false, cell->get_src_attribute())); // SILIMATE: Improve the naming
 | ||||
| 	SigSpec red_or_y = module->addWire(NEW_ID2_SUFFIX("red_or_out"), GetSize(products)); // SILIMATE: Improve the naming
 | ||||
| 	Cell* red_or = module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), products, red_or_y, false, cell->get_src_attribute()); | ||||
| 	red_or->attributes = cell->attributes; | ||||
| 	module->connect(cell->getPort(ID::Y), red_or_y); // SILIMATE: Improve the naming
 | ||||
| } | ||||
| 
 | ||||
| void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell) | ||||
|  |  | |||
|  | @ -165,6 +165,11 @@ struct TechmapWorker | |||
| 				break; | ||||
| 			} | ||||
| 
 | ||||
| 		for (auto tpl_cell : tpl->cells()) | ||||
| 			for (auto attr : cell->attributes) { | ||||
| 				tpl_cell->attributes[attr.first] = attr.second; | ||||
| 			} | ||||
| 
 | ||||
| 		dict<IdString, IdString> memory_renames; | ||||
| 
 | ||||
| 		for (auto &it : tpl->memories) { | ||||
|  | @ -388,6 +393,9 @@ struct TechmapWorker | |||
| 						c->attributes[attr.first] = attr.second; | ||||
| 				c->attributes.erase(ID::reprocess_after); | ||||
| 			} | ||||
| 			for (auto attr : tpl_cell->attributes) { | ||||
| 				c->attributes[attr.first] = attr.second; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto &it : tpl->connections()) { | ||||
|  | @ -527,9 +535,9 @@ struct TechmapWorker | |||
| 						{ | ||||
| 							extmapper_module = extmapper_design->addModule(m_name); | ||||
| 							RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell); | ||||
| 
 | ||||
| 							extmapper_cell->set_src_attribute(cell->get_src_attribute()); | ||||
| 
 | ||||
| 							for (auto attr : cell->attributes) { | ||||
| 								extmapper_cell->attributes[attr.first] = attr.second; | ||||
| 							} | ||||
| 							int port_counter = 1; | ||||
| 							for (auto &c : extmapper_cell->connections_) { | ||||
| 								RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue