Cerata
A library to generate structural hardware designs
vhdl.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/vhdl.h"
16 
17 #include <vector>
18 #include <string>
19 #include <memory>
20 
21 #include "cerata/logging.h"
22 #include "cerata/utils.h"
23 
24 #include "cerata/vhdl/defaults.h"
25 
26 namespace cerata::vhdl {
27 
29  // Make sure the subdirectory exists.
30  CreateDir(root_dir_ + "/" + subdir());
31  size_t num_graphs = 0;
32  for (const auto &o : outputs_) {
33  // Check if output spec is valid
34  if (o.comp == nullptr) {
35  CERATA_LOG(ERROR, "OutputSpec contained no component.");
36  continue;
37  }
38 
39  CERATA_LOG(DEBUG, "VHDL: Transforming Component " + o.comp->name() + " to VHDL-compatible version.");
40  auto vhdl_design = Design(o.comp, notice_, DEFAULT_LIBS);
41 
42  CERATA_LOG(DEBUG, "VHDL: Generating sources for component " + o.comp->name());
43  auto vhdl_source = vhdl_design.Generate().ToString();
44  auto vhdl_path = root_dir_ + "/" + subdir() + "/" + o.comp->name() + ".gen.vhd";
45 
46  // Disable backup by default.
47  bool backup = (o.meta.count(meta::BACKUP_EXISTING) > 0) && (o.meta.at(meta::BACKUP_EXISTING) == "true");
48 
49  CERATA_LOG(DEBUG, "VHDL: Saving design to: " + vhdl_path);
50  if (!FileExists(vhdl_path) || !backup) {
51  auto vhdl_file = std::ofstream(vhdl_path);
52  vhdl_file << vhdl_source;
53  vhdl_file.close();
54  } else {
55  CERATA_LOG(DEBUG, "VHDL: File exists, backing up and saving to " + vhdl_path + "t");
56  // Copy the old file.
57  auto original = std::ifstream(vhdl_path, std::ios::binary);
58  auto copy = std::ofstream(vhdl_path + ".bak", std::ios::binary);
59  copy << original.rdbuf();
60  // Save the new file.
61  auto vhdl_file = std::ofstream(vhdl_path);
62  vhdl_file << vhdl_source;
63  }
64 
65  num_graphs++;
66  }
67  CERATA_LOG(DEBUG, "VHDL: Generated output for " + std::to_string(num_graphs) + " graphs.");
68 }
69 
70 } // namespace cerata::vhdl
71 
cerata::vhdl::Design
A VHDL design that can generate code for a single file.
Definition: design.h:29
cerata::OutputGenerator::root_dir_
std::string root_dir_
The root directory to generate the output in.
Definition: output.h:54
cerata::vhdl::DEFAULT_LIBS
constexpr char DEFAULT_LIBS[]
Default libraries to include.
Definition: defaults.h:23
cerata::vhdl::VHDLOutputGenerator::Generate
void Generate() override
Generate the output.
Definition: vhdl.cc:28
cerata::vhdl::VHDLOutputGenerator::notice_
std::string notice_
Copyright notice to place on top of a file.
Definition: vhdl.h:62
cerata::vhdl::VHDLOutputGenerator::subdir
std::string subdir() override
Return that the VHDLOutputGenerator will place the files in.
Definition: vhdl.h:74
cerata::CreateDir
void CreateDir(const std::string &dir_name)
Create a directory.
Definition: utils.cc:52
cerata::OutputGenerator::outputs_
std::vector< OutputSpec > outputs_
A list of things to put out.
Definition: output.h:56
cerata::FileExists
bool FileExists(const std::string &name)
Check if file exists.
Definition: utils.cc:60
cerata::vhdl
Contains everything related to the VHDL back-end.
Definition: architecture.cc:31