mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	WIP temporary drivertools example
This commit is contained in:
		
							parent
							
								
									56572978f5
								
							
						
					
					
						commit
						68c3a47945
					
				
					 2 changed files with 141 additions and 0 deletions
				
			
		|  | @ -49,3 +49,4 @@ OBJS += passes/cmds/xprop.o | |||
| OBJS += passes/cmds/dft_tag.o | ||||
| OBJS += passes/cmds/future.o | ||||
| OBJS += passes/cmds/box_derive.o | ||||
| OBJS += passes/cmds/example_dt.o | ||||
|  |  | |||
							
								
								
									
										140
									
								
								passes/cmds/example_dt.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								passes/cmds/example_dt.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,140 @@ | |||
| #include "kernel/yosys.h" | ||||
| #include "kernel/drivertools.h" | ||||
| #include "kernel/topo_scc.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| struct ExampleWorker | ||||
| { | ||||
| 	DriverMap dm; | ||||
| 	Module *module; | ||||
| 
 | ||||
| 	ExampleWorker(Module *module) : module(module) { | ||||
| 		dm.celltypes.setup(); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| struct ExampleDtPass : public Pass | ||||
| { | ||||
| 	ExampleDtPass() : Pass("example_dt", "drivertools example") {} | ||||
| 
 | ||||
|     void help() override | ||||
| 	{ | ||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||
| 		log("\n"); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) override | ||||
| 	{ | ||||
| 		size_t argidx = 1; | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		for (auto module : design->selected_modules()) { | ||||
| 			ExampleWorker worker(module); | ||||
| 			DriverMap dm; | ||||
| 
 | ||||
| 			dm.add(module); | ||||
| 
 | ||||
| 			idict<DriveSpec> queue; | ||||
| 			idict<Cell *> cells; | ||||
| 
 | ||||
| 			IntGraph edges; | ||||
| 
 | ||||
| 
 | ||||
| 			for (auto cell : module->cells()) { | ||||
| 				if (cell->type.in(ID($assert), ID($assume), ID($cover), ID($check))) | ||||
| 					queue(DriveBitMarker(cells(cell), 0)); | ||||
| 			} | ||||
| 
 | ||||
| 			for (auto wire : module->wires()) { | ||||
| 				if (!wire->port_output) | ||||
| 					continue; | ||||
| 				queue(DriveChunk(DriveChunkWire(wire, 0, wire->width))); | ||||
| 			} | ||||
| 
 | ||||
| #define emit log | ||||
| // #define emit(X...) do {} while (false)
 | ||||
| 
 | ||||
| 			for (int i = 0; i != GetSize(queue); ++i) | ||||
| 			{ | ||||
| 				emit("n%d: ", i); | ||||
| 				DriveSpec spec = queue[i]; | ||||
| 				if (spec.chunks().size() > 1) { | ||||
| 					emit("concat %s <-\n", log_signal(spec)); | ||||
| 					for (auto const &chunk : spec.chunks()) { | ||||
| 						emit("  * %s\n", log_signal(chunk)); | ||||
| 						edges.add_edge(i, queue(chunk)); | ||||
| 					} | ||||
| 				} else if (spec.chunks().size() == 1) { | ||||
| 					DriveChunk chunk = spec.chunks()[0]; | ||||
| 					if (chunk.is_wire()) { | ||||
| 						DriveChunkWire wire_chunk = chunk.wire(); | ||||
| 						if (wire_chunk.is_whole()) { | ||||
| 							if (wire_chunk.wire->port_input) { | ||||
| 								emit("input %s\n", log_signal(spec)); | ||||
| 							} else { | ||||
| 								DriveSpec driver = dm(DriveSpec(wire_chunk)); | ||||
| 								edges.add_edge(i, queue(driver)); | ||||
| 								emit("wire driver %s <- %s\n", log_signal(spec), log_signal(driver)); | ||||
| 							} | ||||
| 						} else { | ||||
| 							DriveChunkWire whole_wire(wire_chunk.wire, 0, wire_chunk.width); | ||||
| 							edges.add_edge(i, queue(whole_wire)); | ||||
| 							emit("wire slice %s <- %s\n", log_signal(spec), log_signal(DriveSpec(whole_wire))); | ||||
| 						} | ||||
| 					} else if (chunk.is_port()) { | ||||
| 						DriveChunkPort port_chunk = chunk.port(); | ||||
| 						if (port_chunk.is_whole()) { | ||||
| 							if (dm.celltypes.cell_output(port_chunk.cell->type, port_chunk.port)) { | ||||
| 								int cell_marker = queue(DriveBitMarker(cells(port_chunk.cell), 0)); | ||||
| 								if (!port_chunk.cell->type.in(ID($dff), ID($ff))) | ||||
| 									edges.add_edge(i, cell_marker); | ||||
| 								emit("cell output %s %s\n", log_id(port_chunk.cell), log_id(port_chunk.port)); | ||||
| 							} else { | ||||
| 								DriveSpec driver = dm(DriveSpec(port_chunk)); | ||||
| 								edges.add_edge(i, queue(driver)); | ||||
| 								emit("cell port driver %s <- %s\n", log_signal(spec), log_signal(driver)); | ||||
| 							} | ||||
| 
 | ||||
| 						} else { | ||||
| 							DriveChunkPort whole_port(port_chunk.cell, port_chunk.port, 0, GetSize(port_chunk.cell->connections().at(port_chunk.port))); | ||||
| 							edges.add_edge(i, queue(whole_port)); | ||||
| 							emit("port slice %s <- %s\n", log_signal(spec), log_signal(DriveSpec(whole_port))); | ||||
| 						} | ||||
| 					} else if (chunk.is_constant()) { | ||||
| 						emit("constant %s <- %s\n", log_signal(spec), log_const(chunk.constant())); | ||||
| 					} else if (chunk.is_marker()) { | ||||
| 						Cell *cell = cells[chunk.marker().marker]; | ||||
| 						emit("cell %s %s\n", log_id(cell->type), log_id(cell)); | ||||
| 						for (auto const &conn : cell->connections()) { | ||||
| 							if (!dm.celltypes.cell_input(cell->type, conn.first)) | ||||
| 								continue; | ||||
| 							emit("  * %s <- %s\n", log_id(conn.first), log_signal(conn.second)); | ||||
| 							edges.add_edge(i, queue(DriveChunkPort(cell, conn))); | ||||
| 						} | ||||
| 					} else { | ||||
| 						log_abort(); | ||||
| 					} | ||||
| 				} else { | ||||
| 					log_abort(); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			topo_sorted_sccs(edges, [&](int *begin, int *end) { | ||||
| 				emit("scc:"); | ||||
| 				for (int *i = begin; i != end; ++i) | ||||
| 					emit(" n%d", *i); | ||||
| 				emit("\n"); | ||||
| 			}); | ||||
| 
 | ||||
| 		} | ||||
| 		log("Plugin test passed!\n"); | ||||
| 	} | ||||
| } ExampleDtPass; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue