Skip to content

Commit 80deaed

Browse files
committed
Escaped identifier is supported. Instantiation of basic primitives without instance name is allowed.
1 parent 75c533e commit 80deaed

File tree

7 files changed

+101
-38
lines changed

7 files changed

+101
-38
lines changed

pyverilog/ast_code_generator/codegen.py

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ def generic_visit(self, node):
3636
def getfilename(node):
3737
return node.__class__.__name__.lower() + '.txt'
3838

39+
def escape(s):
40+
if s.startswith('\\'):
41+
return s + ' '
42+
return s
43+
3944
class ASTCodeGenerator(ConvertVisitor):
4045
def __init__(self):
4146
self.env = Environment(loader=FileSystemLoader(DEFAULT_TEMPLATE_DIR))
@@ -63,7 +68,7 @@ def visit_ModuleDef(self, node):
6368
template = self.env.get_template(filename)
6469
paramlist = self.visit(node.paramlist)
6570
template_dict = {
66-
'modulename' : node.name,
71+
'modulename' : escape(node.name),
6772
'paramlist' : '' if len(node.paramlist.params) == 0 else paramlist,
6873
'portlist' : self.visit(node.portlist),
6974
'items' : [ self.visit(item) for item in node.items ],
@@ -97,7 +102,7 @@ def visit_Port(self, node):
97102
filename = getfilename(node)
98103
template = self.env.get_template(filename)
99104
template_dict = {
100-
'name' : node.name,
105+
'name' : escape(node.name),
101106
}
102107
rslt = template.render(template_dict)
103108
return rslt
@@ -126,7 +131,7 @@ def visit_Identifier(self, node):
126131
filename = getfilename(node)
127132
template = self.env.get_template(filename)
128133
template_dict = {
129-
'name' : node.name,
134+
'name' : escape(node.name),
130135
'scope' : '' if node.scope is None else self.visit(node.scope),
131136
}
132137
rslt = template.render(template_dict)
@@ -181,7 +186,7 @@ def visit_Variable(self, node):
181186
filename = getfilename(node)
182187
template = self.env.get_template(filename)
183188
template_dict = {
184-
'name' : node.name,
189+
'name' : escape(node.name),
185190
'width' : '' if node.width is None else self.visit(node.width),
186191
'signed' : node.signed,
187192
}
@@ -192,7 +197,7 @@ def visit_Input(self, node):
192197
filename = getfilename(node)
193198
template = self.env.get_template(filename)
194199
template_dict = {
195-
'name' : node.name,
200+
'name' : escape(node.name),
196201
'width' : '' if node.width is None else self.visit(node.width),
197202
'signed' : node.signed,
198203
}
@@ -203,7 +208,7 @@ def visit_Output(self, node):
203208
filename = getfilename(node)
204209
template = self.env.get_template(filename)
205210
template_dict = {
206-
'name' : node.name,
211+
'name' : escape(node.name),
207212
'width' : '' if node.width is None else self.visit(node.width),
208213
'signed' : node.signed,
209214
}
@@ -214,7 +219,7 @@ def visit_Inout(self, node):
214219
filename = getfilename(node)
215220
template = self.env.get_template(filename)
216221
template_dict = {
217-
'name' : node.name,
222+
'name' : escape(node.name),
218223
'width' : '' if node.width is None else self.visit(node.width),
219224
'signed' : node.signed,
220225
}
@@ -225,7 +230,7 @@ def visit_Tri(self, node):
225230
filename = getfilename(node)
226231
template = self.env.get_template(filename)
227232
template_dict = {
228-
'name' : node.name,
233+
'name' : escape(node.name),
229234
'width' : '' if node.width is None else self.visit(node.width),
230235
'signed' : node.signed,
231236
}
@@ -236,7 +241,7 @@ def visit_Wire(self, node):
236241
filename = getfilename(node)
237242
template = self.env.get_template(filename)
238243
template_dict = {
239-
'name' : node.name,
244+
'name' : escape(node.name),
240245
'width' : '' if node.width is None else self.visit(node.width),
241246
'signed' : node.signed,
242247
}
@@ -247,7 +252,7 @@ def visit_Reg(self, node):
247252
filename = getfilename(node)
248253
template = self.env.get_template(filename)
249254
template_dict = {
250-
'name' : node.name,
255+
'name' : escape(node.name),
251256
'width' : '' if node.width is None else self.visit(node.width),
252257
'signed' : node.signed,
253258
}
@@ -258,7 +263,7 @@ def visit_WireArray(self, node):
258263
filename = getfilename(node)
259264
template = self.env.get_template(filename)
260265
template_dict = {
261-
'name' : node.name,
266+
'name' : escape(node.name),
262267
'width' : '' if node.width is None else self.visit(node.width),
263268
'length' : self.visit(node.length),
264269
'signed' : node.signed,
@@ -270,7 +275,7 @@ def visit_RegArray(self, node):
270275
filename = getfilename(node)
271276
template = self.env.get_template(filename)
272277
template_dict = {
273-
'name' : node.name,
278+
'name' : escape(node.name),
274279
'width' : '' if node.width is None else self.visit(node.width),
275280
'length' : self.visit(node.length),
276281
'signed' : node.signed,
@@ -282,7 +287,7 @@ def visit_Integer(self, node):
282287
filename = getfilename(node)
283288
template = self.env.get_template(filename)
284289
template_dict = {
285-
'name' : node.name,
290+
'name' : escape(node.name),
286291
'signed' : node.signed,
287292
}
288293
rslt = template.render(template_dict)
@@ -292,7 +297,7 @@ def visit_Real(self, node):
292297
filename = getfilename(node)
293298
template = self.env.get_template(filename)
294299
template_dict = {
295-
'name' : node.name,
300+
'name' : escape(node.name),
296301
}
297302
rslt = template.render(template_dict)
298303
return rslt
@@ -301,7 +306,7 @@ def visit_Genvar(self, node):
301306
filename = getfilename(node)
302307
template = self.env.get_template(filename)
303308
template_dict = {
304-
'name' : node.name,
309+
'name' : escape(node.name),
305310
}
306311
rslt = template.render(template_dict)
307312
return rslt
@@ -312,7 +317,7 @@ def visit_Ioport(self, node):
312317
template_dict = {
313318
'first' : node.first.__class__.__name__.lower(),
314319
'second' : '' if node.second is None else node.second.__class__.__name__.lower(),
315-
'name' : node.first.name,
320+
'name' : escape(node.first.name),
316321
'width' : '' if node.first.width is None else self.visit(node.first.width),
317322
}
318323
rslt = template.render(template_dict)
@@ -323,7 +328,7 @@ def visit_Parameter(self, node):
323328
template = self.env.get_template(filename)
324329
value = self.visit(node.value)
325330
template_dict = {
326-
'name' : node.name,
331+
'name' : escape(node.name),
327332
'width' : '' if node.width is None or (value.startswith('"') and value.endswith('"')) else self.visit(node.width),
328333
'value' : value,
329334
'signed' : node.signed,
@@ -336,7 +341,7 @@ def visit_Localparam(self, node):
336341
template = self.env.get_template(filename)
337342
value = self.visit(node.value)
338343
template_dict = {
339-
'name' : node.name,
344+
'name' : escape(node.name),
340345
'width' : '' if node.width is None or (value.startswith('"') and value.endswith('"')) else self.visit(node.width),
341346
'value' : value,
342347
'signed' : node.signed,
@@ -694,7 +699,7 @@ def visit_Block(self, node):
694699
filename = getfilename(node)
695700
template = self.env.get_template(filename)
696701
template_dict = {
697-
'scope' : '' if node.scope is None else node.scope,
702+
'scope' : '' if node.scope is None else escape(node.scope),
698703
'statements' : [ self.visit(statement) for statement in node.statements ],
699704
}
700705
rslt = template.render(template_dict)
@@ -752,7 +757,7 @@ def visit_InstanceList(self, node):
752757
parameterlist = [ self.visit(param) for param in node.parameterlist ]
753758
instances = [ self.visit(instance) for instance in node.instances ]
754759
template_dict = {
755-
'module' : node.module,
760+
'module' : escape(node.module),
756761
'parameterlist' : parameterlist,
757762
'len_parameterlist' : len(parameterlist),
758763
'instances' : instances,
@@ -767,7 +772,7 @@ def visit_Instance(self, node):
767772
array = '' if node.array is None else self.visit(node.array)
768773
portlist = [ self.visit(port) for port in node.portlist ]
769774
template_dict = {
770-
'name' : node.name,
775+
'name' : escape(node.name),
771776
'array' : array,
772777
'portlist' : portlist,
773778
'len_portlist' : len(portlist),
@@ -779,7 +784,7 @@ def visit_ParamArg(self, node):
779784
filename = getfilename(node)
780785
template = self.env.get_template(filename)
781786
template_dict = {
782-
'paramname' : '' if node.paramname is None else node.paramname,
787+
'paramname' : '' if node.paramname is None else escape(node.paramname),
783788
'argname' : '' if node.argname is None else self.visit(node.argname),
784789
}
785790
rslt = template.render(template_dict)
@@ -789,7 +794,7 @@ def visit_PortArg(self, node):
789794
filename = getfilename(node)
790795
template = self.env.get_template(filename)
791796
template_dict = {
792-
'portname' : '' if node.portname is None else node.portname,
797+
'portname' : '' if node.portname is None else escape(node.portname),
793798
'argname' : '' if node.argname is None else self.visit(node.argname),
794799
}
795800
rslt = template.render(template_dict)
@@ -800,7 +805,7 @@ def visit_Function(self, node):
800805
template = self.env.get_template(filename)
801806
statement = [ self.visit(s) for s in node.statement ]
802807
template_dict = {
803-
'name' : node.name,
808+
'name' : escape(node.name),
804809
'retwidth' : self.visit(node.retwidth),
805810
'statement' : statement,
806811
}
@@ -823,7 +828,7 @@ def visit_Task(self, node):
823828
filename = getfilename(node)
824829
template = self.env.get_template(filename)
825830
template_dict = {
826-
'name' : node.name,
831+
'name' : escape(node.name),
827832
'statement' : self.visit(node.statement),
828833
}
829834
rslt = template.render(template_dict)
@@ -855,7 +860,7 @@ def visit_SystemCall(self, node):
855860
template = self.env.get_template(filename)
856861
args = [ self.visit(arg) for arg in node.args ]
857862
template_dict = {
858-
'syscall' : node.syscall,
863+
'syscall' : escape(node.syscall),
859864
'args' : args,
860865
'len_args' : len(args),
861866
}
@@ -866,7 +871,7 @@ def visit_IdentifierScopeLabel(self, node):
866871
filename = getfilename(node)
867872
template = self.env.get_template(filename)
868873
template_dict = {
869-
'name' : node.name,
874+
'name' : escape(node.name),
870875
'loop' : '' if node.loop is None else self.visit(node.loop),
871876
}
872877
rslt = template.render(template_dict)
@@ -895,7 +900,7 @@ def visit_PragmaEntry(self, node):
895900
filename = getfilename(node)
896901
template = self.env.get_template(filename)
897902
template_dict = {
898-
'name' : node.name,
903+
'name' : escape(node.name),
899904
'value' : '' if node.value is None else self.visit(node.value),
900905
}
901906
rslt = template.render(template_dict)
@@ -905,7 +910,7 @@ def visit_Disable(self, node):
905910
filename = getfilename(node)
906911
template = self.env.get_template(filename)
907912
template_dict = {
908-
'name' : node.dest,
913+
'name' : escape(node.dest),
909914
}
910915
rslt = template.render(template_dict)
911916
return rslt
@@ -914,7 +919,7 @@ def visit_ParallelBlock(self, node):
914919
filename = getfilename(node)
915920
template = self.env.get_template(filename)
916921
template_dict = {
917-
'scope' : '' if node.scope is None else node.scope,
922+
'scope' : '' if node.scope is None else escape(node.scope),
918923
'statements' : [ self.visit(statement) for statement in node.statements ],
919924
}
920925
rslt = template.render(template_dict)

pyverilog/dataflow/bindvisitor.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ def visit_Instance(self, node):
145145
return self._visit_Instance_body(node, nodename)
146146

147147
def _visit_Instance_array(self, node):
148+
if node.name == '':
149+
raise verror.FormatError("Module %s requires an instance name" % node.module)
150+
148151
current = self.frames.getCurrent()
149152
msb = self.optimize(self.getTree(node.array.msb, current)).value
150153
lsb = self.optimize(self.getTree(node.array.lsb, current)).value
@@ -157,6 +160,9 @@ def _visit_Instance_array(self, node):
157160
def _visit_Instance_body(self, node, nodename, arrayindex=None):
158161
if node.module in primitives: return self._visit_Instance_primitive(node, arrayindex)
159162

163+
if nodename == '':
164+
raise verror.FormatError("Module %s requires an instance name" % node.module)
165+
160166
current = self.stackInstanceFrame(nodename, node.module)
161167

162168
scope = self.frames.getCurrent()

pyverilog/dataflow/signalvisitor.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ def visit_Instance(self, node):
126126
return self._visit_Instance_body(node, nodename)
127127

128128
def _visit_Instance_array(self, node):
129+
if node.name == '':
130+
raise verror.FormatError("Module %s requires an instance name" % node.module)
131+
129132
current = self.frames.getCurrent()
130133
msb = self.optimize(self.getTree(node.array.msb, current)).value
131134
lsb = self.optimize(self.getTree(node.array.lsb, current)).value
@@ -137,6 +140,9 @@ def _visit_Instance_array(self, node):
137140
def _visit_Instance_body(self, node, nodename):
138141
if node.module in primitives: return self._visit_Instance_primitive(node)
139142

143+
if nodename == '':
144+
raise verror.FormatError("Module %s requires an instance name" % node.module)
145+
140146
current = self.stackInstanceFrame(nodename, node.module)
141147

142148
self.setInstanceSimpleConstantTerms()

pyverilog/testcode/escape.v

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module \1234
2+
(
3+
\CLK~ , // "\CLK~"
4+
LE$D, // LE$D
5+
\1234RST*%& // "\1234RST*%&"
6+
);
7+
8+
input \CLK~ , \1234RST*%& ;
9+
output LE$D;
10+
11+
genvar i, j;
12+
generate for(i=0; i<4; i=i+1) begin: \1stLoop
13+
for(j=0; j<4; j=j+1) begin: \2ndLoop
14+
wire [7:0] tmp;
15+
assign tmp = i * j;
16+
end
17+
end endgenerate
18+
19+
wire [7:0] rslt;
20+
assign rslt = \1stLoop [0].\2ndLoop [1].tmp;
21+
22+
endmodule

pyverilog/testcode/instance_array.v

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
module TOP
22
(
33
input [3:0] VAL,
4-
output [3:0] LED0,
5-
output [3:0] LED1,
6-
output [3:0] LED2,
7-
output [3:0] LED3,
8-
input [3:0] in0, in1, in2
4+
input [3:0] in0, in1, in2,
5+
input in3, in4, in5,
6+
output [3:0] LED0, LED1, LED2, LED3,
7+
output LED4, LED5
98
);
109

1110
SUB
@@ -21,7 +20,7 @@ module TOP
2120
inst_sub5[3:0] (VAL, LED2);
2221

2322
and U0[3:0] (LED3, in0, in1, in2);
24-
23+
and (LED4, in3, in4, in5), (LED5, in3, in4, in5);
2524
endmodule
2625

2726
module SUB #

pyverilog/vparser/lexer.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,7 @@ def t_COMMENTOUT(self, t):
191191
string_char = r"""([^"\\\n]|"""+escape_sequence+')'
192192
string_literal = '"'+string_char+'*"'
193193

194-
#identifier = r"""[a-zA-Z_][a-zA-Z_0-9$]*"""
195-
identifier = r"""([a-zA-Z_]|\\.)([a-zA-Z_0-9$]|\\.)*"""
194+
identifier = r"""(([a-zA-Z_])([a-zA-Z_0-9$])*)|((\\\S)(\S)*)"""
196195

197196
@TOKEN(string_literal)
198197
def t_STRING_LITERAL(self, t):

0 commit comments

Comments
 (0)