2 # -*- coding: utf-8 -*-
4 =======================================
5 module_name: vut_generator
6 ---------------------------------------
7 Author: Rodrigo Peixoto
9 ---------------------------------------
11 - This modules generates the Verilog
12 module skeleton, based in the vut
14 =======================================
16 ======================================================================
18 This program is free software: you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation, either version 3 of the License, or
21 (at your option) any later version.
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 =======================================================================
39 DEST_GEN_FILES
="./gen/"
42 def __init__(self
, vmodule
, flags
):
44 self
.vmodule
= vmodule
45 self
.vmodule
.gen_random_values()
46 self
.vmodule
.resolve_reference_functions()
47 print "Code generation stars"
53 def get_(self
, items
=[], string_label
=""):
56 yield " %s [%d:%d] %s;" % (string_label
, sig
[1][0], sig
[1][1], sig
[0])
58 yield " %s %s;" % (string_label
, sig
[0])
60 def get_memories(self
):
61 items
= self
.vmodule
.in_ports
+ self
.vmodule
.out_ports
62 verf_items
= self
.vmodule
.in_ports_behavior
+ self
.vmodule
.out_ports_behavior
66 mem_len
= len(verf_items
[items
.index(sig
)].get_content()) -1
68 yield " reg [%d:%d] mem_%s [0:%d];" % (sig
[1][0], sig
[1][1], sig
[0], mem_len
)
70 yield " reg mem_%s [0:%d];" % (sig
[0], mem_len
)
72 def gen_module_skeleton(self
):
73 inputs
= list(self
.get_(self
.vmodule
.in_ports
, "input"))
75 outputs
= list(self
.get_(self
.vmodule
.out_ports
, "output"))
77 wires
= list(self
.get_(self
.vmodule
.in_ports
, "wire"))
79 regs
= list(self
.get_(self
.vmodule
.out_ports
, "reg"))
81 verilog_code
= BASIC_SKELETON
% {'module_name':self
.vmodule
.name
,
82 'ports':','.join([x
[0] for x
in self
.vmodule
.in_ports
] + [x
[0] for x
in self
.vmodule
.out_ports
]),
83 'inputs':"\n".join(inputs
),
84 'outputs':"\n".join(outputs
),
85 'wires':"\n".join(wires
),
86 'regs':"\n".join(regs
),
88 file = open(DEST_GEN_FILES
+ "%s.v" % self
.vmodule
.name
, "w")
89 file.writelines(verilog_code
)
92 def gen_makefile(self
):
93 makefile_code
= MAKEFILE
% {'module_name': self
.vmodule
.name
}
94 file = open(DEST_GEN_FILES
+ "makefile","w")
95 file.write(makefile_code
)
100 regs
= list(self
.get_(self
.vmodule
.in_ports
, "reg"))
102 wires
= list(self
.get_(self
.vmodule
.out_ports
, "wire"))
104 memos
= list(self
.get_memories())
107 def gen_module_inst():
108 ret
=" %(module)s test(\n%(cons)s);"
110 for p
in self
.vmodule
.in_ports
+ self
.vmodule
.out_ports
:
111 cons
.append(" .%(port)s(%(port)s)" % {'port':p
[0]})
112 return ret
% {'module':self
.vmodule
.name
,
113 'cons':',\n'.join(cons
)}
117 for p
in self
.vmodule
.out_ports
:
119 ret
.append(" reg [%d:%d] from_mem_%s;" % (p
[1][0], p
[1][1], p
[0]))
121 ret
.append(" reg from_mem_%s;" % p
[0])
122 return '\n'.join(ret
)
124 def gen_initial_mems():
126 for p
in self
.vmodule
.in_ports
:
127 ret
.append(' initial $readmemh("%(port)s.mem",mem_%(port)s);' % {'port':p
[0]})
128 for p
in self
.vmodule
.out_ports
:
129 ret
.append(' initial $readmemh("%(port)s.mem",mem_%(port)s);' % {'port':p
[0]})
130 return '\n'.join(ret
)
134 for p
in self
.vmodule
.in_ports
:
135 ret
.append(" %s = 0;" % p
[0])
136 return '\n'.join(ret
)
140 for p
in self
.vmodule
.in_ports
:
141 ret
.append(8*" " + "%(p)s = mem_%(p)s[k];" % {'p':p
[0]})
142 for p
in self
.vmodule
.out_ports
:
143 ret
.append(8*" " + "from_mem_%(p)s = mem_%(p)s[k];" % {'p':p
[0]})
144 return '\n'.join(ret
)
148 for p
in self
.vmodule
.out_ports
:
150 return ' or '.join(ret
)
154 for p
in self
.vmodule
.out_ports
:
155 ret
.append(BASIC_IF
% {'port': p
[0]})
156 return '\n'.join(ret
)
158 behavior_code
= BASIC_VUT_BEHAVIOR
% {'memories':'\n'.join(memos
),
159 'tmpmem': gen_tmp_mem(),
160 'module': gen_module_inst(),
161 'initialmems': gen_initial_mems(),
162 'initregs': gen_init_regs(),
163 'memlen': len(self
.vmodule
.in_ports_behavior
[0].content
),
165 'mematt': gen_set_regs(),
166 'outlist':gen_sens_list(),
167 'iferrors': gen_if_errors(),
168 'tofin': len(self
.vmodule
.in_ports_behavior
[0].content
) * 10
171 verilog_code
= BASIC_SKELETON
% {'module_name':"vut_" + self
.vmodule
.name
,
175 'wires':"\n".join(wires
),
176 'regs':"\n".join(regs
),
177 'behavior': behavior_code
}
180 file = open(DEST_GEN_FILES
+ "vut_%s.v" % self
.vmodule
.name
, "w")
181 file.writelines(verilog_code
)
184 for in_p
in self
.vmodule
.in_ports_behavior
:
185 f
= open(DEST_GEN_FILES
+ in_p
.name
+ ".mem", "w")
187 f
.write("\n".join(in_p
.content
) + '\n')
189 # self.gen_random_values(in_p)
191 for out_p
in self
.vmodule
.out_ports_behavior
:
192 f
= open(DEST_GEN_FILES
+ out_p
.name
+ ".mem", "w")
193 f
.write("\n".join(out_p
.content
) + '\n')
196 # def gen_random_values(self, cont):
197 # regexp = re.compile("R\d+")
199 # if regexp.match(val):
200 # regexp.findall(val)
201 # cont[cont.index(val)] = hex(randrange(0,255))[2:]
205 if 'skeleton' in self
.flags
:
206 if os
.path
.exists("gen/%s.v" % self
.vmodule
.name
):
207 verif
= re
.compile(r
"[ynYN]$")
208 res
= raw_input("|VUT QUESTION| > Already exists a %s.v in gen folder, do you want to override it?[y/n]" % self
.vmodule
.name
)
209 while not verif
.match(res
):
210 res
= raw_input("|VUT QUESTION| > Already exists a %s.v in gen folder, do you want to override it?[y/n]" % self
.vmodule
.name
)
211 if re
.match(r
"[yY]$",res
):
213 os
.system("cp gen/%s.v ./%s.v~" % (self
.vmodule
.name
,self
.vmodule
.name
))
214 print "|VUT INFO| > A backup file will be generate in %s" % os
.getcwd()
218 self
.gen_module_skeleton()
219 print "--> skeleton's code generated %s.v" % self
.vmodule
.name
221 self
.gen_module_skeleton()
222 print "--> skeleton's code generated %s.v" % self
.vmodule
.name
223 if 'makefile' in self
.flags
:
225 print "--> makefile generated in %s" % DEST_GEN_FILES
227 print "--> unittest's code generated vut_%s.v" % self
.vmodule
.name
229 if __name__
== '__main__':
230 vm
= VerilogModule("Teste_de_geracao")
231 vm
.in_ports
.append(('a', (3, 0)))
232 vm
.in_ports
.append(('c',))
233 vm
.in_ports
.append(('d', (3, 0)))
234 vm
.in_ports_behavior
.append( MemoryIO('a',['R1','F','R2','9','4','R3','R2','R1','R2','R3','R4']))
235 vm
.in_ports_behavior
.append( MemoryIO('c',['4','R3','A','R4','R1','R2','R3','R4','R3','R2','R1']))
236 vm
.in_ports_behavior
.append( MemoryIO('d',['4','F','A','9']))
237 vm
.out_ports
.append(('e', (3, 0)))
238 vm
.out_ports
.append(('f', (3, 0)))
239 vm
.out_ports
.append(('g', (3, 0)))
240 vm
.out_ports_behavior
.append( MemoryIO('e',['4','F','A','9']))
241 vm
.out_ports_behavior
.append( MemoryIO('f',['4','F','A','9','c','6']))
242 vm
.out_ports_behavior
.append( MemoryIO('g',['4','F','A','9']))
243 vm
.ran_range
['R1'] = (0,24)
244 vm
.ran_range
['R2'] = (25,49)
245 vm
.ran_range
['R3'] = (50,74)
246 vm
.ran_range
['R4'] = (75,100)
247 vm
.ref_functions
['e'] = "lambda a,c:a+c"
248 vm
.out_ports_dep
['e'] = ['a','c']
249 test
= VUTGenerator(vm
)