1
2
3
4
5
6
7
8
9
10
11
12
13 use strict;
14 use warnings;
15 use diagnostics;
16 use 5.006;
17 use FileHandle;
18 use List::MoreUtils qw(firstidx);
19 use IPC::System::Simple qw(system);
20 local $| = 1;
21
22
23
24 sub partial_products;
25 sub wallace_tree;
26 sub kogge_stone;
27 sub testbench;
28 sub generate_and_testbench;
29 sub generate_and_test;
30
31
32 &generate_and_test();
33 exit(0);
34
35
36 sub generate_and_testbench
37 {
38 my ($mdl,$mrl,$us,$dr)=(@_);
39 my $pp=&partial_products($mdl,$mrl,$us);
40 my @pp=@$pp;
41 my $pph=&wallace_tree($mdl,$mrl,$us,\@pp);
42 my %pp=%$pph;
43 my $plm1=$mdl+$mrl-1;
44 &kogge_stone($plm1,$us,\%pp);;
45 &testbench($mdl,$mrl,$us,$dr);
46 return;
47 }
48
49
50 sub partial_products
51 {
52 my ($multiplicand_length,$multiplier_length,$us)=(@_);
53 my $ul =$multiplicand_length - 1;
54 my $zl =$multiplier_length - 1;
55 my $ul2 ="a" . "$ul";
56 my $zl2 ="b" . "$zl";
57 my @rmultiplicand;
58 my @pp;
59 my $i; my $k; my $fh;
60 for ($i=0; $i < $multiplicand_length; $i++)
61 { $rmultiplicand[$i]= 'a'.$i; }
62 my @multiplicand=reverse(@rmultiplicand);
63 my $multiplicand = @multiplicand;
64 my @rmultiplier;
65 for ($i=0; $i < $multiplier_length; $i++)
66 { $rmultiplier[$i]= 'b'.$i; }
67 my @multiplier=reverse(@rmultiplier);
68 my $multiplier = @multiplier;
69 my $product = $multiplicand + $multiplier;
70 my $pl =$product - 1;
71 for my $multiplier (@multiplier)
72 { for my $multiplicand (@multiplicand)
73 {push @pp, $multiplier.$multiplicand;}
74 }
75 if ($us eq "u")
76 {open $fh, ">", "wallace.vl";
77 print $fh ("module wallace(a, b, product);\n");
78 print $fh (" // Unsigned nonrecoded Wallace multiplier.\n");}
79 else {open $fh, ">", "signed_wallace.vl";
80 print $fh ("module s_wallace(a, b, product);\n");
81 print $fh (" // Signed nonrecoded Wallace multiplier.\n");}
82 print $fh (" // John Bryan, v.02 2017.\n");
83 print $fh (" input [$ul:0] a;\n input [$zl:0] b;\n");
84 print $fh (" output [$pl:0] product;\n");
85 if ($us eq "s")
86 { print $fh (" assign pho1 = 1'b1;\n");
87 print $fh (" assign pho2 = 1'b1;\n");
88 if ($multiplicand_length != $multiplier_length)
89 {print $fh (" assign pho3 = 1'b1;\n");}
90 }
91 my $icount=$zl;
92 my $jcount=$ul;
93 loop_g:
94 for($k = 0; $k < scalar(@pp); $k++)
95 {
96 if (($us eq "s") && ((($icount == $zl)&&($jcount != $ul)) ||
97 (($icount != $zl)&&($jcount == $ul))))
98 {print $fh (" assign ", $pp[$k], " = ","~(b[",$icount,"]", " & ",
99 "a[",$jcount,"]);\n");}
100 else
101 {print $fh (" assign ", $pp[$k], " = ","b[",$icount,"]", " & ",
102 "a[",$jcount,"];\n");}
103 if ($jcount==0)
104 { $icount--;
105 $jcount=$ul; }
106 else
107 { $jcount--; }
108 }
109 close $fh;
110 return (\@pp);
111 }
112
113
114 sub wallace_tree
115 {
116 my ($multiplicand_length,$multiplier_length,$us,$pp)=(@_);
117 my @pp=@$pp;
118 my $i;
119 my $j=0;
120 my $k;
121 my(@other_array)=();
122 my %pp;
123 my %pp_copy;
124 my $key;
125 my $fh;
126 my $value;
127 my $final_flag;
128 my $flag;
129 my $tag;
130 my $string="";
131 my $c_string="";
132 my $cutoff_count;
133 my @sum_array=();
134 my @carry_array=();
135 my @sorted_pp_keys = ();
136 my @sca=();
137 my @carries=();
138 my %counts;
139 my $sca_count;
140 my $sum_array_index=0;
141 my $carry_array_index=0;
142 my $array_index=0;
143 my $carries_index=0;
144 my @array = ("aaaa" .. "zzzz");
145 @pp{@pp} = (1) x @pp;
146 my @two_nums;
147 while ( ($key, $value) = each(%pp) )
148 {
149 @two_nums=$key =~ /(\d+)/g;
150 $pp{$key}=$two_nums[0]+$two_nums[1];
151 }
152 my $pl=$multiplicand_length+$multiplier_length;
153 if ($us eq "s")
154 {
155 $pp{'pho1'}=$pl-1;
156 my $pho2w;
157 my $pho3w;
158 if ($multiplier_length==$multiplicand_length)
159 {$pp{'pho2'}=$multiplier_length;}
160 else
161 {$pho2w=$multiplier_length-1;
162 $pho3w=$multiplicand_length-1;
163 $pp{'pho2'}=$pho2w;
164 $pp{'pho3'}=$pho3w;}
165 }
166 @other_array=values %pp;
167 $counts{$_} ++ for @other_array;
168 $j=scalar(keys %counts)-1;
169 %pp_copy=%pp;
170 $sca_count=0;
171 $flag=1;
172 $tag=0;
173 loop_e:
174 while (($j>-1)&&($flag==1))
175 {
176 loop_d:
177 for ($i=0;$i<int($counts{$j}/3);$i++)
178 {
179 $cutoff_count=0;
180 $string=$array[$array_index];
181 $array_index++;
182 $c_string=$array[$array_index];
183 $array_index++;
184 loop_c:
185 while ( ($key, $value) = each(%pp_copy) )
186 {
187 conditional_b:
188 if (($value==$j) && ($cutoff_count < 3))
189 {
190 $cutoff_count++;
191 $pp{$string} = $pp{$key};
192 $pp{$c_string} = $pp{$key};
193 $sca[$sca_count] = $key;
194 $sca_count++;
195 delete($pp{$key});
196 delete($pp_copy{$key});
197 my $n = keys %pp;
198 conditional_a:
199 if ($cutoff_count==3)
200 {
201 $pp{$c_string} = int($pp{$c_string})+1;
202 $sum_array[$sum_array_index]= " assign $string" . ' = ' . "$sca[0]" . ' ^ ' .
203 "$sca[1]" . ' ^ ' . "$sca[2]" . ';';
204 $carry_array[$carry_array_index]= " assign $c_string" . ' = (' . "$sca[0]" .' & '.
205 "$sca[1]" .') | ('. "$sca[2]" .' & (' .
206 "$sca[0]" .' ^ '. "$sca[1]" .'));';
207 $sum_array_index++;
208 $carry_array_index++;
209 $sca_count=0;
210 }
211 }
212 }
213 $tag=1;
214 }
215 %counts = grep defined, %counts;
216 $counts{$j}=$counts{$j}-(3*($i));
217 loop_h:
218
219 for ($i=0;$i<int($counts{$j}/2);$i++)
220 {
221 $counts{$j}=$counts{$j}-2;
222 $cutoff_count=0;
223 $string=$array[$array_index];
224 $array_index++;
225 $c_string=$array[$array_index];
226 $array_index++;
227 loop_i:
228 while ( ($key, $value) = each(%pp_copy) )
229 {
230 if (($value==$j) && ($cutoff_count < 2))
231 {
232 $cutoff_count++;
233 $pp{$string} = $pp{$key};
234 $pp{$c_string} = $pp{$key};
235 $sca[$sca_count] = $key;
236 $sca_count++;
237 delete($pp{$key});
238 delete($pp_copy{$key});
239 if ($cutoff_count ==2 )
240 {
241 $pp{$c_string} = $pp{$c_string}+1;
242 $sum_array[$sum_array_index]= " assign $string" . ' = ' . "$sca[0]" .
243 ' ^ ' . "$sca[1]" . ';';
244 $carry_array[$carry_array_index]= " assign $c_string" . ' = ' . "$sca[0]" .
245 ' & '. "$sca[1]" .';';
246 $sum_array_index++;
247 $carry_array_index++;
248 $sca_count=0;
249 }
250 }
251 }
252 $tag=1;
253 }
254 $j=$j-1;
255 conditional_c:
256 if (($tag==1) && ($j==-1))
257 {
258 @other_array=values %pp;
259 $_ = 0 for %counts;
260 $counts{$_} ++ for @other_array;
261 $j=scalar(keys %counts)-1;
262 %pp_copy=%pp;
263 $flag=0;
264 for my $i ( 0 .. (keys %counts) )
265 {
266 if (defined $counts{$i})
267 { if ($counts{$i}>2)
268 { $flag=1; }
269 }
270 }
271 }
272 }
273 if ($us eq "u")
274 {open $fh, ">>", "wallace.vl";}
275 else
276 {open $fh, ">>", "signed_wallace.vl";}
277 for ($k = 0; $k < $sum_array_index; $k++)
278 { print $fh "$sum_array[$k]\n";
279 print $fh "$carry_array[$k]\n";
280 }
281 close $fh;
282 return (\%pp);
283 }
284
285
286 sub kogge_stone
287 {
288 my ($pl,$us,$pp)=(@_);
289 my %pp=%$pp;
290 my %counts;
291 my @other_array;
292 my @sorted_counts;
293 @other_array=values %pp;
294 $counts{$_}=0 for @other_array;
295 $counts{$_}++ for @other_array;
296 $sorted_counts[$_]=$counts{$_} for sort {$a <=> $b} keys %counts;
297 my @sorted_pp_keys = sort {$pp{$a} <=> $pp{$b}} keys %pp;
298 my $first_index= firstidx { $_ eq '2' } @sorted_counts;
299 my $adder_length=$pl+1-$first_index;
300 my @p0= ("p000" .. "p200");
301 my @p1= ("pa000" .. "pa200");
302 my @p2= ("pb000" .. "pb200");
303 my @p3= ("pc000" .. "pc200");
304 my @p4= ("pd000" .. "pd200");
305 my @p5= ("pe000" .. "pe200");
306 my @p6= ("pf000" .. "pf200");
307 my @p7= ("pg000" .. "pg200");
308 my @g0= ("g000" .. "g200");
309 my @g1= ("ga000" .. "ga200");
310 my @g2= ("gb000" .. "gb200");
311 my @g3= ("gc000" .. "gc200");
312 my @g4= ("gd000" .. "gd200");
313 my @g5= ("ge000" .. "ge200");
314 my @g6= ("gf000" .. "gf200");
315 my @g7= ("gg000" .. "gg200");
316 my $final_flag=0; my $i=0; my $k=0; my $gg=0; my $fh;
317 if ($us eq "u")
318 {open $fh, ">>", "wallace.vl";}
319 else {open $fh, ">>", "signed_wallace.vl";}
320 loop_k:
321 for my $k ( 0 .. $#sorted_counts )
322 {
323 if (($sorted_counts[$k]==1) && ($final_flag==0))
324 {
325 print $fh " assign product[$k] = $sorted_pp_keys[$i];\n";
326 $i++;
327 }
328 conditional_d:
329 if (($sorted_counts[$k]==2) && ($final_flag==0))
330 {
331 print $fh " assign $p0[$gg] = $sorted_pp_keys[$i] ^ $sorted_pp_keys[$i+1];\n";
332 print $fh " assign product[$k] = $p0[$gg];\n";
333 print $fh " assign $g0[$gg] = $sorted_pp_keys[$i] & $sorted_pp_keys[$i+1];\n";
334 if ($adder_length > 1)
335 {
336 print $fh " buf($p1[$gg],$p0[$gg]);\n";
337 print $fh " buf($g1[$gg],$g0[$gg]);\n";
338 }
339 if ($adder_length > 2)
340 {
341 print $fh " buf($p2[$gg],$p1[$gg]);\n";
342 print $fh " buf($g2[$gg],$g1[$gg]);\n";
343 }
344 if ($adder_length > 4)
345 {
346 print $fh " buf($p3[$gg],$p2[$gg]);\n";
347 print $fh " buf($g3[$gg],$g2[$gg]);\n";
348 }
349 if ($adder_length > 8)
350 {
351 print $fh " buf($p4[$gg],$p3[$gg]);\n";
352 print $fh " buf($g4[$gg],$g3[$gg]);\n";
353 }
354 if ($adder_length > 16)
355 {
356 print $fh " buf($p5[$gg],$p4[$gg]);\n";
357 print $fh " buf($g5[$gg],$g4[$gg]);\n";
358 }
359 if ($adder_length > 32)
360 {
361 print $fh " buf($p6[$gg],$p5[$gg]);\n";
362 print $fh " buf($g6[$gg],$g5[$gg]);\n";
363 }
364 if ($adder_length > 64)
365 {
366 print $fh " buf($p7[$gg],$p6[$gg]);\n";
367 print $fh " buf($g7[$gg],$g6[$gg]);\n";
368 }
369 $final_flag=1;
370 $gg=$gg+1;
371 $i=$i+2;
372 next;
373 }
374 conditional_e:
375 if ($final_flag==1)
376 {
377 conditional_f:
378 if ($k < $pl)
379 {
380 print $fh " assign $p0[$gg] = $sorted_pp_keys[$i] ^ $sorted_pp_keys[$i+1];\n";
381 print $fh " assign $g0[$gg] = $sorted_pp_keys[$i] & $sorted_pp_keys[$i+1];\n";
382 if ($adder_length==2)
383 { print $fh " assign product[$k] = $p0[$gg];\n"; }
384 if ($adder_length==3)
385 { print $fh " assign product[$k] = $p0[$gg] ^ $g1[$gg-1];\n"; }
386 if ((6> $adder_length) && ($adder_length > 3))
387 { print $fh " assign product[$k] = $p0[$gg] ^ $g2[$gg-1];\n"; }
388 if ((9> $adder_length) && ($adder_length > 5))
389 { print $fh " assign product[$k] = $p0[$gg] ^ $g3[$gg-1];\n"; }
390 if ((18> $adder_length) && ($adder_length > 8))
391 { print $fh " assign product[$k] = $p0[$gg] ^ $g4[$gg-1];\n"; }
392 if ((34> $adder_length) && ($adder_length > 17))
393 { print $fh " assign product[$k] = $p0[$gg] ^ $g5[$gg-1];\n"; }
394 if ((66> $adder_length) && ($adder_length > 33))
395 { print $fh " assign product[$k] = $p0[$gg] ^ $g6[$gg-1];\n"; }
396 if ((130> $adder_length) && ($adder_length > 65))
397 { print $fh " assign product[$k] = $p0[$gg] ^ $g7[$gg-1];\n"; }
398 if ($adder_length > 1)
399 { if ($gg>0)
400 { print $fh " assign $p1[$gg] = $p0[$gg] & $p0[$gg-1];\n";
401 print $fh " assign $g1[$gg] = $g0[$gg] | ($p0[$gg] & $g0[$gg-1]);\n"; }
402 else
403 { print $fh " buf($p1[$gg],$p0[$gg]);\n";
404 print $fh " buf($g1[$gg],$g0[$gg]);\n"; }
405 }
406 if ($adder_length > 2)
407 { if ($gg>1)
408 { print $fh " assign $p2[$gg] = $p1[$gg] & $p1[$gg-2];\n";
409 print $fh " assign $g2[$gg] = $g1[$gg] | ($p1[$gg] & $g1[$gg-2]);\n"; }
410 else
411 { print $fh " buf($p2[$gg],$p1[$gg]);\n";
412 print $fh " buf($g2[$gg],$g1[$gg]);\n"; }
413 }
414 if ($adder_length > 4)
415 { if ($gg>3)
416 { print $fh " assign $p3[$gg] = $p2[$gg] & $p2[$gg-4];\n";
417 print $fh " assign $g3[$gg] = $g2[$gg] | ($p2[$gg] & $g2[$gg-4]);\n"; }
418 else
419 { print $fh " buf($p3[$gg],$p2[$gg]);\n";
420 print $fh " buf($g3[$gg],$g2[$gg]);\n"; }
421 }
422 if ($adder_length > 8)
423 { if ($gg>7)
424 { print $fh " assign $p4[$gg] = $p3[$gg] & $p3[$gg-8];\n";
425 print $fh " assign $g4[$gg] = $g3[$gg] | ($p3[$gg] & $g3[$gg-8]);\n"; }
426 else
427 { print $fh " buf($p4[$gg],$p3[$gg]);\n";
428 print $fh " buf($g4[$gg],$g3[$gg]);\n"; }
429 }
430 if ($adder_length > 16)
431 { if ($gg>15)
432 { print $fh " assign $p5[$gg] = $p4[$gg] & $p4[$gg-16];\n";
433 print $fh " assign $g5[$gg] = $g4[$gg] | ($p4[$gg] & $g4[$gg-16]);\n"; }
434 else
435 { print $fh " buf($p5[$gg],$p4[$gg]);\n";
436 print $fh " buf($g5[$gg],$g4[$gg]);\n"; }
437 }
438 if ($adder_length > 32)
439 { if ($gg>31)
440 { print $fh " assign $p6[$gg] = $p5[$gg] & $p5[$gg-32];\n";
441 print $fh " assign $g6[$gg] = $g5[$gg] | ($p5[$gg] & $g5[$gg-32]);\n"; }
442 else
443 { print $fh " buf($p6[$gg],$p5[$gg]);\n";
444 print $fh " buf($g6[$gg],$g5[$gg]);\n"; }
445 }
446 if ($adder_length > 64)
447 { if ($gg>63)
448 { print $fh " assign $p7[$gg] = $p6[$gg] & $p6[$gg-64];\n";
449 print $fh " assign $g7[$gg] = $g6[$gg] | ($p6[$gg] & $g6[$gg-64]);\n"; }
450 else
451 { print $fh " buf($p7[$gg],$p6[$gg]);\n";
452 print $fh " buf($g7[$gg],$g6[$gg]);\n"; }
453 }
454 }
455 else
456 {
457 if ($k==$pl)
458 {
459 if ($sorted_counts[$k]==2)
460 {print $fh " assign $p0[$gg] = $sorted_pp_keys[$i] ^ $sorted_pp_keys[$i+1];\n";}
461 else
462 {print $fh " assign $p0[$gg] = $sorted_pp_keys[$i];\n";}
463 if ($adder_length==2)
464 {
465 print $fh " assign product[$k] = $p0[$gg] ^ $g0[$gg-1];\n";
466 }
467 if ($adder_length==3)
468 {
469 print $fh " assign product[$k] = $p0[$gg] ^ $g1[$gg-1];\n";
470 }
471 if (($adder_length==4) || ($adder_length == 5))
472 {
473 print $fh " assign product[$k] = $p0[$gg] ^ $g2[$gg-1];\n";
474 }
475 if ((10> $adder_length) && ($adder_length > 5))
476 {
477 print $fh " assign product[$k] = $p0[$gg] ^ $g3[$gg-1];\n";
478 }
479 if ((18> $adder_length) && ($adder_length > 9))
480 {
481 print $fh " assign product[$k] = $p0[$gg] ^ $g4[$gg-1];\n";
482 }
483 if ((34> $adder_length) && ($adder_length > 17))
484 {
485 print $fh " assign product[$k] = $p0[$gg] ^ $g5[$gg-1];\n";
486 }
487 if ((66> $adder_length) && ($adder_length > 33))
488 {
489 print $fh " assign product[$k] = $p0[$gg] ^ $g6[$gg-1];\n";
490 }
491 if ((130> $adder_length) && ($adder_length > 65))
492 {
493 print $fh " assign product[$k] = $p0[$gg] ^ $g7[$gg-1];\n";
494 }
495 }
496 }
497 $i=$i+2;
498 $gg=$gg+1;
499 }
500 }
501 if ($pl>$#sorted_counts)
502 {
503 if ($adder_length==2)
504 {
505 print $fh " assign product[$pl] = $g0[$gg-1];\n";
506 }
507 if ($adder_length==3)
508 {
509 print $fh " assign product[$pl] = $g1[$gg-1];\n";
510 }
511 if (($adder_length==4) || ($adder_length == 5))
512 {
513 print $fh " assign product[$pl] = $g2[$gg-1];\n";
514 }
515 if (($adder_length>=6) && ($adder_length<=9))
516 {
517 print $fh " assign product[$pl] = $g3[$gg-1];\n";
518 }
519 if (($adder_length>=10) && ($adder_length<=17))
520 {
521 print $fh " assign product[$pl] = $g4[$gg-1];\n";
522 }
523 if (($adder_length>=18) && ($adder_length<=33))
524 {
525 print $fh " assign product[$pl] = $g5[$gg-1];\n";
526 }
527 if (($adder_length>=34) && ($adder_length<=65))
528 {
529 print $fh " assign product[$pl] = $g6[$gg-1];\n";
530 }
531 }
532 print $fh "endmodule";
533 close $fh;
534 return;
535 }
536
537
538 sub testbench
539 {
540 my ($mdl,$mrl,$us,$dr)=(@_);
541 my $ul =$mdl - 1;
542 my $zl =$mrl - 1;
543 my $pl =$ul+$zl+1;
544 my $plplus1 =$pl+1;
545 my $fh;
546 if ($us eq "u")
547 {open $fh, ">", "tb_wallace.vl";
548 print $fh "`timescale 1ns/1ns\n";
549 print $fh "module tb_wallace;\n";
550 print $fh " // Unsigned multiplier testbench\n";
551 print $fh " // John Bryan, 2017\n";
552 print $fh " reg [$ul:0] a;\n";
553 print $fh " reg [$zl:0] b;\n";
554 print $fh " wire [$pl:0] product;\n";
555 print $fh " reg [$pl:0] check;\n";}
556 else
557 {open $fh, ">", "tb_swallace.vl";
558 print $fh "`timescale 1ns/1ns\n";
559 print $fh "module tb_swallace;\n";
560 print $fh " // Signed multiplier testbench\n";
561 print $fh " // John Bryan, 2017\n";
562 print $fh " reg signed [$ul:0] a;\n";
563 print $fh " reg signed [$zl:0] b;\n";
564 print $fh " wire signed [$pl:0] product;\n";
565 print $fh " reg signed [$pl:0] check;\n";}
566 my $mdlul = 2**$mdl;
567 my $mrlul = 2**$mrl;
568 my $total_tested = $mdlul*$mrlul;
569 my $mdlp1 = $mdl+1;
570 my $mrlp1 = $mrl+1;
571 if ($dr eq "d")
572 {print $fh " reg [$mdl:0] i,mdlul;\n";
573 print $fh " reg [$mrl:0] j,mrlul;\n\n";}
574 else
575 {print $fh " integer i;\n\n";}
576 if ($us eq "u")
577 {print $fh " wallace wall0(a,b,product);\n\n";}
578 else
579 {print $fh " s_wallace s_wall0(a,b,product);\n\n";}
580 print $fh " initial\n";
581 print $fh " begin\n";
582 if ($dr eq "d")
583 {
584 if ($us eq "u")
585 {print $fh " a=$mdl\'d0;\n";
586 print $fh " b=$mrl\'d0;\n";
587 print $fh " mrlul=$mrlp1\'d$mrlul;\n";
588 print $fh " mdlul=$mdlp1\'d$mdlul;\n";
589 print $fh " for (i=0;i<mdlul;i=i+1)\n";
590 print $fh " begin\n";
591 print $fh " for (j=0;j<mrlul;j=j+1)\n";
592 print $fh " begin\n";
593 print $fh " check=a*b;\n";}
594 else
595 {
596 my $smdll = 2**$ul;
597 my $smrll = 2**$zl;
598 print $fh " a=-$mdl\'d$smdll;\n";
599 print $fh " b=-$mrl\'d$smrll;\n";
600 print $fh " mrlul=$mrlp1\'d$mrlul;\n";
601 print $fh " mdlul=$mdlp1\'d$mdlul;\n";
602 print $fh " for (i=0;i<mdlul;i=i+1)\n";
603 print $fh " begin\n";
604 print $fh " for (j=0;j<mrlul;j=j+1)\n";
605 print $fh " begin\n";
606 print $fh " check=\$signed(a)*\$signed(b);\n";}
607 print $fh " #1;\n";
608 print $fh " if (product != check)\n";
609 print $fh " begin\n";
610 print $fh " \$display(\"time=%0t\", \$time);\n";
611 print $fh " \$display(\"a =%0d, b=%0d\", a, b);\n";
612 print $fh " \$display(\"product=%0d, check=%0d\", product, check);\n";
613 print $fh " \$finish;\n";
614 print $fh " end\n";
615 print $fh " b=b+1'b1;\n";
616 print $fh " end\n";
617 print $fh " a=a+1'b1;\n";
618 print $fh " end\n";
619 print $fh " \$display(\" All $total_tested were correct.\\n\");\n";
620 print $fh " \$finish;\n";
621 print $fh " end\n\n";}
622 else
623 {print $fh " for (i=0;i<10000;i=i+1)\n";
624 print $fh " begin\n";
625 if (($us eq "u") && ($ul <= 31))
626 {print $fh " a=\$urandom;\n";}
627 if (($us eq "u") && ($ul > 31))
628 {print $fh " a[31:0]=\$urandom;\n";
629 print $fh " a[$ul:32]=\$urandom;\n";}
630 if (($us eq "u") && ($zl <= 31))
631 {print $fh " b=\$urandom;\n";}
632 if (($us eq "u") && ($zl > 31))
633 {print $fh " b[31:0]=\$urandom;\n";
634 print $fh " b[$zl:32]=\$urandom;\n";}
635 if ($us eq "u")
636 {print $fh " check=a*b;\n";}
637 if (($us eq "s") && ($ul <= 31))
638 {print $fh " a=\$random;\n";}
639 if (($us eq "s") && ($ul > 31))
640 {print $fh " a[31:0]=\$random;\n";
641 print $fh " a[$ul:32]=\$random;\n";}
642 if (($us eq "s") && ($zl <= 31))
643 {print $fh " b=\$random;\n";}
644 if (($us eq "s") && ($zl > 31))
645 {print $fh " b[31:0]=\$random;\n";
646 print $fh " b[$ul:32]=\$random;\n";}
647 if ($us eq "s")
648 {print $fh " check=\$signed(a)*\$signed(b);\n";}
649 print $fh " #1;\n";
650 print $fh " if (product != check)\n";
651 print $fh " begin\n";
652 print $fh " \$display(\"time=%0t\", \$time);\n";
653 print $fh " \$display(\"a =%0d, b=%0d\", a, b);\n";
654 print $fh " \$display(\"product=%0d, check=%0d\", product, check);\n";
655 print $fh " \$finish;\n";
656 print $fh " end\n";
657 print $fh " end\n";
658 print $fh " \$display(\" All 10000 were correct.\\n\");\n";
659 print $fh " \$finish;\n";
660 print $fh " end\n\n";}
661 print $fh " endmodule\n";
662 close $fh;
663 return;
664 }
665
666
667 sub generate_and_test
668 {
669 my ($i,$j,$us,$dr,$increment)=@ARGV;
670 my $hl=$i+$j+$increment+1;
671 my $k;
672 my $pl;
673 my $ll=$i+$j;
674 my $left;
675 my $count=$ll;
676 us_for:
677 for (;($i+$j)<$hl;$i++)
678 {
679 $pl=$i+$j;
680 print "\n\n Testing product length of $pl . . .\n";
681 &generate_and_testbench($i,$j,$us,$dr);
682 if ($us eq "u")
683 {system ("iverilog wallace.vl tb_wallace.vl");}
684 if ($us eq "s")
685 {system ("iverilog signed_wallace.vl tb_swallace.vl");}
686 system ("vvp a.out");
687 $count++;
688 $left=$hl-$count;
689 $j=$j+1;
690 if (($i+$j)<$hl)
691 {
692 print "\n $left test(s) to go . . .\n";
693 $pl=$i+$j;
694 print "\n\n Testing product length of $pl . . .\n";
695 &generate_and_testbench($i,$j,$us,$dr);
696 if ($us eq "u")
697 {system ("iverilog wallace.vl tb_wallace.vl");}
698 if ($us eq "s")
699 {system ("iverilog signed_wallace.vl tb_swallace.vl");}
700 system ("vvp a.out");
701 $count++;
702 $left=$hl-$count;
703 }
704 }
705 return;
706 }