OpenASIP  2.0
Generatable.hh
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2017 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25 * @file Generatable.hh
26 *
27 * @author Lasse Lehtonen 2017 (lasse.lehtonen-no.spam-tut.fi)
28 */
29 #pragma once
30 #include <LHSValue.hh>
31 #include <HWGenTools.hh>
32 #include <HDLRegister.hh>
33 #include <boost/format.hpp>
34 #include <chrono>
35 #include <cmath>
36 #include <ctime>
37 #include <deque>
38 #include <iomanip>
39 #include <iostream>
40 #include <memory>
41 #include <sstream>
42 #include <string>
43 #include <unordered_map>
44 #include <unordered_set>
45 #include <vector>
46 
47 namespace HDLGenerator {
48  /**
49  * Base class for all generatable classes.
50  */
51  class Generatable {
52  public:
53  Generatable(std::string name) : name_(name), parent_(nullptr) {}
54  virtual ~Generatable() = default;
55 
56  virtual void build() {
57  forAll([this](std::shared_ptr<Generatable> c) {
58  c->setParent(this);
59  c->build();
60  });
61  }
62 
63  virtual void reads(const std::string& var) {
64  if (parent() == nullptr) {
65  std::string err =
66  std::string("Couldn't find parent for ") + name();
67  throw std::runtime_error(err.c_str());
68  }
69  parent()->reads(var);
70  }
71 
72  virtual void reads(const LHSValue& var) {
73  std::unordered_set<std::string> readList;
74  var.writeSignals(readList);
75  for (auto&& r : readList) {
76  reads(r);
77  }
78  }
79 
80  virtual void writes(const std::string& var) {
81  if (parent() == nullptr) {
82  std::string err =
83  std::string("Couldn't find parent for ") + name();
84  throw std::runtime_error(err.c_str());
85  }
86  parent()->writes(var);
87  }
88 
89  virtual Register& getRegister(const std::string& var) {
90  if (parent() == nullptr) {
91  std::string err =
92  std::string("Couldn't find parent for ") + name();
93  throw std::runtime_error(err.c_str());
94  }
95  return parent()->getRegister(var);
96  }
97 
98  virtual bool hasOption(const std::string& var) {
99  if (parent() == nullptr) {
100  std::string err =
101  std::string("Couldn't find parent for ") + name();
102  throw std::runtime_error(err.c_str());
103  }
104  return parent()->hasOption(var);
105  }
106 
107  virtual bool isRegister(const std::string& name) {
108  if (parent() == nullptr) {
109  std::string err =
110  std::string("Couldn't find parent for ") + name_;
111  throw std::runtime_error(err.c_str());
112  }
113  return parent()->isRegister(name);
114  }
115 
116  virtual bool isVariable(const std::string& name) {
117  if (parent() == nullptr) {
118  std::string err =
119  std::string("Couldn't find parent for ") + name_;
120  throw std::runtime_error(err.c_str());
121  }
122  return parent()->isVariable(name);
123  }
124 
125  virtual bool isConstant(const std::string& name) {
126  if (parent() == nullptr) {
127  std::string err =
128  std::string("Couldn't find parent for ") + name_;
129  throw std::runtime_error(err.c_str());
130  }
131  return parent()->isConstant(name);
132  }
133 
134  virtual Width width(const std::string& name) {
135  if (parent() == nullptr) {
136  std::string err =
137  std::string("Couldn't find parent for ") + name_;
138  throw std::runtime_error(err.c_str());
139  }
140  return parent()->width(name);
141  }
142 
143  int integerWidth(const std::string& name) {
144  int intWidth = width(name).intWidth;
145  if (intWidth == -1) {
146  std::string err = name_
147  + std::string(" does not have an integer width value.");
148  throw std::runtime_error(err.c_str());
149  }
150  return intWidth;
151  }
152 
153  virtual WireType wireType(const std::string& name) {
154  if (parent() == nullptr) {
155  std::string err =
156  std::string("Couldn't find parent for ") + name_;
157  throw std::runtime_error(err.c_str());
158  }
159  return parent()->wireType(name);
160  }
161 
162  virtual Width width() {
163  throw std::runtime_error("Shouldn't be here!");
164  }
165 
166  virtual WireType wireType() const {
167  throw std::runtime_error("Shouldn't be here!");
168  }
169 
170  virtual void hdl(std::ostream& stream, Language lang, int indent) {
171  (void)stream;
172  (void)lang;
173  (void)indent;
174  std::string err = std::string("Attempted to generate ") + name_;
175  throw std::runtime_error(err);
176  }
177 
178  virtual void hdl(std::ostream& stream, Language lang) {
179  (void)lang;
180  stream << name();
181  }
182 
183  virtual void implementAll(std::ostream& stream, Language lang) {
184  forAll([&](
185  std::shared_ptr<Generatable> c) { c->hdl(stream, lang); });
186  }
187 
188  virtual void
189  implementAll(std::ostream& stream, Language lang, int indent) {
190  forAll([&](std::shared_ptr<Generatable> c) {
191  c->hdl(stream, lang, indent);
192  });
193  }
194 
195  template <typename Func> void forAll(Func func) {
196  for (auto&& c : components_) {
197  func(c);
198  }
199  }
200 
201  template <typename Type, typename Func> void forAll(Func func) {
202  for (auto&& c : components_) {
203  Type* ptr = dynamic_cast<Type*>(c.get());
204  if (ptr != nullptr)
205  func(ptr);
206  }
207  }
208 
209  template <class Type> bool parentIs() {
210  if (parent() == nullptr) {
211  return false;
212  } else if (dynamic_cast<Type*>(parent()) != nullptr) {
213  return true;
214  } else {
215  return parent()->parentIs<Type>();
216  }
217  }
218 
219  template <class Type> Type* parentType() {
220  if (parent() == nullptr) {
221  throw std::runtime_error("Couldn't find parent'");
222  } else if (dynamic_cast<Type*>(parent()) != nullptr) {
223  return dynamic_cast<Type*>(parent());
224  } else {
225  return parent()->parentType<Type>();
226  }
227  }
228 
229  // Badly named to avoid using the template below
230  void pushComponent(std::shared_ptr<Generatable> c) {
231  components_.push_back(c);
232  }
233 
234  template <class Component>
235  void addComponent(Component c) {
236  components_.push_back(std::make_shared<Component>(c));
237  }
238 
239  const std::string& name() const noexcept { return name_; }
240 
241  void setParent(Generatable* parent) noexcept { parent_ = parent; }
242  Generatable* parent() const noexcept { return parent_; }
243 
244  private:
245  std::string name_;
247  std::vector<std::shared_ptr<Generatable>> components_;
248  };
249 }
HDLGenerator::Generatable::writes
virtual void writes(const std::string &var)
Definition: Generatable.hh:80
HDLGenerator::LHSValue
Definition: LHSValue.hh:39
HDLGenerator::Generatable::pushComponent
void pushComponent(std::shared_ptr< Generatable > c)
Definition: Generatable.hh:230
HDLGenerator::Generatable::components_
std::vector< std::shared_ptr< Generatable > > components_
Definition: Generatable.hh:247
HDLGenerator
Definition: BinaryOps.hh:35
HDLGenerator::Generatable::parent_
Generatable * parent_
Definition: Generatable.hh:246
HDLGenerator::Generatable::wireType
virtual WireType wireType(const std::string &name)
Definition: Generatable.hh:153
LHSValue.hh
HDLGenerator::Generatable::addComponent
void addComponent(Component c)
Definition: Generatable.hh:235
HDLGenerator::Generatable::hdl
virtual void hdl(std::ostream &stream, Language lang)
Definition: Generatable.hh:178
HDLGenerator::Generatable::reads
virtual void reads(const LHSValue &var)
Definition: Generatable.hh:72
HDLGenerator::Generatable::getRegister
virtual Register & getRegister(const std::string &var)
Definition: Generatable.hh:89
HDLGenerator::Width::intWidth
int intWidth
Definition: HWGenTools.hh:39
HDLGenerator::Generatable::hasOption
virtual bool hasOption(const std::string &var)
Definition: Generatable.hh:98
HDLGenerator::Generatable::forAll
void forAll(Func func)
Definition: Generatable.hh:195
HDLGenerator::LHSValue::writeSignals
void writeSignals(std::unordered_set< std::string > &readList) const
Definition: LHSValue.cc:52
HDLGenerator::Generatable::isConstant
virtual bool isConstant(const std::string &name)
Definition: Generatable.hh:125
HDLGenerator::Generatable::Generatable
Generatable(std::string name)
Definition: Generatable.hh:53
HDLGenerator::Generatable::isRegister
virtual bool isRegister(const std::string &name)
Definition: Generatable.hh:107
HDLGenerator::WireType
WireType
Definition: HWGenTools.hh:34
HDLGenerator::Generatable::parent
Generatable * parent() const noexcept
Definition: Generatable.hh:242
HDLGenerator::Generatable::forAll
void forAll(Func func)
Definition: Generatable.hh:201
HDLGenerator::Generatable::~Generatable
virtual ~Generatable()=default
HDLGenerator::Generatable::width
virtual Width width(const std::string &name)
Definition: Generatable.hh:134
HDLGenerator::Generatable::parentType
Type * parentType()
Definition: Generatable.hh:219
HDLGenerator::Generatable::build
virtual void build()
Definition: Generatable.hh:56
HDLGenerator::Generatable::implementAll
virtual void implementAll(std::ostream &stream, Language lang)
Definition: Generatable.hh:183
HDLGenerator::Language
Language
Definition: HWGenTools.hh:33
HDLGenerator::Generatable::parentIs
bool parentIs()
Definition: Generatable.hh:209
HDLGenerator::Generatable::reads
virtual void reads(const std::string &var)
Definition: Generatable.hh:63
HDLGenerator::Generatable::implementAll
virtual void implementAll(std::ostream &stream, Language lang, int indent)
Definition: Generatable.hh:189
HDLGenerator::Generatable::width
virtual Width width()
Definition: Generatable.hh:162
HWGenTools.hh
HDLGenerator::Generatable::isVariable
virtual bool isVariable(const std::string &name)
Definition: Generatable.hh:116
HDLGenerator::Generatable::name_
std::string name_
Definition: Generatable.hh:245
HDLGenerator::Generatable::hdl
virtual void hdl(std::ostream &stream, Language lang, int indent)
Definition: Generatable.hh:170
HDLGenerator::Generatable::integerWidth
int integerWidth(const std::string &name)
Definition: Generatable.hh:143
HDLGenerator::Generatable::name
const std::string & name() const noexcept
Definition: Generatable.hh:239
HDLGenerator::Register
Definition: HDLRegister.hh:51
HDLGenerator::Generatable::wireType
virtual WireType wireType() const
Definition: Generatable.hh:166
HDLRegister.hh
HDLGenerator::Generatable
Definition: Generatable.hh:51
HDLGenerator::Generatable::setParent
void setParent(Generatable *parent) noexcept
Definition: Generatable.hh:241
HDLGenerator::Width
Definition: HWGenTools.hh:37