📄 em_sdram.pm
字号:
width => $WSA->{sdram_data_width}}), e_port->new({name => "zt_data", width => $WSA->{sdram_data_width}, direction => "output"}), e_port->new({name => "zt_dqm", width => $dqm_width, direction => "output"}), e_port->new({name => "zt_addr", width=>$WSA->{sdram_addr_width}, direction => "output"}), e_port->new({name => "zt_ba", width=>$WSA->{sdram_bank_width}, direction => "output"}), e_port->new({name => "zt_oe", direction => "output"}), e_port->new({name => "zt_cke", direction => "output"}), e_port->new({name => "zt_we_n", direction => "output"}), e_port->new({name => "zt_cas_n", direction => "output"}), e_port->new({name => "zt_ras_n", direction => "output"}), e_port->new({name => "zt_cs_n", width => $num_chipselects, direction => "output"}), e_port->new({name => "zt_lock_n", direction => "output"}), e_port->new({name => "tz_readdatavalid"}), ); if ($starvation_int == 1) { push @port_list, ( e_port->new({name => "za_cannotrefresh", # type => "irq", direction => "output"}), ); } my @sideband_signals = qw (sdram_bank sdram_ras_n sdram_cas_n sdram_we_n sdram_cs_n sdram_clockenable); $module->add_contents( e_avalon_master->new({ name => 'tristate_master', sideband_signals => \@sideband_signals, SBI_section => { Address_Width => $tpm_addr_width, Data_Width => $WSA->{sdram_data_width}, Is_Enabled => 1, Is_Visible => 0, }, type_map => { tz_readdatavalid => 'readdatavalid', tz_waitrequest => 'waitrequest', tz_data => 'readdata', zt_data => 'writedata', zt_dqm => 'byteenable_n', zt_addr => 'address', zt_cke => 'sdram_clockenable', zt_ba => 'sdram_bank', zt_we_n => 'sdram_we_n', zt_cas_n => 'sdram_cas_n', zt_ras_n => 'sdram_ras_n', zt_oe => 'write', zt_cs_n => 'sdram_cs_n', zt_lock_n => 'arbiterlock_n', zt_chipselect => 'chipselect', }, })); } else { push @port_list, ( e_port->new({name => "zs_dq", type => undef, width => $WSA->{sdram_data_width}, direction => "inout"}), e_port->new({name => "zs_dqm", type => undef, width => $dqm_width, direction => "output"}), e_port->new({name => "zs_ba", type => undef, width=>$WSA->{sdram_bank_width},direction => "output"}), e_port->new({name => "zs_addr", type => undef, width => $tpm_addr_width, direction => "output"}), e_port->new({name => "zs_cke", type => undef, direction => "output"}), e_port->new({name => "zs_ras_n", type => undef, direction => "output"}), e_port->new({name => "zs_cas_n", type => undef, direction => "output"}), e_port->new({name => "zs_we_n", type => undef, direction => "output"}), e_port->new({name => "zs_cs_n", type => undef, width => $num_chipselects, direction => "output"}), ); } $module->add_contents(@port_list); my %type_map = (); my $temp_name; for (@port_list) { if (defined ($_->type())) { $temp_name = $_->name(); if ($_->type() !~ /^tpm_/) { $type_map{$temp_name} = $_->type(); } } } $module->add_contents( e_avalon_slave->new({ name => "s1", #$module->name()."_s1", type_map => \%type_map, }) ); if ($tristate_bridge_mode == 1) { my %shared_type_map = (); for (@port_list) { if (defined ($_->type())) { $temp_name = $_->{name}; if ($_->type() =~ /^tpm_/) { $shared_type_map{$temp_name} = $_->{type}; } } } if ($num_chipselects == 1) { $module->add_contents ( e_assign->news ( ["m_csn" => "init_done ? m_cmd[3] : i_cmd[3]"], ["m_qualified_csn" => "m_csn | tz_waitrequest"], ), ); } else # more than 1 chipselect... { $module->add_contents ( e_signal->new(["m_qualified_csn" => $num_chipselects]), e_assign->news ( ["m_csn" => "init_done". " ? m_cmd[".(2+$num_chipselects).":3]". " : i_cmd[".(2+$num_chipselects).":3]"], ["m_qualified_csn" => "m_csn | {".$num_chipselects."{tz_waitrequest}}"], ), ); } $module->add_contents ( e_assign->news ( ["zt_addr" => "init_done ? m_addr : i_addr"], ["zt_cke" => "clk_en"], ["zt_data" => "m_data"], ["zt_dqm" => "m_dqm"], ["zt_ba" => "m_bank"], ["zt_oe" => "oe"], ["zt_we_n" => "init_done ? m_cmd[0] : i_cmd[0]"], ["zt_cas_n" => "init_done ? m_cmd[1] : i_cmd[1]"], ["zt_ras_n" => "init_done ? m_cmd[2] : i_cmd[2]"], ["zt_cs_n" => "m_qualified_csn"], ["zt_lock_n" => "&m_csn"], ["zt_chipselect" => "~zt_lock_n"], ), ); } else { $module->add_contents ( e_assign->news ( ["{zs_cs_n, zs_ras_n, zs_cas_n, zs_we_n}" => "m_cmd"], ["zs_addr" => "m_addr"], ["zs_cke" => "clk_en"], ["zs_dq" => "oe?m_data:{".$WSA->{sdram_data_width}."{1'bz}}"], ["zs_dqm" => "m_dqm"], ["zs_ba" => "m_bank"], ), ); } my ($top_bank_addr, $bottom_bank_addr, $top_row_addr, $bottom_row_addr, $top_col_addr, $bottom_col_addr); if ($WSA->{sdram_bank_width} == 1) { $top_bank_addr = $controller_addr_width; # NOT USED! $bottom_bank_addr= $WSA->{sdram_col_width}; $top_row_addr = $controller_addr_width - ($num_chipselect_address_bits + 1); $bottom_row_addr = $WSA->{sdram_col_width} + 1; $top_col_addr = $WSA->{sdram_col_width} - 1; $bottom_col_addr = 0; } else { $top_bank_addr = $controller_addr_width - 1 - $num_chipselect_address_bits; $bottom_bank_addr= $WSA->{sdram_col_width}; $top_row_addr = $controller_addr_width - 2 - $num_chipselect_address_bits; $bottom_row_addr = $top_row_addr - $WSA->{sdram_addr_width} + 1; $top_col_addr = $WSA->{sdram_col_width} - 1; $bottom_col_addr = 0; } $module->add_contents ( e_signal->new(["f_select"]), e_assign->new(["f_select" => "f_pop & pending"]), ); my $csn_for_refresh; if ($num_chipselect_address_bits > 0) { # for multiple chipselects, set up real compare/decode $module->add_contents ( e_signal->news ( {name => "f_cs_n", width => $num_chipselect_address_bits}, {name => "active_cs_n", width => $num_chipselect_address_bits}, {name => "cs_n", width => $num_chipselect_address_bits}, {name => "csn_decode", width => $num_chipselects}, ), e_assign->news({lhs => "{f_rnw, f_cs_n, f_addr, f_dqm, f_data}", rhs => "fifo_read_data"}), e_assign->new(["cs_n" => "f_select ? f_cs_n : active_cs_n"]), ); foreach my $select (0 .. ($num_chipselects - 1)) { $module->add_contents ( e_assign->new ( {lhs =>"csn_decode[".$select."]", rhs =>"cs_n != ".$num_chipselect_address_bits."'h".$select}, ), ); } $csn_for_refresh = "{".$num_chipselect_address_bits."{1'b1}}"; } else { # for 1 chipselect (no address bits), compare/decode is trivial: $module->add_contents ( e_assign->news ( ["f_cs_n" => "1'b0"], ["cs_n" => "f_select ? f_cs_n : active_cs_n"], ["csn_decode" => "cs_n"], ), e_assign->new({lhs => "{f_rnw, f_addr, f_dqm, f_data}", rhs => "fifo_read_data"}), ); $csn_for_refresh = "1'b1"; } $module->add_contents ( e_signal->news ( {name => "f_addr", width => $controller_addr_width - $num_chipselect_address_bits, }, {name => "active_addr", width => $controller_addr_width - $num_chipselect_address_bits, }, {name => "f_data", width => $WSA->{sdram_data_width}}, {name => "active_data", width => $WSA->{sdram_data_width}}, {name => "f_dqm", width => $dqm_width}, {name => "active_dqm", width => $dqm_width}, {name => "f_bank", width => $WSA->{sdram_bank_width}}, {name => "active_bank", width => $WSA->{sdram_bank_width}}, {name => "fifo_read_data", width => ($controller_addr_width + $dqm_width + $WSA->{sdram_data_width} + 1)}, ), e_instance->new ({ # let this auto-name the instance: _module_name => e_efifo->new ({ name_stub => $module->name()."_input", data_width => 1 + $controller_addr_width + $dqm_width + $WSA->{sdram_data_width}, depth => 2, }), port_map => { "wr" => "(~az_wr_n | ~az_rd_n) & !za_waitrequest", "rd" => "f_select", "wr_data" => "{az_wr_n, az_addr, az_wr_n ? ${dqm_width}'b0 : az_be_n, az_data}", "rd_data" => "fifo_read_data", "empty" => "f_empty", "full" => "za_waitrequest", }, }), e_signal->news ( {name => "almost_full", never_export => 1}, {name => "almost_empty", never_export => 1}, ), ); if ($WSA->{sdram_bank_width} == 1) { $module->add_contents ( e_assign->new (["f_bank" => "f_addr[$bottom_bank_addr]"]), ); } else { $module->add_contents ( e_assign->new (["f_bank"=>"{f_addr[$top_bank_addr],f_addr[$bottom_bank_addr]}"]), ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -