mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge pull request #3126 from georgerennie/equiv_make_assertions
equiv_make: Add -make_assert option
This commit is contained in:
		
						commit
						85f611fb23
					
				
					 2 changed files with 97 additions and 27 deletions
				
			
		|  | @ -33,6 +33,7 @@ struct EquivMakeWorker | |||
| 	bool inames; | ||||
| 	vector<string> blacklists; | ||||
| 	vector<string> encfiles; | ||||
| 	bool make_assert; | ||||
| 
 | ||||
| 	pool<IdString> blacklist_names; | ||||
| 	dict<IdString, dict<Const, Const>> encdata; | ||||
|  | @ -133,6 +134,12 @@ struct EquivMakeWorker | |||
| 		delete gate_clone; | ||||
| 	} | ||||
| 
 | ||||
| 	void add_eq_assertion(const SigSpec &gold_sig, const SigSpec &gate_sig) | ||||
| 	{ | ||||
| 		auto eq_wire = equiv_mod->Eqx(NEW_ID, gold_sig, gate_sig); | ||||
| 		equiv_mod->addAssert(NEW_ID_SUFFIX("assert"), eq_wire, State::S1); | ||||
| 	} | ||||
| 
 | ||||
| 	void find_same_wires() | ||||
| 	{ | ||||
| 		SigMap assign_map(equiv_mod); | ||||
|  | @ -231,15 +238,24 @@ struct EquivMakeWorker | |||
| 
 | ||||
| 			if (gold_wire->port_output || gate_wire->port_output) | ||||
| 			{ | ||||
| 				Wire *wire = equiv_mod->addWire(id, gold_wire->width); | ||||
| 				wire->port_output = true; | ||||
| 				gold_wire->port_input = false; | ||||
| 				gate_wire->port_input = false; | ||||
| 				gold_wire->port_output = false; | ||||
| 				gate_wire->port_output = false; | ||||
| 
 | ||||
| 				Wire *wire = equiv_mod->addWire(id, gold_wire->width); | ||||
| 				wire->port_output = true; | ||||
| 
 | ||||
| 				if (make_assert) | ||||
| 				{ | ||||
| 					add_eq_assertion(gold_wire, gate_wire); | ||||
| 					equiv_mod->connect(wire, gold_wire); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					for (int i = 0; i < wire->width; i++) | ||||
| 						equiv_mod->addEquiv(NEW_ID, SigSpec(gold_wire, i), SigSpec(gate_wire, i), SigSpec(wire, i)); | ||||
| 				} | ||||
| 
 | ||||
| 				rd_signal_map.add(assign_map(gold_wire), wire); | ||||
| 				rd_signal_map.add(assign_map(gate_wire), wire); | ||||
|  | @ -259,6 +275,10 @@ struct EquivMakeWorker | |||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (make_assert) | ||||
| 					add_eq_assertion(gold_wire, gate_wire); | ||||
| 
 | ||||
| 				else { | ||||
| 					Wire *wire = equiv_mod->addWire(id, gold_wire->width); | ||||
| 					SigSpec rdmap_gold, rdmap_gate, rdmap_equiv; | ||||
| 
 | ||||
|  | @ -281,6 +301,7 @@ struct EquivMakeWorker | |||
| 					rd_signal_map.add(rdmap_gate, rdmap_equiv); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto c : cells_list) | ||||
| 		for (auto &conn : c->connections()) | ||||
|  | @ -335,12 +356,20 @@ struct EquivMakeWorker | |||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				if (make_assert) | ||||
| 				{ | ||||
| 					if (gold_sig != gate_sig) | ||||
| 						add_eq_assertion(gold_sig, gate_sig); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					for (int i = 0; i < GetSize(gold_sig); i++) | ||||
| 						if (gold_sig[i] != gate_sig[i]) { | ||||
| 							Wire *w = equiv_mod->addWire(NEW_ID); | ||||
| 							equiv_mod->addEquiv(NEW_ID, gold_sig[i], gate_sig[i], w); | ||||
| 							gold_sig[i] = w; | ||||
| 						} | ||||
| 				} | ||||
| 
 | ||||
| 				gold_cell->setPort(gold_conn.first, gold_sig); | ||||
| 			} | ||||
|  | @ -417,6 +446,10 @@ struct EquivMakePass : public Pass { | |||
| 		log("        Match FSM encodings using the description from the file.\n"); | ||||
| 		log("        See 'help fsm_recode' for details.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -make_assert\n"); | ||||
| 		log("        Check equivalence with $assert cells instead of $equiv.\n"); | ||||
| 		log("        $eqx (===) is used to compare signals."); | ||||
| 		log("\n"); | ||||
| 		log("Note: The circuit created by this command is not a miter (with something like\n"); | ||||
| 		log("a trigger output), but instead uses $equiv cells to encode the equivalence\n"); | ||||
| 		log("checking problem. Use 'miter -equiv' if you want to create a miter circuit.\n"); | ||||
|  | @ -427,6 +460,7 @@ struct EquivMakePass : public Pass { | |||
| 		EquivMakeWorker worker; | ||||
| 		worker.ct.setup(design); | ||||
| 		worker.inames = false; | ||||
| 		worker.make_assert = false; | ||||
| 
 | ||||
| 		size_t argidx; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | ||||
|  | @ -443,6 +477,10 @@ struct EquivMakePass : public Pass { | |||
| 				worker.encfiles.push_back(args[++argidx]); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-make_assert") { | ||||
| 				worker.make_assert = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										32
									
								
								tests/various/equiv_make_make_assert.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								tests/various/equiv_make_make_assert.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| read_verilog <<EOT | ||||
| module gold( | ||||
| 	input wire [7:0] a, | ||||
| 	input wire [7:0] b, | ||||
| 	output wire [7:0] c | ||||
| ); | ||||
| 
 | ||||
| wire [7:0] b_neg; | ||||
| assign b_neg = -b; | ||||
| assign c = a + b_neg; | ||||
| endmodule | ||||
| 
 | ||||
| module gate( | ||||
| 	input wire [7:0] a, | ||||
| 	input wire [7:0] b, | ||||
| 	output wire [7:0] c | ||||
| ); | ||||
| 
 | ||||
| wire [7:0] b_neg; | ||||
| assign b_neg = ~b + 1; | ||||
| assign c = a + b_neg; | ||||
| endmodule | ||||
| 
 | ||||
| EOT | ||||
| 
 | ||||
| equiv_make -make_assert gold gate miter | ||||
| 
 | ||||
| select -assert-count 0 t:$equiv | ||||
| select -assert-count 2 t:$assert | ||||
| 
 | ||||
| prep -top miter | ||||
| sat -prove-asserts -verify | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue