mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Code now resides in `docs/source/code_examples`. `CHAPTER_Prog` -> `stubnets` `APPNOTE_011_Design_Investigation` -> `selections` and `show` `resources/PRESENTATION_Intro` -> `intro` `resources/PRESENTATION_ExSyn` -> `synth_flow` `resources/PRESENTATION_ExAdv` -> `techmap`, `macc`, and `selections` `resources/PRESENTATION_ExOth` -> `scrambler` and `axis` Note that generated images are not yet configured to build from the new code locations.
		
			
				
	
	
		
			130 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // This is free and unencumbered software released into the public domain.
 | |
| //
 | |
| // Anyone is free to copy, modify, publish, use, compile, sell, or
 | |
| // distribute this software, either in source code form or as a compiled
 | |
| // binary, for any purpose, commercial or non-commercial, and by any
 | |
| // means.
 | |
| 
 | |
| #include "kernel/yosys.h"
 | |
| #include "kernel/sigtools.h"
 | |
| 
 | |
| #include <string>
 | |
| #include <map>
 | |
| #include <set>
 | |
| 
 | |
| USING_YOSYS_NAMESPACE
 | |
| PRIVATE_NAMESPACE_BEGIN
 | |
| 
 | |
| // this function is called for each module in the design
 | |
| static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool report_bits)
 | |
| {
 | |
| 	// use a SigMap to convert nets to a unique representation
 | |
| 	SigMap sigmap(module);
 | |
| 
 | |
| 	// count how many times a single-bit signal is used
 | |
| 	std::map<RTLIL::SigBit, int> bit_usage_count;
 | |
| 
 | |
| 	// count output lines for this module (needed only for summary output at the end)
 | |
| 	int line_count = 0;
 | |
| 
 | |
| 	log("Looking for stub wires in module %s:\n", RTLIL::id2cstr(module->name));
 | |
| 
 | |
| 	// For all ports on all cells
 | |
| 	for (auto &cell_iter : module->cells_)
 | |
| 	for (auto &conn : cell_iter.second->connections())
 | |
| 	{
 | |
| 		// Get the signals on the port
 | |
| 		// (use sigmap to get a uniqe signal name)
 | |
| 		RTLIL::SigSpec sig = sigmap(conn.second);
 | |
| 
 | |
| 		// add each bit to bit_usage_count, unless it is a constant
 | |
| 		for (auto &bit : sig)
 | |
| 			if (bit.wire != NULL)
 | |
| 				bit_usage_count[bit]++;
 | |
| 	}
 | |
| 
 | |
| 	// for each wire in the module
 | |
| 	for (auto &wire_iter : module->wires_)
 | |
| 	{
 | |
| 		RTLIL::Wire *wire = wire_iter.second;
 | |
| 
 | |
| 		// .. but only selected wires
 | |
| 		if (!design->selected(module, wire))
 | |
| 			continue;
 | |
| 
 | |
| 		// add +1 usage if this wire actually is a port
 | |
| 		int usage_offset = wire->port_id > 0 ? 1 : 0;
 | |
| 
 | |
| 		// we will record which bits of the (possibly multi-bit) wire are stub signals
 | |
| 		std::set<int> stub_bits;
 | |
| 
 | |
| 		// get a signal description for this wire and split it into separate bits
 | |
| 		RTLIL::SigSpec sig = sigmap(wire);
 | |
| 
 | |
| 		// for each bit (unless it is a constant):
 | |
| 		// check if it is used at least two times and add to stub_bits otherwise
 | |
| 		for (int i = 0; i < GetSize(sig); i++)
 | |
| 			if (sig[i].wire != NULL && (bit_usage_count[sig[i]] + usage_offset) < 2)
 | |
| 				stub_bits.insert(i);
 | |
| 
 | |
| 		// continue if no stub bits found
 | |
| 		if (stub_bits.size() == 0)
 | |
| 			continue;
 | |
| 
 | |
| 		// report stub bits and/or stub wires, don't report single bits
 | |
| 		// if called with report_bits set to false.
 | |
| 		if (GetSize(stub_bits) == GetSize(sig)) {
 | |
| 			log("  found stub wire: %s\n", RTLIL::id2cstr(wire->name));
 | |
| 		} else {
 | |
| 			if (!report_bits)
 | |
| 				continue;
 | |
| 			log("  found wire with stub bits: %s [", RTLIL::id2cstr(wire->name));
 | |
| 			for (int bit : stub_bits)
 | |
| 				log("%s%d", bit == *stub_bits.begin() ? "" : ", ", bit);
 | |
| 			log("]\n");
 | |
| 		}
 | |
| 
 | |
| 		// we have outputted a line, increment summary counter
 | |
| 		line_count++;
 | |
| 	}
 | |
| 
 | |
| 	// report summary
 | |
| 	if (report_bits)
 | |
| 		log("  found %d stub wires or wires with stub bits.\n", line_count);
 | |
| 	else
 | |
| 		log("  found %d stub wires.\n", line_count);
 | |
| }
 | |
| 
 | |
| // each pass contains a singleton object that is derived from Pass
 | |
| struct StubnetsPass : public Pass {
 | |
| 	StubnetsPass() : Pass("stubnets") { }
 | |
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) override
 | |
| 	{
 | |
| 		// variables to mirror information from passed options
 | |
| 		bool report_bits = 0;
 | |
| 
 | |
| 		log_header(design, "Executing STUBNETS pass (find stub nets).\n");
 | |
| 
 | |
| 		// parse options
 | |
| 		size_t argidx;
 | |
| 		for (argidx = 1; argidx < args.size(); argidx++) {
 | |
| 			std::string arg = args[argidx];
 | |
| 			if (arg == "-report_bits") {
 | |
| 				report_bits = true;
 | |
| 				continue;
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		// handle extra options (e.g. selection)
 | |
| 		extra_args(args, argidx, design);
 | |
| 
 | |
| 		// call find_stub_nets() for each module that is either
 | |
| 		// selected as a whole or contains selected objects.
 | |
| 		for (auto &it : design->modules_)
 | |
| 			if (design->selected_module(it.first))
 | |
| 				find_stub_nets(design, it.second, report_bits);
 | |
| 	}
 | |
| } StubnetsPass;
 | |
| 
 | |
| PRIVATE_NAMESPACE_END
 |