aboutsummaryrefslogtreecommitdiffstats
path: root/manual/FILES_Prog/stubnets.cc
blob: 1c71f78b894163ce01af99b828293a71eb206e3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// 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/rtlil.h"
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/log.h"

#include <string>
#include <map>
#include <set>

// 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::SigSpec, int> bit_usage_count;

	// count ouput 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);

		// split the signal up into single-bit chunks
		sig.expand();

		// add each chunk to bit_usage_count, unless it is a constant
		for (auto &c : sig.chunks)
			if (c.wire != NULL)
				bit_usage_count[c]++;
	}

	// 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 seperate bits
		RTLIL::SigSpec sig = sigmap(wire);
		sig.expand();

		// for each bit (unless it is a constant):
		// check if it is used at least two times and add to stub_bits otherwise
		for (size_t i = 0; i < sig.chunks.size(); i++)
			if (sig.chunks[i].wire != NULL && (bit_usage_count[sig.chunks[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 (int(stub_bits.size()) == sig.width) {
			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") { }
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		// variables to mirror information from passed options
		bool report_bits = 0;

		log_header("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;
n>format( cipher.name, mode.name if mode else mode), _Reasons.UNSUPPORTED_CIPHER ) def create_symmetric_decryption_ctx(self, cipher, mode): for b in self._filtered_backends(CipherBackend): try: return b.create_symmetric_decryption_ctx(cipher, mode) except UnsupportedAlgorithm: pass raise UnsupportedAlgorithm( "cipher {0} in {1} mode is not supported by this backend.".format( cipher.name, mode.name if mode else mode), _Reasons.UNSUPPORTED_CIPHER ) def hash_supported(self, algorithm): return any( b.hash_supported(algorithm) for b in self._filtered_backends(HashBackend) ) def create_hash_ctx(self, algorithm): for b in self._filtered_backends(HashBackend): try: return b.create_hash_ctx(algorithm) except UnsupportedAlgorithm: pass raise UnsupportedAlgorithm( "{0} is not a supported hash on this backend.".format( algorithm.name), _Reasons.UNSUPPORTED_HASH ) def hmac_supported(self, algorithm): return any( b.hmac_supported(algorithm) for b in self._filtered_backends(HMACBackend) ) def create_hmac_ctx(self, key, algorithm): for b in self._filtered_backends(HMACBackend): try: return b.create_hmac_ctx(key, algorithm) except UnsupportedAlgorithm: pass raise UnsupportedAlgorithm( "{0} is not a supported hash on this backend.".format( algorithm.name), _Reasons.UNSUPPORTED_HASH ) def pbkdf2_hmac_supported(self, algorithm): return any( b.pbkdf2_hmac_supported(algorithm) for b in self._filtered_backends(PBKDF2HMACBackend) ) def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, key_material): for b in self._filtered_backends(PBKDF2HMACBackend): try: return b.derive_pbkdf2_hmac( algorithm, length, salt, iterations, key_material ) except UnsupportedAlgorithm: pass raise UnsupportedAlgorithm( "{0} is not a supported hash on this backend.".format( algorithm.name), _Reasons.UNSUPPORTED_HASH ) def generate_rsa_private_key(self, public_exponent, key_size): for b in self._filtered_backends(RSABackend): return b.generate_rsa_private_key(public_exponent, key_size) raise UnsupportedAlgorithm("RSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def generate_rsa_parameters_supported(self, public_exponent, key_size): for b in self._filtered_backends(RSABackend): return b.generate_rsa_parameters_supported( public_exponent, key_size ) raise UnsupportedAlgorithm("RSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def rsa_padding_supported(self, padding): for b in self._filtered_backends(RSABackend): return b.rsa_padding_supported(padding) raise UnsupportedAlgorithm("RSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def load_rsa_private_numbers(self, numbers): for b in self._filtered_backends(RSABackend): return b.load_rsa_private_numbers(numbers) raise UnsupportedAlgorithm("RSA is not supported by the backend", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def load_rsa_public_numbers(self, numbers): for b in self._filtered_backends(RSABackend): return b.load_rsa_public_numbers(numbers) raise UnsupportedAlgorithm("RSA is not supported by the backend", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def generate_dsa_parameters(self, key_size): for b in self._filtered_backends(DSABackend): return b.generate_dsa_parameters(key_size) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def generate_dsa_private_key(self, parameters): for b in self._filtered_backends(DSABackend): return b.generate_dsa_private_key(parameters) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def generate_dsa_private_key_and_parameters(self, key_size): for b in self._filtered_backends(DSABackend): return b.generate_dsa_private_key_and_parameters(key_size) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def dsa_hash_supported(self, algorithm): for b in self._filtered_backends(DSABackend): return b.dsa_hash_supported(algorithm) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def dsa_parameters_supported(self, p, q, g): for b in self._filtered_backends(DSABackend): return b.dsa_parameters_supported(p, q, g) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def load_dsa_public_numbers(self, numbers): for b in self._filtered_backends(DSABackend): return b.load_dsa_public_numbers(numbers) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def load_dsa_private_numbers(self, numbers): for b in self._filtered_backends(DSABackend): return b.load_dsa_private_numbers(numbers) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def load_dsa_parameter_numbers(self, numbers): for b in self._filtered_backends(DSABackend): return b.load_dsa_parameter_numbers(numbers) raise UnsupportedAlgorithm("DSA is not supported by the backend.", _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) def cmac_algorithm_supported(self, algorithm): return any( b.cmac_algorithm_supported(algorithm) for b in self._filtered_backends(CMACBackend) ) def create_cmac_ctx(self, algorithm): for b in self._filtered_backends(CMACBackend): try: return b.create_cmac_ctx(algorithm) except UnsupportedAlgorithm: pass raise UnsupportedAlgorithm("This backend does not support CMAC.", _Reasons.UNSUPPORTED_CIPHER) def elliptic_curve_supported(self, curve): return any( b.elliptic_curve_supported(curve) for b in self._filtered_backends(EllipticCurveBackend) ) def elliptic_curve_signature_algorithm_supported( self, signature_algorithm, curve ): return any( b.elliptic_curve_signature_algorithm_supported( signature_algorithm, curve ) for b in self._filtered_backends(EllipticCurveBackend) ) def generate_elliptic_curve_private_key(self, curve): for b in self._filtered_backends(EllipticCurveBackend): try: return b.generate_elliptic_curve_private_key(curve) except UnsupportedAlgorithm: continue raise UnsupportedAlgorithm( "This backend does not support this elliptic curve.", _Reasons.UNSUPPORTED_ELLIPTIC_CURVE ) def load_elliptic_curve_private_numbers(self, numbers): for b in self._filtered_backends(EllipticCurveBackend): try: return b.load_elliptic_curve_private_numbers(numbers) except UnsupportedAlgorithm: continue raise UnsupportedAlgorithm( "This backend does not support this elliptic curve.", _Reasons.UNSUPPORTED_ELLIPTIC_CURVE ) def load_elliptic_curve_public_numbers(self, numbers): for b in self._filtered_backends(EllipticCurveBackend): try: return b.load_elliptic_curve_public_numbers(numbers) except UnsupportedAlgorithm: continue raise UnsupportedAlgorithm( "This backend does not support this elliptic curve.", _Reasons.UNSUPPORTED_ELLIPTIC_CURVE ) def elliptic_curve_exchange_algorithm_supported(self, algorithm, curve): return any( b.elliptic_curve_exchange_algorithm_supported(algorithm, curve) for b in self._filtered_backends(EllipticCurveBackend) ) def load_pem_private_key(self, data, password): for b in self._filtered_backends(PEMSerializationBackend): return b.load_pem_private_key(data, password) raise UnsupportedAlgorithm( "This backend does not support this key serialization.", _Reasons.UNSUPPORTED_SERIALIZATION ) def load_pem_public_key(self, data): for b in self._filtered_backends(PEMSerializationBackend): return b.load_pem_public_key(data) raise UnsupportedAlgorithm( "This backend does not support this key serialization.", _Reasons.UNSUPPORTED_SERIALIZATION ) def load_der_private_key(self, data, password): for b in self._filtered_backends(DERSerializationBackend): return b.load_der_private_key(data, password) raise UnsupportedAlgorithm( "This backend does not support this key serialization.", _Reasons.UNSUPPORTED_SERIALIZATION ) def load_der_public_key(self, data): for b in self._filtered_backends(DERSerializationBackend): return b.load_der_public_key(data) raise UnsupportedAlgorithm( "This backend does not support this key serialization.", _Reasons.UNSUPPORTED_SERIALIZATION ) def load_pem_x509_certificate(self, data): for b in self._filtered_backends(X509Backend): return b.load_pem_x509_certificate(data) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def load_der_x509_certificate(self, data): for b in self._filtered_backends(X509Backend): return b.load_der_x509_certificate(data) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def load_pem_x509_crl(self, data): for b in self._filtered_backends(X509Backend): return b.load_pem_x509_crl(data) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def load_der_x509_crl(self, data): for b in self._filtered_backends(X509Backend): return b.load_der_x509_crl(data) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def load_der_x509_csr(self, data): for b in self._filtered_backends(X509Backend): return b.load_der_x509_csr(data) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def load_pem_x509_csr(self, data): for b in self._filtered_backends(X509Backend): return b.load_pem_x509_csr(data) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def create_x509_csr(self, builder, private_key, algorithm): for b in self._filtered_backends(X509Backend): return b.create_x509_csr(builder, private_key, algorithm) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def create_x509_certificate(self, builder, private_key, algorithm): for b in self._filtered_backends(X509Backend): return b.create_x509_certificate(builder, private_key, algorithm) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def create_x509_crl(self, builder, private_key, algorithm): for b in self._filtered_backends(X509Backend): return b.create_x509_crl(builder, private_key, algorithm) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 ) def create_x509_revoked_certificate(self, builder): for b in self._filtered_backends(X509Backend): return b.create_x509_revoked_certificate(builder) raise UnsupportedAlgorithm( "This backend does not support X.509.", _Reasons.UNSUPPORTED_X509 )