Cerata
A library to generate structural hardware designs
design.cc
1 // Copyright 2018-2019 Delft University of Technology
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "cerata/vhdl/design.h"
16 
17 #include <string>
18 #include <unordered_map>
19 #include <vector>
20 #include <algorithm>
21 
22 #include "cerata/logging.h"
23 #include "cerata/vhdl/resolve.h"
24 #include "cerata/vhdl/declaration.h"
25 #include "cerata/vhdl/architecture.h"
26 
27 namespace cerata::vhdl {
28 
30  MultiBlock ret;
31 
32  // TODO(johanpel): when proper copy is in place, make a deep copy of the whole structure before sanitizing,
33  // in case multiple back ends are processing the graph. This currently modifies the original structure.
34 
35  // Resolve VHDL specific problems
36  // Make signals out of all ports, because of a whole bunch of reasons, including the most annoying locally static
37  // errors for port maps when wanting to use generics on the left hand side.
39 
40  // Place header
41  Block h;
42  if (!notice_.empty()) {
43  h << notice_;
44  h << Line();
45  }
46 
47  if (!libs_.empty()) {
48  h << Line(libs_);
49  h << Line();
50  ret << h;
51  }
52 
53  // Figure out potential libs and packages used for primitive components.
54  std::unordered_map<std::string, std::vector<std::string>> libs_and_packages;
55  for (const auto &c : component_->GetAllInstanceComponents()) {
56  if (c->meta().count(meta::PRIMITIVE) > 0) {
57  if (c->meta().at(meta::PRIMITIVE) == "true") {
58  std::string lib = c->meta().at(meta::LIBRARY);
59  std::string pkg = c->meta().at(meta::PACKAGE);
60  // Create the kv-pair if there is none yet
61  if (libs_and_packages.count(lib) == 0) {
62  libs_and_packages[lib] = std::vector<std::string>({pkg});
63  } else {
64  libs_and_packages.at(lib).push_back(pkg);
65  }
66  }
67  }
68  }
69 
70  // Sort and remove duplicate packages for each library
71  for (auto &v : libs_and_packages) {
72  auto &vec = v.second;
73  std::sort(vec.begin(), vec.end());
74  vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
75  }
76 
77  Block incl;
78  for (const auto &kv : libs_and_packages) {
79  incl << Line("library " + kv.first + ";");
80  for (const auto &pkg : kv.second) {
81  // TODO(johanpel): consider also allowing non-all.
82  incl << Line("use " + kv.first + "." + pkg + ".all;");
83  }
84  incl << Line();
85  }
86 
87  ret << incl;
88 
89  // Place any libraries from sub-components
90 
91  auto decl = Decl::Generate(*component_, true);
92  auto arch = Arch::Generate(*component_);
93 
94  ret << decl;
95  ret << Line();
96  ret << arch;
97 
98  return ret;
99 }
100 
101 } // namespace cerata::vhdl
cerata::Component::GetAllInstanceComponents
virtual std::vector< const Component * > GetAllInstanceComponents() const
Returns all unique Components that are referred to by child Instances of this graph.
Definition: graph.cc:268
cerata::vhdl::Design::notice_
std::string notice_
A potential copyright notice to place in the header.
Definition: design.h:33
cerata::vhdl::Design::Generate
MultiBlock Generate()
Generate the design VHDL code.
Definition: design.cc:29
cerata::vhdl::MultiBlock
A structure to hold multiple blocks.
Definition: block.h:77
cerata::vhdl::Design::component_
Component * component_
The component for this design file.
Definition: design.h:31
cerata::vhdl::Line
A line of code.
Definition: block.h:25
cerata::vhdl::Decl::Generate
static Block Generate(const Parameter &par, int depth=0)
Generate a parameter declaration as VHDL generic.
Definition: declaration.cc:72
cerata::vhdl::Design::libs_
std::string libs_
Libraries to place after the header.
Definition: design.h:35
cerata::vhdl::Block
A block of code.
Definition: block.h:50
cerata::vhdl::Arch::Generate
static MultiBlock Generate(const Component &comp)
Generate the VHDL architecture of a component.
Definition: architecture.cc:61
cerata::vhdl::Resolve::SignalizePorts
static Component * SignalizePorts(Component *comp)
Transforms the component, inserting signals for every instance port.
Definition: resolve.cc:69
cerata::vhdl
Contains everything related to the VHDL back-end.
Definition: architecture.cc:31