2
* $Id: verilog.c 4474 2009-12-07 17:51:37Z ntrel $
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 */
36
typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
59
static int Lang_verilog;
60
static jmp_buf Exception;
62
static kindOption VerilogKinds [] = {
63
{ TRUE, 'c', "variable", "constants (define, parameter, specparam)" },
64
{ TRUE, 'e', "typedef", "events" },
65
{ TRUE, 'f', "function", "functions" },
66
{ TRUE, 'm', "class", "modules" },
67
{ TRUE, 'n', "variable", "net data types" },
68
{ TRUE, 'p', "variable", "ports" },
69
{ TRUE, 'r', "variable", "register data types" },
70
{ TRUE, 't', "function", "tasks" }
73
static keywordAssoc VerilogKeywordTable [] = {
74
{ "`define", K_CONSTANT },
76
{ "function", K_FUNCTION },
79
{ "integer", K_REGISTER },
80
{ "module", K_MODULE },
82
{ "parameter", K_CONSTANT },
83
{ "real", K_REGISTER },
84
{ "realtime", K_REGISTER },
85
{ "reg", K_REGISTER },
86
{ "specparam", K_CONSTANT },
90
{ "time", K_REGISTER },
103
* FUNCTION DEFINITIONS
106
static void initialize (const langType language)
110
sizeof (VerilogKeywordTable) / sizeof (VerilogKeywordTable [0]);
111
Lang_verilog = language;
112
for (i = 0 ; i < count ; ++i)
114
const keywordAssoc* const p = &VerilogKeywordTable [i];
115
addKeyword (p->keyword, language, (int) p->kind);
119
static void vUngetc (int c)
121
Assert (Ungetc == '\0');
125
static int vGetc (void)
137
int c2 = fileGetc ();
139
longjmp (Exception, (int) ExceptionEOF);
140
else if (c2 == '/') /* strip comment until end-of-line */
144
while (c != '\n' && c != EOF);
146
else if (c2 == '*') /* strip block comment */
148
c = skipOverCComment();
155
else if (c == '"') /* strip string contents */
160
while (c2 != '"' && c2 != EOF);
164
longjmp (Exception, (int) ExceptionEOF);
168
static boolean isIdentifierCharacter (const int c)
170
return (boolean)(isalnum (c) || c == '_' || c == '`');
173
static int skipWhite (int c)
180
static int skipPastMatch (const char *const pair)
182
const int begin = pair [0], end = pair [1];
193
while (matchLevel > 0);
197
static boolean readIdentifier (vString *const name, int c)
200
if (isIdentifierCharacter (c))
202
while (isIdentifierCharacter (c))
204
vStringPut (name, c);
208
vStringTerminate (name);
210
return (boolean)(name->length > 0);
213
static void tagNameList (const verilogKind kind, int c)
215
vString *name = vStringNew ();
217
Assert (isIdentifierCharacter (c));
221
if (isIdentifierCharacter (c))
223
readIdentifier (name, c);
224
makeSimpleTag (name, VerilogKinds, kind);
228
c = skipWhite (vGetc ());
230
c = skipPastMatch ("[]");
235
skipPastMatch ("{}");
240
while (c != ',' && c != ';');
245
c = skipWhite (vGetc ());
251
vStringDelete (name);
255
static void findTag (vString *const name)
257
const verilogKind kind = (verilogKind) lookupKeyword (vStringValue (name), Lang_verilog);
258
if (kind == K_CONSTANT && vStringItem (name, 0) == '`')
260
/* Bug #961001: Verilog compiler directives are line-based. */
261
int c = skipWhite (vGetc ());
262
readIdentifier (name, c);
263
makeSimpleTag (name, VerilogKinds, kind);
264
/* Skip the rest of the line. */
270
else if (kind != K_UNDEFINED)
272
int c = skipWhite (vGetc ());
274
/* Many keywords can have bit width.
275
* reg [3:0] net_name;
276
* inout [(`DBUSWIDTH-1):0] databus;
279
c = skipPastMatch ("()");
282
c = skipPastMatch ("[]");
288
c = skipPastMatch ("()");
291
if (isIdentifierCharacter (c))
292
tagNameList (kind, c);
296
static void findVerilogTags (void)
298
vString *const name = vStringNew ();
299
volatile boolean newStatement = TRUE;
300
volatile int c = '\0';
301
exception_t exception = (exception_t) setjmp (Exception);
303
if (exception == ExceptionNone) while (c != EOF)
318
if (newStatement && readIdentifier (name, c))
320
newStatement = FALSE;
324
vStringDelete (name);
327
extern parserDefinition* VerilogParser (void)
329
static const char *const extensions [] = { "v", NULL };
330
parserDefinition* def = parserNew ("Verilog");
331
def->kinds = VerilogKinds;
332
def->kindCount = KIND_COUNT (VerilogKinds);
333
def->extensions = extensions;
334
def->parser = findVerilogTags;
335
def->initialize = initialize;
339
/* vi:set tabstop=4 shiftwidth=4: */