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