Project

General

Profile

Getting Started » History » Version 11

Alexander Kamkin, 05/06/2014 02:04 PM

1 1 Alexander Kamkin
h1. Getting Started
2
3 4 Alexander Kamkin
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@).
4 3 Alexander Kamkin
5 1 Alexander Kamkin
h2. Developing a Backend
6
7 3 Alexander Kamkin
Technically, a backend is a Java object that implements the @VerilogBackend@ interface (the method @start@). Here is an example:
8 1 Alexander Kamkin
9 3 Alexander Kamkin
<pre><code class="java">
10 5 Alexander Kamkin
package ru.ispras.verilog.parser.sample;
11
12 1 Alexander Kamkin
import ru.ispras.verilog.parser.VerilogBackend;
13 8 Alexander Kamkin
14 9 Alexander Kamkin
import ru.ispras.verilog.parser.model.*;       // AST nodes (Module, Activity, etc.)
15
import ru.ispras.verilog.parser.model.basis.*; // Objects used in AST nodes (Expression, Range, etc.)
16 3 Alexander Kamkin
...
17 1 Alexander Kamkin
18
/**
19 3 Alexander Kamkin
 * This class illustrates development of a Verilog backend.
20 1 Alexander Kamkin
 */
21
public final class VerilogPrinter extends VerilogBackend
22
{
23
    /**
24 3 Alexander Kamkin
     * Processes the abstract syntax tree (AST).
25
     *
26
     * @param root the AST''s root.
27 1 Alexander Kamkin
     */
28
    public void start(final VerilogNode root)
29
    {
30 3 Alexander Kamkin
        ...
31 1 Alexander Kamkin
    }
32 3 Alexander Kamkin
}
33
</code></pre>
34
35 4 Alexander Kamkin
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:
36 3 Alexander Kamkin
37 1 Alexander Kamkin
<pre><code class="java">
38
...
39 9 Alexander Kamkin
import ru.ispras.verilog.parser.walker.*; // Walker and visitor (VerilogTreeWalker and VerilogNodeVisitor)
40 3 Alexander Kamkin
41 1 Alexander Kamkin
public void start(final VerilogNode root)
42 3 Alexander Kamkin
{
43 4 Alexander Kamkin
    // Create the AST traverser.
44 3 Alexander Kamkin
    VerilogTreeWalker walker = new VerilogTreeWalker(root, new VerilogNodePrinter());
45
    walker.start();
46 1 Alexander Kamkin
}
47
</code></pre>
48 4 Alexander Kamkin
49
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:
50
51
<pre><code class="java">
52
// Pre-visitor: it is invoked before the child nodes are visited.
53
public void on<NodeType>Begin (final <NodeType> node);
54
55
// Post-visitor: it is invoked after the child nodes are visited.
56
public void on<NodeType>End   (final <NodeType> node);
57
</code></pre>
58
59 6 Alexander Kamkin
Supported node types include (see the package @ru.ispras.verilog.parser.model@):
60 4 Alexander Kamkin
61 7 Alexander Kamkin
| *Activity* |<. process (@always@ or @initial@) |
62
| *AssignBegin* |<. continuous assignment (@assign@) |
63
| *AssignStatement* |<. assignment statement (@=@, @<=@, @assign@, @deassign@, @force@ or @release@) |
64
| *Assignment* |<. assignment |
65
| *Attribute* |<. attribute |
66
| *BlockGenerate* |<. generate block |
67
| *BlockStatement* |<. block statement (@begin@ or @fork@) |
68
| *CaseGenerate* |<. generate case selection |
69
| *CaseGenerateItem* |<. generate case item |
70
| *CaseStatement* |<. case statement (@case@, @casex@ or @casez@) |
71
| *CaseStatementItem* |<. case statement item |
72
| *Code* |<. source code |
73
| *Declaration* |<. declaration (@input@, @output@, @inout@, @event@, @parameter@, @specparam@, @localparam@, @defparam@, @genvar@ or variable) |
74
| *DelayedStatement* |<. delayed statement |
75
| *DisableStatement* |<. disable statement |
76
| *Generate* |<. generate construct |
77
| *IfGenerate* |<. conditional generate construct |
78
| *IfGenerateBranch* |<. if generate branch (@then@ or @else@) |
79
| *IfStatement* |<. conditional statement |
80
| *IfStatementBranch* |<. if statement branch (@then@ or @else@) |
81
| *Instantiation* |<. instantiation construct |
82
| *LoopGenerate* |<. generate loop |
83
| *LoopStatement* |<. loop statement (@forever@, @repeat@, @while@ or @for@) |
84
| *Module* |<. module declaration |
85
| *NullStatement* |<. null statement |
86
| *PathDeclaration* |<. path declaration |
87
| *Port* |<. port declaration |
88
| *PortConnection* |<. port connection |
89
| *Procedure* |<. procedure declaration (@function@ or @task@) |
90
| *PulseStyle* |<. pulse style specification |
91
| *ShowCancelled* |<. show-cancelled construct |
92
| *Specify* |<. specify construct |
93
| *Table* |<. UDP (user-defined primitive) table |
94
| *TableEntry* |<. UDP table entry |
95
| *TaskStatement* |<. task statement |
96
| *TriggerStatement* |<. trigger statement |
97
| *WaitStatement* |<. wait statement |
98 5 Alexander Kamkin
99
A visitor example is given below.
100
101
<pre><code class="java">
102
package ru.ispras.verilog.parser.sample;
103 1 Alexander Kamkin
104 5 Alexander Kamkin
import ru.ispras.verilog.parser.model.*;
105 8 Alexander Kamkin
import ru.ispras.verilog.parser.model.basis.*;
106 5 Alexander Kamkin
import ru.ispras.verilog.parser.walker.*;
107
...
108
109
/**
110
 * This class illustrates development of a Verilog node visitor.
111
 */
112
public final class VerilogNodePrinter extends VerilogNodeVisitor
113
{
114
    @Override
115
    public void onActivityBegin(final Activity node)
116
    {
117
        indent();
118
119
        switch(node.getType())
120
        {
121
        case INITIAL:
122
            text("initial");
123
            break;
124
        case ALWAYS:
125
            text("always");
126
            break;
127
        }
128
129
        endl();
130
        begin();
131
    }
132
133
    @Override
134
    public void onActivityEnd(final Activity node)
135
    {
136
        end();
137
    }
138
    ...
139
}
140
</code></pre>
141 2 Alexander Kamkin
142
h2. Registering a Backend
143 10 Alexander Kamkin
144 11 Alexander Kamkin
A backend is registered by calling the @add@ method of the @VerilogTranslator@ object. An example is given below:
145 10 Alexander Kamkin
146
<pre><code class="java">
147 1 Alexander Kamkin
/**
148 11 Alexander Kamkin
 * Launches the Verilog translator with the Verilog printer as a backend.
149 10 Alexander Kamkin
 *
150
 * @param args the command line parameters.
151
 */
152
public static void main(String[] args)
153
{
154
    VerilogTranslator translator = new VerilogTranslator();
155
    translator.add(new VerilogPrinter());
156
    translator.start(args);
157
}
158
</code></pre>