📄 cb_generator.pl
字号:
# | file: cb_generator.pl# |# | This SOPC Builder Generator program is provided by# | the Component Builder application. It is copied# | straight across and is data-driven from its command# | line arguments and the PTF files referenced.# |# | Its purpose is to construct an HDL "wrapper" for# | a particular instance of a particular SOPC Builder# | peripheral. This wrapper resolves the instance# | name and any HDL parameterization.# |# +-------------------------------------------# +-------------------------------------------# |use strict;use format_conversion_utils;use ptf_parse;use wiz_utils;use europa_all;use run_system_command_utils;# |# +-------------------------------------------# +-------------------------------------------# |# | first pass: include all of generator_libarary.pm RIGHT HERE.# | dvb04.08.02# | then prune down to actual functionality.# |# | TODO: Rewrite this whole file into something readable# | this is much more confusing than I'm comfortable with. dvb04.# | (though it does seem to work.)# |my $DEBUG_DEFAULT_GEN = 1;#This is the global hash of arguments passed in by the generator programmy $generator_hr = { wrapper_args => { make_wrapper => 0, top_module_name => "", simulate_hdl => 1, ports => "", }, class_ptf_hr => "", module_ptf_hr => "", system_ptf_hr => "", language => "", external_args => "", external_args_hr => "", project_path_widget => "__PROJECT_DIRECTORY__", generator_mode => "silent", };sub generator_print_verbose{ my ($info) = (@_); if($generator_hr->{generator_mode} eq "verbose"){ print("cb_generator.pl: ".$info); }}sub generator_enable_mode{ my ($mode) = (@_); $generator_hr->{generator_mode} = $mode;}sub generator_get_system_ptf_handle{ return $generator_hr->{system_ptf_hr};}sub generator_get_language{ return $generator_hr->{language};}sub generator_get_class_ptf_handle{ return $generator_hr->{class_ptf_hr};}sub default_ribbit{ my ($arg) = (@_); &ribbit("\n\n--Error: default_gen_lib: $arg\n"); }sub _copy_files{ my ($dest_dir, $source_dir, @files) = (@_); my $function_name; #validate args &default_ribbit("No target dir for function copy_files!") unless ($dest_dir ne ""); &default_ribbit("No source dir for function copy_files!") unless ($source_dir ne ""); &default_ribbit("No files for function copy_files!") unless (@files != 0); #check for valid directories opendir (SDIR, $source_dir) or &default_ribbit("can't open $source_dir !"); opendir (DDIR, $dest_dir) or &default_ribbit("can't open $dest_dir !"); foreach my $source_file(@files){ # | # | Separate out the source subdir and the source filename # | my $source_subdir = ""; my $source_filename = $source_file; if($source_filename =~ /^(.*)\/(.*)$/) # break on last slash { $source_subdir = "/$1"; # embed its leading slash, for concatty $source_filename = $2; } my $source_fullpath = "$source_dir$source_subdir/$source_filename"; my $dest_fullpath = "$dest_dir/$source_filename"; &Perlcopy($source_fullpath, $dest_fullpath); &generator_print_verbose("Copying file: \"$source_fullpath\"" . " to \"$dest_fullpath\".\n"); } closedir (SDIR); closedir (DDIR);}sub get_module_wrapper_arg_hash_from_system_ptf_file{ my $module_ptf_hr = $generator_hr->{module_ptf_hr}; my @list_of_sections = ("MASTER","SLAVE","PORT_WIRING"); my @port_list; foreach my $section(@list_of_sections){ my $number = get_child_count($module_ptf_hr, $section); for(my $initial=0; $initial < $number; $initial++){ my $interface_section = get_child($module_ptf_hr, $initial, $section); my $interface_section_name = get_data($interface_section); my $port_wiring_section; if($section ne "PORT_WIRING"){ $port_wiring_section = get_child_by_path($module_ptf_hr, $section." ".$interface_section_name."/PORT_WIRING"); }else{ $port_wiring_section = get_child_by_path($module_ptf_hr, $section); } my $num_ports = get_child_count($port_wiring_section, "PORT"); foreach(my $port_count = 0; $port_count < $num_ports; $port_count++){ my $port = get_child($port_wiring_section, $port_count, "PORT"); my %port_info_struct; $port_info_struct{name} = get_data($port); $port_info_struct{direction} = get_data_by_path($port, "direction"); $port_info_struct{width} = get_data_by_path($port, "width"); $port_info_struct{vhdl_record_name} = get_data_by_path($port, "vhdl_record_name"); $port_info_struct{vhdl_record_type} = get_data_by_path($port, "vhdl_record_type"); push(@port_list, \%port_info_struct); } } } $generator_hr->{wrapper_args}{ports} = \@port_list;}sub generator_make_module_wrapper{ my ($simulate_hdl, $top_module_name, $module_language) = (@_); &default_ribbit("generator_make_module_wrapper: no arg0 passed in for simulate_hdl\n") if($simulate_hdl eq ''); &default_ribbit("generator_make_module_wrapper: no arg1 passed in for top_module_name\n") unless($top_module_name); $generator_hr->{wrapper_args}{simulate_hdl} = $simulate_hdl; $generator_hr->{wrapper_args}{top_module_name} = $top_module_name; $generator_hr->{wrapper_args}{make_wrapper} = 1; $generator_hr->{wrapper_args}{module_language} = $module_language;}# |# | recognize varous number forms,# | return 'h0123abcd-ish.# |sub turn_anything_into_appropriate_string($$$$) { my ($value,$type,$editable,$module_language) = (@_); return $value if($value =~ /^\"/); # quoted string: unscathed return $value if($type eq "string"); # string: anything is ok return $value if(!$editable); # and you know, if you can't change it, keep it! # | # | first, convert to a number # | my $base = 10; my $n = $value; my $width = 32; my $number = 0; $value = lc($value); # lower case if($value =~ /^([0-9]*)\'([hbo])(.*)$/) { # | tick notation: AOK for verilog if($module_language eq "verilog") { $number = $value; } # | # | note: at this point, we could notice if the # | result should be vhdl binary, and convert # | to that, avoiding the precision-losing # | integer intermediary # | # | (alternatively, we could use a binary string # | always as the intermediate form, rather than # | a precision-losing int.) # | else { $width = $1; my $baseletter = $2; my $digits = $3; if($baseletter eq "h") { $base = 16; } elsif($baseletter eq "b") { $base = 2; } elsif($baseletter eq "o") # must be { $base = 8; } $digits =~ s/[ _-]//g; # crush out dividing value while(length($digits) > 0) { my $digit = substr($digits,0,1); $digits = substr($digits,1); my $digitvalue = hex($digit); # how handy $number = $number * $base + $digitvalue; } } } elsif($value =~ /^0x(.*)$/) { $number = hex($1); } else # try for decimal { $number = int(1 * $value); } # | # | ok, we have a number. If our target type # | is "std_logic_vector(this downto that)" # | for tricky VHDL, we # | must quote a binary string out of it. # | if(($module_language eq "vhdl") and ($type =~ /^.*\((\d+) downto (\d+)\).*$/)) { my ($high_bit,$low_bit) = ($1,$2); my $binary = ""; for(my $bit = $low_bit; $bit <= $high_bit; $bit++) { $binary = ($number % 2) . $binary; $number = int($number >> 1); } $number = '"' . $binary . '"'; } return $number; }## return @array of vhdl libraries, if any, from the class.ptfsub get_libraries(){ my $class_ptf = generator_get_class_ptf_handle(); my @libraries; my $libraries_ptf = get_child_by_path($class_ptf,"CLASS/CB_GENERATOR/LIBRARIES"); if($libraries_ptf) { my $library_count = get_child_count($libraries_ptf,"library"); for(my $i = 0; $i < $library_count; $i++) { my $library_ptf = get_child($libraries_ptf,$i,"library"); my $library_name = get_data($library_ptf); push(@libraries,$library_name); } } return @libraries;}sub _generator_make_module_wrapper { my $wrapper_args = $generator_hr->{wrapper_args}; my $no_black_box = $wrapper_args->{simulate_hdl}; my $top_module_name = $wrapper_args->{top_module_name}; my $language = $generator_hr->{language}; my @external_args = @{$generator_hr->{external_args}}; my $module_ptf_hr = $generator_hr->{module_ptf_hr}; ### Build Module my $project = e_project->new(@external_args); my $top = $project->top(); # add the ports to the system module my @ports; foreach my $port_hash(@{$wrapper_args->{ports}}){ my $porto = e_port->new({ name => $port_hash->{name}, width => $port_hash->{width}, direction => $port_hash->{direction}, vhdl_record_name => $port_hash->{vhdl_record_name}, vhdl_record_type => $port_hash->{vhdl_record_type} }); push(@ports, $porto); } $top->add_contents(@ports); # +---------------------------------------- # | Get parameters from class.ptf # | create @array of parameters, eacho # | one like name=>, default=>, type=>, # | # | These are the definitions of parameters for # | ANY instance of this module; we need to # | have them in the "wrapee" module so that # | when the system bus is knitted together # | the parameter types can be properly used. # | # | (as it turns out, verilog doesnt need # | them, but vhld does) # |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -