Merge pull request #949 from YosysHQ/clifford/pmux2shimprove
[yosys.git] / frontends / aiger / aigerparse.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 * Eddie Hung <eddie@fpgeh.com>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21 // [[CITE]] The AIGER And-Inverter Graph (AIG) Format Version 20071012
22 // Armin Biere. The AIGER And-Inverter Graph (AIG) Format Version 20071012. Technical Report 07/1, October 2011, FMV Reports Series, Institute for Formal Models and Verification, Johannes Kepler University, Altenbergerstr. 69, 4040 Linz, Austria.
23 // http://fmv.jku.at/papers/Biere-FMV-TR-07-1.pdf
24
25 #ifndef _WIN32
26 #include <libgen.h>
27 #endif
28 #include <array>
29
30 #include "kernel/yosys.h"
31 #include "kernel/sigtools.h"
32 #include "aigerparse.h"
33
34 YOSYS_NAMESPACE_BEGIN
35
36 #define log_debug log
37
38 AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name)
39 : design(design), f(f), clk_name(clk_name)
40 {
41 module = new RTLIL::Module;
42 module->name = module_name;
43 if (design->module(module->name))
44 log_error("Duplicate definition of module %s!\n", log_id(module->name));
45 }
46
47 void AigerReader::parse_aiger()
48 {
49 std::string header;
50 f >> header;
51 if (header != "aag" && header != "aig")
52 log_error("Unsupported AIGER file!\n");
53
54 // Parse rest of header
55 if (!(f >> M >> I >> L >> O >> A))
56 log_error("Invalid AIGER header\n");
57
58 // Optional values
59 B = C = J = F = 0;
60 for (auto &i : std::array<std::reference_wrapper<unsigned>,4>{B, C, J, F}) {
61 if (f.peek() != ' ') break;
62 if (!(f >> i))
63 log_error("Invalid AIGER header\n");
64 }
65
66 std::string line;
67 std::getline(f, line); // Ignore up to start of next line, as standard
68 // says anything that follows could be used for
69 // optional sections
70
71 log_debug("M=%u I=%u L=%u O=%u A=%u B=%u C=%u J=%u F=%u\n", M, I, L, O, A, B, C, J, F);
72
73 line_count = 1;
74
75 if (header == "aag")
76 parse_aiger_ascii();
77 else if (header == "aig")
78 parse_aiger_binary();
79 else
80 log_abort();
81
82 // Parse footer (symbol table, comments, etc.)
83 unsigned l1;
84 std::string s;
85 for (int c = f.peek(); c != EOF; c = f.peek(), ++line_count) {
86 if (c == 'i' || c == 'l' || c == 'o') {
87 f.ignore(1);
88 if (!(f >> l1 >> s))
89 log_error("Line %u cannot be interpreted as a symbol entry!\n", line_count);
90
91 if ((c == 'i' && l1 > inputs.size()) || (c == 'l' && l1 > latches.size()) || (c == 'o' && l1 > outputs.size()))
92 log_error("Line %u has invalid symbol position!\n", line_count);
93
94 RTLIL::Wire* wire;
95 if (c == 'i') wire = inputs[l1];
96 else if (c == 'l') wire = latches[l1];
97 else if (c == 'o') wire = outputs[l1];
98 else log_abort();
99
100 module->rename(wire, stringf("\\%s", s.c_str()));
101 }
102 else if (c == 'b' || c == 'j' || c == 'f') {
103 // TODO
104 }
105 else if (c == 'c') {
106 f.ignore(1);
107 if (f.peek() == '\n')
108 break;
109 // Else constraint (TODO)
110 }
111 else
112 log_error("Line %u: cannot interpret first character '%c'!\n", line_count, c);
113 std::getline(f, line); // Ignore up to start of next line
114 }
115
116 module->fixup_ports();
117 design->add(module);
118 }
119
120 static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned literal)
121 {
122 const unsigned variable = literal >> 1;
123 const bool invert = literal & 1;
124 RTLIL::IdString wire_name(stringf("\\n%d%s", variable, invert ? "_inv" : "")); // FIXME: is "_inv" the right suffix?
125 RTLIL::Wire *wire = module->wire(wire_name);
126 if (wire) return wire;
127 log_debug("Creating %s\n", wire_name.c_str());
128 wire = module->addWire(wire_name);
129 if (!invert) return wire;
130 RTLIL::IdString wire_inv_name(stringf("\\n%d", variable));
131 RTLIL::Wire *wire_inv = module->wire(wire_inv_name);
132 if (wire_inv) {
133 if (module->cell(wire_inv_name)) return wire;
134 }
135 else {
136 log_debug("Creating %s\n", wire_inv_name.c_str());
137 wire_inv = module->addWire(wire_inv_name);
138 }
139
140 log_debug("Creating %s = ~%s\n", wire_name.c_str(), wire_inv_name.c_str());
141 module->addNotGate(stringf("\\n%d_not", variable), wire_inv, wire); // FIXME: is "_not" the right suffix?
142
143 return wire;
144 }
145
146 void AigerReader::parse_aiger_ascii()
147 {
148 std::string line;
149 std::stringstream ss;
150
151 unsigned l1, l2, l3;
152
153 // Parse inputs
154 for (unsigned i = 0; i < I; ++i, ++line_count) {
155 if (!(f >> l1))
156 log_error("Line %u cannot be interpreted as an input!\n", line_count);
157 log_debug("%d is an input\n", l1);
158 log_assert(!(l1 & 1)); // TODO: Inputs can't be inverted?
159 RTLIL::Wire *wire = createWireIfNotExists(module, l1);
160 wire->port_input = true;
161 inputs.push_back(wire);
162 }
163
164 // Parse latches
165 RTLIL::Wire *clk_wire = nullptr;
166 if (L > 0) {
167 clk_wire = module->wire(clk_name);
168 log_assert(!clk_wire);
169 log_debug("Creating %s\n", clk_name.c_str());
170 clk_wire = module->addWire(clk_name);
171 clk_wire->port_input = true;
172 }
173 for (unsigned i = 0; i < L; ++i, ++line_count) {
174 if (!(f >> l1 >> l2))
175 log_error("Line %u cannot be interpreted as a latch!\n", line_count);
176 log_debug("%d %d is a latch\n", l1, l2);
177 log_assert(!(l1 & 1)); // TODO: Latch outputs can't be inverted?
178 RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
179 RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
180
181 module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
182
183 // Reset logic is optional in AIGER 1.9
184 if (f.peek() == ' ') {
185 if (!(f >> l3))
186 log_error("Line %u cannot be interpreted as a latch!\n", line_count);
187
188 if (l3 == 0 || l3 == 1)
189 q_wire->attributes["\\init"] = RTLIL::Const(l3);
190 else if (l3 == l1) {
191 //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
192 }
193 else
194 log_error("Line %u has invalid reset literal for latch!\n", line_count);
195 }
196 else {
197 // AIGER latches are assumed to be initialized to zero
198 q_wire->attributes["\\init"] = RTLIL::Const(0);
199 }
200 latches.push_back(q_wire);
201 }
202
203 // Parse outputs
204 for (unsigned i = 0; i < O; ++i, ++line_count) {
205 if (!(f >> l1))
206 log_error("Line %u cannot be interpreted as an output!\n", line_count);
207
208 log_debug("%d is an output\n", l1);
209 RTLIL::Wire *wire = createWireIfNotExists(module, l1);
210 wire->port_output = true;
211 outputs.push_back(wire);
212 }
213 std::getline(f, line); // Ignore up to start of next line
214
215 // TODO: Parse bad state properties
216 for (unsigned i = 0; i < B; ++i, ++line_count)
217 std::getline(f, line); // Ignore up to start of next line
218
219 // TODO: Parse invariant constraints
220 for (unsigned i = 0; i < C; ++i, ++line_count)
221 std::getline(f, line); // Ignore up to start of next line
222
223 // TODO: Parse justice properties
224 for (unsigned i = 0; i < J; ++i, ++line_count)
225 std::getline(f, line); // Ignore up to start of next line
226
227 // TODO: Parse fairness constraints
228 for (unsigned i = 0; i < F; ++i, ++line_count)
229 std::getline(f, line); // Ignore up to start of next line
230
231 // Parse AND
232 for (unsigned i = 0; i < A; ++i) {
233 if (!(f >> l1 >> l2 >> l3))
234 log_error("Line %u cannot be interpreted as an AND!\n", line_count);
235
236 log_debug("%d %d %d is an AND\n", l1, l2, l3);
237 log_assert(!(l1 & 1)); // TODO: Output of ANDs can't be inverted?
238 RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
239 RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
240 RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
241 module->addAndGate(NEW_ID, i1_wire, i2_wire, o_wire);
242 }
243 std::getline(f, line); // Ignore up to start of next line
244 }
245
246 static unsigned parse_next_delta_literal(std::istream &f, unsigned ref)
247 {
248 unsigned x = 0, i = 0;
249 unsigned char ch;
250 while ((ch = f.get()) & 0x80)
251 x |= (ch & 0x7f) << (7 * i++);
252 return ref - (x | (ch << (7 * i)));
253 }
254
255 void AigerReader::parse_aiger_binary()
256 {
257 unsigned l1, l2, l3;
258 std::string line;
259
260 // Parse inputs
261 for (unsigned i = 1; i <= I; ++i) {
262 RTLIL::Wire *wire = createWireIfNotExists(module, i << 1);
263 wire->port_input = true;
264 inputs.push_back(wire);
265 }
266
267 // Parse latches
268 RTLIL::Wire *clk_wire = nullptr;
269 if (L > 0) {
270 clk_wire = module->wire(clk_name);
271 log_assert(!clk_wire);
272 log_debug("Creating %s\n", clk_name.c_str());
273 clk_wire = module->addWire(clk_name);
274 clk_wire->port_input = true;
275 }
276 l1 = (I+1) * 2;
277 for (unsigned i = 0; i < L; ++i, ++line_count, l1 += 2) {
278 if (!(f >> l2))
279 log_error("Line %u cannot be interpreted as a latch!\n", line_count);
280 log_debug("%d %d is a latch\n", l1, l2);
281 RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
282 RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
283
284 module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
285
286 // Reset logic is optional in AIGER 1.9
287 if (f.peek() == ' ') {
288 if (!(f >> l3))
289 log_error("Line %u cannot be interpreted as a latch!\n", line_count);
290
291 if (l3 == 0 || l3 == 1)
292 q_wire->attributes["\\init"] = RTLIL::Const(l3);
293 else if (l3 == l1) {
294 //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
295 }
296 else
297 log_error("Line %u has invalid reset literal for latch!\n", line_count);
298 }
299 else {
300 // AIGER latches are assumed to be initialized to zero
301 q_wire->attributes["\\init"] = RTLIL::Const(0);
302 }
303 latches.push_back(q_wire);
304 }
305
306 // Parse outputs
307 for (unsigned i = 0; i < O; ++i, ++line_count) {
308 if (!(f >> l1))
309 log_error("Line %u cannot be interpreted as an output!\n", line_count);
310
311 log_debug("%d is an output\n", l1);
312 RTLIL::Wire *wire = createWireIfNotExists(module, l1);
313 wire->port_output = true;
314 outputs.push_back(wire);
315 }
316 std::getline(f, line); // Ignore up to start of next line
317
318 // TODO: Parse bad state properties
319 for (unsigned i = 0; i < B; ++i, ++line_count)
320 std::getline(f, line); // Ignore up to start of next line
321
322 // TODO: Parse invariant constraints
323 for (unsigned i = 0; i < C; ++i, ++line_count)
324 std::getline(f, line); // Ignore up to start of next line
325
326 // TODO: Parse justice properties
327 for (unsigned i = 0; i < J; ++i, ++line_count)
328 std::getline(f, line); // Ignore up to start of next line
329
330 // TODO: Parse fairness constraints
331 for (unsigned i = 0; i < F; ++i, ++line_count)
332 std::getline(f, line); // Ignore up to start of next line
333
334 // Parse AND
335 l1 = (I+L+1) << 1;
336 for (unsigned i = 0; i < A; ++i, ++line_count, l1 += 2) {
337 l2 = parse_next_delta_literal(f, l1);
338 l3 = parse_next_delta_literal(f, l2);
339
340 log_debug("%d %d %d is an AND\n", l1, l2, l3);
341 log_assert(!(l1 & 1)); // TODO: Output of ANDs can't be inverted?
342 RTLIL::Wire *o_wire = createWireIfNotExists(module, l1);
343 RTLIL::Wire *i1_wire = createWireIfNotExists(module, l2);
344 RTLIL::Wire *i2_wire = createWireIfNotExists(module, l3);
345
346 RTLIL::Cell *and_cell = module->addCell(NEW_ID, "$_AND_");
347 and_cell->setPort("\\A", i1_wire);
348 and_cell->setPort("\\B", i2_wire);
349 and_cell->setPort("\\Y", o_wire);
350 }
351 }
352
353 struct AigerFrontend : public Frontend {
354 AigerFrontend() : Frontend("aiger", "read AIGER file") { }
355 void help() YS_OVERRIDE
356 {
357 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
358 log("\n");
359 log(" read_aiger [options] [filename]\n");
360 log("\n");
361 log("Load module from an AIGER file into the current design.\n");
362 log("\n");
363 log(" -module_name <module_name>\n");
364 log(" Name of module to be created (default: <filename>)"
365 #ifdef _WIN32
366 "top" // FIXME
367 #else
368 "<filename>"
369 #endif
370 ")\n");
371 log("\n");
372 log(" -clk_name <wire_name>\n");
373 log(" AIGER latches to be transformed into posedge DFFs clocked by wire of");
374 log(" this name (default: clk)\n");
375 log("\n");
376 }
377 void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
378 {
379 log_header(design, "Executing AIGER frontend.\n");
380
381 RTLIL::IdString clk_name = "\\clk";
382 RTLIL::IdString module_name;
383
384 size_t argidx;
385 for (argidx = 1; argidx < args.size(); argidx++) {
386 std::string arg = args[argidx];
387 if (arg == "-module_name" && argidx+1 < args.size()) {
388 module_name = RTLIL::escape_id(args[++argidx]);
389 continue;
390 }
391 if (arg == "-clk_name" && argidx+1 < args.size()) {
392 clk_name = RTLIL::escape_id(args[++argidx]);
393 continue;
394 }
395 break;
396 }
397 extra_args(f, filename, args, argidx);
398
399 if (module_name.empty()) {
400 #ifdef _WIN32
401 module_name = "top"; // FIXME: basename equivalent on Win32?
402 #else
403 char* bn = strdup(filename.c_str());
404 module_name = RTLIL::escape_id(bn);
405 free(bn);
406 #endif
407 }
408
409 AigerReader reader(design, *f, module_name, clk_name);
410 reader.parse_aiger();
411 }
412 } AigerFrontend;
413
414 YOSYS_NAMESPACE_END