mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Wider range of cell types supported in "share" pass
This commit is contained in:
		
							parent
							
								
									c54d1f2ad1
								
							
						
					
					
						commit
						3cb61d03f8
					
				
					 3 changed files with 249 additions and 36 deletions
				
			
		|  | @ -30,11 +30,14 @@ struct ShareWorkerConfig | ||||||
| 	bool opt_force; | 	bool opt_force; | ||||||
| 	bool opt_aggressive; | 	bool opt_aggressive; | ||||||
| 	bool opt_fast; | 	bool opt_fast; | ||||||
|  | 	std::set<std::string> generic_uni_ops, generic_bin_ops, generic_cbin_ops; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct ShareWorker | struct ShareWorker | ||||||
| { | { | ||||||
| 	ShareWorkerConfig config; | 	ShareWorkerConfig config; | ||||||
|  | 	std::set<std::string> generic_ops; | ||||||
|  | 
 | ||||||
| 	RTLIL::Design *design; | 	RTLIL::Design *design; | ||||||
| 	RTLIL::Module *module; | 	RTLIL::Module *module; | ||||||
| 
 | 
 | ||||||
|  | @ -125,19 +128,19 @@ struct ShareWorker | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { | 			if (cell->type == "$mul" || cell->type == "$div" || cell->type == "$mod") { | ||||||
| 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 4) | 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 4) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { | 			if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") { | ||||||
| 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 8) | 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 8) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$add" || cell->type == "$sub") { | 			if (generic_ops.count(cell->type)) { | ||||||
| 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() > 10) | 				if (config.opt_aggressive || cell->parameters.at("\\Y_WIDTH").as_int() >= 10) | ||||||
| 					shareable_cells.insert(cell); | 					shareable_cells.insert(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -157,15 +160,25 @@ struct ShareWorker | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || c1->type == "$add" || c1->type == "$sub" || | 		if (config.generic_uni_ops.count(c1->type)) | ||||||
| 				c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") |  | ||||||
| 		{ | 		{ | ||||||
| 			if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) | 			if (!config.opt_aggressive) | ||||||
| 				return false; | 			{ | ||||||
|  | 				int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); | ||||||
|  | 				int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); | ||||||
| 
 | 
 | ||||||
| 			if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) | 				int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); | ||||||
| 				return false; | 				int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); | ||||||
| 
 | 
 | ||||||
|  | 				if (std::max(a1_width, a2_width) > 2 * std::min(a1_width, a2_width)) return false; | ||||||
|  | 				if (std::max(y1_width, y2_width) > 2 * std::min(y1_width, y2_width)) return false; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (config.generic_bin_ops.count(c1->type)) | ||||||
|  | 		{ | ||||||
| 			if (!config.opt_aggressive) | 			if (!config.opt_aggressive) | ||||||
| 			{ | 			{ | ||||||
| 				int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); | 				int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); | ||||||
|  | @ -184,6 +197,32 @@ struct ShareWorker | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (config.generic_cbin_ops.count(c1->type)) | ||||||
|  | 		{ | ||||||
|  | 			if (!config.opt_aggressive) | ||||||
|  | 			{ | ||||||
|  | 				int a1_width = c1->parameters.at("\\A_WIDTH").as_int(); | ||||||
|  | 				int b1_width = c1->parameters.at("\\B_WIDTH").as_int(); | ||||||
|  | 				int y1_width = c1->parameters.at("\\Y_WIDTH").as_int(); | ||||||
|  | 
 | ||||||
|  | 				int a2_width = c2->parameters.at("\\A_WIDTH").as_int(); | ||||||
|  | 				int b2_width = c2->parameters.at("\\B_WIDTH").as_int(); | ||||||
|  | 				int y2_width = c2->parameters.at("\\Y_WIDTH").as_int(); | ||||||
|  | 
 | ||||||
|  | 				int min1_width = std::min(a1_width, b1_width); | ||||||
|  | 				int max1_width = std::max(a1_width, b1_width); | ||||||
|  | 
 | ||||||
|  | 				int min2_width = std::min(a2_width, b2_width); | ||||||
|  | 				int max2_width = std::max(a2_width, b2_width); | ||||||
|  | 
 | ||||||
|  | 				if (std::max(min1_width, min2_width) > 2 * std::min(min1_width, min2_width)) return false; | ||||||
|  | 				if (std::max(max1_width, max2_width) > 2 * std::min(max1_width, max2_width)) return false; | ||||||
|  | 				if (std::max(y1_width, y2_width) > 2 * std::min(y1_width, y2_width)) return false; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		for (auto &it : c1->parameters) | 		for (auto &it : c1->parameters) | ||||||
| 			if (c2->parameters.count(it.first) == 0 || c2->parameters.at(it.first) != it.second) | 			if (c2->parameters.count(it.first) == 0 || c2->parameters.at(it.first) != it.second) | ||||||
| 				return false; | 				return false; | ||||||
|  | @ -209,12 +248,108 @@ struct ShareWorker | ||||||
| 	// -----------------------
 | 	// -----------------------
 | ||||||
| 
 | 
 | ||||||
| 	RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act) | 	RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act) | ||||||
| 	{ |  | ||||||
| 		if (c1->type == "$mul" || c1->type == "$div" || c1->type == "$mod" || c1->type == "$add" || c1->type == "$sub" || |  | ||||||
| 				c1->type == "$shl" || c1->type == "$shr" || c1->type == "$sshl" || c1->type == "$sshr") |  | ||||||
| 	{ | 	{ | ||||||
| 		log_assert(c1->type == c2->type); | 		log_assert(c1->type == c2->type); | ||||||
| 
 | 
 | ||||||
|  | 		if (config.generic_uni_ops.count(c1->type)) | ||||||
|  | 		{ | ||||||
|  | 			if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) | ||||||
|  | 			{ | ||||||
|  | 				RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; | ||||||
|  | 				if (unsigned_cell->connections.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { | ||||||
|  | 					unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; | ||||||
|  | 					unsigned_cell->connections.at("\\A").append_bit(RTLIL::State::S0); | ||||||
|  | 				} | ||||||
|  | 				unsigned_cell->parameters.at("\\A_SIGNED") = true; | ||||||
|  | 				unsigned_cell->check(); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); | ||||||
|  | 			log_assert(a_signed == c2->parameters.at("\\A_SIGNED").as_bool()); | ||||||
|  | 
 | ||||||
|  | 			RTLIL::SigSpec a1 = c1->connections.at("\\A"); | ||||||
|  | 			RTLIL::SigSpec y1 = c1->connections.at("\\Y"); | ||||||
|  | 
 | ||||||
|  | 			RTLIL::SigSpec a2 = c2->connections.at("\\A"); | ||||||
|  | 			RTLIL::SigSpec y2 = c2->connections.at("\\Y"); | ||||||
|  | 
 | ||||||
|  | 			int a_width = std::max(a1.width, a2.width); | ||||||
|  | 			int y_width = std::max(y1.width, y2.width); | ||||||
|  | 
 | ||||||
|  | 			if (a1.width != a_width) a1 = module->addPos(NEW_ID, a1, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); | ||||||
|  | 			if (a2.width != a_width) a2 = module->addPos(NEW_ID, a2, module->new_wire(a_width, NEW_ID), a_signed)->connections.at("\\Y"); | ||||||
|  | 
 | ||||||
|  | 			RTLIL::SigSpec a = module->Mux(NEW_ID, a2, a1, act); | ||||||
|  | 			RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); | ||||||
|  | 
 | ||||||
|  | 			RTLIL::Cell *supercell = new RTLIL::Cell; | ||||||
|  | 			supercell->name = NEW_ID; | ||||||
|  | 			supercell->type = c1->type; | ||||||
|  | 			supercell->parameters["\\A_SIGNED"] = a_signed; | ||||||
|  | 			supercell->parameters["\\A_WIDTH"] = a_width; | ||||||
|  | 			supercell->parameters["\\Y_WIDTH"] = y_width; | ||||||
|  | 			supercell->connections["\\A"] = a; | ||||||
|  | 			supercell->connections["\\Y"] = y; | ||||||
|  | 			module->add(supercell); | ||||||
|  | 
 | ||||||
|  | 			RTLIL::SigSpec new_y1(y, y1.width); | ||||||
|  | 			RTLIL::SigSpec new_y2(y, y2.width); | ||||||
|  | 
 | ||||||
|  | 			module->connections.push_back(RTLIL::SigSig(y1, new_y1)); | ||||||
|  | 			module->connections.push_back(RTLIL::SigSig(y2, new_y2)); | ||||||
|  | 
 | ||||||
|  | 			return supercell; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type)) | ||||||
|  | 		{ | ||||||
|  | 			bool modified_src_cells = false; | ||||||
|  | 
 | ||||||
|  | 			if (config.generic_cbin_ops.count(c1->type)) | ||||||
|  | 			{ | ||||||
|  | 				int score_unflipped = std::max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()) + | ||||||
|  | 						std::max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()); | ||||||
|  | 
 | ||||||
|  | 				int score_flipped = std::max(c1->parameters.at("\\A_WIDTH").as_int(), c2->parameters.at("\\B_WIDTH").as_int()) + | ||||||
|  | 						std::max(c1->parameters.at("\\B_WIDTH").as_int(), c2->parameters.at("\\A_WIDTH").as_int()); | ||||||
|  | 
 | ||||||
|  | 				if (score_flipped < score_unflipped) | ||||||
|  | 				{ | ||||||
|  | 					std::swap(c2->connections.at("\\A"), c2->connections.at("\\B")); | ||||||
|  | 					std::swap(c2->parameters.at("\\A_WIDTH"), c2->parameters.at("\\B_WIDTH")); | ||||||
|  | 					std::swap(c2->parameters.at("\\A_SIGNED"), c2->parameters.at("\\B_SIGNED")); | ||||||
|  | 					modified_src_cells = true; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (c1->parameters.at("\\A_SIGNED").as_bool() != c2->parameters.at("\\A_SIGNED").as_bool()) | ||||||
|  | 
 | ||||||
|  | 			{ | ||||||
|  | 				RTLIL::Cell *unsigned_cell = c1->parameters.at("\\A_SIGNED").as_bool() ? c2 : c1; | ||||||
|  | 				if (unsigned_cell->connections.at("\\A").to_sigbit_vector().back() != RTLIL::State::S0) { | ||||||
|  | 					unsigned_cell->parameters.at("\\A_WIDTH") = unsigned_cell->parameters.at("\\A_WIDTH").as_int() + 1; | ||||||
|  | 					unsigned_cell->connections.at("\\A").append_bit(RTLIL::State::S0); | ||||||
|  | 				} | ||||||
|  | 				unsigned_cell->parameters.at("\\A_SIGNED") = true; | ||||||
|  | 				modified_src_cells = true; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (c1->parameters.at("\\B_SIGNED").as_bool() != c2->parameters.at("\\B_SIGNED").as_bool()) | ||||||
|  | 			{ | ||||||
|  | 				RTLIL::Cell *unsigned_cell = c1->parameters.at("\\B_SIGNED").as_bool() ? c2 : c1; | ||||||
|  | 				if (unsigned_cell->connections.at("\\B").to_sigbit_vector().back() != RTLIL::State::S0) { | ||||||
|  | 					unsigned_cell->parameters.at("\\B_WIDTH") = unsigned_cell->parameters.at("\\B_WIDTH").as_int() + 1; | ||||||
|  | 					unsigned_cell->connections.at("\\B").append_bit(RTLIL::State::S0); | ||||||
|  | 				} | ||||||
|  | 				unsigned_cell->parameters.at("\\B_SIGNED") = true; | ||||||
|  | 				modified_src_cells = true; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (modified_src_cells) { | ||||||
|  | 				c1->check(); | ||||||
|  | 				c2->check(); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); | 			bool a_signed = c1->parameters.at("\\A_SIGNED").as_bool(); | ||||||
| 			bool b_signed = c1->parameters.at("\\B_SIGNED").as_bool(); | 			bool b_signed = c1->parameters.at("\\B_SIGNED").as_bool(); | ||||||
| 
 | 
 | ||||||
|  | @ -259,9 +394,7 @@ struct ShareWorker | ||||||
| 			RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); | 			RTLIL::SigSpec b = module->Mux(NEW_ID, b2, b1, act); | ||||||
| 			RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); | 			RTLIL::Wire *y = module->new_wire(y_width, NEW_ID); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::Cell *supercell = new RTLIL::Cell; | 			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type); | ||||||
| 			supercell->name = NEW_ID; |  | ||||||
| 			supercell->type = c1->type; |  | ||||||
| 			supercell->parameters["\\A_SIGNED"] = a_signed; | 			supercell->parameters["\\A_SIGNED"] = a_signed; | ||||||
| 			supercell->parameters["\\B_SIGNED"] = b_signed; | 			supercell->parameters["\\B_SIGNED"] = b_signed; | ||||||
| 			supercell->parameters["\\A_WIDTH"] = a_width; | 			supercell->parameters["\\A_WIDTH"] = a_width; | ||||||
|  | @ -270,7 +403,7 @@ struct ShareWorker | ||||||
| 			supercell->connections["\\A"] = a; | 			supercell->connections["\\A"] = a; | ||||||
| 			supercell->connections["\\B"] = b; | 			supercell->connections["\\B"] = b; | ||||||
| 			supercell->connections["\\Y"] = y; | 			supercell->connections["\\Y"] = y; | ||||||
| 			module->add(supercell); | 			supercell->check(); | ||||||
| 
 | 
 | ||||||
| 			RTLIL::SigSpec new_y1(y, y1.width); | 			RTLIL::SigSpec new_y1(y, y1.width); | ||||||
| 			RTLIL::SigSpec new_y2(y, y2.width); | 			RTLIL::SigSpec new_y2(y, y2.width); | ||||||
|  | @ -502,6 +635,10 @@ struct ShareWorker | ||||||
| 	ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : | 	ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) : | ||||||
| 			config(config), design(design), module(module) | 			config(config), design(design), module(module) | ||||||
| 	{ | 	{ | ||||||
|  | 		generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end()); | ||||||
|  | 		generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end()); | ||||||
|  | 		generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end()); | ||||||
|  | 
 | ||||||
| 		fwd_ct.setup_internals(); | 		fwd_ct.setup_internals(); | ||||||
| 
 | 
 | ||||||
| 		cone_ct.setup_internals(); | 		cone_ct.setup_internals(); | ||||||
|  | @ -752,10 +889,53 @@ struct SharePass : public Pass { | ||||||
| 	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) | 	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) | ||||||
| 	{ | 	{ | ||||||
| 		ShareWorkerConfig config; | 		ShareWorkerConfig config; | ||||||
|  | 
 | ||||||
| 		config.opt_force = false; | 		config.opt_force = false; | ||||||
| 		config.opt_aggressive = false; | 		config.opt_aggressive = false; | ||||||
| 		config.opt_fast = false; | 		config.opt_fast = false; | ||||||
| 
 | 
 | ||||||
|  | 		config.generic_uni_ops.insert("$not"); | ||||||
|  | 		// config.generic_uni_ops.insert("$pos");
 | ||||||
|  | 		// config.generic_uni_ops.insert("$bu0");
 | ||||||
|  | 		config.generic_uni_ops.insert("$neg"); | ||||||
|  | 
 | ||||||
|  | 		config.generic_uni_ops.insert("$reduce_and"); | ||||||
|  | 		config.generic_uni_ops.insert("$reduce_or"); | ||||||
|  | 		config.generic_uni_ops.insert("$reduce_xor"); | ||||||
|  | 		config.generic_uni_ops.insert("$reduce_xnor"); | ||||||
|  | 		config.generic_uni_ops.insert("$reduce_bool"); | ||||||
|  | 
 | ||||||
|  | 		config.generic_cbin_ops.insert("$and"); | ||||||
|  | 		config.generic_cbin_ops.insert("$or"); | ||||||
|  | 		config.generic_cbin_ops.insert("$xor"); | ||||||
|  | 		config.generic_cbin_ops.insert("$xnor"); | ||||||
|  | 
 | ||||||
|  | 		config.generic_bin_ops.insert("$shl"); | ||||||
|  | 		config.generic_bin_ops.insert("$shr"); | ||||||
|  | 		config.generic_bin_ops.insert("$sshl"); | ||||||
|  | 		config.generic_bin_ops.insert("$sshr"); | ||||||
|  | 
 | ||||||
|  | 		config.generic_bin_ops.insert("$lt"); | ||||||
|  | 		config.generic_bin_ops.insert("$le"); | ||||||
|  | 		config.generic_bin_ops.insert("$eq"); | ||||||
|  | 		config.generic_bin_ops.insert("$ne"); | ||||||
|  | 		config.generic_bin_ops.insert("$eqx"); | ||||||
|  | 		config.generic_bin_ops.insert("$nex"); | ||||||
|  | 		config.generic_bin_ops.insert("$ge"); | ||||||
|  | 		config.generic_bin_ops.insert("$gt"); | ||||||
|  | 
 | ||||||
|  | 		config.generic_cbin_ops.insert("$add"); | ||||||
|  | 		config.generic_cbin_ops.insert("$mul"); | ||||||
|  | 
 | ||||||
|  | 		config.generic_bin_ops.insert("$sub"); | ||||||
|  | 		config.generic_bin_ops.insert("$div"); | ||||||
|  | 		config.generic_bin_ops.insert("$mod"); | ||||||
|  | 		// config.generic_bin_ops.insert("$pow");
 | ||||||
|  | 
 | ||||||
|  | 		config.generic_uni_ops.insert("$logic_not"); | ||||||
|  | 		config.generic_cbin_ops.insert("$logic_and"); | ||||||
|  | 		config.generic_cbin_ops.insert("$logic_or"); | ||||||
|  | 
 | ||||||
| 		log_header("Executing SHARE pass (SAT-based resource sharing).\n"); | 		log_header("Executing SHARE pass (SAT-based resource sharing).\n"); | ||||||
| 
 | 
 | ||||||
| 		size_t argidx; | 		size_t argidx; | ||||||
|  |  | ||||||
|  | @ -15,36 +15,58 @@ def redirect_stdout(new_target): | ||||||
|     finally: |     finally: | ||||||
|         sys.stdout = old_target |         sys.stdout = old_target | ||||||
| 
 | 
 | ||||||
| def maybe_plus_e(expr): | def random_plus_x(): | ||||||
|  |     return "%s x" % random.choice(['+', '+', '+', '-', '-', '|', '&', '^']) | ||||||
|  | 
 | ||||||
|  | def maybe_plus_x(expr): | ||||||
|     if random.randint(0, 4) == 0: |     if random.randint(0, 4) == 0: | ||||||
|         return "(%s + e)" % expr |         return "(%s %s)" % (expr, random_plus_x()) | ||||||
|     else: |     else: | ||||||
|         return expr |         return expr | ||||||
| 
 | 
 | ||||||
| for idx in range(100): | for idx in range(100): | ||||||
|     with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): |     with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): | ||||||
|         print('module uut_%05d(a, b, c, d, e, s, y);' % (idx)) |         if random.choice(['bin', 'uni']) == 'bin': | ||||||
|         ac_signed = random.choice(['', ' signed']) |             print('module uut_%05d(a, b, c, d, x, s, y);' % (idx)) | ||||||
|         bd_signed = random.choice(['', ' signed']) |             op = random.choice([ | ||||||
|         op = random.choice(['+', '-', '*', '/', '%', '<<', '>>', '<<<', '>>>']) |                 random.choice(['+', '-', '*', '/', '%']), | ||||||
|         print('  input%s [%d:0] a;' % (ac_signed, random.randint(0, 8))) |                 random.choice(['<', '<=', '==', '!=', '===', '!==', '>=', '>' ]), | ||||||
|         print('  input%s [%d:0] b;' % (bd_signed, random.randint(0, 8))) |                 random.choice(['<<', '>>', '<<<', '>>>']), | ||||||
|         print('  input%s [%d:0] c;' % (ac_signed, random.randint(0, 8))) |                 random.choice(['|', '&', '^', '~^', '||', '&&']), | ||||||
|         print('  input%s [%d:0] d;' % (bd_signed, random.randint(0, 8))) |             ]) | ||||||
|         print('  input signed [%d:0] e;' % random.randint(0, 8)) |             print('  input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|  |             print('  input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|  |             print('  input%s [%d:0] c;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|  |             print('  input%s [%d:0] d;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|  |             print('  input%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|             print('  input s;') |             print('  input s;') | ||||||
|             print('  output [%d:0] y;' % random.randint(0, 8)) |             print('  output [%d:0] y;' % random.randint(0, 8)) | ||||||
|             print('  assign y = (s ? %s(%s %s %s) : %s(%s %s %s))%s;' % |             print('  assign y = (s ? %s(%s %s %s) : %s(%s %s %s))%s;' % | ||||||
|                 (random.choice(['', '$signed', '$unsigned']), maybe_plus_e('a'), op, maybe_plus_e('b'), |                     (random.choice(['', '$signed', '$unsigned']), maybe_plus_x('a'), op, maybe_plus_x('b'), | ||||||
|                  random.choice(['', '$signed', '$unsigned']), maybe_plus_e('c'), op, maybe_plus_e('d'), |                      random.choice(['', '$signed', '$unsigned']), maybe_plus_x('c'), op, maybe_plus_x('d'), | ||||||
|                  ' + e' if random.randint(0, 4) == 0 else '')) |                      random_plus_x() if random.randint(0, 4) == 0 else '')) | ||||||
|  |             print('endmodule') | ||||||
|  |         else: | ||||||
|  |             print('module uut_%05d(a, b, x, s, y);' % (idx)) | ||||||
|  |             op = random.choice(['~', '-', '!']) | ||||||
|  |             print('  input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|  |             print('  input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|  |             print('  input%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 8))) | ||||||
|  |             print('  input s;') | ||||||
|  |             print('  output [%d:0] y;' % random.randint(0, 8)) | ||||||
|  |             print('  assign y = (s ? %s(%s%s) : %s(%s%s))%s;' % | ||||||
|  |                     (random.choice(['', '$signed', '$unsigned']), op, maybe_plus_x('a'), | ||||||
|  |                      random.choice(['', '$signed', '$unsigned']), op, maybe_plus_x('b'), | ||||||
|  |                      random_plus_x() if random.randint(0, 4) == 0 else '')) | ||||||
|             print('endmodule') |             print('endmodule') | ||||||
|     with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): |     with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): | ||||||
|         print('read_verilog temp/uut_%05d.v' % idx) |         print('read_verilog temp/uut_%05d.v' % idx) | ||||||
|         print('proc;;') |         print('proc;;') | ||||||
|         print('copy uut_%05d gold' % idx) |         print('copy uut_%05d gold' % idx) | ||||||
|         print('rename uut_%05d gate' % idx) |         print('rename uut_%05d gate' % idx) | ||||||
|         print('share -aggressive gate') |         print('tee -a temp/all_share_log.txt log') | ||||||
|  |         print('tee -a temp/all_share_log.txt log #job# uut_%05d' % idx) | ||||||
|  |         print('tee -a temp/all_share_log.txt share -aggressive gate') | ||||||
|         print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') |         print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter') | ||||||
|         print('sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter') |         print('sat -set-def-inputs -verify -prove trigger 0 -show-inputs -show-outputs miter') | ||||||
|   |   | ||||||
|  |  | ||||||
|  | @ -1,4 +1,8 @@ | ||||||
| #!/bin/bash | #!/bin/bash | ||||||
|  | 
 | ||||||
|  | # run this test many times: | ||||||
|  | # time bash -c 'for ((i=0; i<100; i++)); do echo "-- $i --"; bash run-test.sh || exit 1; done' | ||||||
|  | 
 | ||||||
| set -e | set -e | ||||||
| 
 | 
 | ||||||
| rm -rf temp | rm -rf temp | ||||||
|  | @ -14,3 +18,10 @@ for i in $( ls temp/*.ys | sed 's,[^0-9],,g; s,^0*\(.\),\1,g;' ); do | ||||||
| done | done | ||||||
| echo | echo | ||||||
| 
 | 
 | ||||||
|  | failed_share=$( echo $( gawk '/^#job#/ { j=$2; db[j]=0; } /^Removing [24] cells/ { delete db[j]; } END { for (j in db) print(j); }' temp/all_share_log.txt ) ) | ||||||
|  | if [ -n "$failed_share" ]; then | ||||||
|  | 	echo "Resource sharing failed for the following test cases: $failed_share" | ||||||
|  | 	false | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | exit 0 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue