I uploaded the next version to
sourceforge.
This new version cleaned up a few missing constructs and pre-processor directives which I encountered while testing even more real design RTL.
So, while getting the parser/grammar stuff done was not too painful, thanx to
ANTLR and the great debugger in
Netbeans; moving on to the linker stage was a great experience: I bit the bullet and learned
JRuby.
(An
excellent book on Ruby itself is here.)
Why JRuby? Well, I am normally a Tcl guy, when it comes to complex scripting. I never learned Perl, since when I was at the crossroads of having to abandon complex awk, greps, seds and csh, I was fortunate enough to cross paths w/ John Ousterhout (the creator of Tcl) on a road show at Sun promoting Tcl. Never had any regrets: it's a great language, and ever prevelant in any self-respecting EDA tools.
Hmmm, I still haven't answered the why JRuby, huh?
So, while I could have continued to do more of the rudimentary stuff around the parser (such as quick linking) in Java, I was aware of the JRuby capabilities w/in Netbeans (did I say how much I luv Netbeans?)... so did a little more digging and playing... and it's great!
JRuby essentially gives you the Ruby language, which is a truly object-oriented interpreted language (while some may say scripting language, that has some negative connotations, IMHO, esp. if you compare it w/ other so-called scripting languages (like Perl --- yuk!)). BUT, the best part is that the "J" part brings Java into the picture, too. So, we can use Java for the more elegant parts of our design, and then Ruby for the more "one offs", experimental, oft-changing, ... parts. (Or, just an excuse to use/learn Ruby!)
So, the tact I took in this release is to use the Java part for the analyze part of the parser, and the Ruby side to parse options, iterate looking for candidate files (i.e., the -y +libext+ verilog options) and interact with the parse tree to (quick) link the design, in the interest of finding the complete (flat list of) files from the (typically) succinct .f files.
(Go back to my 1st blog post to refresh to my original motivation for this project.)
So, after you download and untar
this release, you will also need to install/add the path to jruby on your system.
If you do not have jruby, I would strongly suggest using the
Netbeans "all" pack.
On my system, I have:
> which jruby/opt/netbeans-6.1/ruby2/jruby-1.1/bin/jrubyAfter that is all setup, you can run a very simple testcase. (I will eventually add something more complex; but, didn't want to slog the sourceforge downloads w/ huge designs, like the
free Sparc one... and the
opencores.org ones may not be so easily redistributed... and didn't want any legal hassles at such a young age).
So, the simple one:
# I untar-d the download under /tmp/v2k, in this example> cd /tmp; mkdir v2k; cd v2k> download v2kparse-0.2.tar.gz; tar zxf v2kparse-0.2.tar.gz> bin/analyzeUsage: analyze.rb topModule vlogOpts+ where vlogOpts is one of file.v
-f args.f
-v library.v -y library_directory +incdir+dir1(+dirn)* +define+d(=v)?(+dn(=vn)?)*> cd data# run the simple testcase> ../bin/analyze m1 -f tc2.fDBG1: after proc_args: +define+SYNTHESIS +incdir+tc2 -y tc2 tc2/m1.vInfo: Pass 1: -I tc2 -D SYNTHESIS tc2/m1.v.Info : tc2/m1.v:1: include file "/tmp/v2k/data/tc2/defs.vh". (INCL-1)Info: Unresolved: m2.Info: Pass 2: /tmp/v2k/data/tc2/m2.v.Info: Unresolved: m3.Info: Pass 3: /tmp/v2k/data/tc2/m3.v.Info: Link status: true.In this (simple) testcase, the tc2.f is:
+define+SYNTHESIS+incdir+tc2-y tc2tc2/m1.vSo, as the analyze runs, the analyze.rb script is iterating:
- starting with the fully specific file: tc2/m1.v
- running the (java-based) parser
- querying the parse tree (created by parser) for defined modules and their references
- (analyze.rb) keeps track of defined, linked and unresolved references
- uses the unresolved references and the -y +libext+ specs to find matching files
- repeatedly calls the parser (with the newly found files) and queries the incrementally (modified) parse tree
- goto 3 and repeat until fully linked, or nothing else to do
I've left some debug messages in the code; and, the final message indicates whether the link was successful.
DISCLAIMER: this is a quick link, in the sense that an elaborate is not done: there are no port/pin checks, etc. Just a simple check that a referenced module is defined, or is defined to be a leaf cell.
If you want to play around with your own designs, you will likely have instanced memories, standard cells, macros, etc. which you normally would not specify in a .f file, explicitly. These normally are added via a library.f for simulation; and, would use .lib/.db files for typical implementation tasks, like synthesis.
So, there needs to be a convenient way to specify what modules names should be considered leafs. If you look in the ruby/srcs/analyze.rb file (at the bottom), you will see:
210 #TODO: Redefine the is_leaf method to describe module names211 # which are not defined in any (user created) verilog contexts.212 # There are typically leaf/library cells.213 #...That describes how to specify leafs for your specific needs.
Have fun with this release, and I'll be back with more soon!