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