18 #include "cerata/logging.h"
19 #include "cerata/edge.h"
20 #include "cerata/node.h"
21 #include "cerata/expression.h"
22 #include "cerata/array.h"
23 #include "cerata/type.h"
24 #include "cerata/graph.h"
25 #include "cerata/pool.h"
26 #include "cerata/parameter.h"
28 #include "cerata/vhdl/instantiation.h"
29 #include "cerata/vhdl/identifier.h"
30 #include "cerata/vhdl/vhdl.h"
34 static std::string lit2vhdl(
const Literal &lit) {
35 switch (lit.type()->id()) {
36 default:
return lit.ToString();
39 return "\"" + lit.ToString() +
"\"";
42 if (lit.BoolValue()) {
50 static bool IsInputTerminator(
const Object &obj) {
52 auto term =
dynamic_cast<const Term &
>(obj);
53 return term.IsInput();
55 catch (
const std::bad_cast &e) {
65 auto val = par.
value();
67 if (val->IsLiteral()) {
68 auto *lit =
dynamic_cast<const Literal *
>(val);
79 const std::shared_ptr<Node> &offset_a,
81 const std::shared_ptr<Node> &offset_b,
82 const std::string &lh_prefix,
83 const std::string &rh_prefix,
89 std::shared_ptr<Node> next_offset_a;
90 std::shared_ptr<Node> next_offset_b;
95 next_offset_a = (offset_a + (b_width ? b_width.value() :
rintl(0)));
96 next_offset_b = (offset_b + (a_width ? a_width.value() :
rintl(0)));
105 if ((p.
num_b() > 1) || (a_is_array && !full_array)) {
107 l +=
"(" + offset_a->ToString() +
")";
109 l +=
"(" + (next_offset_a - 1)->
ToString();
110 l +=
" downto " + offset_a->ToString() +
")";
115 if ((p.
num_a() > 1) || (b_is_array && !full_array)) {
117 l +=
"(" + offset_b->ToString() +
")";
119 l +=
"(" + (next_offset_b - 1)->
ToString();
120 l +=
" downto " + offset_b->ToString() +
")";
129 static Block GeneratePortMappingPair(std::vector<MappingPair> pairs,
const Node &a,
const Node &b,
bool full_array) {
132 std::sort(pairs.begin(), pairs.end(), [](
const MappingPair &x,
const MappingPair &y) ->
bool {
133 return x.index_a(0) < y.index_a(0);
135 bool a_array =
false;
136 bool b_array =
false;
142 a_idx = a.array().value()->IndexOf(a);
146 b_idx = b.array().value()->IndexOf(b);
148 if (a.type()->meta.count(meta::FORCE_VECTOR) > 0) {
151 if (b.type()->meta.count(meta::FORCE_VECTOR) > 0) {
155 for (
const auto &pair : pairs) {
157 std::shared_ptr<Node> b_offset = pair.width_a(
intl(1)) *
intl(b_idx);
159 for (int64_t ia = 0; ia < pair.num_a(); ia++) {
161 auto a_width = pair.flat_type_a(ia).type_->width();
163 std::shared_ptr<Node> a_offset = pair.width_b(
intl(1)) *
intl(a_idx);
164 for (int64_t ib = 0; ib < pair.num_b(); ib++) {
166 auto b_width = pair.flat_type_b(ib).type_->width();
169 GenerateMappingPair(pair, ia, a_offset, ib, b_offset, a.name(), b.name(), a_array, b_array, full_array);
172 a_offset = a_offset + (b_width ? b_width.value() :
rintl(1));
175 b_offset = b_offset + (a_width ? a_width.value() :
rintl(1));
183 std::vector<Edge *> connections;
185 if (IsInputTerminator(
port)) {
186 connections =
port.sources();
188 connections =
port.sinks();
191 auto port_type =
port.type();
193 for (
const auto &edge : connections) {
195 auto other = *edge->GetOtherNode(
port);
197 auto other_type = other->type();
199 auto optional_type_mapper = port_type->GetMapper(other_type);
200 if (optional_type_mapper) {
201 auto type_mapper = optional_type_mapper.value();
203 auto pairs = type_mapper->GetUniqueMappingPairs();
205 result << GeneratePortMappingPair(pairs,
port, *other, full_array);
207 CERATA_LOG(FATAL,
"No type mapping available for: Port[" +
port.name() +
": " +
port.type()->name()
208 +
"] to Other[" + other->name() +
" : " + other->type()->name() +
"]");
217 std::vector<NodeArray *> others;
219 for (
const auto &e : node->edges()) {
220 auto other = e->GetOtherNode(*node);
222 if (other.value()->array()) {
223 if (other.value()->array().value()->IsArray()) {
224 auto na =
dynamic_cast<NodeArray *
>(other.value()->array().value());
225 others.push_back(na);
232 others.erase(std::unique(others.begin(), others.end()), others.end());
233 bool full_array = others.
size() == 1;
237 const auto &
port =
dynamic_cast<const Port &
>(*node);
243 return ret.
Sort(
'(');
252 auto &inst =
dynamic_cast<const Instance &
>(graph);
262 ih << inst.name() +
" : " + inst.component()->name();
267 gh <<
"generic map (";
283 for (
const auto &p : inst.GetAll<
Port>()) {
288 for (
const auto &a : inst.GetAll<
PortArray>()) {
299 ret << gmh << gmb << gmf;
300 ret << pmh << pmb << pmf;