mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Fix generation of vlogtb output in yosys-smtbmc for "rand reg" and "rand const reg"
This commit is contained in:
		
							parent
							
								
									129984e115
								
							
						
					
					
						commit
						8f8baccfde
					
				
					 5 changed files with 61 additions and 4 deletions
				
			
		|  | @ -458,8 +458,10 @@ struct Smt2Worker | ||||||
| 			if (cell->type.in("$anyconst", "$anyseq")) | 			if (cell->type.in("$anyconst", "$anyseq")) | ||||||
| 			{ | 			{ | ||||||
| 				registers.insert(cell); | 				registers.insert(cell); | ||||||
| 				decls.push_back(stringf("; yosys-smt2-%s %s#%d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, | 				string infostr = cell->attributes.count("\\src") ? cell->attributes.at("\\src").decode_string().c_str() : get_id(cell); | ||||||
| 						cell->attributes.count("\\src") ? cell->attributes.at("\\src").decode_string().c_str() : get_id(cell))); | 				if (cell->attributes.count("\\reg")) | ||||||
|  | 					infostr += " " + cell->attributes.at("\\reg").decode_string(); | ||||||
|  | 				decls.push_back(stringf("; yosys-smt2-%s %s#%d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, infostr.c_str())); | ||||||
| 				makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Y")), log_signal(cell->getPort("\\Y"))); | 				makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Y")), log_signal(cell->getPort("\\Y"))); | ||||||
| 				register_bv(cell->getPort("\\Y"), idcounter++); | 				register_bv(cell->getPort("\\Y"), idcounter++); | ||||||
| 				recursive_cells.erase(cell); | 				recursive_cells.erase(cell); | ||||||
|  |  | ||||||
|  | @ -709,6 +709,13 @@ def write_vlogtb_trace(steps_start, steps_stop, index): | ||||||
|                     hidden_net = True |                     hidden_net = True | ||||||
|             print("    %sUUT.%s = %d'b%s;" % ("// " if hidden_net else "", ".".join(reg), len(val), val), file=f) |             print("    %sUUT.%s = %d'b%s;" % ("// " if hidden_net else "", ".".join(reg), len(val), val), file=f) | ||||||
| 
 | 
 | ||||||
|  |         anyconsts = sorted(smt.hieranyconsts(topmod)) | ||||||
|  |         for info in anyconsts: | ||||||
|  |             if info[3] is not None: | ||||||
|  |                 modstate = smt.net_expr(topmod, "s%d" % steps_start, info[0]) | ||||||
|  |                 value = smt.bv2bin(smt.get("(|%s| %s)" % (info[1], modstate))) | ||||||
|  |                 print("    UUT.%s = %d'b%s;" % (".".join(info[0] + [info[3]]), len(value), value), file=f); | ||||||
|  | 
 | ||||||
|         mems = sorted(smt.hiermems(topmod)) |         mems = sorted(smt.hiermems(topmod)) | ||||||
|         for mempath in mems: |         for mempath in mems: | ||||||
|             abits, width, rports, wports = smt.mem_info(topmod, mempath) |             abits, width, rports, wports = smt.mem_info(topmod, mempath) | ||||||
|  | @ -733,6 +740,8 @@ def write_vlogtb_trace(steps_start, steps_stop, index): | ||||||
|             for addr, data in addr_data.items(): |             for addr, data in addr_data.items(): | ||||||
|                 print("    UUT.%s[%d'b%s] = %d'b%s;" % (".".join(mempath), len(addr), addr, len(data), data), file=f) |                 print("    UUT.%s[%d'b%s] = %d'b%s;" % (".".join(mempath), len(addr), addr, len(data), data), file=f) | ||||||
| 
 | 
 | ||||||
|  |         anyseqs = sorted(smt.hieranyseqs(topmod)) | ||||||
|  | 
 | ||||||
|         for i in range(steps_start, steps_stop): |         for i in range(steps_start, steps_stop): | ||||||
|             pi_names = [[name] for name, _ in primary_inputs if name not in clock_inputs] |             pi_names = [[name] for name, _ in primary_inputs if name not in clock_inputs] | ||||||
|             pi_values = smt.get_net_bin_list(topmod, pi_names, "s%d" % i) |             pi_values = smt.get_net_bin_list(topmod, pi_names, "s%d" % i) | ||||||
|  | @ -744,6 +753,12 @@ def write_vlogtb_trace(steps_start, steps_stop, index): | ||||||
|             for name, val in zip(pi_names, pi_values): |             for name, val in zip(pi_names, pi_values): | ||||||
|                 print("    PI_%s <= %d'b%s;" % (".".join(name), len(val), val), file=f) |                 print("    PI_%s <= %d'b%s;" % (".".join(name), len(val), val), file=f) | ||||||
| 
 | 
 | ||||||
|  |             for info in anyseqs: | ||||||
|  |                 if info[3] is not None: | ||||||
|  |                     modstate = smt.net_expr(topmod, "s%d" % steps_start, info[0]) | ||||||
|  |                     value = smt.bv2bin(smt.get("(|%s| %s)" % (info[1], modstate))) | ||||||
|  |                     print("    UUT.%s = %d'b%s;" % (".".join(info[0] + [info[3]]), len(value), value), file=f); | ||||||
|  | 
 | ||||||
|         print("    genclock = 0;", file=f) |         print("    genclock = 0;", file=f) | ||||||
|         print("  end", file=f) |         print("  end", file=f) | ||||||
| 
 | 
 | ||||||
|  | @ -859,7 +874,10 @@ def print_anyconsts_worker(mod, state, path): | ||||||
|         print_anyconsts_worker(celltype, "(|%s_h %s| %s)" % (mod, cellname, state), path + "." + cellname) |         print_anyconsts_worker(celltype, "(|%s_h %s| %s)" % (mod, cellname, state), path + "." + cellname) | ||||||
| 
 | 
 | ||||||
|     for fun, info in smt.modinfo[mod].anyconsts.items(): |     for fun, info in smt.modinfo[mod].anyconsts.items(): | ||||||
|         print_msg("Value for anyconst in %s (%s): %d" % (path, info, smt.bv2int(smt.get("(|%s| %s)" % (fun, state))))) |         if info[1] is None: | ||||||
|  |             print_msg("Value for anyconst in %s (%s): %d" % (path, info, smt.bv2int(smt.get("(|%s| %s)" % (fun, state))))) | ||||||
|  |         else: | ||||||
|  |             print_msg("Value for anyconst %s.%s (%s): %d" % (path, info[1], info[0], smt.bv2int(smt.get("(|%s| %s)" % (fun, state))))) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def print_anyconsts(state): | def print_anyconsts(state): | ||||||
|  |  | ||||||
|  | @ -44,6 +44,7 @@ class SmtModInfo: | ||||||
|         self.asserts = dict() |         self.asserts = dict() | ||||||
|         self.covers = dict() |         self.covers = dict() | ||||||
|         self.anyconsts = dict() |         self.anyconsts = dict() | ||||||
|  |         self.anyseqs = dict() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SmtIo: | class SmtIo: | ||||||
|  | @ -349,7 +350,10 @@ class SmtIo: | ||||||
|             self.modinfo[self.curmod].covers["%s_c %s" % (self.curmod, fields[2])] = fields[3] |             self.modinfo[self.curmod].covers["%s_c %s" % (self.curmod, fields[2])] = fields[3] | ||||||
| 
 | 
 | ||||||
|         if fields[1] == "yosys-smt2-anyconst": |         if fields[1] == "yosys-smt2-anyconst": | ||||||
|             self.modinfo[self.curmod].anyconsts[fields[2]] = fields[3] |             self.modinfo[self.curmod].anyconsts[fields[2]] = (fields[3], None if len(fields) <= 4 else fields[4]) | ||||||
|  | 
 | ||||||
|  |         if fields[1] == "yosys-smt2-anyseq": | ||||||
|  |             self.modinfo[self.curmod].anyseqs[fields[2]] = (fields[3], None if len(fields) <= 4 else fields[4]) | ||||||
| 
 | 
 | ||||||
|     def hiernets(self, top, regs_only=False): |     def hiernets(self, top, regs_only=False): | ||||||
|         def hiernets_worker(nets, mod, cursor): |         def hiernets_worker(nets, mod, cursor): | ||||||
|  | @ -363,6 +367,28 @@ class SmtIo: | ||||||
|         hiernets_worker(nets, top, []) |         hiernets_worker(nets, top, []) | ||||||
|         return nets |         return nets | ||||||
| 
 | 
 | ||||||
|  |     def hieranyconsts(self, top): | ||||||
|  |         def worker(results, mod, cursor): | ||||||
|  |             for name, value in sorted(self.modinfo[mod].anyconsts.items()): | ||||||
|  |                 results.append((cursor, name, value[0], value[1])) | ||||||
|  |             for cellname, celltype in sorted(self.modinfo[mod].cells.items()): | ||||||
|  |                 worker(results, celltype, cursor + [cellname]) | ||||||
|  | 
 | ||||||
|  |         results = list() | ||||||
|  |         worker(results, top, []) | ||||||
|  |         return results | ||||||
|  | 
 | ||||||
|  |     def hieranyseqs(self, top): | ||||||
|  |         def worker(results, mod, cursor): | ||||||
|  |             for name, value in sorted(self.modinfo[mod].anyseqs.items()): | ||||||
|  |                 results.append((cursor, name, value[0], value[1])) | ||||||
|  |             for cellname, celltype in sorted(self.modinfo[mod].cells.items()): | ||||||
|  |                 worker(results, celltype, cursor + [cellname]) | ||||||
|  | 
 | ||||||
|  |         results = list() | ||||||
|  |         worker(results, top, []) | ||||||
|  |         return results | ||||||
|  | 
 | ||||||
|     def hiermems(self, top): |     def hiermems(self, top): | ||||||
|         def hiermems_worker(mems, mod, cursor): |         def hiermems_worker(mems, mod, cursor): | ||||||
|             for memname in sorted(self.modinfo[mod].memories.keys()): |             for memname in sorted(self.modinfo[mod].memories.keys()): | ||||||
|  | @ -555,6 +581,9 @@ class SmtIo: | ||||||
|         return [".".join(path)] |         return [".".join(path)] | ||||||
| 
 | 
 | ||||||
|     def net_expr(self, mod, base, path): |     def net_expr(self, mod, base, path): | ||||||
|  |         if len(path) == 0: | ||||||
|  |             return base | ||||||
|  | 
 | ||||||
|         if len(path) == 1: |         if len(path) == 1: | ||||||
|             assert mod in self.modinfo |             assert mod in self.modinfo | ||||||
|             if path[0] == "": |             if path[0] == "": | ||||||
|  |  | ||||||
|  | @ -1497,6 +1497,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | ||||||
| 				cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); | 				cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); | ||||||
| 				cell->parameters["\\WIDTH"] = width; | 				cell->parameters["\\WIDTH"] = width; | ||||||
| 
 | 
 | ||||||
|  | 				if (attributes.count("\\reg")) { | ||||||
|  | 					auto &attr = attributes.at("\\reg"); | ||||||
|  | 					if (attr->type != AST_CONSTANT) | ||||||
|  | 						log_error("Attribute `reg' with non-constant value at %s:%d!\n", filename.c_str(), linenum); | ||||||
|  | 					cell->attributes["\\reg"] =  attr->asAttrConst(); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 				Wire *wire = current_module->addWire(myid + "_wire", width); | 				Wire *wire = current_module->addWire(myid + "_wire", width); | ||||||
| 				wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); | 				wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum); | ||||||
| 				cell->setPort("\\Y", wire); | 				cell->setPort("\\Y", wire); | ||||||
|  |  | ||||||
|  | @ -764,6 +764,7 @@ wire_name_and_opt_assign: | ||||||
| 			AstNode *fcall = new AstNode(AST_FCALL); | 			AstNode *fcall = new AstNode(AST_FCALL); | ||||||
| 			wire->str = ast_stack.back()->children.back()->str; | 			wire->str = ast_stack.back()->children.back()->str; | ||||||
| 			fcall->str = current_wire_const ? "\\$anyconst" : "\\$anyseq"; | 			fcall->str = current_wire_const ? "\\$anyconst" : "\\$anyseq"; | ||||||
|  | 			fcall->attributes["\\reg"] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str)); | ||||||
| 			ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, fcall)); | 			ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, fcall)); | ||||||
| 		} | 		} | ||||||
| 	} | | 	} | | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue