📄 em_sdram.pm
字号:
#Copyright (C)2001-2004 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;use e_efifo;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_timessub 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; $result = eval($result); $result = ceil ($result * $system_clock_rate); if ($@) { ribbit("failed to eval '$$valRef' in convert_time_unit(): '$@'"); } $$valRef = $result;} # & convert_time_unitsub get_time_values{ 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_valuessub replicate_bit{ my $width = shift or ribbit("Usage error: no width! ". "(expected 'replicate_bit(width, value)')\n"); $width =~ /^\d+$/ or die "Unexpected width: '$width'\n"; 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_bitsub make_sdram_controller{ if (!@_) { return 0; # make_class_ptf(); } my $project = e_project->new(@_); my %Options = %{$project->WSA()}; my $WSA = \%Options; my $module = $project->top(); my $lang = $project->system_ptf()->{WIZARD_SCRIPT_ARGUMENTS}{hdl_language}; my $sim_model_base = $project->module_ptf()->{WIZARD_SCRIPT_ARGUMENTS}{sim_model_base}; if (!$sim_model_base) { my @write_lines = ( "", "This reference design requires a vendor simulation model.", "To simulate accesses to SDRAM, you must:", "\t - Download the vendor model", "\t - Install the model in the system_sim directory", ); if ($lang =~ /vhd/i) { push @write_lines, ( "\t - Add the vendor file to the list of files passed to 'vcom' in setup_sim.do" ); } elsif ($lang =~ /verilog/i) { push @write_lines, ( "\t - `include the vendor model in the the top-level system file,", ); } push @write_lines, ( "\t - Instantiate sdram simulation models and wire them to testbench signals", "\t - Be aware that you may have to disable some timing checks in the vendor model", "\t\t (because this simulation is zero-delay based)", "" ); map {$_ = e_sim_write->new({spec_string => $_ . '\\n'})} @write_lines; if (@write_lines) { my $init = e_initial_block->new({ tag => "simulation", contents => [ @write_lines, ], }); $module->add_contents($init); } $project->do_makefile_target_ptf_assignments ( '', [], ); delete $project->module_ptf()->{SIMULATION}{PORT_WIRING}; } # we have a non altera-sodimm sim_model_base... else { my $Opt = {name => $project->_target_module_name()}; $project->do_makefile_target_ptf_assignments ( 's1', ['dat', 'sym', ], $Opt, ); } $WSA->{system_clock_rate} = $project->get_module_clock_frequency(); &validate_parameter({ hash => $WSA, name => "sdram_data_width", type => "integer", allowed => [8, 16, 32, 64], }); &validate_parameter({ hash => $WSA, name => "sdram_bank_width", type => "integer", allowed => [1, 2], }); my $num_chipselects = $WSA->{sdram_num_chipselects}; my $num_chipselect_address_bits = log2($num_chipselects); &validate_parameter({ hash => $WSA, name => "sdram_num_chipselects", type => "integer", allowed => [1, 2, 4, 8], }); &validate_parameter({ hash => $WSA, name => "cas_latency", type => "integer", allowed => [0 .. 7], }); &validate_parameter({ hash => $WSA, name => "init_refresh_commands", type => "integer", allowed => [1 .. 8], }); ($WSA->{cas_latency} < 1 or $WSA->{cas_latency} > 3) and goldfish("weird CAS latency: '", $WSA->{cas_latency}, "'"); my $cas_latency = $WSA->{cas_latency}; my $controller_addr_width = $num_chipselect_address_bits + $WSA->{sdram_bank_width} + $WSA->{sdram_col_width} + $WSA->{sdram_row_width}; my %time_values = get_time_values(); convert_times($WSA, \%time_values); my $trp = $WSA->{t_rp} - 1; my $trfc = $WSA->{t_rfc} - 1; my $tmrd = $WSA->{t_mrd}; my $trcd = $WSA->{t_rcd}; my $twr = $WSA->{t_wr}; # This FSM does not do auto_precharge if (0 == $twr) { ribbit("T_WR = 0. Need to update ptf file?\n"); } my $dqm_width = $WSA->{sdram_data_width} / 8; if (int($dqm_width) != $dqm_width) { ribbit ( "Unexpected: SDRAM data width '", $WSA->{sdram_data_width}, "', ". "leads to non-integer DQM width ($dqm_width)" ); } $module->add_contents ( e_assign->new({ lhs => e_signal->new({name => "clk_en", never_export => 1}), rhs => 1, }) ); my @port_list = ( e_port->new({name => "clk", type => "clk",}), e_port->new({name => "reset_n", type => "reset_n",}), e_port->new({name => "az_cs", type => "chipselect",}), e_port->new({name => "az_rd_n", type => "read_n",}), e_port->new({name => "az_wr_n", type => "write_n",}), e_port->new({name => "az_be_n", type => "byteenable_n", width => $dqm_width}), e_port->new({name => "az_addr", type => "address", width => $controller_addr_width,}), e_port->new({name => "az_data", type => "writedata", width => $WSA->{sdram_data_width}}), e_port->new({name => "za_data", type => "readdata", width=>$WSA->{sdram_data_width},direction => "output"}), e_port->new({name => "za_valid", type => "readdatavalid", direction => "output"}), e_port->new({name => "za_waitrequest", type => "waitrequest", direction => "output"}), ); my $tpm_addr_width = $WSA->{sdram_addr_width}; my $tristate_bridge_mode = $WSA->{shared_data}; my $starvation_int = $WSA->{starvation_interrupt}; &make_tristate_module_ptf($project); if ($tristate_bridge_mode == 1) { push @port_list, ( e_port->new({name => "tz_waitrequest"}), e_port->new({name => "tz_data",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -