mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Some improvements in fsm_opt and fsm_map for FSM with unreachable states
This commit is contained in:
		
							parent
							
								
									51aa5544fb
								
							
						
					
					
						commit
						2faef89738
					
				
					 3 changed files with 104 additions and 52 deletions
				
			
		|  | @ -207,6 +207,12 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) | ||||||
| 
 | 
 | ||||||
| 	// generate next_state signal
 | 	// generate next_state signal
 | ||||||
| 
 | 
 | ||||||
|  | 	if (SIZE(fsm_data.state_table) == 1) | ||||||
|  | 	{ | ||||||
|  | 		module->connect(next_state_wire, fsm_data.state_table.front()); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
| 		RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size()); | 		RTLIL::Wire *next_state_onehot = module->addWire(NEW_ID, fsm_data.state_table.size()); | ||||||
| 
 | 
 | ||||||
| 		for (size_t i = 0; i < fsm_data.state_table.size(); i++) | 		for (size_t i = 0; i < fsm_data.state_table.size(); i++) | ||||||
|  | @ -267,6 +273,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) | ||||||
| 			mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); | 			mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size()); | ||||||
| 			mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); | 			mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size()); | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	// Generate ctrl_out signal
 | 	// Generate ctrl_out signal
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,6 +31,48 @@ struct FsmOpt | ||||||
| 	RTLIL::Cell *cell; | 	RTLIL::Cell *cell; | ||||||
| 	RTLIL::Module *module; | 	RTLIL::Module *module; | ||||||
| 
 | 
 | ||||||
|  | 	void opt_unreachable_states() | ||||||
|  | 	{ | ||||||
|  | 		while (1) | ||||||
|  | 		{ | ||||||
|  | 			std::set<int> unreachable_states; | ||||||
|  | 			std::vector<FsmData::transition_t> new_transition_table; | ||||||
|  | 			std::vector<RTLIL::Const> new_state_table; | ||||||
|  | 			std::map<int, int> old_to_new_state; | ||||||
|  | 
 | ||||||
|  | 			for (int i = 0; i < SIZE(fsm_data.state_table); i++) | ||||||
|  | 				if (i != fsm_data.reset_state) | ||||||
|  | 					unreachable_states.insert(i); | ||||||
|  | 
 | ||||||
|  | 			for (auto &trans : fsm_data.transition_table) | ||||||
|  | 				unreachable_states.erase(trans.state_out); | ||||||
|  | 
 | ||||||
|  | 			if (unreachable_states.empty()) | ||||||
|  | 				break; | ||||||
|  | 
 | ||||||
|  | 			for (int i = 0; i < SIZE(fsm_data.state_table); i++) { | ||||||
|  | 				if (unreachable_states.count(i)) { | ||||||
|  | 					log("  Removing unreachable state %s.\n", log_signal(fsm_data.state_table[i])); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				old_to_new_state[i] = SIZE(new_state_table); | ||||||
|  | 				new_state_table.push_back(fsm_data.state_table[i]); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			for (auto trans : fsm_data.transition_table) { | ||||||
|  | 				if (unreachable_states.count(trans.state_in)) | ||||||
|  | 					continue; | ||||||
|  | 				trans.state_in = old_to_new_state.at(trans.state_in); | ||||||
|  | 				trans.state_out = old_to_new_state.at(trans.state_out); | ||||||
|  | 				new_transition_table.push_back(trans); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			new_transition_table.swap(fsm_data.transition_table); | ||||||
|  | 			new_state_table.swap(fsm_data.state_table); | ||||||
|  | 			fsm_data.reset_state = old_to_new_state.at(fsm_data.reset_state); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
| 	bool signal_is_unused(RTLIL::SigSpec sig) | 	bool signal_is_unused(RTLIL::SigSpec sig) | ||||||
| 	{ | 	{ | ||||||
| 		RTLIL::SigBit bit = sig.to_single_sigbit(); | 		RTLIL::SigBit bit = sig.to_single_sigbit(); | ||||||
|  | @ -253,6 +295,8 @@ struct FsmOpt | ||||||
| 		this->cell = cell; | 		this->cell = cell; | ||||||
| 		this->module = module; | 		this->module = module; | ||||||
| 
 | 
 | ||||||
|  | 		opt_unreachable_states(); | ||||||
|  | 
 | ||||||
| 		opt_unused_outputs(); | 		opt_unused_outputs(); | ||||||
| 
 | 
 | ||||||
| 		opt_alias_inputs(); | 		opt_alias_inputs(); | ||||||
|  |  | ||||||
|  | @ -17,7 +17,8 @@ python generate.py | ||||||
| 		idx=$( printf "%05d" $i ) | 		idx=$( printf "%05d" $i ) | ||||||
| 		echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v" | 		echo "temp/uut_${idx}.log: temp/uut_${idx}.ys temp/uut_${idx}.v" | ||||||
| 		echo "	@echo -n '[$i]'" | 		echo "	@echo -n '[$i]'" | ||||||
| 		echo "	@../../yosys -ql temp/uut_${idx}.log temp/uut_${idx}.ys" | 		echo "	@../../yosys -ql temp/uut_${idx}.out temp/uut_${idx}.ys" | ||||||
|  | 		echo "	@mv temp/uut_${idx}.out temp/uut_${idx}.log" | ||||||
| 		echo "	@grep -q 'SAT proof finished' temp/uut_${idx}.log && echo -n K || echo -n T" | 		echo "	@grep -q 'SAT proof finished' temp/uut_${idx}.log && echo -n K || echo -n T" | ||||||
| 		all_targets="$all_targets temp/uut_${idx}.log" | 		all_targets="$all_targets temp/uut_${idx}.log" | ||||||
| 	done | 	done | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue