@@ -56,129 +56,93 @@ struct CxxType {
56
56
}
57
57
};
58
58
59
- struct CxxWriter {
60
- std::ostream &f;
61
- CxxWriter (std::ostream &out) : f(out) {}
62
- void printf (const char *fmt, ...)
63
- {
64
- va_list va;
65
- va_start (va, fmt);
66
- f << vstringf (fmt, va);
67
- va_end (va);
68
- }
69
- };
59
+ using CxxWriter = FunctionalTools::Writer;
70
60
71
61
struct CxxStruct {
72
62
std::string name;
73
63
dict<IdString, CxxType> types;
74
64
FunctionalTools::Scope scope;
75
65
CxxStruct (std::string name)
76
66
: name(name), scope(illegal_characters, reserved_keywords) {
77
- scope.reserve (" out " );
78
- scope.reserve (" dump " );
67
+ scope.reserve (" fn " );
68
+ scope.reserve (" visit " );
79
69
}
80
70
void insert (IdString name, CxxType type) {
81
71
scope (name);
82
72
types.insert ({name, type});
83
73
}
84
74
void print (CxxWriter &f) {
85
- f.printf (" \t struct %s { \n " , name. c_str () );
75
+ f.print (" \t struct {} {{ \n " , name);
86
76
for (auto p : types) {
87
- f.printf (" \t\t %s %s ;\n " , p.second .to_string (). c_str () , scope (p.first ). c_str ( ));
77
+ f.print (" \t\t {} {} ;\n " , p.second .to_string (), scope (p.first ));
88
78
}
89
- f.printf (" \n\t\t template <typename T> void visit(T &&fn) {\n " );
79
+ f.print (" \n\t\t template <typename T> void visit(T &&fn) { {\n " );
90
80
for (auto p : types) {
91
- f.printf (" \t\t\t fn(\" %s \" , %s );\n " , RTLIL::unescape_id (p.first ). c_str () , scope (p.first ). c_str ( ));
81
+ f.print (" \t\t\t fn(\" {} \" , {} );\n " , RTLIL::unescape_id (p.first ), scope (p.first ));
92
82
}
93
- f.printf (" \t\t }\n " );
94
- f.printf (" \t };\n\n " );
83
+ f.print (" \t\t } }\n " );
84
+ f.print (" \t } };\n\n " );
95
85
};
96
86
std::string operator [](IdString field) {
97
87
return scope (field);
98
88
}
99
89
};
100
90
101
- struct CxxTemplate {
102
- vector<std::variant<std::string, int >> _v;
103
- public:
104
- CxxTemplate (std::string fmt) {
105
- std::string buf;
106
- for (auto it = fmt.begin (); it != fmt.end (); it++){
107
- if (*it == ' %' ){
108
- it++;
109
- log_assert (it != fmt.end ());
110
- if (*it == ' %' )
111
- buf += *it;
112
- else {
113
- log_assert (*it >= ' 0' && *it <= ' 9' );
114
- _v.emplace_back (std::move (buf));
115
- _v.emplace_back ((int )(*it - ' 0' ));
116
- }
117
- }else
118
- buf += *it;
119
- }
120
- if (!buf.empty ())
121
- _v.emplace_back (std::move (buf));
122
- }
123
- template <typename ... Args> static std::string format (CxxTemplate fmt, Args&&... args) {
124
- vector<std::string> strs = {args...};
125
- std::string result;
126
- for (auto &v : fmt._v ){
127
- if (std::string *s = std::get_if<std::string>(&v))
128
- result += *s;
129
- else if (int *i = std::get_if<int >(&v))
130
- result += strs[*i];
131
- else
132
- log_error (" missing case" );
133
- }
134
- return result;
135
- }
136
- };
137
-
138
- template <class NodeNames > struct CxxPrintVisitor {
91
+ template <class NodePrinter > struct CxxPrintVisitor {
139
92
using Node = FunctionalIR::Node;
140
- NodeNames np;
93
+ CxxWriter &f;
94
+ NodePrinter np;
141
95
CxxStruct &input_struct;
142
96
CxxStruct &state_struct;
143
- CxxPrintVisitor (NodeNames np, CxxStruct &input_struct, CxxStruct &state_struct) : np(np), input_struct(input_struct), state_struct(state_struct) { }
144
- template <class T > std::string arg_to_string (T n) { return std::to_string (n); }
145
- std::string arg_to_string (std::string n) { return n; }
146
- std::string arg_to_string (Node n) { return np (n); }
147
- template <typename ... Args> std::string format (std::string fmt, Args&&... args) {
148
- return CxxTemplate::format (fmt, arg_to_string (args)...);
97
+ CxxPrintVisitor (CxxWriter &f, NodePrinter np, CxxStruct &input_struct, CxxStruct &state_struct) : f(f), np(np), input_struct(input_struct), state_struct(state_struct) { }
98
+ template <typename ... Args> void print (const char *fmt, Args&&... args) {
99
+ f.print_with (np, fmt, std::forward<Args>(args)...);
149
100
}
150
- std::string buf (Node, Node n) { return np (n); }
151
- std::string slice (Node, Node a, int , int offset, int out_width) { return format (" %0.slice<%2>(%1)" , a, offset, out_width); }
152
- std::string zero_extend (Node, Node a, int , int out_width) { return format (" %0.zero_extend<%1>()" , a, out_width); }
153
- std::string sign_extend (Node, Node a, int , int out_width) { return format (" %0.sign_extend<%1>()" , a, out_width); }
154
- std::string concat (Node, Node a, int , Node b, int ) { return format (" %0.concat(%1)" , a, b); }
155
- std::string add (Node, Node a, Node b, int ) { return format (" %0 + %1" , a, b); }
156
- std::string sub (Node, Node a, Node b, int ) { return format (" %0 - %1" , a, b); }
157
- std::string bitwise_and (Node, Node a, Node b, int ) { return format (" %0 & %1" , a, b); }
158
- std::string bitwise_or (Node, Node a, Node b, int ) { return format (" %0 | %1" , a, b); }
159
- std::string bitwise_xor (Node, Node a, Node b, int ) { return format (" %0 ^ %1" , a, b); }
160
- std::string bitwise_not (Node, Node a, int ) { return format (" ~%0" , a); }
161
- std::string unary_minus (Node, Node a, int ) { return format (" -%0" , a); }
162
- std::string reduce_and (Node, Node a, int ) { return format (" %0.all()" , a); }
163
- std::string reduce_or (Node, Node a, int ) { return format (" %0.any()" , a); }
164
- std::string reduce_xor (Node, Node a, int ) { return format (" %0.parity()" , a); }
165
- std::string equal (Node, Node a, Node b, int ) { return format (" %0 == %1" , a, b); }
166
- std::string not_equal (Node, Node a, Node b, int ) { return format (" %0 != %1" , a, b); }
167
- std::string signed_greater_than (Node, Node a, Node b, int ) { return format (" %0.signed_greater_than(%1)" , a, b); }
168
- std::string signed_greater_equal (Node, Node a, Node b, int ) { return format (" %0.signed_greater_equal(%1)" , a, b); }
169
- std::string unsigned_greater_than (Node, Node a, Node b, int ) { return format (" %0 > %1" , a, b); }
170
- std::string unsigned_greater_equal (Node, Node a, Node b, int ) { return format (" %0 >= %1" , a, b); }
171
- std::string logical_shift_left (Node, Node a, Node b, int , int ) { return format (" %0 << %1" , a, b); }
172
- std::string logical_shift_right (Node, Node a, Node b, int , int ) { return format (" %0 >> %1" , a, b); }
173
- std::string arithmetic_shift_right (Node, Node a, Node b, int , int ) { return format (" %0.arithmetic_shift_right(%1)" , a, b); }
174
- std::string mux (Node, Node a, Node b, Node s, int ) { return format (" %2.any() ? %1 : %0" , a, b, s); }
175
- std::string pmux (Node, Node a, Node b, Node s, int , int ) { return format (" %0.pmux(%1, %2)" , a, b, s); }
176
- std::string constant (Node, RTLIL::Const value) { return format (" Signal<%0>(%1)" , value.size (), value.as_int ()); }
177
- std::string input (Node, IdString name) { return format (" input.%0" , input_struct[name]); }
178
- std::string state (Node, IdString name) { return format (" current_state.%0" , state_struct[name]); }
179
- std::string memory_read (Node, Node mem, Node addr, int , int ) { return format (" %0.read(%1)" , mem, addr); }
180
- std::string memory_write (Node, Node mem, Node addr, Node data, int , int ) { return format (" %0.write(%1, %2)" , mem, addr, data); }
181
- std::string undriven (Node, int width) { return format (" Signal<%0>(0)" , width); }
101
+ void buf (Node, Node n) { print (" {}" , n); }
102
+ void slice (Node, Node a, int , int offset, int out_width) { print (" {0}.slice<{2}>({1})" , a, offset, out_width); }
103
+ void zero_extend (Node, Node a, int , int out_width) { print (" {}.zero_extend<{}>()" , a, out_width); }
104
+ void sign_extend (Node, Node a, int , int out_width) { print (" {}.sign_extend<{}>()" , a, out_width); }
105
+ void concat (Node, Node a, int , Node b, int ) { print (" {}.concat({})" , a, b); }
106
+ void add (Node, Node a, Node b, int ) { print (" {} + {}" , a, b); }
107
+ void sub (Node, Node a, Node b, int ) { print (" {} - {}" , a, b); }
108
+ void bitwise_and (Node, Node a, Node b, int ) { print (" {} & {}" , a, b); }
109
+ void bitwise_or (Node, Node a, Node b, int ) { print (" {} | {}" , a, b); }
110
+ void bitwise_xor (Node, Node a, Node b, int ) { print (" {} ^ {}" , a, b); }
111
+ void bitwise_not (Node, Node a, int ) { print (" ~{}" , a); }
112
+ void unary_minus (Node, Node a, int ) { print (" -{}" , a); }
113
+ void reduce_and (Node, Node a, int ) { print (" {}.all()" , a); }
114
+ void reduce_or (Node, Node a, int ) { print (" {}.any()" , a); }
115
+ void reduce_xor (Node, Node a, int ) { print (" {}.parity()" , a); }
116
+ void equal (Node, Node a, Node b, int ) { print (" {} == {}" , a, b); }
117
+ void not_equal (Node, Node a, Node b, int ) { print (" {} != {}" , a, b); }
118
+ void signed_greater_than (Node, Node a, Node b, int ) { print (" {}.signed_greater_than({})" , a, b); }
119
+ void signed_greater_equal (Node, Node a, Node b, int ) { print (" {}.signed_greater_equal({})" , a, b); }
120
+ void unsigned_greater_than (Node, Node a, Node b, int ) { print (" {} > {}" , a, b); }
121
+ void unsigned_greater_equal (Node, Node a, Node b, int ) { print (" {} >= {}" , a, b); }
122
+ void logical_shift_left (Node, Node a, Node b, int , int ) { print (" {} << {}" , a, b); }
123
+ void logical_shift_right (Node, Node a, Node b, int , int ) { print (" {} >> {}" , a, b); }
124
+ void arithmetic_shift_right (Node, Node a, Node b, int , int ) { print (" {}.arithmetic_shift_right{})" , a, b); }
125
+ void mux (Node, Node a, Node b, Node s, int ) { print (" {2}.any() ? {1} : {0}" , a, b, s); }
126
+ void pmux (Node, Node a, Node b, Node s, int , int ) { print (" {0}.pmux({1}, {2})" , a, b, s); }
127
+ void constant (Node, RTLIL::Const value) {
128
+ std::stringstream ss;
129
+ bool multiple = value.size () > 32 ;
130
+ ss << " Signal<" << value.size () << " >(" << std::hex << std::showbase;
131
+ if (multiple) ss << " {" ;
132
+ while (value.size () > 32 ) {
133
+ ss << value.as_int () << " , " ;
134
+ value = value.extract (32 , value.size () - 32 );
135
+ }
136
+ ss << value.as_int ();
137
+ if (multiple) ss << " }" ;
138
+ ss << " )" ;
139
+ print (" {}" , ss.str ());
140
+ }
141
+ void input (Node, IdString name) { print (" input.{}" , input_struct[name]); }
142
+ void state (Node, IdString name) { print (" current_state.{}" , state_struct[name]); }
143
+ void memory_read (Node, Node mem, Node addr, int , int ) { print (" {}.read({})" , mem, addr); }
144
+ void memory_write (Node, Node mem, Node addr, Node data, int , int ) { print (" {}.write({}, {})" , mem, addr, data); }
145
+ void undriven (Node, int width) { print (" Signal<{}>(0)" , width); }
182
146
};
183
147
184
148
struct CxxModule {
@@ -201,31 +165,35 @@ struct CxxModule {
201
165
module_name = FunctionalTools::Scope (illegal_characters, reserved_keywords)(module->name );
202
166
}
203
167
void write_header (CxxWriter &f) {
204
- f.printf (" #include \" sim.h\"\n\n " );
168
+ f.print (" #include \" sim.h\"\n\n " );
205
169
}
206
170
void write_struct_def (CxxWriter &f) {
207
- f.printf (" struct %s { \n " , module_name. c_str () );
171
+ f.print (" struct {} {{ \n " , module_name);
208
172
input_struct.print (f);
209
173
output_struct.print (f);
210
174
state_struct.print (f);
211
- f.printf (" \t static void eval(Inputs const &, Outputs &, State const &, State &);\n " );
212
- f.printf ( " };\n\n " );
175
+ f.print (" \t static void eval(Inputs const &, Outputs &, State const &, State &);\n " );
176
+ f.print ( " } };\n\n " );
213
177
}
214
178
void write_eval_def (CxxWriter &f) {
215
- f.printf (" void %s ::eval(%s ::Inputs const &input, %s ::Outputs &output, %s ::State const ¤t_state, %s ::State &next_state)\n {\n " , module_name. c_str (), module_name. c_str (), module_name. c_str (), module_name. c_str (), module_name. c_str () );
179
+ f.print (" void {0} ::eval({0} ::Inputs const &input, {0} ::Outputs &output, {0} ::State const ¤t_state, {0} ::State &next_state)\n {{ \n " , module_name);
216
180
FunctionalTools::Scope locals (illegal_characters, reserved_keywords);
217
181
locals.reserve (" input" );
218
182
locals.reserve (" output" );
219
183
locals.reserve (" current_state" );
220
184
locals.reserve (" next_state" );
221
185
auto node_name = [&](FunctionalIR::Node n) { return locals (n.id (), n.name ()); };
222
- for (auto node : ir)
223
- f.printf (" \t %s %s = %s;\n " , CxxType (node.sort ()).to_string ().c_str (), node_name (node).c_str (), node.visit (CxxPrintVisitor (node_name, input_struct, state_struct)).c_str ());
186
+ CxxPrintVisitor printVisitor (f, node_name, input_struct, state_struct);
187
+ for (auto node : ir) {
188
+ f.print (" \t {} {} = " , CxxType (node.sort ()).to_string (), node_name (node));
189
+ node.visit (printVisitor);
190
+ f.print (" ;\n " );
191
+ }
224
192
for (auto [name, sort] : ir.state ())
225
- f.printf (" \t next_state.%s = %s ;\n " , state_struct[name]. c_str () , node_name (ir.get_state_next_node (name)). c_str ( ));
193
+ f.print (" \t next_state.{} = {} ;\n " , state_struct[name], node_name (ir.get_state_next_node (name)));
226
194
for (auto [name, sort] : ir.outputs ())
227
- f.printf (" \t output.%s = %s ;\n " , output_struct[name]. c_str () , node_name (ir.get_output_node (name)). c_str ( ));
228
- f.printf ( " }\n " );
195
+ f.print (" \t output.{} = {} ;\n " , output_struct[name], node_name (ir.get_output_node (name)));
196
+ f.print ( " } }\n " );
229
197
}
230
198
};
231
199
0 commit comments