mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	opt_expr: Propagate constants to port connections.
This adds one simple piece of functionality to opt_expr: when a cell port is connected to a fully-constant signal (as determined by sigmap), the port is reconnected directly to the constant value. This is just enough optimization to fix the "non-constant $meminit input" problem without requiring a full opt_clean or a separate pass.
This commit is contained in:
		
							parent
							
								
									9600f20be8
								
							
						
					
					
						commit
						436d42c00c
					
				
					 3 changed files with 37 additions and 3 deletions
				
			
		| 
						 | 
					@ -395,9 +395,6 @@ int get_highest_hot_index(RTLIL::SigSpec signal)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool noclkinv)
 | 
					void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool noclkinv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!design->selected(module))
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	CellTypes ct_combinational;
 | 
						CellTypes ct_combinational;
 | 
				
			||||||
	ct_combinational.setup_internals();
 | 
						ct_combinational.setup_internals();
 | 
				
			||||||
	ct_combinational.setup_stdcells();
 | 
						ct_combinational.setup_stdcells();
 | 
				
			||||||
| 
						 | 
					@ -2007,6 +2004,23 @@ skip_alu_split:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void replace_const_connections(RTLIL::Module *module) {
 | 
				
			||||||
 | 
						SigMap assign_map(module);
 | 
				
			||||||
 | 
						for (auto cell : module->selected_cells())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::vector<std::pair<RTLIL::IdString, SigSpec>> changes;
 | 
				
			||||||
 | 
							for (auto &conn : cell->connections()) {
 | 
				
			||||||
 | 
								SigSpec mapped = assign_map(conn.second);
 | 
				
			||||||
 | 
								if (conn.second != mapped && mapped.is_fully_const())
 | 
				
			||||||
 | 
									changes.push_back({conn.first, mapped});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!changes.empty())
 | 
				
			||||||
 | 
								did_something = true;
 | 
				
			||||||
 | 
							for (auto &it : changes)
 | 
				
			||||||
 | 
								cell->setPort(it.first, it.second);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct OptExprPass : public Pass {
 | 
					struct OptExprPass : public Pass {
 | 
				
			||||||
	OptExprPass() : Pass("opt_expr", "perform const folding and simple expression rewriting") { }
 | 
						OptExprPass() : Pass("opt_expr", "perform const folding and simple expression rewriting") { }
 | 
				
			||||||
	void help() override
 | 
						void help() override
 | 
				
			||||||
| 
						 | 
					@ -2117,6 +2131,11 @@ struct OptExprPass : public Pass {
 | 
				
			||||||
					design->scratchpad_set_bool("opt.did_something", true);
 | 
										design->scratchpad_set_bool("opt.did_something", true);
 | 
				
			||||||
			} while (did_something);
 | 
								} while (did_something);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								did_something = false;
 | 
				
			||||||
 | 
								replace_const_connections(module);
 | 
				
			||||||
 | 
								if (did_something)
 | 
				
			||||||
 | 
									design->scratchpad_set_bool("opt.did_something", true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			log_suppressed();
 | 
								log_suppressed();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								tests/opt/opt_expr_constconn.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								tests/opt/opt_expr_constconn.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					module top(...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input [7:0] A;
 | 
				
			||||||
 | 
					output [7:0] B;
 | 
				
			||||||
 | 
					wire [7:0] C = 3;
 | 
				
			||||||
 | 
					assign B = A + C;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
							
								
								
									
										7
									
								
								tests/opt/opt_expr_constconn.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/opt/opt_expr_constconn.ys
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					read_verilog opt_expr_constconn.v
 | 
				
			||||||
 | 
					select -assert-count 1 t:$add
 | 
				
			||||||
 | 
					select -assert-count 1 t:$add %ci w:C %i
 | 
				
			||||||
 | 
					equiv_opt -assert opt_expr
 | 
				
			||||||
 | 
					design -load postopt
 | 
				
			||||||
 | 
					select -assert-count 1 t:$add
 | 
				
			||||||
 | 
					select -assert-count 0 t:$add %ci w:C %i
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue