HAL  v4.5.0-83-g30c8f0afc
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;
106  std::string m_expression;
107  PinDirection m_direction;
108  std::vector<std::vector<u32>> m_ranges;
109  std::vector<std::string> m_expanded_identifiers;
110  };
111 
115  struct VerilogPortAssignment
116  {
117  std::optional<std::string> m_port_name;
118  std::vector<assignment_t> m_assignment;
119  };
120 
124  struct VerilogAssignment
125  {
126  std::vector<assignment_t> m_variable;
127  std::vector<assignment_t> m_assignment;
128  };
129 
133  struct VerilogInstance
134  {
135  std::string m_name;
136  std::string m_type;
137  bool m_is_module = false;
138  std::vector<VerilogPortAssignment> m_port_assignments;
139  std::vector<VerilogDataEntry> m_parameters;
140  std::vector<VerilogDataEntry> m_attributes;
141  std::vector<std::pair<std::string, std::string>> m_expanded_port_assignments;
142  };
143 
147  struct VerilogModule
148  {
149  public:
150  VerilogModule() = default;
151  ~VerilogModule() = default;
152 
159  bool operator<(const VerilogModule& other) const
160  {
161  return m_name < other.m_name;
162  }
163 
164  // module information
165  std::string m_name;
166  u32 m_line_number;
167  std::vector<VerilogDataEntry> m_attributes; // module attributes
168 
169  // ports
170  std::vector<std::unique_ptr<VerilogPort>> m_ports;
171  std::map<std::string, VerilogPort*> m_ports_by_identifier;
172  std::map<std::string, VerilogPort*> m_ports_by_expression;
173  std::map<std::string, std::string> m_expanded_port_identifiers_to_expressions;
174 
175  // signals
176  std::vector<std::unique_ptr<VerilogSignal>> m_signals;
177  std::map<std::string, VerilogSignal*> m_signals_by_name;
178 
179  // assignments
180  std::vector<VerilogAssignment> m_assignments;
181  std::vector<std::pair<std::string, std::string>> m_expanded_assignments;
182 
183  // instances
184  std::vector<std::unique_ptr<VerilogInstance>> m_instances;
185  std::map<std::string, VerilogInstance*> m_instances_by_name;
186  };
187 
188  std::stringstream m_fs;
189  std::filesystem::path m_path;
190 
191  // temporary netlist
192  Netlist* m_netlist = nullptr;
193 
194  // all modules of the netlist
195  std::vector<std::unique_ptr<VerilogModule>> m_modules;
196  std::unordered_map<std::string, VerilogModule*> m_modules_by_name;
197  std::string m_last_module;
198 
199  // token stream of entire input file
200  TokenStream<std::string> m_token_stream;
201 
202  // some caching
203  std::unordered_map<std::string, GateType*> m_gate_types;
204  std::unordered_map<std::string, GateType*> m_vcc_gate_types;
205  std::unordered_map<std::string, GateType*> m_gnd_gate_types;
206  std::unordered_map<Net*, std::vector<std::pair<Module*, u32>>> m_module_port_by_net;
207  std::unordered_map<Module*, std::vector<std::tuple<std::string, Net*>>> m_module_ports;
208 
209  // unique aliases
210  std::unordered_map<std::string, u32> m_module_instantiation_count;
211  std::unordered_map<std::string, u32> m_instance_name_occurences;
212  std::unordered_map<std::string, u32> m_net_name_occurences;
213 
214  // nets
215  Net* m_zero_net;
216  Net* m_one_net;
217  std::unordered_map<std::string, Net*> m_net_by_name;
218  std::vector<std::pair<std::string, std::string>> m_nets_to_merge;
219 
220  // parser settings
221  const std::string instance_name_seperator = "/";
222 
223  // parse HDL into intermediate format
224  void tokenize();
225  Result<std::monostate> parse_tokens();
226  Result<std::monostate> parse_module(std::vector<VerilogDataEntry>& attributes);
227  void parse_port_list(VerilogModule* module);
228  Result<std::monostate> parse_port_declaration_list(VerilogModule* module);
229  Result<std::monostate> parse_port_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
230  Result<std::monostate> parse_signal_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
231  Result<std::monostate> parse_assignment(VerilogModule* module);
232  Result<std::monostate> parse_defparam(VerilogModule* module);
233  void parse_attribute(std::vector<VerilogDataEntry>& attributes);
234  Result<std::monostate> parse_instance(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
235  Result<std::monostate> parse_port_assign(VerilogInstance* instance);
236  Result<std::vector<VerilogDataEntry>> parse_parameter_assign();
237 
238  // construct netlist from intermediate format
239  Result<std::monostate> construct_netlist(VerilogModule* top_module);
240  Result<Module*>
241  instantiate_module(const std::string& instance_name, VerilogModule* verilog_module, Module* parent, const std::unordered_map<std::string, std::string>& parent_module_assignments);
242 
243  // helper functions
244  std::string get_unique_alias(const std::string& parent_name, const std::string& name, const std::unordered_map<std::string, u32>& name_occurences) const;
245  std::vector<u32> parse_range(TokenStream<std::string>& stream) const;
246  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;
247  std::vector<std::string> expand_ranges(const std::string& name, const std::vector<std::vector<u32>>& ranges) const;
248  Result<std::vector<BooleanFunction::Value>> get_binary_vector(std::string value) const;
249  Result<std::string> get_hex_from_literal(const Token<std::string>& value_token) const;
250  Result<std::pair<std::string, std::string>> parse_parameter_value(const Token<std::string>& value_token) const;
251  Result<std::vector<VerilogParser::assignment_t>> parse_assignment_expression(TokenStream<std::string>&& stream) const;
252  std::vector<std::string> expand_assignment_expression(VerilogModule* verilog_module, const std::vector<assignment_t>& vars) const;
253  };
254 } // 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