Project

General

Profile

Actions

Getting Started » History » Revision 6

« Previous | Revision 6/11 (diff) | Next »
Alexander Kamkin, 05/06/2014 08:43 AM


Getting Started

This is a step-by-step instruction for getting started with developing a 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).

Developing a Backend

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

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)
    {
        ...
    }
}

To ease development of a backend, one can use VerilogTreeWalker, a 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:

...
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();
}

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-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);

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

  • Activity
  • AssignBegin
  • AssignStatement
  • Assignment
  • Attribute
  • BlockGenerate
  • BlockStatement
  • CaseGenerate
  • CaseGenerateItem
  • CaseStatement
  • CaseStatementItem
  • Code
  • Declaration
  • DelayedStatement
  • DisableStatement
  • Generate
  • IfGenerate
  • IfGenerateBranch
  • IfStatement
  • IfStatementBranch
  • Instantiation
  • LoopGenerate
  • LoopStatement
  • Module
  • NullStatement
  • PathDeclaration
  • Port
  • PortConnection
  • Procedure
  • PulseStyle
  • ShowCancelled
  • Specify
  • Table
  • TableEntry
  • TaskStatement
  • TriggerStatement
  • WaitStatement

A visitor example is given below.

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();
    }
    ...
}

Registering a Backend

Updated by Alexander Kamkin over 10 years ago · 11 revisions