more improvements.
[vutg.git] / src / vut_generator.py
bloba9d52cb228a51c0d4a547467e20b8583c9825890
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
37 DEST_GEN_FILES="./gen/"
39 class VUTGenerator:
40 def __init__(self, vmodule, flags):
41 self.flags=flags
42 self.vmodule = vmodule
43 self.vmodule.gen_random_values()
44 self.vmodule.resolve_reference_functions()
45 print "Code generation stars"
47 def get_(self, items=[], string_label=""):
48 for sig in items:
49 if len(sig) > 1:
50 yield " %s [%d:%d] %s;" % (string_label, sig[1][0], sig[1][1], sig[0])
51 else:
52 yield " %s %s;" % (string_label, sig[0])
54 def get_memories(self):
55 items = self.vmodule.in_ports + self.vmodule.out_ports
56 verf_items = self.vmodule.in_ports_behavior + self.vmodule.out_ports_behavior
57 #print items
58 #print verf_items
59 for sig in items:
60 mem_len = len(verf_items[items.index(sig)].get_content()) -1
61 if len(sig) > 1:
62 yield " reg [%d:%d] mem_%s [0:%d];" % (sig[1][0], sig[1][1], sig[0], mem_len)
63 else:
64 yield " reg mem_%s [0:%d];" % (sig[0], mem_len)
66 def gen_module_skeleton(self):
67 inputs = list(self.get_(self.vmodule.in_ports, "input"))
68 inputs.sort()
69 outputs = list(self.get_(self.vmodule.out_ports, "output"))
70 outputs.sort()
71 wires = list(self.get_(self.vmodule.in_ports, "wire"))
72 wires.sort()
73 regs = list(self.get_(self.vmodule.out_ports, "reg"))
74 regs.sort()
75 verilog_code = BASIC_SKELETON % {'module_name':self.vmodule.name,
76 'ports':','.join([x[0] for x in self.vmodule.in_ports] + [x[0] for x in self.vmodule.out_ports]),
77 'inputs':"\n".join(inputs),
78 'outputs':"\n".join(outputs),
79 'wires':"\n".join(wires),
80 'regs':"\n".join(regs),
81 'behavior': ""}
82 file = open(DEST_GEN_FILES + "%s.v" % self.vmodule.name, "w")
83 file.writelines(verilog_code)
84 file.close()
86 def gen_makefile(self):
87 makefile_code = MAKEFILE % {'module_name': self.vmodule.name}
88 file = open(DEST_GEN_FILES + "makefile","w")
89 file.write(makefile_code)
90 file.close()
92 def gen_vut(self):
94 regs = list(self.get_(self.vmodule.in_ports, "reg"))
95 regs.sort()
96 wires = list(self.get_(self.vmodule.out_ports, "wire"))
97 wires.sort()
98 memos = list(self.get_memories())
99 memos.sort()
101 def gen_module_inst():
102 ret=" %(module)s test(\n%(cons)s);"
103 cons = []
104 for p in self.vmodule.in_ports + self.vmodule.out_ports:
105 cons.append(" .%(port)s(%(port)s)" % {'port':p[0]})
106 return ret % {'module':self.vmodule.name,
107 'cons':',\n'.join(cons)}
108 def gen_tmp_mem():
109 ret=[]
111 for p in self.vmodule.out_ports:
112 if len(p) > 1:
113 ret.append(" reg [%d:%d] tmp_%s;" % (p[1][0], p[1][1], p[0]))
114 else:
115 ret.append(" reg tmp_%s;" % p[0])
116 return '\n'.join(ret)
118 def gen_initial_mems():
119 ret = []
120 for p in self.vmodule.in_ports:
121 ret.append(' initial $readmemh("%(port)s.mem",mem_%(port)s);' % {'port':p[0]})
122 for p in self.vmodule.out_ports:
123 ret.append(' initial $readmemh("%(port)s.mem",mem_%(port)s);' % {'port':p[0]})
124 return '\n'.join(ret)
126 def gen_init_regs():
127 ret = []
128 for p in self.vmodule.in_ports:
129 ret.append(" %s = 0;" % p[0])
130 return '\n'.join(ret)
132 def gen_set_regs():
133 ret = []
134 for p in self.vmodule.in_ports:
135 ret.append(8*" " + "%(p)s = mem_%(p)s[k];" % {'p':p[0]})
136 for p in self.vmodule.out_ports:
137 ret.append(8*" " + "tmp_%(p)s = mem_%(p)s[k];" % {'p':p[0]})
138 return '\n'.join(ret)
140 def gen_sens_list():
141 ret = []
142 for p in self.vmodule.out_ports:
143 ret.append(p[0])
144 return ' or '.join(ret)
146 def gen_if_errors():
147 ret = []
148 for p in self.vmodule.out_ports:
149 ret.append(BASIC_IF % {'port': p[0]})
150 return '\n'.join(ret)
152 behavior_code = BASIC_VUT_BEHAVIOR % {'memories':'\n'.join(memos),
153 'tmpmem': gen_tmp_mem(),
154 'module': gen_module_inst(),
155 'initialmems': gen_initial_mems(),
156 'initregs': gen_init_regs(),
157 'memlen': len(self.vmodule.in_ports_behavior[0].content),
158 'delay': 2,
159 'mematt': gen_set_regs(),
160 'outlist':gen_sens_list(),
161 'iferrors': gen_if_errors(),
162 'tofin': len(self.vmodule.in_ports_behavior[0].content) * 10
165 verilog_code = BASIC_SKELETON % {'module_name':"vut_" + self.vmodule.name,
166 'ports': "",
167 'inputs':"",
168 'outputs':"",
169 'wires':"\n".join(wires),
170 'regs':"\n".join(regs),
171 'behavior': behavior_code}
174 file = open(DEST_GEN_FILES + "vut_%s.v" % self.vmodule.name, "w")
175 file.writelines(verilog_code)
176 file.close()
178 for in_p in self.vmodule.in_ports_behavior:
179 f = open(DEST_GEN_FILES + in_p.name + ".mem", "w")
181 f.write("\n".join(in_p.content) + '\n')
182 f.close()
183 # self.gen_random_values(in_p)
185 for out_p in self.vmodule.out_ports_behavior:
186 f = open(DEST_GEN_FILES + out_p.name + ".mem", "w")
187 f.write("\n".join(out_p.content) + '\n')
188 f.close()
190 # def gen_random_values(self, cont):
191 # regexp = re.compile("R\d+")
192 # for val in cont:
193 # if regexp.match(val):
194 # regexp.findall(val)
195 # cont[cont.index(val)] = hex(randrange(0,255))[2:]
196 # print cont
198 def gen(self):
199 if 'skeleton' in self.flags:
200 self.gen_module_skeleton()
201 print "--> skeleton's code generated %s.v" % self.vmodule.name
202 if 'makefile' in self.flags:
203 self.gen_makefile()
204 print "--> makefile generated in %s" % DEST_GEN_FILES
205 self.gen_vut()
206 print "--> unittest's code generated vut_%s.v" % self.vmodule.name
208 if __name__ == '__main__':
209 vm = VerilogModule("Teste_de_geracao")
210 vm.in_ports.append(('a', (3, 0)))
211 vm.in_ports.append(('c',))
212 vm.in_ports.append(('d', (3, 0)))
213 vm.in_ports_behavior.append( MemoryIO('a',['R1','F','R2','9','4','R3','R2','R1','R2','R3','R4']))
214 vm.in_ports_behavior.append( MemoryIO('c',['4','R3','A','R4','R1','R2','R3','R4','R3','R2','R1']))
215 vm.in_ports_behavior.append( MemoryIO('d',['4','F','A','9']))
216 vm.out_ports.append(('e', (3, 0)))
217 vm.out_ports.append(('f', (3, 0)))
218 vm.out_ports.append(('g', (3, 0)))
219 vm.out_ports_behavior.append( MemoryIO('e',['4','F','A','9']))
220 vm.out_ports_behavior.append( MemoryIO('f',['4','F','A','9','c','6']))
221 vm.out_ports_behavior.append( MemoryIO('g',['4','F','A','9']))
222 vm.ran_range['R1'] = (0,24)
223 vm.ran_range['R2'] = (25,49)
224 vm.ran_range['R3'] = (50,74)
225 vm.ran_range['R4'] = (75,100)
226 vm.ref_functions['e'] = "lambda a,c:a+c"
227 vm.out_ports_dep['e'] = ['a','c']
228 test = VUTGenerator(vm)
229 test.gen()