30 std::map<RTLIL::Wire*, std::vector<RTLIL::SigBit>>
splitmap;
34 std::string new_wire_name = wire->
name.
str();
36 if (format.size() > 0)
37 new_wire_name += format.substr(0, 1);
40 new_wire_name +=
stringf(
"%d", offset+width-1);
41 if (format.size() > 2)
42 new_wire_name += format.substr(2, 1);
47 new_wire_name +=
stringf(
"%d", offset);
49 if (format.size() > 1)
50 new_wire_name += format.substr(1, 1);
65 bit =
splitmap.at(bit.wire).at(bit.offset);
75 log(
" splitnets [options] [selection]\n");
77 log(
"This command splits multi-bit nets into single-bit nets.\n");
79 log(
" -format char1[char2[char3]]\n");
80 log(
" the first char is inserted between the net name and the bit index, the\n");
81 log(
" second char is appended to the netname. e.g. -format () creates net\n");
82 log(
" names like 'mysignal(42)'. the 3rd character is the range separation\n");
83 log(
" character when creating multi-bit wires. the default is '[]:'.\n");
86 log(
" also split module ports. per default only internal signals are split.\n");
89 log(
" don't blindly split nets in individual bits. instead look at the driver\n");
90 log(
" and split nets so that no driver drives only part of a net.\n");
95 bool flag_ports =
false;
96 bool flag_driver =
false;
97 std::string format =
"[]:";
99 log_header(
"Executing SPLITNETS pass (splitting up multi-bit signals).\n");
102 for (argidx = 1; argidx < args.size(); argidx++)
104 if (args[argidx] ==
"-format" && argidx+1 < args.size()) {
105 format = args[++argidx];
108 if (args[argidx] ==
"-ports") {
112 if (args[argidx] ==
"-driver") {
120 for (
auto &mod_it : design->
modules_)
132 std::map<RTLIL::Wire*, std::set<int>> split_wires_at;
134 for (
auto &c : module->
cells_)
135 for (
auto &p : c.second->connections())
143 for (
auto &chunk : sig.
chunks()) {
144 if (chunk.wire ==
NULL)
146 if (chunk.wire->port_id == 0 || flag_ports) {
147 if (chunk.offset != 0)
148 split_wires_at[chunk.wire].insert(chunk.offset);
149 if (chunk.offset + chunk.width < chunk.wire->width)
150 split_wires_at[chunk.wire].insert(chunk.offset + chunk.width);
155 for (
auto &it : split_wires_at) {
157 for (
int next_cursor : it.second) {
158 worker.
append_wire(module, it.first, cursor, next_cursor - cursor, format);
159 cursor = next_cursor;
161 worker.
append_wire(module, it.first, cursor, it.first->width - cursor, format);
166 for (
auto &w : module->
wires_) {
168 if (wire->
width > 1 && (wire->
port_id == 0 || flag_ports) && design->
selected(module, w.second))
169 worker.
splitmap[wire] = std::vector<RTLIL::SigBit>();
173 for (
int i = 0; i < it.first->width; i++)
174 worker.
append_wire(module, it.first, i, 1, format);
179 std::set<RTLIL::Wire*> delete_wires;
181 delete_wires.insert(it.first);
182 module->
remove(delete_wires);
std::map< RTLIL::Wire *, std::vector< RTLIL::SigBit > > splitmap
bool selected(T1 *module) const
std::string stringf(const char *fmt,...)
void log_header(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
void rewrite_sigspecs(T functor)
bool cell_known(RTLIL::IdString type)
#define PRIVATE_NAMESPACE_BEGIN
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
void append_wire(RTLIL::Module *module, RTLIL::Wire *wire, int offset, int width, std::string format)
#define PRIVATE_NAMESPACE_END
SplitnetsPass SplitnetsPass
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
#define USING_YOSYS_NAMESPACE
std::map< RTLIL::IdString, RTLIL::Module * > modules_
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
void remove(const std::set< RTLIL::Wire * > &wires)
RTLIL::IdString uniquify(RTLIL::IdString name)
void log(const char *format,...)
void operator()(RTLIL::SigSpec &sig)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
std::vector< RTLIL::SigBit > to_sigbit_vector() const
const std::vector< RTLIL::SigChunk > & chunks() const