📄 generate_ddr_sim_model.pl
字号:
#Copyright (C)1991-2002 Altera Corporation
#Any megafunction design, and related net list (encrypted or decrypted),
#support information, device programming or simulation file, and any other
#associated documentation or information provided by Altera or a partner
#under Altera's Megafunction Partnership Program may be used only to
#program PLD devices (but not masked PLD devices) from Altera. Any other
#use of such megafunction design, net list, support information, device
#programming or simulation file, or any other related documentation or
#information is prohibited for any other purpose, including, but not
#limited to modification, reverse engineering, de-compiling, or use with
#any other silicon devices, unless such use is explicitly licensed under
#a separate agreement with Altera or a megafunction partner. Title to
#the intellectual property, including patents, copyrights, trademarks,
#trade secrets, or maskworks, embodied in any such megafunction design,
#net list, support information, device programming or simulation file, or
#any other related documentation or information provided by Altera or a
#megafunction partner, remains with Altera, the megafunction partner, or
#their respective licensors. No other licenses, including any licenses
#needed under any third party's intellectual property, are provided herein.
#Copying or modifying any file, or portion thereof, to which this notice
#is attached violates this copyright.
use europa_all;
use strict;
# This model tries to leverage as many functions and GUI similarities as
# possible from Aaron Ferrucci's sdram_controller.pm. The actual
# generated code and pin interface is quite different, but all the
# parameters and restrictions of generic SDRAM still apply...
### NB: &one_hot_encoding now in europa_utils.pm!
### NB: str2hex routine now in europa_utils.pm!
sub convert_times
{
my ($WSA, $time_values) = @_;
my $sys_clk = $WSA->{system_clock_rate};
for my $k (keys %{$time_values})
{
$WSA->{$k} .= $time_values->{$k};
convert_time_unit(\$WSA->{$k}, $sys_clk);
}
} # &convert_times
# Convert stuff like
#
# 15.625us
# 100us
# 70ns
# 120us
# 20ns
# 2clocks
# 20ns
# 17ns
# 1clock+7ns
#
# into CLOCKS (rounded up), and return in the input value.
sub convert_time_unit
{
my ($valRef, $system_clock_rate) = @_;
my $result = $$valRef;
my $system_clock_period = 1 / $system_clock_rate;
$result =~ s/ms/*(1e-3)/g;
$result =~ s/us/*(1e-6)/g;
$result =~ s/ns/*(1e-9)/g;
$result =~ s/clock[s]?/*($system_clock_period)/g;
# create result in seconds:
$result = eval($result);
# convert result from seconds into clocks:
$result = ceil ($result * $system_clock_rate);
# print "em_sdram.pm/convert_time_unit:\t$$valRef\t=\t$result clocks\n";
if ($@)
{
ribbit("failed to eval '$$valRef' in convert_time_unit(): '$@'");
}
$$valRef = $result;
} # & convert_time_unit
sub get_time_values
{
# This table gives the units that apply to each WSA parameter.
return (
refresh_period => "us",
powerup_delay => "us",
t_rfc => "ns",
t_mrd => "clocks",
t_rp => "ns",
t_rcd => "ns",
t_ac => "ns",
t_wr => "ns",
init_nop_delay => "us",
);
} # &get_time_values
# replicate_bit(width, value)
#
# e.g.
# replicate(4, 0) returns "4'b0000'".
sub replicate_bit
{
# width has to be only decimal digits, and non-zero.
my $width = shift
or ribbit("Usage error: no width! ".
"(expected 'replicate_bit(width, value)')\n");
$width =~ /^\d+$/ or die "Unexpected width: '$width'\n";
# value must be 0 or 1.
my $value = shift;
ribbit("Usage error: bad value '$value'!\n")
if $value !~ /^[01]$/;
ribbit("Usage error: too many parameters! ".
"(expected 'replicate_bit(width, value)')\n") if @_;
$value =~ /^\d+$/ or die "Unexpected value: '$value'\n";
return $width . "'b" . ($value x $width);
} # &replicate_bit
# Main DDR simulation model.
sub make_ddr_sim_model
{
# No arguments means "Ignore -- I'm being called from make".
if (!@_)
{
# print "\n\tmake_sdram_controller now uses a static".
# " external 'class.ptf'!\n\n";
return 0; # make_class_ptf();
}
# TEW: Get SDRAM's project, Options, etc:
my $project = e_project->new(@_);
my %Options = %{$project->WSA()};
my $WSA = \%Options;
# Grab the module that was created during handle_args.
my $module = $project->top();
# Grab some args to determine how to proceed, like model_base and init_file
$WSA->{is_blank}=($WSA->{sim_Kind} =~ /^blank/i) ? "1" : "0";
$WSA->{is_file} =($WSA->{sim_Kind} =~ /^textfile/i) ? "1" : "0";
my $textfile = $WSA->{sim_Textfile_Info};
#turn bar/foo.srec relative path into an absolute one if needed
my $system_directory = $project->_system_directory();
$textfile =~ s/^(\w+)(\\|\/)/$system_directory$2$1$2/;
#turn foo.srec to absolute path
$textfile =~ s/^(\w+)$/$system_directory\/$1/;
$WSA->{textfile}= $textfile;
# Figure out where our contents are coming from:
$WSA->{Initfile} = $project->_target_module_name() . "_contents.srec";
my $do_generation = $project->system_ptf()->{WIZARD_SCRIPT_ARGUMENTS}{do_build_sim};
# Only generate model if "Simulation. Create simulator..." is ticked.
if ($do_generation == 1) {
print "# Creating memory simulation model for use with ".$project->_target_module_name()."\n";
# We only accept .mif- and .srec-files (or just blankness)
&ribbit ("Memory-initialization files must be either .mif or .srec.\n",
" not '$WSA->{Initfile}'\n")
unless $WSA->{Initfile} =~ /\.(srec|mif)$/i;
# Figure out what language we're generating for
my $lang = $project->system_ptf()->{WIZARD_SCRIPT_ARGUMENTS}{hdl_language};
my $extension;
my $sim_file = $project->get_top_module_name();
my $sim_dat = $project->_target_module_name() . ".dat";
if ($lang =~ /vhd/i ) {
$sim_file .= ".vhd";
$extension = ".vhd";
}
if ($lang =~ /verilog/i) {
$sim_file .= ".v";
$extension = ".v";
}
my @write_lines;
# Add datapath and other files to simulation list
my $sopc_device_family = lc($project->system_ptf()->{WIZARD_SCRIPT_ARGUMENTS}{device_family_id});
my $device_family = lc($WSA->{MEGACORE}{NETLIST_SECTION}{STATIC_SECTION}{PRIVATES}{NAMESPACE}{parameterization}{PRIVATE}{family}{value});
#if ($sopc_device_family ne $device_family) { print "WARNING! The device selected in SOPC Builder (".$sopc_device_family.") does match the DDR SDRAM device (".$device_family.")\n";}
#print "SOPC Builder device family is ".$sopc_device_family."\n";
#print "DDR Megacore device family is ".$device_family."\n";
my $wrapper_name = $project->_target_module_name();
my $quartus_directory = $project->get_quartus_rootdir();
#print "Quartus came from ".$quartus_directory." and device family is $device_family\n";
#print "Wrapper file name is ".$wrapper_name.$extension."\n";
#print "\nOriginal files list = ".$project->module_ptf()->{HDL_INFO}{Simulation_HDL_Files}."\n";
my $magic_proj_dir = "__PROJECT_DIRECTORY__/";
my $datapath_files = "";
# SOPC Builder treats Stratix II & Stratix II GX as different families but we don't...
if ($sopc_device_family eq "stratixiigx") {
$sopc_device_family = "stratixii";
}
# SOPC Builder now treats Stratix & Stratix GX as different families (it didn't used to!) but we don't...
if ($sopc_device_family eq "stratixgx") {
$sopc_device_family = "stratix";
}
# Simulation libraries required
$project->module_ptf()->{HDL_INFO}{Simulation_Library_Names} = "auk_ddr_user_lib,";
#$project->module_ptf()->{HDL_INFO}{Simulation_Library_Names} .= "UNUSED";
$project->module_ptf()->{HDL_INFO}{Simulation_Library_Names} .= "$sopc_device_family";
if ($sopc_device_family eq "cycloneii")
{
$datapath_files .= $quartus_directory."/eda/sim_lib/cycloneii_atoms".$extension.",";
if ($lang =~ /vhd/i) {$datapath_files .= $quartus_directory."/eda/sim_lib/cycloneii_components.vhd,"; }
}
if ($sopc_device_family eq "cyclone")
{
$datapath_files .= $quartus_directory."/eda/sim_lib/cyclone_atoms".$extension.",";
if ($lang =~ /vhd/i) {$datapath_files .= $quartus_directory."/eda/sim_lib/cyclone_components.vhd,"; }
}
# SOPC Builder treats StratixII & StratixII GX as different so we have made the names the same for now
if ($sopc_device_family eq "stratixii")
{
$datapath_files .= $quartus_directory."/eda/sim_lib/stratixii_atoms".$extension.",";
if ($lang =~ /vhd/i) {$datapath_files .= $quartus_directory."/eda/sim_lib/stratixii_components.vhd,"; }
}
# SOPC Builder treats StratixII & StratixII GX as different so we have made the names the same for now
if ($sopc_device_family eq "stratix")
{
$datapath_files .= $quartus_directory."/eda/sim_lib/stratix_atoms".$extension.",";
if ($lang =~ /vhd/i) {$datapath_files .= $quartus_directory."/eda/sim_lib/stratix_components.vhd,"; }
}
# Now add the files needed for the datapath itself
$datapath_files .= $magic_proj_dir.$wrapper_name."_auk_ddr_dqs_group".$extension.",";
$datapath_files .= $magic_proj_dir.$wrapper_name."_auk_ddr_clk_gen".$extension.",";
$datapath_files .= $magic_proj_dir.$wrapper_name."_auk_ddr_datapath".$extension.",";
if ($lang =~ /vhd/i) {$datapath_files .= $magic_proj_dir.$wrapper_name."_auk_ddr_datapath_pack.vhd,";}
$project->module_ptf()->{HDL_INFO}{Simulation_HDL_Files} = $datapath_files.$project->module_ptf()->{HDL_INFO}{Simulation_HDL_Files};
#print "Updated files list = ".$project->module_ptf()->{HDL_INFO}{Simulation_HDL_Files}."\n";
#print "Create libraries called = ".$project->module_ptf()->{HDL_INFO}{Simulation_Library_Names}."\n";
#--------------------------------------------------------
# Create a shortcut to the right bit of the DDR's PTF
my %myshortcut = %{$WSA->{MEGACORE}{NETLIST_SECTION}{STATIC_SECTION}{PRIVATES}{NAMESPACE}{parameterization}};
my $wizard_shortcut = \%myshortcut;
#--------------------------------------------------------
# Work out whether this should be DDR1 or DDR2
my $memtype = $wizard_shortcut->{PRIVATE}{gMEM_TYPE}{value};
#print "This is a ".$memtype." controller\n";
my $mem_pretty_name = "DDR SDRAM";
if ($memtype eq "ddr2_sdram") {$mem_pretty_name = "DDR2 SDRAM";}
my $default_pin_prefix = "ddr_";
if ($memtype eq "ddr2_sdram") {$default_pin_prefix = "ddr2_";}
my $local_burst_length = $wizard_shortcut->{PRIVATE}{local_burst_length}{value};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -