?? 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) = (@_);
&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;
}
# |
# | recognize varous number forms,
# | return 'h0123abcd-ish.
# |
sub turn_anything_into_appropriate_string($$$)
{
my ($value,$type,$editable) = (@_);
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
$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($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");
for(my $i = 0; $i < $hdl_parameter_count; $i++)
{
my $a_parameter = get_child($hdl_parameter_definitions_ptf,$i,"HDL_PARAMETER");
my $boring_name = get_data($a_parameter); # legal guinevere-ized
my $name = get_data_by_path($a_parameter,"parameter_name"); # original HDL name
my $default = get_data_by_path($a_parameter,"default_value");
my $type = get_data_by_path($a_parameter,"type");
$type = "integer"; # !!!!!
if($default =~ /^\"(.*)\"$/)
{
my $slv_width = length($1);
my $slv_top = $slv_width - 1;
my $slv_bottom = 0;
$type = "std_logic_vector($slv_top downto $slv_bottom)";
} # !!!!!
my $a_parameter = e_parameter->new
({
name => $name,
default => $default,
type => $type
});
push (@e_hdl_parameters,$a_parameter);
}
# | and @e_hdl_parameters is used below in the wrappee module
# +--------------------------------------------
# +--------------------------------------------
# | Now, we build a "hdl_parameter_map", which is just
# | your basic hash table with keys (parameters)
# | and values (parameter values).
# |
# | these are the particular values for this instance.
# |
my %hdl_parameter_map;
my $module_ptf = $generator_hr->{module_ptf_hr};
my $hdl_parameters_ptf =
get_child_by_path($module_ptf,"WIZARD_SCRIPT_ARGUMENTS/hdl_parameters");
my $child_count = get_child_count($hdl_parameters_ptf);
for(my $i = 0; $i < $child_count; $i++)
{
my $a_parameter = get_child($hdl_parameters_ptf,$i);
my $boring_name = get_name($a_parameter);
my $value = get_data($a_parameter);
# refer back to the original HDL name...
my $parameter_definition_ptf = get_child_by_path($hdl_parameter_definitions_ptf,"HDL_PARAMETER $boring_name");
my $parameter_name = get_data_by_path($parameter_definition_ptf,"parameter_name");
my $parameter_type = get_data_by_path($parameter_definition_ptf,"type");
my $parameter_editable = get_data_by_path($parameter_definition_ptf,"editable");
$value = turn_anything_into_appropriate_string($value,$parameter_type,$parameter_editable);
$hdl_parameter_map{$parameter_name} = $value;
}
my $wrapee_module;
$wrapee_module = e_module->new({
name => $top_module_name,
contents => [@ports,@e_hdl_parameters],
do_black_box => 0,
do_ptf => 0,
_hdl_generated => 1,
_explicitly_empty_module => 1,
});
$top->add_contents (
e_instance->new({
module => $wrapee_module,
parameter_map => \%hdl_parameter_map
}),
);
$project->top()->do_ptf(0);
$project->do_write_ptf(0);
my $module_file = $project->_target_module_name().".v";
$module_file = $project->_target_module_name().".vhd"
if($language eq "vhdl");
$module_file = $generator_hr->{project_path_widget}."/".$module_file;
&generator_set_files_in_system_ptf("Synthesis_HDL_Files", ($module_file));
$project->output();
# if you don't want a simulation model, you don't get a simulation model
if($no_black_box eq "0")
{
my $black_project = e_project->new(@external_args);
$black_project->_target_module_name($top_module_name);
my $black_top = $black_project->top();
$black_top->add_contents(@ports);
my $black_top_instance;
$black_top_instance = e_module->new({
name => $wrapper_args->{top_module_name}."_bb",
contents => [@ports],
do_black_box => 1,
do_ptf => 0,
_hdl_generated => 0,
_explicitly_empty_module => 1,
});
$black_top->add_contents (
e_instance->new({
module => $black_top_instance,
}),
);
$black_project->top()->do_ptf(0);
$black_project->do_write_ptf(0);
my $black_module_file = $black_project->_target_module_name().".v";
$black_module_file = $black_project->_target_module_name().".vhd"
if($language eq "vhdl");
$black_module_file = $generator_hr->{project_path_widget}."/".$black_module_file;
&generator_set_files_in_system_ptf("Simulation_HDL_Files", ($black_module_file));
# &set_data_by_path($module_ptf_hr, "HDL_INFO/Simulation_HDL_Files", $black_module_file);
$black_project->output();
}
}
####
# Args: $file_type : "synthesis", "synthesis_only", "simulation"
# @file_list : an array of files. This list of files is assumed to be relative to the
# component's directory
my $decoder_ring_hr = {
quartus_only => {
copy => 1,
copy_to => "project",
ptf_set => 0,
},
simulation_only => {
copy => 1,
copy_to => "simulation",
ptf_set => 1,
ptf_section => "Simulation_HDL_Files",
},
simulation_and_quartus => {
copy => 1,
copy_to => "project",
ptf_set => 1,
ptf_section => "Synthesis_HDL_Files",
},
precompiled_simulation_files => {
copy => 0,
ptf_set => 1,
ptf_section => "Precompiled_Simulation_Library_Files",
},
};
sub generator_copy_files_and_set_system_ptf
{
my ($hdl_section, @file_list) = (@_);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -