HAL
netlist_writer_manager.cpp
Go to the documentation of this file.
2 
8 
9 #include <chrono>
10 #include <fstream>
11 #include <vector>
12 
13 namespace hal
14 {
15  namespace netlist_writer_manager
16  {
17  namespace
18  {
19  std::unordered_map<std::string, std::vector<std::string>> m_writer_to_extensions;
20  std::unordered_map<std::string, std::pair<std::string, WriterFactory>> m_extension_to_writer;
21 
22  WriterFactory get_writer_factory_for_file(const std::filesystem::path& file_name)
23  {
24  std::string extension = utils::to_lower(file_name.extension().string());
25  if (!extension.empty() && extension[0] != '.')
26  {
27  extension = "." + extension;
28  }
29 
30  if (auto it = m_extension_to_writer.find(extension); it != m_extension_to_writer.end())
31  {
32  log_info("netlist_writer", "selected writer: {}", it->second.first);
33  return it->second.second;
34  }
35 
36  log_error("netlist_writer", "no netlist writer registered for file extension '{}'.", extension);
37  return WriterFactory();
38  }
39  } // namespace
40 
42  {
43  ProgramOptions description;
44  description.add("--write-hdl", "Write netlist to file.", {ProgramOptions::A_REQUIRED_PARAMETER});
45  return description;
46  }
47 
48  const std::unordered_map<std::string, std::vector<std::string>>& get_writer_extensions()
49  {
50  return m_writer_to_extensions;
51  }
52 
53  void register_writer(const std::string& name, const WriterFactory& writer_factory, const std::vector<std::string>& supported_file_extensions)
54  {
55  for (std::string ext : supported_file_extensions)
56  {
57  ext = utils::trim(utils::to_lower(ext));
58  if (!ext.empty() && ext[0] != '.')
59  {
60  ext = "." + ext;
61  }
62  if (auto it = m_extension_to_writer.find(ext); it != m_extension_to_writer.end())
63  {
64  log_warning("netlist_writer", "writer '{}' cannot be registered as file extension '{}' is already associated with writer '{}'.", name, ext, it->second.first);
65  continue;
66  }
67  m_extension_to_writer.emplace(ext, std::make_pair(name, writer_factory));
68  m_writer_to_extensions[name].push_back(ext);
69 
70  log_info("netlist_writer", "registered netlist writer '{}' for file extension '{}'.", name, ext);
71  }
72  }
73 
74  void unregister_writer(const std::string& name)
75  {
76  if (auto it = m_writer_to_extensions.find(name); it != m_writer_to_extensions.end())
77  {
78  for (const auto& ext : it->second)
79  {
80  if (auto rm_it = m_extension_to_writer.find(ext); rm_it != m_extension_to_writer.end())
81  {
82  m_extension_to_writer.erase(rm_it);
83  log_info("netlist_writer", "unregistered netlist writer '{}' for file extension '{}'.", name, ext);
84  }
85  }
86  m_writer_to_extensions.erase(it);
87  }
88  }
89 
91  {
92  if (args.is_option_set("--write-hdl"))
93  {
94  auto output_file = args.get_parameter("--write-hdl");
95 
96  return write(netlist, output_file);
97  }
98  return true;
99  }
100 
101  bool write(Netlist* netlist, const std::filesystem::path& file_path)
102  {
103  auto factory = get_writer_factory_for_file(file_path);
104  if (!factory)
105  {
106  return false;
107  }
108 
109  std::unique_ptr<NetlistWriter> writer = factory();
110 
111  log_info("netlist_writer", "writing netlist '{}' to file '{}'...", netlist->get_design_name(), file_path.string());
112 
113  auto begin_time = std::chrono::high_resolution_clock::now();
114  if (auto res = writer->write(netlist, file_path); res.is_error())
115  {
116  log_error("netlist", "error encountered during netlist writing:\n{}", res.get_error().get());
117  return false;
118  }
119 
120  log_info("netlist_writer",
121  "wrote netlist '{}' to file '{}' in {:2.2f} seconds.",
122  netlist->get_design_name(),
123  file_path.string(),
124  (double)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - begin_time).count() / 1000);
125 
126  return true;
127  }
128  } // namespace netlist_writer_manager
129 } // namespace hal
bool add(const std::string &flag, const std::string &description, const std::initializer_list< std::string > &parameters={})
static const std::string A_REQUIRED_PARAMETER
constant to specify that a parameter is required and does not have a default value.
#define log_error(channel,...)
Definition: log.h:78
#define log_info(channel,...)
Definition: log.h:70
#define log_warning(channel,...)
Definition: log.h:76
std::function< std::unique_ptr< NetlistWriter >()> WriterFactory
const std::unordered_map< std::string, std::vector< std::string > > & get_writer_extensions()
Retrieve the extensions for which extensions have been registered.
void unregister_writer(const std::string &name)
bool write(Netlist *netlist, const ProgramArguments &args)
void register_writer(const std::string &name, const WriterFactory &writer_factory, const std::vector< std::string > &supported_file_extensions)
CORE_API T trim(const T &s, const char *to_remove=" \t\r\n")
Definition: utils.h:358
CORE_API T to_lower(const T &s)
Definition: utils.h:477
std::string name
This file contains various functions to create and load netlists.