mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Fixed handling of driver-driver conflicts in wreduce
This commit is contained in:
		
							parent
							
								
									4cec1c058d
								
							
						
					
					
						commit
						2a0f577f83
					
				
					 3 changed files with 42 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -226,7 +226,7 @@ struct ModIndex : public RTLIL::Monitor
 | 
			
		|||
		auto_reload_module = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ModIndex(RTLIL::Module *_m) : module(_m)
 | 
			
		||||
	ModIndex(RTLIL::Module *_m) : sigmap(_m), module(_m)
 | 
			
		||||
	{
 | 
			
		||||
		auto_reload_counter = 0;
 | 
			
		||||
		auto_reload_module = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -274,6 +274,27 @@ struct ModIndex : public RTLIL::Monitor
 | 
			
		|||
			return empty_result_set;
 | 
			
		||||
		return info->ports;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void dump_db()
 | 
			
		||||
	{
 | 
			
		||||
		log("--- ModIndex Dump ---\n");
 | 
			
		||||
 | 
			
		||||
		if (auto_reload_module) {
 | 
			
		||||
			log("AUTO-RELOAD\n");
 | 
			
		||||
			reload_module();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto &it : database) {
 | 
			
		||||
			log("BIT %s:\n", log_signal(it.first));
 | 
			
		||||
			if (it.second.is_input)
 | 
			
		||||
				log("  PRIMARY INPUT\n");
 | 
			
		||||
			if (it.second.is_output)
 | 
			
		||||
				log("  PRIMARY OUTPUT\n");
 | 
			
		||||
			for (auto &port : it.second.ports)
 | 
			
		||||
				log("  PORT: %s.%s[%d] (%s)\n", log_id(port.cell),
 | 
			
		||||
						log_id(port.port), port.offset, log_id(port.cell->type));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ModWalker
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1448,6 +1448,10 @@ void RTLIL::Module::connect(const RTLIL::SigSig &conn)
 | 
			
		|||
		for (auto mon : design->monitors)
 | 
			
		||||
			mon->notify_connect(this, conn);
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
	log_assert(!conn.first.has_const());
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (yosys_xtrace) {
 | 
			
		||||
		log("#X# Connect (SigSig) in %s: %s = %s (%d bits)\n", log_id(this), log_signal(conn.first), log_signal(conn.second), GetSize(conn.first));
 | 
			
		||||
		log_backtrace("-X- ", yosys_xtrace-1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,9 @@ struct WreduceWorker
 | 
			
		|||
		SigSpec sig_y = mi.sigmap(cell->getPort("\\Y"));
 | 
			
		||||
		std::vector<SigBit> bits_removed;
 | 
			
		||||
 | 
			
		||||
		if (sig_y.has_const())
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		for (int i = GetSize(sig_y)-1; i >= 0; i--)
 | 
			
		||||
		{
 | 
			
		||||
			auto info = mi.query(sig_y[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -173,6 +176,11 @@ struct WreduceWorker
 | 
			
		|||
		if (cell->type.in("$mux", "$pmux"))
 | 
			
		||||
			return run_cell_mux(cell);
 | 
			
		||||
 | 
			
		||||
		SigSpec sig = mi.sigmap(cell->getPort("\\Y"));
 | 
			
		||||
 | 
			
		||||
		if (sig.has_const())
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		// Reduce size of ports A and B based on constant input bits and size of output port
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -180,8 +188,8 @@ struct WreduceWorker
 | 
			
		|||
		int max_port_b_size = cell->hasPort("\\B") ? GetSize(cell->getPort("\\B")) : -1;
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in("$not", "$pos", "$neg", "$and", "$or", "$xor", "$add", "$sub")) {
 | 
			
		||||
			max_port_a_size = std::min(max_port_a_size, GetSize(cell->getPort("\\Y")));
 | 
			
		||||
			max_port_b_size = std::min(max_port_b_size, GetSize(cell->getPort("\\Y")));
 | 
			
		||||
			max_port_a_size = std::min(max_port_a_size, GetSize(sig));
 | 
			
		||||
			max_port_b_size = std::min(max_port_b_size, GetSize(sig));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool port_a_signed = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -196,8 +204,6 @@ struct WreduceWorker
 | 
			
		|||
 | 
			
		||||
		// Reduce size of port Y based on sizes for A and B and unused bits in Y
 | 
			
		||||
 | 
			
		||||
		SigSpec sig = mi.sigmap(cell->getPort("\\Y"));
 | 
			
		||||
 | 
			
		||||
		int bits_removed = 0;
 | 
			
		||||
		if (port_a_signed && cell->type == "$shr") {
 | 
			
		||||
			// do not reduce size of output on $shr cells with signed A inputs
 | 
			
		||||
| 
						 | 
				
			
			@ -358,10 +364,12 @@ struct WreducePass : public Pass {
 | 
			
		|||
						"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
 | 
			
		||||
						"$logic_not", "$logic_and", "$logic_or") && GetSize(c->getPort("\\Y")) > 1) {
 | 
			
		||||
					SigSpec sig = c->getPort("\\Y");
 | 
			
		||||
					c->setPort("\\Y", sig[0]);
 | 
			
		||||
					c->setParam("\\Y_WIDTH", 1);
 | 
			
		||||
					sig.remove(0);
 | 
			
		||||
					module->connect(sig, Const(0, GetSize(sig)));
 | 
			
		||||
					if (!sig.has_const()) {
 | 
			
		||||
						c->setPort("\\Y", sig[0]);
 | 
			
		||||
						c->setParam("\\Y_WIDTH", 1);
 | 
			
		||||
						sig.remove(0);
 | 
			
		||||
						module->connect(sig, Const(0, GetSize(sig)));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			WreduceWorker worker(&config, module);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue