Jump to content
  • 0

Nexys Video MIG 7 not calibrating


wyingst

Question

Hello all,

I've been working on an audio looping project which requires DDR3 memory for audio sample storage. After setting up the MIG-7 according to the Nexys Video Reference Sec 3.1 and reading through the 7 Series FPGAs Memory Interface Solutions User Guide, I'm at a loss for why the memory component won't initialize. I'm including a link to my repo here, but I'll try to explain my implementation in detail below:

Clocking: Using the settings recommended here by @elodg, I set up an IBUFG in my top level file, feeding a clk_wiz instantiation in the file containing my MIG. This also involved setting up a clock backbone route in my constraint file.

Instantiation: I've been instantiating my MIG with inputs set to 0 (except clocks) and outputs left open, just trying to get that init_calib_complete signal to go high.

    clk1 : clk_wiz_0
        port map ( 
        -- Clock out ports  
        clk_out1 => clk_ref,
        -- Status and control signals
        resetn => reset_n,
        -- Clock in ports
        clk_in1 => sys_clk_ibufg);
    
    u_mig_7 : mig_7
    port map (
        -- Memory interface ports
        ddr3_addr                      => ddr3_addr,
        ddr3_ba                        => ddr3_ba,
        ddr3_cas_n                     => ddr3_cas_n,
        ddr3_ck_n                      => ddr3_ck_n,
        ddr3_ck_p                      => ddr3_ck_p,
        ddr3_cke                       => ddr3_cke,
        ddr3_ras_n                     => ddr3_ras_n,
        ddr3_reset_n                   => ddr3_reset_n,
        ddr3_we_n                      => ddr3_we_n,
        ddr3_dq                        => ddr3_dq,
        ddr3_dqs_n                     => ddr3_dqs_n,
        ddr3_dqs_p                     => ddr3_dqs_p,
        init_calib_complete            => init_calib_complete,
        ddr3_odt                       => ddr3_odt,
        -- Application interface ports
        app_addr                       => app_addr,
        app_cmd                        => app_cmd,
        app_en                         => app_en,
        app_wdf_data                   => app_wdf_data,
        app_wdf_end                    => app_wdf_end,
        app_wdf_mask                   => (others => '0'),
        app_wdf_wren                   => app_wdf_wren,
        app_rd_data                    => app_rd_data,
        app_rd_data_end                => open,
        app_rd_data_valid              => open,
        app_rdy                        => open,
        app_wdf_rdy                    => open,
        app_sr_req                     => '0',
        app_ref_req                    => '0',
        app_zq_req                     => '0',
        app_sr_active                  => open,
        app_ref_ack                    => open,
        app_zq_ack                     => open,
        ui_clk                         => open,
        ui_clk_sync_rst                => open,
        -- System Clock Ports
        sys_clk_i                      => sys_clk_ibufg,
        -- Reference Clock Ports
        clk_ref_i                      => clk_ref,
        sys_rst                        => reset_n
    );

Constraints: I have one user constraint file bringing in the 100MHz clock from the board as well as buttons, switches, leds, and the audio codec signals for debugging and other functionality. It's attached to this post.

MIG setup wizard settings:

image.thumb.png.37bfdc1c799d589628c7ba19793daae4.png

image.thumb.png.0d1127497007d94401db01b95e629011.png

image.thumb.png.e61598986ea27f44f7918cf91b0f301e.png

image.thumb.png.b3c0c4e5dd82a8dccf42ab56e26b008c.png

image.thumb.png.947431785d8da01756d4d6ace6827a7c.png

image.thumb.png.bf24708dcd92ae32cdabd8d61464b06c.png

image.thumb.png.d8bd894c61c2829b1908e130c86a82ab.png

image.thumb.png.bf68375bb79b7bb5d3d11b9208540d02.png

image.thumb.png.f2dc6cf2e0dcf01b3aabf03e024aca81.png

image.png.1fe9060849c65734748a8d8607721049.png

 

image.thumb.png.89d9b269f1431952440adc93ad31aff0.png

 

If anyone has experience with using this MIG or any clocking expertise, please let me know. I've been banging my head against this just hoping for a calibration, and I would really appreciate your help.

Thank you!

Link to comment
Share on other sites

11 answers to this question

Recommended Posts

@wyingst,

Your MIG configuration looks good.  I didn't check the actual pinout --- but I'll trust you on that for now.  A couple of comments:

  1. It looks like you are pulling the system reset into your design from an external port, but without guaranteeing that it is A) valid for at least a couple of clock ticks, and b) has a synchronized release.  Xilinx I/O primitives can be finicky about this.
  2. While this isn't your current problem, it will be your next problem: When using the MIG controller, you need to use the clock that comes out of it for your design.  (Not for the reset in the last step--lest you get yourself into a loop)  So, your logic should run off of ui_clk and ui_clk_sync_rst rather than clk100 and reset_n.

Hope that gets you closer,

Dan

Link to comment
Share on other sites

-- convert board reset into sys_clk_ibufg domain
process(sys_clk_ibufg)
begin
    if rising_edge(sys_clk_ibufg) then
        sreg <= sreg(0) & reset_n;
        sys_rst <= sreg(1);
    end if;
end process;

Here's an attempt at synchronizing the reset.

Link to comment
Share on other sites

@wyingst,

No, that's not a proper reset synchronizer, and you'll want to use clk100.  If I remember right, the reset into the core also resets the PLLs that then generate the system clocks ... so you can't synchronize the reset using something that will be cleared on a reset (the clock).

You can find an example of a VHDL asynchronous reset synchronizer among the sunburst design papers by Clifford Cummings.  Check out page 16-17 of this paper for a good example.

Dan

Link to comment
Share on other sites

For all the forum users who might find this post ... @wyingst was able to get the DDR3 SDRAM working.  Some key lessons learned:

  • The reset into the MIG core needs to be initially set and then synchronously released with the clock input to the core
  • External resets, such as those from buttons, need to be synchronized before use.  Even better, they should be debounced, but debouncing wasn't (yet) the issue.
  • The design that uses the MIG core needs to use the clock and synchronous reset outputs from the core for its logic, not the clock that was sent into the core.  (This wasn't yet he bug, but it was going to be next.)

Dan

Link to comment
Share on other sites

Clarifying:

I ended up taking on-board clock through a clk_wiz module using a MMCM to generate a 100MHz and 200MHz output. I reconfigured the MIG to accept a system clock frequency of 200 MHz "no buffer," and to use that system clock also as the reference clock for IDELAY stuff. 

The main and most fundamental bug was not synchronizing my reset from the on-board button into the 200MHz clock domain for use as MIG reset. Once I did that I started getting signs of life. Still working on read/write, if anyone else is working on something like this feel free to message me.

Link to comment
Share on other sites

@wyingst,

Thanks for the clarification!  I was afraid you'd vanish and not complete the story ;)

You are using the native interface to the core.  I haven't used that interface (yet), so I don't have good working examples of how it works.  All my stuff uses the bloated AXI interface.  If you or someone else manages to build a good example of how that native interface works or should work, I'd love to review it.  I just find the specification of the native interface to be light on details.

Dan

Link to comment
Share on other sites

29 minutes ago, D@n said:

If you or someone else manages to build a good example of how that native interface works or should work, I'd love to review it.

Better yet build one. Avoid AXI unless absolutely necessary; to me this means ARM based device designs. Most Xilinx IP can be used with native interfaces suitable for HDL designs. Sometimes this comes with an additional design burden, but the effort is well worth the trouble. For the Mig this generally means creating read and write state machines to connect user logic to the external memory controller. Some FPGA devices have a nice multi-channel hard memory controller block to replace the soft-controller outputs generated by the IP. Spartan 6 and Cyclone V are two that I'm familiar with.The hard controller blocks require user state machines and sometimes additional FIFO instantiation as well.

One place to look for hints is the example design project. You can open the project file as a new project. Ive yet to run into an FPGA vendor who wants to help users who choose to go their own way instead of following along in the 'board design flow' figure this stuff out. I wonder why this is? (the last question is completely rhetorical sarcasm as I think that I know the answer). 

Opal Kelly is one board vendor who does supply a stand-alone external memory demo for it's board but you have to be a registered user, and perhaps but a board, to get the sample sources. They have an odd niche in the FPGA development board space but I have done projects using their hardware and FrontPanel framework with success.

Oh and for what it's worth. If you are going to reset your MMCM or PLL understand the implications of doing so.

Link to comment
Share on other sites

Memory update: great success!

The working configuration that I will be sticking with for this project involves a slight deviation from the Nexys Video Reference recommended settings. Instead of a 100 MHz system clock and independently provided 200 MHz reference clock, I opted for a 200 MHz system clock (no buffer) with the reference clock set to use system clock internally. This simplified all of the clocking confusion since I only needed one clk_wiz instantiation and no IBUFG stuff. 

The rest of the bugs sprung up when working between different clock domains. All of the memory-related FSM structure and processes should be using the ui_clk which the IP itself generates. All inputs from the user or other components working at different frequencies (such as the audio codec, in my case) must be brought across the clock domain divide carefully. Additionally, the asynchronous button reset_n on the board had to be set up with a synchronous return to ensure the memory got started well.

Check out my repo if you're interested in seeing my code.

If you're having trouble with this component please drop me a line, and definitely definitely definitely read the document linked below, or you won't make it very far.

MIG-7 Reference Guide

Link to comment
Share on other sites

7 hours ago, wyingst said:

Instead of a 100 MHz system clock and independently provided 200 MHz reference clock, I opted for a 200 MHz system clock (no buffer) with the reference clock set to use system clock internally.

This change didn't do anything for you. The rest of your design can be any clock frequency that is appropriate. I suggest that you carefully review the Seried7 Clocking User's Guide. I't important to understand how clocking works and the rules for using MMCMs and buffers with clocks. You can certainly use the Mig generated IP as constructed or start ripping into it and mucking around, but you can use the source without modification. I'm not sure what you mean by no buffer but I'm betting that if you bring up the RTL view of your design you will see that Vivado inferred one despite what your source code says. I do agree with your other conclusions about clock domains and reset conditioning. It is not unusual for an FPGA design to have 3-4 clock domains in it. Best to understand how to make them all get along in a way that the tools understand.

I heartily agree with the advice to read any IP literature available especially for something as complicated as a DDR controller.

Link to comment
Share on other sites

@zygot,

The "no buffer" setting is part of the MIG set up.  It has to deal with whether or not you are passing raw clock signals straight from the input pins to the core and so the core should instantiate a buffer, or whether the wire has already been through a buffer and so the MIG IP doesn't need to instantiate one.  Since I've always passed my clock signals from a PLL (under my own control) to the MIG, I've always had to set the "no buffer" flag.  Incidentally, if you don't set "no buffer", it wants to know what pins to connect the clocks to directly.  It's not the clearest interface out there, but it's what we've got to work with for the time being.

Dan

Link to comment
Share on other sites

24 minutes ago, D@n said:

It's not the clearest interface out there

Can't argue with that. I interpreted 'system clock' as referring to the main clock for the user's design independent of the Mig infrastructure. It's easy to misunderstand the intended inference of a posting. I suppose that all advice posted to these forums should come with a disclaimer that point out the possibility that it might be best ignored... seems counter-productive to me.

I'm familiar with the Mig IP and happen to be working, among others, on a design requiring one at the moment..It's amazing how little change this IP has undergone throughout the years relative to other IP.

Whether a buffer, or latch, or other primitive gets instantiated either by design or inference is all by itself an interesting topic. It's not until you get bitten that your interest gets focused on it.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...