mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	cxxrtl_backend: move sync $print grouping out of dump into analyze
This commit is contained in:
		
							parent
							
								
									ce245b5105
								
							
						
					
					
						commit
						2829cd9caa
					
				
					 1 changed files with 36 additions and 12 deletions
				
			
		|  | @ -292,6 +292,7 @@ struct FlowGraph { | ||||||
| 		Type type; | 		Type type; | ||||||
| 		RTLIL::SigSig connect = {}; | 		RTLIL::SigSig connect = {}; | ||||||
| 		const RTLIL::Cell *cell = nullptr; | 		const RTLIL::Cell *cell = nullptr; | ||||||
|  | 		std::vector<const RTLIL::Cell*> print_sync_cells; | ||||||
| 		const RTLIL::Process *process = nullptr; | 		const RTLIL::Process *process = nullptr; | ||||||
| 		const Mem *mem = nullptr; | 		const Mem *mem = nullptr; | ||||||
| 		int portidx; | 		int portidx; | ||||||
|  | @ -473,14 +474,21 @@ struct FlowGraph { | ||||||
| 
 | 
 | ||||||
| 		Node *node = new Node; | 		Node *node = new Node; | ||||||
| 		node->type = Node::Type::CELL_EVAL; | 		node->type = Node::Type::CELL_EVAL; | ||||||
| 		if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) |  | ||||||
| 			node->type = Node::Type::PRINT_SYNC; |  | ||||||
| 		node->cell = cell; | 		node->cell = cell; | ||||||
| 		nodes.push_back(node); | 		nodes.push_back(node); | ||||||
| 		add_cell_eval_defs_uses(node, cell); | 		add_cell_eval_defs_uses(node, cell); | ||||||
| 		return node; | 		return node; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	Node *add_print_sync_node(std::vector<const RTLIL::Cell*> cells) | ||||||
|  | 	{ | ||||||
|  | 		Node *node = new Node; | ||||||
|  | 		node->type = Node::Type::PRINT_SYNC; | ||||||
|  | 		node->print_sync_cells = cells; | ||||||
|  | 		nodes.push_back(node); | ||||||
|  | 		return node; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	// Processes
 | 	// Processes
 | ||||||
| 	void add_case_rule_defs_uses(Node *node, const RTLIL::CaseRule *case_) | 	void add_case_rule_defs_uses(Node *node, const RTLIL::CaseRule *case_) | ||||||
| 	{ | 	{ | ||||||
|  | @ -1057,8 +1065,12 @@ struct CxxrtlWorker { | ||||||
| 		f << indent << "}\n"; | 		f << indent << "}\n"; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void dump_sync_print(const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector<const RTLIL::Cell*> &cells) | 	void dump_sync_print(std::vector<const RTLIL::Cell*> &cells) | ||||||
| 	{ | 	{ | ||||||
|  | 		log_assert(!cells.empty()); | ||||||
|  | 		const auto &trg = cells[0]->getPort(ID::TRG); | ||||||
|  | 		const auto &trg_polarity = cells[0]->getParam(ID::TRG_POLARITY); | ||||||
|  | 
 | ||||||
| 		f << indent << "if ("; | 		f << indent << "if ("; | ||||||
| 		for (int i = 0; i < trg.size(); i++) { | 		for (int i = 0; i < trg.size(); i++) { | ||||||
| 			RTLIL::SigBit trg_bit = trg[i]; | 			RTLIL::SigBit trg_bit = trg[i]; | ||||||
|  | @ -1068,7 +1080,7 @@ struct CxxrtlWorker { | ||||||
| 			if (i != 0) | 			if (i != 0) | ||||||
| 				f << " || "; | 				f << " || "; | ||||||
| 
 | 
 | ||||||
| 			if (polarity[i] == State::S1) | 			if (trg_polarity[i] == State::S1) | ||||||
| 				f << "posedge_"; | 				f << "posedge_"; | ||||||
| 			else | 			else | ||||||
| 				f << "negedge_"; | 				f << "negedge_"; | ||||||
|  | @ -1081,6 +1093,9 @@ struct CxxrtlWorker { | ||||||
| 			}); | 			}); | ||||||
| 			for (auto cell : cells) { | 			for (auto cell : cells) { | ||||||
| 				log_assert(cell->getParam(ID::TRG_ENABLE).as_bool()); | 				log_assert(cell->getParam(ID::TRG_ENABLE).as_bool()); | ||||||
|  | 				log_assert(cell->getPort(ID::TRG) == trg); | ||||||
|  | 				log_assert(cell->getParam(ID::TRG_POLARITY) == trg_polarity); | ||||||
|  | 
 | ||||||
| 				std::vector<const RTLIL::Cell*> inlined_cells; | 				std::vector<const RTLIL::Cell*> inlined_cells; | ||||||
| 				collect_cell_eval(cell, /*for_debug=*/false, inlined_cells); | 				collect_cell_eval(cell, /*for_debug=*/false, inlined_cells); | ||||||
| 				dump_inlined_cells(inlined_cells); | 				dump_inlined_cells(inlined_cells); | ||||||
|  | @ -1261,7 +1276,7 @@ struct CxxrtlWorker { | ||||||
| 		} else if (cell->type == ID($print)) { | 		} else if (cell->type == ID($print)) { | ||||||
| 			log_assert(!for_debug); | 			log_assert(!for_debug); | ||||||
| 
 | 
 | ||||||
| 			// Sync $print cells become PRINT_SYNC in the FlowGraph, not CELL_EVAL.
 | 			// Sync $print cells are grouped into PRINT_SYNC nodes in the FlowGraph.
 | ||||||
| 			log_assert(!cell->getParam(ID::TRG_ENABLE).as_bool()); | 			log_assert(!cell->getParam(ID::TRG_ENABLE).as_bool()); | ||||||
| 
 | 
 | ||||||
| 			f << indent << "auto " << mangle(cell) << "_curr = "; | 			f << indent << "auto " << mangle(cell) << "_curr = "; | ||||||
|  | @ -1988,8 +2003,6 @@ struct CxxrtlWorker { | ||||||
| 
 | 
 | ||||||
| 	void dump_eval_method(RTLIL::Module *module) | 	void dump_eval_method(RTLIL::Module *module) | ||||||
| 	{ | 	{ | ||||||
| 		std::map<std::pair<RTLIL::SigSpec, RTLIL::Const>, std::vector<const RTLIL::Cell*>> sync_print_cells; |  | ||||||
| 
 |  | ||||||
| 		inc_indent(); | 		inc_indent(); | ||||||
| 			f << indent << "bool converged = " << (eval_converges.at(module) ? "true" : "false") << ";\n"; | 			f << indent << "bool converged = " << (eval_converges.at(module) ? "true" : "false") << ";\n"; | ||||||
| 			if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { | 			if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { | ||||||
|  | @ -2023,7 +2036,7 @@ struct CxxrtlWorker { | ||||||
| 							dump_cell_eval(node.cell); | 							dump_cell_eval(node.cell); | ||||||
| 							break; | 							break; | ||||||
| 						case FlowGraph::Node::Type::PRINT_SYNC: | 						case FlowGraph::Node::Type::PRINT_SYNC: | ||||||
| 							sync_print_cells[make_pair(node.cell->getPort(ID::TRG), node.cell->getParam(ID::TRG_POLARITY))].push_back(node.cell); | 							dump_sync_print(node.print_sync_cells); | ||||||
| 							break; | 							break; | ||||||
| 						case FlowGraph::Node::Type::PROCESS_CASE: | 						case FlowGraph::Node::Type::PROCESS_CASE: | ||||||
| 							dump_process_case(node.process); | 							dump_process_case(node.process); | ||||||
|  | @ -2039,8 +2052,6 @@ struct CxxrtlWorker { | ||||||
| 							break; | 							break; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				for (auto &it : sync_print_cells) |  | ||||||
| 					dump_sync_print(it.first.first, it.first.second, it.second); |  | ||||||
| 			} | 			} | ||||||
| 			f << indent << "return converged;\n"; | 			f << indent << "return converged;\n"; | ||||||
| 		dec_indent(); | 		dec_indent(); | ||||||
|  | @ -2890,9 +2901,22 @@ struct CxxrtlWorker { | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// Emit reachable nodes in eval().
 | 			// Emit reachable nodes in eval().
 | ||||||
|  | 			// Accumulate sync $print cells per trigger condition.
 | ||||||
|  | 			dict<std::pair<RTLIL::SigSpec, RTLIL::Const>, std::vector<const RTLIL::Cell*>> sync_print_cells; | ||||||
| 			for (auto node : node_order) | 			for (auto node : node_order) | ||||||
| 				if (live_nodes[node]) | 				if (live_nodes[node]) { | ||||||
| 					schedule[module].push_back(*node); | 					if (node->type == FlowGraph::Node::Type::CELL_EVAL && | ||||||
|  | 					    node->cell->type == ID($print) && | ||||||
|  | 					    node->cell->getParam(ID::TRG_ENABLE).as_bool()) | ||||||
|  | 						sync_print_cells[make_pair(node->cell->getPort(ID::TRG), node->cell->getParam(ID::TRG_POLARITY))].push_back(node->cell); | ||||||
|  | 					else | ||||||
|  | 						schedule[module].push_back(*node); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 			for (auto &it : sync_print_cells) { | ||||||
|  | 				auto node = flow.add_print_sync_node(it.second); | ||||||
|  | 				schedule[module].push_back(*node); | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 			// For maximum performance, the state of the simulation (which is the same as the set of its double buffered
 | 			// For maximum performance, the state of the simulation (which is the same as the set of its double buffered
 | ||||||
| 			// wires, since using a singly buffered wire for any kind of state introduces a race condition) should contain
 | 			// wires, since using a singly buffered wire for any kind of state introduces a race condition) should contain
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue