2 * $Id: verilog.c 753 2010-02-27 17:53:32Z elliotth $
4 * Copyright (c) 2003, Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions for generating tags for the Verilog HDL
10 * (Hardware Description Language).
12 * Language definition documents:
13 * http://www.eg.bucknell.edu/~cs320/verilog/verilog-manual.html
14 * http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_top.html
15 * http://www.verilog.com/VerilogBNF.html
16 * http://eesun.free.fr/DOC/VERILOG/verilog_manual1.html
22 #include "general.h" /* must always come first */
37 typedef enum eException
{ ExceptionNone
, ExceptionEOF
} exception_t
;
60 static int Lang_verilog
;
61 static jmp_buf Exception
;
63 static kindOption VerilogKinds
[] = {
64 { TRUE
, 'c', "constant", "constants (define, parameter, specparam)" },
65 { TRUE
, 'e', "event", "events" },
66 { TRUE
, 'f', "function", "functions" },
67 { TRUE
, 'm', "module", "modules" },
68 { TRUE
, 'n', "net", "net data types" },
69 { TRUE
, 'p', "port", "ports" },
70 { TRUE
, 'r', "register", "register data types" },
71 { TRUE
, 't', "task", "tasks" }
74 static keywordAssoc VerilogKeywordTable
[] = {
75 { "`define", K_CONSTANT
},
77 { "function", K_FUNCTION
},
80 { "integer", K_REGISTER
},
81 { "module", K_MODULE
},
83 { "parameter", K_CONSTANT
},
84 { "real", K_REGISTER
},
85 { "realtime", K_REGISTER
},
86 { "reg", K_REGISTER
},
87 { "specparam", K_CONSTANT
},
91 { "time", K_REGISTER
},
104 * FUNCTION DEFINITIONS
107 static void initialize (const langType language
)
111 sizeof (VerilogKeywordTable
) / sizeof (VerilogKeywordTable
[0]);
112 Lang_verilog
= language
;
113 for (i
= 0 ; i
< count
; ++i
)
115 const keywordAssoc
* const p
= &VerilogKeywordTable
[i
];
116 addKeyword (p
->keyword
, language
, (int) p
->kind
);
120 static void vUngetc (int c
)
122 Assert (Ungetc
== '\0');
126 static int vGetc (void)
138 int c2
= fileGetc ();
140 longjmp (Exception
, (int) ExceptionEOF
);
141 else if (c2
== '/') /* strip comment until end-of-line */
145 while (c
!= '\n' && c
!= EOF
);
147 else if (c2
== '*') /* strip block comment */
149 c
= skipOverCComment();
156 else if (c
== '"') /* strip string contents */
161 while (c2
!= '"' && c2
!= EOF
);
165 longjmp (Exception
, (int) ExceptionEOF
);
169 static boolean
isIdentifierCharacter (const int c
)
171 return (boolean
)(isalnum (c
) || c
== '_' || c
== '`');
174 static int skipWhite (int c
)
181 static int skipPastMatch (const char *const pair
)
183 const int begin
= pair
[0], end
= pair
[1];
194 while (matchLevel
> 0);
198 static boolean
readIdentifier (vString
*const name
, int c
)
201 if (isIdentifierCharacter (c
))
203 while (isIdentifierCharacter (c
))
205 vStringPut (name
, c
);
209 vStringTerminate (name
);
211 return (boolean
)(name
->length
> 0);
214 static void tagNameList (const verilogKind kind
, int c
)
216 vString
*name
= vStringNew ();
218 Assert (isIdentifierCharacter (c
));
222 if (isIdentifierCharacter (c
))
224 readIdentifier (name
, c
);
225 makeSimpleTag (name
, VerilogKinds
, kind
);
229 c
= skipWhite (vGetc ());
231 c
= skipPastMatch ("[]");
235 c
= skipWhite (vGetc ());
237 skipPastMatch ("{}");
242 while (c
!= ',' && c
!= ';');
247 c
= skipWhite (vGetc ());
253 vStringDelete (name
);
257 static void findTag (vString
*const name
)
259 const verilogKind kind
= (verilogKind
) lookupKeyword (vStringValue (name
), Lang_verilog
);
260 if (kind
== K_CONSTANT
&& vStringItem (name
, 0) == '`')
262 /* Bug #961001: Verilog compiler directives are line-based. */
263 int c
= skipWhite (vGetc ());
264 readIdentifier (name
, c
);
265 makeSimpleTag (name
, VerilogKinds
, kind
);
266 /* Skip the rest of the line. */
272 else if (kind
!= K_UNDEFINED
)
274 int c
= skipWhite (vGetc ());
276 /* Many keywords can have bit width.
277 * reg [3:0] net_name;
278 * inout [(`DBUSWIDTH-1):0] databus;
281 c
= skipPastMatch ("()");
284 c
= skipPastMatch ("[]");
290 c
= skipPastMatch ("()");
293 if (isIdentifierCharacter (c
))
294 tagNameList (kind
, c
);
298 static void findVerilogTags (void)
300 vString
*const name
= vStringNew ();
301 volatile boolean newStatement
= TRUE
;
302 volatile int c
= '\0';
303 exception_t exception
= (exception_t
) setjmp (Exception
);
305 if (exception
== ExceptionNone
) while (c
!= EOF
)
320 if (newStatement
&& readIdentifier (name
, c
))
322 newStatement
= FALSE
;
326 vStringDelete (name
);
329 extern parserDefinition
* VerilogParser (void)
331 static const char *const extensions
[] = { "v", NULL
};
332 parserDefinition
* def
= parserNew ("Verilog");
333 def
->kinds
= VerilogKinds
;
334 def
->kindCount
= KIND_COUNT (VerilogKinds
);
335 def
->extensions
= extensions
;
336 def
->parser
= findVerilogTags
;
337 def
->initialize
= initialize
;
341 /* vi:set tabstop=4 shiftwidth=4: */