/** * 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'|'_'|'!'|'"'|'%'..'/'|':'..'@'|'{'..'~')('!'..'~')+ ;