2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #ifndef PMGEN_GENERATE
21 #define PMGEN_GENERATE
23 #define GENERATE_PATTERN(pmclass, pattern) \
24 generate_pattern<pmclass>([](pmclass &pm, std::function<void()> f){ return pm.run_ ## pattern(f); }, #pmclass, #pattern, design)
26 void pmtest_addports(Module
*module
)
28 pool
<SigBit
> driven_bits
, used_bits
;
29 SigMap
sigmap(module
);
30 int icnt
= 0, ocnt
= 0;
32 for (auto cell
: module
->cells())
33 for (auto conn
: cell
->connections())
35 if (cell
->input(conn
.first
))
36 for (auto bit
: sigmap(conn
.second
))
37 used_bits
.insert(bit
);
38 if (cell
->output(conn
.first
))
39 for (auto bit
: sigmap(conn
.second
))
40 driven_bits
.insert(bit
);
43 for (auto wire
: vector
<Wire
*>(module
->wires()))
46 for (auto bit
: sigmap(wire
)) {
47 if (!used_bits
.count(bit
))
49 if (!driven_bits
.count(bit
))
53 Wire
*w
= module
->addWire(stringf("\\i%d", icnt
++), GetSize(ibits
));
55 module
->connect(ibits
, w
);
58 Wire
*w
= module
->addWire(stringf("\\o%d", ocnt
++), GetSize(obits
));
59 w
->port_output
= true;
60 module
->connect(w
, obits
);
64 module
->fixup_ports();
68 void generate_pattern(std::function
<void(pm
&,std::function
<void()>)> run
, const char *pmclass
, const char *pattern
, Design
*design
)
70 log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern
, pmclass
);
78 while (modcnt
< maxmodcnt
)
80 int submodcnt
= 0, itercnt
= 0, cellcnt
= 0;
81 Module
*mod
= design
->addModule(NEW_ID
);
83 while (modcnt
< maxmodcnt
&& submodcnt
< maxsubcnt
&& itercnt
++ < 1000)
85 if (timeout
++ > 10000)
86 log_error("pmgen generator is stuck: 10000 iterations with no matching module generated.\n");
88 pm
matcher(mod
, mod
->cells());
91 matcher
.rngseed
+= modcnt
;
93 matcher
.rngseed
+= submodcnt
;
95 matcher
.rngseed
+= itercnt
;
97 matcher
.rngseed
+= cellcnt
;
100 if (GetSize(mod
->cells()) != cellcnt
)
102 bool found_match
= false;
103 run(matcher
, [&](){ found_match
= true; });
104 cellcnt
= GetSize(mod
->cells());
107 Module
*m
= design
->addModule(stringf("\\pmtest_%s_%s_%05d",
108 pmclass
, pattern
, modcnt
++));
109 log("Creating module %s with %d cells.\n", log_id(m
), cellcnt
);
118 matcher
.generate_mode
= true;
119 run(matcher
, [](){});
122 if (submodcnt
&& maxsubcnt
< (1 << 16))
128 Module
*m
= design
->addModule(stringf("\\pmtest_%s_%s", pmclass
, pattern
));
129 log("Creating module %s with %d cells.\n", log_id(m
), GetSize(mods
));
130 for (auto mod
: mods
) {
131 Cell
*c
= m
->addCell(mod
->name
, mod
->name
);
132 for (auto port
: mod
->ports
) {
133 Wire
*w
= m
->addWire(NEW_ID
, GetSize(mod
->wire(port
)));