📄 em_sdram.pm
字号:
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 + -