1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 #include "signal2vhdlVisitor.hh"
23 #include <cstdlib>
24 #include <map>
25 #include "Text.hh"
26 #include "global.hh"
27 #include "ppsig.hh"
28 #include "property.hh"
29 #include "signals.hh"
30 #include "sigtyperules.hh"
31 #include "tlib.hh"
32 #include "tree.hh"
33 #include <typeinfo>
34
35 //-------------------------Signal2VHDLVisitor-------------------------------
36 // An identity transformation on signals. Can be used to test
37 // that everything works, and as a pattern for real transformations.
38 //--------------------------------------------------------------------------
39
40 static const char* binopname[] = {"+", "-", "*", "/", "%", "<<", ">>", ">", "<", ">=", "<=", "==", "!=", "&", "|", "^"};
41
sigToVHDL(Tree L,ofstream & fout)42 void Signal2VHDLVisitor::sigToVHDL(Tree L, ofstream& fout)
43 {
44 Tree output = hd(L);
45 while (!isNil(L)) {
46 self(hd(L)); // comment
47 L = tl(L);
48 }
49 entity_faust();
50 faust_process();
51 fout << fDeclEntity << endl;
52 fout << fFaustEntity << endl;
53 fout << fDeclSig << endl;
54 fout << fDeclCompnt << endl;
55 fout << fFaustProcess << endl;
56 fout << fInput << endl;
57 fout << fMapCompnt << endl;
58 fout << "sigoutput <= resize(sig" << output << ",0,-23);" << endl;
59 fout << "out_left_V_int <= to_slv(sigoutput);\n" << endl;
60 fout << "out_right_V_int <= to_slv(sigoutput);\n" << endl;
61 fout << "end logic;" << endl;
62 }
63
64 // comment
self(Tree t)65 void Signal2VHDLVisitor::self(Tree t)
66 {
67 // Display function
68 if (!fVisited.count(t)) {
69 fVisited.insert(t);
70 visit(t);
71 }
72 }
73
visit(Tree sig)74 void Signal2VHDLVisitor::visit(Tree sig)
75 {
76 int i;
77 double r;
78 vector<Tree> subsig;
79 Tree c, sel, x, y, z, u, v, var, le, label, id, ff, largs, type, name, file, sf;
80
81 xtended* p = (xtended*)getUserData(sig);
82
83 if (p) {
84 if (strcmp(p->name(), "fmod") == 0) {
85 getSubSignals(sig, subsig);
86 bin_op("FMOD", "mod", sig, subsig[0], subsig[1]);
87 self(subsig[0]);
88 self(subsig[1]);
89 } else if (strcmp(p->name(), "sin") == 0) {
90 getSubSignals(sig, subsig);
91 sincos_op("SIN", sig, subsig[0]);
92 } else if (strcmp(p->name(), "cos") == 0) {
93 getSubSignals(sig, subsig);
94 sincos_op("COS", sig, subsig[0]);
95 } else {
96 for (Tree b : sig->branches()) {
97 self(b);
98 }
99 }
100 return;
101 } else if (isSigInt(sig, &i)) {
102 decl_sig(sig,1,-22);
103 return;
104 } else if (isSigReal(sig, &r)) {
105 decl_sig(sig,1,-22);
106 return;
107 } else if (isSigWaveform(sig)) {
108 return;
109 } else if (isSigInput(sig, &i)) {
110 input_affectation(sig);
111 decl_sig(sig,1,-22);
112 return;
113 } else if (isSigOutput(sig, &i, x)) {
114 self(x);
115 return;
116 } else if (isSigDelay1(sig, x)) {
117 self(x);
118 return;
119 } else if (isSigDelay(sig, x, y)) {
120
121 // Here is the maximum delay
122 int mxd = fOccMarkup->retrieve(x)->getMaxDelay();
123 if (!(isSigInt(y, &i)) && !(isSigReal(y, &r))) {
124 if (fEntity.count("DELAYVAR") == 0) {
125 if (mxd < 5000) { // to precise number
126 entity_delay_var_reg(fDeclEntity);
127 } else {
128 entity_delay_var_ram(fDeclEntity);
129 }
130 component_delay_var(fDeclCompnt);
131 fEntity.insert({"DELAYVAR", true});
132 }
133 decl_sig(sig,1,-22);
134 inst_delay_var(sig, x, y, fMapCompnt, mxd);
135 } else {
136 if (((y->node()).getInt()) == 0) {
137 bypass("DELAY0", sig, x);
138 } else {
139 if (fEntity.count("DELAY") == 0) {
140 entity_delay(fDeclEntity);
141 component_delay(fDeclCompnt);
142 fEntity.insert({"DELAY", true});
143 }
144 decl_sig(sig,1,-22);
145 inst_delay(sig, x, y, fMapCompnt);
146 }
147 }
148 self(x);
149 self(y);
150 return;
151 } else if (isSigPrefix(sig, x, y)) {
152 self(x);
153 self(y);
154 return;
155 } else if (isSigIota(sig, x)) {
156 self(x);
157 return;
158 } else if (isSigBinOp(sig, &i, x, y)) {
159 switch (i) {
160 case 0:
161 bin_op("ADD", binopname[i], sig, x, y);
162 break;
163 case 1:
164 bin_op("SUB", binopname[i], sig, x, y);
165 break;
166 case 2:
167 bin_op("MUL", binopname[i], sig, x, y);
168 break;
169 case 3:
170 bin_op("DIV", binopname[i], sig, x, y);
171 break;
172 case 4:
173 bin_op("MODULO", "mod", sig, x, y);
174 break;
175 case 8:
176 cmp_op("GT", binopname[i], sig, x, y);
177 break;
178 case 9:
179 cmp_op("LT", binopname[i], sig, x, y);
180 break;
181 case 10:
182 cmp_op("GE", binopname[i], sig, x, y);
183 break;
184 case 11:
185 cmp_op("LE", binopname[i], sig, x, y);
186 break;
187 case 12:
188 cmp_op("EQUAL", "=", sig, x, y);
189 break;
190 case 13:
191 cmp_op("DIFF", "/=", sig, x, y);
192 break;
193 case 14:
194 bin_op("ANDL", "and", sig, x, y);
195 break;
196 case 15:
197 bin_op("ORL", "or", sig, x, y);
198 break;
199 case 16:
200 bin_op("XORL", "xor", sig, x, y);
201 break;
202 default:
203 // operator is doesn't match any case constant (+, -, *, /, ...)
204 cout << "Error! The operator is not correct";
205 break;
206 }
207 self(x);
208 self(y);
209 return;
210 // Foreign functions
211 } else if (isSigFFun(sig, ff, largs)) {
212 mapself(largs);
213 return;
214 } else if (isSigFConst(sig, type, name, file)) {
215 return;
216 } else if (isSigFVar(sig, type, name, file)) {
217 return;
218 }
219
220 // Tables
221 else if (isSigTable(sig, id, x, y)) {
222 self(x);
223 self(y);
224 return;
225 } else if (isSigWRTbl(sig, id, x, y, z)) {
226 self(x);
227 self(y);
228 self(z);
229 return;
230 } else if (isSigRDTbl(sig, x, y)) {
231 self(x);
232 self(y);
233 return;
234 }
235
236 // Doc
237 else if (isSigDocConstantTbl(sig, x, y)) {
238 self(x);
239 self(y);
240 return;
241 } else if (isSigDocWriteTbl(sig, x, y, u, v)) {
242 self(x);
243 self(y);
244 self(u);
245 self(v);
246 return;
247 } else if (isSigDocAccessTbl(sig, x, y)) {
248 self(x);
249 self(y);
250 return;
251 }
252
253 // Select2
254 else if (isSigSelect2(sig, sel, x, y)) {
255 select_op("SELECT2", sig, sel, x, y);
256 self(sel);
257 self(x);
258 self(y);
259 return;
260 }
261
262 // Table sigGen
263 else if (isSigGen(sig, x)) {
264 if (fVisitGen) {
265 self(x);
266 return;
267 } else {
268 return;
269 }
270 }
271
272 // recursive signals
273 else if (isProj(sig, &i, x)) {
274 faustassert(isRec(x, var, le));
275 bypass("PROJ", sig, nth(le, i));
276 self(nth(le, i));
277 return;
278 }
279
280 // Int and Float Cast
281 else if (isSigIntCast(sig, x)) {
282 bypass("IntCast", sig, x);
283 self(x);
284 return;
285 } else if (isSigFloatCast(sig, x)) {
286 bypass("FloatCast", sig, x);
287 self(x);
288 return;
289 }
290
291 // UI
292 else if (isSigButton(sig, label)) {
293 return;
294 } else if (isSigCheckbox(sig, label)) {
295 return;
296 } else if (isSigVSlider(sig, label, c, x, y, z)) {
297 bypass("HSLIDER", sig, c);
298 self(c); // self(x), self(y), self(z);
299 return;
300 } else if (isSigHSlider(sig, label, c, x, y, z)) {
301 bypass("HSLIDER", sig, c);
302 self(c); // self(x), self(y), self(z);
303 return;
304 } else if (isSigNumEntry(sig, label, c, x, y, z)) {
305 bypass("ENTRY", sig, c);
306 self(c); // self(x), self(y), self(z);
307 return;
308 } else if (isSigVBargraph(sig, label, x, y, z)) {
309 self(x), self(y), self(z);
310 return;
311 } else if (isSigHBargraph(sig, label, x, y, z)) {
312 self(x), self(y), self(z);
313 return;
314 }
315
316 // Soundfile length, rate, channels, buffer
317 else if (isSigSoundfile(sig, label)) {
318 return;
319 } else if (isSigSoundfileLength(sig, sf, x)) {
320 self(sf), self(x);
321 return;
322 } else if (isSigSoundfileRate(sig, sf, x)) {
323 self(sf), self(x);
324 return;
325 } else if (isSigSoundfileBuffer(sig, sf, x, y, z)) {
326 self(sf), self(x), self(y), self(z);
327 return;
328 }
329
330 // Attach, Enable, Control
331 else if (isSigAttach(sig, x, y)) {
332 self(x), self(y);
333 return;
334 } else if (isSigEnable(sig, x, y)) {
335 self(x), self(y);
336 return;
337 } else if (isSigControl(sig, x, y)) {
338 self(x), self(y);
339 return;
340 }
341
342 else if (isNil(sig)) {
343 // now nil can appear in table write instructions
344 return;
345 } else {
346 stringstream error;
347 error << __FILE__ << ":" << __LINE__ << " ERROR : unrecognized signal : " << *sig << endl;
348 throw faustexception(error.str());
349 }
350 }
351
addr_to_str(Tree t)352 string Signal2VHDLVisitor::addr_to_str(Tree t)
353 {
354 stringstream s;
355 s << t;
356 return s.str();
357 }
358
val_to_str(Tree t)359 string Signal2VHDLVisitor::val_to_str(Tree t)
360 {
361 stringstream s;
362 s << *t;
363 return s.str();
364 }
365
entity_header(string & str)366 void Signal2VHDLVisitor::entity_header(string& str)
367 {
368 str += "library ieee;\n"
369 "use ieee.std_logic_1164.all;\n"
370 "use ieee.numeric_std.all;\n"
371 "use ieee.std_logic_arith.all;\n"
372 "use ieee.std_logic_signed.all;\n"
373 "use work.fixed_pkg.all;\n\n";
374 }
375
generic_decl(string & str)376 void Signal2VHDLVisitor::generic_decl(string& str)
377 {
378 str += "generic (\n"
379 " msb : integer;\n"
380 " lsb : integer);\n";
381 }
382
port_decl(int input,string & str)383 void Signal2VHDLVisitor::port_decl(int input, string& str)
384 {
385 str += "port (\n"
386 " clk : in std_logic;\n"
387 " rst : in std_logic;\n";
388 for (int i = 0; i < input; i++) {
389 str += " input"+ to_string(i) + " : in sfixed(msb downto lsb);\n";
390 }
391 str += " output0 : out sfixed(msb downto lsb));\n";
392 }
393
entity_bin_op(const string & name,const char * op,string & str)394 void Signal2VHDLVisitor::entity_bin_op(const string& name, const char* op, string& str)
395 {
396 entity_header(str);
397 str += "entity " + name + " is\n";
398 generic_decl(str);
399 port_decl(2,str);
400 str += "end " + name + ";\n"
401 "architecture behavioral of " + name + " is\n"
402 "begin\n"
403 "output0 <= resize(input0 " + op + " input1,msb,lsb);\n"
404 "end behavioral;\n\n";
405 }
406
entity_bin_op_concat(const string & name,const char * op,string & str)407 void Signal2VHDLVisitor::entity_bin_op_concat(const string& name, const char* op, string& str)
408 {
409 entity_header(str);
410 str += "entity " + name + " is\n";
411 generic_decl(str);
412 port_decl(2,str);
413 str += "end " + name + ";\n"
414 "architecture behavioral of " + name + " is\n"
415 "signal inter : sfixed(63 downto 0);\n"
416 "begin\n"
417 "inter <= resize(input0 " + op + " input1,63,0);\n"
418 "output0 <= inter(msb downto lsb);\n"
419 "end behavioral;\n\n";
420 }
421
entity_cmp_op(const string & name,const char * op,string & str)422 void Signal2VHDLVisitor::entity_cmp_op(const string& name, const char* op, string& str)
423 {
424 entity_header(str);
425 str += "entity " + name + " is\n";
426 generic_decl(str);
427 port_decl(2,str);
428 str += "end " + name + ";\n"
429 "architecture behavioral of " + name + " is\n"
430 "begin\n"
431 "process(input0, input1)\n"
432 "begin\n"
433 " if (input0 " + op + " input1) then\n"
434 " output0 <= to_sfixed(1,msb,lsb);\n"
435 " else\n"
436 " output0 <= to_sfixed(0,msb,lsb);\n"
437 " end if; \n"
438 "end process;\n"
439 "end behavioral;\n\n";
440 }
441
entity_delay(string & str)442 void Signal2VHDLVisitor::entity_delay(string& str)
443 {
444 entity_header(str);
445 str += "entity DELAY is\n"
446 "generic (\n"
447 " delay : integer;\n"
448 " msb : integer;\n"
449 " lsb : integer);\n"
450 "port (\n"
451 " ws : in std_logic;\n"
452 " input0 : in sfixed(msb downto lsb);\n"
453 " output0 : out sfixed(msb downto lsb));\n"
454 "end DELAY;\n"
455 "architecture behavioral of DELAY is\n"
456 "type mem is array (delay-1 downto 0) of sfixed(msb downto lsb);\n"
457 "signal ligne : mem;\n"
458 "begin\n"
459 "process(ws)\n"
460 " begin\n"
461 " ligne(0) <= input0;\n"
462 " if rising_edge(ws) then\n"
463 " for i in 1 to delay-1 loop\n"
464 " ligne(i) <= ligne(i-1);\n"
465 " end loop;\n"
466 " output0 <= ligne(delay-1);\n"
467 " end if;\n"
468 "end process;\n"
469 "end behavioral;\n\n";
470 }
471
entity_delay_var_reg(string & str)472 void Signal2VHDLVisitor::entity_delay_var_reg(string& str)
473 {
474 entity_header(str);
475 str += "entity DELAYVAR is\n"
476 "generic(\n"
477 " mxd : integer;\n"
478 " msb : integer;\n"
479 " lsb : integer);\n"
480 "port(\n"
481 " ws : in std_logic;\n"
482 " rst_n : in std_logic;\n"
483 " delay_var : in sfixed(23 downto 0);\n"
484 " input0 : in sfixed(msb downto lsb);\n"
485 " output0 : out sfixed(msb downto lsb));\n"
486 "end DELAYVAR;\n"
487 "architecture behavioral of DELAYVAR is\n"
488 "type t_ram is array (mxd downto 0) of sfixed(msb downto lsb);\n"
489 "signal mem : t_ram;\n"
490 "begin\n"
491 "process(ws,delay_var)\n"
492 "begin\n"
493 " if rising_edge(ws) then\n"
494 " mem(0) <= input0;\n"
495 " for i in 1 to mxd loop\n"
496 " mem(i) <= mem(i-1);\n"
497 " end loop;\n"
498 " end if;\n\n"
499 " if (to_integer(delay_var) = 0) then\n"
500 " output0 <= input0;\n"
501 " else\n"
502 " output0 <= mem(to_integer(delay_var)-1);\n"
503 " end if;\n"
504 "end process;\n"
505 "end behavioral;\n\n";
506 }
507
entity_delay_var_ram(string & str)508 void Signal2VHDLVisitor::entity_delay_var_ram(string& str)
509 {
510 entity_header(str);
511 str += "entity DELAYVAR is\n"
512 "generic(\n"
513 " mxd : integer;\n"
514 " msb : integer;\n"
515 " lsb : integer);\n"
516 "port(\n"
517 " ws : in std_logic;\n"
518 " rst_n : in std_logic;\n"
519 " delay_var : in sfixed(23 downto 0);\n"
520 " input0 : in sfixed(msb downto lsb);\n"
521 " output0 : out sfixed(msb downto lsb));\n"
522 "end DELAYVAR;\n"
523 "architecture behavioral of DELAYVAR is\n"
524 "type t_ram is array (mxd downto 0) of sfixed(msb downto lsb);\n"
525 "signal mem : t_ram;\n"
526 "signal r_addr_wr : integer range 0 to mxd := 0;\n"
527 "signal r_addr_rd : integer range 0 to mxd := 0;\n"
528 "begin\n\n"
529 "p_write : process(ws)\n"
530 "begin\n"
531 " if rising_edge(ws) then\n"
532 " mem(r_addr_wr) <= input0;\n"
533 " if(r_addr_wr < mxd) then\n"
534 " r_addr_wr <= r_addr_wr + 1;\n"
535 " else\n"
536 " r_addr_wr <= 0;\n"
537 " end if;\n"
538 " end if;\n"
539 "end process p_write;\n\n"
540 "p_read : process(ws)\n"
541 "begin\n"
542 " if rising_edge(ws) then\n"
543 " r_addr_rd <= r_addr_wr - to_integer(delay_var);\n"
544 " if(r_addr_rd < 0) then\n"
545 " output0 <= mem(r_addr_rd+mxd+1);\n"
546 " else\n"
547 " output0 <= mem(r_addr_rd);\n"
548 " end if;\n"
549 " end if;\n"
550 "end process p_read;\n"
551 "end behavioral;\n\n";
552 }
553
entity_bypass(const string & name,string & str)554 void Signal2VHDLVisitor::entity_bypass(const string& name, string& str)
555 {
556 entity_header(str);
557 str += "entity " + name + " is\n";
558 generic_decl(str);
559 port_decl(1,str);
560 str += "end " + name + ";\n"
561 "architecture behavioral of " + name + " is\n"
562 "begin\n"
563 "process (clk,rst)\n"
564 "begin\n"
565 " if rst = '0' then\n"
566 " output0 <= (others => '0');\n"
567 " else\n"
568 " output0 <= input0;\n"
569 " end if;\n"
570 "end process;\n"
571 "end behavioral;\n\n";
572 }
573
entity_select2(const string & name,string & str)574 void Signal2VHDLVisitor::entity_select2(const string& name, string& str)
575 {
576 entity_header(str);
577 str += "entity " + name + " is\n";
578 generic_decl(str);
579 port_decl(3,str);
580 str += "end " + name + ";\n"
581 "architecture behavioral of " + name + " is\n"
582 "begin\n"
583 "process(input0)\n"
584 "begin\n"
585 "if (input0 = 0) then\n"
586 " output0 <= input2;\n"
587 "else\n"
588 " output0 <= input1;\n"
589 "end if;\n"
590 "end process;\n"
591 "end behavioral;\n\n";
592 }
593
entity_faust()594 void Signal2VHDLVisitor::entity_faust()
595 {
596 entity_header(fDeclEntity);
597 fDeclEntity += "entity FAUST is\n"
598 "port (\n"
599 " ws : in std_logic;\n"
600 " ap_clk : in std_logic;\n"
601 " ap_rst_n : in std_logic;\n"
602 " ap_start : in std_logic;\n"
603 " ap_done : out std_logic;\n"
604 " bypass_dsp : in std_logic;\n"
605 " bypass_faust : in std_logic;\n"
606 " in_left_V : in std_logic_vector (23 downto 0);\n"
607 " in_right_V : in std_logic_vector (23 downto 0);\n"
608 " out_left_V_ap_vld : out std_logic;\n"
609 " out_right_V_ap_vld : out std_logic;\n"
610 " out_left_V : out std_logic_vector (23 downto 0);\n"
611 " out_right_V : out std_logic_vector (23 downto 0));\n"
612 "end FAUST;\n"
613 "architecture logic of FAUST is\n\n"
614 "signal in_left_V_buf : std_logic_vector (23 downto 0);\n"
615 "signal in_left_fixed : sfixed(23 downto 0);\n"
616 "signal in_right_V_buf : std_logic_vector (23 downto 0);\n"
617 "signal out_left_V_int : std_logic_vector (23 downto 0);\n"
618 "signal out_left_fixed : sfixed(23 downto 0);\n"
619 "signal out_right_V_int : std_logic_vector (23 downto 0);\n"
620 "signal step_cnt : integer;\n"
621 "signal sigoutput : sfixed(23 downto 0);";
622 }
623
component_standard(const string & name,int input,string & str)624 void Signal2VHDLVisitor::component_standard(const string& name, int input, string& str)
625 {
626 str += "component " + name + " is\n";
627 generic_decl(str);
628 port_decl(input,str);
629 str += "end component;\n\n";
630 }
631
component_delay(string & str)632 void Signal2VHDLVisitor::component_delay(string& str)
633 {
634 str += "component DELAY is\n"
635 "generic (\n"
636 " delay : integer;\n"
637 " msb : integer;\n"
638 " lsb : integer);\n"
639 "port (\n"
640 " ws : in std_logic;\n"
641 " input0 : in sfixed(msb downto lsb);\n"
642 " output0 : out sfixed(msb downto lsb));\n"
643 "end component;\n\n";
644 }
645
component_delay_var(string & str)646 void Signal2VHDLVisitor::component_delay_var(string& str)
647 {
648 str += "component DELAYVAR is\n"
649 "generic (\n"
650 " mxd : integer;\n"
651 " msb : integer;\n"
652 " lsb : integer);\n"
653 "port (\n"
654 " ws : in std_logic;\n"
655 " rst_n : in std_logic;\n"
656 " delay_var : in sfixed(msb downto lsb);\n"
657 " input0 : in sfixed(msb downto lsb);\n"
658 " output0 : out sfixed(msb downto lsb));\n"
659 "end component;\n\n";
660 }
661
component_sincos(string & str)662 void Signal2VHDLVisitor::component_sincos(string& str)
663 {
664 str += "component SinCos24 is\n"
665 "port (\n"
666 " input : in sfixed(1 downto -22);\n"
667 " SIN : out sfixed(0 downto -23);\n"
668 " COS : out sfixed(0 downto -23));\n"
669 "end component;\n\n";
670 }
671
faust_process()672 void Signal2VHDLVisitor::faust_process()
673 {
674 fFaustProcess += "begin\n\n"
675 " process(ap_clk, ap_rst_n, ap_start)\n"
676 " variable clock_cnt : integer := 0;\n"
677 " variable date_ap_vld1 : integer := 3;\n"
678 " begin\n\n"
679 " if(ap_rst_n = '0') then\n"
680 " step_cnt <= 0;\n"
681 " clock_cnt := 0;\n"
682 " ap_done <= '0';\n"
683 " out_left_V <= (others => '0');\n"
684 " out_left_V_ap_vld <= '0';\n"
685 " out_right_V <= (others => '0');\n"
686 " out_right_V_ap_vld <= '0' ;\n"
687 " elsif(ap_clk'event and ap_clk = '1') then\n"
688 " if (ap_start = '1') then\n"
689 " clock_cnt := 0;\n"
690 " end if;\n"
691 " -- loading (buffering) input data\n"
692 " if (clock_cnt = 1) then\n"
693 " --step_cnt <= step_cnt + 1;\n"
694 " in_left_V_buf <= in_left_V;\n"
695 " in_right_V_buf <= in_right_V;\n"
696 " end if;\n"
697 " clock_cnt := clock_cnt+1;\n"
698 " -- Say faust left output is ready\n"
699 " if (clock_cnt >= 2) and (clock_cnt < 3) then\n"
700 " out_left_V_ap_vld <= '1';\n"
701 " out_left_V <= out_left_V_int;\n"
702 " out_right_V_ap_vld <= '1';\n"
703 " out_right_V <= out_right_V_int;\n"
704 " ap_done <= '1';\n"
705 " else\n"
706 " ap_done <= '0';\n"
707 " out_right_V_ap_vld <= '0';\n"
708 " out_left_V_ap_vld <= '0';\n"
709 " end if;\n"
710 " end if;\n"
711 " end process;\n"
712 " ------------------------------------------------------------------------\n"
713 " -------------- Data flow equation ---------------------------\n"
714 " ------------------------------------------------------------------------\n\n";
715 }
716
inst_bin_op(const string & name,Tree sig,Tree x,Tree y,string & str)717 void Signal2VHDLVisitor::inst_bin_op(const string& name, Tree sig, Tree x, Tree y, string& str)
718 {
719 str += name + "_" + addr_to_str(sig) + " : " + name + "\n"
720 "generic map (\n"
721 " msb => 1,\n"
722 " lsb => -22)\n"
723 "port map (\n"
724 " clk => ap_clk,\n"
725 " rst => ap_rst_n,\n"
726 " input0 => sig"+ addr_to_str(x) +",\n"
727 " input1 => sig"+ addr_to_str(y) +",\n"
728 " output0 => sig"+ addr_to_str(sig) +");\n\n";
729 }
730
inst_delay(Tree sig,Tree x,Tree y,string & str)731 void Signal2VHDLVisitor::inst_delay(Tree sig, Tree x, Tree y, string& str)
732 {
733 str += "DELAY_" + addr_to_str(sig) + " : DELAY\n"
734 "generic map (\n"
735 " delay => "+ val_to_str(y) +",\n"
736 " msb => 1,\n"
737 " lsb => -22)\n"
738 "port map (\n"
739 " ws => ws,\n"
740 " input0 => sig"+ addr_to_str(x) +",\n"
741 " output0 => sig"+ addr_to_str(sig) +");\n\n";
742 }
743
inst_delay_var(Tree sig,Tree x,Tree y,string & str,int mxd)744 void Signal2VHDLVisitor::inst_delay_var(Tree sig, Tree x, Tree y, string& str, int mxd)
745 {
746 str += "DELAYVAR_" + addr_to_str(sig) + " : DELAYVAR\n"
747 "generic map (\n"
748 " mxd => "+ to_string(mxd) +",\n"
749 " msb => 1,\n"
750 " lsb => -22)\n"
751 "port map (\n"
752 " ws => ws,\n"
753 " rst_n => ap_rst_n,\n"
754 " delay_var => sig"+ addr_to_str(y) +",\n"
755 " input0 => sig"+ addr_to_str(x) +",\n"
756 " output0 => sig"+ addr_to_str(sig) +");\n\n";
757 }
758
inst_sincos(const string & name,Tree sig,Tree x,string & str)759 void Signal2VHDLVisitor::inst_sincos(const string& name, Tree sig, Tree x, string& str)
760 {
761 str += name + "_" + addr_to_str(sig) + " : SinCos24\n"
762 "port map (\n"
763 " input => sig"+ addr_to_str(x) +",\n"
764 " " + name + " => sig"+ addr_to_str(sig) +");\n\n";
765 }
766
inst_bypass(const string & name,Tree sig,Tree x,string & str)767 void Signal2VHDLVisitor::inst_bypass(const string& name, Tree sig, Tree x, string& str)
768 {
769 str += name + "_" + addr_to_str(sig) + " : " + name + "\n"
770 "generic map (\n"
771 " msb => 1,\n"
772 " lsb => -22)\n"
773 "port map (\n"
774 " clk => ap_clk,\n"
775 " rst => ap_rst_n,\n"
776 " input0 => sig"+ addr_to_str(x) +",\n"
777 " output0 => sig"+ addr_to_str(sig) +");\n\n";
778 }
779
inst_select2(const string & name,Tree sig,Tree sel,Tree x,Tree y,string & str)780 void Signal2VHDLVisitor::inst_select2(const string& name, Tree sig, Tree sel, Tree x, Tree y, string& str)
781 {
782 str += name + "_" + addr_to_str(sig) + " : " + name + "\n"
783 "generic map (\n"
784 " msb => 1,\n"
785 " lsb => -22)\n"
786 "port map (\n"
787 " clk => ap_clk,\n"
788 " rst => ap_rst_n,\n"
789 " input0 => sig"+ addr_to_str(sel) +",\n"
790 " input1 => sig"+ addr_to_str(x) +",\n"
791 " input2 => sig"+ addr_to_str(y) +",\n"
792 " output0 => sig"+ addr_to_str(sig) +");\n\n";
793 }
794
decl_sig(Tree sig,int msb,int lsb)795 void Signal2VHDLVisitor::decl_sig(Tree sig, int msb, int lsb)
796 {
797 int i;
798 double r;
799 if (isSigInt(sig, &i) || isSigReal(sig, &r)) {
800 fDeclSig += "signal sig"+addr_to_str(sig)+" : sfixed(" +to_string(msb)+ " downto " +to_string(lsb)+") := to_sfixed("+val_to_str(sig)+","+to_string(msb)+","+to_string(lsb)+");\n";
801 } else {
802 fDeclSig += "signal sig"+ addr_to_str(sig) +" : sfixed("+to_string(msb)+" downto "+to_string(lsb)+");\n";
803 }
804 }
805
input_affectation(Tree sig)806 void Signal2VHDLVisitor::input_affectation(Tree sig)
807 {
808 fInput += "sig" + addr_to_str(sig) + " <= to_sfixed(in_left_V_buf,1,-22);\n";
809 }
810
bin_op(const string & name,const char * op,Tree sig,Tree x,Tree y)811 void Signal2VHDLVisitor::bin_op(const string& name, const char* op, Tree sig, Tree x, Tree y)
812 {
813 if (fEntity.count(op) == 0) {
814 entity_bin_op(name, op, fDeclEntity);
815 component_standard(name, 2, fDeclCompnt);
816 fEntity.insert({op, true});
817 }
818 decl_sig(sig,1,-22);
819 inst_bin_op(name, sig, x, y, fMapCompnt);
820 }
821
select_op(const string & name,Tree sig,Tree sel,Tree x,Tree y)822 void Signal2VHDLVisitor::select_op(const string& name, Tree sig, Tree sel, Tree x, Tree y)
823 {
824 if (fEntity.count(name) == 0) {
825 entity_select2(name, fDeclEntity);
826 component_standard(name, 3, fDeclCompnt);
827 fEntity.insert({name, true});
828 }
829 decl_sig(sig,1,-22);
830 inst_select2(name, sig, sel, x, y, fMapCompnt);
831 }
832
cmp_op(const string & name,const char * op,Tree sig,Tree x,Tree y)833 void Signal2VHDLVisitor::cmp_op(const string& name, const char* op, Tree sig, Tree x, Tree y)
834 {
835 if (fEntity.count(op) == 0) {
836 entity_cmp_op(name, op, fDeclEntity);
837 component_standard(name, 2, fDeclCompnt);
838 fEntity.insert({op, true});
839 }
840 decl_sig(sig,1,-22);
841 inst_bin_op(name, sig, x, y, fMapCompnt);
842 }
843
sincos_op(const string & name,Tree sig,Tree x)844 void Signal2VHDLVisitor::sincos_op(const string& name, Tree sig, Tree x)
845 {
846 if (fEntity.count("SinCos24") == 0) {
847 component_sincos(fDeclCompnt);
848 fEntity.insert({"SinCos24", true});
849 }
850 decl_sig(sig,0,-23);
851 inst_sincos(name, sig, x, fMapCompnt);
852 self(x);
853 }
854
bypass(const string & name,Tree sig,Tree x)855 void Signal2VHDLVisitor::bypass(const string& name, Tree sig, Tree x)
856 {
857 if (fEntity.count(name) == 0) {
858 entity_bypass(name, fDeclEntity);
859 component_standard(name, 1, fDeclCompnt);
860 fEntity.insert({name, true});
861 }
862 decl_sig(sig,1,-22);
863 inst_bypass(name, sig, x, fMapCompnt);
864 }
865