1 /****************************************************************************
2 Copyright (C) 1987-2015 by Jeffery P. Hansen
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 ****************************************************************************/
18 #include <unistd.h>
19 #include <string.h>
20 #include <ctype.h>
21 #include <stdio.h>
22 #include "config.h"
23 #include "yybasic.h"
24 #include "vgrammar.h"
25 #include "vparser.h"
26 #include "ycmalloc.h"
27
28 #define STRMAX 8192
29
30 extern struct lex_keywordentry lex_verilog_words[];
31 extern int lex_verilog_num;
32 extern struct lex_keywordentry lex_anotate_words[];
33 extern int lex_anotate_num;
34 extern struct lex_keywordentry lex_delay_words[];
35 extern int lex_delay_num;
36
37 static int default_module_type = HDLMODULE;
38 static int current_module_type = HDLMODULE;
39
40 typedef void *Encoder;
41 size_t recodeText(Encoder *encoder, char *toString,int len, const char *fromString);
42 extern Encoder *parserEncoder;
43
44 /*****************************************************************************
45 *
46 * List of all Verilog reserved words. These are used by the ycIsKW() function
47 * to indicate these names should not be used as identifiers in user circuits.
48 *
49 *****************************************************************************/
50 struct lex_keywordentry lex_reserved_words[] = {
51 {"always",1},
52 {"and",1},
53 {"assign",1},
54 {"attribute",1},
55 {"begin",1},
56 {"buf",1},
57 {"bufif0",1},
58 {"bufif1",1},
59 {"case",1},
60 {"casex",1},
61 {"casez",1},
62 {"cmos",1},
63 {"deassign",1},
64 {"default",1},
65 {"defparam",1},
66 {"disable",1},
67 {"edge",1},
68 {"else",1},
69 {"end",1},
70 {"endattribute",1},
71 {"endcase",1},
72 {"endfunction",1},
73 {"endmodule",1},
74 {"endprimitive",1},
75 {"endspecify",1},
76 {"endtable",1},
77 {"endtask",1},
78 {"event",1},
79 {"for",1},
80 {"force",1},
81 {"forever",1},
82 {"fork",1},
83 {"function",1},
84 {"highz0",1},
85 {"highz1",1},
86 {"if",1},
87 {"ifnone",1},
88 {"initial",1},
89 {"inout",1},
90 {"input",1},
91 {"integer",1},
92 {"join",1},
93 {"large",1},
94 {"medium",1},
95 {"module",1},
96 {"macromodule",1},
97 {"nand",1},
98 {"negedge",1},
99 {"nmos",1},
100 {"nor",1},
101 {"not",1},
102 {"notif0",1},
103 {"notif1",1},
104 {"or",1},
105 {"output",1},
106 {"parameter",1},
107 {"pmos",1},
108 {"posedge",1},
109 {"primitive",1},
110 {"pull0",1},
111 {"pull1",1},
112 {"pulldown",1},
113 {"pullup",1},
114 {"rcmos",1},
115 {"real",1},
116 {"realtime",1},
117 {"reg",1},
118 {"release",1},
119 {"repeat",1},
120 {"rnmos",1},
121 {"rpmos",1},
122 {"rtran",1},
123 {"rtranif0",1},
124 {"rtranif1",1},
125 {"scalared",1},
126 {"signed",1},
127 {"small",1},
128 {"specify",1},
129 {"specparam",1},
130 {"strength",1},
131 {"strong0",1},
132 {"strong1",1},
133 {"supply0",1},
134 {"supply1",1},
135 {"table",1},
136 {"task",1},
137 {"time",1},
138 {"tran",1},
139 {"tranif0",1},
140 {"tranif1",1},
141 {"tri",1},
142 {"tri0",1},
143 {"tri1",1},
144 {"triand",1},
145 {"trior",1},
146 {"trireg",1},
147 {"unsigned",1},
148 {"vectored",1},
149 {"wait",1},
150 {"wand",1},
151 {"weak0",1},
152 {"weak1",1},
153 {"while",1},
154 {"wire",1},
155 {"wor",1},
156 {"xnor",1},
157 {"xor",1},
158 };
159
160 int lex_reserved_num = sizeof(lex_reserved_words)/sizeof(lex_reserved_words[0]);
161
162 int nativeVerilog = 0;
163
ycCheckHdlLine(char * s)164 int ycCheckHdlLine(char *s)
165 {
166 char *p;
167
168 /*
169 * Trim trailing newline.
170 */
171 p = strrchr(s,'\n');
172 if (p) *p = 0;
173
174 if (strstr(s,"//: /builtinEnd") != 0) {
175 ycSetModuleType(XMODULE);
176 return END;
177 }
178
179 if (strstr(s,"//: endscript") != 0) {
180 return END;
181 }
182
183 /*
184 * If this line has a '//: /netlistEnd' or '//: /hdlEnd' on it, treat this as
185 * the end of a new-style text segment. If the line has 'endmodule' on it,
186 * treat it as the end of a native verilog module.
187 */
188 if (nativeVerilog) {
189 if (strstr(s,"endmodule") != 0)
190 return ENDMODULE;
191 } else {
192 if (strstr(s,"//: /netlistEnd") != 0 || strstr(s,"//: /hdlEnd") != 0) {
193 ycSetModuleType(XMODULE);
194 return END;
195 }
196 }
197
198
199
200 yylval.S = yc_strdup(s);
201 return HDLLINE;
202 }
203
204
ycKeyCmp(const char * S1,const char * S2)205 int ycKeyCmp(const char *S1,const char *S2)
206 {
207 for (;*S1;S1++,S2++) {
208 int C1 = islower(*S1) ? toupper(*S1) : *S1;
209 int C2 = islower(*S2) ? toupper(*S2) : *S2;
210 if (C1 != C2) return (C1 < C2) ? -1 : 1;
211 }
212 return *S2 ? -1 : 0;
213 }
214
ycLookup(char * Tok,struct lex_keywordentry * low,int len)215 int ycLookup(char *Tok,struct lex_keywordentry *low,int len)
216 {
217 struct lex_keywordentry *high = low+len-1;
218 struct lex_keywordentry *K;
219
220 while (low <= high) {
221 K = low + (high-low)/2;
222 switch (ycKeyCmp(K->Keyword,Tok)) {
223 case 0 :
224 return K->Value;
225 case -1 :
226 low = K + 1;
227 break;
228 case 1 :
229 high = K - 1;
230 break;
231 }
232 }
233
234 return -1;
235 }
236
237 /*****************************************************************************
238 *
239 *
240 *
241 *****************************************************************************/
ycIsKW(char * Tok)242 int ycIsKW(char *Tok)
243 {
244 if (ycLookup(Tok,lex_anotate_words,lex_anotate_num) >= 0) return 1;
245 if (ycLookup(Tok,lex_verilog_words,lex_verilog_num) >= 0) return 1;
246 if (ycLookup(Tok,lex_reserved_words,lex_reserved_num) >= 0) return 1;
247 return 0;
248 }
249
250 /*
251 Parse a "literal-like" token. If it is in a keyword table, return the
252 token for that keyword, otherwise treat it as a literal.
253 */
ycLiteral(char * Tok,struct lex_keywordentry * low,int len)254 int ycLiteral(char *Tok,struct lex_keywordentry *low,int len)
255 {
256 int t;
257
258 if (!Tok) Tok = "?";
259 yylval.S = "???";
260
261 t = ycLookup(Tok,low,len);
262 yylval.S = yc_strdup(Tok);
263
264 /*
265 * Special case for module keywords
266 */
267 switch (t) {
268 case XMODULE :
269 t = current_module_type;
270 break;
271 case NETLISTBEGIN :
272 ycSetModuleType(NETMODULE);
273 break;
274 case HDLBEGIN :
275 ycSetModuleType(HDLMODULE);
276 break;
277 case END :
278 ycSetModuleType(XMODULE);
279 break;
280 }
281
282 return t >= 0 ? t : LITERAL;
283 }
284
ycString(char * s)285 int ycString(char *s)
286 {
287 char buf[STRMAX];
288 char buf2[STRMAX];
289 char *p;
290
291 /*
292 * Copy string and remove quotes.
293 */
294 strcpy(buf,s+1);
295 buf[strlen(buf)-1] = 0;
296
297 /*
298 * Remove any '\' characters that may have been used to quote a quote character.
299 */
300 for (p = buf;*p;p++)
301 if (*p == '\\' && p[1]) {
302 memmove(p,p+1,strlen(p+1)+1);
303 p++;
304 }
305
306 /*
307 * Translate the string from the file coding system.
308 */
309 recodeText(parserEncoder, buf2, STRMAX, buf);
310
311 /*
312 * Set resulting string
313 */
314 yylval.S = yc_strdup(buf2);
315
316 return STRING;
317 }
318
yywrap()319 int yywrap()
320 {
321 return 1;
322 }
323
ycSetDefaultModuleType(int modType)324 void ycSetDefaultModuleType(int modType)
325 {
326 default_module_type = modType;
327 current_module_type = modType;
328 }
329
ycSetModuleType(int modType)330 void ycSetModuleType(int modType)
331 {
332 if (modType == XMODULE)
333 current_module_type = default_module_type;
334 else
335 current_module_type = modType;
336 }
337
338