⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 em_sdram.pm

📁 SDRAM Controller For Altera SOPC Builder and NIOS on DE2 kit board
💻 PM
📖 第 1 页 / 共 5 页
字号:
                my $refresh_counter_reload_value = $WSA->{refresh_period} - 1;        my $init_countdown_value = $WSA->{powerup_delay} + $WSA->{init_nop_delay};    my $refresh_counter_width =     Bits_To_Encode(max($refresh_counter_reload_value, $init_countdown_value));        $module->add_contents        (         e_signal->new({             name => "refresh_counter",             width => $refresh_counter_width,         }),         e_process->new         ({             comment => " Refresh/init counter.",             contents =>                  [                  e_if->new({                      condition => "(refresh_counter == 0)",                      then => [e_assign->new({                          lhs => "refresh_counter",                          rhs => $refresh_counter_reload_value,                      })],                      else => [e_assign->new({                          lhs => "refresh_counter",                          rhs => "refresh_counter - 1'b1",                      })],                  }),                  ],             asynchronous_contents =>                  [                  e_assign->new({                      lhs => "refresh_counter",                      rhs => $init_countdown_value                      }),                  ],          }),         );        $module->add_contents        (         e_register->new({             comment   => " Refresh request signal.",             in        => "((refresh_counter == 0) | refresh_request)".                 " & ~ack_refresh_request & init_done",             out       => e_signal->new({name => "refresh_request"}),             enable    => undef,         })         );    $module->add_contents        (         e_register->new({             comment   => " Generate an Interrupt if two ref_reqs occur before one ack_refresh_request",             in        => "(refresh_counter == 0) & refresh_request",             out       => e_signal->new({name => "za_cannotrefresh",                                         never_export => 1}),             enable    => undef,             })         );    my @signals = ("i_cmd", "m_cmd");    foreach my $signal (@signals)    {        $module->add_contents            (e_signal->new({name => "$signal",                            width => 3 + $num_chipselects }));    }    @signals = ("i_addr", "m_addr");    foreach my $signal (@signals)    {        $module->add_contents            (e_signal->new({name => "$signal",                            width => $WSA->{sdram_addr_width}}));    }        my ( $I_RESET, $I_PRECH, $I_WAIT,  $I_ARF,   $I_LMR,   $I_INIT) =        ("3'b000", "3'b001", "3'b011", "3'b010", "3'b111", "3'b101");    $module->add_contents(                          e_signal->new({                              name => "init_done",                          }),                          e_register->new({                              comment => " Initialization-done flag.",                              in => "init_done | (i_state == $I_INIT)",                              out => "init_done",                              enable => undef,                          })                          );    my ($LMR,$REFRESH,$PRECHARGE,$ACTIVE,$WRITE,$READ,$BURST,$NOP,$INHIBIT) =       ("3'h0","3'h1","3'h2",   "3'h3", "3'h4","3'h5","3'h6","3'h7","3'h7");    my $ALL = "{".$num_chipselects."{1'b0}}";    my $NONE= "{".$num_chipselects."{1'b1}}";        my $none_and_inhibit = replicate_bit(3 + $num_chipselects, 1);    my $MRD = "{{".($WSA->{sdram_addr_width} - 10).        "{1'b0}},1'b0,2'b00,3'h".$WSA->{cas_latency}.",4'h0}";    @signals = ("i_state", "i_next");    foreach my $signal (@signals)    {        $module->add_contents            (e_signal->new({name => "$signal", width => 3}));    }        my $initfsm_counter_width =        Bits_To_Encode(max($trp, $trfc, $tmrd, $trcd, $twr));        $module->add_contents        (e_signal->news         (          {name => "i_count", width => $initfsm_counter_width},          {name => "i_refs",  width => 3},          )         );        my %i_contents_hash =        (         $I_RESET => [                      e_assign->news                      (                       ["i_cmd"  => $none_and_inhibit],                       ["i_refs" => "3'b0"],                       ),                      e_if->new                      ({                          comment => "Wait for refresh count-down after reset",                          condition => "refresh_counter == 0",                          then => ["i_state" => $I_PRECH],                      }),                      ],         $I_PRECH => [                      e_assign->news                      (                       ["i_state"=>$I_WAIT],                       ["i_cmd"  =>"{".$ALL.",".$PRECHARGE."}"],                       ["i_count"=>$trp],                       ["i_next" =>$I_ARF],                       ),                      ],         $I_ARF   => [                      e_assign->news                      (                       ["i_cmd"  => "{".$ALL.",".$REFRESH."}"],                       ["i_refs" => "i_refs + 1'b1"],                       ["i_state"=> $I_WAIT],                       ["i_count"=> $trfc],                       ),                      e_if->new                      ({                          comment => " Count up init_refresh_commands",                          condition => "i_refs == 3'h".                              ($WSA->{init_refresh_commands} - 1),                          then => ["i_next" => $I_LMR],                          else => ["i_next" => $I_ARF],                      }),                      ],         $I_LMR   => [                      e_assign->news                      (                       ["i_state"  => $I_WAIT],                       ["i_cmd"    => "{".$ALL.",".$LMR."}"],                       ["i_addr"   => $MRD],                       ["i_count"  => $tmrd],                       ["i_next"   => $I_INIT],                       ),                      ],         $I_INIT  => [i_state => $I_INIT],         default  => [i_state => $I_RESET],         );    my $i_next_waitlist = [];        if ($tristate_bridge_mode == 0)    {        $i_next_waitlist =             [             e_assign->new(["i_cmd" => "{".$ALL.",".$NOP."}"]),             e_if->new             ({                 comment => "WAIT til safe to Proceed...",                 condition => "i_count > 1",                 then => ["i_count", "i_count - 1'b1"],                 else => ["i_state", "i_next"],             }),             ],    }    else    {        $i_next_waitlist =            [             e_if->new             ({                 comment => " wait for tz_waitrequest",                 condition => "!tz_waitrequest",                 then =>                     [                      e_assign->new(["i_cmd" => "{".$ALL.",".$NOP."}"]),                      e_if->new                      ({                          comment => "WAIT til safe to Proceed...",                          condition => "i_count > 1",                          then => ["i_count", "i_count - 1'b1"],                          else => ["i_state", "i_next"],                      }),                      ],             }),             ];    }        $i_contents_hash{$I_WAIT} = $i_next_waitlist;    $module->add_contents        (         e_process->new         ({             comment => " **** Init FSM ****",             asynchronous_contents =>                  [                  e_assign->news                  (                   ["i_state"  => $I_RESET],                   ["i_next"   => $I_RESET],                   ["i_cmd"    => $none_and_inhibit],                   ["i_addr"   => "{".$WSA->{sdram_addr_width}."{1'b1}}"],                   ["i_count"  => "{".$initfsm_counter_width."{1'b0}}"],                   ),                  ], # end async_contents             contents =>                 [                  e_assign->news                  (                   ["i_addr"    => "{".$WSA->{sdram_addr_width}."{1'b1}}"],                   ),                  e_case->new                  ({                      switch => "i_state",                      parallel => 1,                      full => 1,                      contents => {%i_contents_hash},                  }),                  ],            # end contents         }),                    # end process         );                     # end add_contents    my $num_main_fsm_states;    my ($M_IDLE, $M_RAS, $M_WAIT,$M_RD, $M_WR, $M_REC, $M_PRE, $M_REF,$M_OPEN);    if ($tristate_bridge_mode == 1)    {        $num_main_fsm_states = 8;        ($M_IDLE, $M_RAS, $M_WAIT, $M_RD, $M_WR, $M_REC, $M_PRE, $M_REF) =            &one_hot_encoding($num_main_fsm_states);    }    else    {        $num_main_fsm_states = 9;        ($M_IDLE,$M_RAS,$M_WAIT,$M_RD,$M_WR,$M_REC,$M_PRE,$M_REF,$M_OPEN)=            &one_hot_encoding($num_main_fsm_states);    }    @signals = ("m_state", "m_next");    foreach my $signal (@signals)    {        $module->add_contents            (e_signal->new({name => "$signal",                       width => Bits_To_Encode((2**$num_main_fsm_states)-1)}));    }    $module->add_contents       # uses same values as initfsm_counter_width        (e_signal->new({name => "m_count", width => $initfsm_counter_width}));            if ($WSA->{sdram_bank_width} == 1)    {        $module->add_contents            (             e_assign->new             (["active_bank"=> "active_addr[$bottom_bank_addr]"]),             );    }    else    {        $module->add_contents            (             e_assign->new             (["active_bank"=>                "{active_addr[$top_bank_addr],active_addr[$bottom_bank_addr]}"]),             );    }    $module->add_contents        (         e_assign->news         (          ["csn_match"  => "active_cs_n == f_cs_n"],          ["rnw_match"  => "active_rnw == f_rnw"],          ["bank_match" => "active_bank == f_bank"],          ["row_match"  =>           "{active_addr[$top_row_addr:$bottom_row_addr]} == ".           "{f_addr[$top_row_addr:$bottom_row_addr]}"],          ),         e_assign->new         (          ["pending" =>           "csn_match && rnw_match && bank_match && row_match && !f_empty"],          ),         );    my $cas_pad = $WSA->{sdram_addr_width} - ($WSA->{sdram_col_width} + 1);    my $cas_pad_expression;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -