Project

General

Profile

Getting Started » History » Revision 7

Revision 6 (Alexander Kamkin, 05/06/2014 08:43 AM) → Revision 7/11 (Alexander Kamkin, 05/06/2014 09:04 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.*; 
 ... 

 /** 
  * 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.*; 

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

 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.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