HAL
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 
49  {
50  public:
51  VerilogParser() = default;
52  ~VerilogParser() = 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 identifier_t = std::string;
72  using ranged_identifier_t = std::pair<std::string, std::vector<std::vector<u32>>>;
73  using numeral_t = std::vector<BooleanFunction::Value>;
74  using empty_t = std::monostate;
75  using assignment_t = std::variant<identifier_t, ranged_identifier_t, numeral_t, empty_t>;
76 
77  struct VerilogDataEntry
78  {
79  std::string m_name;
80  std::string m_type = "unknown";
81  std::string m_value = "";
82  };
83 
84  struct VerilogSignal
85  {
86  std::string m_name;
87  std::vector<std::vector<u32>> m_ranges;
88  std::vector<VerilogDataEntry> m_attributes;
89  std::vector<std::string> m_expanded_names;
90  };
91 
92  struct VerilogPort
93  {
94  std::string m_identifier;
95  std::string m_expression;
96  PinDirection m_direction;
97  std::vector<std::vector<u32>> m_ranges;
98  std::vector<std::string> m_expanded_identifiers;
99  };
100 
101  struct VerilogPortAssignment
102  {
103  std::optional<std::string> m_port_name;
104  std::vector<assignment_t> m_assignment;
105  };
106 
107  struct VerilogAssignment
108  {
109  std::vector<assignment_t> m_variable;
110  std::vector<assignment_t> m_assignment;
111  };
112 
113  struct VerilogInstance
114  {
115  std::string m_name;
116  std::string m_type;
117  bool m_is_module = false;
118  std::vector<VerilogPortAssignment> m_port_assignments;
119  std::vector<VerilogDataEntry> m_parameters;
120  std::vector<VerilogDataEntry> m_attributes;
121  std::vector<std::pair<std::string, std::string>> m_expanded_port_assignments;
122  };
123 
124  struct VerilogModule
125  {
126  public:
127  VerilogModule() = default;
128  ~VerilogModule() = default;
129 
136  bool operator<(const VerilogModule& other) const
137  {
138  return m_name < other.m_name;
139  }
140 
141  // module information
142  std::string m_name;
143  u32 m_line_number;
144  std::vector<VerilogDataEntry> m_attributes; // module attributes
145 
146  // ports
147  std::vector<std::unique_ptr<VerilogPort>> m_ports;
148  std::map<std::string, VerilogPort*> m_ports_by_identifier;
149  std::map<std::string, VerilogPort*> m_ports_by_expression;
150  std::map<std::string, std::string> m_expanded_port_identifiers_to_expressions;
151 
152  // signals
153  std::vector<std::unique_ptr<VerilogSignal>> m_signals;
154  std::map<std::string, VerilogSignal*> m_signals_by_name;
155 
156  // assignments
157  std::vector<VerilogAssignment> m_assignments;
158  std::vector<std::pair<std::string, std::string>> m_expanded_assignments;
159 
160  // instances
161  std::vector<std::unique_ptr<VerilogInstance>> m_instances;
162  std::map<std::string, VerilogInstance*> m_instances_by_name;
163  };
164 
165  std::stringstream m_fs;
166  std::filesystem::path m_path;
167 
168  // temporary netlist
169  Netlist* m_netlist = nullptr;
170 
171  // all modules of the netlist
172  std::vector<std::unique_ptr<VerilogModule>> m_modules;
173  std::unordered_map<std::string, VerilogModule*> m_modules_by_name;
174  std::string m_last_module;
175 
176  // token stream of entire input file
177  TokenStream<std::string> m_token_stream;
178 
179  // some caching
180  std::unordered_map<std::string, GateType*> m_gate_types;
181  std::unordered_map<std::string, GateType*> m_vcc_gate_types;
182  std::unordered_map<std::string, GateType*> m_gnd_gate_types;
183  std::unordered_map<Net*, std::vector<std::pair<Module*, u32>>> m_module_port_by_net;
184  std::unordered_map<Module*, std::vector<std::tuple<std::string, Net*>>> m_module_ports;
185 
186  // unique aliases
187  std::unordered_map<std::string, u32> m_module_instantiation_count;
188  std::unordered_map<std::string, u32> m_instance_name_occurences;
189  std::unordered_map<std::string, u32> m_net_name_occurences;
190 
191  // nets
192  Net* m_zero_net;
193  Net* m_one_net;
194  std::unordered_map<std::string, Net*> m_net_by_name;
195  std::vector<std::pair<std::string, std::string>> m_nets_to_merge;
196 
197  // parser settings
198  const std::string instance_name_seperator = "/";
199 
200  // parse HDL into intermediate format
201  void tokenize();
202  Result<std::monostate> parse_tokens();
203  Result<std::monostate> parse_module(std::vector<VerilogDataEntry>& attributes);
204  void parse_port_list(VerilogModule* module);
205  Result<std::monostate> parse_port_declaration_list(VerilogModule* module);
206  Result<std::monostate> parse_port_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
207  Result<std::monostate> parse_signal_definition(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
208  Result<std::monostate> parse_assignment(VerilogModule* module);
209  Result<std::monostate> parse_defparam(VerilogModule* module);
210  void parse_attribute(std::vector<VerilogDataEntry>& attributes);
211  Result<std::monostate> parse_instance(VerilogModule* module, std::vector<VerilogDataEntry>& attributes);
212  Result<std::monostate> parse_port_assign(VerilogInstance* instance);
213  Result<std::vector<VerilogDataEntry>> parse_parameter_assign();
214 
215  // construct netlist from intermediate format
216  Result<std::monostate> construct_netlist(VerilogModule* top_module);
217  Result<Module*>
218  instantiate_module(const std::string& instance_name, VerilogModule* verilog_module, Module* parent, const std::unordered_map<std::string, std::string>& parent_module_assignments);
219 
220  // helper functions
221  std::string get_unique_alias(const std::string& parent_name, const std::string& name, const std::unordered_map<std::string, u32>& name_occurences) const;
222  std::vector<u32> parse_range(TokenStream<std::string>& stream) const;
223  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;
224  std::vector<std::string> expand_ranges(const std::string& name, const std::vector<std::vector<u32>>& ranges) const;
225  Result<std::vector<BooleanFunction::Value>> get_binary_vector(std::string value) const;
226  Result<std::string> get_hex_from_literal(const Token<std::string>& value_token) const;
227  Result<std::pair<std::string, std::string>> parse_parameter_value(const Token<std::string>& value_token) const;
228  Result<std::vector<VerilogParser::assignment_t>> parse_assignment_expression(TokenStream<std::string>&& stream) const;
229  std::vector<std::string> expand_assignment_expression(VerilogModule* verilog_module, const std::vector<assignment_t>& vars) const;
230  };
231 } // namespace hal
#define NETLIST_API
Definition: arch_linux.h:30
~VerilogParser()=default
VerilogParser()=default
const Module * module(const Gate *g, const NodeBoxes &boxes)
std::unique_ptr< GateLibrary > parse(std::filesystem::path file_path)
PinDirection
Definition: pin_direction.h:36
quint32 u32
std::string name