1 #include "gtest/gtest.h"
2 #include "gate_library_test_utils.h"
3 #include "netlist_test_utils.h"
18 test_utils::init_log_channels();
20 test_utils::create_sandbox_directory();
23 std::unique_ptr<GateLibrary> gl_tmp = test_utils::create_gate_library(test_utils::create_sandbox_path(
"testing_gate_library.hgl"));
44 std::filesystem::path path_netlist = test_utils::create_sandbox_path(
"test.v");
45 std::unique_ptr<Netlist> nl = std::make_unique<Netlist>(m_gl);
48 nl->set_design_name(
"top_module");
49 Module* top_module = nl->get_top_module();
52 Gate* gate_0 = nl->create_gate(m_gl->get_gate_type_by_name(
"AND2"),
"gate_0");
53 Gate* gate_1 = nl->create_gate(m_gl->get_gate_type_by_name(
"GND"),
"gate_1");
54 Gate* gate_2 = nl->create_gate(m_gl->get_gate_type_by_name(
"VCC"),
"gate_2");
55 Gate* gate_3 = nl->create_gate(m_gl->get_gate_type_by_name(
"INV"),
"gate_3");
56 Gate* gate_4 = nl->create_gate(m_gl->get_gate_type_by_name(
"INV"),
"gate_4");
57 Gate* gate_5 = nl->create_gate(m_gl->get_gate_type_by_name(
"AND2"),
"gate_5");
58 Gate* gate_6 = nl->create_gate(m_gl->get_gate_type_by_name(
"AND2"),
"gate_6");
59 Gate* gate_7 = nl->create_gate(m_gl->get_gate_type_by_name(
"AND2"),
"gate_7");
64 Net* net_1_3 = test_utils::connect(nl.get(), gate_1,
"O", gate_3,
"I");
65 Net* net_3_0 = test_utils::connect(nl.get(), gate_3,
"O", gate_0,
"I0");
66 Net* net_2_0 = test_utils::connect(nl.get(), gate_2,
"O", gate_0,
"I1");
67 Net* net_0_4_5 = test_utils::connect(nl.get(), gate_0,
"O", gate_4,
"I");
68 test_utils::connect(nl.get(), gate_0,
"O", gate_5,
"I0");
69 Net* net_6_7 = test_utils::connect(nl.get(), gate_6,
"O", gate_7,
"I0");
71 Net* net_4_out = test_utils::connect_global_out(nl.get(), gate_4,
"O",
"net_4_out");
72 ASSERT_TRUE(net_4_out->
set_data(
"parser_annotation",
"merged_nets",
"string",
"[[\"net_4_out__GLOBAL_IO__\"]]"));
74 ASSERT_NE(pin_1,
nullptr);
78 Net* net_5_out = test_utils::connect_global_out(nl.get(), gate_5,
"O",
"net_5_out");
79 ASSERT_TRUE(net_5_out->
set_data(
"parser_annotation",
"merged_nets",
"string",
"[[\"net_5_out__GLOBAL_IO__\"]]"));
81 ASSERT_NE(pin_2,
nullptr);
85 Net* net_7_out = test_utils::connect_global_out(nl.get(), gate_7,
"O",
"net_7_out");
86 ASSERT_TRUE(net_7_out->
set_data(
"parser_annotation",
"merged_nets",
"string",
"[[\"net_7_out__GLOBAL_IO__\"]]"));
88 ASSERT_NE(pin_3,
nullptr);
94 ASSERT_TRUE(verilog_writer.
write(nl.get(), path_netlist).is_ok());
98 ASSERT_TRUE(parsed_nl_res.is_ok());
99 std::unique_ptr<Netlist> parsed_nl = parsed_nl_res.get();
100 ASSERT_NE(parsed_nl,
nullptr);
103 parsed_nl->set_device_name(nl->get_device_name());
106 EXPECT_TRUE(test_utils::netlists_are_equal(nl.get(), parsed_nl.get(),
true));
116 TEST_F(VerilogWriterTest, check_global_nets) {
119 std::filesystem::path path_netlist = test_utils::create_sandbox_path(
"test.v");
120 std::unique_ptr<Netlist> nl = std::make_unique<Netlist>(m_gl);
123 Module* top_module = nl->get_top_module();
125 Gate* gate_0 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"gate_0");
126 Net* global_in_0 = test_utils::connect_global_in(nl.get(), gate_0,
"I",
"global_in_0");
127 ModulePin* pin_1 = top_module->get_pin_by_net(global_in_0);
128 ASSERT_NE(pin_1,
nullptr);
129 ASSERT_TRUE(top_module->set_pin_name(pin_1, global_in_0->get_name()));
131 Gate* gate_1 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"gate_1");
132 Net* global_in_1 = test_utils::connect_global_in(nl.get(), gate_1,
"I",
"global_in_1");
133 ModulePin* pin_2 = top_module->get_pin_by_net(global_in_1);
134 ASSERT_NE(pin_2,
nullptr);
135 ASSERT_TRUE(top_module->set_pin_name(pin_2, global_in_1->get_name()));
137 Gate* gate_2 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"gate_2");
138 Net* global_out_0 = test_utils::connect_global_out(nl.get(), gate_2,
"O",
"global_out_0");
139 ModulePin* pin_3 = top_module->get_pin_by_net(global_out_0);
140 ASSERT_NE(pin_3,
nullptr);
141 ASSERT_TRUE(top_module->set_pin_name(pin_3, global_out_0->get_name()));
143 Gate* gate_3 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"gate_3");
144 Net* global_out_1 = test_utils::connect_global_out(nl.get(), gate_3,
"O",
"global_out_1");
145 ModulePin* pin_4 = top_module->get_pin_by_net(global_out_1);
146 ASSERT_NE(pin_4,
nullptr);
147 ASSERT_TRUE(top_module->set_pin_name(pin_4, global_out_1->get_name()));
151 VerilogWriter verilog_writer;
152 ASSERT_TRUE(verilog_writer.write(nl.get(), path_netlist).is_ok());
154 VerilogParser verilog_parser;
155 auto parsed_nl_res = verilog_parser.parse_and_instantiate(path_netlist, m_gl);
156 ASSERT_TRUE(parsed_nl_res.is_ok());
157 std::unique_ptr<Netlist> parsed_nl = parsed_nl_res.get();
158 ASSERT_NE(parsed_nl,
nullptr);
160 EXPECT_EQ(parsed_nl->get_global_input_nets().size(), 2);
161 EXPECT_EQ(parsed_nl->get_global_output_nets().size(), 2);
163 std::vector<Net*> nets = parsed_nl->get_nets();
164 ASSERT_EQ(nets.size(), 4);
166 auto global_in_0_it = std::find_if(nets.begin(), nets.end(), [](
const Net*
net){ return net->get_name() ==
"global_in_0"; });
167 ASSERT_NE(global_in_0_it, nets.end());
168 EXPECT_TRUE((*global_in_0_it)->is_global_input_net());
170 auto global_in_1_it = std::find_if(nets.begin(), nets.end(), [](
const Net*
net){ return net->get_name() ==
"global_in_1"; });
171 ASSERT_NE(global_in_1_it, nets.end());
172 EXPECT_TRUE((*global_in_1_it)->is_global_input_net());
174 auto global_out_0_it = std::find_if(nets.begin(), nets.end(), [](
const Net*
net){ return net->get_name() ==
"global_out_0"; });
175 ASSERT_NE(global_out_0_it, nets.end());
176 EXPECT_TRUE((*global_out_0_it)->is_global_output_net());
178 auto global_out_1_it = std::find_if(nets.begin(), nets.end(), [](
const Net*
net){ return net->get_name() ==
"global_out_1"; });
179 ASSERT_NE(global_out_1_it, nets.end());
180 EXPECT_TRUE((*global_out_1_it)->is_global_output_net());
190 TEST_F(VerilogWriterTest, check_modules) {
193 std::filesystem::path path_netlist = test_utils::create_sandbox_path(
"test.v");
194 std::unique_ptr<Netlist> nl = std::make_unique<Netlist>(m_gl);
197 Gate* buf_0 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"buf_0");
198 Gate* buf_1 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"buf_1");
199 Gate* buf_2 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"buf_2");
200 Gate* buf_3 = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"buf_3");
201 Gate* inv_0 = nl->create_gate(m_gl->get_gate_type_by_name(
"INV"),
"inv_0");
202 Gate* and2_0 = nl->create_gate(m_gl->get_gate_type_by_name(
"AND2"),
"and2_0");
203 Gate* and2_1 = nl->create_gate(m_gl->get_gate_type_by_name(
"AND2"),
"and2_1");
204 Gate* or2_0 = nl->create_gate(m_gl->get_gate_type_by_name(
"OR2"),
"or2_0");
206 Net* net_0 = test_utils::connect(nl.get(), buf_0,
"O", and2_0,
"I0",
"net_0");
207 Net* net_1 = test_utils::connect(nl.get(), buf_1,
"O", and2_0,
"I1",
"net_1");
208 Net* net_2 = test_utils::connect(nl.get(), and2_0,
"O", or2_0,
"I0",
"net_2");
209 test_utils::connect(nl.get(), and2_0,
"O", and2_1,
"I0",
"net_3");
210 Net* net_3 = test_utils::connect(nl.get(), inv_0,
"O", or2_0,
"I1",
"net_3");
211 test_utils::connect(nl.get(), inv_0,
"O", and2_1,
"I1",
"net_5");
212 Net* net_4 = test_utils::connect(nl.get(), or2_0,
"O", buf_2,
"I",
"net_4");
213 Net* net_5 = test_utils::connect(nl.get(), and2_1,
"O", buf_3,
"I",
"net_5");
215 Net* net_6 = test_utils::connect_global_in(nl.get(), buf_0,
"I",
"net_6");
216 Net* net_7 = test_utils::connect_global_in(nl.get(), buf_1,
"I",
"net_7");
217 Net* net_8 = test_utils::connect_global_in(nl.get(), inv_0,
"I",
"net_8");
219 Net* net_9 = test_utils::connect_global_out(nl.get(), buf_2,
"O",
"net_9");
220 Net* net_10 = test_utils::connect_global_out(nl.get(), buf_3,
"O",
"net_10");
222 Module* mod_0 = nl->create_module(
"mod_0", nl->get_top_module(), {buf_0, buf_1, and2_0});
223 Module* mod_1 = nl->create_module(
"mod_1", nl->get_top_module());
224 Module* mod_2 = nl->create_module(
"mod_2", mod_1, {or2_0, buf_2});
225 Module* mod_3 = nl->create_module(
"mod_3", mod_1, {and2_1, buf_3});
228 VerilogWriter verilog_writer;
229 ASSERT_TRUE(verilog_writer.write(nl.get(), path_netlist).is_ok());
231 VerilogParser verilog_parser;
232 auto parsed_nl_res = verilog_parser.parse_and_instantiate(path_netlist, m_gl);
233 ASSERT_TRUE(parsed_nl_res.is_ok());
234 std::unique_ptr<Netlist> parsed_nl = parsed_nl_res.get();
235 ASSERT_NE(parsed_nl,
nullptr);
237 EXPECT_EQ(parsed_nl->get_nets().size(), 11);
238 EXPECT_EQ(parsed_nl->get_global_input_nets().size(), 3);
239 EXPECT_EQ(parsed_nl->get_global_output_nets().size(), 2);
240 EXPECT_EQ(parsed_nl->get_gates().size(), 8);
243 std::vector<Module*> modules = parsed_nl->get_modules();
244 EXPECT_EQ(modules.size(), 5);
246 const auto top_mod_it = std::find_if(modules.begin(), modules.end(), [](
const Module*
module){ return module->get_name() ==
"top_module"; });
247 ASSERT_NE(top_mod_it, modules.end());
248 EXPECT_EQ((*top_mod_it)->get_gates().size(), 1);
249 EXPECT_EQ((*top_mod_it)->get_input_nets().size(), 3);
250 EXPECT_EQ((*top_mod_it)->get_output_nets().size(), 2);
251 EXPECT_TRUE((*top_mod_it)->is_top_module());
253 const auto mod_0_it = std::find_if(modules.begin(), modules.end(), [](
const Module*
module){ return module->get_name() ==
"mod_0"; });
254 ASSERT_NE(mod_0_it, modules.end());
255 EXPECT_EQ((*mod_0_it)->get_gates().size(), 3);
256 EXPECT_EQ((*mod_0_it)->get_input_nets().size(), 2);
257 EXPECT_EQ((*mod_0_it)->get_output_nets().size(), 1);
258 EXPECT_EQ((*mod_0_it)->get_parent_module(), parsed_nl->get_top_module());
260 const auto mod_1_it = std::find_if(modules.begin(), modules.end(), [](
const Module*
module){ return module->get_name() ==
"mod_1"; });
261 ASSERT_NE(mod_1_it, modules.end());
262 EXPECT_EQ((*mod_1_it)->get_gates().size(), 0);
263 EXPECT_EQ((*mod_1_it)->get_input_nets().size(), 2);
264 EXPECT_EQ((*mod_1_it)->get_output_nets().size(), 2);
265 EXPECT_EQ((*mod_1_it)->get_parent_module(), parsed_nl->get_top_module());
267 const auto mod_2_it = std::find_if(modules.begin(), modules.end(), [](
const Module*
module){ return module->get_name() ==
"mod_2"; });
268 ASSERT_NE(mod_2_it, modules.end());
269 EXPECT_EQ((*mod_2_it)->get_gates().size(), 2);
270 EXPECT_EQ((*mod_2_it)->get_input_nets().size(), 2);
271 EXPECT_EQ((*mod_2_it)->get_output_nets().size(), 1);
272 EXPECT_EQ((*mod_2_it)->get_parent_module(), (*mod_1_it));
274 const auto mod_3_it = std::find_if(modules.begin(), modules.end(), [](
const Module*
module){ return module->get_name() ==
"mod_3"; });
275 ASSERT_NE(mod_3_it, modules.end());
276 EXPECT_EQ((*mod_3_it)->get_gates().size(), 2);
277 EXPECT_EQ((*mod_3_it)->get_input_nets().size(), 2);
278 EXPECT_EQ((*mod_3_it)->get_output_nets().size(), 1);
279 EXPECT_EQ((*mod_3_it)->get_parent_module(), (*mod_1_it));
290 TEST_F(VerilogWriterTest, check_data) {
293 std::filesystem::path path_netlist = test_utils::create_sandbox_path(
"test.v");
294 std::unique_ptr<Netlist> nl = std::make_unique<Netlist>(m_gl);
296 Gate* gate = nl->create_gate(m_gl->get_gate_type_by_name(
"BUF"),
"gate_0");
297 test_utils::connect_global_in(nl.get(), gate,
"I");
298 test_utils::connect_global_out(nl.get(), gate,
"O");
300 Module* mod = nl->create_module(
"mod", nl->get_top_module(), {gate});
302 gate->set_data(
"generic",
"test_bit_vector",
"bit_vector",
"123ABC");
303 gate->set_data(
"generic",
"test_string",
"string",
"one_two_three");
304 gate->set_data(
"generic",
"test_integer",
"integer",
"123");
305 gate->set_data(
"generic",
"test_float",
"floating_point",
"1.001");
306 gate->set_data(
"generic",
"test_bit_value",
"bit_value",
"1");
309 gate->set_data(
"generic",
"test_invalid",
"invalid",
"ignore_me");
310 gate->set_data(
"attribute",
"test_attr_string",
"string",
"one_two_three");
311 gate->set_data(
"random",
"test_rand_string",
"string",
"one_two_three");
313 mod->set_data(
"generic",
"test_bit_vector",
"bit_vector",
"123ABC");
314 mod->set_data(
"generic",
"test_string",
"string",
"one_two_three");
315 mod->set_data(
"generic",
"test_integer",
"integer",
"123");
316 mod->set_data(
"generic",
"test_float",
"floating_point",
"1.001");
317 mod->set_data(
"generic",
"test_bit_value",
"bit_value",
"1");
320 mod->set_data(
"generic",
"test_invalid",
"invalid",
"ignore_me");
321 mod->set_data(
"attribute",
"test_attr_string",
"string",
"one_two_three");
322 mod->set_data(
"random",
"test_rand_string",
"string",
"one_two_three");
324 VerilogWriter verilog_writer;
325 ASSERT_TRUE(verilog_writer.write(nl.get(), path_netlist).is_ok());
327 VerilogParser verilog_parser;
328 auto parsed_nl_res = verilog_parser.parse_and_instantiate(path_netlist, m_gl);
329 ASSERT_TRUE(parsed_nl_res.is_ok());
330 std::unique_ptr<Netlist> parsed_nl = parsed_nl_res.get();
331 ASSERT_NE(parsed_nl,
nullptr);
333 std::vector<Gate*> gates = parsed_nl->get_gates();
334 ASSERT_EQ(gates.size(), 1);
335 const Gate* parsed_gate = gates.front();
336 ASSERT_NE(parsed_gate,
nullptr);
338 EXPECT_EQ(parsed_gate->get_data_map().size(), 5);
339 EXPECT_EQ(parsed_gate->get_data(
"generic",
"test_bit_vector"), std::make_tuple(std::string(
"bit_vector"), std::string(
"123ABC")));
340 EXPECT_EQ(parsed_gate->get_data(
"generic",
"test_string"), std::make_tuple(std::string(
"string"), std::string(
"one_two_three")));
341 EXPECT_EQ(parsed_gate->get_data(
"generic",
"test_integer"), std::make_tuple(std::string(
"integer"), std::string(
"123")));
342 EXPECT_EQ(parsed_gate->get_data(
"generic",
"test_float"), std::make_tuple(std::string(
"floating_point"), std::string(
"1.001")));
343 EXPECT_EQ(parsed_gate->get_data(
"generic",
"test_bit_value"), std::make_tuple(std::string(
"bit_value"), std::string(
"1")));
345 std::vector<Module*> modules = parsed_nl->get_modules();
346 ASSERT_EQ(modules.size(), 2);
347 auto mod_it = std::find_if(modules.begin(), modules.end(), [](
const Module* m){ return !m->is_top_module(); });
348 ASSERT_NE(mod_it, modules.end());
349 const Module* parsed_module = *mod_it;
350 ASSERT_NE(parsed_module,
nullptr);
352 EXPECT_EQ(parsed_module->get_data_map().size(), 5);
353 EXPECT_EQ(parsed_module->get_data(
"generic",
"test_bit_vector"), std::make_tuple(std::string(
"bit_vector"), std::string(
"123ABC")));
354 EXPECT_EQ(parsed_module->get_data(
"generic",
"test_string"), std::make_tuple(std::string(
"string"), std::string(
"one_two_three")));
355 EXPECT_EQ(parsed_module->get_data(
"generic",
"test_integer"), std::make_tuple(std::string(
"integer"), std::string(
"123")));
356 EXPECT_EQ(parsed_module->get_data(
"generic",
"test_float"), std::make_tuple(std::string(
"floating_point"), std::string(
"1.001")));
357 EXPECT_EQ(parsed_module->get_data(
"generic",
"test_bit_value"), std::make_tuple(std::string(
"bit_value"), std::string(
"1")));
367 TEST_F(VerilogWriterTest, check_multi_bit_pins) {
370 std::filesystem::path path_netlist = test_utils::create_sandbox_path(
"test.v");
371 std::unique_ptr<Netlist> nl = std::make_unique<Netlist>(m_gl);
373 Gate* gate = nl->create_gate(m_gl->get_gate_type_by_name(
"RAM"),
"ram");
375 Module* top_module = nl->get_top_module();
377 for (
u32 i = 0; i < 4; i++)
379 Net*
n = test_utils::connect_global_in(nl.get(), gate,
"DATA_IN(" + std::to_string(i) +
")",
"DATA_IN(" + std::to_string(i) +
")");
380 ModulePin* pin_1 = top_module->get_pin_by_net(
n);
381 ASSERT_NE(pin_1,
nullptr);
382 ASSERT_TRUE(top_module->set_pin_name(pin_1,
"DATA_IN(" + std::to_string(i) +
")"));
384 n = test_utils::connect_global_out(nl.get(), gate,
"DATA_OUT(" + std::to_string(i) +
")",
"DATA_OUT(" + std::to_string(i) +
")");
385 ModulePin* pin_2 = top_module->get_pin_by_net(
n);
386 ASSERT_NE(pin_2,
nullptr);
387 ASSERT_TRUE(top_module->set_pin_name(pin_2,
"DATA_OUT(" + std::to_string(i) +
")"));
389 n = test_utils::connect_global_in(nl.get(), gate,
"ADDR(" + std::to_string(i) +
")",
"ADDR(" + std::to_string(i) +
")");
390 ModulePin* pin_3 = top_module->get_pin_by_net(
n);
391 ASSERT_NE(pin_3,
nullptr);
392 ASSERT_TRUE(top_module->set_pin_name(pin_3,
"ADDR(" + std::to_string(i) +
")"));
395 std::vector<Endpoint*> fan_in = gate->get_fan_in_endpoints();
396 std::vector<Endpoint*> fan_out = gate->get_fan_out_endpoints();
398 VerilogWriter verilog_writer;
399 ASSERT_TRUE(verilog_writer.write(nl.get(), path_netlist).is_ok());
401 VerilogParser verilog_parser;
402 auto parsed_nl_res = verilog_parser.parse_and_instantiate(path_netlist, m_gl);
403 ASSERT_TRUE(parsed_nl_res.is_ok());
404 std::unique_ptr<Netlist> parsed_nl = parsed_nl_res.get();
405 ASSERT_NE(parsed_nl,
nullptr);
407 std::vector<Gate*> gates = parsed_nl->get_gates();
408 ASSERT_EQ(gates.size(), 1);
409 const Gate* parsed_gate = gates.front();
410 ASSERT_NE(parsed_gate,
nullptr);
412 EXPECT_EQ(parsed_gate->get_fan_in_nets().size(), 8);
413 EXPECT_EQ(parsed_gate->get_fan_out_nets().size(), 4);
415 for (
const Endpoint* ep : fan_in)
417 EXPECT_EQ(parsed_gate->get_fan_in_net(ep->get_pin())->get_name(), ep->get_net()->get_name());
420 for (
const Endpoint* ep : fan_out)
422 EXPECT_EQ(parsed_gate->get_fan_out_net(ep->get_pin())->get_name(), ep->get_net()->get_name());
const std::pair< PinGroup< T > *, i32 > & get_group() const
bool set_data(const std::string &category, const std::string &key, const std::string &data_type, const std::string &value, const bool log_with_info_level=false)
bool set_pin_name(ModulePin *pin, const std::string &new_name, bool force_name=false)
void set_type(const std::string &type)
ModulePin * get_pin_by_net(Net *net) const
bool set_pin_group_name(PinGroup< ModulePin > *pin_group, const std::string &new_name, bool force_name=false)
const std::string & get_name() const
Result< std::unique_ptr< Netlist > > parse_and_instantiate(const std::filesystem::path &file_path, const GateLibrary *gate_library)
Result< std::monostate > write(Netlist *netlist, const std::filesystem::path &file_path) override
const Module * module(const Gate *g, const NodeBoxes &boxes)
GateLibrary * load(std::filesystem::path file_path, bool reload)
bool save(std::filesystem::path file_path, GateLibrary *gate_lib, bool overwrite)
bool unload_all_plugins()
bool load_all_plugins(const std::vector< std::filesystem::path > &directory_names)
TEST_F(HGLParserTest, check_library)