HAL
gate_library_manager.cpp
Go to the documentation of this file.
2 
8 
9 #include <iostream>
10 
11 namespace hal
12 {
13  namespace gate_library_manager
14  {
15  namespace
16  {
17  std::map<std::filesystem::path, std::unique_ptr<GateLibrary>> m_gate_libraries;
18 
19  Result<std::monostate> prepare_library(const std::unique_ptr<GateLibrary>& lib)
20  {
21  auto gate_types = lib->get_gate_types();
22 
23  for (const auto& [gt_name, gt] : gate_types)
24  {
25  if (gt->has_property(GateTypeProperty::power))
26  {
27  lib->mark_vcc_gate_type(gt);
28  }
29  else if (gt->has_property(GateTypeProperty::ground))
30  {
31  lib->mark_gnd_gate_type(gt);
32  }
33  }
34 
35  if (lib->get_gnd_gate_types().empty())
36  {
37  std::string name = "HAL_GND";
38  if (gate_types.find(name) != gate_types.end())
39  {
40  return ERR("could not prepare gate library '" + lib->get_name() + "': no GND gate type found within gate library, but gate type 'HAL_GND' already exists");
41  }
42 
44  if (auto res = gt->create_pin("O", PinDirection::output, PinType::ground); res.is_error())
45  {
46  return ERR_APPEND(res.get_error(), "could not prepare gate library '" + lib->get_name() + "': failed to create output pin 'O' for gate type 'HAL_GND'");
47  }
48  gt->add_boolean_function("O", BooleanFunction::Const(BooleanFunction::Value::ZERO));
49  lib->mark_gnd_gate_type(gt);
50  log_info("gate_library_manager", "gate library did not contain a GND gate, auto-generated type '{}'.", name);
51  }
52 
53  if (lib->get_vcc_gate_types().empty())
54  {
55  std::string name = "HAL_VDD";
56  if (gate_types.find(name) != gate_types.end())
57  {
58  return ERR("could not prepare gate library '" + lib->get_name() + "': no VDD gate type found within gate library, but gate type 'HAL_VDD' already exists");
59  }
60 
62  if (auto res = gt->create_pin("O", PinDirection::output, PinType::power); res.is_error())
63  {
64  return ERR_APPEND(res.get_error(), "could not prepare gate library '" + lib->get_name() + "': failed to create output pin 'O' for gate type 'HAL_VDD'");
65  }
66  gt->add_boolean_function("O", BooleanFunction::Const(BooleanFunction::Value::ONE));
67  lib->mark_vcc_gate_type(gt);
68  log_info("gate_library_manager", "gate library did not contain a VDD gate, auto-generated type '{}'.", name);
69  }
70 
71  return OK({});
72  }
73  } // namespace
74 
75  GateLibrary* load(std::filesystem::path file_path, bool reload)
76  {
77  if (!std::filesystem::exists(file_path))
78  {
79  log_error("gate_library_manager", "gate library file '{}' does not exist.", file_path.string());
80  return nullptr;
81  }
82 
83  if (!file_path.is_absolute())
84  {
85  file_path = std::filesystem::absolute(file_path);
86  }
87 
88  if (!reload)
89  {
90  if (auto it = m_gate_libraries.find(file_path); it != m_gate_libraries.end())
91  {
92  log_info("gate_library_parser", "the gate library file '{}' is already loaded.", file_path.string());
93  return it->second.get();
94  }
95  }
96 
97  std::unique_ptr<GateLibrary> gate_lib = gate_library_parser_manager::parse(file_path);
98  if (gate_lib == nullptr)
99  {
100  return nullptr;
101  }
102 
103  if (auto res = prepare_library(gate_lib); res.is_error())
104  {
105  log_error("gate_library_parser", "error encountered while loading gate library:\n{}", res.get_error().get());
106  return nullptr;
107  }
108 
109  GateLibrary* res = gate_lib.get();
110  m_gate_libraries[file_path.string()] = std::move(gate_lib);
111  return res;
112  }
113 
114  void load_all(bool reload)
115  {
116  std::vector<std::filesystem::path> lib_dirs = utils::get_gate_library_directories();
117 
118  for (const auto& lib_dir : lib_dirs)
119  {
120  if (!std::filesystem::exists(lib_dir))
121  {
122  continue;
123  }
124 
125  log_info("gate_library_manager", "loading all gate library files from {}.", lib_dir.string());
126 
127  for (const auto& lib_path : utils::RecursiveDirectoryRange(lib_dir))
128  {
129  load(lib_path.path(), reload);
130  }
131  }
132  }
133 
134  std::vector<std::filesystem::path> get_all_path()
135  {
136  std::vector<std::filesystem::path> retval;
137  for (const auto& lib_dir : utils::get_gate_library_directories())
138  {
139  if (!std::filesystem::exists(lib_dir))
140  continue;
141  for (const auto& lib_path : utils::RecursiveDirectoryRange(lib_dir))
142  retval.push_back(lib_path.path());
143  }
144  return retval;
145  }
146 
147  bool save(std::filesystem::path file_path, GateLibrary* gate_lib, bool overwrite)
148  {
149  if (std::filesystem::exists(file_path))
150  {
151  if (overwrite)
152  {
153  log_info("gate_library_manager", "gate library file '{}' already exists and will be overwritten.", file_path.string());
154  }
155  else
156  {
157  log_error("gate_library_manager", "gate library file '{}' already exists, aborting.", file_path.string());
158  return false;
159  }
160  }
161 
162  if (!file_path.is_absolute())
163  {
164  file_path = std::filesystem::absolute(file_path);
165  }
166 
167  return gate_library_writer_manager::write(gate_lib, file_path);
168  }
169 
170  void remove(std::filesystem::path file_path)
171  {
172  m_gate_libraries.erase(file_path);
173  }
174 
175  GateLibrary* get_gate_library(const std::string& file_path)
176  {
177  std::filesystem::path absolute_path;
178 
179  if (std::filesystem::exists(file_path))
180  {
181  // if an existing file is queried, load it by its absolute path
182  absolute_path = std::filesystem::absolute(file_path);
183  }
184  else
185  {
186  // if a non existing file is queried, search for it in the standard directories
187  auto stripped_name = std::filesystem::path(file_path).filename();
188  log_info("gate_library_manager", "file '{}' does not exist, searching for '{}' in the default gate library directories...", file_path, stripped_name.string());
189 
190  auto lib_path = utils::get_file(stripped_name, utils::get_gate_library_directories());
191  if (lib_path.empty())
192  {
193  log_info("gate_library_manager", "could not find gate library file '{}'.", stripped_name.string());
194  return nullptr;
195  }
196  absolute_path = std::filesystem::absolute(lib_path);
197  }
198 
199  // absolute path to file is known, check if it is already loaded
200  if (auto it = m_gate_libraries.find(absolute_path.string()); it != m_gate_libraries.end())
201  {
202  return it->second.get();
203  }
204 
205  // not loaded yet -> load
206  return load(absolute_path);
207  }
208 
209  GateLibrary* get_gate_library_by_name(const std::string& lib_name)
210  {
211  for (const auto& it : m_gate_libraries)
212  {
213  if (it.second->get_name() == lib_name)
214  {
215  return it.second.get();
216  }
217  }
218  return nullptr;
219  }
220 
221  std::vector<GateLibrary*> get_gate_libraries()
222  {
223  std::vector<GateLibrary*> res;
224  res.reserve(m_gate_libraries.size());
225  for (const auto& it : m_gate_libraries)
226  {
227  res.push_back(it.second.get());
228  }
229  return res;
230  }
231  } // namespace gate_library_manager
232 } // namespace hal
static BooleanFunction Const(const BooleanFunction::Value &value)
Result< GatePin * > create_pin(const u32 id, const std::string &name, PinDirection direction, PinType type=PinType::none, bool create_group=true)
Definition: gate_type.cpp:157
void add_boolean_function(const std::string &name, const BooleanFunction &function)
Definition: gate_type.cpp:701
#define log_error(channel,...)
Definition: log.h:78
#define log_info(channel,...)
Definition: log.h:70
#define ERR(message)
Definition: result.h:53
#define OK(...)
Definition: result.h:49
#define ERR_APPEND(prev_error, message)
Definition: result.h:57
GateLibrary * get_gate_library_by_name(const std::string &lib_name)
std::vector< GateLibrary * > get_gate_libraries()
void remove(std::filesystem::path file_path)
std::vector< std::filesystem::path > get_all_path()
GateLibrary * get_gate_library(const std::string &file_path)
GateLibrary * load(std::filesystem::path file_path, bool reload)
bool save(std::filesystem::path file_path, GateLibrary *gate_lib, bool overwrite)
std::unique_ptr< GateLibrary > parse(std::filesystem::path file_path)
bool write(const GateLibrary *gate_lib, const std::filesystem::path &file_path)
std::vector< std::filesystem::path > get_gate_library_directories()
Definition: utils.cpp:185
std::filesystem::path get_file(std::string file_name, std::vector< std::filesystem::path > path_hints)
Definition: utils.cpp:219
std::string name