mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge pull request #4455 from phsauter/shiftadd-limit-padding
peepopt: limit padding from shiftadd
This commit is contained in:
		
						commit
						dac5bd1983
					
				
					 2 changed files with 23 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -25,6 +25,9 @@ PRIVATE_NAMESPACE_BEGIN
 | 
			
		|||
 | 
			
		||||
bool did_something;
 | 
			
		||||
 | 
			
		||||
// scratchpad configurations for pmgen
 | 
			
		||||
int shiftadd_max_ratio;
 | 
			
		||||
 | 
			
		||||
#include "passes/pmgen/peepopt_pm.h"
 | 
			
		||||
 | 
			
		||||
struct PeepoptPass : public Pass {
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +53,9 @@ struct PeepoptPass : public Pass {
 | 
			
		|||
		log("\n");
 | 
			
		||||
		log("   * shiftadd - Replace A>>(B+D) with (A'>>D)>>(B) where D is constant and\n");
 | 
			
		||||
		log("                A' is derived from A by padding or cutting inaccessible bits.\n");
 | 
			
		||||
		log("                Scratchpad: 'peepopt.shiftadd.max_data_multiple' (default: 2)\n");
 | 
			
		||||
		log("                limits the amount of padding to a multiple of the data, \n");
 | 
			
		||||
		log("                to avoid high resource usage from large temporary MUX trees.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
	void execute(std::vector<std::string> args, RTLIL::Design *design) override
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +69,11 @@ struct PeepoptPass : public Pass {
 | 
			
		|||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		// limit the padding from shiftadd to a multiple of the input data
 | 
			
		||||
		// during techmap it creates (#data + #padding) * log(shift) $_MUX_ cells
 | 
			
		||||
		// 2x implies there is a constant shift larger than the input-data which should be extremely rare
 | 
			
		||||
		shiftadd_max_ratio = design->scratchpad_get_int("peepopt.shiftadd.max_data_multiple", 2);
 | 
			
		||||
 | 
			
		||||
		for (auto module : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			did_something = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,11 +91,21 @@ code
 | 
			
		|||
	// it should only differ if previous passes create invalid data
 | 
			
		||||
	log_assert(!(offset>0 && var_signed));
 | 
			
		||||
 | 
			
		||||
	SigSpec old_a = port(shift, \A); // data
 | 
			
		||||
	std::string location = shift->get_src_attribute();
 | 
			
		||||
 | 
			
		||||
	if(shiftadd_max_ratio>0 && offset<0 && -offset*shiftadd_max_ratio > old_a.size()) {
 | 
			
		||||
		log_warning("at %s: candiate for shiftadd optimization (shifting '%s' by '%s - %d' bits) " 
 | 
			
		||||
					"was ignored to avoid high resource usage, see help peepopt\n", 
 | 
			
		||||
					location.c_str(), log_signal(old_a), log_signal(var_signal), -offset);
 | 
			
		||||
		reject;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	did_something = true;
 | 
			
		||||
	log("shiftadd pattern in %s: shift=%s, add/sub=%s, offset: %d\n", \
 | 
			
		||||
			log_id(module), log_id(shift), log_id(add), offset);
 | 
			
		||||
 | 
			
		||||
	SigSpec old_a = port(shift, \A), new_a;
 | 
			
		||||
	SigSpec new_a;
 | 
			
		||||
	if(offset<0) {
 | 
			
		||||
		// data >> (...-c) transformed to {data, c'X} >> (...)
 | 
			
		||||
		SigSpec padding( (shift->type.in($shiftx) ? State::Sx : State::S0), -offset );
 | 
			
		||||
| 
						 | 
				
			
			@ -107,14 +117,13 @@ code
 | 
			
		|||
			new_a.append(old_a.extract_end(offset));
 | 
			
		||||
		} else {
 | 
			
		||||
			// warn user in case data is empty (no bits left)
 | 
			
		||||
			std::string location = shift->get_src_attribute();
 | 
			
		||||
			if (location.empty())
 | 
			
		||||
				location = shift->name.str();
 | 
			
		||||
			if(shift->type.in($shiftx))
 | 
			
		||||
				log_warning("at %s: result of indexed part-selection is always constant (selecting from '%s' with index '%s + %d')\n", \
 | 
			
		||||
							location.c_str(), log_signal(old_a), log_signal(var_signal), offset);
 | 
			
		||||
			else
 | 
			
		||||
				log_warning("at %s: result of shift operation is always constant (shifting '%s' by '%s + %d'-bits)\n", \
 | 
			
		||||
				log_warning("at %s: result of shift operation is always constant (shifting '%s' by '%s + %d' bits)\n", \
 | 
			
		||||
							location.c_str(), log_signal(old_a), log_signal(var_signal), offset);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue