mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-28 10:19:26 +00:00 
			
		
		
		
	Cope with undoing #895
This commit is contained in:
		
							parent
							
								
									d3930ca79e
								
							
						
					
					
						commit
						93b1621911
					
				
					 1 changed files with 26 additions and 14 deletions
				
			
		|  | @ -96,6 +96,7 @@ struct ShregmapTechGreenpak4 : ShregmapTech | |||
| struct ShregmapTechXilinx7 : ShregmapTech | ||||
| { | ||||
| 	dict<SigBit, std::tuple<Cell*,int,int>> sigbit_to_shiftx_offset; | ||||
| 	dict<SigBit, SigSpec> sigbit_to_eq_input; | ||||
| 	const ShregmapOptions &opts; | ||||
| 
 | ||||
| 	ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {} | ||||
|  | @ -113,16 +114,17 @@ struct ShregmapTechXilinx7 : ShregmapTech | |||
| 			} | ||||
| 			else if (cell->type == "$mux") { | ||||
| 				int j = 0; | ||||
| 				for (auto bit : cell->getPort("\\A")) | ||||
| 				for (auto bit : sigmap(cell->getPort("\\A"))) | ||||
| 					sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++); | ||||
| 				j = 0; | ||||
| 				for (auto bit : sigmap(cell->getPort("\\B"))) | ||||
| 					sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++); | ||||
| 			} | ||||
| 			else if (cell->type == "$pmux") { | ||||
| 				if (!cell->get_bool_attribute("\\shiftx_compatible")) continue; | ||||
| 				int width = cell->getParam("\\WIDTH").as_int(); | ||||
| 				int j = 0; | ||||
| 				for (auto bit : cell->getPort("\\A")) | ||||
| 				for (auto bit : sigmap(cell->getPort("\\A"))) | ||||
| 					sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++); | ||||
| 				j = cell->getParam("\\S_WIDTH").as_int(); | ||||
| 				int k = 0; | ||||
|  | @ -135,6 +137,15 @@ struct ShregmapTechXilinx7 : ShregmapTech | |||
| 				} | ||||
| 				log_assert(j == 0); | ||||
| 			} | ||||
| 			else if (cell->type == "$eq") { | ||||
| 				auto b_wire = cell->getPort("\\B"); | ||||
| 				// Keep track of $eq cells that compare against the value 1
 | ||||
| 				// in anticipation that they drive the select (S) port of a $pmux
 | ||||
| 				if (b_wire.is_fully_const() && b_wire.as_int() == 1) { | ||||
| 					auto y_wire = sigmap(cell->getPort("\\Y").as_bit()); | ||||
| 					sigbit_to_eq_input[y_wire] = cell->getPort("\\A"); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -239,19 +250,20 @@ struct ShregmapTechXilinx7 : ShregmapTech | |||
| 			shiftx->setPort("\\Y", cell->module->addWire(NEW_ID)); | ||||
| 		} | ||||
| 		else if (shiftx->type == "$pmux") { | ||||
| 			// Create a new encoder, out of a $pmux, that takes
 | ||||
| 			// the existing pmux's 'S' input and transforms it
 | ||||
| 			// back into a binary value
 | ||||
| 			int clog2taps = ceil(log2(taps.size())); | ||||
| 			RTLIL::SigSpec b_port; | ||||
| 			for (int i = shiftx->getParam("\\S_WIDTH").as_int(); i > 0; i--) | ||||
| 				b_port.append(RTLIL::Const(i, clog2taps)); | ||||
| 			l_wire = cell->module->addWire(NEW_ID, clog2taps); | ||||
| 			RTLIL::SigSpec s_wire = cell->module->addWire(NEW_ID, shiftx->getParam("\\S_WIDTH").as_int()); | ||||
| 			cell->module->connect(s_wire.extract(0, shiftx->getParam("\\S_WIDTH").as_int()), shiftx->getPort("\\S")); | ||||
| 			cell->module->addPmux(NEW_ID, RTLIL::Const(0, clog2taps), b_port, s_wire, l_wire); | ||||
| 			int group = std::get<2>(it->second); | ||||
| 			// If the 'A' port is fully undef, then opt_expr -mux_undef
 | ||||
| 			// has not been applied, so find the second-to-last bit of
 | ||||
| 			// the 'S' port (corresponding to $eq cell comparing for 1)
 | ||||
| 			// otherwise use the last bit of 'S'
 | ||||
| 			const auto& s_wire_bits = shiftx->getPort("\\S").bits(); | ||||
| 			SigBit s1; | ||||
| 			if (shiftx->getPort("\\A").is_fully_undef()) | ||||
| 				s1 = s_wire_bits[s_wire_bits.size() - 2]; | ||||
| 			else | ||||
| 				s1 = s_wire_bits[s_wire_bits.size() - 1]; | ||||
| 			RTLIL::SigSpec y_wire = shiftx->getPort("\\Y"); | ||||
| 			l_wire = sigbit_to_eq_input.at(s1); | ||||
| 			log_assert(l_wire.size() == ceil(log2(taps.size()))); | ||||
| 			int group = std::get<2>(it->second); | ||||
| 			q_wire = y_wire[group]; | ||||
| 			y_wire[group] = cell->module->addWire(NEW_ID); | ||||
| 			shiftx->setPort("\\Y", y_wire); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue