mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	Added "equiv_simple -undef"
This commit is contained in:
		
							parent
							
								
									f80f5b721d
								
							
						
					
					
						commit
						e9cfc4a453
					
				
					 2 changed files with 61 additions and 17 deletions
				
			
		| 
						 | 
					@ -103,6 +103,20 @@ struct SatGen
 | 
				
			||||||
		return importSigSpecWorker(bit, pf, false, false).front();
 | 
							return importSigSpecWorker(bit, pf, false, false).front();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int importDefSigBit(RTLIL::SigBit bit, int timestep = -1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							log_assert(timestep != 0);
 | 
				
			||||||
 | 
							std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
 | 
				
			||||||
 | 
							return importSigSpecWorker(bit, pf, false, true).front();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int importUndefSigBit(RTLIL::SigBit bit, int timestep = -1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							log_assert(timestep != 0);
 | 
				
			||||||
 | 
							std::string pf = "undef:" + prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
 | 
				
			||||||
 | 
							return importSigSpecWorker(bit, pf, true, false).front();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool importedSigBit(RTLIL::SigBit bit, int timestep = -1)
 | 
						bool importedSigBit(RTLIL::SigBit bit, int timestep = -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		log_assert(timestep != 0);
 | 
							log_assert(timestep != 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,21 +36,22 @@ struct EquivSimpleWorker
 | 
				
			||||||
	int max_seq;
 | 
						int max_seq;
 | 
				
			||||||
	bool verbose;
 | 
						bool verbose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EquivSimpleWorker(Cell *equiv_cell, SigMap &sigmap, dict<SigBit, Cell*> &bit2driver, int max_seq, bool verbose) :
 | 
						EquivSimpleWorker(Cell *equiv_cell, SigMap &sigmap, dict<SigBit, Cell*> &bit2driver, int max_seq, bool verbose, bool model_undef) :
 | 
				
			||||||
			module(equiv_cell->module), equiv_cell(equiv_cell), sigmap(sigmap),
 | 
								module(equiv_cell->module), equiv_cell(equiv_cell), sigmap(sigmap),
 | 
				
			||||||
			bit2driver(bit2driver), satgen(&ez, &sigmap), max_seq(max_seq), verbose(verbose)
 | 
								bit2driver(bit2driver), satgen(&ez, &sigmap), max_seq(max_seq), verbose(verbose)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							satgen.model_undef = model_undef;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void find_input_cone(pool<SigBit> &next_seed, pool<Cell*> &cells_cone, pool<SigBit> &bits_cone, const pool<Cell*> &cells_stop, const pool<SigBit> &bits_stop, Cell *cell)
 | 
						bool find_input_cone(pool<SigBit> &next_seed, pool<Cell*> &cells_cone, pool<SigBit> &bits_cone, const pool<Cell*> &cells_stop, const pool<SigBit> &bits_stop, pool<SigBit> *input_bits, Cell *cell)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (cells_cone.count(cell))
 | 
							if (cells_cone.count(cell))
 | 
				
			||||||
			return;
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cells_cone.insert(cell);
 | 
							cells_cone.insert(cell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (cells_stop.count(cell))
 | 
							if (cells_stop.count(cell))
 | 
				
			||||||
			return;
 | 
								return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (auto &conn : cell->connections())
 | 
							for (auto &conn : cell->connections())
 | 
				
			||||||
			if (yosys_celltypes.cell_input(cell->type, conn.first))
 | 
								if (yosys_celltypes.cell_input(cell->type, conn.first))
 | 
				
			||||||
| 
						 | 
					@ -59,24 +60,28 @@ struct EquivSimpleWorker
 | 
				
			||||||
						if (!conn.first.in("\\CLK", "\\C"))
 | 
											if (!conn.first.in("\\CLK", "\\C"))
 | 
				
			||||||
							next_seed.insert(bit);
 | 
												next_seed.insert(bit);
 | 
				
			||||||
					} else
 | 
										} else
 | 
				
			||||||
						find_input_cone(next_seed, cells_cone, bits_cone, cells_stop, bits_stop, bit);
 | 
											find_input_cone(next_seed, cells_cone, bits_cone, cells_stop, bits_stop, input_bits, bit);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void find_input_cone(pool<SigBit> &next_seed, pool<Cell*> &cells_cone, pool<SigBit> &bits_cone, const pool<Cell*> &cells_stop, const pool<SigBit> &bits_stop, SigBit bit)
 | 
						void find_input_cone(pool<SigBit> &next_seed, pool<Cell*> &cells_cone, pool<SigBit> &bits_cone, const pool<Cell*> &cells_stop, const pool<SigBit> &bits_stop, pool<SigBit> *input_bits, SigBit bit)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (bits_cone.count(bit))
 | 
							if (bits_cone.count(bit))
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bits_cone.insert(bit);
 | 
							bits_cone.insert(bit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (bits_stop.count(bit))
 | 
							if (bits_stop.count(bit)) {
 | 
				
			||||||
 | 
								if (input_bits != nullptr) input_bits->insert(bit);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!bit2driver.count(bit))
 | 
							if (!bit2driver.count(bit))
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		find_input_cone(next_seed, cells_cone, bits_cone, cells_stop, bits_stop, bit2driver.at(bit));
 | 
							if (find_input_cone(next_seed, cells_cone, bits_cone, cells_stop, bits_stop, input_bits, bit2driver.at(bit)))
 | 
				
			||||||
 | 
								if (input_bits != nullptr) input_bits->insert(bit);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool run()
 | 
						bool run()
 | 
				
			||||||
| 
						 | 
					@ -84,9 +89,21 @@ struct EquivSimpleWorker
 | 
				
			||||||
		SigBit bit_a = sigmap(equiv_cell->getPort("\\A")).to_single_sigbit();
 | 
							SigBit bit_a = sigmap(equiv_cell->getPort("\\A")).to_single_sigbit();
 | 
				
			||||||
		SigBit bit_b = sigmap(equiv_cell->getPort("\\B")).to_single_sigbit();
 | 
							SigBit bit_b = sigmap(equiv_cell->getPort("\\B")).to_single_sigbit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (satgen.model_undef)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								int ez_a = satgen.importSigBit(bit_a, max_seq+1);
 | 
				
			||||||
 | 
								int ez_b = satgen.importDefSigBit(bit_b, max_seq+1);
 | 
				
			||||||
 | 
								int ez_undef_a = satgen.importUndefSigBit(bit_a, max_seq+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ez.assume(ez.XOR(ez_a, ez_b));
 | 
				
			||||||
 | 
								ez.assume(ez.NOT(ez_undef_a));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			int ez_a = satgen.importSigBit(bit_a, max_seq+1);
 | 
								int ez_a = satgen.importSigBit(bit_a, max_seq+1);
 | 
				
			||||||
			int ez_b = satgen.importSigBit(bit_b, max_seq+1);
 | 
								int ez_b = satgen.importSigBit(bit_b, max_seq+1);
 | 
				
			||||||
			ez.assume(ez.XOR(ez_a, ez_b));
 | 
								ez.assume(ez.XOR(ez_a, ez_b));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pool<SigBit> seed_a = { bit_a };
 | 
							pool<SigBit> seed_a = { bit_a };
 | 
				
			||||||
		pool<SigBit> seed_b = { bit_b };
 | 
							pool<SigBit> seed_b = { bit_b };
 | 
				
			||||||
| 
						 | 
					@ -110,22 +127,23 @@ struct EquivSimpleWorker
 | 
				
			||||||
			pool<SigBit> next_seed_a, next_seed_b;
 | 
								pool<SigBit> next_seed_a, next_seed_b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (auto bit_a : seed_a)
 | 
								for (auto bit_a : seed_a)
 | 
				
			||||||
				find_input_cone(next_seed_a, full_cells_cone_a, full_bits_cone_a, no_stop_cells, no_stop_bits, bit_a);
 | 
									find_input_cone(next_seed_a, full_cells_cone_a, full_bits_cone_a, no_stop_cells, no_stop_bits, nullptr, bit_a);
 | 
				
			||||||
			next_seed_a.clear();
 | 
								next_seed_a.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (auto bit_b : seed_b)
 | 
								for (auto bit_b : seed_b)
 | 
				
			||||||
				find_input_cone(next_seed_b, full_cells_cone_b, full_bits_cone_b, no_stop_cells, no_stop_bits, bit_b);
 | 
									find_input_cone(next_seed_b, full_cells_cone_b, full_bits_cone_b, no_stop_cells, no_stop_bits, nullptr, bit_b);
 | 
				
			||||||
			next_seed_b.clear();
 | 
								next_seed_b.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pool<Cell*> short_cells_cone_a, short_cells_cone_b;
 | 
								pool<Cell*> short_cells_cone_a, short_cells_cone_b;
 | 
				
			||||||
			pool<SigBit> short_bits_cone_a, short_bits_cone_b;
 | 
								pool<SigBit> short_bits_cone_a, short_bits_cone_b;
 | 
				
			||||||
 | 
								pool<SigBit> input_bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (auto bit_a : seed_a)
 | 
								for (auto bit_a : seed_a)
 | 
				
			||||||
				find_input_cone(next_seed_a, short_cells_cone_a, short_bits_cone_a, full_cells_cone_b, full_bits_cone_b, bit_a);
 | 
									find_input_cone(next_seed_a, short_cells_cone_a, short_bits_cone_a, full_cells_cone_b, full_bits_cone_b, &input_bits, bit_a);
 | 
				
			||||||
			next_seed_a.swap(seed_a);
 | 
								next_seed_a.swap(seed_a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (auto bit_b : seed_b)
 | 
								for (auto bit_b : seed_b)
 | 
				
			||||||
				find_input_cone(next_seed_b, short_cells_cone_b, short_bits_cone_b, full_cells_cone_a, full_bits_cone_a, bit_b);
 | 
									find_input_cone(next_seed_b, short_cells_cone_b, short_bits_cone_b, full_cells_cone_a, full_bits_cone_a, &input_bits, bit_b);
 | 
				
			||||||
			next_seed_b.swap(seed_b);
 | 
								next_seed_b.swap(seed_b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pool<Cell*> problem_cells;
 | 
								pool<Cell*> problem_cells;
 | 
				
			||||||
| 
						 | 
					@ -141,6 +159,11 @@ struct EquivSimpleWorker
 | 
				
			||||||
				if (!satgen.importCell(cell, step+1))
 | 
									if (!satgen.importCell(cell, step+1))
 | 
				
			||||||
					log_cmd_error("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type));
 | 
										log_cmd_error("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (satgen.model_undef) {
 | 
				
			||||||
 | 
									for (auto bit : input_bits)
 | 
				
			||||||
 | 
										ez.assume(ez.NOT(satgen.importUndefSigBit(bit, step+1)));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (verbose)
 | 
								if (verbose)
 | 
				
			||||||
				log("    Problem size at t=%d: %d literals, %d clauses\n", step, ez.numCnfVariables(), ez.numCnfClauses());
 | 
									log("    Problem size at t=%d: %d literals, %d clauses\n", step, ez.numCnfVariables(), ez.numCnfClauses());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,13 +232,16 @@ struct EquivSimplePass : public Pass {
 | 
				
			||||||
		log("    -v\n");
 | 
							log("    -v\n");
 | 
				
			||||||
		log("        verbose output\n");
 | 
							log("        verbose output\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
 | 
							log("    -undef\n");
 | 
				
			||||||
 | 
							log("        enable modelling of undef states\n");
 | 
				
			||||||
 | 
							log("\n");
 | 
				
			||||||
		log("    -seq <N>\n");
 | 
							log("    -seq <N>\n");
 | 
				
			||||||
		log("        the max. number of time steps to be considered (default = 1)\n");
 | 
							log("        the max. number of time steps to be considered (default = 1)\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	virtual void execute(std::vector<std::string> args, Design *design)
 | 
						virtual void execute(std::vector<std::string> args, Design *design)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		bool verbose = false;
 | 
							bool verbose = false, model_undef = false;
 | 
				
			||||||
		int success_counter = 0;
 | 
							int success_counter = 0;
 | 
				
			||||||
		int max_seq = 1;
 | 
							int max_seq = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -227,6 +253,10 @@ struct EquivSimplePass : public Pass {
 | 
				
			||||||
				verbose = true;
 | 
									verbose = true;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if (args[argidx] == "-undef") {
 | 
				
			||||||
 | 
									model_undef = true;
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if (args[argidx] == "-seq" && argidx+1 < args.size()) {
 | 
								if (args[argidx] == "-seq" && argidx+1 < args.size()) {
 | 
				
			||||||
				max_seq = atoi(args[++argidx].c_str());
 | 
									max_seq = atoi(args[++argidx].c_str());
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					@ -266,7 +296,7 @@ struct EquivSimplePass : public Pass {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::sort(unproven_equiv_cells.begin(), unproven_equiv_cells.end());
 | 
								std::sort(unproven_equiv_cells.begin(), unproven_equiv_cells.end());
 | 
				
			||||||
			for (auto it : unproven_equiv_cells) {
 | 
								for (auto it : unproven_equiv_cells) {
 | 
				
			||||||
				EquivSimpleWorker worker(it.second, sigmap, bit2driver, max_seq, verbose);
 | 
									EquivSimpleWorker worker(it.second, sigmap, bit2driver, max_seq, verbose, model_undef);
 | 
				
			||||||
				if (worker.run())
 | 
									if (worker.run())
 | 
				
			||||||
					success_counter++;
 | 
										success_counter++;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue