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