mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	clockgate: EN can be a bit on a multi-bit wire
This commit is contained in:
		
							parent
							
								
									8b464341c2
								
							
						
					
					
						commit
						1e999a3cb7
					
				
					 2 changed files with 38 additions and 13 deletions
				
			
		|  | @ -73,20 +73,20 @@ struct ClockgatePass : public Pass { | |||
| 	// if the number of FFs associated with it is sufficent
 | ||||
| 	struct ClkNetInfo { | ||||
| 		// Original, ungated clock into enabled FF
 | ||||
| 		Wire* clk_net; | ||||
| 		SigBit clk_bit; | ||||
| 		// Original clock enable into enabled FF
 | ||||
| 		Wire* ce_net; | ||||
| 		SigBit ce_bit; | ||||
| 		bool pol_clk; | ||||
| 		bool pol_ce; | ||||
| 		unsigned int hash() const { | ||||
| 			auto t = std::make_tuple(clk_net, ce_net, pol_clk, pol_ce); | ||||
| 			auto t = std::make_tuple(clk_bit, ce_bit, pol_clk, pol_ce); | ||||
| 			unsigned int h = mkhash_init; | ||||
| 			h = mkhash(h, hash_ops<decltype(t)>::hash(t)); | ||||
| 			return h; | ||||
| 		} | ||||
| 		bool operator==(const ClkNetInfo& other) const { | ||||
| 			return (clk_net == other.clk_net) && | ||||
| 			       (ce_net == other.ce_net) && | ||||
| 			return (clk_bit == other.clk_bit) && | ||||
| 			       (ce_bit == other.ce_bit) && | ||||
| 			       (pol_clk == other.pol_clk) && | ||||
| 			       (pol_ce == other.pol_ce); | ||||
| 		} | ||||
|  | @ -100,8 +100,8 @@ struct ClockgatePass : public Pass { | |||
| 	}; | ||||
| 
 | ||||
| 	ClkNetInfo clk_info_from_ff(FfData& ff) { | ||||
| 		Wire* clk = ff.sig_clk.as_wire(); | ||||
| 		Wire* ce = ff.sig_ce.as_wire(); | ||||
| 		SigBit clk = ff.sig_clk[0]; | ||||
| 		SigBit ce = ff.sig_ce[0]; | ||||
| 		ClkNetInfo info{clk, ce, ff.pol_clk, ff.pol_ce}; | ||||
| 		return info; | ||||
| 	} | ||||
|  | @ -147,7 +147,12 @@ struct ClockgatePass : public Pass { | |||
| 
 | ||||
| 				FfData ff(nullptr, cell); | ||||
| 				// It would be odd to get constants, but we better handle it
 | ||||
| 				if (ff.has_ce && ff.sig_clk.is_wire() && ff.sig_ce.is_wire()) { | ||||
| 				if (ff.has_ce) { | ||||
| 					if (!ff.sig_clk.is_bit() || !ff.sig_ce.is_bit()) | ||||
| 						continue; | ||||
| 					if (!ff.sig_clk[0].is_wire() || !ff.sig_ce[0].is_wire()) | ||||
| 						continue; | ||||
| 
 | ||||
| 					ce_ffs.insert(cell); | ||||
| 
 | ||||
| 					ClkNetInfo info = clk_info_from_ff(ff); | ||||
|  | @ -159,7 +164,6 @@ struct ClockgatePass : public Pass { | |||
| 			} | ||||
| 
 | ||||
| 			for (auto& clk_net : clk_nets) { | ||||
| 				log_debug("checking clk net %s\n", clk_net.first.clk_net->name.c_str()); | ||||
| 				auto& clk = clk_net.first; | ||||
| 				auto& gclk = clk_net.second; | ||||
| 
 | ||||
|  | @ -176,10 +180,9 @@ struct ClockgatePass : public Pass { | |||
| 				if (!matching_icg_desc) | ||||
| 					continue; | ||||
| 
 | ||||
| 				log_debug("building ICG for clk net %s\n", clk_net.first.clk_net->name.c_str()); | ||||
| 				Cell* icg = module->addCell(NEW_ID, matching_icg_desc->name); | ||||
| 				icg->setPort(matching_icg_desc->ce_pin, clk.ce_net); | ||||
| 				icg->setPort(matching_icg_desc->clk_in_pin, clk.clk_net); | ||||
| 				icg->setPort(matching_icg_desc->ce_pin, clk.ce_bit); | ||||
| 				icg->setPort(matching_icg_desc->clk_in_pin, clk.clk_bit); | ||||
| 				gclk.new_net = module->addWire(NEW_ID); | ||||
| 				icg->setPort(matching_icg_desc->clk_out_pin, gclk.new_net); | ||||
| 				// Tie low DFT ports like scan chain enable
 | ||||
|  | @ -187,7 +190,7 @@ struct ClockgatePass : public Pass { | |||
| 					icg->setPort(port, Const(0)); | ||||
| 				// Fix CE polarity if needed
 | ||||
| 				if (!clk.pol_ce) { | ||||
| 					SigBit ce_fixed_pol = module->NotGate(NEW_ID, clk.ce_net); | ||||
| 					SigBit ce_fixed_pol = module->NotGate(NEW_ID, clk.ce_bit); | ||||
| 					icg->setPort(matching_icg_desc->ce_pin, ce_fixed_pol); | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
|  | @ -171,4 +171,26 @@ select -module bad2 -assert-count 0 t:\\pdk_icg | |||
| 
 | ||||
| #------------------------------------------------------------------------------ | ||||
| 
 | ||||
| # Regression test: EN is a bit from a multi-bit wire | ||||
| design -reset | ||||
| read_verilog << EOT | ||||
| module dffe_wide_11( input clk, input [1:0] en, | ||||
| 			input [3:0] d1, output reg [3:0] q1, | ||||
| 		); | ||||
| 	always @( posedge clk ) begin | ||||
| 		if ( en[0] ) | ||||
| 			q1 <= d1; | ||||
| 	end | ||||
| endmodule | ||||
| 
 | ||||
| EOT | ||||
| 
 | ||||
| proc | ||||
| opt | ||||
| 
 | ||||
| clockgate -pos pdk_icg ce:clkin:clkout -tie_lo scanen | ||||
| select -assert-count 1 t:\\pdk_icg | ||||
| 
 | ||||
| #------------------------------------------------------------------------------ | ||||
| 
 | ||||
| # TODO test -tie_lo | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue