📄 em_sdram.pm
字号:
if ($cas_pad == 1) { $cas_pad_expression = "1'b0,"; } elsif ($cas_pad > 0) { $cas_pad_expression = "{$cas_pad\{1'b0}},"; } else { $cas_pad_expression = ""; } if ($WSA->{sdram_col_width} > 11) { $module->add_contents ( e_signal->new({name => "cas_addr", width => $WSA->{sdram_col_width} + 1}), e_assign->new ( { lhs => "cas_addr", rhs => "f_select ? {$cas_pad_expression f_addr[$top_col_addr:10],1'b0,f_addr[9:$bottom_col_addr] } : ". "{$cas_pad_expression active_addr[$top_col_addr:10],1'b0,active_addr[9:$bottom_col_addr] }" } ) ); } elsif ($WSA->{sdram_col_width} == 11) { $module->add_contents ( e_signal->new({name => "cas_addr", width => $WSA->{sdram_col_width} + 1}), e_assign->new ( { lhs => "cas_addr", rhs => "f_select ? {$cas_pad_expression f_addr[$top_col_addr],1'b0,f_addr[9:$bottom_col_addr] } : ". "{$cas_pad_expression active_addr[$top_col_addr],1'b0,active_addr[9:$bottom_col_addr] }" } ) ); } else { $cas_pad = $WSA->{sdram_addr_width} - $WSA->{sdram_col_width}; $module->add_contents ( e_signal->new({name => "cas_addr", width => $WSA->{sdram_col_width} }), e_assign->new ( { lhs => "cas_addr", rhs => "f_select ? { {".($cas_pad)."{1'b0}},f_addr[$top_col_addr:$bottom_col_addr] } : ". "{ {".($cas_pad)."{1'b0}},active_addr[$top_col_addr:$bottom_col_addr] }" } ) ); } my %m_contents_hash = ( $M_IDLE => [ # Note that the default IDLE cmd is INHIBIT (cs_ not asserted) e_if->new ({ comment => "Wait for init-fsm to be done...", condition => "init_done", then => [ e_if->new ({ comment=>"Hold bus if another cycle ended to arf.", condition => "refresh_request", then => [ e_assign->new (["m_cmd" => "{".$ALL.",".$NOP."}"]), ], else => [ e_assign->new (["m_cmd" => $none_and_inhibit]), ], }), e_assign->new(["ack_refresh_request" => "1'b0"]), e_if->new ({ comment => "Wait for a read/write request.", condition => "refresh_request", then => [ e_assign->news ( ["m_state" => $M_PRE], ["m_next" => $M_REF], ["m_count" => $trp], ["active_cs_n" => $csn_for_refresh], # for tristate... ), ], # end then elsif => { condition => "!f_empty", then => [ e_assign->news ( ["f_pop" => "1'b1"], ["active_cs_n" => "f_cs_n"], ["active_rnw" => "f_rnw"], ["active_addr" => "f_addr"], ["active_data" => "f_data"], ["active_dqm" => "f_dqm"], ["m_state" => $M_RAS] ), ], # end then }, # end elsif }), # end if ], # end init_done else => # !init_done [ e_assign->new(["m_addr" => "i_addr"]), e_assign->new(["m_state" => $M_IDLE]), e_assign->new(["m_next" => $M_IDLE]), e_assign->new(["m_cmd" => "i_cmd"]), ], # end !init_done }), ], # end IDLE $M_RAS => # Activate a row [ e_assign->news ( ["m_state" => $M_WAIT], ["m_cmd" => "{csn_decode,".$ACTIVE."}"], ["m_bank" => "active_bank"], ["m_addr" => "active_addr[$top_row_addr:$bottom_row_addr]"], ["m_data" => "active_data"], ["m_dqm" => "active_dqm"], ["m_count" => $trcd], ["m_next" => "active_rnw ? ".$M_RD." : ".$M_WR], ), ], # end RAS $M_REC => # Recover from RD or WR before going to PRECHARGE. [ # In essence, a special type of M_WAIT state e_assign->new(["m_cmd" => "{csn_decode,".$NOP."}"]), e_if->new ({ comment => "Count down til safe to Proceed...", condition => "m_count > 1", then => ["m_count" => "m_count - 1'b1"], else => [ e_assign->new(["m_state" => $M_PRE]), e_assign->new(["m_count" => $trp]), ], }), ], # end WAIT $M_PRE => # You must assign m_next/m_count before entering this [ e_assign->news ( ["m_state" => $M_WAIT], ["m_addr" => "{".$WSA->{sdram_addr_width}."{1'b1}}"] ), e_if->new ({ comment => " precharge all if arf, else precharge csn_decode", condition => "refresh_request", then => ["m_cmd" => "{".$ALL.",".$PRECHARGE."}"], else => ["m_cmd" => "{csn_decode,".$PRECHARGE."}"], }), ], # end PREcharge $M_REF => [ e_assign->new(["ack_refresh_request" => "1'b1"]), e_assign->new(["m_state" => $M_WAIT]), e_assign->new(["m_cmd" => "{".$ALL.",".$REFRESH."}"]), e_assign->new(["m_count" => $trfc]), e_assign->new(["m_next" => $M_IDLE]), ], # end REFresh default => [ e_assign->new(["m_state" => "m_state"]), e_assign->new(["m_cmd" => $none_and_inhibit]), e_assign->new(["f_pop" => "1'b0"]), e_assign->new(["oe" => "1'b0"]), ], ); my $m_open_recovery_list = []; my $m_refresh_recovery_list = []; my $m_max_recovery_time = (&max ( ($twr - 1), ($cas_latency - 2), 0 )); if ($m_max_recovery_time > 0) { $m_open_recovery_list = [ e_assign->news ( ["m_state" => $M_REC], ["m_next" => $M_IDLE], ["m_count" => $m_max_recovery_time], ), ]; $m_refresh_recovery_list=[ e_assign->news ( ["m_state" => $M_WAIT], ["m_next" => $M_IDLE], ["m_count" => $m_max_recovery_time], ), ]; } else { $m_open_recovery_list = [ e_assign->news ( ["m_state" => $M_PRE], ["m_next" => $M_IDLE], ["m_count" => $trp], ), ]; $m_refresh_recovery_list=[ e_assign->news ( ["m_state" => $M_IDLE], ), ]; } if ($tristate_bridge_mode == 1) { $m_contents_hash{$M_WAIT} = [ e_if->new ({ comment => " wait for tristate bridge", condition => "!tz_waitrequest", then => [ e_if->new ({ comment => " arf ? prechrg all : prechrg csn", condition => "(m_next == $M_REF)", then => ["m_cmd"=>"{".$ALL.",".$NOP."}"], else => ["m_cmd"=>"{csn_decode,".$NOP."}"], }), e_if->new ({ comment => " Count down til safe to Proceed...", condition => "m_count > 1", then => ["m_count" => "m_count - 1'b1"], else => ["m_state" => "m_next"], }), ], }), ]; # end WAIT $m_contents_hash{$M_RD} = # Read: this is the exciting state [ e_assign->news ( ["m_cmd" => "{csn_decode,".$READ."}"], ["m_bank" => "f_select ? f_bank : active_bank"], ["m_dqm" => "f_select ? f_dqm : active_dqm"], ["m_addr" => "cas_addr"], ), e_if->new ({ comment => "Do we have a transaction pending?", condition => "pending", then => [ e_if->new ({ comment => "if we need to arf, bail out, else spin", condition => "refresh_request", then => [ e_assign->news ( ["m_state" => $M_WAIT], ["m_next" => $M_IDLE], ["m_count" => ($cas_latency - 1)], ), ], # end refresh_req else => # !refresh_req [ # pop fifo, stay in same state! e_assign->news ( ["f_pop" => "1'b1"], ["active_cs_n" => "f_cs_n"], ["active_rnw" => "f_rnw"], ["active_addr" => "f_addr"], ["active_data" => "f_data"], ["active_dqm" => "f_dqm"], ), ], # end !refresh_req }), # end if refresh_req ], # end pending else => # !pending [ e_if->new ({ comment => "correctly end RD spin cycle if fifo mt", condition => "~pending & f_pop", then => ["m_cmd" => "{csn_decode,".$NOP."}"], }), e_assign->news ( ["m_state" => $M_REC], ["m_next" => $M_IDLE], ["m_count" => ($cas_latency - 1)], ), ], # end !pending }), # end if pending ]; # end RD $m_contents_hash{$M_WR} = # Write: this is the exciting state where [ e_assign->news ( ["m_cmd" => "{csn_decode,".$WRITE."}"], ["oe" => "1'b1"], ["m_data" => "f_select ? f_data : active_data"], ["m_dqm" => "f_select ? f_dqm : active_dqm"], ["m_bank" => "f_select ? f_bank : active_bank"], ["m_addr" => "cas_addr"], ), e_if->new ({ comment => "Do we have a transaction pending?", condition => "pending", then => [ e_if->new ({ comment => "if we need to ARF, bail out, else spin", condition => "refresh_request", then => [ e_assign->news ( ["m_state" => $M_WAIT], ["m_next" => $M_IDLE], ["m_count" => $twr], ), ], # end refresh_req else => # !refresh_req [ # pop fifo, stay in same state! e_assign->news ( ["f_pop" => "1'b1"], ["active_cs_n" => "f_cs_n"], ["active_rnw" => "f_rnw"], ["active_addr" => "f_addr"], ["active_data" => "f_data"], ["active_dqm" => "f_dqm"], ), ], # end !refresh_req }), # end if refresh_req ], # end pending else => [ e_if->new ({ comment => "correctly end WR spin cycle if fifo empty", condition => "~pending & f_pop", then => [ e_assign->news ( ["m_cmd" => "{csn_decode,".$NOP."}"], ["oe" => "1'b0"], ), ], }), e_assign->news ( ["m_state" => $M_REC], ["m_next" => $M_IDLE], ["m_count" => $twr], ), ], # end !pending }), # end if pending ]; # end WR } else # optimize for direct control of sdram pins (no tri-state sharing) { $m_contents_hash{$M_WAIT} = [ e_if->new ({ comment => " precharge all if arf, else precharge csn_decode", condition => "(m_next == $M_REF)", then => ["m_cmd" => "{".$ALL.",".$NOP."}"], else => ["m_cmd" => "{csn_decode,".$NOP."}"], }),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -