mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Make a few passes auto-call Mem::narrow instead of rejecting wide ports.
This essentially adds wide port support for free in passes that don't have a usefully better way of handling wide ports than just breaking them up to narrow ports, avoiding "please run memory_narrow" annoyance.
This commit is contained in:
		
							parent
							
								
									055ba748bc
								
							
						
					
					
						commit
						cbf6b719fe
					
				
					 5 changed files with 10 additions and 33 deletions
				
			
		|  | @ -732,14 +732,6 @@ struct BtorWorker | |||
| 				if (port.clk_enable) | ||||
| 					log_error("Memory %s.%s has sync read ports.  Please use memory_nordff to convert them first.\n", | ||||
| 							log_id(module), log_id(mem->memid)); | ||||
| 				if (port.wide_log2) | ||||
| 					log_error("Memory %s.%s has wide read ports.  Please use memory_narrow to convert them first.\n", | ||||
| 							log_id(module), log_id(mem->memid)); | ||||
| 			} | ||||
| 			for (auto &port : mem->wr_ports) { | ||||
| 				if (port.wide_log2) | ||||
| 					log_error("Memory %s.%s has wide write ports.  Please use memory_narrow to convert them first.\n", | ||||
| 							log_id(module), log_id(mem->memid)); | ||||
| 			} | ||||
| 
 | ||||
| 			int data_sid = get_bv_sid(mem->width); | ||||
|  | @ -1089,8 +1081,10 @@ struct BtorWorker | |||
| 		memories = Mem::get_all_memories(module); | ||||
| 
 | ||||
| 		dict<IdString, Mem*> mem_dict; | ||||
| 		for (auto &mem : memories) | ||||
| 		for (auto &mem : memories) { | ||||
| 			mem.narrow(); | ||||
| 			mem_dict[mem.memid] = &mem; | ||||
| 		} | ||||
| 		for (auto cell : module->cells()) | ||||
| 			if (cell->is_mem_cell()) | ||||
| 				mem_cells[cell] = mem_dict[cell->parameters.at(ID::MEMID).decode_string()]; | ||||
|  |  | |||
|  | @ -542,6 +542,8 @@ struct FirrtlWorker | |||
| 		vector<string> port_decls, wire_decls, mem_exprs, cell_exprs, wire_exprs; | ||||
| 
 | ||||
| 		std::vector<Mem> memories = Mem::get_all_memories(module); | ||||
| 		for (auto &mem : memories) | ||||
| 			mem.narrow(); | ||||
| 
 | ||||
| 		for (auto wire : module->wires()) | ||||
| 		{ | ||||
|  | @ -993,8 +995,6 @@ struct FirrtlWorker | |||
| 
 | ||||
| 				if (port.clk_enable) | ||||
| 					log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); | ||||
| 				if (port.wide_log2 != 0) | ||||
| 					log_error("Wide read port %d on memory %s.%s.  Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid)); | ||||
| 
 | ||||
| 				std::ostringstream rpe; | ||||
| 
 | ||||
|  | @ -1016,8 +1016,6 @@ struct FirrtlWorker | |||
| 
 | ||||
| 				if (!port.clk_enable) | ||||
| 					log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); | ||||
| 				if (port.wide_log2 != 0) | ||||
| 					log_error("Wide write port %d on memory %s.%s.  Use memory_narrow to convert them first.\n", i, log_id(module), log_id(mem.memid)); | ||||
| 				if (!port.clk_polarity) | ||||
| 					log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(mem.memid)); | ||||
| 				for (int i = 1; i < GetSize(port.en); i++) | ||||
|  |  | |||
|  | @ -124,6 +124,7 @@ struct Smt2Worker | |||
| 		memories = Mem::get_all_memories(module); | ||||
| 		for (auto &mem : memories) | ||||
| 		{ | ||||
| 			mem.narrow(); | ||||
| 			mem_dict[mem.memid] = &mem; | ||||
| 			for (auto &port : mem.wr_ports) | ||||
| 			{ | ||||
|  | @ -715,12 +716,6 @@ struct Smt2Worker | |||
| 					has_sync_wr = true; | ||||
| 				else | ||||
| 					has_async_wr = true; | ||||
| 				if (port.wide_log2) | ||||
| 					log_error("Memory %s.%s has wide write ports. This is not supported by \"write_smt2\".  Use memory_narrow to convert them first.\n", log_id(cell), log_id(module)); | ||||
| 			} | ||||
| 			for (auto &port : mem->rd_ports) { | ||||
| 				if (port.wide_log2) | ||||
| 					log_error("Memory %s.%s has wide read ports. This is not supported by \"write_smt2\".  Use memory_narrow to convert them first.\n", log_id(cell), log_id(module)); | ||||
| 			} | ||||
| 			if (has_async_wr && has_sync_wr) | ||||
| 				log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module)); | ||||
|  |  | |||
|  | @ -691,6 +691,9 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { | |||
| } | ||||
| 
 | ||||
| void Mem::narrow() { | ||||
| 	// NOTE: several passes depend on this function not modifying
 | ||||
| 	// the design at all until (and unless) emit() is called.
 | ||||
| 	// Be careful to preserve this.
 | ||||
| 	std::vector<MemRd> new_rd_ports; | ||||
| 	std::vector<MemWr> new_wr_ports; | ||||
| 	std::vector<std::pair<int, int>> new_rd_map; | ||||
|  |  | |||
|  | @ -1052,6 +1052,7 @@ grow_read_ports:; | |||
| void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) | ||||
| { | ||||
| 	log("Processing %s.%s:\n", log_id(mem.module), log_id(mem.memid)); | ||||
| 	mem.narrow(); | ||||
| 
 | ||||
| 	bool cell_init = !mem.inits.empty(); | ||||
| 
 | ||||
|  | @ -1069,20 +1070,6 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) | |||
| 		log(" %s=%d", it.first.c_str(), it.second); | ||||
| 	log("\n"); | ||||
| 
 | ||||
| 	for (auto &port : mem.rd_ports) { | ||||
| 		if (port.wide_log2) { | ||||
| 			log("Wide read ports are not supported, skipping.\n"); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto &port : mem.wr_ports) { | ||||
| 		if (port.wide_log2) { | ||||
| 			log("Wide write ports are not supported, skipping.\n"); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// This pass cannot deal with write port priority — we need to emulate it,
 | ||||
| 	// if present.  Since priority emulation will change the enable signals,
 | ||||
| 	// which in turn may change enable grouping and mapping eligibility in
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue