HAL  v4.5.0-137-gacc899e29
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
verilog_parser.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
4 // Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
5 // Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
6 // Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 
26 #pragma once
27 
28 #include "hal_core/defines.h"
31 #include "hal_core/netlist/net.h"
35 
36 #include <optional>
37 #include <sstream>
38 #include <unordered_map>
39 #include <unordered_set>
40 #include <utility>
41 
42 namespace hal
43 {
44 
51  {
52  public:
53  VerilogParser() = default;
54  ~VerilogParser() = default;
55 
62  Result<std::monostate> parse(const std::filesystem::path& file_path) override;
63 
70  Result<std::unique_ptr<Netlist>> instantiate(const GateLibrary* gate_library) override;
71 
72  private:
73  using identifier_t = std::string;
74  using ranged_identifier_t = std::pair<std::string, std::vector<std::vector<u32>>>;
75  using numeral_t = std::vector<BooleanFunction::Value>;
76  using empty_t = std::monostate;
77  using assignment_t = std::variant<identifier_t, ranged_identifier_t, numeral_t, empty_t>;
78 
82  struct VerilogDataEntry
83  {
84  std::string m_name;
85  std::string m_type = "unknown";
86  std::string m_value = "";
87  };
88 
92  struct VerilogSignal
93  {
94  std::string m_name;
95  std::vector<std::vector<u32>> m_ranges;
96  std::vector<VerilogDataEntry> m_attributes;
97  std::vector<std::string> m_expanded_names;
98  };
99 
103  struct VerilogPort
104  {
105  std::string m_identifier;
110  std::vector<assignment_t> m_expression_parts;
111  PinDirection m_direction;
112  std::vector<std::vector<u32>> m_ranges;
113  std::vector<std::string> m_expanded_identifiers;
114  };
115 
119  struct VerilogPortAssignment
120  {
121  std::optional<std::string> m_port_name;
122  std::vector<assignment_t> m_assignment;
123  };
124 
128  struct VerilogAssignment
129  {
130  std::vector<assignment_t> m_variable;
131  std::vector<assignment_t> m_assignment;
132  };
133 
137  struct VerilogInstance
138  {
139  std::string m_name;
140  std::string m_type;
141  bool m_is_module = false;
142  std::vector<VerilogPortAssignment> m_port_assignments;
143  std::vector<VerilogDataEntry> m_parameters;
144  std::vector<VerilogDataEntry> m_attributes;
145  std::vector<std::pair<std::string, std::string>> m_expanded_port_assignments;
146  };
147 
151  struct VerilogModule
152  {
153  public:
154  VerilogModule() = default;
155  ~VerilogModule() = default;
156 
163  bool operator<(const VerilogModule& other) const
164  {
165  return m_name < other.m_name;
166  }
167 
168  // module information
169  std::string m_name;
170  u32 m_line_number;
171  std::vector<VerilogDataEntry> m_attributes; // module attributes
172 
173  // ports
174  std::vector<std::unique_ptr<VerilogPort>> m_ports;
175  std::map<std::string, VerilogPort*> m_ports_by_identifier;
176  std::map<std::string, VerilogPort*> m_ports_by_expression;
177  std::map<std::string, std::string> m_expanded_port_identifiers_to_expressions;
178 
179  // signals
180  std::vector<std::unique_ptr<VerilogSignal>> m_signals;
181  std::map<std::string, VerilogSignal*> m_signals_by_name;
182 
183  // assignments
184  std::vector<VerilogAssignment> m_assignments;
185  std::vector<std::pair<std::string, std::string>> m_expanded_assignments;
186 
187  // instances
188  std::vector<std::unique_ptr<VerilogInstance>> m_instances;
189  std::map<std::string, VerilogInstance*> m_instances_by_name;
190  };
191 
192  std::stringstream m_fs;
193  std::filesystem::path m_path;
194 
195  // temporary netlist
196  Netlist* m_netlist = nullptr;
197 
198  // all modules of the netlist
199  std::vector<std::unique_ptr<VerilogModule>> m_modules;
200  std::unordered_map<std::string, VerilogModule*> m_modules_by_name;
201  std::string m_last_module;
202 
203  // token stream of entire input file
204  TokenStream<std::string> m_token_stream;
205 
206  // some caching
207  std::unordered_map<std::string, GateType*> m_gate_types;
208  std::unordered_map<std::string, GateType*> m_vcc_gate_types;
209  std::unordered_map<std::string, GateType*> m_gnd_gate_types;
210  std::unordered_map<Net*, std::vector<std::pair<Module*, u32>>> m_module_port_by_net;
211  std::unordered_map<Module*, std::vector<std::tuple<std::string, Net*>>> m_module_ports;
212 
213  // unique aliases
214  std::unordered_map<std::string, u32> m_module_instantiation_count;
215  std::unordered_map<std::string, u32> m_instance_name_occurences;
216  std::unordered_map<std::string, u32> m_net_name_occurences;
217 
218  // nets
219  Net* m_zero_net;
220  Net* m_one_net;
221  std::unordered_map<std::string, Net*> m_net_by_name;
222  std::vector<std::pair<std::string, std::string>> m_nets_to_merge;
223 
224  // parser settings
225  const std::string instance_name_seperator = "/";
226 
227  // parse HDL into intermediate format
228  void tokenize();
229  Result<std::monostate> parse_tokens();
230  Result<std::monostate> parse_module(std::vector<VerilogDataEntry>& attributes);
231  Result<std::monostate> parse_port_list(VerilogModule* module);
232  Result<std::monostate> parse_port_declaration_list(VerilogModule* module);
233  Result<std::monostate> parse_port_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
234  Result<std::monostate> parse_signal_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
235  Result<std::monostate> parse_assignment(VerilogModule* module);
236  Result<std::monostate> parse_defparam(VerilogModule* module);
237  void parse_attribute(std::vector<VerilogDataEntry>& attributes);
238  Result<std::monostate> parse_instance(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
239  Result<std::monostate> parse_port_assign(VerilogInstance* instance);
240  Result<std::vector<VerilogDataEntry>> parse_parameter_assign();
241 
242  // construct netlist from intermediate format
243  Result<std::monostate> construct_netlist(VerilogModule* top_module);
244  Result<Module*>
245  instantiate_module(const std::string& instance_name, VerilogModule* verilog_module, Module* parent, const std::unordered_map<std::string, std::string>& parent_module_assignments);
246 
247  // helper functions
248  std::string get_unique_alias(const std::string& parent_name, const std::string& name, const std::unordered_map<std::string, u32>& name_occurences) const;
249  std::vector<u32> parse_range(TokenStream<std::string>& stream) const;
250  void expand_ranges_recursively(std::vector<std::string>& expanded_names, const std::string& current_name, const std::vector<std::vector<u32>>& ranges, u32 dimension) const;
251  std::vector<std::string> expand_ranges(const std::string& name, const std::vector<std::vector<u32>>& ranges) const;
252  Result<std::vector<BooleanFunction::Value>> get_binary_vector(std::string value) const;
253  Result<std::string> get_hex_from_literal(const Token<std::string>& value_token) const;
254  Result<std::pair<std::string, std::string>> parse_parameter_value(const Token<std::string>& value_token) const;
255  Result<std::vector<VerilogParser::assignment_t>> parse_assignment_expression(TokenStream<std::string>&& stream) const;
256  std::vector<std::string> expand_assignment_expression(VerilogModule* verilog_module, const std::vector<assignment_t>& vars) const;
257  };
258 } // namespace hal
#define NETLIST_API
Definition: arch_linux.h:30
~VerilogParser()=default
VerilogParser()=default
uint32_t u32
Definition: defines.h:41
const Module * module(const Gate *g, const NodeBoxes &boxes)
std::unique_ptr< GateLibrary > parse(std::filesystem::path file_path)
Definition: defines.h:45
PinDirection
Definition: pin_direction.h:36
std::string name
std::unique_ptr< BasePluginInterface > instance