📄 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 program
my $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");
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;
}
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},
});
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)
# |
# | dvb2004
my @e_hdl_parameters; # list of e_parameters
my $class_ptf = generator_get_class_ptf_handle();
my $hdl_parameter_definitions_ptf = get_child_by_path($class_ptf,"CLASS/COMPONENT_BUILDER/HDL_PARAMETERS");
my $hdl_parameter_count = get_child_count($hdl_parameter_definitions_ptf,"HDL_PARAMETER");
my $module_language = $generator_hr->{wrapper_args}{module_language};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -