HAL  v4.5.0-254-g8f9f6a423
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"
37 
38 #include <optional>
39 #include <sstream>
40 #include <unordered_map>
41 #include <unordered_set>
42 #include <utility>
43 
44 namespace hal
45 {
52  {
53  public:
54  VHDLParser() = default;
55  ~VHDLParser() = 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 ci_string = core_strings::CaseInsensitiveString;
75  using identifier_t = ci_string;
76  using ranged_identifier_t = std::pair<ci_string, std::vector<std::vector<u32>>>;
77  using numeral_t = std::vector<BooleanFunction::Value>;
78  using empty_t = std::monostate;
79  using assignment_t = std::variant<identifier_t, ranged_identifier_t, numeral_t, empty_t>;
80 
84  struct VhdlDataEntry
85  {
86  u32 m_line_number;
87  std::string m_name;
88  std::string m_type = "unknown"; // free-form data-type tag (only used for attributes today)
89  std::string m_value = ""; // value string (passed to set_data for attributes; to set_parameter for generics)
90  std::optional<Parameter> m_parameter; // populated by parse_generic_assign; empty for attributes
91  };
92 
96  struct VhdlSignal
97  {
98  ci_string m_name;
99  std::vector<std::vector<u32>> m_ranges;
100  std::vector<VhdlDataEntry> m_attributes;
101  std::vector<ci_string> m_expanded_names;
102  };
103 
107  struct VhdlPort
108  {
109  ci_string m_identifier;
110  PinDirection m_direction;
111  std::vector<std::vector<u32>> m_ranges;
112  std::vector<ci_string> m_expanded_identifiers;
113  };
114 
118  struct VhdlPortAssignment
119  {
120  std::optional<assignment_t> m_port;
121  std::vector<assignment_t> m_assignment;
122  };
123 
127  struct VhdlAssignment
128  {
129  std::vector<assignment_t> m_variable;
130  std::vector<assignment_t> m_assignment;
131  };
132 
136  struct VhdlInstance
137  {
138  ci_string m_name;
139  ci_string m_type;
140  bool m_is_entity = false;
141  std::vector<VhdlPortAssignment> m_port_assignments;
142  std::vector<VhdlDataEntry> m_generics;
143  std::vector<VhdlDataEntry> m_attributes;
144  std::vector<std::pair<ci_string, ci_string>> m_expanded_port_assignments;
145  };
146 
150  struct VhdlEntity
151  {
152  public:
153  VhdlEntity() = default;
154  ~VhdlEntity() = default;
155 
162  bool operator<(const VhdlEntity& other) const
163  {
164  return m_name < other.m_name;
165  }
166 
167  // module information
168  ci_string m_name;
169  u32 m_line_number;
170  std::vector<VhdlDataEntry> m_attributes; // module attributes
171 
172  // ports
173  std::vector<std::unique_ptr<VhdlPort>> m_ports;
174  std::map<ci_string, VhdlPort*> m_ports_by_identifier;
175  std::set<ci_string> m_expanded_port_identifiers;
176 
177  // signals
178  std::vector<std::unique_ptr<VhdlSignal>> m_signals;
179  std::map<ci_string, VhdlSignal*> m_signals_by_name;
180 
181  // assignments
182  std::vector<VhdlAssignment> m_assignments;
183  std::vector<std::pair<ci_string, ci_string>> m_expanded_assignments;
184 
185  // instances
186  std::vector<std::unique_ptr<VhdlInstance>> m_instances;
187  std::map<ci_string, VhdlInstance*> m_instances_by_name;
188  };
189 
190  enum class AttributeTarget
191  {
192  ENTITY,
193  INSTANCE,
194  SIGNAL
195  };
196 
197  using attribute_buffer_t = std::map<AttributeTarget, std::map<ci_string, VhdlDataEntry>>;
198 
199  std::stringstream m_fs;
200  std::filesystem::path m_path;
201 
202  // temporary netlist
203  Netlist* m_netlist = nullptr;
204 
205  // all entities of the netlist
206  std::vector<std::unique_ptr<VhdlEntity>> m_entities;
207  std::unordered_map<ci_string, VhdlEntity*> m_entities_by_name;
208  ci_string m_last_entity;
209 
210  // std::unordered_map<ci_string, VhdlEntity> m_entities;
211  // ci_string m_last_entity;
212 
213  // token stream of entire input file
214  TokenStream<ci_string> m_token_stream;
215 
216  // some caching
217  std::unordered_map<ci_string, GateType*> m_gate_types;
218  std::unordered_map<ci_string, GateType*> m_vcc_gate_types;
219  std::unordered_map<ci_string, GateType*> m_gnd_gate_types;
220  std::unordered_map<Net*, std::vector<std::pair<Module*, u32>>> m_module_port_by_net;
221  std::unordered_map<Module*, std::vector<std::pair<std::string, Net*>>> m_module_ports;
222  attribute_buffer_t m_attribute_buffer;
223  std::unordered_map<ci_string, ci_string> m_attribute_types;
224 
225  // library prefixes
226  std::set<ci_string> m_libraries;
227 
228  // unique aliases
229  std::unordered_map<ci_string, u32> m_signal_name_occurrences;
230  std::unordered_map<ci_string, u32> m_instance_name_occurrences;
231 
232  // nets
233  Net* m_zero_net;
234  Net* m_one_net;
235  std::unordered_map<ci_string, Net*> m_net_by_name;
236  std::vector<std::pair<ci_string, ci_string>> m_nets_to_merge;
237 
238  // parse HDL into intermediate format
239  void tokenize();
240  Result<std::monostate> parse_tokens();
241  void parse_library();
242  Result<std::monostate> parse_entity();
243  Result<std::monostate> parse_port_definitons(VhdlEntity* vhdl_entity);
244  Result<std::monostate> parse_attribute();
245  Result<std::monostate> parse_architecture();
246  Result<std::monostate> parse_architecture_header(VhdlEntity* vhdl_entity);
247  Result<std::monostate> parse_signal_definition(VhdlEntity* vhdl_entity);
248  Result<std::monostate> parse_architecture_body(VhdlEntity* vhdl_entity);
249  Result<std::monostate> parse_assignment(VhdlEntity* vhdl_entity);
250  Result<std::monostate> parse_instance(VhdlEntity* vhdl_entity);
251  Result<std::monostate> parse_port_assign(VhdlInstance* instance);
252  Result<std::monostate> parse_generic_assign(VhdlInstance* instance);
253  Result<std::monostate> assign_attributes(VhdlEntity* vhdl_entity);
254 
255  // construct netlist from intermediate format
256  Result<std::monostate> construct_netlist(VhdlEntity* top_entity);
257  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);
258 
259  // helper functions
260  ci_string get_unique_alias(const ci_string& parent_name, const ci_string& name, const std::unordered_map<ci_string, u32>& name_occurences) const;
261  std::vector<u32> parse_range(TokenStream<ci_string>& range_stream) const;
262  Result<std::vector<std::vector<u32>>> parse_signal_ranges(TokenStream<ci_string>& signal_stream) const;
263  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;
264  std::vector<ci_string> expand_ranges(const ci_string& name, const std::vector<std::vector<u32>>& ranges) const;
265  Result<std::vector<BooleanFunction::Value>> get_binary_vector(std::string value) const;
266  Result<std::string> get_hex_from_literal(const Token<ci_string>& value_token) const;
267  Result<std::vector<assignment_t>> parse_assignment_expression(TokenStream<ci_string>&& stream) const;
268  Result<std::vector<ci_string>> expand_assignment_expression(VhdlEntity* vhdl_entity, const std::vector<assignment_t>& vars) const;
269  };
270 } // 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
std::unique_ptr< BasePluginInterface > instance