Improving text messages.
[vutg.git] / src / vut_generator.py
blobab7ba9920b215cffe124c849661c4099129ae09c
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 """
4 =======================================
5 module_name: vut_generator
6 ---------------------------------------
7 Author: Rodrigo Peixoto
8 Data: 11/02/2008
9 ---------------------------------------
10 Description:
11 - This modules generates the Verilog
12 module skeleton, based in the vut
13 file.
14 =======================================
15 License: GPL
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 =======================================================================
32 """
34 from utils import *
35 import re
36 import os
37 import psyco
38 psyco.full()
39 DEST_GEN_FILES="./gen/"
41 class VUTGenerator:
42 def __init__(self, vmodule, flags):
43 self.flags=flags
44 self.vmodule = vmodule
45 self.vmodule.gen_random_values()
46 self.vmodule.resolve_reference_functions()
47 print "Code generation stars"
48 try:
49 os.mkdir("gen")
50 except OSError:
51 pass
53 def get_(self, items=[], string_label=""):
54 for sig in items:
55 if len(sig) > 1:
56 yield " %s [%d:%d] %s;" % (string_label, sig[1][0], sig[1][1], sig[0])
57 else:
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
63 #print items
64 #print verf_items
65 for sig in items:
66 mem_len = len(verf_items[items.index(sig)].get_content()) -1
67 if len(sig) > 1:
68 yield " reg [%d:%d] mem_%s [0:%d];" % (sig[1][0], sig[1][1], sig[0], mem_len)
69 else:
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"))
74 inputs.sort()
75 outputs = list(self.get_(self.vmodule.out_ports, "output"))
76 outputs.sort()
77 wires = list(self.get_(self.vmodule.in_ports, "wire"))
78 wires.sort()
79 regs = list(self.get_(self.vmodule.out_ports, "reg"))
80 regs.sort()
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),
87 'behavior': ""}
88 file = open(DEST_GEN_FILES + "%s.v" % self.vmodule.name, "w")
89 file.writelines(verilog_code)
90 file.close()
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)
96 file.close()
98 def gen_vut(self):
100 regs = list(self.get_(self.vmodule.in_ports, "reg"))
101 regs.sort()
102 wires = list(self.get_(self.vmodule.out_ports, "wire"))
103 wires.sort()
104 memos = list(self.get_memories())
105 memos.sort()
107 def gen_module_inst():
108 ret=" %(module)s test(\n%(cons)s);"
109 cons = []
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)}
114 def gen_tmp_mem():
115 ret=[]
117 for p in self.vmodule.out_ports:
118 if len(p) > 1:
119 ret.append(" reg [%d:%d] from_mem_%s;" % (p[1][0], p[1][1], p[0]))
120 else:
121 ret.append(" reg from_mem_%s;" % p[0])
122 return '\n'.join(ret)
124 def gen_initial_mems():
125 ret = []
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)
132 def gen_init_regs():
133 ret = []
134 for p in self.vmodule.in_ports:
135 ret.append(" %s = 0;" % p[0])
136 return '\n'.join(ret)
138 def gen_set_regs():
139 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)
146 def gen_sens_list():
147 ret = []
148 for p in self.vmodule.out_ports:
149 ret.append(p[0])
150 return ' or '.join(ret)
152 def gen_if_errors():
153 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),
164 'delay': 2,
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,
172 'ports': "",
173 'inputs':"",
174 'outputs':"",
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)
182 file.close()
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')
188 f.close()
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')
194 f.close()
196 # def gen_random_values(self, cont):
197 # regexp = re.compile("R\d+")
198 # for val in cont:
199 # if regexp.match(val):
200 # regexp.findall(val)
201 # cont[cont.index(val)] = hex(randrange(0,255))[2:]
202 # print cont
204 def gen(self):
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):
212 try:
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()
215 except:
216 import sys
217 print sys.exc_info()
218 self.gen_module_skeleton()
219 print "--> skeleton's code generated %s.v" % self.vmodule.name
220 else:
221 self.gen_module_skeleton()
222 print "--> skeleton's code generated %s.v" % self.vmodule.name
223 if 'makefile' in self.flags:
224 self.gen_makefile()
225 print "--> makefile generated in %s" % DEST_GEN_FILES
226 self.gen_vut()
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)
250 test.gen()