📄 em_sdram.pm
字号:
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 where all [ 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, 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->new(["m_state" => $M_OPEN]), ], # 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, 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_OPEN]), ], # end !pending }), # end if pending ]; # end WR $m_contents_hash{$M_OPEN} = [ e_assign->new(["m_cmd" => "{csn_decode,".$NOP."}"]), e_if->new ({ comment => "if we need to ARF, bail, else spin", condition => "refresh_request", then => $m_refresh_recovery_list, # end refresh_req else => # !refresh_req [ # determine one of 3 basic outcomes: e_if->new ({ comment => "wait for fifo to have contents", condition => "!f_empty", then => [ e_if->new ({ comment => "Are we 'pending' yet?", condition => "csn_match && rnw_match && bank_match && row_match", then => # go back where you came from: [ e_assign->news ( {lhs => "m_state", rhs => "f_rnw ? ".$M_RD." : ".$M_WR}, ["f_pop" => "1'b1"], {lhs => "active_cs_n", rhs => "f_cs_n"}, {lhs => "active_rnw", rhs => "f_rnw"}, {lhs => "active_addr", rhs => "f_addr"}, {lhs => "active_data", rhs => "f_data"}, {lhs => "active_dqm", rhs => "f_dqm"}, ), ], else => $m_open_recovery_list, # close row }), ], }), # end ~fifo_empty ], # end !refresh_req }), # end if refresh_req ]; # end state M_OPEN } # end optimize for direct control of SDRAM pins my $i_am_verilog; if ($lang =~ /verilog/i) { $i_am_verilog = 1; } else { $i_am_verilog = 0; } $module->add_contents ( e_signal->news ( {name => "m_bank", width => $WSA->{sdram_bank_width}}, {name => "m_addr", width => $WSA->{sdram_addr_width}}, {name => "m_data", width => $WSA->{sdram_data_width}}, {name => "m_dqm", width => $dqm_width}, ), e_process->new ({ comment => " **** Main FSM ****", output_as_muxes_and_registers => (1 - $tristate_bridge_mode), fast_output_names => ["m_cmd", "m_bank", "m_addr", "m_data", "m_dqm"], fast_enable_names => ["oe","m_data"], asynchronous_contents => [ e_assign->news ( ["m_state" => $M_IDLE], ["m_next" => $M_IDLE], ["m_cmd" => $none_and_inhibit], ["m_bank" => replicate_bit($WSA->{sdram_bank_width}, 0)], ["m_addr" => replicate_bit($WSA->{sdram_addr_width}, 0)], ["m_data" => replicate_bit($WSA->{sdram_data_width}, 0)], ["m_dqm" => replicate_bit($dqm_width, 0)], ["m_count" => replicate_bit($initfsm_counter_width, 0)], ["ack_refresh_request" => "1'b0"], ["f_pop" => "1'b0"], ["oe" => "1'b0"], ), ], # end async_contents contents => [ e_assign->news ( ["f_pop" => "1'b0"], ["oe" => "1'b0"], ), e_case->new ({ switch => "m_state", parallel => 1, full => 1, default_sim => $i_am_verilog, contents => {%m_contents_hash}, }), # end case ], # end process-contents }), # end process ); # end add_contents my $latency = $cas_latency; if ($tristate_bridge_mode) { my $bridge = &get_bridge_slave_sbi($project); my $bridge_reg_out = $bridge->{Register_Outgoing_Signals}; my $bridge_reg_in = $bridge->{Register_Incoming_Signals}; $latency += $bridge_reg_out; $latency += $bridge_reg_in; } $module->add_contents ( e_signal->new({name => "rd_valid", width => $latency}), e_assign->new(["rd_strobe" => "m_cmd[2:0] == $READ"]), ); my $rd_strobe = ""; if ($latency > 1) { $rd_strobe = "{ {".($latency - 1)."{1'b0}}, rd_strobe }"; $module->add_contents ( e_process->new ({ comment => "Track RD Req's based on cas_latency w/shift reg", asynchronous_contents => [ e_assign->new({lhs => "rd_valid", rhs => "{".$latency."{1'b0}}"}), ], # end async_contents contents => [ e_assign->new({lhs => "rd_valid", rhs => "(rd_valid << 1) | ".$rd_strobe}), ], }), ); } else { $module->add_contents ( e_process->new ({ comment => "Track RD Req's based on cas_latency w/shift reg", asynchronous_contents => [ e_assign->new({lhs => "rd_valid", rhs => "1'b0"}), ], # end async_contents contents => [ e_assign->new({lhs => "rd_valid", rhs => "rd_strobe"}), ], }), ); } if ($WSA->{register_data_in}) { if ($tristate_bridge_mode == 1) { $module->add_contents( e_register->new({ comment => " Register dq data.", in => "tz_data", out => "za_data", fast_in => 1, enable => 1, }), e_register->new({ comment => " Delay za_valid to match registered data.", in => "rd_valid[".($latency - 1)."]", out => "za_valid", enable => undef, }), ); } else { $module->add_contents( e_register->new({ comment => " Register dq data.", in => "zs_dq", out => "za_data", fast_in => 1, enable => 1, }), e_register->new({ comment => " Delay za_valid to match registered data.", in => "rd_valid[".($latency - 1)."]", out => "za_valid", enable => undef, }), ); } } else { if ($tristate_bridge_mode == 1) { $module->add_contents ( e_assign->news ( ["za_valid" => "rd_valid[".($latency -1)."]"], ["za_data" => "tz_data"], ), ); } else { $module->add_contents ( e_assign->news ( ["za_valid" => "rd_valid[".($latency - 1)."]"], ["za_data" => "zs_dq"], ), ); } } my $STR_INH = &str2hex ("INH"); if ($tristate_bridge_mode == 0) { $module->add_contents(e_assign->new(["cmd_code" => "m_cmd[2:0]"]),); $module->add_contents ( e_signal->new({name => "cmd_all", width => ($num_chipselects + 3)}), e_assign->new(["cmd_all" => "m_cmd"]), ); } else { $module->add_contents ( e_signal->new({name => "cmd_all", width => ($num_chipselects + 3)}), e_assign->news (["cmd_code" => "init_done ? m_cmd[2:0] : i_cmd[2:0]"], ["cmd_all" => "init_done". " ? {m_qualified_csn,m_cmd[2:0]}". " : {m_qualified_csn,i_cmd[2:0]}"]), ); } $module->add_contents ( # Simulation only process to set text code of cs/ras/cas/we e_signal->new
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -