Project

General

Profile

Getting Started » History » Revision 8

Revision 7 (Alexander Kamkin, 05/06/2014 09:04 AM) → Revision 8/11 (Alexander Kamkin, 05/06/2014 10:28 AM)

h1. Getting Started 

 This is a step-by-step instruction for getting started with developing a "VeriTrans":http://forge.ispras.ru/projects/veritrans backend and using it within the Verilog translator environment. The term _backend_ refers to a component that traverses an _abstract syntax tree_ (_AST_) of the Verilog description and processes it in some way (e.g., constructs the internal representation and/or converts the description into some other language). The document is illustrated by the example of @VerilogPrinter@ (see the package @ru.ispras.verilog.parser.sample@). 

 h2. Developing a Backend 

 Technically, a backend is a Java object that implements the @VerilogBackend@ interface (the method @start@). Here is an example: 

 <pre><code class="java"> 
 package ru.ispras.verilog.parser.sample; 

 import ru.ispras.verilog.parser.VerilogBackend; 

 
 import ru.ispras.verilog.parser.model.*;         // AST nodes (@Module@, @Activity@, etc.) 
 import ru.ispras.verilog.parser.model.basis.*; // Objects used in AST nodes (@Expression@, @Range@, etc.) 
 ... 

 /** 
  * This class illustrates development of a Verilog backend. 
  */ 
 public final class VerilogPrinter extends VerilogBackend 
 { 
     /** 
      * Processes the abstract syntax tree (AST). 
      * 
      * @param root the AST''s root. 
      */ 
     public void start(final VerilogNode root) 
     { 
         ... 
     } 
 } 
 </code></pre> 

 To ease development of a backend, one can use @VerilogTreeWalker@, a "VeriTrans":http://forge.ispras.ru/projects/veritrans class that implements AST traversal. The @VerilogTreeWalker@''s constructor takes two parameters: (1) a reference to the tree''s root and (2) a visitor to be applied to the tree nodes: 

 <pre><code class="java"> 
 ... 
 import ru.ispras.verilog.parser.walker.*; // Walker and visitor (@VerilogTreeWalker@ and @VerilogNodeVisitor@) 

 public void start(final VerilogNode root) 
 { 
     // Create the AST traverser. 
     VerilogTreeWalker walker = new VerilogTreeWalker(root, new VerilogNodePrinter()); 
     walker.start(); 
 } 
 </code></pre> 

 The most substantial part of backend development concerns creation of the AST nodes’ visitor, a subclass of the abstract class @VerilogNodeVisitor@. The visitor should implement two methods for each of the node types: 

 <pre><code class="java"> 
 // Pre-visitor: it is invoked before the child nodes are visited. 
 public void on<NodeType>Begin (final <NodeType> node); 

 // Post-visitor: it is invoked after the child nodes are visited. 
 public void on<NodeType>End     (final <NodeType> node); 
 </code></pre> 

 Supported node types include (see the package @ru.ispras.verilog.parser.model@): 

 | *Activity* |<. process (@always@ or @initial@) | 
 | *AssignBegin* |<. continuous assignment (@assign@) | 
 | *AssignStatement* |<. assignment statement (@=@, @<=@, @assign@, @deassign@, @force@ or @release@) | 
 | *Assignment* |<. assignment | 
 | *Attribute* |<. attribute | 
 | *BlockGenerate* |<. generate block | 
 | *BlockStatement* |<. block statement (@begin@ or @fork@) | 
 | *CaseGenerate* |<. generate case selection | 
 | *CaseGenerateItem* |<. generate case item | 
 | *CaseStatement* |<. case statement (@case@, @casex@ or @casez@) | 
 | *CaseStatementItem* |<. case statement item | 
 | *Code* |<. source code | 
 | *Declaration* |<. declaration (@input@, @output@, @inout@, @event@, @parameter@, @specparam@, @localparam@, @defparam@, @genvar@ or variable) | 
 | *DelayedStatement* |<. delayed statement | 
 | *DisableStatement* |<. disable statement | 
 | *Generate* |<. generate construct | 
 | *IfGenerate* |<. conditional generate construct | 
 | *IfGenerateBranch* |<. if generate branch (@then@ or @else@) | 
 | *IfStatement* |<. conditional statement | 
 | *IfStatementBranch* |<. if statement branch (@then@ or @else@) | 
 | *Instantiation* |<. instantiation construct | 
 | *LoopGenerate* |<. generate loop | 
 | *LoopStatement* |<. loop statement (@forever@, @repeat@, @while@ or @for@) | 
 | *Module* |<. module declaration | 
 | *NullStatement* |<. null statement | 
 | *PathDeclaration* |<. path declaration | 
 | *Port* |<. port declaration | 
 | *PortConnection* |<. port connection | 
 | *Procedure* |<. procedure declaration (@function@ or @task@) | 
 | *PulseStyle* |<. pulse style specification | 
 | *ShowCancelled* |<. show-cancelled construct | 
 | *Specify* |<. specify construct | 
 | *Table* |<. UDP (user-defined primitive) table | 
 | *TableEntry* |<. UDP table entry | 
 | *TaskStatement* |<. task statement | 
 | *TriggerStatement* |<. trigger statement | 
 | *WaitStatement* |<. wait statement | 

 A visitor example is given below. 

 <pre><code class="java"> 
 package ru.ispras.verilog.parser.sample; 

 import ru.ispras.verilog.parser.model.*; 
 import ru.ispras.verilog.parser.model.basis.*; 
 import ru.ispras.verilog.parser.walker.*; 
 ... 

 /** 
  * This class illustrates development of a Verilog node visitor. 
  */ 
 public final class VerilogNodePrinter extends VerilogNodeVisitor 
 { 
     @Override 
     public void onActivityBegin(final Activity node) 
     { 
         indent(); 

         switch(node.getType()) 
         { 
         case INITIAL: 
             text("initial"); 
             break; 
         case ALWAYS: 
             text("always"); 
             break; 
         } 

         endl(); 
         begin(); 
     } 

     @Override 
     public void onActivityEnd(final Activity node) 
     { 
         end(); 
     } 
     ... 
 } 
 </code></pre> 

 h2. Registering a Backend