HAL  v4.5.0-257-ge24279b4e
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"
36 
37 #include <optional>
38 #include <sstream>
39 #include <unordered_map>
40 #include <unordered_set>
41 #include <utility>
42 
43 namespace hal
44 {
45 
52  {
53  public:
54  VerilogParser() = default;
55  ~VerilogParser() = default;
56 
63  Result<std::monostate> parse(const std::filesystem::path& file_path) override;
64 
71  Result<std::unique_ptr<Netlist>> instantiate(const GateLibrary* gate_library) override;
72 
73  private:
74  using identifier_t = std::string;
75  using ranged_identifier_t = std::pair<std::string, std::vector<std::vector<u32>>>;
76  using numeral_t = std::vector<BooleanFunction::Value>;
77  using empty_t = std::monostate;
78  using assignment_t = std::variant<identifier_t, ranged_identifier_t, numeral_t, empty_t>;
79 
83  struct VerilogDataEntry
84  {
85  std::string m_name;
86  std::string m_type = "unknown";
87  std::string m_value = "";
88  std::optional<Parameter> m_parameter; // populated by parse_parameter_value; empty for attributes
89  };
90 
94  struct VerilogSignal
95  {
96  std::string m_name;
97  std::vector<std::vector<u32>> m_ranges;
98  std::vector<VerilogDataEntry> m_attributes;
99  std::vector<std::string> m_expanded_names;
100  };
101 
105  struct VerilogPort
106  {
107  std::string m_identifier;
112  std::vector<assignment_t> m_expression_parts;
113  PinDirection m_direction;
114  std::vector<std::vector<u32>> m_ranges;
115  std::vector<std::string> m_expanded_identifiers;
116  };
117 
121  struct VerilogPortAssignment
122  {
123  std::optional<std::string> m_port_name;
124  std::vector<assignment_t> m_assignment;
125  };
126 
130  struct VerilogAssignment
131  {
132  std::vector<assignment_t> m_variable;
133  std::vector<assignment_t> m_assignment;
134  };
135 
139  struct VerilogInstance
140  {
141  std::string m_name;
142  std::string m_type;
143  bool m_is_module = false;
144  std::vector<VerilogPortAssignment> m_port_assignments;
145  std::vector<VerilogDataEntry> m_parameters;
146  std::vector<VerilogDataEntry> m_attributes;
147  std::vector<std::pair<std::string, std::string>> m_expanded_port_assignments;
148  };
149 
153  struct VerilogModule
154  {
155  public:
156  VerilogModule() = default;
157  ~VerilogModule() = default;
158 
165  bool operator<(const VerilogModule& other) const
166  {
167  return m_name < other.m_name;
168  }
169 
170  // module information
171  std::string m_name;
172  u32 m_line_number;
173  std::vector<VerilogDataEntry> m_attributes; // module attributes
174 
175  // ports
176  std::vector<std::unique_ptr<VerilogPort>> m_ports;
177  std::map<std::string, VerilogPort*> m_ports_by_identifier;
178  std::map<std::string, VerilogPort*> m_ports_by_expression;
179  std::map<std::string, std::string> m_expanded_port_identifiers_to_expressions;
180 
181  // signals
182  std::vector<std::unique_ptr<VerilogSignal>> m_signals;
183  std::map<std::string, VerilogSignal*> m_signals_by_name;
184 
185  // assignments
186  std::vector<VerilogAssignment> m_assignments;
187  std::vector<std::pair<std::string, std::string>> m_expanded_assignments;
188 
189  // instances
190  std::vector<std::unique_ptr<VerilogInstance>> m_instances;
191  std::map<std::string, VerilogInstance*> m_instances_by_name;
192  };
193 
194  std::stringstream m_fs;
195  std::filesystem::path m_path;
196 
197  // temporary netlist
198  Netlist* m_netlist = nullptr;
199 
200  // all modules of the netlist
201  std::vector<std::unique_ptr<VerilogModule>> m_modules;
202  std::unordered_map<std::string, VerilogModule*> m_modules_by_name;
203  std::string m_last_module;
204 
205  // token stream of entire input file
206  TokenStream<std::string> m_token_stream;
207 
208  // some caching
209  std::unordered_map<std::string, GateType*> m_gate_types;
210  std::unordered_map<std::string, GateType*> m_vcc_gate_types;
211  std::unordered_map<std::string, GateType*> m_gnd_gate_types;
212  std::unordered_map<Net*, std::vector<std::pair<Module*, u32>>> m_module_port_by_net;
213  std::unordered_map<Module*, std::vector<std::tuple<std::string, Net*>>> m_module_ports;
214 
215  // unique aliases
216  std::unordered_map<std::string, u32> m_module_instantiation_count;
217  std::unordered_map<std::string, u32> m_instance_name_occurences;
218  std::unordered_map<std::string, u32> m_net_name_occurences;
219 
220  // nets
221  Net* m_zero_net;
222  Net* m_one_net;
223  std::unordered_map<std::string, Net*> m_net_by_name;
224  std::vector<std::pair<std::string, std::string>> m_nets_to_merge;
225 
226  // parser settings
227  const std::string instance_name_seperator = "/";
228 
229  // parse HDL into intermediate format
230  void tokenize();
231  Result<std::monostate> parse_tokens();
232  Result<std::monostate> parse_module(std::vector<VerilogDataEntry>& attributes);
233  Result<std::monostate> parse_port_list(VerilogModule* module);
234  Result<std::monostate> parse_port_declaration_list(VerilogModule* module);
235  Result<std::monostate> parse_port_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
236  Result<std::monostate> parse_signal_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
237  Result<std::monostate> parse_assignment(VerilogModule* module);
238  Result<std::monostate> parse_defparam(VerilogModule* module);
239  void parse_attribute(std::vector<VerilogDataEntry>& attributes);
240  Result<std::monostate> parse_instance(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
241  Result<std::monostate> parse_port_assign(VerilogInstance* instance);
242  Result<std::vector<VerilogDataEntry>> parse_parameter_assign();
243 
244  // construct netlist from intermediate format
245  Result<std::monostate> construct_netlist(VerilogModule* top_module);
246  Result<Module*>
247  instantiate_module(const std::string& instance_name, VerilogModule* verilog_module, Module* parent, const std::unordered_map<std::string, std::string>& parent_module_assignments);
248 
249  // helper functions
250  std::string get_unique_alias(const std::string& parent_name, const std::string& name, const std::unordered_map<std::string, u32>& name_occurences) const;
251  std::vector<u32> parse_range(TokenStream<std::string>& stream) const;
252  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;
253  std::vector<std::string> expand_ranges(const std::string& name, const std::vector<std::vector<u32>>& ranges) const;
254  Result<std::vector<BooleanFunction::Value>> get_binary_vector(std::string value) const;
255  Result<std::string> get_hex_from_literal(const Token<std::string>& value_token) const;
256  Result<std::pair<Parameter, std::string>> parse_parameter_value(const std::string& name, const Token<std::string>& value_token) const;
257  Result<std::vector<VerilogParser::assignment_t>> parse_assignment_expression(TokenStream<std::string>&& stream) const;
258  std::vector<std::string> expand_assignment_expression(VerilogModule* verilog_module, const std::vector<assignment_t>& vars) const;
259  };
260 } // 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