HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
vhdl_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 {
51  {
52  public:
53  VHDLParser() = default;
54  ~VHDLParser() = 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 ci_string = core_strings::CaseInsensitiveString;
74  using identifier_t = ci_string;
75  using ranged_identifier_t = std::pair<ci_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 VhdlDataEntry
84  {
85  u32 m_line_number;
86  std::string m_name;
87  std::string m_type = "unknown";
88  std::string m_value = "";
89  };
90 
94  struct VhdlSignal
95  {
96  ci_string m_name;
97  std::vector<std::vector<u32>> m_ranges;
98  std::vector<VhdlDataEntry> m_attributes;
99  std::vector<ci_string> m_expanded_names;
100  };
101 
105  struct VhdlPort
106  {
107  ci_string m_identifier;
108  PinDirection m_direction;
109  std::vector<std::vector<u32>> m_ranges;
110  std::vector<ci_string> m_expanded_identifiers;
111  };
112 
116  struct VhdlPortAssignment
117  {
118  std::optional<assignment_t> m_port;
119  std::vector<assignment_t> m_assignment;
120  };
121 
125  struct VhdlAssignment
126  {
127  std::vector<assignment_t> m_variable;
128  std::vector<assignment_t> m_assignment;
129  };
130 
134  struct VhdlInstance
135  {
136  ci_string m_name;
137  ci_string m_type;
138  bool m_is_entity = false;
139  std::vector<VhdlPortAssignment> m_port_assignments;
140  std::vector<VhdlDataEntry> m_generics;
141  std::vector<VhdlDataEntry> m_attributes;
142  std::vector<std::pair<ci_string, ci_string>> m_expanded_port_assignments;
143  };
144 
148  struct VhdlEntity
149  {
150  public:
151  VhdlEntity() = default;
152  ~VhdlEntity() = default;
153 
160  bool operator<(const VhdlEntity& other) const
161  {
162  return m_name < other.m_name;
163  }
164 
165  // module information
166  ci_string m_name;
167  u32 m_line_number;
168  std::vector<VhdlDataEntry> m_attributes; // module attributes
169 
170  // ports
171  std::vector<std::unique_ptr<VhdlPort>> m_ports;
172  std::map<ci_string, VhdlPort*> m_ports_by_identifier;
173  std::set<ci_string> m_expanded_port_identifiers;
174 
175  // signals
176  std::vector<std::unique_ptr<VhdlSignal>> m_signals;
177  std::map<ci_string, VhdlSignal*> m_signals_by_name;
178 
179  // assignments
180  std::vector<VhdlAssignment> m_assignments;
181  std::vector<std::pair<ci_string, ci_string>> m_expanded_assignments;
182 
183  // instances
184  std::vector<std::unique_ptr<VhdlInstance>> m_instances;
185  std::map<ci_string, VhdlInstance*> m_instances_by_name;
186  };
187 
188  enum class AttributeTarget
189  {
190  ENTITY,
191  INSTANCE,
192  SIGNAL
193  };
194 
195  using attribute_buffer_t = std::map<AttributeTarget, std::map<ci_string, VhdlDataEntry>>;
196 
197  std::stringstream m_fs;
198  std::filesystem::path m_path;
199 
200  // temporary netlist
201  Netlist* m_netlist = nullptr;
202 
203  // all entities of the netlist
204  std::vector<std::unique_ptr<VhdlEntity>> m_entities;
205  std::unordered_map<ci_string, VhdlEntity*> m_entities_by_name;
206  ci_string m_last_entity;
207 
208  // std::unordered_map<ci_string, VhdlEntity> m_entities;
209  // ci_string m_last_entity;
210 
211  // token stream of entire input file
212  TokenStream<ci_string> m_token_stream;
213 
214  // some caching
215  std::unordered_map<ci_string, GateType*> m_gate_types;
216  std::unordered_map<ci_string, GateType*> m_vcc_gate_types;
217  std::unordered_map<ci_string, GateType*> m_gnd_gate_types;
218  std::unordered_map<Net*, std::vector<std::pair<Module*, u32>>> m_module_port_by_net;
219  std::unordered_map<Module*, std::vector<std::pair<std::string, Net*>>> m_module_ports;
220  attribute_buffer_t m_attribute_buffer;
221  std::unordered_map<ci_string, ci_string> m_attribute_types;
222 
223  // library prefixes
224  std::set<ci_string> m_libraries;
225 
226  // unique aliases
227  std::unordered_map<ci_string, u32> m_signal_name_occurrences;
228  std::unordered_map<ci_string, u32> m_instance_name_occurrences;
229 
230  // nets
231  Net* m_zero_net;
232  Net* m_one_net;
233  std::unordered_map<ci_string, Net*> m_net_by_name;
234  std::vector<std::pair<ci_string, ci_string>> m_nets_to_merge;
235 
236  // parse HDL into intermediate format
237  void tokenize();
238  Result<std::monostate> parse_tokens();
239  void parse_library();
240  Result<std::monostate> parse_entity();
241  Result<std::monostate> parse_port_definitons(VhdlEntity* vhdl_entity);
242  Result<std::monostate> parse_attribute();
243  Result<std::monostate> parse_architecture();
244  Result<std::monostate> parse_architecture_header(VhdlEntity* vhdl_entity);
245  Result<std::monostate> parse_signal_definition(VhdlEntity* vhdl_entity);
246  Result<std::monostate> parse_architecture_body(VhdlEntity* vhdl_entity);
247  Result<std::monostate> parse_assignment(VhdlEntity* vhdl_entity);
248  Result<std::monostate> parse_instance(VhdlEntity* vhdl_entity);
249  Result<std::monostate> parse_port_assign(VhdlInstance* instance);
250  Result<std::monostate> parse_generic_assign(VhdlInstance* instance);
251  Result<std::monostate> assign_attributes(VhdlEntity* vhdl_entity);
252 
253  // construct netlist from intermediate format
254  Result<std::monostate> construct_netlist(VhdlEntity* top_entity);
255  Result<Module*> instantiate_entity(const ci_string& instance_name, VhdlEntity* vhdl_entity, Module* parent, const std::unordered_map<ci_string, ci_string>& parent_module_assignments);
256 
257  // helper functions
258  ci_string get_unique_alias(const ci_string& parent_name, const ci_string& name, const std::unordered_map<ci_string, u32>& name_occurences) const;
259  std::vector<u32> parse_range(TokenStream<ci_string>& range_stream) const;
260  Result<std::vector<std::vector<u32>>> parse_signal_ranges(TokenStream<ci_string>& signal_stream) const;
261  void expand_ranges_recursively(std::vector<ci_string>& expanded_names, const ci_string& current_name, const std::vector<std::vector<u32>>& ranges, u32 dimension) const;
262  std::vector<ci_string> expand_ranges(const ci_string& name, const std::vector<std::vector<u32>>& ranges) const;
263  Result<std::vector<BooleanFunction::Value>> get_binary_vector(std::string value) const;
264  Result<std::string> get_hex_from_literal(const Token<ci_string>& value_token) const;
265  Result<std::vector<assignment_t>> parse_assignment_expression(TokenStream<ci_string>&& stream) const;
266  Result<std::vector<ci_string>> expand_assignment_expression(VhdlEntity* vhdl_entity, const std::vector<assignment_t>& vars) const;
267  };
268 } // namespace hal
#define NETLIST_API
Definition: arch_linux.h:30
~VHDLParser()=default
VHDLParser()=default
uint32_t u32
Definition: defines.h:41
std::basic_string< char, CaseInsensitiveCharTraits > CaseInsensitiveString
std::unique_ptr< GateLibrary > parse(std::filesystem::path file_path)
Definition: defines.h:45
PinDirection
Definition: pin_direction.h:36
std::string name