mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	wreduce in opt_balance_tree
This commit is contained in:
		
							parent
							
								
									b69cbaa792
								
							
						
					
					
						commit
						6552f131de
					
				
					 1 changed files with 71 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -147,6 +147,56 @@ struct OptBalanceTreeWorker {
 | 
			
		|||
		return chain;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void wreduce(Cell *cell) {
 | 
			
		||||
		// If cell is arithmetic, remove leading zeros from inputs, then clean up outputs
 | 
			
		||||
		if (cell->type.in(ID($add), ID($mul))) {
 | 
			
		||||
			// Remove leading zeros from inputs
 | 
			
		||||
			for (auto inport : {ID::A, ID::B}) {
 | 
			
		||||
				// Record number of bits removed
 | 
			
		||||
				int bits_removed = 0;
 | 
			
		||||
				IdString inport_signed = (inport == ID::A) ? ID::A_SIGNED : ID::B_SIGNED;
 | 
			
		||||
				IdString inport_width = (inport == ID::A) ? ID::A_WIDTH : ID::B_WIDTH;
 | 
			
		||||
				SigSpec inport_sig = sigmap(cell->getPort(inport));
 | 
			
		||||
				cell->unsetPort(inport);
 | 
			
		||||
				if (cell->getParam((inport == ID::A) ? ID::A_SIGNED : ID::B_SIGNED).as_bool()) {
 | 
			
		||||
					while (GetSize(inport_sig) > 1 && inport_sig[GetSize(inport_sig)-1] == State::S0 && inport_sig[GetSize(inport_sig)-2] == State::S0) {
 | 
			
		||||
						inport_sig.remove(GetSize(inport_sig)-1, 1);
 | 
			
		||||
						bits_removed++;
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					while (GetSize(inport_sig) > 0 && inport_sig[GetSize(inport_sig)-1] == State::S0) {
 | 
			
		||||
						inport_sig.remove(GetSize(inport_sig)-1, 1);
 | 
			
		||||
						bits_removed++;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				cell->setPort(inport, inport_sig);
 | 
			
		||||
				cell->setParam(inport_width, GetSize(inport_sig));
 | 
			
		||||
				log("Width reduced %s/%s by %d bits\n", log_id(cell), log_id(inport), bits_removed);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Record number of bits removed from output
 | 
			
		||||
			int bits_removed = 0;
 | 
			
		||||
 | 
			
		||||
			// Remove unnecessary bits from output
 | 
			
		||||
			SigSpec y_sig = sigmap(cell->getPort(ID::Y));
 | 
			
		||||
			cell->unsetPort(ID::Y);
 | 
			
		||||
			int width;
 | 
			
		||||
			if (cell->type == ID($add))
 | 
			
		||||
				width = std::max(cell->getParam(ID::A_WIDTH).as_int(), cell->getParam(ID::B_WIDTH).as_int()) + 1;
 | 
			
		||||
			else if (cell->type == ID($mul))
 | 
			
		||||
				width = cell->getParam(ID::A_WIDTH).as_int() + cell->getParam(ID::B_WIDTH).as_int();
 | 
			
		||||
			else log_abort();
 | 
			
		||||
			for (int i = GetSize(y_sig) - 1; i >= width; i--) {
 | 
			
		||||
				module->connect(y_sig[i], State::S0);
 | 
			
		||||
				y_sig.remove(i, 1);
 | 
			
		||||
				bits_removed++;
 | 
			
		||||
			}
 | 
			
		||||
			cell->setPort(ID::Y, y_sig);
 | 
			
		||||
			cell->setParam(ID::Y_WIDTH, GetSize(y_sig));
 | 
			
		||||
			log("Width reduced %s/Y by %d bits\n", log_id(cell), bits_removed);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void process_chain(vector<Cell*> &chain) {
 | 
			
		||||
		// If chain size is less than 3, no balancing needed
 | 
			
		||||
		if (GetSize(chain) < 3)
 | 
			
		||||
| 
						 | 
				
			
			@ -180,7 +230,7 @@ struct OptBalanceTreeWorker {
 | 
			
		|||
		end_cell->unsetPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
		// Create new mid wire
 | 
			
		||||
		Wire *mid_wire = module->addWire(NEW_ID, GetSize(mid_non_chain_sig));
 | 
			
		||||
		Wire *mid_wire = module->addWire(NEW_ID, GetSize(end_y_sig));
 | 
			
		||||
 | 
			
		||||
		// Perform rotation
 | 
			
		||||
		mid_cell->setPort(mid_non_chain_port, mid_wire);
 | 
			
		||||
| 
						 | 
				
			
			@ -188,11 +238,30 @@ struct OptBalanceTreeWorker {
 | 
			
		|||
		midnext_cell->setPort(midnext_chain_port, mid_non_chain_sig);
 | 
			
		||||
		end_cell->setPort(ID::Y, mid_wire);
 | 
			
		||||
 | 
			
		||||
		// Recurse on subtrees
 | 
			
		||||
		// Get subtrees
 | 
			
		||||
		vector<Cell*> left_chain(chain.begin(), chain.begin() + GetSize(chain) / 2);
 | 
			
		||||
		vector<Cell*> right_chain(chain.begin() + GetSize(chain) / 2 + 1, chain.end());
 | 
			
		||||
 | 
			
		||||
		// Recurse on subtrees
 | 
			
		||||
		process_chain(left_chain);
 | 
			
		||||
		process_chain(right_chain);
 | 
			
		||||
 | 
			
		||||
		// Recreate sigmap
 | 
			
		||||
		sigmap.set(module);
 | 
			
		||||
		
 | 
			
		||||
		// Width reduce left subtree
 | 
			
		||||
		for (auto c : left_chain)
 | 
			
		||||
			wreduce(c);
 | 
			
		||||
		
 | 
			
		||||
		// Width reduce right subtree
 | 
			
		||||
		for (auto c : right_chain)
 | 
			
		||||
			wreduce(c);
 | 
			
		||||
 | 
			
		||||
		// Recreate sigmap
 | 
			
		||||
		sigmap.set(module);
 | 
			
		||||
 | 
			
		||||
		// Width reduce mid cell
 | 
			
		||||
		wreduce(mid_cell);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void cleanup() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue