Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
272 lines (229 sloc) 5.35 KB
/**
* Grammar for Verilog four-state Value Change Dump (VCD) files, based
* on IEEE Std 1364-2001 (Verilog Hardware Description Language),
* Chapter 18.
*
* NOTE that I've taken some liberty with the lexer rule for
* identifiers (id_code and reference): The spec allows any
* combination of printable ASCII characters as id_code, but that
* makes for some serious lexing conflict. I've excluded a digits, b,
* B, x, X, z, Z, #, and $ as initial characters -- I've never
* personally seen a VCD file use any of those characters to begin an
* id_code, but it's legal to do so.
*
* Author: Eric Anderson
* Copyright (C) 2011 Carnegie Mellon University
* License: GNU General Public License (GPL) version 3 or later
*
* This grammar is part of the AD9510 SPI command parser at
* https://github.com/ewa/ad9510spi, or it can be used on its own.
* The tree parsers InterpretVCDHeader.g and VCDSimulation.g "read"
* the AST generated by this grammar.
*
*/
grammar ValueChangeDump;
options {
language=Python;
output=AST;
}
tokens {
ENDDEFNS = '$enddefinitions';
END= '$end';
TIMESCALE= '$timescale';
SCOPE= '$scope';
VAR= '$var';
UPSCOPE= '$upscope';
OCTOTHORPE= '#';
DUMPALL= '$dumpall';
DUMPON= '$dumpon';
DUMPOFF= '$dumpoff';
DUMPVARS= '$dumpvars';
BEGIN= 'begin';
FORK= 'fork';
FUNCTION= 'function';
MODULE= 'module' ;
TASK= 'task';
EVENT= 'event';
INTEGER= 'integer';
PARAMETER= 'parameter';
REAL= 'real';
REG= 'reg';
SUPPLY0= 'supp ly0';
SUPPLY1= 'supply1';
TIME= 'time';
TRI= 'tri';
TRIAND= 'triand';
TRIOR= 'trio';
TRIREG= 'trireg';
TRI0= 'tri0';
TRI1= 'tri1';
WAND= 'wand';
WIRE= 'wire';
WOR= 'wor';
HEADER;
FOO;
DECL;
DECLS;
NEWSCOPE;
NEWVAR;
DECLSCOPE;
BINVEC;
SIM_COMMAND;
TIME;
SCALAR_CHANGE;
VECTOR_CHANGE;
SCALAR_VALUE;
}
/* Parser rules */
vcd_file: vcd_header simulation_commands ;
// HEADER
vcd_header
: decl_command_list end_defns
-> ^(HEADER decl_command_list)
;
decl_command_list
: decl_command+
-> ^(DECLS decl_command+)
;
decl_command
: vcd_decl_date
| vcd_decl_version
| vcd_decl_timescale
| vcd_scope
| vcd_decl_vars
;
end_defns
: ENDDEFNS END ->
;
vcd_decl_date
: DATE ->
;
vcd_decl_version
: VERSION ->
;
vcd_decl_timescale
: TIMESCALE DEC_NUM TIME_UNIT END
-> ^(TIMESCALE DEC_NUM TIME_UNIT)
;
vcd_scope
: vcd_decl_scope decl_command_list vcd_decl_upscope
-> ^(NEWSCOPE vcd_decl_scope decl_command_list)
;
vcd_decl_scope
: SCOPE scope_type IDENTIFIER END
-> ^(DECLSCOPE scope_type IDENTIFIER)
;
vcd_decl_upscope
: UPSCOPE END
;
scope_type
: BEGIN
| FORK
| FUNCTION
| MODULE
| TASK
;
vcd_decl_vars
: VAR type=var_type size=DEC_NUM id_code=IDENTIFIER ref=IDENTIFIER END
-> ^(NEWVAR $type $size $id_code $ref)
;
var_type
: EVENT
| INTEGER
| PARAMETER
| REAL
| REG
| SUPPLY0
| SUPPLY1
| TIME
| TRI
| TRIAND
| TRIOR
| TRIREG
| TRI0
| TRI1
| WAND
| WIRE
| WOR
;
//COMMANDS
simulation_commands
: simulation_command+
;
simulation_command
: simulation_time
-> ^(SIM_COMMAND simulation_time)
| value_change
-> ^(SIM_COMMAND value_change)
| ML_COMMENT
-> ^(ML_COMMENT)
| simulation_keyword (value_change)+ END
->
;
simulation_keyword
: DUMPALL | DUMPON | DUMPOFF | DUMPVARS
;
simulation_time
: OCTOTHORPE DEC_NUM
-> ^(TIME DEC_NUM)
;
value_change
: scalar_value_change
| vector_value_change
;
scalar_value_change
: value IDENTIFIER
-> ^(SCALAR_CHANGE IDENTIFIER value)
;
// Throw an error if DEC_NUM is mult-digit
value
: DEC_NUM
-> ^(SCALAR_VALUE[$DEC_NUM.text])
| 'X'
-> ^(SCALAR_VALUE['X'])
| 'x'
-> ^(SCALAR_VALUE['x'])
| 'Z'
-> ^(SCALAR_VALUE['Z'])
| 'z'
-> ^(SCALAR_VALUE['z'])
;
vector_value_change
: n=BIN_NUM IDENTIFIER
// What? This is a fugly work-around for the fact that [] doesn't play nice with antlr
-> ^(VECTOR_CHANGE IDENTIFIER BINVEC[$n.text.__getslice__(1,len($n.text))])
;
/* Lexer rules */
DEC_NUM : ('0'..'9')+
;
BIN_NUM : ('b'|'B')('x'|'X'|'z'|'Z'|'0'|'1')+
;
TIME_UNIT
: 's' | 'ms' | 'us' | 'ns' | 'ps' | 'fs'
;
ML_COMMENT
: '$comment' (options {greedy=false;} : .)* '$end' {$channel=HIDDEN;}
;
DATE
: '$date' (options {greedy=false;} : .)* '$end'
;
VERSION
: '$version' (options {greedy=false;} : .)* '$end'
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
/*
IDENTIFIER : ('a'..'z'|'A'..'Z'|'_'|'!'..'/') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'!'..'/')*
;
*/
// Almost every non-space printable character. The '..' operation here depends on the ASCII ordering
// Note that I am departing from the IEEE standard by not allowing a digit, b, B, x, X, z, Z, #, or $ as the first character. That's a
// hack to prevent strings like "10ns" from being lexed as an identifier. So far, every VCD file I've looked at
// complies with this, but it's still technically wrong.
IDENTIFIER
: ('a'|'c'..'w'|'y'|'A'|'C'..'W'|'Y'|'_'|'!'|'"'|'%'..'/'|':'..'@'|'{'..'~')('!'..'~')+
;