mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	proc_prune: Make assign removal and promotion per-bit, remember promoted bits.
Fixes #2962.
This commit is contained in:
		
							parent
							
								
									539d4ee907
								
							
						
					
					
						commit
						faacc7ad89
					
				
					 2 changed files with 47 additions and 40 deletions
				
			
		| 
						 | 
				
			
			@ -67,51 +67,36 @@ struct PruneWorker
 | 
			
		|||
		}
 | 
			
		||||
		for (auto it = cs->actions.rbegin(); it != cs->actions.rend(); ) {
 | 
			
		||||
			RTLIL::SigSpec lhs = sigmap(it->first);
 | 
			
		||||
			bool redundant = true;
 | 
			
		||||
			for (auto &bit : lhs) {
 | 
			
		||||
			RTLIL::SigSpec rhs = sigmap(it->second);
 | 
			
		||||
			SigSpec new_lhs, new_rhs;
 | 
			
		||||
			SigSpec conn_lhs, conn_rhs;
 | 
			
		||||
			for (int i = 0; i < GetSize(lhs); i++) {
 | 
			
		||||
				SigBit bit = lhs[i];
 | 
			
		||||
				if (bit.wire && !assigned[bit]) {
 | 
			
		||||
					redundant = false;
 | 
			
		||||
					break;
 | 
			
		||||
					if (!affected[bit] && root) {
 | 
			
		||||
						conn_lhs.append(bit);
 | 
			
		||||
						conn_rhs.append(rhs[i]);
 | 
			
		||||
					} else {
 | 
			
		||||
						new_lhs.append(bit);
 | 
			
		||||
						new_rhs.append(rhs[i]);
 | 
			
		||||
					}
 | 
			
		||||
					assigned.insert(bit);
 | 
			
		||||
					affected.insert(bit);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			bool remove = false;
 | 
			
		||||
			if (redundant) {
 | 
			
		||||
				removed_count++;
 | 
			
		||||
				remove = true;
 | 
			
		||||
			} else {
 | 
			
		||||
				if (root) {
 | 
			
		||||
					bool promotable = true;
 | 
			
		||||
					for (auto &bit : lhs) {
 | 
			
		||||
						if (bit.wire && affected[bit] && !assigned[bit]) {
 | 
			
		||||
							promotable = false;
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (promotable) {
 | 
			
		||||
						RTLIL::SigSpec rhs = sigmap(it->second);
 | 
			
		||||
						RTLIL::SigSig conn;
 | 
			
		||||
						for (int i = 0; i < GetSize(lhs); i++) {
 | 
			
		||||
							RTLIL::SigBit lhs_bit = lhs[i];
 | 
			
		||||
							if (lhs_bit.wire && !assigned[lhs_bit]) {
 | 
			
		||||
								conn.first.append(lhs_bit);
 | 
			
		||||
								conn.second.append(rhs.extract(i));
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						promoted_count++;
 | 
			
		||||
						module->connect(conn);
 | 
			
		||||
						remove = true;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				for (auto &bit : lhs)
 | 
			
		||||
					if (bit.wire)
 | 
			
		||||
						assigned.insert(bit);
 | 
			
		||||
				for (auto &bit : lhs)
 | 
			
		||||
					if (bit.wire)
 | 
			
		||||
						affected.insert(bit);
 | 
			
		||||
			if (GetSize(conn_lhs)) {
 | 
			
		||||
				promoted_count++;
 | 
			
		||||
				module->connect(conn_lhs, conn_rhs);
 | 
			
		||||
			}
 | 
			
		||||
			if (remove)
 | 
			
		||||
			if (GetSize(new_lhs) == 0) {
 | 
			
		||||
				if (GetSize(conn_lhs) == 0)
 | 
			
		||||
					removed_count++;
 | 
			
		||||
				cs->actions.erase((it++).base() - 1);
 | 
			
		||||
			else it++;
 | 
			
		||||
			} else {
 | 
			
		||||
				it->first = new_lhs;
 | 
			
		||||
				it->second = new_rhs;
 | 
			
		||||
				it++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return assigned;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								tests/proc/bug2962.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								tests/proc/bug2962.ys
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
read_ilang << EOT
 | 
			
		||||
module \top
 | 
			
		||||
   wire width 4 input 1 \a
 | 
			
		||||
   wire width 2 input 2 \b
 | 
			
		||||
   wire input 3 \clk
 | 
			
		||||
   wire width 4 output 4 \q
 | 
			
		||||
   wire input 5 \en
 | 
			
		||||
   wire width 4 \nq
 | 
			
		||||
   process \p
 | 
			
		||||
     assign \nq \a
 | 
			
		||||
     assign \nq [1:0] \b
 | 
			
		||||
     switch \en
 | 
			
		||||
       case 1'1
 | 
			
		||||
         assign \nq [3] 1'0
 | 
			
		||||
     end
 | 
			
		||||
     sync posedge \clk
 | 
			
		||||
       update \q \nq
 | 
			
		||||
   end
 | 
			
		||||
end
 | 
			
		||||
EOT
 | 
			
		||||
proc
 | 
			
		||||
check -assert
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue