HAL
verilog_parser.cpp
Go to the documentation of this file.
2 
3 #include "netlist_test_utils.h"
4 #include "gate_library_test_utils.h"
5 
6 #include <bitset>
7 #include <filesystem>
8 
9 namespace hal {
10 
11  class VerilogParserTest : public ::testing::Test {
12  protected:
13  virtual void SetUp()
14  {
15  NO_COUT_BLOCK;
16  test_utils::init_log_channels();
17  test_utils::create_sandbox_directory();
18  }
19 
20  virtual void TearDown()
21  {
22  test_utils::remove_sandbox_directory();
23  }
24  };
25 
26  /* net_0
27  * .--= INV (0) =------.
28  * net_global_in | '-= net_global_out
29  * ------------| .-= AND3 (2) = ----------
30  * | | =
31  * +--= |
32  * | AND2 (1) =-----'
33  * '--= net_1
34  */
41  TEST_F(VerilogParserTest, check_main_example)
42  {
43  TEST_START
44  {
45  std::string netlist_input("module top ("
46  " net_global_in,"
47  " net_global_out "
48  " ) ;"
49  " input net_global_in ;"
50  " output net_global_out ;"
51  " wire net_0 ;"
52  " wire net_1 ;"
53  "BUF gate_0 ("
54  " .I (net_global_in ),"
55  " .O (net_0 )"
56  " ) ;"
57  "AND2 gate_1 ("
58  " .I0 (net_global_in ),"
59  " .I1 (net_global_in ),"
60  " .O (net_1 )"
61  " ) ;"
62  "AND3 gate_2 ("
63  " .I0 (net_0 ),"
64  " .I1 (net_1 ),"
65  " .O (net_global_out )"
66  " ) ;"
67  "endmodule");
68  const GateLibrary* gate_lib = test_utils::get_gate_library();
69  std::filesystem::path verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
70  VerilogParser verilog_parser;
71  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
72  ASSERT_TRUE(nl_res.is_ok());
73  std::unique_ptr<Netlist> nl = nl_res.get();
74  ASSERT_NE(nl, nullptr);
75 
76  // Check if the gates are parsed correctly
77  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("BUF")).size(), 1);
78  Gate* gate_0 = *(nl->get_gates(test_utils::gate_type_filter("BUF")).begin());
79  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("AND2")).size(), 1);
80  Gate* gate_1 = *(nl->get_gates(test_utils::gate_type_filter("AND2")).begin());
81  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("AND3")).size(), 1);
82  Gate* gate_2 = *(nl->get_gates(test_utils::gate_type_filter("AND3")).begin());
83 
84  ASSERT_NE(gate_0, nullptr);
85  EXPECT_EQ(gate_0->get_name(), "gate_0");
86 
87  ASSERT_NE(gate_1, nullptr);
88  EXPECT_EQ(gate_1->get_name(), "gate_1");
89 
90  ASSERT_NE(gate_2, nullptr);
91  EXPECT_EQ(gate_2->get_name(), "gate_2");
92 
93  // Check if the nets are parsed correctly
94  Net* net_0 = *(nl->get_nets(test_utils::net_name_filter("net_0")).begin());
95  Net* net_1 = *(nl->get_nets(test_utils::net_name_filter("net_1")).begin());
96  Net*
97  net_global_in = *(nl->get_nets(test_utils::net_name_filter("net_global_in")).begin());
98  Net*
99  net_global_out = *(nl->get_nets(test_utils::net_name_filter("net_global_out")).begin());
100 
101  ASSERT_NE(net_0, nullptr);
102  EXPECT_EQ(net_0->get_name(), "net_0");
103  ASSERT_EQ(net_0->get_sources().size(), 1);
104  EXPECT_EQ(net_0->get_sources()[0], test_utils::get_endpoint(gate_0, "O"));
105  std::vector<Endpoint*> exp_net_0_dsts = {test_utils::get_endpoint(gate_2, "I0")};
107  std::vector<Endpoint*>({test_utils::get_endpoint(gate_2,
108  "I0")})));
109 
110  ASSERT_NE(net_1, nullptr);
111  EXPECT_EQ(net_1->get_name(), "net_1");
112  ASSERT_EQ(net_1->get_sources().size(), 1);
113  EXPECT_EQ(net_1->get_sources()[0], test_utils::get_endpoint(gate_1, "O"));
115  std::vector<Endpoint*>({test_utils::get_endpoint(gate_2,
116  "I1")})));
117 
118  ASSERT_NE(net_global_in, nullptr);
119  EXPECT_EQ(net_global_in->get_name(), "net_global_in");
120  EXPECT_EQ(net_global_in->get_sources().size(), 0);
121  EXPECT_TRUE(test_utils::vectors_have_same_content(net_global_in->get_destinations(),
122  std::vector<Endpoint*>({test_utils::get_endpoint(gate_0,
123  "I"),
124  test_utils::get_endpoint(gate_1,
125  "I0"),
126  test_utils::get_endpoint(gate_1,
127  "I1")})));
128  EXPECT_TRUE(nl->is_global_input_net(net_global_in));
129 
130  ASSERT_NE(net_global_out, nullptr);
131  EXPECT_EQ(net_global_out->get_name(), "net_global_out");
132  ASSERT_EQ(net_global_out->get_sources().size(), 1);
133  EXPECT_EQ(net_global_out->get_sources()[0], test_utils::get_endpoint(gate_2, "O"));
134  EXPECT_TRUE(net_global_out->get_destinations().empty());
135  EXPECT_TRUE(nl->is_global_output_net(net_global_out));
136 
137  EXPECT_EQ(nl->get_global_input_nets().size(), 1);
138  EXPECT_EQ(nl->get_global_output_nets().size(), 1);
139  }
140  TEST_END
141  }
142 
148  TEST_F(VerilogParserTest, check_whitespace_chaos)
149  {
150  TEST_START
151  {
152  std::string netlist_input("module top(net_global_in,net_global_out);input net_global_in;\n"
153  " output net_global_out;wire net_0;wire net_1;BUF gate_0 (\n"
154  " .I (net_global_in),\n"
155  "\n"
156  " \t.O (net_0 )\n"
157  " );\n"
158  "AND2 gate_1 (.I0\n\t"
159  " (\n"
160  " net_global_in\n"
161  " \t)\n"
162  " ,\n"
163  " .I1 (net_global_in),.O (net_1));\n"
164  "AND3 gate_2 (.I0 (net_0 ),.I1 (net_1 ),.O (net_global_out ));endmodule");
165  const GateLibrary* gate_lib = test_utils::get_gate_library();
166  std::filesystem::path verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
167  VerilogParser verilog_parser;
168  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
169  ASSERT_TRUE(nl_res.is_ok());
170  std::unique_ptr<Netlist> nl = nl_res.get();
171  ASSERT_NE(nl, nullptr);
172 
173  // Check if the gates are parsed correctly
174  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("BUF")).size(), 1);
175  Gate* gate_0 = *(nl->get_gates(test_utils::gate_type_filter("BUF")).begin());
176  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("AND2")).size(), 1);
177  Gate* gate_1 = *(nl->get_gates(test_utils::gate_type_filter("AND2")).begin());
178  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("AND3")).size(), 1);
179  Gate* gate_2 = *(nl->get_gates(test_utils::gate_type_filter("AND3")).begin());
180 
181  ASSERT_NE(gate_0, nullptr);
182  EXPECT_EQ(gate_0->get_name(), "gate_0");
183 
184  ASSERT_NE(gate_1, nullptr);
185  EXPECT_EQ(gate_1->get_name(), "gate_1");
186 
187  ASSERT_NE(gate_2, nullptr);
188  EXPECT_EQ(gate_2->get_name(), "gate_2");
189 
190  // Check if the nets are parsed correctly
191  Net* net_0 = *(nl->get_nets(test_utils::net_name_filter("net_0")).begin());
192  Net* net_1 = *(nl->get_nets(test_utils::net_name_filter("net_1")).begin());
193  Net* net_global_in = *(nl->get_nets(test_utils::net_name_filter("net_global_in")).begin());
194  Net* net_global_out = *(nl->get_nets(test_utils::net_name_filter("net_global_out")).begin());
195 
196  ASSERT_NE(net_0, nullptr);
197  EXPECT_EQ(net_0->get_name(), "net_0");
198  ASSERT_EQ(net_0->get_sources().size(), 1);
199  EXPECT_EQ(net_0->get_sources()[0], test_utils::get_endpoint(gate_0, "O"));
200  std::vector<Endpoint*> exp_net_0_dsts = {test_utils::get_endpoint(gate_2, "I0")};
201  EXPECT_TRUE(test_utils::vectors_have_same_content(net_0->get_destinations(), std::vector<Endpoint*>({test_utils::get_endpoint(gate_2, "I0")})));
202 
203  ASSERT_NE(net_1, nullptr);
204  EXPECT_EQ(net_1->get_name(), "net_1");
205  ASSERT_EQ(net_1->get_sources().size(), 1);
206  EXPECT_EQ(net_1->get_sources()[0], test_utils::get_endpoint(gate_1, "O"));
207  EXPECT_TRUE(test_utils::vectors_have_same_content(net_1->get_destinations(), std::vector<Endpoint*>({test_utils::get_endpoint(gate_2, "I1")})));
208 
209  ASSERT_NE(net_global_in, nullptr);
210  EXPECT_EQ(net_global_in->get_name(), "net_global_in");
211  EXPECT_EQ(net_global_in->get_sources().size(), 0);
212  EXPECT_TRUE(test_utils::vectors_have_same_content(net_global_in->get_destinations(), std::vector<Endpoint*>({test_utils::get_endpoint(gate_0, "I"),
213  test_utils::get_endpoint(gate_1, "I0"),
214  test_utils::get_endpoint(gate_1, "I1")})));
215  EXPECT_TRUE(nl->is_global_input_net(net_global_in));
216 
217  ASSERT_NE(net_global_out, nullptr);
218  EXPECT_EQ(net_global_out->get_name(), "net_global_out");
219  ASSERT_EQ(net_global_out->get_sources().size(), 1);
220  EXPECT_EQ(net_global_out->get_sources()[0], test_utils::get_endpoint(gate_2, "O"));
221  EXPECT_TRUE(net_global_out->get_destinations().empty());
222  EXPECT_TRUE(nl->is_global_output_net(net_global_out));
223 
224  EXPECT_EQ(nl->get_global_input_nets().size(), 1);
225  EXPECT_EQ(nl->get_global_output_nets().size(), 1);
226  }
227  TEST_END
228  }
229 
235  TEST_F(VerilogParserTest, check_pins)
236  {
237  TEST_START
238  {
240 
241  std::string netlist_input( "module top (a, b, c, d); "
242  " input a, b;"
243  " output c, d;"
244  ""
245  " AND2 gate_0 ("
246  " .I0 (a),"
247  " .I1 (b),"
248  " .O (c)"
249  " );"
250  ""
251  " OR2 gate_1 ("
252  " .I0 (a),"
253  " .I1 (b),"
254  " .O (d)"
255  " );"
256  "endmodule");
257 
258  const GateLibrary* gate_lib = test_utils::get_gate_library();
259  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
260  VerilogParser verilog_parser;
261  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
262  ASSERT_TRUE(nl_res.is_ok());
263  std::unique_ptr<Netlist> nl = nl_res.get();
264  ASSERT_NE(nl, nullptr);
265 
266  EXPECT_EQ(nl->get_gates().size(), 2);
267  EXPECT_EQ(nl->get_nets().size(), 4);
268  EXPECT_EQ(nl->get_modules().size(), 1);
269 
270  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).size(), 1);
271  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).front();
272  Endpoint* ep_g0_net_a = gate_0->get_fan_in_endpoint("I0");
273  Endpoint* ep_g0_net_b = gate_0->get_fan_in_endpoint("I1");
274  Endpoint* ep_g0_net_c = gate_0->get_fan_out_endpoint("O");
275  ASSERT_NE(ep_g0_net_a, nullptr);
276  ASSERT_NE(ep_g0_net_b, nullptr);
277  ASSERT_NE(ep_g0_net_c, nullptr);
278  Net* net_g0_a = ep_g0_net_a->get_net();
279  Net* net_g0_b = ep_g0_net_b->get_net();
280  Net* net_g0_c = ep_g0_net_c->get_net();
281  ASSERT_NE(net_g0_a, nullptr);
282  ASSERT_NE(net_g0_b, nullptr);
283  ASSERT_NE(net_g0_c, nullptr);
284  EXPECT_EQ(net_g0_a->get_name(), "a");
285  EXPECT_EQ(net_g0_b->get_name(), "b");
286  EXPECT_EQ(net_g0_c->get_name(), "c");
287 
288  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).size(), 1);
289  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).front();
290  Endpoint* ep_g1_net_a = gate_1->get_fan_in_endpoint("I0");
291  Endpoint* ep_g1_net_b = gate_1->get_fan_in_endpoint("I1");
292  Endpoint* ep_g1_net_d = gate_1->get_fan_out_endpoint("O");
293  ASSERT_NE(ep_g1_net_a, nullptr);
294  ASSERT_NE(ep_g1_net_b, nullptr);
295  ASSERT_NE(ep_g1_net_d, nullptr);
296  Net* net_g1_a = ep_g1_net_a->get_net();
297  Net* net_g1_b = ep_g1_net_b->get_net();
298  Net* net_g1_d = ep_g1_net_d->get_net();
299  ASSERT_NE(net_g1_a, nullptr);
300  ASSERT_NE(net_g1_b, nullptr);
301  ASSERT_NE(net_g1_d, nullptr);
302  EXPECT_EQ(net_g1_a->get_name(), "a");
303  EXPECT_EQ(net_g1_b->get_name(), "b");
304  EXPECT_EQ(net_g1_d->get_name(), "d");
305 
306  ASSERT_EQ(net_g0_a, net_g1_a);
307  ASSERT_EQ(net_g0_b, net_g1_b);
308 
309  Net* net_a = net_g0_a;
310  Net* net_b = net_g0_b;
311  Net* net_c = net_g0_c;
312  Net* net_d = net_g1_d;
313 
314  Module* top = nl->get_top_module();
315  ASSERT_NE(top, nullptr);
316  EXPECT_TRUE(top->is_input_net(net_a));
317  EXPECT_TRUE(top->is_input_net(net_b));
318  EXPECT_TRUE(top->is_output_net(net_c));
319  EXPECT_TRUE(top->is_output_net(net_d));
320 
321  EXPECT_TRUE(net_a->is_global_input_net());
322  EXPECT_TRUE(net_b->is_global_input_net());
323  EXPECT_TRUE(net_c->is_global_output_net());
324  EXPECT_TRUE(net_d->is_global_output_net());
325  }
326  {
328 
329  std::string netlist_input( "module top (input a, b, output c, d); "
330  ""
331  " AND2 gate_0 ("
332  " .I0 (a),"
333  " .I1 (b),"
334  " .O (c)"
335  " );"
336  ""
337  " OR2 gate_1 ("
338  " .I0 (a),"
339  " .I1 (b),"
340  " .O (d)"
341  " );"
342  "endmodule");
343 
344  const GateLibrary* gate_lib = test_utils::get_gate_library();
345  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
346  VerilogParser verilog_parser;
347  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
348  ASSERT_TRUE(nl_res.is_ok());
349  std::unique_ptr<Netlist> nl = nl_res.get();
350  ASSERT_NE(nl, nullptr);
351 
352  EXPECT_EQ(nl->get_gates().size(), 2);
353  EXPECT_EQ(nl->get_nets().size(), 4);
354  EXPECT_EQ(nl->get_modules().size(), 1);
355 
356  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).size(), 1);
357  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).front();
358  Endpoint* ep_g0_net_a = gate_0->get_fan_in_endpoint("I0");
359  Endpoint* ep_g0_net_b = gate_0->get_fan_in_endpoint("I1");
360  Endpoint* ep_g0_net_c = gate_0->get_fan_out_endpoint("O");
361  ASSERT_NE(ep_g0_net_a, nullptr);
362  ASSERT_NE(ep_g0_net_b, nullptr);
363  ASSERT_NE(ep_g0_net_c, nullptr);
364  Net* net_g0_a = ep_g0_net_a->get_net();
365  Net* net_g0_b = ep_g0_net_b->get_net();
366  Net* net_g0_c = ep_g0_net_c->get_net();
367  ASSERT_NE(net_g0_a, nullptr);
368  ASSERT_NE(net_g0_b, nullptr);
369  ASSERT_NE(net_g0_c, nullptr);
370  EXPECT_EQ(net_g0_a->get_name(), "a");
371  EXPECT_EQ(net_g0_b->get_name(), "b");
372  EXPECT_EQ(net_g0_c->get_name(), "c");
373 
374  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).size(), 1);
375  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).front();
376  Endpoint* ep_g1_net_a = gate_1->get_fan_in_endpoint("I0");
377  Endpoint* ep_g1_net_b = gate_1->get_fan_in_endpoint("I1");
378  Endpoint* ep_g1_net_d = gate_1->get_fan_out_endpoint("O");
379  ASSERT_NE(ep_g1_net_a, nullptr);
380  ASSERT_NE(ep_g1_net_b, nullptr);
381  ASSERT_NE(ep_g1_net_d, nullptr);
382  Net* net_g1_a = ep_g1_net_a->get_net();
383  Net* net_g1_b = ep_g1_net_b->get_net();
384  Net* net_g1_d = ep_g1_net_d->get_net();
385  ASSERT_NE(net_g1_a, nullptr);
386  ASSERT_NE(net_g1_b, nullptr);
387  ASSERT_NE(net_g1_d, nullptr);
388  EXPECT_EQ(net_g1_a->get_name(), "a");
389  EXPECT_EQ(net_g1_b->get_name(), "b");
390  EXPECT_EQ(net_g1_d->get_name(), "d");
391 
392  ASSERT_EQ(net_g0_a, net_g1_a);
393  ASSERT_EQ(net_g0_b, net_g1_b);
394 
395  Net* net_a = net_g0_a;
396  Net* net_b = net_g0_b;
397  Net* net_c = net_g0_c;
398  Net* net_d = net_g1_d;
399 
400  Module* top = nl->get_top_module();
401  ASSERT_NE(top, nullptr);
402  EXPECT_TRUE(top->is_input_net(net_a));
403  EXPECT_TRUE(top->is_input_net(net_b));
404  EXPECT_TRUE(top->is_output_net(net_c));
405  EXPECT_TRUE(top->is_output_net(net_d));
406 
407  EXPECT_TRUE(net_a->is_global_input_net());
408  EXPECT_TRUE(net_b->is_global_input_net());
409  EXPECT_TRUE(net_c->is_global_output_net());
410  EXPECT_TRUE(net_d->is_global_output_net());
411  }
412  {
414 
415  std::string netlist_input( "module top (input a, b, output c, d); "
416  " wire a, b;"
417  " wire c, d;"
418  ""
419  " AND2 gate_0 ("
420  " .I0 (a),"
421  " .I1 (b),"
422  " .O (c)"
423  " );"
424  ""
425  " OR2 gate_1 ("
426  " .I0 (a),"
427  " .I1 (b),"
428  " .O (d)"
429  " );"
430  "endmodule");
431 
432  const GateLibrary* gate_lib = test_utils::get_gate_library();
433  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
434  VerilogParser verilog_parser;
435  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
436  ASSERT_TRUE(nl_res.is_ok());
437  std::unique_ptr<Netlist> nl = nl_res.get();
438  ASSERT_NE(nl, nullptr);
439 
440  EXPECT_EQ(nl->get_gates().size(), 2);
441  EXPECT_EQ(nl->get_nets().size(), 4);
442  EXPECT_EQ(nl->get_modules().size(), 1);
443 
444  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).size(), 1);
445  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).front();
446  Endpoint* ep_g0_net_a = gate_0->get_fan_in_endpoint("I0");
447  Endpoint* ep_g0_net_b = gate_0->get_fan_in_endpoint("I1");
448  Endpoint* ep_g0_net_c = gate_0->get_fan_out_endpoint("O");
449  ASSERT_NE(ep_g0_net_a, nullptr);
450  ASSERT_NE(ep_g0_net_b, nullptr);
451  ASSERT_NE(ep_g0_net_c, nullptr);
452  Net* net_g0_a = ep_g0_net_a->get_net();
453  Net* net_g0_b = ep_g0_net_b->get_net();
454  Net* net_g0_c = ep_g0_net_c->get_net();
455  ASSERT_NE(net_g0_a, nullptr);
456  ASSERT_NE(net_g0_b, nullptr);
457  ASSERT_NE(net_g0_c, nullptr);
458  EXPECT_EQ(net_g0_a->get_name(), "a");
459  EXPECT_EQ(net_g0_b->get_name(), "b");
460  EXPECT_EQ(net_g0_c->get_name(), "c");
461 
462  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).size(), 1);
463  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).front();
464  Endpoint* ep_g1_net_a = gate_1->get_fan_in_endpoint("I0");
465  Endpoint* ep_g1_net_b = gate_1->get_fan_in_endpoint("I1");
466  Endpoint* ep_g1_net_d = gate_1->get_fan_out_endpoint("O");
467  ASSERT_NE(ep_g1_net_a, nullptr);
468  ASSERT_NE(ep_g1_net_b, nullptr);
469  ASSERT_NE(ep_g1_net_d, nullptr);
470  Net* net_g1_a = ep_g1_net_a->get_net();
471  Net* net_g1_b = ep_g1_net_b->get_net();
472  Net* net_g1_d = ep_g1_net_d->get_net();
473  ASSERT_NE(net_g1_a, nullptr);
474  ASSERT_NE(net_g1_b, nullptr);
475  ASSERT_NE(net_g1_d, nullptr);
476  EXPECT_EQ(net_g1_a->get_name(), "a");
477  EXPECT_EQ(net_g1_b->get_name(), "b");
478  EXPECT_EQ(net_g1_d->get_name(), "d");
479 
480  ASSERT_EQ(net_g0_a, net_g1_a);
481  ASSERT_EQ(net_g0_b, net_g1_b);
482 
483  Net* net_a = net_g0_a;
484  Net* net_b = net_g0_b;
485  Net* net_c = net_g0_c;
486  Net* net_d = net_g1_d;
487 
488  Module* top = nl->get_top_module();
489  ASSERT_NE(top, nullptr);
490  EXPECT_TRUE(top->is_input_net(net_a));
491  EXPECT_TRUE(top->is_input_net(net_b));
492  EXPECT_TRUE(top->is_output_net(net_c));
493  EXPECT_TRUE(top->is_output_net(net_d));
494 
495  EXPECT_TRUE(net_a->is_global_input_net());
496  EXPECT_TRUE(net_b->is_global_input_net());
497  EXPECT_TRUE(net_c->is_global_output_net());
498  EXPECT_TRUE(net_d->is_global_output_net());
499  }
500  {
502 
503  std::string netlist_input( "module top (a, b, c, d); "
504  " input a, b;"
505  " output c, d;"
506  " wire a, b;"
507  " wire c, d;"
508  ""
509  " AND2 gate_0 ("
510  " .I0 (a),"
511  " .I1 (b),"
512  " .O (c)"
513  " );"
514  ""
515  " OR2 gate_1 ("
516  " .I0 (a),"
517  " .I1 (b),"
518  " .O (d)"
519  " );"
520  "endmodule");
521 
522  const GateLibrary* gate_lib = test_utils::get_gate_library();
523  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
524  VerilogParser verilog_parser;
525  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
526  ASSERT_TRUE(nl_res.is_ok());
527  std::unique_ptr<Netlist> nl = nl_res.get();
528  ASSERT_NE(nl, nullptr);
529 
530  EXPECT_EQ(nl->get_gates().size(), 2);
531  EXPECT_EQ(nl->get_nets().size(), 4);
532  EXPECT_EQ(nl->get_modules().size(), 1);
533 
534  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).size(), 1);
535  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).front();
536  Endpoint* ep_g0_net_a = gate_0->get_fan_in_endpoint("I0");
537  Endpoint* ep_g0_net_b = gate_0->get_fan_in_endpoint("I1");
538  Endpoint* ep_g0_net_c = gate_0->get_fan_out_endpoint("O");
539  ASSERT_NE(ep_g0_net_a, nullptr);
540  ASSERT_NE(ep_g0_net_b, nullptr);
541  ASSERT_NE(ep_g0_net_c, nullptr);
542  Net* net_g0_a = ep_g0_net_a->get_net();
543  Net* net_g0_b = ep_g0_net_b->get_net();
544  Net* net_g0_c = ep_g0_net_c->get_net();
545  ASSERT_NE(net_g0_a, nullptr);
546  ASSERT_NE(net_g0_b, nullptr);
547  ASSERT_NE(net_g0_c, nullptr);
548  EXPECT_EQ(net_g0_a->get_name(), "a");
549  EXPECT_EQ(net_g0_b->get_name(), "b");
550  EXPECT_EQ(net_g0_c->get_name(), "c");
551 
552  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).size(), 1);
553  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("OR2", "gate_1")).front();
554  Endpoint* ep_g1_net_a = gate_1->get_fan_in_endpoint("I0");
555  Endpoint* ep_g1_net_b = gate_1->get_fan_in_endpoint("I1");
556  Endpoint* ep_g1_net_d = gate_1->get_fan_out_endpoint("O");
557  ASSERT_NE(ep_g1_net_a, nullptr);
558  ASSERT_NE(ep_g1_net_b, nullptr);
559  ASSERT_NE(ep_g1_net_d, nullptr);
560  Net* net_g1_a = ep_g1_net_a->get_net();
561  Net* net_g1_b = ep_g1_net_b->get_net();
562  Net* net_g1_d = ep_g1_net_d->get_net();
563  ASSERT_NE(net_g1_a, nullptr);
564  ASSERT_NE(net_g1_b, nullptr);
565  ASSERT_NE(net_g1_d, nullptr);
566  EXPECT_EQ(net_g1_a->get_name(), "a");
567  EXPECT_EQ(net_g1_b->get_name(), "b");
568  EXPECT_EQ(net_g1_d->get_name(), "d");
569 
570  ASSERT_EQ(net_g0_a, net_g1_a);
571  ASSERT_EQ(net_g0_b, net_g1_b);
572 
573  Net* net_a = net_g0_a;
574  Net* net_b = net_g0_b;
575  Net* net_c = net_g0_c;
576  Net* net_d = net_g1_d;
577 
578  Module* top = nl->get_top_module();
579  ASSERT_NE(top, nullptr);
580  EXPECT_TRUE(top->is_input_net(net_a));
581  EXPECT_TRUE(top->is_input_net(net_b));
582  EXPECT_TRUE(top->is_output_net(net_c));
583  EXPECT_TRUE(top->is_output_net(net_d));
584 
585  EXPECT_TRUE(net_a->is_global_input_net());
586  EXPECT_TRUE(net_b->is_global_input_net());
587  EXPECT_TRUE(net_c->is_global_output_net());
588  EXPECT_TRUE(net_d->is_global_output_net());
589  }
590  TEST_END
591  }
592 
598  TEST_F(VerilogParserTest, check_pin_assignments) {
599 
600  TEST_START
601  { // test gate pin assignment by name
603 
604  std::string netlist_input(
605  "module top (a, b, c); "
606  " input a, b;"
607  " output c;"
608  ""
609  " AND2 gate_0 ("
610  " .I0 (a),"
611  " .I1 (b),"
612  " .O (c)"
613  " );"
614  ""
615  " AND2 gate_1 ("
616  " .I1 (b),"
617  " .O (c)"
618  " );"
619  ""
620  " AND2 gate_2 ("
621  " .O (c)"
622  " );"
623  "endmodule");
624 
625  const GateLibrary* gate_lib = test_utils::get_gate_library();
626  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
627  VerilogParser verilog_parser;
628  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
629  ASSERT_TRUE(nl_res.is_ok());
630  std::unique_ptr<Netlist> nl = nl_res.get();
631  ASSERT_NE(nl, nullptr);
632 
633  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).size(), 1);
634  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).front();
635  EXPECT_EQ(gate_0->get_fan_in_endpoint("I0")->get_net()->get_name(), "a");
636  EXPECT_EQ(gate_0->get_fan_in_endpoint("I1")->get_net()->get_name(), "b");
637  EXPECT_EQ(gate_0->get_fan_out_endpoint("O")->get_net()->get_name(), "c");
638 
639  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_1")).size(), 1);
640  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("AND2", "gate_1")).front();
641  EXPECT_EQ(gate_1->get_fan_in_endpoint("I0"), nullptr);
642  EXPECT_EQ(gate_1->get_fan_in_endpoint("I1")->get_net()->get_name(), "b");
643  EXPECT_EQ(gate_1->get_fan_out_endpoint("O")->get_net()->get_name(), "c");
644 
645  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_2")).size(), 1);
646  Gate* gate_2 = nl->get_gates(test_utils::gate_filter("AND2", "gate_2")).front();
647  EXPECT_EQ(gate_2->get_fan_in_endpoint("I0"), nullptr);
648  EXPECT_EQ(gate_2->get_fan_in_endpoint("I1"), nullptr);
649  EXPECT_EQ(gate_2->get_fan_out_endpoint("O")->get_net()->get_name(), "c");
650  }
651  { // test gate pin assignment by name with empty assignments
653 
654  std::string netlist_input(
655  "module top (a, b, c); "
656  " input a, b;"
657  " output c;"
658  ""
659  " AND2 gate_0 ("
660  " .I0 (a),"
661  " .I1 (b),"
662  " .O (c)"
663  " );"
664  ""
665  " AND2 gate_1 ("
666  " .I0 (),"
667  " .I1 (b),"
668  " .O (c)"
669  " );"
670  ""
671  " AND2 gate_2 ("
672  " .I0 (),"
673  " .I1 (),"
674  " .O (c)"
675  " );"
676  "endmodule");
677 
678  const GateLibrary* gate_lib = test_utils::get_gate_library();
679  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
680  VerilogParser verilog_parser;
681  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
682  ASSERT_TRUE(nl_res.is_ok());
683  std::unique_ptr<Netlist> nl = nl_res.get();
684  ASSERT_NE(nl, nullptr);
685 
686  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).size(), 1);
687  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).front();
688  EXPECT_EQ(gate_0->get_fan_in_endpoint("I0")->get_net()->get_name(), "a");
689  EXPECT_EQ(gate_0->get_fan_in_endpoint("I1")->get_net()->get_name(), "b");
690  EXPECT_EQ(gate_0->get_fan_out_endpoint("O")->get_net()->get_name(), "c");
691 
692  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_1")).size(), 1);
693  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("AND2", "gate_1")).front();
694  EXPECT_EQ(gate_1->get_fan_in_endpoint("I0"), nullptr);
695  EXPECT_EQ(gate_1->get_fan_in_endpoint("I1")->get_net()->get_name(), "b");
696  EXPECT_EQ(gate_1->get_fan_out_endpoint("O")->get_net()->get_name(), "c");
697 
698  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_2")).size(), 1);
699  Gate* gate_2 = nl->get_gates(test_utils::gate_filter("AND2", "gate_2")).front();
700  EXPECT_EQ(gate_2->get_fan_in_endpoint("I0"), nullptr);
701  EXPECT_EQ(gate_2->get_fan_in_endpoint("I1"), nullptr);
702  EXPECT_EQ(gate_2->get_fan_out_endpoint("O")->get_net()->get_name(), "c");
703  }
704  { // test gate pin assignment by order
706 
707  std::string netlist_input(
708  "module top (a, b, c); "
709  " input a, b;"
710  " output c;"
711  ""
712  " AND2 gate_0 (a, b, c);"
713  ""
714  " AND2 gate_1 (a, b);"
715  ""
716  " AND2 gate_2 (a);"
717  "endmodule");
718 
719  const GateLibrary* gate_lib = test_utils::get_gate_library();
720  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
721  VerilogParser verilog_parser;
722  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
723  ASSERT_TRUE(nl_res.is_ok());
724  std::unique_ptr<Netlist> nl = nl_res.get();
725  ASSERT_NE(nl, nullptr);
726 
727  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).size(), 1);
728  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("AND2", "gate_0")).front();
729  EXPECT_EQ(gate_0->get_fan_in_endpoint("I0")->get_net()->get_name(), "a");
730  EXPECT_EQ(gate_0->get_fan_in_endpoint("I1")->get_net()->get_name(), "b");
731  EXPECT_EQ(gate_0->get_fan_out_endpoint("O")->get_net()->get_name(), "c");
732 
733  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_1")).size(), 1);
734  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("AND2", "gate_1")).front();
735  EXPECT_EQ(gate_1->get_fan_in_endpoint("I0")->get_net()->get_name(), "a");
736  EXPECT_EQ(gate_1->get_fan_in_endpoint("I1")->get_net()->get_name(), "b");
737  EXPECT_EQ(gate_1->get_fan_out_endpoint("O"), nullptr);
738 
739  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND2", "gate_2")).size(), 1);
740  Gate* gate_2 = nl->get_gates(test_utils::gate_filter("AND2", "gate_2")).front();
741  EXPECT_EQ(gate_2->get_fan_in_endpoint("I0")->get_net()->get_name(), "a");
742  EXPECT_EQ(gate_2->get_fan_in_endpoint("I1"), nullptr);
743  EXPECT_EQ(gate_2->get_fan_out_endpoint("O"), nullptr);
744  }
745  { // test module pin assignment by name
747 
748  std::string netlist_input(
749  "module sub_mod (as, bs, cs);"
750  " input as, bs;"
751  " output cs;"
752  ""
753  " AND2 gate_0 ("
754  " .I0 (as),"
755  " .I1 (bs),"
756  " .O (cs)"
757  " );"
758  "endmodule"
759  "\n"
760  "module top (a, b, c); "
761  " input a, b;"
762  " output c;"
763  ""
764  " sub_mod inst_0 ("
765  " .as(a),"
766  " .bs(b),"
767  " .cs(c)"
768  " );"
769  ""
770  " sub_mod inst_1 ("
771  " .bs(b),"
772  " .cs(c)"
773  " );"
774  ""
775  " sub_mod inst_2 ("
776  " .cs(c)"
777  " );"
778  "endmodule"
779  );
780 
781  const GateLibrary* gate_lib = test_utils::get_gate_library();
782  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
783  VerilogParser verilog_parser;
784  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
785  ASSERT_TRUE(nl_res.is_ok());
786  std::unique_ptr<Netlist> nl = nl_res.get();
787  ASSERT_NE(nl, nullptr);
788 
789  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_0")).size(), 1);
790  Module* inst_0 = nl->get_modules(test_utils::module_name_filter("inst_0")).front();
791  const auto pins_0 = inst_0->get_pins();
792  EXPECT_EQ(pins_0.size(), 3);
793  EXPECT_EQ(pins_0.at(0)->get_name(), "as");
794  EXPECT_EQ(pins_0.at(0)->get_net()->get_name(), "a");
795  EXPECT_EQ(pins_0.at(1)->get_name(), "bs");
796  EXPECT_EQ(pins_0.at(1)->get_net()->get_name(), "b");
797  EXPECT_EQ(pins_0.at(2)->get_name(), "cs");
798  EXPECT_EQ(pins_0.at(2)->get_net()->get_name(), "c");
799 
800  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_1")).size(), 1);
801  Module* inst_1 = nl->get_modules(test_utils::module_name_filter("inst_1")).front();
802  const auto pins_1 = inst_1->get_pins();
803  EXPECT_EQ(pins_1.size(), 2);
804  EXPECT_EQ(pins_1.at(0)->get_name(), "bs");
805  EXPECT_EQ(pins_1.at(0)->get_net()->get_name(), "b");
806  EXPECT_EQ(pins_1.at(1)->get_name(), "cs");
807  EXPECT_EQ(pins_1.at(1)->get_net()->get_name(), "c");
808 
809  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_2")).size(), 1);
810  Module* inst_2 = nl->get_modules(test_utils::module_name_filter("inst_2")).front();
811  const auto pins_2 = inst_2->get_pins();
812  EXPECT_EQ(pins_2.size(), 1);
813  EXPECT_EQ(pins_2.at(0)->get_name(), "cs");
814  EXPECT_EQ(pins_2.at(0)->get_net()->get_name(), "c");
815  }
816  { // test module pin aliasing
818 
819  std::string netlist_input("module sub_mod (as, .bs(bs_int), cs);"
820  " input as, bs_int;"
821  " output cs;"
822  ""
823  " AND2 gate_0 ("
824  " .I0 (as),"
825  " .I1 (bs_int),"
826  " .O (cs)"
827  " );"
828  "endmodule"
829  "\n"
830  "module top (a, b, c); "
831  " input a, b;"
832  " output c;"
833  ""
834  " sub_mod inst_0 ("
835  " .as(a),"
836  " .bs(b),"
837  " .cs(c)"
838  " );"
839  ""
840  " sub_mod inst_1 ("
841  " .bs(b),"
842  " .cs(c)"
843  " );"
844  ""
845  " sub_mod inst_2 ("
846  " .cs(c)"
847  " );"
848  "endmodule");
849 
850  const GateLibrary* gate_lib = test_utils::get_gate_library();
851  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
852  VerilogParser verilog_parser;
853  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
854  ASSERT_TRUE(nl_res.is_ok());
855  std::unique_ptr<Netlist> nl = nl_res.get();
856  ASSERT_NE(nl, nullptr);
857 
858  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_0")).size(), 1);
859  Module* inst_0 = nl->get_modules(test_utils::module_name_filter("inst_0")).front();
860  const auto pins_0 = inst_0->get_pins();
861  EXPECT_EQ(pins_0.size(), 3);
862  EXPECT_EQ(pins_0.at(0)->get_name(), "as");
863  EXPECT_EQ(pins_0.at(0)->get_net()->get_name(), "a");
864  EXPECT_EQ(pins_0.at(1)->get_name(), "bs");
865  EXPECT_EQ(pins_0.at(1)->get_net()->get_name(), "b");
866  EXPECT_EQ(pins_0.at(2)->get_name(), "cs");
867  EXPECT_EQ(pins_0.at(2)->get_net()->get_name(), "c");
868 
869  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_1")).size(), 1);
870  Module* inst_1 = nl->get_modules(test_utils::module_name_filter("inst_1")).front();
871  const auto pins_1 = inst_1->get_pins();
872  EXPECT_EQ(pins_1.size(), 2);
873  EXPECT_EQ(pins_1.at(0)->get_name(), "bs");
874  EXPECT_EQ(pins_1.at(0)->get_net()->get_name(), "b");
875  EXPECT_EQ(pins_1.at(1)->get_name(), "cs");
876  EXPECT_EQ(pins_1.at(1)->get_net()->get_name(), "c");
877 
878  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_2")).size(), 1);
879  Module* inst_2 = nl->get_modules(test_utils::module_name_filter("inst_2")).front();
880  const auto pins_2 = inst_2->get_pins();
881  EXPECT_EQ(pins_2.size(), 1);
882  EXPECT_EQ(pins_2.at(0)->get_name(), "cs");
883  EXPECT_EQ(pins_2.at(0)->get_net()->get_name(), "c");
884  }
885  { // test module pin assignment by name with empty assignments
887 
888  std::string netlist_input(
889  "module sub_mod (as, bs, cs);"
890  " input as, bs;"
891  " output cs;"
892  ""
893  " AND2 gate_0 ("
894  " .I0 (as),"
895  " .I1 (bs),"
896  " .O (cs)"
897  " );"
898  "endmodule"
899  "\n"
900  "module top (a, b, c); "
901  " input a, b;"
902  " output c;"
903  ""
904  " sub_mod inst_0 ("
905  " .as(a),"
906  " .bs(b),"
907  " .cs(c)"
908  " );"
909  ""
910  " sub_mod inst_1 ("
911  " .as(),"
912  " .bs(b),"
913  " .cs(c)"
914  " );"
915  ""
916  " sub_mod inst_2 ("
917  " .as(),"
918  " .bs(),"
919  " .cs(c)"
920  " );"
921  "endmodule"
922  );
923 
924  const GateLibrary* gate_lib = test_utils::get_gate_library();
925  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
926  VerilogParser verilog_parser;
927  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
928  ASSERT_TRUE(nl_res.is_ok());
929  std::unique_ptr<Netlist> nl = nl_res.get();
930  ASSERT_NE(nl, nullptr);
931 
932  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_0")).size(), 1);
933  Module* inst_0 = nl->get_modules(test_utils::module_name_filter("inst_0")).front();
934  const auto pins_0 = inst_0->get_pins();
935  EXPECT_EQ(pins_0.size(), 3);
936  EXPECT_EQ(pins_0.at(0)->get_name(), "as");
937  EXPECT_EQ(pins_0.at(0)->get_net()->get_name(), "a");
938  EXPECT_EQ(pins_0.at(1)->get_name(), "bs");
939  EXPECT_EQ(pins_0.at(1)->get_net()->get_name(), "b");
940  EXPECT_EQ(pins_0.at(2)->get_name(), "cs");
941  EXPECT_EQ(pins_0.at(2)->get_net()->get_name(), "c");
942 
943  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_1")).size(), 1);
944  Module* inst_1 = nl->get_modules(test_utils::module_name_filter("inst_1")).front();
945  const auto pins_1 = inst_1->get_pins();
946  EXPECT_EQ(pins_1.size(), 2);
947  EXPECT_EQ(pins_1.at(0)->get_name(), "bs");
948  EXPECT_EQ(pins_1.at(0)->get_net()->get_name(), "b");
949  EXPECT_EQ(pins_1.at(1)->get_name(), "cs");
950  EXPECT_EQ(pins_1.at(1)->get_net()->get_name(), "c");
951 
952  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_2")).size(), 1);
953  Module* inst_2 = nl->get_modules(test_utils::module_name_filter("inst_2")).front();
954  const auto pins_2 = inst_2->get_pins();
955  EXPECT_EQ(pins_2.size(), 1);
956  EXPECT_EQ(pins_2.at(0)->get_name(), "cs");
957  EXPECT_EQ(pins_2.at(0)->get_net()->get_name(), "c");
958  }
959  { // test module pin assignment by order
961 
962  std::string netlist_input(
963  "module sub_mod (as, bs, cs);"
964  " input as, bs;"
965  " output cs;"
966  ""
967  " AND2 gate_0 (as, bs, cs);"
968  "endmodule"
969  "\n"
970  "module top (a, b, c); "
971  " input a, b;"
972  " output c;"
973  ""
974  " sub_mod inst_0 (a, b, c);"
975  ""
976  " sub_mod inst_1 (a, b);"
977  ""
978  " sub_mod inst_2 (a);"
979  "endmodule"
980  );
981 
982  const GateLibrary* gate_lib = test_utils::get_gate_library();
983  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
984  VerilogParser verilog_parser;
985  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
986  ASSERT_TRUE(nl_res.is_ok());
987  std::unique_ptr<Netlist> nl = nl_res.get();
988  ASSERT_NE(nl, nullptr);
989 
990  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_0")).size(), 1);
991  Module* inst_0 = nl->get_modules(test_utils::module_name_filter("inst_0")).front();
992  const auto pins_0 = inst_0->get_pins();
993  EXPECT_EQ(pins_0.size(), 3);
994  EXPECT_EQ(pins_0.at(0)->get_name(), "as");
995  EXPECT_EQ(pins_0.at(0)->get_net()->get_name(), "a");
996  EXPECT_EQ(pins_0.at(1)->get_name(), "bs");
997  EXPECT_EQ(pins_0.at(1)->get_net()->get_name(), "b");
998  EXPECT_EQ(pins_0.at(2)->get_name(), "cs");
999  EXPECT_EQ(pins_0.at(2)->get_net()->get_name(), "c");
1000 
1001  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_1")).size(), 1);
1002  Module* inst_1 = nl->get_modules(test_utils::module_name_filter("inst_1")).front();
1003  const auto pins_1 = inst_1->get_pins();
1004  EXPECT_EQ(pins_1.size(), 2);
1005  EXPECT_EQ(pins_1.at(0)->get_name(), "as");
1006  EXPECT_EQ(pins_1.at(0)->get_net()->get_name(), "a");
1007  EXPECT_EQ(pins_1.at(1)->get_name(), "bs");
1008  EXPECT_EQ(pins_1.at(1)->get_net()->get_name(), "b");
1009 
1010  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_2")).size(), 1);
1011  Module* inst_2 = nl->get_modules(test_utils::module_name_filter("inst_2")).front();
1012  const auto pins_2 = inst_2->get_pins();
1013  EXPECT_EQ(pins_2.size(), 1);
1014  EXPECT_EQ(pins_2.at(0)->get_name(), "as");
1015  EXPECT_EQ(pins_2.at(0)->get_net()->get_name(), "a");
1016  }
1017  { // test pass-through module
1019 
1020  std::string netlist_input(
1021  "module sub_sub_mod (ass, bss, css);"
1022  " input ass, bss;"
1023  " output css;"
1024  ""
1025  " AND2 gate_0 ("
1026  " .I0 (ass),"
1027  " .I1 (bss),"
1028  " .O (css)"
1029  " );"
1030  "endmodule"
1031  "\n"
1032  "module sub_mod (as, bs, cs);"
1033  " input as, bs;"
1034  " output cs;"
1035  ""
1036  " sub_sub_mod mid ("
1037  " .ass (as),"
1038  " .bss (bs),"
1039  " .css (cs)"
1040  " );"
1041  "endmodule"
1042  "\n"
1043  "module top (a, b, c); "
1044  " input a, b;"
1045  " output c;"
1046  ""
1047  " sub_mod inst_0 ("
1048  " .as(a),"
1049  " .bs(b),"
1050  " .cs(c)"
1051  " );"
1052  ""
1053  " sub_mod inst_1 ("
1054  " .bs(b),"
1055  " .cs(c)"
1056  " );"
1057  ""
1058  " sub_mod inst_2 ("
1059  " .cs(c)"
1060  " );"
1061  "endmodule"
1062  );
1063 
1064  const GateLibrary* gate_lib = test_utils::get_gate_library();
1065  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1066  VerilogParser verilog_parser;
1067  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1068  ASSERT_TRUE(nl_res.is_ok());
1069  std::unique_ptr<Netlist> nl = nl_res.get();
1070  ASSERT_NE(nl, nullptr);
1071 
1072  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_0")).size(), 1);
1073  Module* inst_0 = nl->get_modules(test_utils::module_name_filter("inst_0")).front();
1074  const auto pins_0 = inst_0->get_pins();
1075  EXPECT_EQ(pins_0.size(), 3);
1076  EXPECT_EQ(pins_0.at(0)->get_name(), "as");
1077  EXPECT_EQ(pins_0.at(0)->get_net()->get_name(), "a");
1078  EXPECT_EQ(pins_0.at(1)->get_name(), "bs");
1079  EXPECT_EQ(pins_0.at(1)->get_net()->get_name(), "b");
1080  EXPECT_EQ(pins_0.at(2)->get_name(), "cs");
1081  EXPECT_EQ(pins_0.at(2)->get_net()->get_name(), "c");
1082 
1083  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_1")).size(), 1);
1084  Module* inst_1 = nl->get_modules(test_utils::module_name_filter("inst_1")).front();
1085  const auto pins_1 = inst_1->get_pins();
1086  EXPECT_EQ(pins_1.size(), 2);
1087  EXPECT_EQ(pins_1.at(0)->get_name(), "bs");
1088  EXPECT_EQ(pins_1.at(0)->get_net()->get_name(), "b");
1089  EXPECT_EQ(pins_1.at(1)->get_name(), "cs");
1090  EXPECT_EQ(pins_1.at(1)->get_net()->get_name(), "c");
1091 
1092  ASSERT_EQ(nl->get_modules(test_utils::module_name_filter("inst_2")).size(), 1);
1093  Module* inst_2 = nl->get_modules(test_utils::module_name_filter("inst_2")).front();
1094  const auto pins_2 = inst_2->get_pins();
1095  EXPECT_EQ(pins_2.size(), 1);
1096  EXPECT_EQ(pins_2.at(0)->get_name(), "cs");
1097  EXPECT_EQ(pins_2.at(0)->get_net()->get_name(), "c");
1098  }
1099  TEST_END
1100  }
1101 
1108  TEST_F(VerilogParserTest, check_parameters)
1109  {
1110  TEST_START
1111  {
1112  // Store an instance of all possible data types in one Gate + some special cases
1113  std::string netlist_input("module top ("
1114  " global_in,"
1115  " global_out"
1116  " ) ;"
1117  " input global_in ;"
1118  " output global_out ;"
1119  "BUF #("
1120  ".key_integer(1234),"
1121  ".key_floating_point(1.234),"
1122  ".key_string(\"test_string\"),"
1123  ".key_bit_vector_hex('habc)," // All values are 'ABC' in hex
1124  ".key_bit_vector_dec('d2748),"
1125  ".key_bit_vector_oct('o5274),"
1126  ".key_bit_vector_bin('b1010_1011_1100),"
1127  ".key_negative_comma_string(\"test,1,2,3\"),"
1128  ".key_negative_float_string(\"1.234\")) "
1129  "gate_0 ("
1130  " .I (global_in ),"
1131  " .O (global_out )"
1132  " ) ;"
1133  "defparam gate_0.external_int = 3;"
1134  "endmodule");
1135  const GateLibrary* gate_lib = test_utils::get_gate_library();
1136  std::filesystem::path verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1137  VerilogParser verilog_parser;
1138  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1139  // std::cout << nl_res.get_error().get() << std::endl;
1140  ASSERT_TRUE(nl_res.is_ok());
1141  std::unique_ptr<Netlist> nl = nl_res.get();
1142  ASSERT_NE(nl, nullptr);
1143 
1144  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).size(), 1);
1145  Gate* gate_0 = *nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).begin();
1146 
1147  // Integers are stored in their hex representation
1148  EXPECT_EQ(gate_0->get_data("generic", "key_integer"), std::make_tuple("integer", "1234"));
1149  EXPECT_EQ(gate_0->get_data("generic", "key_floating_point"), std::make_tuple("floating_point", "1.234"));
1150  EXPECT_EQ(gate_0->get_data("generic", "key_string"), std::make_tuple("string", "test_string"));
1151  EXPECT_EQ(gate_0->get_data("generic", "key_bit_vector_hex"), std::make_tuple("bit_vector", "ABC"));
1152  EXPECT_EQ(gate_0->get_data("generic", "key_bit_vector_dec"), std::make_tuple("bit_vector", "ABC"));
1153  EXPECT_EQ(gate_0->get_data("generic", "key_bit_vector_oct"), std::make_tuple("bit_vector", "ABC"));
1154  EXPECT_EQ(gate_0->get_data("generic", "key_bit_vector_bin"), std::make_tuple("bit_vector", "ABC"));
1155  EXPECT_EQ(gate_0->get_data("generic", "external_int"), std::make_tuple("integer", "3"));
1156 
1157  // Special Characters
1158  EXPECT_EQ(gate_0->get_data("generic", "key_negative_comma_string"), std::make_tuple("string", "test,1,2,3"));
1159  EXPECT_EQ(gate_0->get_data("generic", "key_negative_float_string"), std::make_tuple("string", "1.234"));
1160  }
1161  {
1162  // Port map gets multiple nets (should only assign right-most one)
1163  std::string netlist_input("module top ("
1164  " global_in,"
1165  " global_out "
1166  " ) ;"
1167  " input global_in ;"
1168  " output global_out ;"
1169  " wire net_0;"
1170  "BUF gate_0 ("
1171  " .I ({net_0, global_in} )"
1172  " ) ;"
1173  "BUF gate_1 ("
1174  " .I (net_0 ),"
1175  " .O (global_out )"
1176  " ) ;"
1177  "endmodule");
1178  const GateLibrary* gate_lib = test_utils::get_gate_library();
1179  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1180  VerilogParser verilog_parser;
1181  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1182  ASSERT_TRUE(nl_res.is_ok());
1183  std::unique_ptr<Netlist> nl = nl_res.get();
1184 
1185  Gate* gate;
1186 
1187  ASSERT_NE(nl, nullptr);
1188  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).empty());
1189  gate = *(nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).begin());
1190 
1191  ASSERT_NE(gate->get_fan_in_net("I"), nullptr);
1192  EXPECT_EQ(gate->get_fan_in_net("I")->get_name(), "global_in");
1193  }
1194  TEST_END
1195  }
1196 
1202  TEST_F(VerilogParserTest, check_net_vectors) {
1203 
1204  TEST_START
1205  {
1206  // Use two logic vectors with dimension 1. One is declared with ascending indices, the other with
1207  // descending indices. ([0:3] and [3:0])
1208  /*
1209  * n_vec_1 n_vec_2
1210  * =-----------= =-----------=
1211  * =-----------= =-----------=
1212  * global_in ---= gate_0 =-----------= gate_1 =-----------= gate_2 =--- global_out
1213  * =-----------= =-----------=
1214  *
1215  */
1216 
1217  std::string netlist_input("module top ( "
1218  " global_in, "
1219  " global_out "
1220  " ) ; "
1221  " input global_in ; "
1222  " output global_out ; "
1223  " wire [0:3] n_vec_1 ; "
1224  " wire [3:0] n_vec_2 ; "
1225  " COMB14 gate_0 ( "
1226  " .I (global_in ), "
1227  " .O0 (n_vec_1[0]), "
1228  " .O1 (n_vec_1[1]), "
1229  " .O2 (n_vec_1[2]), "
1230  " .O3 (n_vec_1[3]) "
1231  " ) ; "
1232  " COMB44 gate_1 ( "
1233  " .I0 (n_vec_1[0]), "
1234  " .I1 (n_vec_1[1]), "
1235  " .I2 (n_vec_1[2]), "
1236  " .I3 (n_vec_1[3]), "
1237  " .O0 (n_vec_2[0]), "
1238  " .O1 (n_vec_2[1]), "
1239  " .O2 (n_vec_2[2]), "
1240  " .O3 (n_vec_2[3]) "
1241  " ) ; "
1242  " COMB41 gate_2 ( "
1243  " .I0 (n_vec_2[0]), "
1244  " .I1 (n_vec_2[1]), "
1245  " .I2 (n_vec_2[2]), "
1246  " .I3 (n_vec_2[3]), "
1247  " .O (global_out ) "
1248  " ) ; "
1249  "endmodule");
1250  const GateLibrary* gate_lib = test_utils::get_gate_library();
1251  std::filesystem::path verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1252  VerilogParser verilog_parser;
1253  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1254  ASSERT_TRUE(nl_res.is_ok());
1255  std::unique_ptr<Netlist> nl = nl_res.get();
1256  ASSERT_NE(nl, nullptr);
1257 
1258  // Check that all nets are created and connected correctly
1259  EXPECT_EQ(nl->get_nets().size(),
1260  10); // net_global_in + net_global_out + 4 nets in n_vec_1 + 4 nets in n_vec_2
1261  for (auto net_name : std::set<std::string>({"n_vec_1(0)", "n_vec_1(1)", "n_vec_1(2)", "n_vec_1(3)",
1262  "n_vec_2(0)", "n_vec_2(1)", "n_vec_2(2)", "n_vec_2(3)"})) {
1263  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter(net_name)).size(), 1);
1264  }
1265  for (unsigned i = 0; i < 4; i++) {
1266  std::string i_str = std::to_string(i);
1267  Net* n_vec_1_i = *nl->get_nets(test_utils::net_name_filter("n_vec_1(" + i_str + ")")).begin();
1268  Net* n_vec_2_i = *nl->get_nets(test_utils::net_name_filter("n_vec_2(" + i_str + ")")).begin();
1269  ASSERT_EQ(n_vec_1_i->get_sources().size(), 1);
1270  EXPECT_EQ(n_vec_1_i->get_sources()[0]->get_pin()->get_name(), "O" + i_str);
1271  EXPECT_EQ((*n_vec_1_i->get_destinations().begin())->get_pin()->get_name(), "I" + i_str);
1272  ASSERT_EQ(n_vec_2_i->get_sources().size(), 1);
1273  EXPECT_EQ(n_vec_2_i->get_sources()[0]->get_pin()->get_name(), "O" + i_str);
1274  EXPECT_EQ((*n_vec_2_i->get_destinations().begin())->get_pin()->get_name(), "I" + i_str);
1275  }
1276  }
1277  {
1278  // Use a logic vector of dimension two
1279  std::string netlist_input("module top ( "
1280  " global_in, "
1281  " global_out "
1282  " ) ; "
1283  " input global_in ; "
1284  " output global_out ; "
1285  " wire [0:1][2:3] n_vec ; "
1286  "COMB14 gate_0 ( "
1287  " .I (global_in ), "
1288  " .O0 (n_vec[0][2]), "
1289  " .O1 (n_vec[0][3]), "
1290  " .O2 (n_vec[1][2]), "
1291  " .O3 (n_vec[1][3]) "
1292  " ) ; "
1293  "COMB41 gate_1 ( "
1294  " .I0 (n_vec[0][2]), "
1295  " .I1 (n_vec[0][3]), "
1296  " .I2 (n_vec[1][2]), "
1297  " .I3 (n_vec[1][3]), "
1298  " .O (global_out ) "
1299  " ) ; "
1300  "endmodule");
1301  const GateLibrary* gate_lib = test_utils::get_gate_library();
1302  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1303  VerilogParser verilog_parser;
1304  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1305  ASSERT_TRUE(nl_res.is_ok());
1306  std::unique_ptr<Netlist> nl = nl_res.get();
1307  ASSERT_NE(nl, nullptr);
1308 
1309  // Check that all nets are created and connected correctly
1310  EXPECT_EQ(nl->get_nets().size(), 6); // net_global_in + global_out + 4 nets in n_vec
1311  unsigned pin = 0;
1312  for (auto n : std::vector<std::string>({"n_vec(0)(2)", "n_vec(0)(3)", "n_vec(1)(2)", "n_vec(1)(3)"})) {
1313  ASSERT_FALSE(nl->get_nets(test_utils::net_name_filter(n)).empty());
1314  Net* n_vec_i_j = *nl->get_nets(test_utils::net_name_filter(n)).begin();
1315  ASSERT_EQ(n_vec_i_j->get_sources().size(), 1);
1316  EXPECT_EQ(n_vec_i_j->get_sources()[0]->get_pin()->get_name(), "O" + std::to_string(pin));
1317  EXPECT_EQ((*n_vec_i_j->get_destinations().begin())->get_pin()->get_name(), "I" + std::to_string(pin));
1318  pin++;
1319  }
1320  }
1321  {
1322  // Use a Net vector of dimension three
1323  std::string netlist_input("module top ( "
1324  " global_in, "
1325  " global_out "
1326  " ) ; "
1327  " input global_in ; "
1328  " output global_out ; "
1329  " wire [0:1][1:0][0:1] n_vec ; "
1330  "COMB18 gate_0 ( "
1331  " .I (global_in ), "
1332  " .O0 (n_vec[0][0][0]), "
1333  " .O1 (n_vec[0][0][1]), "
1334  " .O2 (n_vec[0][1][0]), "
1335  " .O3 (n_vec[0][1][1]), "
1336  " .O4 (n_vec[1][0][0]), "
1337  " .O5 (n_vec[1][0][1]), "
1338  " .O6 (n_vec[1][1][0]), "
1339  " .O7 (n_vec[1][1][1]) "
1340  " ) ; "
1341  "COMB81 gate_1 ( "
1342  " .I0 (n_vec[0][0][0]), "
1343  " .I1 (n_vec[0][0][1]), "
1344  " .I2 (n_vec[0][1][0]), "
1345  " .I3 (n_vec[0][1][1]), "
1346  " .I4 (n_vec[1][0][0]), "
1347  " .I5 (n_vec[1][0][1]), "
1348  " .I6 (n_vec[1][1][0]), "
1349  " .I7 (n_vec[1][1][1]), "
1350  " .O (global_out ) "
1351  " ) ; "
1352  "endmodule");
1353  const GateLibrary* gate_lib = test_utils::get_gate_library();
1354  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1355  VerilogParser verilog_parser;
1356  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1357  ASSERT_TRUE(nl_res.is_ok());
1358  std::unique_ptr<Netlist> nl = nl_res.get();
1359  ASSERT_NE(nl, nullptr);
1360 
1361  // Check that all nets are created and connected correctly
1362  EXPECT_EQ(nl->get_nets().size(), 10); // net_global_in + net_global_out + 8 nets in n_vec
1363  std::vector<std::string> net_idx
1364  ({"(0)(0)(0)", "(0)(0)(1)", "(0)(1)(0)", "(0)(1)(1)", "(1)(0)(0)", "(1)(0)(1)", "(1)(1)(0)",
1365  "(1)(1)(1)"});
1366  for (size_t idx = 0; idx < 8; idx++)
1367  {
1368  ASSERT_FALSE(nl->get_nets(test_utils::net_name_filter("n_vec" + net_idx[idx])).empty());
1369  Net* n_vec_i_j = nl->get_nets(test_utils::net_name_filter("n_vec" + net_idx[idx])).front();
1370  ASSERT_EQ(n_vec_i_j->get_sources().size(), 1);
1371  EXPECT_EQ(n_vec_i_j->get_sources()[0]->get_pin()->get_name(), "O" + std::to_string(idx));
1372  EXPECT_EQ((*n_vec_i_j->get_destinations().begin())->get_pin()->get_name(), "I" + std::to_string(idx));
1373  }
1374  }
1375  TEST_END
1376  }
1377 
1383  TEST_F(VerilogParserTest, check_zero_padding) {
1384 
1385  TEST_START
1386  {
1388 
1389  std::string netlist_input(
1390  "module top ();\n "
1391  " wire [3:0] gate_0_in, gate_1_in;\n"
1392  " RAM gate_0 (\n "
1393  " .DATA_IN (gate_0_in ) \n"
1394  " ) ; \n"
1395  " RAM gate_1 (\n "
1396  " .DATA_IN (gate_1_in ) \n"
1397  " ) ;\n "
1398  " assign gate_0_in = 4'd0;\n"
1399  " assign gate_1_in = 1'd0;\n"
1400  "endmodule");
1401 
1402  const GateLibrary* gate_lib = test_utils::get_gate_library();
1403  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1404  VerilogParser verilog_parser;
1405  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1406  ASSERT_TRUE(nl_res.is_ok());
1407  std::unique_ptr<Netlist> nl = nl_res.get();
1408  ASSERT_NE(nl, nullptr);
1409 
1410  ASSERT_TRUE(!nl->get_gnd_gates().empty());
1411  EXPECT_EQ(nl->get_gnd_gates().front()->get_successors().size(), 8);
1412  for (Gate* gate : nl->get_gates([](const Gate* gate) { return !gate->is_gnd_gate(); }))
1413  {
1414  EXPECT_EQ(gate->get_fan_in_endpoints().size(), 4);
1415  for (Endpoint* ep : gate->get_fan_in_endpoints())
1416  {
1417  EXPECT_TRUE(ep->get_net()->is_gnd_net());
1418  }
1419  }
1420  }
1421  TEST_END
1422  }
1423 
1429  TEST_F(VerilogParserTest, check_special_nets) {
1430 
1431  TEST_START
1432  {
1433  std::string netlist_input("module top ("
1434  " global_out_0,"
1435  " global_out_1,"
1436  " global_out_2,"
1437  " global_out_3 "
1438  " ) ;"
1439  " output global_out_0 ;"
1440  " output global_out_1 ;"
1441  " output global_out_2 ;"
1442  " output global_out_3 ;"
1443  "BUF gate_0 ("
1444  " .I ('b0 ),"
1445  " .O (global_out_0)"
1446  " ) ;"
1447  "BUF gate_1 ("
1448  " .I ('b1 ),"
1449  " .O (global_out_1)"
1450  " ) ;"
1451  "BUF gate_2 ("
1452  " .I ('bZ ),"
1453  " .O (global_out_2)"
1454  " ) ;"
1455  "BUF gate_3 ("
1456  " .I ('bX ),"
1457  " .O (global_out_3)"
1458  " ) ;"
1459  "endmodule");
1460  const GateLibrary* gate_lib = test_utils::get_gate_library();
1461  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1462  VerilogParser verilog_parser;
1463  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1464  ASSERT_TRUE(nl_res.is_ok());
1465  std::unique_ptr<Netlist> nl = nl_res.get();
1466  ASSERT_NE(nl, nullptr);
1467 
1468  Gate* gate_0 = nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).front();
1469  ASSERT_NE(gate_0, nullptr);
1470  Gate* gate_1 = nl->get_gates(test_utils::gate_filter("BUF", "gate_1")).front();
1471  ASSERT_NE(gate_1, nullptr);
1472  Gate* gate_2 = nl->get_gates(test_utils::gate_filter("BUF", "gate_2")).front();
1473  ASSERT_NE(gate_2, nullptr);
1474  Gate* gate_3 = nl->get_gates(test_utils::gate_filter("BUF", "gate_3")).front();
1475  ASSERT_NE(gate_3, nullptr);
1476 
1477  // check whether net '0' was created and is connected to a GND gate through input pin "I"
1478  Net* net_gnd = gate_0->get_fan_in_net("I");
1479  ASSERT_NE(net_gnd, nullptr);
1480  EXPECT_EQ(net_gnd->get_name(), "'0'");
1481  ASSERT_EQ(net_gnd->get_sources().size(), 1);
1482  ASSERT_NE(net_gnd->get_sources()[0]->get_gate(), nullptr);
1483  EXPECT_TRUE(net_gnd->get_sources()[0]->get_gate()->is_gnd_gate());
1484 
1485  // check whether net '1' was created and is connected to a VCC gate through input pin "I"
1486  Net* net_vcc = gate_1->get_fan_in_net("I");
1487  ASSERT_NE(net_vcc, nullptr);
1488  EXPECT_EQ(net_vcc->get_name(), "'1'");
1489  ASSERT_EQ(net_vcc->get_sources().size(), 1);
1490  ASSERT_NE(net_vcc->get_sources()[0]->get_gate(), nullptr);
1491  EXPECT_TRUE(net_vcc->get_sources()[0]->get_gate()->is_vcc_gate());
1492 
1493  // check whether input pin "I" remains unconnected for 'Z' assignment
1494  ASSERT_EQ(gate_2->get_fan_in_net("I"), nullptr);
1495 
1496  // check whether input pin "I" remains unconnected for 'X' assignment
1497  ASSERT_EQ(gate_2->get_fan_in_net("I"), nullptr);
1498  }
1499  TEST_END
1500  }
1501 
1510  TEST_F(VerilogParserTest, check_multiple_entities)
1511  {
1512  TEST_START
1513  {
1514  // Create a new entity with an attribute that is used once by the main entity
1515  /* ---------------------------------------------.
1516  * | child_mod |
1517  * | |
1518  * global_in ---=| gate_0 |=---=---=| gate_0_child |=---=| gate_1_child |=---=---=| gate_1 |=--- global_out
1519  * | |
1520  * '---------------------------------------------'
1521  */
1522  std::string netlist_input("(* child_attribute = \"child_attribute_value\" *)"
1523  "module MODULE_CHILD ("
1524  " child_in,"
1525  " child_out"
1526  " ) ;"
1527  " (* child_net_attribute = \"child_net_attribute_value\" *)"
1528  " input child_in ;"
1529  " output child_out ;"
1530  " wire net_0_child ;"
1531  "BUF gate_0_child ("
1532  " .I (child_in ),"
1533  " .O (net_0_child )"
1534  " ) ;"
1535  "BUF gate_1_child ("
1536  " .I (net_0_child ),"
1537  " .O (child_out )"
1538  " ) ;"
1539  "endmodule"
1540  "\n"
1541  "module MODULE_TOP ("
1542  " net_global_in,"
1543  " net_global_out"
1544  " ) ;"
1545  " input net_global_in ;"
1546  " output net_global_out ;"
1547  " wire net_0 ;"
1548  " wire net_1 ;"
1549  "BUF gate_0 ("
1550  " .I (net_global_in ),"
1551  " .O (net_0 )"
1552  " ) ;"
1553  "MODULE_CHILD child_mod ("
1554  " .\\child_in (net_0 ),"
1555  " .\\child_out (net_1 )"
1556  " ) ;"
1557  "BUF gate_1 ("
1558  " .I (net_1 ), "
1559  " .O (net_global_out )"
1560  " ) ;"
1561  "endmodule");
1562  const GateLibrary* gate_lib = test_utils::get_gate_library();
1563  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1564  VerilogParser verilog_parser;
1565  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1566  ASSERT_TRUE(nl_res.is_ok());
1567  std::unique_ptr<Netlist> nl = nl_res.get();
1568  ASSERT_NE(nl, nullptr);
1569 
1570  // check gates
1571  Gate* gate_0 = *nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).begin();
1572  ASSERT_NE(gate_0, nullptr);
1573  Gate* gate_1 = *nl->get_gates(test_utils::gate_filter("BUF", "gate_1")).begin();
1574  ASSERT_NE(gate_1, nullptr);
1575  Gate* gate_0_child = *nl->get_gates(test_utils::gate_filter("BUF", "gate_0_child")).begin();
1576  ASSERT_NE(gate_0_child, nullptr);
1577  Gate* gate_1_child = *nl->get_gates(test_utils::gate_filter("BUF", "gate_1_child")).begin();
1578  ASSERT_NE(gate_1_child, nullptr);
1579 
1580  // check nets
1581  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_0")).size(), 1);
1582  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_1")).size(), 1);
1583  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_global_in")).size(), 1);
1584  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_global_out")).size(), 1);
1585  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_0_child")).size(), 1);
1586  Net* net_0 = *nl->get_nets(test_utils::net_name_filter("net_0")).begin();
1587  Net* net_1 = *nl->get_nets(test_utils::net_name_filter("net_1")).begin();
1588  Net* net_global_in = *nl->get_nets(test_utils::net_name_filter("net_global_in")).begin();
1589  Net* net_global_out = *nl->get_nets(test_utils::net_name_filter("net_global_out")).begin();
1590  Net* net_0_child = *nl->get_nets(test_utils::net_name_filter("net_0_child")).begin();
1591 
1592  // check connections
1593  EXPECT_EQ(gate_0->get_fan_in_net("I"), net_global_in);
1594  EXPECT_EQ(gate_0->get_fan_out_net("O"), net_0);
1595  EXPECT_EQ(gate_1->get_fan_in_net("I"), net_1);
1596  EXPECT_EQ(gate_1->get_fan_out_net("O"), net_global_out);
1597  EXPECT_EQ(gate_0_child->get_fan_in_net("I"), net_0);
1598  EXPECT_EQ(gate_0_child->get_fan_out_net("O"), net_0_child);
1599  EXPECT_EQ(gate_1_child->get_fan_in_net("I"), net_0_child);
1600  EXPECT_EQ(gate_1_child->get_fan_out_net("O"), net_1);
1601 
1602  // check modules
1603  Module* top_mod = nl->get_top_module();
1604  ASSERT_NE(top_mod, nullptr);
1605  EXPECT_TRUE(top_mod->is_top_module());
1606  EXPECT_EQ(top_mod->get_name(), "top_module");
1607  EXPECT_EQ(top_mod->get_type(), "MODULE_TOP");
1608  ASSERT_EQ(top_mod->get_submodules().size(), 1);
1609  Module* child_mod = *top_mod->get_submodules().begin();
1610  ASSERT_NE(child_mod, nullptr);
1611  EXPECT_EQ(child_mod->get_name(), "child_mod");
1612  EXPECT_EQ(child_mod->get_type(), "MODULE_CHILD");
1613  EXPECT_EQ(top_mod->get_gates(), std::vector<Gate*>({gate_0, gate_1}));
1614  EXPECT_EQ(child_mod->get_gates(), std::vector<Gate*>({gate_0_child, gate_1_child}));
1615 
1616  // check attributes
1617  EXPECT_EQ(net_0->get_data("attribute", "child_net_attribute"), std::make_tuple("unknown", "child_net_attribute_value"));
1618  EXPECT_EQ(child_mod->get_data("attribute", "child_attribute"), std::make_tuple("unknown", "child_attribute_value"));
1619  }
1620  {
1621  // Create a netlist with the following MODULE hierarchy (assigned gates in '()'):
1622  /*
1623  * .---- CHILD_TWO --- (gate_child_two)
1624  * |
1625  * .----- CHILD_ONE-+
1626  * | |
1627  * TOP_MODULE -+ +---- CHILD_TWO --- (gate_child_two)
1628  * | |
1629  * | '---- (gate_child_one)
1630  * |
1631  * +----- CHILD_TWO --- (gate_child_two)
1632  * |
1633  * '---- (gate_top)
1634  *
1635  */
1636  // Testing the correct build of the Module hierarchy. Moreover the correct substitution of Gate and Net names,
1637  // which would be added twice (because an entity can be used multiple times) is tested as well.
1638 
1639  std::string netlist_input("module ENT_CHILD_TWO ( "
1640  " I_c2, "
1641  " O_c2 "
1642  " ) ; "
1643  " input I_c2 ; "
1644  " output O_c2 ; "
1645  "BUF gate_child_two ( "
1646  " .I (I_c2 ), "
1647  " .O (O_c2 ) "
1648  " ) ; "
1649  "endmodule "
1650  " "
1651  "module ENT_CHILD_ONE ( "
1652  " I_c1, "
1653  " O_c1 "
1654  " ) ; "
1655  " input I_c1 ; "
1656  " output O_c1 ; "
1657  " wire net_child_0 ; "
1658  " wire net_child_1 ; "
1659  "ENT_CHILD_TWO gate_0_ent_two ( "
1660  " .\\I_c2 (I_c1 ), "
1661  " .\\O_c2 (net_child_0 ) "
1662  " ) ; "
1663  "ENT_CHILD_TWO gate_1_ent_two ( "
1664  " .\\I_c2 (net_child_0 ), "
1665  " .\\O_c2 (net_child_1 ) "
1666  " ) ; "
1667  "BUF gate_child_one ( "
1668  " .I (net_child_1 ), "
1669  " .O (O_c1 ) "
1670  " ) ; "
1671  "endmodule "
1672  " "
1673  "module ENT_TOP ("
1674  " net_global_in,"
1675  " net_global_out"
1676  " ) ;"
1677  " input net_global_in ;"
1678  " output net_global_out ;"
1679  " wire net_0 ;"
1680  " wire net_1 ;"
1681  "ENT_CHILD_ONE #("
1682  " .child_one_mod_key(1234)"
1683  ") child_one_mod ("
1684  " .\\I_c1 (net_global_in ),"
1685  " .\\O_c1 (net_0 )"
1686  " ) ;"
1687  "ENT_CHILD_TWO child_two_mod ("
1688  " .\\I_c2 (net_0 ),"
1689  " .\\O_c2 (net_1 )"
1690  " ) ;"
1691  "BUF gate_top ("
1692  " .I (net_1 ),"
1693  " .O (net_global_out )"
1694  " ) ;"
1695  "endmodule");
1696  const GateLibrary* gate_lib = test_utils::get_gate_library();
1697  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1698  VerilogParser verilog_parser;
1699  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1700  ASSERT_TRUE(nl_res.is_ok());
1701  std::unique_ptr<Netlist> nl = nl_res.get();
1702 
1703  // Test if all modules are created and assigned correctly
1704  ASSERT_NE(nl, nullptr);
1705  EXPECT_EQ(nl->get_gates().size(), 5); // 3 * gate_child_two + gate_child_one + gate_top
1706  EXPECT_EQ(nl->get_modules().size(), 5); // 3 * ENT_CHILD_TWO + ENT_CHILD_ONE + ENT_TOP
1707  Module* top_module = nl->get_top_module();
1708 
1709  ASSERT_EQ(top_module->get_submodules().size(), 2);
1710  Module* top_child_one = *top_module->get_submodules().begin();
1711  Module* top_child_two = *(++top_module->get_submodules().begin());
1712  if (top_child_one->get_submodules().empty()) {
1713  std::swap(top_child_one, top_child_two);
1714  }
1715 
1716  ASSERT_EQ(top_child_one->get_submodules().size(), 2);
1717  Module* one_child_0 = *(top_child_one->get_submodules().begin());
1718  Module* one_child_1 = *(++top_child_one->get_submodules().begin());
1719 
1720  // Test if all names that are used multiple times are substituted correctly
1721  std::string module_suffix = "";
1722 
1723  EXPECT_EQ(top_child_one->get_name(), "child_one_mod");
1724 
1725  EXPECT_TRUE(utils::starts_with(top_child_two->get_name(), "child_two_mod" + module_suffix));
1726  EXPECT_TRUE(utils::starts_with(one_child_0->get_name(), "gate_0_ent_two" + module_suffix));
1727  EXPECT_TRUE(utils::starts_with(one_child_1->get_name(), "gate_1_ent_two" + module_suffix));
1728  // All 3 names should be unique
1729  EXPECT_EQ(std::set<std::string>({top_child_two->get_name(), one_child_0->get_name(),
1730  one_child_1->get_name()}).size(), 3);
1731 
1732  // Test if the Gate names are substituted correctly as well (gate_child_two is used multiple times)
1733  std::string gate_suffix = "";
1734 
1735  ASSERT_EQ(top_module->get_gates().size(), 1);
1736  EXPECT_EQ((*top_module->get_gates().begin())->get_name(), "gate_top");
1737 
1738  ASSERT_EQ(top_child_one->get_gates().size(), 1);
1739  EXPECT_EQ((*top_child_one->get_gates().begin())->get_name(), "gate_child_one");
1740 
1741  ASSERT_EQ(top_child_two->get_gates().size(), 1);
1742  ASSERT_EQ(one_child_0->get_gates().size(), 1);
1743  ASSERT_EQ(one_child_1->get_gates().size(), 1);
1744  Gate* gate_child_two_0 = *top_child_two->get_gates().begin();
1745  Gate* gate_child_two_1 = *one_child_0->get_gates().begin();
1746  Gate* gate_child_two_2 = *one_child_1->get_gates().begin();
1747 
1748  EXPECT_TRUE(utils::starts_with(gate_child_two_0->get_name(), "child_two_mod/gate_child_two" + gate_suffix));
1749  EXPECT_TRUE(utils::starts_with(gate_child_two_1->get_name(), "gate_0_ent_two/gate_child_two" + gate_suffix));
1750  EXPECT_TRUE(utils::starts_with(gate_child_two_2->get_name(), "gate_1_ent_two/gate_child_two" + gate_suffix));
1751  // All 3 names should be unique
1752  EXPECT_EQ(std::set<std::string>({gate_child_two_0->get_name(), gate_child_two_1->get_name(),
1753  gate_child_two_2->get_name()}).size(), 3);
1754 
1755  // Test the creation on generic data of the Module child_one_mod
1756  EXPECT_EQ(top_child_one->get_data("generic", "child_one_mod_key"),
1757  std::make_tuple("integer", "1234"));
1758  }
1759  {
1760  // Create a netlist as follows and test its creation (due to request):
1761  /* - - - - - - - - - - - - - - - - - - - - - - .
1762  * ' mod '
1763  * ' mod_inner/mod_out '
1764  * ' .------------------. '
1765  * 'mod_in | | 'net_0
1766  * net_global_in ----=------=| gate_a |=---+---=| gate_b |= '---=----=| gate_top |=---- net_global_out
1767  * ' '
1768  * ' '
1769  * '- - - - - - - - - - - - - - - - - - - - - - '
1770  */
1771 
1772  std::string netlist_input("module ENT_MODULE ( "
1773  " mod_in, "
1774  " mod_out "
1775  " ) ; "
1776  " input mod_in ; "
1777  " output mod_out ; "
1778  " wire mod_inner ; "
1779  " assign mod_out = mod_inner ; "
1780  "BUF gate_a ( "
1781  " .I (mod_in ), "
1782  " .O (mod_inner ) "
1783  " ) ; "
1784  "BUF gate_b ( "
1785  " .I (mod_inner ) "
1786  " ) ; "
1787  "endmodule "
1788  " "
1789  " "
1790  "module ENT_TOP ( "
1791  " net_global_in, "
1792  " net_global_out "
1793  " ) ; "
1794  " input net_global_in ; "
1795  " output net_global_out ; "
1796  " wire net_0 ; "
1797  "ENT_MODULE mod ( "
1798  " .\\mod_in (net_global_in ), "
1799  " .\\mod_out (net_0 ) "
1800  " ) ; "
1801  "BUF gate_top ( "
1802  " .I (net_0 ), "
1803  " .O (net_global_out ) "
1804  " ) ; "
1805  "endmodule");
1806  const GateLibrary* gate_lib = test_utils::get_gate_library();
1807  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1808  VerilogParser verilog_parser;
1809  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1810  ASSERT_TRUE(nl_res.is_ok());
1811  std::unique_ptr<Netlist> nl = nl_res.get();
1812 
1813  // Test if all modules are created and assigned correctly
1814  ASSERT_NE(nl, nullptr);
1815  EXPECT_EQ(nl->get_gates().size(), 3); // 1 in top + 2 in mod
1816  EXPECT_EQ(nl->get_modules().size(), 2); // top + mod
1817  Module* top_module = nl->get_top_module();
1818 
1819  ASSERT_EQ(top_module->get_submodules().size(), 1);
1820  Module* mod = *top_module->get_submodules().begin();
1821 
1822  ASSERT_EQ(mod->get_gates(test_utils::gate_name_filter("gate_a")).size(), 1);
1823  ASSERT_EQ(mod->get_gates(test_utils::gate_name_filter("gate_b")).size(), 1);
1824  ASSERT_EQ(nl->get_gates(test_utils::gate_name_filter("gate_top")).size(), 1);
1825  Gate* gate_a = *mod->get_gates(test_utils::gate_name_filter("gate_a")).begin();
1826  Gate* gate_b = *mod->get_gates(test_utils::gate_name_filter("gate_b")).begin();
1827  Gate* gate_top = *nl->get_gates(test_utils::gate_name_filter("gate_top")).begin();
1828 
1829  Net* mod_out = gate_a->get_fan_out_net("O");
1830  ASSERT_NE(mod_out, nullptr);
1831  ASSERT_EQ(mod->get_output_nets().size(), 1);
1832  EXPECT_EQ(*mod->get_output_nets().begin(), mod_out);
1833 
1835  std::vector<Endpoint*>({test_utils::get_endpoint(gate_b,
1836  "I"),
1837  test_utils::get_endpoint(
1838  gate_top,
1839  "I")})));
1840 
1841  }
1842  {
1843  // Testing the correct naming of gates and nets that occur in multiple modules by
1844  // creating the following netlist:
1845 
1846  /* MODULE_B
1847  * . - - - - - - - - - - - - - - - - - - - - - .
1848  * ' .-----------------. shared_net_name .--------------. '
1849  * ' | |=----------------=| | ' net_0
1850  * net_global_in ---=---=| shared_gate_name |=----------------=| gate_b |=----=-- ...
1851  * ' '------------------' net_b '---------------' '
1852  * ' - - - - - - - - - - - - - - - - - - - - - '
1853  *
1854  * MODULE_A
1855  * . - - - - - - - - - - - - - - - - - - - - - .
1856  * ' .-----------------. shared_net_name .--------------. '
1857  * net_0 ' | |=----------------=| | ' net_1
1858  * ... ---=---=| shared_gate_name |=----------------=| gate_a |=----=-- ...
1859  * ' '------------------' net_a '---------------' '
1860  * ' - - - - - - - - - - - - - - - - - - - - - '
1861  *
1862  * MODULE_B
1863  * net_1 . - - . net_2
1864  * ... --- = ... =-------=| gate_top |=--- net_global_out
1865  * ' - - '
1866  */
1867  std::string netlist_input("module MODULE_A ( "
1868  " I_A, "
1869  " O_A "
1870  " ) ; "
1871  " input I_A ; "
1872  " output O_A ; "
1873  " wire shared_net_name ; "
1874  " wire net_a ; "
1875  "COMB12 shared_gate_name ( "
1876  " .\\I (I_A ), "
1877  " .\\O0 (shared_net_name ), "
1878  " .\\O1 (net_a ) "
1879  " ) ; "
1880  "COMB21 gate_a ( "
1881  " .\\I0 (shared_net_name ), "
1882  " .\\I1 (net_a ), "
1883  " .\\O (O_A ) "
1884  " ) ; "
1885  "endmodule "
1886  " "
1887  "module MODULE_B ( "
1888  " I_B, "
1889  " O_B "
1890  " ) ; "
1891  " input I_B ; "
1892  " output O_B ; "
1893  " wire shared_net_name ; "
1894  " wire net_b ; "
1895  "COMB12 shared_gate_name ( "
1896  " .\\I (I_B ), "
1897  " .\\O0 (shared_net_name ), "
1898  " .\\O1 (net_b ) "
1899  " ) ; "
1900  "COMB21 gate_b ( "
1901  " .\\I0 (shared_net_name ), "
1902  " .\\I1 (net_b ), "
1903  " .\\O (O_B ) "
1904  " ) ; "
1905  "endmodule "
1906  " "
1907  "module ENT_TOP ( "
1908  " net_global_in, "
1909  " net_global_out "
1910  " ) ; "
1911  " input net_global_in ; "
1912  " output net_global_out ; "
1913  " wire net_0 ; "
1914  " wire net_1; "
1915  " wire net_2; "
1916  "MODULE_B mod_b_0 ( "
1917  " .\\I_B (net_global_in ), "
1918  " .\\O_B (net_0 ) "
1919  " ) ; "
1920  "MODULE_A mod_a_0 ( "
1921  " .\\I_A (net_0 ), "
1922  " .\\O_A (net_1 ) "
1923  " ) ; "
1924  "MODULE_B mod_b_1 ( "
1925  " .\\I_B (net_1 ), "
1926  " .\\O_B (net_2 ) "
1927  " ) ; "
1928  "BUF gate_top ( "
1929  " .\\I (net_2 ), "
1930  " .\\O (net_global_out ) "
1931  " ) ; "
1932  "endmodule");
1933  const GateLibrary* gate_lib = test_utils::get_gate_library();
1934  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
1935  VerilogParser verilog_parser;
1936  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
1937  ASSERT_TRUE(nl_res.is_ok());
1938  std::unique_ptr<Netlist> nl = nl_res.get();
1939 
1940  // Test if all modules are created and assigned correctly
1941  ASSERT_NE(nl, nullptr);
1942 
1943  // ISSUE: Seems not to be correct. For example net_b occurs two times, but is named net_b__[3]__ and net_b__[4]__
1944  // or shared_net_name occurs 3 times and is labeled with 4,5,6
1945 
1946  Net* glob_in = *nl->get_global_input_nets().begin();
1947  ASSERT_NE(glob_in, nullptr);
1948  ASSERT_EQ(glob_in->get_destinations().size(), 1);
1949 
1950  Gate* shared_gate_0 = (*glob_in->get_destinations().begin())->get_gate();
1951  ASSERT_NE(shared_gate_0, nullptr);
1952 
1953  // Get all gates from left to right
1954  std::vector<Gate*> nl_gates = {shared_gate_0};
1955  std::vector<std::string> suc_pin = {"O0","O","O0","O","O0","O"};
1956  for(size_t idx = 0; idx < suc_pin.size(); idx++){
1957  ASSERT_NE(nl_gates[idx]->get_successor(suc_pin[idx]), nullptr);
1958  Gate* next_gate = nl_gates[idx]->get_successor(suc_pin[idx])->get_gate();
1959  ASSERT_NE(next_gate, nullptr);
1960  nl_gates.push_back(next_gate);
1961  }
1962 
1963  // Get all nets from left to right (and from top to bottom)
1964  std::vector<Net*> nl_nets = {glob_in};
1965  std::vector<std::pair<Gate*, std::string>> net_out_gate_and_pin = {{nl_gates[0], "O0"}, {nl_gates[0], "O1"}, {nl_gates[1], "O"}, {nl_gates[2], "O0"},
1966  {nl_gates[2], "O1"}, {nl_gates[3], "O"}, {nl_gates[4], "O0"}, {nl_gates[4], "O1"}, {nl_gates[5], "O"}, {nl_gates[6], "O"}};
1967  for(size_t idx = 0; idx < net_out_gate_and_pin.size(); idx++){
1968  Net* next_net = (net_out_gate_and_pin[idx].first)->get_fan_out_net(net_out_gate_and_pin[idx].second);
1969  ASSERT_NE(next_net, nullptr);
1970  nl_nets.push_back(next_net);
1971  }
1972 
1973  // Check that the gate names are correct
1974  std::vector<std::string> nl_gate_names;
1975  for(Gate* g : nl_gates) nl_gate_names.push_back(g->get_name());
1976  std::vector<std::string> expected_gate_names = {"mod_b_0/shared_gate_name", "mod_b_0/gate_b", "mod_a_0/shared_gate_name", "gate_a", "mod_b_1/shared_gate_name", "mod_b_1/gate_b", "gate_top"};
1977  EXPECT_EQ(nl_gate_names, expected_gate_names);
1978 
1979  // Check that the net names are correct
1980  std::vector<std::string> nl_net_names;
1981  for(Net* n : nl_nets) nl_net_names.push_back(n->get_name());
1982  std::vector<std::string> expected_net_names = {"net_global_in", "mod_b_0/shared_net_name", "mod_b_0/net_b", "net_0", "mod_a_0/shared_net_name", "net_a", "net_1", "mod_b_1/shared_net_name", "mod_b_1/net_b", "net_2", "net_global_out"};
1983  EXPECT_EQ(nl_net_names, expected_net_names);
1984 
1985  }
1986  TEST_END
1987  }
1988 
2002  TEST_F(VerilogParserTest, check_direct_assignment) {
2003 
2004  TEST_START
2005  {
2006  // Build up a master-slave hierarchy as follows: (NOTE: Whats up with global inputs?)
2007  /* .--- net_slave_1 (is global input)
2008  * net_master <--- net_slave_0 <--+
2009  * '--- net_slave_2
2010  */
2011  std::string netlist_input(
2012  "module top (\n"
2013  " net_global_in,\n"
2014  " net_global_out,\n"
2015  " net_master\n"
2016  ");\n"
2017  " input net_global_in ;\n"
2018  " output net_global_out ;\n"
2019  " wire net_slave_1 ;\n"
2020  " wire net_slave_0 ;\n"
2021  " input net_master ;\n"
2022  " wire net_slave_2 ;\n"
2023  " assign net_slave_1 = net_slave_0;\n"
2024  " assign net_slave_2 = net_slave_0;\n"
2025  " assign net_master = net_slave_0;\n"
2026  ""
2027  " BUF gate_0 (\n"
2028  " .I (net_global_in ),\n"
2029  " .O (net_slave_0 )\n"
2030  " );\n"
2031  " AND3 gate_1 (\n"
2032  " .I0 (net_master ),\n"
2033  " .I1 (net_slave_1 ),\n"
2034  " .I2 (net_slave_2 ),\n"
2035  " .O (net_global_out )\n"
2036  " );\n"
2037  "endmodule");
2038 
2039  const GateLibrary* gate_lib = test_utils::get_gate_library();
2040  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2041  VerilogParser verilog_parser;
2042  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2043  ASSERT_TRUE(nl_res.is_ok());
2044  std::unique_ptr<Netlist> nl = nl_res.get();
2045 
2046  ASSERT_NE(nl, nullptr);
2047  EXPECT_EQ(nl->get_nets().size(), 3); // global_in + global_out + net_master
2048  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_master")).size(), 1);
2049  Net* net_master = nl->get_nets(test_utils::net_name_filter("net_master")).front();
2050 
2051  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).size(), 1);
2052  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("AND3", "gate_1")).size(), 1);
2053 
2054  Gate* g_0 = *nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).begin();
2055  Gate* g_1 = *nl->get_gates(test_utils::gate_filter("AND3", "gate_1")).begin();
2056 
2057  // Check the connections
2058  EXPECT_EQ(g_0->get_fan_out_net("O"), net_master);
2059  EXPECT_EQ(g_1->get_fan_in_net("I0"), net_master);
2060  EXPECT_EQ(g_1->get_fan_in_net("I1"), net_master);
2061  EXPECT_EQ(g_1->get_fan_in_net("I2"), net_master);
2062 
2063  // Check that net_master becomes also a global input
2064  EXPECT_TRUE(net_master->is_global_input_net());
2065 
2066  }
2067  {
2068  // Create a cyclic master-slave Net hierarchy (first master net should survive)
2069  NO_COUT_TEST_BLOCK;
2070  std::string netlist_input("module top ("
2071  " global_in,"
2072  " global_out "
2073  " ) ;"
2074  " input global_in ;"
2075  " output global_out ;"
2076  " wire net_0;"
2077  " wire net_1;"
2078  " assign net_0 = net_1;"
2079  " assign net_1 = net_0;"
2080  "BUF gate_0 ("
2081  " .I (global_in ),"
2082  " .O (net_0 )"
2083  " ) ;"
2084  "BUF gate_1 ("
2085  " .I (net_1 ),"
2086  " .O (global_out )"
2087  " ) ;"
2088  "endmodule");
2089  const GateLibrary* gate_lib = test_utils::get_gate_library();
2090  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2091  VerilogParser verilog_parser;
2092  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2093  ASSERT_TRUE(nl_res.is_ok());
2094  std::unique_ptr<Netlist> nl = nl_res.get();
2095 
2096  ASSERT_NE(nl, nullptr);
2097  EXPECT_EQ(nl->get_nets().size(), 3); // global_in + global_out + net_0
2098  EXPECT_EQ(nl->get_nets(test_utils::net_name_filter("net_0")).size(), 1);
2099  }
2100  {
2101  std::string netlist_input("module passthrough_test (\n"
2102  " input net_in,\n"
2103  " output net_out\n"
2104  ");\n"
2105  " wire net_a;\n"
2106  " assign net_out = net_a;\n"
2107  " BUF gate_1 (\n"
2108  " .I (net_in ),\n"
2109  " .O (net_a )\n"
2110  " );\n"
2111  "endmodule\n"
2112  "\n"
2113  "module top (net_global_in, net_global_out) ;\n"
2114  " input net_global_in ;\n"
2115  " output net_global_out ;\n"
2116  " passthrough_test pt (\n"
2117  " .net_in (net_global_in ),\n"
2118  " .net_out ()\n"
2119  " );\n"
2120  "endmodule");
2121 
2122  const GateLibrary* gate_lib = test_utils::get_gate_library();
2123  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2124  VerilogParser verilog_parser;
2125  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2126  ASSERT_TRUE(nl_res.is_ok());
2127  std::unique_ptr<Netlist> nl = nl_res.get();
2128 
2129  ASSERT_NE(nl, nullptr);
2130  EXPECT_EQ(nl->get_nets().size(), 2);
2131  EXPECT_EQ(nl->get_nets(test_utils::net_name_filter("net_global_in")).size(), 1);
2132  EXPECT_EQ(nl->get_nets(test_utils::net_name_filter("net_out")).size(), 1);
2133  }
2134  {
2135  std::string netlist_input("module passthrough_test (\n"
2136  " input net_in,\n"
2137  " output net_out\n"
2138  ");\n"
2139  " wire net_a;\n"
2140  " assign net_out = net_a;\n"
2141  " BUF gate_1 (\n"
2142  " .I (net_in ),\n"
2143  " .O (net_a )\n"
2144  " );\n"
2145  "endmodule\n"
2146  "\n"
2147  "module top (net_global_in, net_global_out) ;\n"
2148  " input net_global_in ;\n"
2149  " output net_global_out ;\n"
2150  " passthrough_test pt (\n"
2151  " .net_in (),\n"
2152  " .net_out (net_global_out)\n"
2153  " );\n"
2154  "endmodule");
2155 
2156  const GateLibrary* gate_lib = test_utils::get_gate_library();
2157  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2158  VerilogParser verilog_parser;
2159  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2160  ASSERT_TRUE(nl_res.is_ok());
2161  std::unique_ptr<Netlist> nl = nl_res.get();
2162 
2163  ASSERT_NE(nl, nullptr);
2164  EXPECT_EQ(nl->get_nets().size(), 2);
2165  EXPECT_EQ(nl->get_nets(test_utils::net_name_filter("net_in")).size(), 1);
2166  EXPECT_EQ(nl->get_nets(test_utils::net_name_filter("net_global_out")).size(), 1);
2167  }
2168  // -- Verilog Specific Tests
2169  {
2170  // Verilog specific: Testing assignments with logic vectors (assign wires 0 and 1 of each dimension)
2171  // for example (for dim 2): wire [0:1][0:1] slave_vector; wire [0:3] master_vector; assign slave_vector = master_vector;
2172 
2173  // Will be tested for dimensions up to MAX_DIMENSION (runtime growth exponentially)
2174  const u8 MAX_DIMENSION = 3; // Can be turned up, if you are bored ;)
2175 
2176  for (u8 dim = 0; dim <= MAX_DIMENSION; dim++) {
2177  std::stringstream global_out_list_module;
2178  std::stringstream global_out_list;
2179  std::stringstream gate_list;
2180  std::string dim_decl = "";
2181 
2182  dim_decl += "";
2183  for (u8 d = 0; d < dim; d++) {
2184  dim_decl += "[0:1]";
2185  }
2186 
2187  // 2^(dim) gates (with one pin) must be created to connect all assigned wires
2188  for (u64 i = 0; i < (1 << dim); i++) {
2189  global_out_list_module << " global_out_" << i << ",";
2190  global_out_list << " output global_out_" << i << ";";
2191 
2192  std::bitset<64> i_bs(i);
2193  std::stringstream brackets("");
2194  for (int j = dim - 1; j >= 0; j--) {
2195  brackets << "[" << (i_bs[j] ? "1" : "0") << "]";
2196  }
2197 
2198  gate_list << "BUF in_gate_" << i
2199  << " ("
2200  " .I (global_in ),"
2201  " .O ( net_slave_vector"
2202  << brackets.str()
2203  << ")"
2204  " ) ;";
2205  gate_list << "BUF out_gate_" << i
2206  << " ("
2207  " .I (net_slave_vector"
2208  << brackets.str()
2209  << "),"
2210  " .O ( global_out_"
2211  << i
2212  << ")"
2213  " ) ;";
2214  }
2215 
2216  std::stringstream netlist_input;
2217  netlist_input << "module top ("
2218  " global_in,"
2219  << global_out_list_module.str()
2220  << " );"
2221  " input global_in ;"
2222  << global_out_list.str() << " wire " << dim_decl << " net_slave_vector;"
2223  << " wire [0:" << ((1 << dim) - 1) << "] net_master_vector;"
2224  << " assign net_master_vector = net_slave_vector;" // <- !!!
2225  << gate_list.str() << "endmodule";
2226 
2227  const GateLibrary* gate_lib = test_utils::get_gate_library();
2228  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input.str());
2229  VerilogParser verilog_parser;
2230  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2231  ASSERT_TRUE(nl_res.is_ok());
2232  std::unique_ptr<Netlist> nl = nl_res.get();
2233 
2234  for (u64 i = 0; i < (1 << dim); i++) {
2235  ASSERT_NE(nl, nullptr);
2236 
2237  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter(
2238  "net_master_vector(" + std::to_string(i) + ")")).size(),
2239  1);
2240  Net* net_i =
2241  *nl->get_nets(test_utils::net_name_filter("net_master_vector(" + std::to_string(i) + ")"))
2242  .begin();
2243 
2244  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("BUF", "in_gate_" + std::to_string(i)))
2245  .size(), 1);
2246  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("BUF", "out_gate_" + std::to_string(i)))
2247  .size(), 1);
2248  Gate* in_gate_i =
2249  *nl->get_gates(test_utils::gate_filter("BUF", "in_gate_" + std::to_string(i)))
2250  .begin();
2251  Gate* out_gate_i =
2252  *nl->get_gates(test_utils::gate_filter("BUF", "out_gate_" + std::to_string(i)))
2253  .begin();
2254 
2255  EXPECT_EQ(in_gate_i->get_fan_out_net("O"), net_i);
2256  EXPECT_EQ(out_gate_i->get_fan_in_net("I"), net_i);
2257  }
2258  }
2259  }
2260  {
2261  // Verilog specific: Assign constants ('b0 and 'b1)
2262  std::string netlist_input("module top ("
2263  " global_out"
2264  " ) ;"
2265  " output global_out ;"
2266  " wire [0:3] bit_vector ;"
2267  " assign bit_vector = 4'hA ;"
2268  ""
2269  " BUF test_gate ("
2270  " .I (bit_vector[0] ),"
2271  " .O (global_out )"
2272  " ) ;"
2273  "endmodule");
2274  const GateLibrary* gate_lib = test_utils::get_gate_library();
2275  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2276  VerilogParser verilog_parser;
2277  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2278  ASSERT_TRUE(nl_res.is_ok());
2279  std::unique_ptr<Netlist> nl = nl_res.get();
2280 
2281  ASSERT_NE(nl, nullptr);
2282 
2283  ASSERT_EQ(nl->get_gates(test_utils::gate_name_filter("test_gate")).size(), 1);
2284  Gate* test_gate = *nl->get_gates(test_utils::gate_name_filter("test_gate")).begin();
2285  }
2286  {
2287  // Verilog specific: Assign a set of wires to a single vector
2288  std::string netlist_input("module top ("
2289  " global_out_0,"
2290  " global_out_1,"
2291  " global_out_2"
2292  " ) ;"
2293  " output global_out_0 ;"
2294  " output global_out_1 ;"
2295  " output global_out_2 ;"
2296  ""
2297  " wire single_net ;"
2298  " wire [0:2][0:2] _2_d_vector_0;"
2299  " wire [0:2][0:1] _2_d_vector_1;"
2300  " wire [0:15] big_vector;"
2301  " wire [0:11] net_vector_master;"
2302  " assign net_vector_master = {single_net, big_vector[3], big_vector[0:1], _2_d_vector_0[0:1][0:1], _2_d_vector_1[1:0][0:1]};"
2303  ""
2304  "AND4 test_gate_0 ("
2305  " .I0 (single_net ),"
2306  " .I1 (big_vector[3] ),"
2307  " .I2 (big_vector[0] ),"
2308  " .I3 (big_vector[1] ),"
2309  " .O (global_out_0 )"
2310  " ) ;"
2311  ""
2312  "AND4 test_gate_1 ("
2313  " .I0 (_2_d_vector_0[0][0] ),"
2314  " .I1 (_2_d_vector_0[0][1] ),"
2315  " .I2 (_2_d_vector_0[1][0] ),"
2316  " .I3 (_2_d_vector_0[1][1] ),"
2317  " .O (global_out_1 )"
2318  " ) ;"
2319  "AND4 test_gate_2 ("
2320  " .I0 (_2_d_vector_1[1][0] ),"
2321  " .I1 (_2_d_vector_1[1][1] ),"
2322  " .I2 (_2_d_vector_1[0][0] ),"
2323  " .I3 (_2_d_vector_1[0][1] ),"
2324  " .O (global_out_2 )"
2325  " ) ;"
2326  "endmodule");
2327  const GateLibrary* gate_lib = test_utils::get_gate_library();
2328  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2329  VerilogParser verilog_parser;
2330  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2331  ASSERT_TRUE(nl_res.is_ok());
2332  std::unique_ptr<Netlist> nl = nl_res.get();
2333 
2334  ASSERT_NE(nl, nullptr);
2335  std::vector<Net *> net_master_vector(12);
2336  for (int i = 0; i < 12; i++) {
2337  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_vector_master(" + std::to_string(i) + ")"))
2338  .size(), 1);
2339  net_master_vector[i] =
2340  *nl->get_nets(test_utils::net_name_filter("net_vector_master(" + std::to_string(i) + ")"))
2341  .begin();
2342  }
2343  for (int i = 0; i < 12; i++) {
2344  ASSERT_EQ(net_master_vector[i]->get_destinations().size(), 1);
2345  Endpoint *ep = *net_master_vector[i]->get_destinations().begin();
2346  EXPECT_EQ(ep->get_gate()->get_name(), "test_gate_" + std::to_string(i / 4));
2347  EXPECT_EQ(ep->get_pin()->get_name(), "I" + std::to_string(i % 4));
2348  }
2349  }
2350  {
2351  // Verilog specific: Assign a 2 bit vector to a set of 1 bit vectors
2352 
2353  std::string netlist_input("module top ("
2354  " global_out"
2355  ") ;"
2356  " output global_out ;"
2357  " wire net_master_0 ;"
2358  " wire net_master_1 ;"
2359  " wire [0:1] net_vector_slave;"
2360  " assign { net_master_0, net_master_1 } = net_vector_slave;"
2361  " AND2 test_gate ("
2362  " .I0 ( net_vector_slave[0] ),"
2363  " .I1 ( net_vector_slave[1] ),"
2364  " .O (global_out )"
2365  " ) ;"
2366  "endmodule");
2367 
2368  const GateLibrary* gate_lib = test_utils::get_gate_library();
2369  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2370  VerilogParser verilog_parser;
2371  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2372  ASSERT_TRUE(nl_res.is_ok());
2373  std::unique_ptr<Netlist> nl = nl_res.get();
2374 
2375  ASSERT_NE(nl, nullptr);
2376 
2377  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_master_0")).size(), 1);
2378  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_master_1")).size(), 1);
2379  Net*
2380  net_vector_master_0 = *nl->get_nets(test_utils::net_name_filter("net_master_0")).begin();
2381  Net*
2382  net_vector_master_1 = *nl->get_nets(test_utils::net_name_filter("net_master_1")).begin();
2383  ASSERT_EQ(net_vector_master_0->get_destinations().size(), 1);
2384  ASSERT_EQ(net_vector_master_1->get_destinations().size(), 1);
2385  EXPECT_EQ((*net_vector_master_0->get_destinations().begin())->get_pin()->get_name(), "I0");
2386  EXPECT_EQ((*net_vector_master_1->get_destinations().begin())->get_pin()->get_name(), "I1");
2387  }
2388  {
2389  // Verilog specific: Testing assignments, where escaped identifiers are used (e.g.\Net[1:3][2:3] stands for a Net, literally named "Net[1:3][2:3]")
2390 
2391  std::string netlist_input("module top ("
2392  " global_out"
2393  ") ;"
2394  " output global_out ;"
2395  " wire \\escaped_net_range[0:3] ;"
2396  " wire [0:3] escaped_net_range ;"
2397  " wire \\escaped_net[0] ;"
2398  " wire [0:1] net_vector_master ;"
2399  " assign net_vector_master = { \\escaped_net_range[0:3] , \\escaped_net[0] };"
2400  " AND2 test_gate ("
2401  " .I0 ( \\escaped_net_range[0:3] ),"
2402  " .I1 ( \\escaped_net[0] ),"
2403  " .O (global_out )"
2404  " ) ;"
2405  "endmodule");
2406 
2407  const GateLibrary* gate_lib = test_utils::get_gate_library();
2408  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2409  VerilogParser verilog_parser;
2410  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2411  ASSERT_TRUE(nl_res.is_ok());
2412  std::unique_ptr<Netlist> nl = nl_res.get();
2413 
2414  ASSERT_NE(nl, nullptr);
2415  }
2416  TEST_END
2417  }
2418 
2424  TEST_F(VerilogParserTest, check_pin_group_port_assignment) {
2425 
2426  TEST_START
2427  {
2428  // Connect an entire output pin group with global input nets by using a binary string ('b0101)
2429  std::string netlist_input("module top (\n"
2430  " ) ;\n"
2431  " wire [0:3] l_vec;\n"
2432  " wire net_1 ;\n"
2433  "RAM gate_0 (\n"
2434  " .ADDR ('b0101)\n"
2435  " ) ;\n"
2436  "endmodule");
2437  const GateLibrary* gate_lib = test_utils::get_gate_library();
2438  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2439  VerilogParser verilog_parser;
2440  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2441  ASSERT_TRUE(nl_res.is_ok());
2442  std::unique_ptr<Netlist> nl = nl_res.get();
2443 
2444  ASSERT_NE(nl, nullptr);
2445  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).empty());
2446  Gate* gate_0 = *(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).begin());
2447  Net* net_0 = gate_0->get_fan_in_net("ADDR(0)");
2448  ASSERT_NE(net_0, nullptr);
2449  EXPECT_EQ(net_0->get_name(), "'1'");
2450 
2451  Net* net_1 = gate_0->get_fan_in_net("ADDR(1)");
2452  ASSERT_NE(net_1, nullptr);
2453  EXPECT_EQ(net_1->get_name(), "'0'");
2454 
2455  Net* net_2 = gate_0->get_fan_in_net("ADDR(2)");
2456  ASSERT_NE(net_2, nullptr);
2457  EXPECT_EQ(net_2->get_name(), "'1'");
2458 
2459  Net* net_3 = gate_0->get_fan_in_net("ADDR(3)");
2460  ASSERT_NE(net_3, nullptr);
2461  EXPECT_EQ(net_3->get_name(), "'0'");
2462 
2463  }
2464  {
2465  // Connect a vector of output pins with a list of nets using '{ net_0, net_1, ... }'
2466  std::string netlist_input("module top (\n"
2467  " ) ;\n"
2468  " wire net_0;\n"
2469  " wire net_1;\n"
2470  " wire[0:1] l_vec;\n"
2471  "RAM gate_0 (\n"
2472  " .DATA_OUT ({net_0, net_1, l_vec[0], l_vec[1]})\n"
2473  " ) ;\n"
2474  "endmodule");
2475  const GateLibrary* gate_lib = test_utils::get_gate_library();
2476  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2477  VerilogParser verilog_parser;
2478  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2479  ASSERT_TRUE(nl_res.is_ok());
2480  std::unique_ptr<Netlist> nl = nl_res.get();
2481 
2482  ASSERT_NE(nl, nullptr);
2483  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).empty());
2484  Gate* gate_0 = *(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).begin());
2485 
2486  EXPECT_EQ(gate_0->get_fan_out_nets().size(), 4);
2487 
2488  Net* net_0 = gate_0->get_fan_out_net("DATA_OUT(0)");
2489  ASSERT_NE(net_0, nullptr);
2490  EXPECT_EQ(net_0->get_name(), "l_vec(1)");
2491 
2492  Net* net_1 = gate_0->get_fan_out_net("DATA_OUT(1)");
2493  ASSERT_NE(net_1, nullptr);
2494  EXPECT_EQ(net_1->get_name(), "l_vec(0)");
2495 
2496  Net* net_2 = gate_0->get_fan_out_net("DATA_OUT(2)");
2497  ASSERT_NE(net_2, nullptr);
2498  EXPECT_EQ(net_2->get_name(), "net_1");
2499 
2500  Net* net_3 = gate_0->get_fan_out_net("DATA_OUT(3)");
2501  ASSERT_NE(net_3, nullptr);
2502  EXPECT_EQ(net_3->get_name(), "net_0");
2503  }
2504  {
2505  // Connect a vector of output pins with a vector of nets (O(0) with l_vec(0),...,O(4) with l_vec(4))
2506  std::string netlist_input("module top (\n"
2507  " ) ;\n"
2508  " wire [3:0] l_vec;\n"
2509  " wire net_1 ;\n"
2510  "RAM gate_0 (\n"
2511  " .DATA_OUT (l_vec)\n"
2512  " ) ;\n"
2513  "endmodule");
2514  const GateLibrary* gate_lib = test_utils::get_gate_library();
2515  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2516  VerilogParser verilog_parser;
2517  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2518  ASSERT_TRUE(nl_res.is_ok());
2519  std::unique_ptr<Netlist> nl = nl_res.get();
2520 
2521  ASSERT_NE(nl, nullptr);
2522  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).empty());
2523  Gate* gate_0 = *(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).begin());
2524 
2525  EXPECT_EQ(gate_0->get_fan_out_nets().size(), 4);
2526  Net* net_0 = gate_0->get_fan_out_net("DATA_OUT(0)");
2527  ASSERT_NE(net_0, nullptr);
2528  EXPECT_EQ(net_0->get_name(), "l_vec(0)");
2529 
2530  Net* net_1 = gate_0->get_fan_out_net("DATA_OUT(1)");
2531  ASSERT_NE(net_1, nullptr);
2532  EXPECT_EQ(net_1->get_name(), "l_vec(1)");
2533 
2534  Net* net_2 = gate_0->get_fan_out_net("DATA_OUT(2)");
2535  ASSERT_NE(net_2, nullptr);
2536  EXPECT_EQ(net_2->get_name(), "l_vec(2)");
2537 
2538  Net* net_3 = gate_0->get_fan_out_net("DATA_OUT(3)");
2539  ASSERT_NE(net_3, nullptr);
2540  EXPECT_EQ(net_3->get_name(), "l_vec(3)");
2541 
2542  }
2543  {
2544  // Connect a vector of output pins with a vector of nets (O(0) with l_vec(0),...,O(3) with l_vec(3))
2545  // but the vector has a smaller size
2546  std::string netlist_input("module top (\n"
2547  " ) ;\n"
2548  " wire [2:0] l_vec;\n"
2549  "RAM gate_0 (\n"
2550  " .DATA_OUT (l_vec)\n"
2551  " ) ;\n"
2552  "endmodule");
2553  const GateLibrary* gate_lib = test_utils::get_gate_library();
2554  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2555  VerilogParser verilog_parser;
2556  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2557  ASSERT_TRUE(nl_res.is_ok());
2558  std::unique_ptr<Netlist> nl = nl_res.get();
2559 
2560  ASSERT_NE(nl, nullptr);
2561  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).empty());
2562  Gate* gate_0 = *(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).begin());
2563 
2564  EXPECT_EQ(gate_0->get_fan_out_nets().size(), 3);
2565  Net* net_0 = gate_0->get_fan_out_net("DATA_OUT(0)");
2566  ASSERT_NE(net_0, nullptr);
2567  EXPECT_EQ(net_0->get_name(), "l_vec(0)");
2568 
2569  Net* net_1 = gate_0->get_fan_out_net("DATA_OUT(1)");
2570  ASSERT_NE(net_1, nullptr);
2571  EXPECT_EQ(net_1->get_name(), "l_vec(1)");
2572 
2573  Net* net_2 = gate_0->get_fan_out_net("DATA_OUT(2)");
2574  ASSERT_NE(net_2, nullptr);
2575  EXPECT_EQ(net_2->get_name(), "l_vec(2)");
2576 
2577  EXPECT_EQ(gate_0->get_fan_out_net("DATA_OUT(3)"), nullptr);
2578 
2579  }
2580  {
2581  // Test assigning 2-bit input and 3-bit output wires to 4-bit ports
2582  std::string netlist_input("module top (in, out) ;\n"
2583  " input [1:0] in;\n"
2584  " output [2:0] out;\n"
2585  "RAM gate_0 (\n"
2586  " .DATA_IN (in),\n"
2587  " .DATA_OUT (out)\n"
2588  " ) ;\n"
2589  "endmodule");
2590  const GateLibrary* gate_lib = test_utils::get_gate_library();
2591  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2592  VerilogParser verilog_parser;
2593  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2594  ASSERT_TRUE(nl_res.is_ok());
2595  std::unique_ptr<Netlist> nl = nl_res.get();
2596 
2597  Net* net;
2598  Gate* gate;
2599 
2600  ASSERT_NE(nl, nullptr);
2601  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).empty());
2602  gate = *(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).begin());
2603 
2604  EXPECT_EQ(gate->get_fan_in_nets().size(), 2);
2605  net = gate->get_fan_in_net("DATA_IN(0)");
2606  ASSERT_NE(net, nullptr);
2607  EXPECT_EQ(net->get_name(), "in(0)");
2608  net = gate->get_fan_in_net("DATA_IN(1)");
2609  ASSERT_NE(net, nullptr);
2610  EXPECT_EQ(net->get_name(), "in(1)");
2611 
2612  EXPECT_EQ(gate->get_fan_out_nets().size(), 3);
2613  net = gate->get_fan_out_net("DATA_OUT(0)");
2614  ASSERT_NE(net, nullptr);
2615  EXPECT_EQ(net->get_name(), "out(0)");
2616  net = gate->get_fan_out_net("DATA_OUT(1)");
2617  ASSERT_NE(net, nullptr);
2618  EXPECT_EQ(net->get_name(), "out(1)");
2619  net = gate->get_fan_out_net("DATA_OUT(2)");
2620  ASSERT_NE(net, nullptr);
2621  EXPECT_EQ(net->get_name(), "out(2)");
2622  }
2623  {
2624  // test using only parts of global in- and outputs (unused nets should be removed)
2625  std::string netlist_input("module top (in, out) ;\n"
2626  " input [1:0] in;\n"
2627  " output [1:0] out;\n"
2628  "BUF gate_0 (\n"
2629  " .I (in[1]),\n"
2630  " .O (out[0])\n"
2631  " ) ;\n"
2632  "endmodule");
2633  const GateLibrary* gate_lib = test_utils::get_gate_library();
2634  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2635  VerilogParser verilog_parser;
2636  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2637  ASSERT_TRUE(nl_res.is_ok());
2638  std::unique_ptr<Netlist> nl = nl_res.get();
2639 
2640  Net* net;
2641  Gate* gate;
2642 
2643  ASSERT_NE(nl, nullptr);
2644  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).empty());
2645  gate = *(nl->get_gates(test_utils::gate_filter("BUF", "gate_0")).begin());
2646 
2647  EXPECT_EQ(nl->get_nets().size(), 2);
2648  EXPECT_EQ(nl->get_top_module()->get_pins().size(), 2);
2649 
2650  EXPECT_EQ(gate->get_fan_in_nets().size(), 1);
2651  net = gate->get_fan_in_net("I");
2652  ASSERT_NE(net, nullptr);
2653  EXPECT_EQ(net->get_name(), "in(1)");
2654 
2655  EXPECT_EQ(gate->get_fan_out_nets().size(), 1);
2656  net = gate->get_fan_out_net("O");
2657  ASSERT_NE(net, nullptr);
2658  EXPECT_EQ(net->get_name(), "out(0)");
2659  }
2660  {
2661  // empty pin assignment
2662  std::string netlist_input("module top (in) ;\n"
2663  " input [3:0] in;\n"
2664  "RAM gate_0 (\n"
2665  " .DATA_IN (in),\n"
2666  " .DATA_OUT ()\n"
2667  " ) ;\n"
2668  "endmodule");
2669  const GateLibrary* gate_lib = test_utils::get_gate_library();
2670  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2671  VerilogParser verilog_parser;
2672  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2673  ASSERT_TRUE(nl_res.is_ok());
2674  std::unique_ptr<Netlist> nl = nl_res.get();
2675 
2676  Net* net;
2677  Gate* gate;
2678 
2679  ASSERT_NE(nl, nullptr);
2680  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).empty());
2681  gate = *(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).begin());
2682 
2683  EXPECT_EQ(nl->get_nets().size(), 4);
2684  EXPECT_EQ(nl->get_top_module()->get_pins([](const ModulePin* p) {return p->get_direction() == PinDirection::input; }).size(), 4);
2685  EXPECT_EQ(nl->get_top_module()->get_pins([](const ModulePin* p) {return p->get_direction() == PinDirection::output; }).size(), 0);
2686 
2687  EXPECT_EQ(gate->get_fan_in_nets().size(), 4);
2688  EXPECT_EQ(gate->get_fan_out_nets().size(), 0);
2689  }
2690  {
2691  // Connect a vector of output pins with a list of nets using '{ net_0, net_1, ... }' that is wider than
2692  // the input port size (only the last elements of the list should be assigned)
2693  std::string netlist_input("module top (\n"
2694  " ) ;\n"
2695  " wire net_0;\n"
2696  " wire net_1;\n"
2697  " wire[5:0] l_vec;\n"
2698  "RAM gate_0 (\n"
2699  " .DATA_OUT (l_vec)\n"
2700  " ) ;\n"
2701  "endmodule");
2702  const GateLibrary* gate_lib = test_utils::get_gate_library();
2703  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2704  VerilogParser verilog_parser;
2705  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2706  ASSERT_TRUE(nl_res.is_ok());
2707  std::unique_ptr<Netlist> nl = nl_res.get();
2708  ASSERT_NE(nl, nullptr);
2709  ASSERT_FALSE(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).empty());
2710  Gate* gate_0 = *(nl->get_gates(test_utils::gate_filter("RAM", "gate_0")).begin());
2711  EXPECT_EQ(gate_0->get_fan_out_nets().size(), 4);
2712  Net* net_0 = gate_0->get_fan_out_net("DATA_OUT(0)");
2713  ASSERT_NE(net_0, nullptr);
2714  EXPECT_EQ(net_0->get_name(), "l_vec(0)");
2715  Net* net_1 = gate_0->get_fan_out_net("DATA_OUT(1)");
2716  ASSERT_NE(net_1, nullptr);
2717  EXPECT_EQ(net_1->get_name(), "l_vec(1)");
2718  Net* net_2 = gate_0->get_fan_out_net("DATA_OUT(2)");
2719  ASSERT_NE(net_2, nullptr);
2720  EXPECT_EQ(net_2->get_name(), "l_vec(2)");
2721  Net* net_3 = gate_0->get_fan_out_net("DATA_OUT(3)");
2722  ASSERT_NE(net_3, nullptr);
2723  EXPECT_EQ(net_3->get_name(), "l_vec(3)");
2724  }
2725  TEST_END
2726  }
2727 
2728  /*#########################################################################
2729  Verilog Specific Tests (Tests that can not be directly applied to VHDL)
2730  #########################################################################*/
2731 
2737  TEST_F(VerilogParserTest, check_comments) {
2738 
2739  TEST_START
2740  {
2741  // Testing all comment types with attributes
2742  std::string netlist_input("/*here comes a module*/ module top (\n"
2743  " global_in,\n"
2744  " \\global_out_with//comment \n"
2745  " ) ;\n"
2746  " input global_in;\n"
2747  " output \\global_out_with//comment ;\n"
2748  "\n"
2749  "BUF #(\n"
2750  " .no_comment_0(123), //.comment_0(123),\n"
2751  " //.comment_1(123),\n"
2752  " .no_comment_1(123), /*.comment_2(123),*/ .no_comment_2(123),\n"
2753  " /*.comment_3(123),\n"
2754  " .comment_4(123),\n"
2755  " .comment_5(123),*/\n"
2756  " .no_comment_3(123),\n"
2757  " .no_comment_4(123), /*.comment_6(123),*/ .no_comment_5(123),\n"
2758  " /*.comment_7(123),\n"
2759  " .comment_8(123),\n"
2760  " .comment_9(123),*/\n"
2761  " .no_comment_6(123)\n"
2762  ") \n"
2763  "test_gate (\n"
2764  " .I (global_in ),\n"
2765  " .O (\\global_out_with//comment )\n"
2766  " ) ;\n"
2767  "endmodule");
2768  const GateLibrary* gate_lib = test_utils::get_gate_library();
2769  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2770  VerilogParser verilog_parser;
2771  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2772  ASSERT_TRUE(nl_res.is_ok());
2773  std::unique_ptr<Netlist> nl = nl_res.get();
2774 
2775  ASSERT_NE(nl, nullptr);
2776  ASSERT_EQ(nl->get_gates(test_utils::gate_filter("BUF", "test_gate")).size(), 1);
2777  Gate*
2778  test_gate = *nl->get_gates(test_utils::gate_filter("BUF", "test_gate")).begin();
2779 
2780  // Test that the comments did not removed other parts (all no_comment_n generics should be created)
2781  for (std::string key : std::set<std::string>({"no_comment_0", "no_comment_1", "no_comment_2",
2782  "no_comment_3", "no_comment_4", "no_comment_5",
2783  "no_comment_6"})) {
2784  EXPECT_NE(test_gate->get_data("generic", key), std::make_tuple("", ""));
2785  if (test_gate->get_data("generic", key) == std::make_tuple("", "")) {
2786  std::cout << "comment test failed for: " << key << std::endl;
2787  }
2788  }
2789 
2790  // Test that the comments are not interpreted (all comment_n generics shouldn't be created)
2791  for (std::string key : std::set<std::string>({"comment_0", "comment_1", "comment_2", "comment_3",
2792  "comment_4", "comment_5", "comment_6", "comment_7",
2793  "comment_8", "comment_9"})) {
2794  EXPECT_EQ(test_gate->get_data("generic", key), std::make_tuple("", ""));
2795  if (test_gate->get_data("generic", key) != std::make_tuple("", "")) {
2796  std::cout << "comment failed for: " << key << std::endl;
2797  }
2798  }
2799 
2800  // comment within escaped identifier
2801  EXPECT_EQ(test_gate->get_fan_out_net("O")->get_name(), "global_out_with//comment");
2802  }
2803  TEST_END
2804  }
2805 
2811  TEST_F(VerilogParserTest, check_attributes) {
2812  TEST_START
2813  {
2814  // Add attributes for a module, a gate and a net.
2815  std::string netlist_input("(* ATTRIBUTE_MODULE=attri_module, FLAG_MODULE *)\n"
2816  "module top (\n"
2817  " net_global_in,\n"
2818  " net_global_out\n"
2819  " ) ;\n"
2820  "(* ATTRIBUTE_NET=attri_net, FLAG_NET *)\n"
2821  " input net_global_in ;\n"
2822  " output net_global_out ;\n"
2823  "(* ATTRIBUTE_GATE=attri_gate, FLAG_GATE *)\n"
2824  "BUF gate_0 (\n"
2825  " .\\I (net_global_in ),\n"
2826  " .\\O (net_global_out )\n"
2827  " ) ;\n"
2828  "endmodule");
2829  const GateLibrary* gate_lib = test_utils::get_gate_library();
2830  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2831  VerilogParser verilog_parser;
2832  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2833  ASSERT_TRUE(nl_res.is_ok());
2834  std::unique_ptr<Netlist> nl = nl_res.get();
2835 
2836  ASSERT_NE(nl, nullptr);
2837 
2838  // Access the Elements with attributes
2839  Module* attri_module = nl->get_top_module();
2840 
2841  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("BUF")).size(), 1);
2842  Gate* attri_gate = *nl->get_gates(test_utils::gate_type_filter("BUF")).begin();
2843 
2844  ASSERT_EQ(nl->get_global_input_nets().size(), 1);
2845  Net* attri_net = *nl->get_global_input_nets().begin();
2846 
2847  // Check their attributes
2848  // -- Module
2849  EXPECT_EQ(attri_module->get_data("attribute", "ATTRIBUTE_MODULE"),
2850  std::make_tuple("unknown", "attri_module"));
2851  EXPECT_EQ(attri_module->get_data("attribute", "FLAG_MODULE"), std::make_tuple("unknown", ""));
2852  // -- Gate
2853  EXPECT_EQ(attri_gate->get_data("attribute", "ATTRIBUTE_GATE"),
2854  std::make_tuple("unknown", "attri_gate"));
2855  EXPECT_EQ(attri_gate->get_data("attribute", "FLAG_GATE"), std::make_tuple("unknown", ""));
2856  // -- Net
2857  EXPECT_EQ(attri_net->get_data("attribute", "ATTRIBUTE_NET"),
2858  std::make_tuple("unknown", "attri_net"));
2859  EXPECT_EQ(attri_net->get_data("attribute", "FLAG_NET"), std::make_tuple("unknown", ""));
2860  }
2861  {
2862  // Use atrribute strings with special characters (',','.')
2863  std::string netlist_input("module top (\n"
2864  " net_global_in,\n"
2865  " net_global_out\n"
2866  " ) ;\n"
2867  " input net_global_in ;\n"
2868  " output net_global_out ;\n"
2869  " (* ATTRI_COMMA_STRING=\"test, 1, 2, 3\", ATTRI_FLOAT_STRING=\"1.234\" *)\n"
2870  "BUF gate_0 (\n"
2871  " .\\I (net_global_in ),\n"
2872  " .\\O (net_global_out )\n"
2873  " ) ;\n"
2874  "endmodule");
2875  const GateLibrary* gate_lib = test_utils::get_gate_library();
2876  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2877  VerilogParser verilog_parser;
2878  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2879  ASSERT_TRUE(nl_res.is_ok());
2880  std::unique_ptr<Netlist> nl = nl_res.get();
2881 
2882  ASSERT_NE(nl, nullptr);
2883  ASSERT_EQ(nl->get_gates(test_utils::gate_type_filter("BUF")).size(), 1);
2884  Gate* attri_gate = *nl->get_gates(test_utils::gate_type_filter("BUF")).begin();
2885  EXPECT_EQ(attri_gate->get_data("attribute", "ATTRI_COMMA_STRING"),
2886  std::make_tuple("unknown", "test, 1, 2, 3"));
2887  EXPECT_EQ(attri_gate->get_data("attribute", "ATTRI_FLOAT_STRING"),
2888  std::make_tuple("unknown", "1.234"));
2889  }
2890  TEST_END
2891  }
2892 
2898  TEST_F(VerilogParserTest, check_one_line_multiple_nets) {
2899 
2900  TEST_START
2901  {
2902  // Declare multiple wire vectors in one line
2903  std::string netlist_input("module top ("
2904  " global_in,"
2905  " global_out"
2906  " ) ;"
2907  " input global_in ;"
2908  " output global_out ;"
2909  " wire [0:1] net_vec_0, net_vec_1 ;" // <- !!!
2910  "COMB41 gate_0 ("
2911  " .I0 (net_vec_0[0] ),"
2912  " .I1 (net_vec_0[1] ),"
2913  " .I2 (net_vec_1[0] ),"
2914  " .I3 (net_vec_1[1] ),"
2915  " .O (global_out )"
2916  " ) ;"
2917  "BUF gate_1 ("
2918  " .I (global_in ),"
2919  " .O (net_vec_0[0] )"
2920  ") ;"
2921  "BUF gate_2 ("
2922  " .I (global_in ),"
2923  " .O (net_vec_0[1] )"
2924  ") ;"
2925  "BUF gate_3 ("
2926  " .I (global_in ),"
2927  " .O (net_vec_1[0] )"
2928  ") ;"
2929  "BUF gate_4 ("
2930  " .I (global_in ),"
2931  " .O (net_vec_1[1] )"
2932  ") ;"
2933  "endmodule");
2934  const GateLibrary* gate_lib = test_utils::get_gate_library();
2935  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2936  VerilogParser verilog_parser;
2937  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2938  if(nl_res.is_error()) {
2939  std::cout << nl_res.get_error().get() << std::endl;
2940  }
2941  ASSERT_TRUE(nl_res.is_ok());
2942  std::unique_ptr<Netlist> nl = nl_res.get();
2943 
2944  ASSERT_NE(nl, nullptr);
2945  EXPECT_EQ(nl->get_nets().size(), 6); // 3 of the net_vector + global_in + global_out
2946  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_vec_0(0)")).size(), 1);
2947  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_vec_0(1)")).size(), 1);
2948  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_vec_0(0)")).size(), 1);
2949  ASSERT_EQ(nl->get_nets(test_utils::net_name_filter("net_vec_0(1)")).size(), 1);
2950  }
2951  TEST_END
2952  }
2953 
2959  TEST_F(VerilogParserTest, check_port_dekl_in_list_of_ports) {
2960  TEST_START
2961  {
2962  // Testing the declaration of single ports within the list of ports.
2963  std::string netlist_input("module top ( \n"
2964  " input global_in_0, global_in_1, global_in_2,\n"
2965  " output global_out_0, global_out_1, global_out_2,\n"
2966  " input global_in_3,"
2967  " output global_out_3"
2968  " ) ; \n"
2969  "COMB44 gate_0 ( \n"
2970  " .I0 (global_in_0 ), \n"
2971  " .I1 (global_in_1 ), \n"
2972  " .I2 (global_in_2 ), \n"
2973  " .I3 (global_in_3 ), \n"
2974  " .O0 (global_out_0 ), \n"
2975  " .O1 (global_out_1 ), \n"
2976  " .O2 (global_out_2 ), \n"
2977  " .O3 (global_out_3 ) \n"
2978  " ) ; \n"
2979  "endmodule \n");
2980  const GateLibrary* gate_lib = test_utils::get_gate_library();
2981  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
2982  VerilogParser verilog_parser;
2983  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
2984  ASSERT_TRUE(nl_res.is_ok());
2985  std::unique_ptr<Netlist> nl = nl_res.get();
2986 
2987  ASSERT_NE(nl, nullptr);
2988 
2989  // Check all input nets
2990  std::set<std::string> input_net_names;
2991  for(Net* n : nl->get_global_input_nets())
2992  input_net_names.insert(n->get_name());
2993  EXPECT_EQ(input_net_names, std::set<std::string>({"global_in_0", "global_in_1","global_in_2","global_in_3"}));
2994 
2995  // Check all output nets
2996  std::set<std::string> output_net_names;
2997  for(Net* n : nl->get_global_output_nets())
2998  output_net_names.insert(n->get_name());
2999  EXPECT_EQ(output_net_names, std::set<std::string>({"global_out_0", "global_out_1","global_out_2","global_out_3"}));
3000  }
3001  {
3002  // Testing the declaration of port vectors within the list of ports.
3003  std::string netlist_input("module top ( \n"
3004  " input [0:1] global_in_asc,\n"
3005  " output [0:1] global_out_asc,\n"
3006  " input [3:2] global_in_desc,"
3007  " output [3:2] global_out_desc"
3008  " ) ; \n"
3009  "COMB44 gate_0 ( \n"
3010  " .I0 (global_in_asc[0] ), \n"
3011  " .I1 (global_in_asc[1] ), \n"
3012  " .I2 (global_in_desc[2] ), \n"
3013  " .I3 (global_in_desc[3] ), \n"
3014  " .O0 (global_out_asc[0] ), \n"
3015  " .O1 (global_out_asc[1] ), \n"
3016  " .O2 (global_out_desc[2] ), \n"
3017  " .O3 (global_out_desc[3] ) \n"
3018  " ) ; \n"
3019  "endmodule \n");
3020  const GateLibrary* gate_lib = test_utils::get_gate_library();
3021  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3022  VerilogParser verilog_parser;
3023  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3024  ASSERT_TRUE(nl_res.is_ok());
3025  std::unique_ptr<Netlist> nl = nl_res.get();
3026 
3027  ASSERT_NE(nl, nullptr);
3028 
3029  // Check all input nets
3030  std::set<std::string> input_net_names;
3031  for(Net* n : nl->get_global_input_nets())
3032  input_net_names.insert(n->get_name());
3033  EXPECT_EQ(input_net_names, std::set<std::string>({"global_in_asc(0)", "global_in_asc(1)","global_in_desc(2)","global_in_desc(3)"}));
3034 
3035  // Check all output nets
3036  std::set<std::string> output_net_names;
3037  for(Net* n : nl->get_global_output_nets())
3038  output_net_names.insert(n->get_name());
3039  EXPECT_EQ(output_net_names, std::set<std::string>({"global_out_asc(0)", "global_out_asc(1)","global_out_desc(2)","global_out_desc(3)"}));
3040  }
3041  {
3042  // Testing the declaration of 2-dim port vectors within the list of ports.
3043  std::string netlist_input("module top ( \n"
3044  " input [0:1][1:0] global_in,\n"
3045  " output [1:0][0:1] global_out"
3046  " ) ; \n"
3047  "COMB44 gate_0 ( \n"
3048  " .I0 (global_in[0][0] ), \n"
3049  " .I1 (global_in[0][1] ), \n"
3050  " .I2 (global_in[1][0] ), \n"
3051  " .I3 (global_in[1][1] ), \n"
3052  " .O0 (global_out[0][0] ), \n"
3053  " .O1 (global_out[0][1] ), \n"
3054  " .O2 (global_out[1][0] ), \n"
3055  " .O3 (global_out[1][1] ) \n"
3056  " ) ; \n"
3057  "endmodule \n");
3058  const GateLibrary* gate_lib = test_utils::get_gate_library();
3059  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3060  VerilogParser verilog_parser;
3061  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3062  ASSERT_TRUE(nl_res.is_ok());
3063  std::unique_ptr<Netlist> nl = nl_res.get();
3064 
3065  ASSERT_NE(nl, nullptr);
3066 
3067  // Check all input nets
3068  std::set<std::string> input_net_names;
3069  for(Net* n : nl->get_global_input_nets())
3070  input_net_names.insert(n->get_name());
3071  EXPECT_EQ(input_net_names, std::set<std::string>({"global_in(0)(0)", "global_in(0)(1)","global_in(1)(0)","global_in(1)(1)"}));
3072 
3073  // Check all output nets
3074  std::set<std::string> output_net_names;
3075  for(Net* n : nl->get_global_output_nets())
3076  output_net_names.insert(n->get_name());
3077  EXPECT_EQ(output_net_names, std::set<std::string>({"global_out(0)(0)", "global_out(0)(1)","global_out(1)(0)","global_out(1)(1)"}));
3078  }
3079  TEST_END
3080  }
3086  TEST_F(VerilogParserTest, check_invalid_input) {
3087  TEST_START
3088  {
3089  // Try to connect to a pin, that does not exist
3090  NO_COUT_TEST_BLOCK;
3091  std::string netlist_input("module top ("
3092  " global_in "
3093  " ) ;"
3094  " input global_in ;"
3095 
3096  "BUF gate_0 ("
3097  " .\\NON_EXISTING_PIN (global_in)"
3098  " ) ;"
3099  "endmodule");
3100  const GateLibrary* gate_lib = test_utils::get_gate_library();
3101  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3102  VerilogParser verilog_parser;
3103  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3104  EXPECT_TRUE(nl_res.is_error());
3105  }
3106  {
3107  // The passed Gate library name is unknown
3108  NO_COUT_TEST_BLOCK;
3109  std::string netlist_input("module top ("
3110  " global_in,"
3111  " global_out"
3112  " ) ;"
3113  " input global_in ;"
3114  " output global_out ;"
3115  "UNKNOWN_GATE_TYPE gate_0 ("
3116  " .I (global_in ),"
3117  " .O (global_out )"
3118  " ) ;"
3119  "endmodule");
3120  const GateLibrary* gate_lib = test_utils::get_gate_library();
3121  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3122  VerilogParser verilog_parser;
3123  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3124  EXPECT_TRUE(nl_res.is_error());
3125  }
3126  {
3127  // The input does not contain any Module (is empty)
3128  NO_COUT_TEST_BLOCK;
3129  std::string netlist_input("");
3130  const GateLibrary* gate_lib = test_utils::get_gate_library();
3131  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3132  VerilogParser verilog_parser;
3133  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3134  EXPECT_TRUE(nl_res.is_error());
3135  }
3136  /* non-used entity test commented out (entity erroneously considered as top module)
3137  {
3138  // Create a non-used entity (should not create any problems...)
3139  NO_COUT_TEST_BLOCK;
3140  std::string netlist_input("module ignore_me ("
3141  " min,"
3142  " mout"
3143  " ) ;"
3144  " input min ;"
3145  " output mout ;"
3146  "BUF gate_0 ("
3147  " .I (min ),"
3148  " .O (mout )"
3149  " ) ;"
3150  "endmodule"
3151  "\n"
3152  "module top ("
3153  " global_in,"
3154  " global_out"
3155  " ) ;"
3156  " input global_in ;"
3157  " output global_out ;"
3158  "BUF gate_0 ("
3159  " .I (global_in ),"
3160  " .O (global_out )"
3161  " ) ;"
3162  "endmodule");
3163  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3164  VerilogParser verilog_parser;
3165  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, m_gl);
3166  if (!nl_res.is_ok())
3167  std::cerr << "error <" << nl_res.get_error().get() << ">" << std::endl;
3168  ASSERT_TRUE(nl_res.is_ok());
3169  std::unique_ptr<Netlist> nl = nl_res.get();
3170  EXPECT_NE(nl, nullptr);
3171  }
3172  */
3173  if(test_utils::known_issue_tests_active())
3174  {
3175  // Use non-numeric ranges (invalid) ISSUE: stoi Failure
3176  NO_COUT_TEST_BLOCK;
3177  std::string netlist_input("module top ("
3178  " global_in,"
3179  " global_out"
3180  " ) ;"
3181  " input global_in ;"
3182  " output global_out ;"
3183  " wire [0:4] signal_vec_0 ;"
3184  " wire [0:4] signal_vec_1 ;"
3185  " assign signal_vec_0[p:q] = signal_vec_1[p:q];"
3186  "INV gate_0 ("
3187  " .\\I (global_in ),"
3188  " .\\O (global_out )"
3189  " ) ;"
3190  "endmodule");
3191  const GateLibrary* gate_lib = test_utils::get_gate_library();
3192  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3193  VerilogParser verilog_parser;
3194  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3195  EXPECT_TRUE(nl_res.is_error());
3196  }
3197  // ------ Verilog specific tests ------
3198 #if !defined(__APPLE__)
3199  {
3200  // The Module has no identifier
3201  NO_COUT_TEST_BLOCK;
3202  std::string netlist_input("module ("
3203  " global_in,"
3204  " global_out"
3205  " ) ;"
3206  " input global_in ;"
3207  " output global_out ;"
3208  "BUF gate_0 ("
3209  " .I (global_in ),"
3210  " .O (global_out )"
3211  " ) ;"
3212  "endmodule");
3213  const GateLibrary* gate_lib = test_utils::get_gate_library();
3214  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3215  VerilogParser verilog_parser;
3216  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3217  EXPECT_TRUE(nl_res.is_error());
3218  }
3219  {
3220  // implicit net declaration through assign (not yet supported)
3221  NO_COUT_TEST_BLOCK;
3222  std::string netlist_input(
3223  "module ();"
3224  " wire b;"
3225  " assign a = b;"
3226  "endmodule");
3227  const GateLibrary* gate_lib = test_utils::get_gate_library();
3228  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3229  VerilogParser verilog_parser;
3230  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3231  EXPECT_TRUE(nl_res.is_error());
3232  }
3233  {
3234  // implicit net declaration through port assign (not yet supported)
3235  NO_COUT_TEST_BLOCK;
3236  std::string netlist_input(
3237  "module ();"
3238  " wire b;"
3239  " BUF gate_0 ("
3240  " .I(a),"
3241  " .O(b)"
3242  " );"
3243  "endmodule");
3244  const GateLibrary* gate_lib = test_utils::get_gate_library();
3245  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3246  VerilogParser verilog_parser;
3247  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3248  EXPECT_TRUE(nl_res.is_error());
3249  }
3250 #endif
3251  if(test_utils::known_issue_tests_active())
3252  {
3253  // one side of the direct assignment is empty
3254  NO_COUT_TEST_BLOCK;
3255  std::string netlist_input("module top ("
3256  " global_in,"
3257  " global_out"
3258  " ) ;"
3259  " input global_in ;"
3260  " output global_out ;"
3261  " wire signal_0 ;"
3262  " assign signal_0 = ;"
3263  "endmodule");
3264  const GateLibrary* gate_lib = test_utils::get_gate_library();
3265  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3266  VerilogParser verilog_parser;
3267  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3268  EXPECT_TRUE(nl_res.is_error());
3269  }
3270  {
3271  // Having a cyclic Module hierarchy
3272  NO_COUT_TEST_BLOCK;
3273  std::string netlist_input("module ENT_0 ("
3274  " IE0,"
3275  " OE0 "
3276  " ) ;"
3277  " input IE0 ;"
3278  " output OE0 ;"
3279  "ENT_1 gate_0 ("
3280  " .\\IE1 (IE0 ),"
3281  " .\\OE1 (OE0 )"
3282  " ) ;"
3283  "endmodule"
3284  "module ENT_1 ("
3285  " IE1,"
3286  " OE1 "
3287  " ) ;"
3288  " input IE1 ;"
3289  " output OE1 ;"
3290  "ENT_0 gate_0 ("
3291  " .\\IE0 (IE1 ),"
3292  " .\\OE0 (OE1 )"
3293  " ) ;"
3294  "endmodule");
3295  const GateLibrary* gate_lib = test_utils::get_gate_library();
3296  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3297  VerilogParser verilog_parser;
3298  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3299  EXPECT_TRUE(nl_res.is_error());
3300  }
3301  {
3302  // Store an unknown data type
3303  NO_COUT_TEST_BLOCK;
3304  std::string netlist_input("module top ("
3305  " global_in,"
3306  " global_out"
3307  " ) ;"
3308  " input global_in ;"
3309  " output global_out ;"
3310  "BUF #("
3311  ".key_unknown(#Unkn0wn!)) "
3312  "gate_0 ("
3313  " .I (global_in ),"
3314  " .O (global_out )"
3315  " ) ;"
3316  "endmodule");
3317  const GateLibrary* gate_lib = test_utils::get_gate_library();
3318  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3319  VerilogParser verilog_parser;
3320  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3321  EXPECT_TRUE(nl_res.is_ok());
3322  }
3323  {
3324  // Use an undeclared signal
3325  NO_COUT_TEST_BLOCK;
3326  std::string netlist_input("module top ("
3327  " global_in,"
3328  " global_out"
3329  " ) ;"
3330  " input global_in ;"
3331  " output global_out ;"
3332  "BUF gate_0 ("
3333  " .I (global_in ),"
3334  " .O (net_0 )" // <- undeclared
3335  " ) ;"
3336  "BUF gate_1 ("
3337  " .I (net_0 ),"
3338  " .O (global_out )"
3339  " ) ;"
3340  "endmodule");
3341  const GateLibrary* gate_lib = test_utils::get_gate_library();
3342  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3343  VerilogParser verilog_parser;
3344  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3345  EXPECT_TRUE(nl_res.is_error());
3346  }
3347  {
3348  // Assign unknown signals
3349  NO_COUT_TEST_BLOCK;
3350  std::string netlist_input("module top ("
3351  " global_in,"
3352  " global_out"
3353  " ) ;"
3354  " input global_in ;"
3355  " output global_out ;"
3356  " wire [0:4] signal_vec ;"
3357  " assign signal_unknown[0:4] = signal_vec[0:4];"
3358  "BUF gate_0 ("
3359  " .I (global_in ),"
3360  " .O (global_out )"
3361  " ) ;"
3362  "endmodule");
3363  const GateLibrary* gate_lib = test_utils::get_gate_library();
3364  auto verilog_file = test_utils::create_sandbox_file("netlist.v", netlist_input);
3365  VerilogParser verilog_parser;
3366  auto nl_res = verilog_parser.parse_and_instantiate(verilog_file, gate_lib);
3367  EXPECT_TRUE(nl_res.is_ok());
3368  }
3369  TEST_END
3370  }
3371 } // namespace hal
const std::string & get_name() const
Definition: base_pin.h:108
std::tuple< std::string, std::string > get_data(const std::string &category, const std::string &key) const
Net * get_net() const
Definition: endpoint.cpp:33
GatePin * get_pin() const
Definition: endpoint.cpp:28
Gate * get_gate() const
Definition: endpoint.cpp:23
Definition: gate.h:58
Net * get_fan_in_net(const std::string &pin_name) const
Definition: gate.cpp:617
const std::vector< Net * > & get_fan_in_nets() const
Definition: gate.cpp:591
Net * get_fan_out_net(const std::string &pin_name) const
Definition: gate.cpp:761
const std::string & get_name() const
Definition: gate.cpp:105
Endpoint * get_fan_in_endpoint(const std::string &pin_name) const
Definition: gate.cpp:679
Endpoint * get_successor(const std::string &pin_name) const
Definition: gate.cpp:1018
const std::vector< Net * > & get_fan_out_nets() const
Definition: gate.cpp:735
const std::vector< Endpoint * > & get_fan_in_endpoints() const
Definition: gate.cpp:653
Endpoint * get_fan_out_endpoint(const std::string &pin_name) const
Definition: gate.cpp:823
bool is_input_net(Net *net) const
Definition: module.cpp:555
std::vector< ModulePin * > get_pins(const std::function< bool(ModulePin *)> &filter=nullptr) const
Definition: module.cpp:871
bool is_top_module() const
Definition: module.cpp:312
bool is_output_net(Net *net) const
Definition: module.cpp:565
const std::vector< Gate * > & get_gates() const
Definition: module.cpp:391
std::string get_name() const
Definition: module.cpp:87
std::vector< Module * > get_submodules(const std::function< bool(Module *)> &filter=nullptr, bool recursive=false) const
Definition: module.cpp:259
std::string get_type() const
Definition: module.cpp:106
const std::unordered_set< Net * > & get_output_nets() const
Definition: module.cpp:545
Definition: net.h:58
const std::string & get_name() const
Definition: net.cpp:98
bool is_global_output_net() const
Definition: net.cpp:485
std::vector< Endpoint * > get_destinations(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:426
bool is_global_input_net() const
Definition: net.cpp:480
std::vector< Endpoint * > get_sources(const std::function< bool(Endpoint *ep)> &filter=nullptr) const
Definition: net.cpp:264
Result< std::unique_ptr< Netlist > > parse_and_instantiate(const std::filesystem::path &file_path, const GateLibrary *gate_library)
uint64_t u64
Definition: defines.h:42
uint8_t u8
Definition: defines.h:39
GateLibrary * get_gate_library(const std::string &file_path)
CORE_API bool starts_with(const T &s, const T &start)
Definition: utils.h:167
bool vectors_have_same_content(std::vector< T > vec_1, std::vector< T > vec_2)
Definition: utils.h:78
TEST_F(HGLParserTest, check_library)
Definition: hgl_parser.cpp:26
n
Definition: test.py:6
Net * net