|
17 | 17 | *
|
18 | 18 | */
|
19 | 19 |
|
| 20 | +#include <cassert> |
20 | 21 | #include "kernel/yosys.h"
|
21 | 22 | #include "kernel/drivertools.h"
|
22 | 23 | #include "kernel/topo_scc.h"
|
@@ -96,31 +97,70 @@ struct CxxWriter {
|
96 | 97 | };
|
97 | 98 |
|
98 | 99 | struct CxxStruct {
|
99 |
| - std::string name; |
100 |
| - dict<IdString, std::string> types; |
101 |
| - CxxScope scope; |
102 |
| - CxxStruct(std::string name) : name(name) { |
103 |
| - scope.reserve("out"); |
104 |
| - scope.reserve("dump"); |
105 |
| - } |
106 |
| - void insert(IdString name, std::string type) { |
107 |
| - scope.insert(name); |
108 |
| - types.insert({name, type}); |
109 |
| - } |
110 |
| - void print(CxxWriter &f) { |
111 |
| - f.printf("struct %s {\n", name.c_str()); |
112 |
| - for (auto p : types) { |
113 |
| - f.printf("\t%s %s;\n", p.second.c_str(), scope[p.first].c_str()); |
114 |
| - } |
115 |
| - f.printf("\n\ttemplate <typename T> void dump(T &out) {\n"); |
116 |
| - for (auto p : types) { |
117 |
| - f.printf("\t\tout(\"%s\", %s);\n", RTLIL::unescape_id(p.first).c_str(), scope[p.first].c_str()); |
118 |
| - } |
119 |
| - f.printf("\t}\n};\n\n"); |
120 |
| - } |
121 |
| - std::string operator[](IdString field) { |
122 |
| - return scope[field]; |
123 |
| - } |
| 100 | + std::string name; |
| 101 | + dict<IdString, std::string> types; |
| 102 | + CxxScope scope; |
| 103 | + bool generate_methods; |
| 104 | + int count; |
| 105 | + CxxStruct(std::string name, bool generate_methods = false, int count = 0) |
| 106 | + : name(name), generate_methods(generate_methods), count(count) { |
| 107 | + scope.reserve("out"); |
| 108 | + scope.reserve("dump"); |
| 109 | + } |
| 110 | + void insert(IdString name, std::string type) { |
| 111 | + scope.insert(name); |
| 112 | + types.insert({name, type}); |
| 113 | + } |
| 114 | + void print(CxxWriter &f) { |
| 115 | + f.printf("struct %s {\n", name.c_str()); |
| 116 | + for (auto p : types) { |
| 117 | + f.printf("\t%s %s;\n", p.second.c_str(), scope[p.first].c_str()); |
| 118 | + } |
| 119 | + f.printf("\n\ttemplate <typename T> void dump(T &out) const {\n"); |
| 120 | + for (auto p : types) { |
| 121 | + f.printf("\t\tout(\"%s\", %s);\n", RTLIL::unescape_id(p.first).c_str(), scope[p.first].c_str()); |
| 122 | + } |
| 123 | + f.printf("\t}\n\n"); |
| 124 | + |
| 125 | + if (generate_methods) { |
| 126 | + // Add size method |
| 127 | + f.printf("\tint size() const {\n"); |
| 128 | + f.printf("\t\treturn %d;\n", count); |
| 129 | + f.printf("\t}\n\n"); |
| 130 | + |
| 131 | + // Add get_input method |
| 132 | + f.printf("\tstd::variant<%s> get_input(const int index) {\n", generate_variant_types().c_str()); |
| 133 | + f.printf("\t\tswitch (index) {\n"); |
| 134 | + int idx = 0; |
| 135 | + for (auto p : types) { |
| 136 | + f.printf("\t\t\tcase %d: return std::ref(%s);\n", idx, scope[p.first].c_str()); |
| 137 | + idx++; |
| 138 | + } |
| 139 | + f.printf("\t\t\tdefault: throw std::out_of_range(\"Invalid input index\");\n"); |
| 140 | + f.printf("\t\t}\n"); |
| 141 | + f.printf("\t}\n"); |
| 142 | + } |
| 143 | + |
| 144 | + f.printf("};\n\n"); |
| 145 | + }; |
| 146 | + std::string operator[](IdString field) { |
| 147 | + return scope[field]; |
| 148 | + } |
| 149 | + private: |
| 150 | + std::string generate_variant_types() const { |
| 151 | + std::set<std::string> unique_types; |
| 152 | + for (const auto& p : types) { |
| 153 | + unique_types.insert("std::reference_wrapper<" + p.second + ">"); |
| 154 | + } |
| 155 | + std::ostringstream oss; |
| 156 | + for (auto it = unique_types.begin(); it != unique_types.end(); ++it) { |
| 157 | + if (it != unique_types.begin()) { |
| 158 | + oss << ", "; |
| 159 | + } |
| 160 | + oss << *it; |
| 161 | + } |
| 162 | + return oss.str(); |
| 163 | + } |
124 | 164 | };
|
125 | 165 |
|
126 | 166 | struct CxxFunction {
|
@@ -302,7 +342,8 @@ struct FunctionalCxxBackend : public Backend
|
302 | 342 | state[ref.function().parameters.begin()->first] = ref.function().width;
|
303 | 343 | }
|
304 | 344 | f.printf("#include \"sim.h\"\n");
|
305 |
| - CxxStruct input_struct(name + "_Inputs"); |
| 345 | + f.printf("#include <variant>\n"); |
| 346 | + CxxStruct input_struct(name + "_Inputs", true, inputs.size()); |
306 | 347 | for (auto const &input : inputs)
|
307 | 348 | input_struct.insert(input.first, "Signal<" + std::to_string(input.second) + ">");
|
308 | 349 | CxxStruct output_struct(name + "_Outputs");
|
|
0 commit comments