fixed a bug in subcircuit library with cells that have connections to itself
[yosys.git] / libs / subcircuit / test_large.spl
1 #!/usr/bin/env splrun
2
3 var idx = 0;
4 var count_nand = 0;
5 var count_nor = 0;
6
7 function makeNAND(net, id)
8 {
9 count_nand++;
10
11 net["${id}_VDD"] = "${id}_pa S";
12 net["${id}_VSS"] = "${id}_nb S";
13
14 net["${id}_A"] = "${id}_pa G";
15 net["${id}_B"] = "${id}_pb G";
16 net["${id}_Y"] = "${id}_pb D";
17
18 return <:>
19 : node ${id}_pa pmos S 1 D 1 G 1
20 : node ${id}_pb pmos S 1 D 1 G 1
21 : node ${id}_na nmos S 1 D 1 G 1
22 : node ${id}_nb nmos S 1 D 1 G 1
23 : connect ${id}_pa S ${id}_pb S
24 : connect ${id}_pa D ${id}_pb D
25 : connect ${id}_pa D ${id}_na D
26 : connect ${id}_na S ${id}_nb D
27 : connect ${id}_pa G ${id}_na G
28 : connect ${id}_pb G ${id}_nb G
29 </>;
30 }
31
32 function makeNOR(net, id)
33 {
34 count_nor++;
35
36 net["${id}_VDD"] = "${id}_pa S";
37 net["${id}_VSS"] = "${id}_nb S";
38
39 net["${id}_A"] = "${id}_pa G";
40 net["${id}_B"] = "${id}_pb G";
41 net["${id}_Y"] = "${id}_pb D";
42
43 return <:>
44 : node ${id}_pa pmos S 1 D 1 G 1
45 : node ${id}_pb pmos S 1 D 1 G 1
46 : node ${id}_na nmos S 1 D 1 G 1
47 : node ${id}_nb nmos S 1 D 1 G 1
48 : connect ${id}_pa D ${id}_pb S
49 : connect ${id}_pb D ${id}_na D
50 : connect ${id}_pb D ${id}_nb D
51 : connect ${id}_na S ${id}_nb S
52 : connect ${id}_pa G ${id}_na G
53 : connect ${id}_pb G ${id}_nb G
54 </>;
55 }
56
57 function makeGraph(seed, gates, primaryInputs, primaryOutputs)
58 {
59 srand(seed);
60
61 var code = "";
62 var net, vdd, vss, outputs;
63 var unusedOutpus;
64 for (var i = 0; i < gates; i++)
65 {
66 var id = fmt("G%d", idx++);
67 if (rand(2) == 0)
68 code ~= makeNAND(net, id);
69 else
70 code ~= makeNOR(net, id);
71
72 if (i == 0) {
73 vdd = net["${id}_VDD"];
74 vss = net["${id}_VSS"];
75 } else {
76 code ~= <:>
77 : connect $vdd ${net["${id}_VDD"]}
78 : connect $vss ${net["${id}_VSS"]}
79 </>;
80 }
81
82 var inIdx1 = rand((elementsof outputs) + 1);
83 if (inIdx1 < elementsof outputs) {
84 code ~= " connect ${outputs[inIdx1]} ${net["${id}_A"]}\n";
85 delete unusedOutpus[outputs[inIdx1]];
86 } else
87 push primaryInputs, net["${id}_A"];
88
89 var inIdx2 = rand((elementsof outputs) + 1);
90 if (inIdx2 < elementsof outputs) {
91 code ~= " connect ${outputs[inIdx2]} ${net["${id}_B"]}\n";
92 delete unusedOutpus[outputs[inIdx2]];
93 } else
94 push primaryInputs, net["${id}_B"];
95
96 unusedOutpus[net["${id}_Y"]] = 1;
97 push outputs, net["${id}_Y"];
98 }
99
100 foreach netDecl (unusedOutpus)
101 push primaryOutputs, netDecl;
102
103 return code;
104 }
105
106 function makeConnections(fromNets, toNets)
107 {
108 var code = "";
109 foreach[] toNet (toNets) {
110 var fromNet = fromNets[rand(elementsof fromNets)];
111 code != " connect $fromNet $toNet\n";
112 }
113 return code;
114 }
115
116 var numNodes;
117
118 write(<:>
119 : graph nand
120 <?spl var net = []; ?>
121 ${makeNAND(net, "nand")}
122 : extern ${net["nand_VDD"]}
123 : extern ${net["nand_VSS"]}
124 : extern ${net["nand_A"]}
125 : extern ${net["nand_B"]}
126 : extern ${net["nand_Y"]}
127 : endgraph
128 :
129 : graph nor
130 ${makeNOR(net, "nor")}
131 : extern ${net["nor_VDD"]}
132 : extern ${net["nor_VSS"]}
133 : extern ${net["nor_A"]}
134 : extern ${net["nor_B"]}
135 : extern ${net["nor_Y"]}
136 : endgraph
137 :
138 : graph needle_1
139 <?spl var ports; ?>
140 ${makeGraph(1, 100, ports, ports)}
141 <?spl numNodes["needle_1"] = idx*4; ?>
142 <spl:foreach var="[]net" list="ports">
143 : extern $net
144 </spl:foreach>
145 : endgraph
146 :
147 : graph needle_2
148 <?spl var ports; ?>
149 ${makeGraph(2, 200, ports, ports)}
150 <?spl numNodes["needle_2"] = idx*4; ?>
151 <spl:foreach var="[]net" list="ports">
152 : extern $net
153 </spl:foreach>
154 : endgraph
155 :
156 : graph needle_3
157 <?spl var ports; ?>
158 ${makeGraph(3, 300, ports, ports)}
159 <?spl numNodes["needle_3"] = idx*4; ?>
160 <spl:foreach var="[]net" list="ports">
161 : extern $net
162 </spl:foreach>
163 : endgraph
164 :
165 : graph haystack
166
167 <?spl count_nand=0; count_nor=0; ?>
168
169 <?spl var inPorts1, outPorts1; ?>
170 ${makeGraph(1, 100, inPorts1, outPorts1)}
171
172 <?spl var inPorts2, outPorts2; ?>
173 ${makeGraph(2, 200, inPorts2, outPorts2)}
174
175 <?spl var inPorts3, outPorts3; ?>
176 ${makeGraph(3, 300, inPorts3, outPorts3)}
177
178 <?spl var inPorts4, outPorts4; ?>
179 ${makeGraph(2, 200, inPorts4, outPorts4)}
180
181 <?spl var inPorts5, outPorts5; ?>
182 ${makeGraph(1, 100, inPorts5, outPorts5)}
183 <?spl numNodes["haystack"] = idx*4; ?>
184
185 ${makeConnections(outPorts1, inPorts2)}
186 ${makeConnections(outPorts2, inPorts3)}
187 ${makeConnections(outPorts3, inPorts4)}
188 ${makeConnections(outPorts4, inPorts5)}
189
190 : endgraph
191 :
192 : solve nand haystack false
193 : expect $count_nand
194 : clearoverlap
195 :
196 : solve nor haystack false
197 : expect $count_nor
198 : clearoverlap
199 :
200 : solve needle_1 haystack false
201 : expect 2
202 :
203 : solve needle_2 haystack false
204 : expect 2
205 :
206 : solve needle_3 haystack false
207 : expect 1
208 </>);
209
210 numNodes["haystack"] -= numNodes["needle_3"];
211 numNodes["needle_3"] -= numNodes["needle_2"];
212 numNodes["needle_2"] -= numNodes["needle_1"];
213
214 write(<:>
215 :
216 : # Needle_1: ${numNodes["needle_1"]} transistors
217 : # Needle_2: ${numNodes["needle_2"]} transistors
218 : # Needle_3: ${numNodes["needle_3"]} transistors
219 : # Haystack: ${numNodes["haystack"]} transistors
220 </>);
221