📄 verilog.c
字号:
/** $Id: verilog.c,v 1.3 2003/07/17 04:31:49 darren Exp $* * Copyright (c) 2003, Darren Hiebert* * This source code is released for free distribution under the terms of the* GNU General Public License.* * This module contains functions for generating tags for the Verilog HDL* (Hardware Description Language).* * Language definition documents:* http://www.eg.bucknell.edu/~cs320/1995-fall/verilog-manual.html* http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_top.html* http://home.europa.com/~celiac/VerilogBNF.html* http://eesun.free.fr/DOC/VERILOG/verilog_manual1.html*//* * INCLUDE FILES */#include "general.h" /* must always come first */#include <string.h>#include <setjmp.h>#include "debug.h"#include "keyword.h"#include "parse.h"#include "read.h"#include "vstring.h"/* * DATA DECLARATIONS */typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;typedef enum { K_UNDEFINED = -1, K_CONSTANT, K_EVENT, K_FUNCTION, K_MODULE, K_NET, K_PORT, K_REGISTER, K_TASK} verilogKind;typedef struct { const char *keyword; verilogKind kind;} keywordAssoc;/* * DATA DEFINITIONS */static int Ungetc;static int Lang_verilog;static jmp_buf Exception;static kindOption VerilogKinds [] = { { TRUE, 'c', "constant", "constants (define, parameter, specparam)" }, { TRUE, 'e', "event", "events" }, { TRUE, 'f', "function", "functions" }, { TRUE, 'm', "module", "modules" }, { TRUE, 'n', "net", "net data types" }, { TRUE, 'p', "port", "ports" }, { TRUE, 'r', "register", "register data types" }, { TRUE, 't', "task", "tasks" }};static keywordAssoc VerilogKeywordTable [] = { { "`define", K_CONSTANT }, { "event", K_EVENT }, { "function", K_FUNCTION }, { "inout", K_PORT }, { "input", K_PORT }, { "integer", K_REGISTER }, { "module", K_MODULE }, { "output", K_PORT }, { "parameter", K_CONSTANT }, { "real", K_REGISTER }, { "realtime", K_REGISTER }, { "reg", K_REGISTER }, { "specparam", K_CONSTANT }, { "supply0", K_NET }, { "supply1", K_NET }, { "task", K_TASK }, { "time", K_REGISTER }, { "tri0", K_NET }, { "tri1", K_NET }, { "triand", K_NET }, { "tri", K_NET }, { "trior", K_NET }, { "trireg", K_NET }, { "wand", K_NET }, { "wire", K_NET }, { "wor", K_NET }};/* * FUNCTION DEFINITIONS */static void initialize (const langType language){ size_t i; const size_t count = sizeof (VerilogKeywordTable) / sizeof (VerilogKeywordTable [0]); Lang_verilog = language; for (i = 0 ; i < count ; ++i) { const keywordAssoc* const p = &VerilogKeywordTable [i]; addKeyword (p->keyword, language, (int) p->kind); }}static void vUngetc (int c){ Assert (Ungetc == '\0'); Ungetc = c;}static int vGetc (void){ int c; if (Ungetc == '\0') c = fileGetc (); else { c = Ungetc; Ungetc = '\0'; } if (c == '/') { int c2 = fileGetc (); if (c2 == EOF) longjmp (Exception, (int) ExceptionEOF); else if (c2 == '/') /* strip comment until end-of-line */ { do c = fileGetc (); while (c != '\n' && c != EOF); } else if (c2 == '*') /* strip block comment */ { do { do c = fileGetc (); while (c != '*' && c != EOF); if (c != EOF) c = fileGetc (); } while (c != '/' && c != EOF); if (c != EOF) c = ' '; /* comment equivalent to white space */ } else Ungetc = c2; } else if (c == '"') /* strip string contents */ { int c2; do c2 = fileGetc (); while (c2 != '"' && c2 != EOF); c = '@'; } if (c == EOF) longjmp (Exception, (int) ExceptionEOF); return c;}static boolean isIdentifierCharacter (const int c){ return (boolean)(isalnum (c) || c == '_' || c == '`');}static int skipWhite (int c){ while (isspace (c)) c = vGetc (); return c;}static int skipPastMatch (const char *const pair){ const int begin = pair [0], end = pair [1]; int matchLevel = 1; int c; do { c = vGetc (); if (c == begin) ++matchLevel; else if (c == end) --matchLevel; } while (matchLevel > 0); return vGetc ();}static boolean readIdentifier (vString *const name, int c){ vStringClear (name); if (isIdentifierCharacter (c)) { while (isIdentifierCharacter (c)) { vStringPut (name, c); c = vGetc (); } vUngetc (c); vStringTerminate (name); } return (boolean)(name->length > 0);}static void tagNameList (const verilogKind kind, int c){ vString *name = vStringNew (); boolean repeat; Assert (isIdentifierCharacter (c)); do { repeat = FALSE; if (isIdentifierCharacter (c)) { readIdentifier (name, c); makeSimpleTag (name, VerilogKinds, kind); } else break; c = skipWhite (vGetc ()); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '=') { if (c == '{') skipPastMatch ("{}"); else { do c = vGetc (); while (c != ',' && c != ';'); } } if (c == ',') { c = skipWhite (vGetc ()); repeat = TRUE; } else repeat = FALSE; } while (repeat); vStringDelete (name); vUngetc (c);}static void findTag (vString *const name){ const verilogKind kind = (verilogKind) lookupKeyword (vStringValue (name), Lang_verilog); if (kind != K_UNDEFINED) { int c = skipWhite (vGetc ()); /* Many keywords can have bit width. * reg [3:0] net_name; * inout [(`DBUSWIDTH-1):0] databus; */ if (c == '(') c = skipPastMatch ("()"); c = skipWhite (c); if (c == '[') c = skipPastMatch ("[]"); c = skipWhite (c); if (c == '#') { c = vGetc (); if (c == '(') c = skipPastMatch ("()"); } c = skipWhite (c); if (isIdentifierCharacter (c)) tagNameList (kind, c); }}static void findVerilogTags (void){ vString *const name = vStringNew (); volatile boolean newStatement = TRUE; volatile int c = '\0'; exception_t exception = (exception_t) setjmp (Exception); if (exception == ExceptionNone) while (c != EOF) { c = vGetc (); switch (c) { case ';': case '\n': newStatement = TRUE; break; case ' ': case '\t': break; default: if (newStatement && readIdentifier (name, c)) findTag (name); newStatement = FALSE; break; } } vStringDelete (name);}extern parserDefinition* VerilogParser (void){ static const char *const extensions [] = { "v", NULL }; parserDefinition* def = parserNew ("Verilog"); def->kinds = VerilogKinds; def->kindCount = KIND_COUNT (VerilogKinds); def->extensions = extensions; def->parser = findVerilogTags; def->initialize = initialize; return def;}/* vi:set tabstop=8 shiftwidth=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -