I’m having trouble implementing an FPGA DDR4 EMIF on the Altera Arria10 Dev board. I can generate the emif example design (with the traffic generator etc) and that works fine. But when I try to implement the interface in my own project no such luck. I’m using the same emif parameters as the example project (using the presets panel) but I’m missing a step somewhere. My project synthesizes and the Fitter runs to completion, but the fitter throws off constraint warnings so I know I don’t have the constraints right.The emif is instantiated in a Qsys (or should I say Platform Designer) system and the emif readme file says “If you instantiate the IP as part of a Qsys system, follow the Qsys documentation on how to instantiate the system in a Quartus Prime project.” Not sure what documentation they’re referring to, but the example project works with just the qsys system added to the top level project so I thought that would be all I needed to do. Shouldn’t Quartus be able to find the constraints files from that? The External Memory Interface volume 3 (18.104.22.168.1 Adding Pins and DQ Group Assignments) talks about a pin_assignments.tcl file that should be in the synth folder, but I don’t find it there, and the readme file in the emif synth directory says it’s no longer necessary to run that manually anyway. “Unlike previous EMIF IP, there is no need to manually run a *_pin_assignments.tcl script to annotate the assignments into the project's .qsf file.” What am I missing? How is it nobody else has the same problem? I’m not really a noob to Quartus tools (I am to the emif though) I just don’t see clear documentation on the steps necessary to implement the FPGA EMIF in anything other than the example design. Any help will be appreciated.
While you don't have to run a pin_assignments.tcl script with Arria 10, you still have to make pin location assignments. Have you done that? The pin_assignments.tcl script is used to specify I/O related assignments, like voltage, drive strength, etc. The message you mention just indicates that with Arria 10, you don't have to run the script (while with older families, you still do). If you generated the example design for that specific dev kit, the pin location assignments were probably set for you. For your own project, you'd have to set them.If you're using Quartus Pro, you can use BluePrint (now known as Interface Planner) to set up the I/O. Otherwise, you have to manually create location assignments in the Pin Planner or Assignment Editor. What "constraint warnings" are you getting?
It doesn’t seem that a pin_assignments.tcl script was generated, but since I’m implementing my project on the dev board, I had already copied and pasted the assignments in the qsf file. I double checked those and they seem to match. Where is that tcl script supposed to end up anyway?I found that I had an extra sdc file in my project (from one of my earlier gyrations). Once I pulled that out I no longer had the constraint warnings. However, the emif still didn’t work. I added Signaltap to view some of the signals and saw that the local_cal_success signal wasn’t going high. There were no warning that I could see that lead to a solution though. Finally, I noticed that there were emif directories left over from my previous tries (same ip directories with a different unique value suffix). I deleted all of those, and recompiled. The compile took ~3 times longer, but now it’s working. I guess Quartus was running all of the tcl scripts that it could find and was plowing over the top of itself? I don’t know, but I’m on to the next hurdle! Thanks for your time and advice!
I am on a similar path as you. I am using the A10 SoC Devkit trying to get a handle on DDR4 use. i am using Quartus v17.0.2 and when I create the example design it runs fine and I can see sucessful reports in the EMIF toolkit, but in my program using the same DDR4 QSYS file I get no memory function. I am getting good timing closure (using the reference recommendations), but if I use SignalTap I can see that the emif_ready line never changes when I write or read (and of course my read result is always zeros).Any chance you can pass along a source_top file I can scan through as I am exhausting the reasonable project rebuild efforts here. Thanks,
Here's the EMIF portion of my top module:
//... Ports output wire user_emif_ck, output wire user_emif_ck_n, output wire user_emif_a, output wire user_emif_act_n, output wire user_emif_ba, output wire user_emif_bg, output wire user_emif_cke, output wire user_emif_cs_n, output wire user_emif_odt, output wire user_emif_reset_n, output wire user_emif_par, input wire user_emif_alert_n, inout wire user_emif_dqs, inout wire user_emif_dqs_n, inout wire user_emif_dq, inout wire user_emif_dbi_n, input wire user_emif_oct_rzqin, input wire user_emif_pll_ref_clk, output wire user_emif_status_local_cal_fail, output wire user_emif_status_local_cal_success //... // Connections in the soc instance .user_emif_interrupt_ctrl_ecc_user_interrupt (), .user_emif_mem_mem_ck (user_emif_ck ), .user_emif_mem_mem_ck_n (user_emif_ck_n ), .user_emif_mem_mem_a (user_emif_a ), .user_emif_mem_mem_act_n (user_emif_act_n ), .user_emif_mem_mem_ba (user_emif_ba ), .user_emif_mem_mem_bg (user_emif_bg ), .user_emif_mem_mem_cke (user_emif_cke ), .user_emif_mem_mem_cs_n (user_emif_cs_n ), .user_emif_mem_mem_odt (user_emif_odt ), .user_emif_mem_mem_reset_n (user_emif_reset_n ), .user_emif_mem_mem_par (user_emif_par ), .user_emif_mem_mem_alert_n (user_emif_alert_n ), .user_emif_mem_mem_dqs (user_emif_dqs ), .user_emif_mem_mem_dqs_n (user_emif_dqs_n ), .user_emif_mem_mem_dq (user_emif_dq ), .user_emif_mem_mem_dbi_n (user_emif_dbi_n ), .user_emif_oct_oct_rzqin (user_emif_oct_rzqin ), .user_emif_pll_ref_clk_clk (user_emif_pll_ref_clk), .user_emif_status_local_cal_success (user_emif_status_local_cal_success), .user_emif_status_local_cal_fail (user_emif_status_local_cal_fail),