File Coverage

blib/lib/Verilog/CodeGen.pm
Criterion Covered Total %
statement 79 328 24.0
branch 23 100 23.0
condition 6 20 30.0
subroutine 9 23 39.1
pod 10 16 62.5
total 127 487 26.0


line stmt bran cond sub pod time code
1             package Verilog::CodeGen;
2              
3 1     1   7445 use vars qw( $VERSION );
  1         2  
  1         83  
4             $VERSION='0.9.4';
5              
6             #################################################################################
7             # #
8             # Copyright (C) 2002,2003 Wim Vanderbauwhede. All rights reserved. #
9             # This program is free software; you can redistribute it and/or modify it #
10             # under the same terms as Perl itself. #
11             # #
12             #################################################################################
13              
14             #print STDOUT "//Package Verilog::CodeGen loaded\n";
15              
16 1         9 use sigtrap qw(die untrapped normal-signals
17 1     1   1347 stack-trace any error-signals);
  1         1595  
18              
19 1     1   381 use strict;
  1         7  
  1         260  
20              
21             ################################################################################
22              
23             @Verilog::CodeGen::ISA = qw(Exporter);
24             @Verilog::CodeGen::EXPORT =qw(
25             &make_module
26             &create_objtest_code
27             &create_code_template
28             );
29              
30              
31             #Modify this to use different compiler/simulator/viewer
32             my $compiler="/usr/bin/iverilog";
33             my $simulator="/usr/bin/vvp";
34             my $vcdviewer="/usr/local/bin/gtkwave";
35              
36             # to store the module code for all modules
37             my %modules;
38              
39             # for print configuration
40             my %printcfg=(_fh=>*STDOUT,_fn=>'');
41              
42             #------------------------------------------------------------------------------
43             #object constructor
44             sub new {
45             #next 2 lines are fine in general, but for me a fixed class is better (saves typing)
46             #my $invocant=shift;
47             #my $class=ref($invocant) || $invocant;
48 0     0 1 0 my $class="Verilog::CodeGen";
49 0         0 my @keysvals=@_;
50 0 0       0 if ($keysvals[0] ne 'type'){unshift @keysvals,'type';unshift @_,'type'}
  0         0  
  0         0  
51 0         0 my @keys=();
52 0         0 my @args=();
53 0         0 while (@keysvals) {
54 0         0 push @keys, shift @keysvals;
55 0         0 push @args, shift @keysvals;
56             }
57              
58             #this is extremely redundant: the hash contains an array with its keys and an array with its values, so everything is there twice!!
59             #but it's convenient
60              
61 0         0 my $self= { '_keys'=>[@keys],'_args'=>[@args],@_ };
62              
63 0         0 my $modulekey=join('_',@args);
64 0         0 $modulekey=~s/\.//g;
65 0         0 $self->{modulename}=$modulekey;
66              
67 0         0 my $sub=$self->{type};
68 0         0 $sub='gen_'.$sub;
69 1         3021 SOFTREF: {
70 1     1   5 no strict "refs";
  1         2  
  0         0  
71 0         0 $self->{code}=&$sub($self);
72             }
73             #eval never works as it should for me
74             #eval('$self->{code}= &'.$sub.'($self);');
75              
76 0         0 bless($self,$class);
77              
78 0         0 $modules{$modulekey}=$self->{code};
79              
80 0         0 return $self;
81             }
82              
83             #===============================================================================
84              
85             # this is a class method to set the print options
86             sub output {
87 0     0 1 0 my $invocant=shift;
88 0         0 my $arg=$invocant;
89 0 0       0 if($invocant=~/=HASH\(0x/) {
90 0         0 $arg=shift;
91             }
92 0         0 my $fh;
93             my $filename;
94 0 0 0     0 if(!$arg || $arg!~/\n|\s/m) { # store the attributes
95              
96 0 0       0 if(!$arg) {
    0          
97 0         0 $fh=*STDOUT;
98             } elsif (scalar($arg)!~/^\*/ ) {
99 0         0 $filename=$arg;
100 0         0 $fh=*_VER;
101             } else {
102 0         0 $fh=$arg;
103             }
104 0         0 $printcfg{_fh}=$fh;
105 0 0       0 if($filename){
106 0         0 $printcfg{_fn}=$filename;
107 0         0 unlink $filename;
108             }
109             } else { # print the string
110 0   0     0 my $fh=$printcfg{_fh}||*STDOUT;
111 0         0 my $filename=$printcfg{_fn};
112              
113 0 0       0 if($filename) {
114 0         0 open $fh,">>$filename";
115             }
116              
117 0         0 print $fh $arg;
118              
119 0 0       0 if($filename) {
120 0         0 close $fh;
121             }
122              
123             }
124 0         0 return $arg;
125             }
126             #===============================================================================
127             #this is a class method to print all currently used modules
128             sub modules {
129 0   0 0 1 0 my $fh=$printcfg{_fh}||*STDOUT;
130 0         0 my $filename=$printcfg{_fn};
131              
132 0 0       0 if($filename) {
133 0         0 open $fh,">>$filename";
134             }
135 0         0 foreach my $key (keys %modules) {
136 0         0 print $fh "
137             //
138             // $key
139             //
140             ";
141 0         0 print $fh $modules{$key};
142 0         0 print $fh "
143              
144             //==============================================================================
145              
146             ";
147             }
148 0 0       0 if($filename) {
149 0         0 close $fh;
150             }
151             }
152              
153             #===============================================================================
154              
155             sub module {
156 0     0 1 0 my $objref=shift;
157 0         0 $objref->output($objref->{code});
158             }
159              
160             #===============================================================================
161             # this is what the enduser uses to print instances
162             sub instance {
163 0     0 1 0 my $objref=shift;
164              
165 0         0 my $suffix=shift ; # throw away 'suffix'
166              
167 0 0       0 if($suffix) {
  0         0  
168 0 0       0 if($suffix eq 'suffix'){
169 0         0 $suffix=shift;
170             }
171             } else {$suffix=''}
172              
173             # get module pins
174 0         0 my $modpins=$objref->{pins};
175 0         0 $modpins=~s/[)(]//g;
176 0         0 $modpins=~s/\s+//g;
177 0         0 my @modpins=split(',',$modpins);
178 0         0 my %pinlist=();
179             # assign to nets with same name as default
180 0         0 foreach my $modpin (@modpins) {
181 0         0 $pinlist{$modpin}='.'.$modpin.'('.$modpin.')';
182             }
183              
184             # override defaults
185 0         0 while (@_) {
186 0         0 my $pin=shift;
187 0         0 my $net=shift;
188 0         0 $pinlist{$pin}='.'.$pin.'('.$net.')';
189             }
190              
191 0         0 my @pinlist=();
192 0         0 foreach my $key (keys %pinlist) {
193 0         0 push @pinlist,$pinlist{$key};
194             }
195              
196 0         0 my $pins;
197 0 0       0 if(@pinlist>1) {
  0         0  
198 0         0 $pins=join(',',@pinlist)
199             } else {$pins=$pinlist[0]}
200 0         0 my @args=@{$objref->{'_args'}};
  0         0  
201 0         0 my $args=join('_',@args);
202 0         0 $args=~s/\.//g;
203              
204 0         0 my $instlabel="x_${args}_$suffix";
205 0         0 my $instline= "$args $instlabel ($pins);\n";
206             # this is fancy and unnecessary, but anyway
207             # all instances of a given object
208 0         0 $objref->{_instances}->{$suffix}=$instline;
209 0         0 $objref->{$suffix}=$instlabel;
210             # we need: $objname->{$suffix} => $instlabel
211 0         0 $objref->output($instline);
212             }
213             #===============================================================================
214             # this is for use inside modules
215             # no print, just return the string
216             sub inst {
217 0     0 1 0 my $objref=shift;
218              
219 0         0 my $suffix=shift ; # throw away 'suffix'
220 0 0       0 if($suffix) {
  0         0  
221 0 0       0 if($suffix eq 'suffix'){
222 0         0 $suffix=shift;
223             }
224             }else {$suffix=''}
225             # get module pins
226 0         0 my $modpins=$objref->{pins};
227 0         0 $modpins=~s/[)(]//g;
228 0         0 $modpins=~s/\s+//g;
229 0         0 my @modpins=split(',',$modpins);
230 0         0 my %pinlist=();
231             # assign to nets with same name as default
232 0         0 foreach my $modpin (@modpins) {
233 0         0 $pinlist{$modpin}='.'.$modpin.'('.$modpin.')';
234             }
235              
236             # override defaults
237 0         0 while (@_) {
238 0         0 my $pin=shift;
239 0         0 my $net=shift;
240 0         0 $pinlist{$pin}='.'.$pin.'('.$net.')';
241             }
242              
243 0         0 my @pinlist=();
244 0         0 foreach my $key (keys %pinlist) {
245 0         0 push @pinlist,$pinlist{$key};
246             }
247              
248 0         0 my $pins;
249 0 0       0 if(@pinlist>1) {
  0         0  
250 0         0 $pins=join(',',@pinlist)
251             } else {$pins=$pinlist[0]}
252 0         0 my @args=@{$objref->{'_args'}};
  0         0  
253 0         0 my $args=join('_',@args);
254 0         0 $args=~s/\.//g;
255              
256 0         0 my $instlabel="x_${args}_$suffix";
257 0         0 my $instline= "$args $instlabel ($pins);\n";
258             # this is fancy and unnecessary, but anyway
259 0         0 $objref->{_instances}->{$suffix}=$instline;
260 0         0 $objref->{$suffix}=$instlabel;
261 0         0 return $instline;
262              
263             }
264              
265             #===============================================================================
266              
267             sub search {
268 0     0 1 0 my $objref=shift;
269 0         0 my $pattern=shift;
270 0         0 my $result='';
271 0         0 my @code=split("\n",$objref->{code});
272 0         0 foreach my $line (@code){
273 0 0       0 if($line=~/$pattern/){
274             #print STDOUT "$line\n";
275 0         0 $result.= "$line\n";
276             }
277             }
278 0         0 return $result;
279             }
280             #===============================================================================
281              
282             sub find_inst { # returns an array ref if multiple instances!
283 0     0 1 0 my $objref=shift;
284 0         0 my $pattern=shift;
285 0         0 my @result=();
286 0         0 my @code=split("\n",$objref->{code});
287 0         0 foreach my $line (@code){
288              
289 0 0       0 if($line=~/$pattern.*$pattern/) {
290 0         0 my $instlabel=$line;
291 0         0 $instlabel=~s/^.*?\s+//;
292 0         0 $instlabel=~s/\s.*$//;
293 0         0 push @result, $instlabel;
294             }
295             }
296 0 0       0 if (@result>1){
297 0         0 return [@result];
298             } else {
299 0         0 return $result[0];
300             }
301              
302              
303             }
304             #===============================================================================
305             # a class method to run the netlist through Icarus Verilog
306             sub run {
307 0     0 1 0 my $netlist=shift;
308 0 0       0 if(scalar($netlist)=~/=HASH\(0x/){
309 0         0 $netlist=shift;
310             }
311              
312 0 0       0 if(!$netlist) {
313 0         0 $netlist=$printcfg{_fn};
314             }
315             #$netlist=~/\.v$/ || $netlist.='.v';
316 0 0       0 if ($netlist){
  0         0  
317 0         0 system("$compiler -o${netlist}vp $netlist");
318 0         0 system("$simulator ${netlist}vp");
319             } else {print STDERR "The run() method only works if the netlist is printed to a file.\n"}
320             }
321             #===============================================================================
322             # a class method to plot the results with GTKWave
323             sub plot {
324 0     0 1 0 my $netlist=shift;
325 0 0       0 if(scalar($netlist)=~/=HASH\(0x/){
326 0         0 $netlist=shift;
327             }
328              
329 0 0       0 if(!$netlist) {
330 0         0 $netlist=$printcfg{_fn};
331             }
332             #$netlist=~/\.v$/ || $netlist.='.v';
333 0 0       0 if (-e "${netlist}cd"){
  0         0  
334             # send output to /dev/null to avoid blocking the socket!
335 0         0 system("$vcdviewer ${netlist}cd >& /dev/null &");
336              
337             } else {print STDERR "The plot() method only works if the netlist is printed to a file.\n"}
338             }
339              
340             ################################################################################
341              
342             #function to convert decimal to binary
343             sub dec2bin {
344              
345 0     0 0 0 my $dec=shift;
346 0         0 my $nbits=shift;
347 0         0 my @Q=();
348 0         0 for my $nr (0..$nbits-1) {
349 0         0 my $n=$nbits-1-$nr;
350 0 0       0 if(($dec-2**$n)<0) {
351             #MSB=left unshift @Q,'0';
352 0         0 push @Q,'0';
353             }
354             else
355             {
356             # unshift @Q, '1';
357 0         0 push @Q, '1';
358 0         0 $dec=$dec-2**$n;
359             }
360             }
361 0         0 return [@Q];
362             } # END of dec2bin
363              
364              
365             #===============================================================================
366             sub splitbus {
367             # bus[n0:0] => a[n0a:0],b[n0b:0],...
368             # busname, width
369             # sum of all widths=width of original bus
370 0     0 0 0 my @nets=@_;
371 0         0 my $busname=shift @nets;
372 0         0 my $buswidth=shift @nets;
373              
374 0         0 my $fullwidth=0;
375              
376             # an addition for the frequent case of equidistant split:
377 0 0       0 if(@nets==1) {
378 0         0 my $n=shift(@nets);
379 0         0 foreach my $i (0..$n-1) {
380 0         0 $nets[2*$i+1]=$buswidth/$n;
381 0         0 $nets[2*$i]=$busname.$i;
382             }
383 0         0 $fullwidth=$buswidth;
384             } else {
385 0         0 foreach my $i (0..@nets/2-1) {
386 0         0 $fullwidth+=$nets[2*$i+1];
387             }
388             }
389 0         0 my $code="//generated with splitbus() function\n";
390              
391 0 0       0 if($fullwidth>$buswidth){
392 0         0 $code="//sum of width exceeds original bus width\n";
393 0         0 return $code;
394             }
395 0 0       0 if($fullwidth<$buswidth){
396 0         0 $code="//sum of width is smaller than original bus width\n";
397             }
398              
399 0         0 my $begin=$fullwidth;
400 0         0 foreach my $i (0..@nets/2-1) {
401 0         0 my $width=$nets[2*$i+1];
402 0         0 my $name=$nets[2*$i];
403 0         0 foreach my $b (1 ..$width) {
404             # my $i=$width-$b;
405 0         0 my $i=$b-1;
406             # my $bb=$begin-$b;
407 0         0 my $bb=$buswidth-($begin-$b)-1;
408 0         0 $code .="buf xBUF$name$b ($name\[$i\],$busname\[$bb\]);\n";
409             }
410 0         0 $begin-=$width;
411             }
412 0         0 return $code;
413             } # END of splitbus
414              
415             #===============================================================================
416             sub combinebus {
417             # bus[n0:0] => a[n0a:0],b[n0b:0],...
418             # busname, width
419             # sum of all widths=width of original bus
420 0     0 0 0 my @nets=@_;
421 0         0 my $busname=shift @nets;
422 0         0 my $buswidth=shift @nets;
423 0         0 my $fullwidth=0;
424              
425             # an addition for the frequent case of equidistant split:
426 0 0       0 if(@nets==1) {
427 0         0 my $n=shift(@nets);
428 0         0 foreach my $i (0..$n-1) {
429 0         0 $nets[2*$i+1]=$buswidth/$n;
430 0         0 $nets[2*$i]=$busname.$i;
431             }
432 0         0 $fullwidth=$buswidth;
433             } else {
434 0         0 foreach my $i (0..@nets/2-1) {
435 0         0 $fullwidth+=$nets[2*$i+1];
436             }
437             }
438              
439 0         0 my $code="//generated with combinebus() function\n";
440              
441 0 0       0 if($fullwidth>$buswidth){
442 0         0 $code="//sum of width exceeds destination bus width\n";
443 0         0 return $code;
444             }
445 0 0       0 if($fullwidth<$buswidth){
446 0         0 $code="//sum of width is smaller than destination bus width\n";
447             }
448              
449 0         0 my $begin=$fullwidth;
450 0         0 foreach my $i (0..@nets/2-1) {
451 0         0 my $width=$nets[2*$i+1];
452 0         0 my $name=$nets[2*$i];
453 0         0 foreach my $b (1 ..$width) {
454             # my $i=$width-$b;
455 0         0 my $i=$b-1;
456             # my $bb=$begin-$b;
457 0         0 my $bb=$buswidth-($begin-$b)-1;
458              
459 0         0 $code .="buf xBUF$name$b ($busname\[$bb\],$name\[$i\]);\n";
460             }
461 0         0 $begin-=$width;
462             }
463 0         0 return $code;
464             } # END of combinebus
465              
466             #===============================================================================
467             sub make_module {
468 2   100 2 0 409 my $skip=shift||'';
469 2   50     24 my $design=shift||'Verilog';
470              
471 2         7 my $up='';
472 2 50       11 if($design eq 'Verilog') {
473 1     1   7 use Cwd;
  1         2  
  1         826  
474 2         10088 my $dir=cwd();
475 2         85 $dir=~s/.*\///;
476             #we assume that a chdir to the design dir has been done
477 2 50       33 if($dir ne 'Objects') {$design=$dir; $up='../'}
  0         0  
  0         0  
478 0         0 } else { $up='../' }
479              
480 2         16 my $moduledir='DeviceLibs';
481              
482 2 100       29 if($skip eq ''){
483 1 50       40 $moduledir=($design ne 'Verilog')?'../..':'../';
484             } else {
485 1         163 my @v=<$up../*.v>;
486 1 50       15 if(@v) {
487 0         0 system("cp $up../*.v ../DeviceLibs");
488             }
489             }
490 2         14210 my $date=`date`;
491 2         48 chomp $date;
492 2         13088 my $me=`whoami`;
493 2         34 chomp $me;
494              
495 2         25 my $header="
496             #
497             # Generated using Verilog::CodeGen::make_module
498             # from Objects/*.pl
499             #
500             # by $me on $date
501             #
502             ";
503 2 50 66     105 if (($moduledir!~/\.\./)&& (not -d "$moduledir")){mkdir "$moduledir", 0755;}
  0         0  
504 2         292 open(OUT,">$moduledir/$design.pm"); # .. ,../.. or DeviceLibs
505 2         25 my $modulepath=$INC{'Verilog/CodeGen.pm'};
506 2         142 open(IN,"<$modulepath");
507 2         89 while() {
508 1772         2100 s/Verilog::CodeGen/DeviceLibs::$design/;
509 1772 100       3287 /\s+\&make_module/ && next;
510 1766 100       2993 /\s+\&create_objtest_code/ && next;
511 1764 100       2808 /\s+\&create_code_template/ && do {
512 2         6 print OUT '
513             %modules
514             %printcfg
515             &new
516             &output
517             &instance
518             &inst
519             &module
520             &modules
521             &run
522             &plot
523             &dec2bin
524             &splitbus
525             &combinebus
526             ';
527 2         91 next;
528             };
529 1762         2440 print OUT $_;
530 1762 100       5874 if(/use\ strict;/){
531 4         39 print OUT $header;
532             }
533              
534             }
535 2         43 close IN;
536              
537 2         775 my @objects=<*.pl>;
538              
539 2         19 foreach my $obj (@objects) {
540 2 50       13 $obj=~/R_/ && next;
541 2 100       31 if($obj ne "$skip.pl"){
542 1         47 open(IN,"<$obj");
543 1         5 my $ok=0;
544 1         12 print OUT "
545             #===============================================================================
546             # $obj
547             ";
548 1         20 while(){
549 24 100       55 if(/^sub/){$ok=1}
  1         5  
550 24 50       42 if($ok==1){
551 24         61 print OUT $_;
552             }
553             }
554 1         17 close IN;
555             }
556             }
557 2         204 close OUT;
558              
559             } # END of make_module()
560              
561             #===============================================================================
562             sub create_code_template {
563 1     1 0 46 my $objname=shift;
564 1   50     6 my $design=shift||'Verilog';
565              
566 1 50       4 if($design eq 'Verilog') {
567 1     1   6 use Cwd;
  1         11  
  1         224  
568 1         12674 my $dir=cwd();
569 1         38 $dir=~s/.*\///;
570 1 50       26 if($dir ne 'Objects') {$design=$dir; }
  0         0  
571             }
572              
573             #-------------------------------------------------------------------------------
574 1         14 my $templ=<<'ENDTEMPL';
575             sub gen_code_template {
576              
577             #purpose
578              
579             #args: varname
580              
581             my $objref=shift;
582             my $varname=$objref->{varname}||'DEFAULT';
583              
584             my $pins="(P1,...,Pn)";
585             my $modname=$objref->{modulename};
586             my $code = "
587             module $modname $pins;
588             ";
589             $code.='//module code';
590             $code .="
591             endmodule // $modname
592             ";
593              
594             $objref->{pins}=$pins;
595             return $code;
596              
597             } # END of gen_code_template
598              
599             ENDTEMPL
600             #-------------------------------------------------------------------------------
601              
602 1         13 $templ=~s/code_template/$objname/gms;
603 1         10 $templ=~s/DesignName/$design/gms;
604              
605 1         141 open(OBJ,">$objname.pl");
606 1         8 print OBJ $templ;
607 1         91 close OBJ;
608              
609             } # END of create_code_template
610             #===============================================================================
611             sub create_objtest_code {
612 0     0 0   my $objname=shift;
613 0   0       my $design=shift||'Verilog';
614              
615 0 0         if($design eq 'Verilog') {
616 1     1   6 use Cwd;
  1         1  
  1         308  
617 0           my $dir=cwd();
618 0           $dir=~s/.*\///;
619 0 0         if($dir ne 'Objects') {$design=$dir; }
  0            
620             }
621              
622             #-------------------------------------------------------------------------------
623 0           my $templ=<<'ENDHEADER';
624             #!/usr/bin/perl -w
625             use strict;
626              
627             ###############################################################################
628             ### This part makes it possible to test the object. ###
629             my $obj='code_template';
630             my $design='DesignName';
631             my $up='';
632             if(-d "../$design"){$up='../'}
633             BEGIN {
634             use Verilog::CodeGen;
635             &make_module('code_template','DesignName');
636             }
637             use lib '.';
638             use DeviceLibs::DesignName;
639              
640             my $test=new("$obj");
641             my $code= $test->{code};
642              
643             print $code;
644             ($design eq 'Verilog') && ($design='');
645             chdir("$up../../TestObj/$design");
646              
647             open (VER,">${obj}_default.v");
648             print VER $code;
649             close VER;
650              
651             package DeviceLibs::DesignName;
652              
653             ###############################################################################
654             ### The actual object code starts here ###
655              
656             ENDHEADER
657             #-------------------------------------------------------------------------------
658              
659 0           $templ=~s/code_template/$objname/gms;
660 0           $templ=~s/DesignName/$design/gms;
661              
662 0           open(OBJ,"<$objname.pl");
663 0           while(){
664 0           $templ.=$_;
665             }
666 0           close OBJ;
667              
668 0           open(OBJ,">$objname.tb");
669 0           print OBJ $templ;
670 0           close OBJ;
671              
672             } # END of create_objtest_code
673             #===============================================================================
674             ################################################################################
675             =head1 NAME
676              
677             B - Verilog code generator
678              
679             =head1 SYNOPSIS
680              
681             use Verilog::CodeGen;
682              
683             mkdir 'DeviceLibs/Objects/YourDesign', 0755;
684             chdir 'DeviceLibs/Objects/YourDesign';
685            
686             # if the directory YourDesign exists, the second argument can be omitted
687             # create YourModule.pl in YourDesign
688             &create_template_file('YourModule','YourDesign');
689              
690             # create a device library for testing in DeviceLibs/Objects/DeviceLibs
691             &make_module('YourModule','YourDesign');
692              
693             # create the final device library in DeviceLibs (once YourModule code is clean)
694             &make_module('','YourDesign');
695              
696             =head1 USAGE
697              
698             The most efficient way to use the code generator is using the GUI (L in the distribution). Read the documentation in L). Alternatively, you can use the scripts that the GUI uses to do the work (in the scripts/GUI folder). If you want to make your own, follow the L.
699              
700             Then edit the file YourModule.pl in the folder DeviceLibs/Objects/YourDesign.
701              
702             For example:
703              
704             sub gen_YourModule {
705             my $objref=shift;
706             my $par=$objref->{parname}||1;
707              
708             # Create Objects
709              
710             my $submodule=new('SubModule',parname1=>$par);
711              
712             # Instantiate
713            
714             my $pins="(A,Z)";
715             my $modname=$objref->{modulename};
716             my $code = "
717             module $modname $pins;
718             input A;
719             output Z;
720             ";
721             $code.=$submodule->inst('suffix',P1=>'A');
722             $code .="
723             endmodule // $modname
724             ";
725             $objref->{pins}=$pins;
726             return $code;
727             } # END of gen_YourModule
728              
729              
730             Then run C to check if the code produces valid a Verilog module.
731              
732             If this is the case, add YourModule to the device library with C<&make_module()>
733              
734             Next, create a testbench test_YourModule.pl in a directory on the same level as DeviceLibs (TestObj if you use the GUI):
735            
736             use lib '..';
737             use DeviceLibs::YourDesign;
738              
739             my $device=new("S_buffer_demux",depth=>7,);
740              
741             open (VER,">test_S_buffer_demux.v");
742              
743             output(*VER);
744              
745             modules();
746              
747             print VER "
748             module test_S_buffer_demux;
749             wire A;
750             wire [7:0] S;
751             wire [6:0] Z;
752             wire D;
753            
754             reg a;
755             reg [7:0] s;
756            
757             assign A= a;
758             assign S= s;
759            
760             reg _ck;
761             ";
762             $device->instance();
763             my $x=$device->{""};
764              
765             print VER "
766             // clock generator
767             always begin: clock_wave
768             #10 _ck = 0;
769             #10 _ck = 1;
770              
771             end
772            
773             always @(posedge _ck)
774             begin
775             \$display(\" \%0d \%b \%b \",\$time,$x. Z,$x. D);
776             end
777              
778             initial
779             begin
780             \$display(\"Time Z D\");
781             a<=1;
782             #25;
783             a<=0;
784             #25;
785             \$finish;
786             end
787             endmodule
788             ";
789             close VER;
790             run("test_S_buffer_demux.v");
791             #plot("test_S_buffer_demux.v");
792              
793             Execute the testbench script with C.
794              
795             =head1 DESCRIPTION
796              
797             Provides an object-oriented environment to generate Verilog code for modules and testbenches. The Verilog::CodeGen module provides two functions, one to create a code template and another to create a Perl module which contains the device library. This module , DeviceLibs::YourDesign, provides the class methods and contains the objects for every Verilog module; the objects are created based on a fixed template.
798             The purpose of this module is to allow the generation of customized Verilog modules. A Verilog module can have a large number of parameters like input and output bus width, buffer depth, signal delay etc. The code generator allows to create an object that will generate the Verilog module code for arbitraty values of the parameters.
799              
800             =head1 UTILITY SCRIPTS
801              
802             With the Perl module distribution come a number of utility scripts. The most important one is gui.pl, a GUI frontend for Verilog development using the code generator.
803              
804             =head1 MAIN METHODS
805              
806             =head2 B(I<$object_name>[,%attributes]);
807              
808             Create a new Verilog module object. The object attributes are optional, the object should provide reasonable defaults.
809              
810             =head2 B
811              
812             output() takes a reference to a filehandle or a filename as argument. These are stored in the global %printcfg. Without arguments, this defaults to STDOUT.
813             If output() is called with as argument a string containing \n and/or \s, this string is printed on the current filehandle.
814              
815             =head2 B
816              
817             The code generator stores all submodules of a given module in the global %modules. Calling modules() prints the code for these modules on the current filehandle.
818              
819             =head2 B
820              
821             The instance() method will print the code for the instantiation of the object on the current filehandle. An optional instance suffix can be specified (to distinguish between different instances of the same module), as well as the pin connectivity. If the connectivity for a pin is not specified, it defaults to the pin name.
822              
823             =head2 B
824              
825             The inst() method will return the code for the instantiation of the object as a string. An optional instance suffix can be specified (to distinguish between different instances of the same module), as well as the pin connectivity. If the connectivity for a pin is not specified, it defaults to the pin name.
826              
827             =head2 B
828              
829             Run the netlist through the Icarus Verilog (http://www.icarus.com) open source verilog simulator. The filename is optional if it was specified with the output() method.
830              
831             =head2 B
832              
833             Plot the result of the simulation with gtkwave. For this purpose, the \$dumpvar and \$dumpfile compiler directives must be present in the testbench code. The filename is optional if it was specified with the output() method.
834              
835             =head2 B
836              
837             This method can be used to print the code for a specified module on the current filehandle.
838              
839             =head2 B
840              
841             Search the verilog code for a given pattern.
842              
843             =head2 B
844              
845             Find all instances matching /pattern/ in the netlist.
846              
847             =head1 MAIN ATTRIBUTES
848              
849             =head2 B<{$instance_suffix}>
850              
851             Returns the full instance name of the object.
852             $x=$object->{$instance_suffix};
853              
854             =head1 TODO
855              
856             =over
857              
858             =item *
859              
860             Convert the utility scripts to functions to be called from Verilog::CodeGen.
861              
862             =item *
863              
864             Put the GUI scripts in a module Gui.pm.
865              
866             =item *
867              
868             Separate the code for testing purposes from the module object code.
869              
870             =back
871              
872             =head1 SEE ALSO
873              
874             Icarus Verilog L
875              
876             =head1 AUTHOR
877              
878             W. Vanderbauwhede B.
879              
880             L
881              
882             =head1 COPYRIGHT
883              
884             Copyright (c) 2002 Wim Vanderbauwhede. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
885              
886             =cut