mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Create one $shiftx per bit in width
This commit is contained in:
		
							parent
							
								
									2507d01b03
								
							
						
					
					
						commit
						b7a3d35c6b
					
				
					 1 changed files with 17 additions and 10 deletions
				
			
		| 
						 | 
					@ -340,7 +340,7 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
 | 
				
			||||||
		// evaluate in reverse order to give the first entry the top priority
 | 
							// evaluate in reverse order to give the first entry the top priority
 | 
				
			||||||
		RTLIL::SigSpec initial_val = result;
 | 
							RTLIL::SigSpec initial_val = result;
 | 
				
			||||||
		RTLIL::Cell *last_mux_cell = NULL;
 | 
							RTLIL::Cell *last_mux_cell = NULL;
 | 
				
			||||||
		bool shiftx = true;
 | 
							bool shiftx = initial_val.is_fully_undef();
 | 
				
			||||||
		for (size_t i = 0; i < sw->cases.size(); i++) {
 | 
							for (size_t i = 0; i < sw->cases.size(); i++) {
 | 
				
			||||||
			int case_idx = sw->cases.size() - i - 1;
 | 
								int case_idx = sw->cases.size() - i - 1;
 | 
				
			||||||
			RTLIL::CaseRule *cs2 = sw->cases[case_idx];
 | 
								RTLIL::CaseRule *cs2 = sw->cases[case_idx];
 | 
				
			||||||
| 
						 | 
					@ -355,20 +355,27 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
 | 
				
			||||||
				// Keep checking if case condition is the same as the current case index
 | 
									// Keep checking if case condition is the same as the current case index
 | 
				
			||||||
				if (cs2->compare.size() == 1 && cs2->compare.front().is_fully_const())
 | 
									if (cs2->compare.size() == 1 && cs2->compare.front().is_fully_const())
 | 
				
			||||||
					shiftx = (cs2->compare.front().as_int() == case_idx);
 | 
										shiftx = (cs2->compare.front().as_int() == case_idx);
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										shiftx = false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Transform into a $shiftx if possible
 | 
							// Transform into a $shiftx where possible
 | 
				
			||||||
		if (shiftx && last_mux_cell->type == "$pmux") {
 | 
							if (shiftx && last_mux_cell->type == "$pmux") {
 | 
				
			||||||
			// Sanity check that A port of $pmux should be 'bx
 | 
								// Create bit-blasted $shiftx-es that shifts by the address line used in the case statement
 | 
				
			||||||
			log_assert(last_mux_cell->getPort("\\A").is_fully_undef());
 | 
								auto pmux_b_port = last_mux_cell->getPort("\\B");
 | 
				
			||||||
			// Because we went in reverse order above, un-reverse its B port here
 | 
								auto pmux_y_port = last_mux_cell->getPort("\\Y");
 | 
				
			||||||
			auto b_port = last_mux_cell->getPort("\\B").chunks();
 | 
								int width = last_mux_cell->getParam("\\WIDTH").as_int();
 | 
				
			||||||
			std::reverse(b_port.begin(), b_port.end());
 | 
								for (int i = 0; i < width; ++i) {
 | 
				
			||||||
			// Create a $shiftx that shifts by the address line used in the case statement
 | 
									RTLIL::SigSpec a_port;
 | 
				
			||||||
			mod->addShiftx(NEW_ID, b_port, sw->signal, last_mux_cell->getPort("\\Y"));
 | 
									// Because we went in reverse order above, un-reverse $pmux's B port here
 | 
				
			||||||
 | 
									for (int j = pmux_b_port.size()/width-1; j >= 0; --j)
 | 
				
			||||||
 | 
										a_port.append(pmux_b_port.extract(j*width+i, 1));
 | 
				
			||||||
 | 
									// Create a $shiftx that shifts by the address line used in the case statement
 | 
				
			||||||
 | 
									mod->addShiftx(NEW_ID, a_port, sw->signal, pmux_y_port.extract(i, 1));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Disconnect $pmux by replacing its output port with a floating wire
 | 
								// Disconnect $pmux by replacing its output port with a floating wire
 | 
				
			||||||
			last_mux_cell->setPort("\\Y", mod->addWire(NEW_ID, last_mux_cell->getParam("\\WIDTH").as_int()));
 | 
								last_mux_cell->setPort("\\Y", mod->addWire(NEW_ID, width));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue