HAL
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 {
49  {
50  public:
51  VHDLParser() = default;
52  ~VHDLParser() = default;
53 
60  Result<std::monostate> parse(const std::filesystem::path& file_path) override;
61 
68  Result<std::unique_ptr<Netlist>> instantiate(const GateLibrary* gate_library) override;
69 
70  private:
71  using ci_string = core_strings::CaseInsensitiveString;
72  using identifier_t = ci_string;
73  using ranged_identifier_t = std::pair<ci_string, std::vector<std::vector<u32>>>;
74  using numeral_t = std::vector<BooleanFunction::Value>;
75  using empty_t = std::monostate;
76  using assignment_t = std::variant<identifier_t, ranged_identifier_t, numeral_t, empty_t>;
77 
78  struct VhdlDataEntry
79  {
80  u32 m_line_number;
81  std::string m_name;
82  std::string m_type = "unknown";
83  std::string m_value = "";
84  };
85 
86  struct VhdlSignal
87  {
88  ci_string m_name;
89  std::vector<std::vector<u32>> m_ranges;
90  std::vector<VhdlDataEntry> m_attributes;
91  std::vector<ci_string> m_expanded_names;
92  };
93 
94  struct VhdlPort
95  {
96  ci_string m_identifier;
97  PinDirection m_direction;
98  std::vector<std::vector<u32>> m_ranges;
99  std::vector<ci_string> m_expanded_identifiers;
100  };
101 
102  struct VhdlPortAssignment
103  {
104  std::optional<assignment_t> m_port;
105  std::vector<assignment_t> m_assignment;
106  };
107 
108  struct VhdlAssignment
109  {
110  std::vector<assignment_t> m_variable;
111  std::vector<assignment_t> m_assignment;
112  };
113 
114  struct VhdlInstance
115  {
116  ci_string m_name;
117  ci_string m_type;
118  bool m_is_entity = false;
119  std::vector<VhdlPortAssignment> m_port_assignments;
120  std::vector<VhdlDataEntry> m_generics;
121  std::vector<VhdlDataEntry> m_attributes;
122  std::vector<std::pair<ci_string, ci_string>> m_expanded_port_assignments;
123  };
124 
125  struct VhdlEntity
126  {
127  public:
128  VhdlEntity() = default;
129  ~VhdlEntity() = default;
130 
137  bool operator<(const VhdlEntity& other) const
138  {
139  return m_name < other.m_name;
140  }
141 
142  // module information
143  ci_string m_name;
144  u32 m_line_number;
145  std::vector<VhdlDataEntry> m_attributes; // module attributes
146 
147  // ports
148  std::vector<std::unique_ptr<VhdlPort>> m_ports;
149  std::map<ci_string, VhdlPort*> m_ports_by_identifier;
150  std::set<ci_string> m_expanded_port_identifiers;
151 
152  // signals
153  std::vector<std::unique_ptr<VhdlSignal>> m_signals;
154  std::map<ci_string, VhdlSignal*> m_signals_by_name;
155 
156  // assignments
157  std::vector<VhdlAssignment> m_assignments;
158  std::vector<std::pair<ci_string, ci_string>> m_expanded_assignments;
159 
160  // instances
161  std::vector<std::unique_ptr<VhdlInstance>> m_instances;
162  std::map<ci_string, VhdlInstance*> m_instances_by_name;
163  };
164 
165  enum class AttributeTarget
166  {
167  ENTITY,
168  INSTANCE,
169  SIGNAL
170  };
171 
172  using attribute_buffer_t = std::map<AttributeTarget, std::map<ci_string, VhdlDataEntry>>;
173 
174  std::stringstream m_fs;
175  std::filesystem::path m_path;
176 
177  // temporary netlist
178  Netlist* m_netlist = nullptr;
179 
180  // all entities of the netlist
181  std::vector<std::unique_ptr<VhdlEntity>> m_entities;
182  std::unordered_map<ci_string, VhdlEntity*> m_entities_by_name;
183  ci_string m_last_entity;
184 
185  // std::unordered_map<ci_string, VhdlEntity> m_entities;
186  // ci_string m_last_entity;
187 
188  // token stream of entire input file
189  TokenStream<ci_string> m_token_stream;
190 
191  // some caching
192  std::unordered_map<ci_string, GateType*> m_gate_types;
193  std::unordered_map<ci_string, GateType*> m_vcc_gate_types;
194  std::unordered_map<ci_string, GateType*> m_gnd_gate_types;
195  std::unordered_map<Net*, std::vector<std::pair<Module*, u32>>> m_module_port_by_net;
196  std::unordered_map<Module*, std::vector<std::pair<std::string, Net*>>> m_module_ports;
197  attribute_buffer_t m_attribute_buffer;
198  std::unordered_map<ci_string, ci_string> m_attribute_types;
199 
200  // library prefixes
201  std::set<ci_string> m_libraries;
202 
203  // unique aliases
204  std::unordered_map<ci_string, u32> m_signal_name_occurrences;
205  std::unordered_map<ci_string, u32> m_instance_name_occurrences;
206 
207  // nets
208  Net* m_zero_net;
209  Net* m_one_net;
210  std::unordered_map<ci_string, Net*> m_net_by_name;
211  std::vector<std::pair<ci_string, ci_string>> m_nets_to_merge;
212 
213  // parse HDL into intermediate format
214  void tokenize();
215  Result<std::monostate> parse_tokens();
216  void parse_library();
217  Result<std::monostate> parse_entity();
218  Result<std::monostate> parse_port_definitons(VhdlEntity* vhdl_entity);
219  Result<std::monostate> parse_attribute();
220  Result<std::monostate> parse_architecture();
221  Result<std::monostate> parse_architecture_header(VhdlEntity* vhdl_entity);
222  Result<std::monostate> parse_signal_definition(VhdlEntity* vhdl_entity);
223  Result<std::monostate> parse_architecture_body(VhdlEntity* vhdl_entity);
224  Result<std::monostate> parse_assignment(VhdlEntity* vhdl_entity);
225  Result<std::monostate> parse_instance(VhdlEntity* vhdl_entity);
226  Result<std::monostate> parse_port_assign(VhdlInstance* instance);
227  Result<std::monostate> parse_generic_assign(VhdlInstance* instance);
228  Result<std::monostate> assign_attributes(VhdlEntity* vhdl_entity);
229 
230  // construct netlist from intermediate format
231  Result<std::monostate> construct_netlist(VhdlEntity* top_entity);
232  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);
233 
234  // helper functions
235  ci_string get_unique_alias(const ci_string& parent_name, const ci_string& name, const std::unordered_map<ci_string, u32>& name_occurences) const;
236  std::vector<u32> parse_range(TokenStream<ci_string>& range_stream) const;
237  Result<std::vector<std::vector<u32>>> parse_signal_ranges(TokenStream<ci_string>& signal_stream) const;
238  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;
239  std::vector<ci_string> expand_ranges(const ci_string& name, const std::vector<std::vector<u32>>& ranges) const;
240  Result<std::vector<BooleanFunction::Value>> get_binary_vector(std::string value) const;
241  Result<std::string> get_hex_from_literal(const Token<ci_string>& value_token) const;
242  Result<std::vector<assignment_t>> parse_assignment_expression(TokenStream<ci_string>&& stream) const;
243  Result<std::vector<ci_string>> expand_assignment_expression(VhdlEntity* vhdl_entity, const std::vector<assignment_t>& vars) const;
244  };
245 } // namespace hal
#define NETLIST_API
Definition: arch_linux.h:30
~VHDLParser()=default
VHDLParser()=default
std::basic_string< char, CaseInsensitiveCharTraits > CaseInsensitiveString
std::unique_ptr< GateLibrary > parse(std::filesystem::path file_path)
PinDirection
Definition: pin_direction.h:36
quint32 u32
std::string name