All about a Verilog V200x parser project hosted at SourceForge:

Wednesday, December 30, 2009

Latest version includes (Synopsys) Liberty File parser

I (finally) uploaded an update here.

The most interesting new feature is support for Liberty Files (aka., .lib files).
Upon download, note a slight rearrangement of the directory structure:

slf/ --- files related to parsing of Synopsys Liberty Files
ssi/ --- files related to Simple Serialization Interface
v2k/ --- files related to Verilog parser

There is also an additional option --gen_xref which can be used to generate a module cross reference.

> v2k/bin/analyze

Usage: analyze --flatten? (--tcl out.tcl)? (--rb out.rb)? (--outf out.f)?
--only_used? --exit_on_err? (--verbose n)? --abs_paths?
(--redefn n)? (-E -C?)?
topModule vlogOpts+

--flatten : stop after flattening .f files.
: Useful with "--outf" to capture flat .f
: for subsequent processing.
--tcl out.tcl : dump details in tcl format to "out.tcl".
--rb out.rb : dump details in ruby format to "out.rb".
--outf out.f : dump details into flat Verilog .f file "out.f"
using only +incdir+, +define+ and file.v.
--only_used : only dump files which contained a module
: definition required for linking "topModule".
--exit_on_err : exit status != 0 if any parse errors.
And, no "out.tcl" generated if errors.
--verbose n : Verbose messages during linking. "n" is:
2 (most verbose) 1 (default); 0 (off).
--abs_paths : Make/display all file/directory names absolute.
Useful for debugging (the where of) include files.
--gen_xref : Generate "topModule.refs.txt".
Contains a cross-reference of module references.
-E : dump pre-processed files to "file.v.E".
Useful for debugging preprocessing issues.
-C : do not discard comments when "-E" is specified.

vlogOpts is one of:
-f args.f
-v library.v
-y library_directory
+no_defn+mod1(+modn)* : specify "mod1" as undefined
(a priori) so no link error.
+slf+f1.lib(+fi.lib)* : specify Synopsys Liberty File "f1.lib".

NOTE: a .f file can contain entries of the form "${VAR}/foo.v"
to specify that the value of the environment variable "VAR"
be used (i.e., replace ${VAR} with ENV['VAR'], in ruby parlance)
during .f file processing. This is useful to root file/directory
locations using an environment variable, rather than hardcoding
in .f files themselves.

The +slf+ option can be used to pass .lib files to resolve any (typically instantiated) library (leaf) or macro cells.

If any of the +slf+ file(s) are actually required to link the design, their filename(s) will be output into the out.tcl file specified using the --tcl option. The tcl list variable slf_used will be used.

Wednesday, March 25, 2009

Unscheduled interruption (but a good one)

I have been adding a few fixes to the grammar and infrastructure: adding a symbol table and Simple Streaming Interface (SSI, as I call it): a file persistance mechanism. Hopefully, I'll have these posted next week, in a very alpha-ish state.

On the interrupt front: during my day job, I do a lot with synthesis and timing/design closure for large ASICs. I have been looking a lot at design/RTL and netlist quality (QOR) and to the latter: do a lot of manipulation/querying in either the synthesis tool or static timing analyzer, since both those have excellent (Tcl-based) UIs for such.

However, since those tools/licenses are very few and very $$$, it seemed natural to just strip down the v2kparse stuff for netlist-only type stuff. I had done an earlier (C++) type project at this sourceforge project and decided to shift gears a bit. So, I am in the process of revamping that project to use Java and Ruby: let's all say it together: JRuby!

At this point, I have the (netlist) and parser infrastructure completed in Antlr and Java, and have added a JRuby layer around it. For example: to iterate over a full (hierarchical) module/netlist to find and print (inefficient) instances of sequential cells with constant clocks and/or constant async set/reset pins, you simply:

#Find important reg pins tied to 0
msg = ": pin tied 0"
top_module.foreach_on_const_net(0) do |conns, val, inst_name|
conns.each do |conn|
if conn.isPin
pin =
Message.warn(pin.get_name(inst_name)+msg) if pin.get_name =~ /\/([CS]DN|CP)$/

Pretty cool!

Anyway, I want to flush through and post my updates to sourceforce and then update v2kparse shortly.

Stay tuned.

Monday, January 26, 2009

The parse tree evolves

The latest release to sourceforge includes the 1st pass of a full parse tree.
The parse tree classes are under:
There are 133 .java source files there; no wonder it's taken a while.

NOTE: ANTLR does have (automatic) AST (Abstract Syntax Tree) building capability. However, I wanted to experience the very hands-on experience of crafting my own, for this project. Not to worry, there will be many more parsers, for many more DSLs to work on; and, automatic AST generation will be more efficient there.

There is a simple script
 > bin/ptree

Error: Must specify at least one "infile".
Usage: v2kparse [options] infile...


-I dir Add dir (must be readable) to `include file search path.

-D name Predefine name as a macro with value 1.

-D name=defn Predefine name as a macro with value defn.

Those options are less friendly than the (more common) Verilog style options (as in bin/analyze; see earlier blogs); but useful for testing.

Examine the bin/analyze and bin/ptree script to see the latter simply defines the constant USEPT (use parse tree). This constant is detected in file srcs/v2k/parser/ and selects which sub-class of
  public abstract class ASTreeBase
to build the tree. There are 2 sub-classes:
  1. v2k.parser.tree.basic.ParseTree
  2. v2k.parser.tree.ParseTree
The 1st: tree.basic.ParseTree is used to build a simple tree which simply tracks module names and instances. That is used by the bin/analyze script to glean info appropriate for source file dependency tracking (described in earlier blogs.) The 2nd one: tree.ParseTree is used for full tree construction, as in the bin/ptree script.

So, get your hands dirty playing around with bin/ptree. And, if you embelish the bin/analyze script with use of the -DUSEPT argument to java, then you could also get a full-blown parse tree, and use the more standard Verilog command line arguments, too. However, since the analyze script also uses jruby hooks to generate usable output, by walking the basic.ParseTree, the jruby scripts would also have to be changed (since the API of the basic.ParseTree and (full) tree.ParseTree is slightly different).

The next phase of the project is to add elaboration...