cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
tobias.schmidt
Visitor
Visitor
799 Views
Registered: ‎01-28-2019

MIG7 DDR3 VC707 won't return from read

Jump to solution

Hello,

I want to use the ddr3 memory in my xilinx vc707 to store some data. I access the addresses randomly and in no specific order. After some time my memory controller does not return from a read operation. As far as I can tell the MIG-Controller does not send a r_app_rd_data_valid high signal and the state machine therefore stays in s_read (see code below).

Here is the part of my memory controller responsible for the communication with MIG-Controller (User Interface):

process(r_ui_clk, i_rst, r_ui_clk_sync_rst)
  begin
    if i_rst = '1' or r_ui_clk_sync_rst = '1' then
      r_app_en             <= '0';
      r_app_wdf_wren       <= '0';
      r_app_wdf_end        <= '0';
      r_ddr3_state         <= s_idle;
    elsif rising_edge(r_ui_clk) then
        case r_ddr3_state is
          when s_idle =>
            if r_init_calib_complete = '1' then
              if i_wr_enable = '1' then
                  r_app_wdf_data       <= io_data;
                  r_app_wdf_wren       <= '1';
                  r_app_wdf_end        <= '1';
                  r_ddr3_state         <= s_write_send_data;
              elsif i_rd_enable = '1' then
                  r_app_cmd            <= "001";
                  r_app_addr           <= "0" & i_address(23 downto 0) & "000";
                  r_app_en             <= '1';
                  r_ddr3_state         <= s_read;
              end if;
            end if;

          when s_write_send_data =>
            if r_app_wdf_rdy = '1' then
                r_app_wdf_end  <= '0';
                r_app_wdf_wren <= '0';
                r_app_cmd            <= "000";
                r_app_addr           <= "0" & i_address(23 downto 0) & "000";
                r_app_en             <= '1';
                r_ddr3_state <= s_write_send_command;
            else
                r_app_wdf_data       <= io_data;
                r_app_wdf_wren       <= '1';
                r_app_wdf_end        <= '1';
            end if;

          when s_write_send_command =>
            if r_app_rdy = '1' then
              r_app_en <= '0';
              r_ddr3_state <= s_idle;
            else
              r_app_cmd            <= "000";
              r_app_addr           <= "0" & i_address(23 downto 0) & "000";
              r_app_en             <= '1';
            end if;

          when s_read =>
            if r_app_rdy <= '1' then
              r_app_en <= '0';
            end if;
            if r_app_rd_data_valid = '1' then
              r_ddr3_state <= s_idle;
            end if;
        end case;
      end if;
  end process;


Any help is appreciated.  Thanks in advance.

0 Kudos
1 Solution

Accepted Solutions
ryana
Moderator
Moderator
733 Views
Registered: ‎11-28-2016

Hello @tobias.schmidt,
This happens when the app_interface is driven incorrectly.  My recommendation is to review the User Interface signals section of UG586 starting on page 92 of the latest version.  A link is in my signature.  Overall you need to have a better understanding of how to control the user interface signals and you also need to be aware that the command path is seperate from the write data path.  Take a look at the Command Path, Write Path, and Read Path section starting on page 167.  Also I would run the example design simulation and see how the test bench drives the app_interface.

View solution in original post

2 Replies
jg_bds
Scholar
Scholar
769 Views
Registered: ‎02-01-2013

I guess we should assume your DDR controller is running in 4:1 mode? What version of Vivado are you using?

When you say that you think the MIG is not asserting r_app_rd_data_valid, are you assuming that r_app_rdy was asserted to accept the read command, or do you actually see it being asserted?

An ILA trace would be nice, showing the hang-up. You can add a counter that increments in state s_read; trigger the ILA when the counter reaches a value of ~2x the normal read wait time. Then you can see the preceding bus activity that led to the hang-up.

As long as you're hamstringing the MIG with your state machine, clean-up the code to make it easier to follow--and easier to synthesize. e.g.:

==========================================================================

  when s_idle =>
    -- Update both of these here, and only here
    r_app_wdf_data       <= io_data;
    r_app_addr           <= "0" & i_address(23 downto 0) & "000";

    if r_init_calib_complete = '1' then
      if i_wr_enable = '1' then
          r_app_wdf_wren       <= '1';
          -- r_app_wdf_end     <= '1';  -- unneeded in 4:1; drive wdf_end with wdf_wren
          r_ddr3_state         <= s_write_send_data;
      elsif i_rd_enable = '1' then
          r_app_cmd            <= "001";
          r_app_en             <= '1';
          r_ddr3_state         <= s_read;
      end if;
    end if;

==========================================================================

-Joe G.

 

ryana
Moderator
Moderator
734 Views
Registered: ‎11-28-2016

Hello @tobias.schmidt,
This happens when the app_interface is driven incorrectly.  My recommendation is to review the User Interface signals section of UG586 starting on page 92 of the latest version.  A link is in my signature.  Overall you need to have a better understanding of how to control the user interface signals and you also need to be aware that the command path is seperate from the write data path.  Take a look at the Command Path, Write Path, and Read Path section starting on page 167.  Also I would run the example design simulation and see how the test bench drives the app_interface.

View solution in original post