bootloader: bumped the version to 2.1
[nios2ecos.git] / eth_ocm / cb_generator.pl
blob17a482468f7980d7168fbf7c0227870580a5807c
1 # | file: cb_generator.pl
2 # |
3 # | This SOPC Builder Generator program is provided by
4 # | the Component Builder application. It is copied
5 # | straight across and is data-driven from its command
6 # | line arguments and the PTF files referenced.
7 # |
8 # | Its purpose is to construct an HDL "wrapper" for
9 # | a particular instance of a particular SOPC Builder
10 # | peripheral. This wrapper resolves the instance
11 # | name and any HDL parameterization.
12 # |
13 # +-------------------------------------------
17 # +-------------------------------------------
18 # |
20 use strict;
21 use format_conversion_utils;
22 use ptf_parse;
23 use wiz_utils;
24 use europa_all;
25 use run_system_command_utils;
27 # |
28 # +-------------------------------------------
32 # +-------------------------------------------
33 # |
34 # | first pass: include all of generator_libarary.pm RIGHT HERE.
35 # | dvb04.08.02
36 # | then prune down to actual functionality.
37 # |
38 # | TODO: Rewrite this whole file into something readable
39 # | this is much more confusing than I'm comfortable with. dvb04.
40 # | (though it does seem to work.)
41 # |
43 my $DEBUG_DEFAULT_GEN = 1;
45 #This is the global hash of arguments passed in by the generator program
47 my $generator_hr = {
48 wrapper_args => {
49 make_wrapper => 0,
50 top_module_name => "",
51 simulate_hdl => 1,
52 ports => "",
54 class_ptf_hr => "",
55 module_ptf_hr => "",
56 system_ptf_hr => "",
57 language => "",
58 external_args => "",
59 external_args_hr => "",
60 project_path_widget => "__PROJECT_DIRECTORY__",
61 generator_mode => "silent",
65 sub generator_print_verbose
67 my ($info) = (@_);
69 if($generator_hr->{generator_mode} eq "verbose"){
70 print("cb_generator.pl: ".$info);
74 sub generator_enable_mode
76 my ($mode) = (@_);
77 $generator_hr->{generator_mode} = $mode;
80 sub generator_get_system_ptf_handle
82 return $generator_hr->{system_ptf_hr};
85 sub generator_get_language
87 return $generator_hr->{language};
90 sub generator_get_class_ptf_handle
92 return $generator_hr->{class_ptf_hr};
95 sub default_ribbit
97 my ($arg) = (@_);
98 &ribbit("\n\n--Error: default_gen_lib: $arg\n");
102 sub _copy_files
104 my ($dest_dir, $source_dir, @files) = (@_);
105 my $function_name;
107 #validate args
108 &default_ribbit("No target dir for function copy_files!")
109 unless ($dest_dir ne "");
111 &default_ribbit("No source dir for function copy_files!")
112 unless ($source_dir ne "");
114 &default_ribbit("No files for function copy_files!")
115 unless (@files != 0);
118 #check for valid directories
119 opendir (SDIR, $source_dir) or
120 &default_ribbit("can't open $source_dir !");
122 opendir (DDIR, $dest_dir) or
123 &default_ribbit("can't open $dest_dir !");
126 foreach my $source_file(@files){
128 # | Separate out the source subdir and the source filename
130 my $source_subdir = "";
131 my $source_filename = $source_file;
133 if($source_filename =~ /^(.*)\/(.*)$/) # break on last slash
135 $source_subdir = "/$1"; # embed its leading slash, for concatty
136 $source_filename = $2;
139 my $source_fullpath = "$source_dir$source_subdir/$source_filename";
140 my $dest_fullpath = "$dest_dir/$source_filename";
142 &Perlcopy($source_fullpath, $dest_fullpath);
143 &generator_print_verbose("Copying file: \"$source_fullpath\""
144 . " to \"$dest_fullpath\".\n");
147 closedir (SDIR);
148 closedir (DDIR);
152 sub get_module_wrapper_arg_hash_from_system_ptf_file
154 my $module_ptf_hr = $generator_hr->{module_ptf_hr};
156 my @list_of_sections = ("MASTER","SLAVE","PORT_WIRING");
157 my @port_list;
158 foreach my $section(@list_of_sections){
159 my $number = get_child_count($module_ptf_hr, $section);
161 for(my $initial=0; $initial < $number; $initial++){
163 my $interface_section = get_child($module_ptf_hr, $initial, $section);
164 my $interface_section_name = get_data($interface_section);
166 my $port_wiring_section;
167 if($section ne "PORT_WIRING"){
168 $port_wiring_section =
169 get_child_by_path($module_ptf_hr, $section." ".$interface_section_name."/PORT_WIRING");
170 }else{
171 $port_wiring_section =
172 get_child_by_path($module_ptf_hr, $section);
174 my $num_ports = get_child_count($port_wiring_section, "PORT");
175 foreach(my $port_count = 0; $port_count < $num_ports; $port_count++){
176 my $port = get_child($port_wiring_section, $port_count, "PORT");
178 my %port_info_struct;
179 $port_info_struct{name} = get_data($port);
180 $port_info_struct{direction} = get_data_by_path($port, "direction");
181 $port_info_struct{width} = get_data_by_path($port, "width");
182 $port_info_struct{vhdl_record_name} = get_data_by_path($port, "vhdl_record_name");
183 $port_info_struct{vhdl_record_type} = get_data_by_path($port, "vhdl_record_type");
185 push(@port_list, \%port_info_struct);
190 $generator_hr->{wrapper_args}{ports} = \@port_list;
194 sub generator_make_module_wrapper
196 my ($simulate_hdl, $top_module_name, $module_language) = (@_);
198 &default_ribbit("generator_make_module_wrapper: no arg0 passed in for simulate_hdl\n")
199 if($simulate_hdl eq '');
201 &default_ribbit("generator_make_module_wrapper: no arg1 passed in for top_module_name\n")
202 unless($top_module_name);
204 $generator_hr->{wrapper_args}{simulate_hdl} = $simulate_hdl;
205 $generator_hr->{wrapper_args}{top_module_name} = $top_module_name;
206 $generator_hr->{wrapper_args}{make_wrapper} = 1;
207 $generator_hr->{wrapper_args}{module_language} = $module_language;
215 # | recognize varous number forms,
216 # | return 'h0123abcd-ish.
218 sub turn_anything_into_appropriate_string($$$$)
220 my ($value,$type,$editable,$module_language) = (@_);
222 return $value if($value =~ /^\"/); # quoted string: unscathed
223 return $value if($type eq "string"); # string: anything is ok
225 return $value if(!$editable); # and you know, if you can't change it, keep it!
229 # | first, convert to a number
231 my $base = 10;
232 my $n = $value;
233 my $width = 32;
234 my $number = 0;
236 $value = lc($value); # lower case
238 if($value =~ /^([0-9]*)\'([hbo])(.*)$/)
240 # | tick notation: AOK for verilog
241 if($module_language eq "verilog")
243 $number = $value;
246 # | note: at this point, we could notice if the
247 # | result should be vhdl binary, and convert
248 # | to that, avoiding the precision-losing
249 # | integer intermediary
251 # | (alternatively, we could use a binary string
252 # | always as the intermediate form, rather than
253 # | a precision-losing int.)
255 else
257 $width = $1;
258 my $baseletter = $2;
259 my $digits = $3;
261 if($baseletter eq "h")
263 $base = 16;
265 elsif($baseletter eq "b")
267 $base = 2;
269 elsif($baseletter eq "o") # must be
271 $base = 8;
274 $digits =~ s/[ _-]//g; # crush out dividing value
276 while(length($digits) > 0)
278 my $digit = substr($digits,0,1);
279 $digits = substr($digits,1);
280 my $digitvalue = hex($digit); # how handy
281 $number = $number * $base + $digitvalue;
285 elsif($value =~ /^0x(.*)$/)
287 $number = hex($1);
289 else # try for decimal
291 $number = int(1 * $value);
295 # | ok, we have a number. If our target type
296 # | is "std_logic_vector(this downto that)"
297 # | for tricky VHDL, we
298 # | must quote a binary string out of it.
301 if(($module_language eq "vhdl") and ($type =~ /^.*\((\d+) downto (\d+)\).*$/))
303 my ($high_bit,$low_bit) = ($1,$2);
304 my $binary = "";
305 for(my $bit = $low_bit; $bit <= $high_bit; $bit++)
307 $binary = ($number % 2) . $binary;
308 $number = int($number >> 1);
311 $number = '"' . $binary . '"';
314 return $number;
318 # return @array of vhdl libraries, if any, from the class.ptf
319 sub get_libraries()
321 my $class_ptf = generator_get_class_ptf_handle();
322 my @libraries;
323 my $libraries_ptf = get_child_by_path($class_ptf,"CLASS/CB_GENERATOR/LIBRARIES");
325 if($libraries_ptf)
327 my $library_count = get_child_count($libraries_ptf,"library");
328 for(my $i = 0; $i < $library_count; $i++)
330 my $library_ptf = get_child($libraries_ptf,$i,"library");
331 my $library_name = get_data($library_ptf);
332 push(@libraries,$library_name);
336 return @libraries;
341 sub _generator_make_module_wrapper
344 my $wrapper_args = $generator_hr->{wrapper_args};
345 my $no_black_box = $wrapper_args->{simulate_hdl};
346 my $top_module_name = $wrapper_args->{top_module_name};
347 my $language = $generator_hr->{language};
348 my @external_args = @{$generator_hr->{external_args}};
349 my $module_ptf_hr = $generator_hr->{module_ptf_hr};
351 ### Build Module
352 my $project = e_project->new(@external_args);
353 my $top = $project->top();
355 # add the ports to the system module
356 my @ports;
358 foreach my $port_hash(@{$wrapper_args->{ports}}){
359 my $porto = e_port->new({
360 name => $port_hash->{name},
361 width => $port_hash->{width},
362 direction => $port_hash->{direction},
363 vhdl_record_name => $port_hash->{vhdl_record_name},
364 vhdl_record_type => $port_hash->{vhdl_record_type}
366 push(@ports, $porto);
368 $top->add_contents(@ports);
374 # +----------------------------------------
375 # | Get parameters from class.ptf
376 # | create @array of parameters, eacho
377 # | one like name=>, default=>, type=>,
378 # |
379 # | These are the definitions of parameters for
380 # | ANY instance of this module; we need to
381 # | have them in the "wrapee" module so that
382 # | when the system bus is knitted together
383 # | the parameter types can be properly used.
385 # | (as it turns out, verilog doesnt need
386 # | them, but vhld does)
388 # | dvb2004
391 my @e_hdl_parameters; # list of e_parameters
393 my $class_ptf = generator_get_class_ptf_handle();
394 my $hdl_parameter_definitions_ptf = get_child_by_path($class_ptf,"CLASS/COMPONENT_BUILDER/HDL_PARAMETERS");
396 my @libraries = get_libraries();
398 my $hdl_parameter_count = get_child_count($hdl_parameter_definitions_ptf,"HDL_PARAMETER");
400 my $module_language = $generator_hr->{wrapper_args}{module_language};
402 for(my $i = 0; $i < $hdl_parameter_count; $i++)
404 my $a_parameter = get_child($hdl_parameter_definitions_ptf,$i,"HDL_PARAMETER");
405 my $parameter_editable = get_data_by_path($a_parameter,"editable");
406 if($parameter_editable)
408 my $boring_name = get_data($a_parameter); # legal guinevere-ized
409 my $name = get_data_by_path($a_parameter,"parameter_name"); # original HDL name
410 my $default = get_data_by_path($a_parameter,"default_value");
411 my $type = get_data_by_path($a_parameter,"type");
413 $default = turn_anything_into_appropriate_string($default,$type,1,$module_language);
415 my $a_parameter = e_parameter->new
417 name => $name,
418 default => $default,
419 type => $type
422 push (@e_hdl_parameters,$a_parameter);
428 # | and @e_hdl_parameters is used below in the wrapee module
429 # +--------------------------------------------
431 # +--------------------------------------------
432 # | Now, we build a "hdl_parameter_map", which is just
433 # | your basic hash table with keys (parameters)
434 # | and values (parameter values).
436 # | these are the particular values for this instance.
439 my %hdl_parameter_map;
440 my $module_ptf = $generator_hr->{module_ptf_hr};
441 my $hdl_parameters_ptf =
442 get_child_by_path($module_ptf,"WIZARD_SCRIPT_ARGUMENTS/hdl_parameters");
444 my $child_count = get_child_count($hdl_parameters_ptf);
446 for(my $i = 0; $i < $child_count; $i++)
448 my $a_parameter = get_child($hdl_parameters_ptf,$i);
450 my $boring_name = get_name($a_parameter);
451 my $value = get_data($a_parameter);
453 # refer back to the original HDL name...
454 my $parameter_definition_ptf = get_child_by_path($hdl_parameter_definitions_ptf,"HDL_PARAMETER $boring_name");
455 my $parameter_name = get_data_by_path($parameter_definition_ptf,"parameter_name");
456 my $parameter_type = get_data_by_path($parameter_definition_ptf,"type");
457 my $parameter_editable = get_data_by_path($parameter_definition_ptf,"editable");
459 $value = turn_anything_into_appropriate_string($value,$parameter_type,$parameter_editable,$module_language);
462 # | our internal _dummy assignment shows up here
463 # | without a corresponding hdl entry. we
464 # | ignore it.
467 if(($parameter_name ne "") and $parameter_editable)
469 $hdl_parameter_map{$parameter_name} = $value;
473 my $wrapee_module;
474 $wrapee_module = e_module->new({
475 name => $top_module_name,
476 contents => [@ports,@e_hdl_parameters],
477 do_black_box => 0,
478 do_ptf => 0,
479 _hdl_generated => 1,
480 _explicitly_empty_module => 1,
483 # VHDL Libraries, from PTF file...
484 $wrapee_module->add_vhdl_libraries(@libraries);
485 $top->add_vhdl_libraries(@libraries);
488 $top->add_contents (
489 e_instance->new({
490 module => $wrapee_module,
491 parameter_map => \%hdl_parameter_map
495 $project->top()->do_ptf(0);
496 $project->do_write_ptf(0);
499 my $module_file = $project->_target_module_name().".v";
500 $module_file = $project->_target_module_name().".vhd"
501 if($language eq "vhdl");
503 $module_file = $generator_hr->{project_path_widget}."/".$module_file;
504 &generator_set_files_in_system_ptf("Synthesis_HDL_Files", ($module_file));
505 $project->output();
508 # if you don't want a simulation model, you don't get a simulation model
509 if($no_black_box eq "0")
511 my $black_project = e_project->new(@external_args);
512 $black_project->_target_module_name($top_module_name);
513 my $black_top = $black_project->top();
517 $black_top->add_contents(@ports);
518 my $black_top_instance;
519 $black_top_instance = e_module->new({
520 name => $wrapper_args->{top_module_name}."_bb",
521 contents => [@ports],
522 do_black_box => 1,
523 do_ptf => 0,
524 _hdl_generated => 0,
525 _explicitly_empty_module => 1,
528 $black_top->add_contents (
529 e_instance->new({
530 module => $black_top_instance,
537 $black_project->top()->do_ptf(0);
538 $black_project->do_write_ptf(0);
540 my $black_module_file = $black_project->_target_module_name().".v";
541 $black_module_file = $black_project->_target_module_name().".vhd"
542 if($language eq "vhdl");
545 $black_module_file = $generator_hr->{project_path_widget}."/".$black_module_file;
546 &generator_set_files_in_system_ptf("Simulation_HDL_Files", ($black_module_file));
548 # &set_data_by_path($module_ptf_hr, "HDL_INFO/Simulation_HDL_Files", $black_module_file);
551 $black_project->output();
556 ####
557 # Args: $file_type : "synthesis", "synthesis_only", "simulation"
558 # @file_list : an array of files. This list of files is assumed to be relative to the
559 # component's directory
562 my $decoder_ring_hr = {
563 quartus_only => {
564 copy => 1,
565 copy_to => "project",
566 ptf_set => 0,
568 simulation_only => {
569 copy => 1,
570 copy_to => "simulation",
571 ptf_set => 1,
572 ptf_section => "Simulation_HDL_Files",
574 simulation_and_quartus => {
575 copy => 1,
576 copy_to => "project",
577 ptf_set => 1,
578 ptf_section => "Synthesis_HDL_Files",
580 precompiled_simulation_files => {
581 copy => 0,
582 ptf_set => 1,
583 ptf_section => "Precompiled_Simulation_Library_Files",
590 sub generator_copy_files_and_set_system_ptf
592 my ($hdl_section, @file_list) = (@_);
594 my $ptf_path_prefix = "";
595 my $external_args_hr = $generator_hr->{external_args_hr};
596 my @new_file_array;
598 #validate first
599 my $decoder_hash = $decoder_ring_hr->{$hdl_section};
600 &default_ribbit("generator_copy_files_and_set_system_ptf: No understood HDL section passed in for first arg\n")
601 unless($decoder_ring_hr->{$hdl_section} ne "");
603 &generator_print_verbose("generator_copy_files_and_set_system_ptf: copying files for section ".$hdl_section."\n");
605 #copy second
606 my @new_file_array;
608 # If we need to copy over some files, then we need to make sure we are
609 # keeping track of what files we copy over.
610 # Otherwise, we just need to keep track of the files that the user has asked to copy over
611 # and use these instead.
612 if($decoder_hash->{copy}){
613 my $copy_to_location;
614 my $copy_from_location;
616 if($decoder_hash->{copy_to} eq "project"){
617 $copy_to_location = $external_args_hr->{system_directory};
618 }elsif($decoder_hash->{copy_to} eq "simulation"){
619 $copy_to_location = $external_args_hr->{system_sim_dir};
620 }else{
621 &default_ribbit("generator_copy_files_and_set_system_ptf: No understood copy files to location\n");
624 $copy_from_location = $external_args_hr->{class_directory};
625 @new_file_array = &generator_copy_files($copy_to_location, $copy_from_location, @file_list);
626 }else{
627 @new_file_array = @file_list;
630 #scribble on PTF hash last
631 if($decoder_hash->{ptf_set}){
633 if($decoder_hash->{copy_to} eq "project"){
634 foreach my $file(@new_file_array){
635 $file =~ s/^.*\/(.*?)$/$1/;
636 $file = $generator_hr->{project_path_widget}."/".$file;
639 &generator_print_verbose("generator_copy_files_and_set_system_ptf: setting system PTF file in section ".$hdl_section."\n");
640 if($decoder_hash->{ptf_section} eq "Precompiled_Simulation_Library_Files"){
641 @new_file_array = map{$external_args_hr->{class_directory}."/".$_} @new_file_array;
643 &generator_set_files_in_system_ptf($decoder_hash->{ptf_section}, @new_file_array);
649 ####
650 # Name: generator_set_files_in_system_ptf
651 # Args: $hdl_section
652 # @list_of_files
653 # Returns: 1 or 0
654 # Purpose: This is an internal function used to set files in the module's section in the system PTF file
656 sub generator_set_files_in_system_ptf
658 my ($hdl_section, @list_of_files) = (@_);
660 my $file_list = join(",", @list_of_files);
661 my $previous_data;
663 &generator_print_verbose("setting HDL_INFO/".$hdl_section." in system PTF file with ".$file_list."\n");
664 my $previous_data = &get_data_by_path($generator_hr->{module_ptf_hr}, "HDL_INFO/".$hdl_section);
665 if($previous_data){
666 $file_list = $previous_data . ", $file_list"; # spr 132177
667 # swapping order, dvb 2003
669 &set_data_by_path($generator_hr->{module_ptf_hr}, "HDL_INFO/".$hdl_section, $file_list);
672 ####
673 # Name: generator_copy_files
674 # Args: $target_directory
675 # $source_directory
676 # @list_of_files
677 # Returns: The list of files which has been copied (suitable for framing!)
678 # Purpose: This is an internal function used to copy files around in the generator program.
680 sub generator_copy_files
682 my ($target_directory, $source_directory, @list_of_files) = (@_);
684 my @new_file_array;
686 foreach my $file_name(@list_of_files){
687 $file_name =~ s|\\|\/|g;
688 if($file_name =~ /\*\.*/){
689 $file_name =~ s/\*/$1/;
690 my @found_list = &_find_all_dir_files_with_ext($source_directory, $file_name);
691 push(@new_file_array, @found_list);
692 }else{
693 &generator_print_verbose("Copying: ".$file_name."\n");
694 push(@new_file_array, $file_name);
698 &_copy_files($target_directory, $source_directory, @new_file_array);
699 return @new_file_array;
704 sub _find_all_dir_files_with_ext
706 my ($dir,
707 $ext) = (@_);
709 opendir (DIR, $dir) or
710 &default_ribbit("can't open $dir !");
712 my @all_files = readdir(DIR);
713 my @new_file_list;
716 foreach my $file (@all_files){
717 if($file =~ /^.*($ext)$/){
718 push(@new_file_list, $file);
722 return @new_file_list;
725 ####
726 # Name: generator_begin
727 # Args: Array of generator program launcher args
728 # Returns: A hash reference to the module's section in the system PTF file
729 # Purpose: This is the first subroutine a user should call before running the rest of their
730 # generator program.
733 sub generator_begin
735 my @external_args = (@_);
737 my ($external_args_hr,
738 $temp_user_defined,
739 $temp_db_Module,
740 $temp_db_PTF_File) = Process_Wizard_Script_Arguments("", @external_args);
742 &generator_print_verbose("generator_begin: initializing\n");
744 $generator_hr->{external_args_hr} = $external_args_hr;
745 $generator_hr->{external_args} = \@external_args;
747 # open up class.ptf and
748 $generator_hr->{class_ptf_hr} = new_ptf_from_file($external_args_hr->{class_directory}."/class.ptf");
750 # get the system.ptf
751 $generator_hr->{system_ptf_hr} = new_ptf_from_file($external_args_hr->{system_directory}."/".$external_args_hr->{system_name}.".ptf");
752 $generator_hr->{module_ptf_hr} = &get_child_by_path($generator_hr->{system_ptf_hr}, "SYSTEM $external_args_hr->{system_name}/MODULE $external_args_hr->{target_module_name}");
753 my $class_name = get_data_by_path($generator_hr->{module_ptf_hr}, "class");
755 # find the default generator section
756 $generator_hr->{language} = get_data_by_path($generator_hr->{system_ptf_hr}, "SYSTEM $external_args_hr->{system_name}/WIZARD_SCRIPT_ARGUMENTS/hdl_language");
758 # get some wrapper settings
759 &get_module_wrapper_arg_hash_from_system_ptf_file();
761 # clear system ptf's HDL section
762 &delete_child($generator_hr->{module_ptf_hr}, "HDL_INFO");
764 return $generator_hr->{module_ptf_hr};
767 ####
768 # Name: generator_end
769 # Args: none
770 # Returns: nothing
771 # Purpose: This is the last subroutine a user should call from their generator program.
772 # Not calling this subroutine will make you very sad... =<
775 sub generator_end
777 # o.k., time to make the wrapper and output it.
778 if($generator_hr->{wrapper_args}{make_wrapper}){
779 &_generator_make_module_wrapper();
783 my $external_args_hr = $generator_hr->{external_args_hr};
784 my $ptf_file_name = $external_args_hr->{system_directory}."/".$external_args_hr->{system_name}.".ptf";
785 &generator_print_verbose("generator_end: writing PTF file ".$external_args_hr->{system_name}.".ptf to ".$external_args_hr->{system_directory}."\n");
787 default_ribbit("Cannot write PTF file ".$ptf_file_name."!\n")
788 unless(&write_ptf_file($generator_hr->{system_ptf_hr}, $external_args_hr->{system_directory}."/".$external_args_hr->{system_name}.".ptf"));
791 sub generator_end_read_module_wrapper_string
793 my $language = &generator_get_language();
794 my $ls;
796 if($language =~ /vhdl/){
797 $ls = ".vhd";
798 }elsif($language =~ /verilog/){
799 $ls = ".v";
800 }else{
801 &ribbit("generator_end_read_module_wrapper_string invoked with unkown language");
803 my $system_dir = $generator_hr->{external_args_hr}->{system_directory};
804 my $module_name = $generator_hr->{external_args_hr}->{target_module_name};
806 my $file = $system_dir."/".$module_name.$ls;
807 &generator_print_verbose("generator library reading file into string: $file\n");
809 open (FILE,"<$file") or ribbit "cannot open file ($file) ($!)\n";
810 my $return_string;
811 while (<FILE>)
813 $return_string .= $_;
815 close (FILE);
816 return($return_string);
819 sub generator_end_write_module_wrapper_string
821 my $string = shift or ribbit "no string specified\n";
823 my $language = &generator_get_language();
824 my $ls;
826 print $language;
828 if($language =~ /vhdl/){
829 $ls = ".vhd";
830 }elsif($language =~ /verilog/){
831 $ls = ".v";
832 }else{
833 &ribbit("generator_end_read_module_wrapper_string invoked with unkown language");
835 my $system_dir = $generator_hr->{external_args_hr}->{system_directory};
836 my $module_name = $generator_hr->{external_args_hr}->{target_module_name};
838 my $file = $system_dir."/".$module_name.$ls;
839 &generator_print_verbose("generator library writing string into file: $file\n");
841 open (FILE,">$file") or ribbit "cannot open file ($file) ($!)\n";
842 print FILE $string;
843 close (FILE);
845 # end of generator_library.pm
855 # ---------------------------------------------------------------------
857 # +----------------------------------------------------
858 # | emit_system_h
860 # | if "is_cpu", attempt to emit a system.h
861 # | memory map.
864 sub emit_system_h($$$)
866 my ($sopc_directory,$master,$system_ptf) = (@_);
869 # | Build a system.h file for masters.
873 # as of quartus 5.0, we prefer gtf-generate in sopc_builder directly
875 my $gtf_generate = "$sopc_directory/bin/gtf-generate";
876 my $gtf_filename = "$sopc_directory/bin/gtf/system.h.gtf";
878 if(! -f $gtf_generate)
880 # but if sopc_builder is missing it for whatever reason,
881 # try the one in sopc_kit_nios2
883 my $sopc_kit_nios2 = $ENV{SOPC_KIT_NIOS2};
884 if($sopc_kit_nios2 ne "")
886 $gtf_generate = "$sopc_kit_nios2/bin/gtf-generate";
887 $gtf_filename = "$sopc_kit_nios2/bin/gtf/system.h.gtf";
892 # | xml template
895 my $stf_template = <<EOP;
896 <?xml version="1.0" encoding="UTF-8"?>
897 <stf>
898 <!-- This file generated on --date-- by --whoami-- -->
899 <project name="--project_name--"
900 ptf="--system_ptf--"
901 dir="--output_directory--"
903 <cpu name="--master--" />
904 </stf>
909 # | THINK
912 my $output_directory = "./${master}_map";
913 my $project_name = "ignored";
914 my $stf_filename = "./${master}_project.stf";
917 # | build up template variables
920 my %template_vars;
921 $template_vars{date} = fcu_date_time();
922 $template_vars{whoami} = $0;
923 $template_vars{project_name} = $project_name;
924 $template_vars{system_ptf} = $system_ptf;
925 $template_vars{output_directory} = $output_directory;
926 $template_vars{master} = $master;
929 # | poke in the values to the template
932 foreach my $key (sort(keys(%template_vars)))
934 $stf_template =~ s/--$key--/$template_vars{$key}/gs;
937 ## debug print $stf_template;
940 # | write out the stf file, so we can soon use it
943 fcu_write_file($stf_filename,$stf_template);
946 # | and use it
949 if(-e $gtf_generate && -e $gtf_filename)
952 my $generate_cmd = $gtf_generate;
954 $generate_cmd .= " --output-directory=$output_directory";
955 $generate_cmd .= " --gtf=$gtf_filename";
956 $generate_cmd .= " --stf=$stf_filename";
958 r_system($sopc_directory,$generate_cmd);
961 # | done with it
964 r_system($sopc_directory,"rm $stf_filename");
966 fcu_print_command("Generated memory map \"$output_directory/system.h\"");
968 else
970 fcu_print_command("Warning: did NOT emit system.h for $master");
979 sub r_system($$)
981 my ($sopc_directory,$cmd) = (@_);
982 fcu_print_command($cmd);
983 return Run_Command_In_Unix_Like_Shell($sopc_directory,$cmd);
992 # +------------------------------------------
993 # | synthesis and simulation files are are
994 # | listed in CLASS/CB_GENERATOR/HDL_FILES.
997 sub get_synthesis_files($)
999 my ($class_ptf) = (@_);
1000 my $synthesis_files = "";
1001 my $simulation_files = "";
1003 my $hdl_files = get_child_by_path($class_ptf,"CLASS/CB_GENERATOR/HDL_FILES");
1004 my $child_count = get_child_count($hdl_files);
1005 for(my $i = 0; $i < $child_count; $i++)
1007 my $hdl_file = get_child($hdl_files,$i);
1008 if(get_name($hdl_file) eq "FILE")
1010 my $filename = get_data_by_path($hdl_file,"filepath");
1011 my $use_in_synthesis = get_data_by_path($hdl_file,"use_in_synthesis");
1012 my $use_in_simulation = get_data_by_path($hdl_file,"use_in_simulation");
1014 if($use_in_synthesis)
1016 $synthesis_files .= ", " if $synthesis_files;
1017 $synthesis_files .= $filename;
1020 if($use_in_simulation)
1022 $simulation_files .= ", " if $simulation_files;
1023 $simulation_files .= $filename;
1028 return $synthesis_files;
1038 sub main
1041 push(@ARGV,"--verbose=1") if 0;
1042 my %args = fcu_parse_args(@ARGV);
1044 if(0)
1046 foreach my $key (sort(keys(%args)))
1048 print("--$key = $args{$key} \n");
1053 # | get the arguments we care about
1056 my $class_dir = fcu_get_switch(\%args,"module_lib_dir");
1059 my $target_module_name = fcu_get_switch(\%args,"target_module_name");
1060 my $system_name = fcu_get_switch(\%args,"system_name");
1061 my $sopc_directory = fcu_get_switch(\%args,"sopc_directory");
1064 # | preflight the arguments a little
1067 my $error_count = 0;
1069 my $class_ptf_path = "$class_dir/class.ptf";
1070 if(!-f $class_ptf_path)
1072 print "error: no class.ptf at \"$class_dir\"\n";
1073 $error_count++;
1076 die "$error_count errors" if($error_count > 0);
1078 # +-------------------------------------------
1079 # | ok, let us get to work
1083 my $class_ptf = new_ptf_from_file($class_ptf_path);
1086 # | emit system.h for this module
1087 # | TODO iff Is_CPU i guess.
1090 my $do_emit_system_h = get_data_by_path($class_ptf,
1091 "CLASS/CB_GENERATOR/emit_system_h");
1092 if($do_emit_system_h)
1094 emit_system_h($sopc_directory,
1095 $target_module_name,
1096 "./$system_name.ptf");
1099 my $top_module_name = get_data_by_path($class_ptf,
1100 "CLASS/CB_GENERATOR/top_module_name");
1101 my $file_name = "";
1103 # | stored as file_name.v:module_name, so we break it open
1104 if($top_module_name =~ /^(.*):(.*)$/)
1106 $file_name = $1;
1107 my $module_name = $2;
1108 $top_module_name = $module_name;
1111 # | language of this particular module...
1113 my $module_language = "verilog";
1114 if($file_name =~ /^.*\.vhd$/)
1116 $module_language = "vhdl";
1120 # | consult the CB_GENERATOR/HDL_FILES section regarding
1121 # | where our HDL files for synthesis are.
1125 my $synthesis_files = get_synthesis_files($class_ptf);
1128 my $instantiate_in_system_module = get_data_by_path($class_ptf,
1129 "CLASS/MODULE_DEFAULTS/SYSTEM_BUILDER_INFO/Instantiate_In_System_Module");
1133 if($instantiate_in_system_module)
1135 generator_enable_mode ("terse");
1138 generator_begin (@ARGV);
1141 generator_make_module_wrapper(1,$top_module_name,$module_language);
1143 generator_copy_files_and_set_system_ptf
1145 "simulation_and_quartus",
1146 split(/ *, */,$synthesis_files)
1147 # "$synthesis_files"
1150 generator_end ();
1153 exit (0);
1156 $| = 1; # always polite to flush.
1157 main()
1159 # end of file