I am implementing a DDR4 memory interface using the emif controller.The emif code is generated by QSYS, using Arria 10/10AX115N3F45E2SG on a NALLATECH 510T board. The design is basically working, the calibration success signal goes high, I never seen calibration fail on this board. Clock is running at 266MHz. Most memory access cycles are fine but sometimes I receive a wrong data value, the previous access cycle value. The problem is with the avs_waitrequest_n and avs_readdatavalid signals. All documentation shows nice clean signals, each cycle gets a nice avs_waitrequest_n pulse and avs_readdatavalid as required. When I capture these signals using Signaltap I dont see that. The avs_waitrequest_n signal pulses low twice in most cycles, sometimes it remains low for extended 30+ clock cycles. The avs_readdatavalid also pulses high multiple times for when performing a read of burstlenght 1. The attached image shows an example in which there are 4 read cycles. The first two cycles starting at t-825 and t-750 are completed and return the correct data. But the avs_waitrequest_n pulses low twice for each cycle and the avs_readdatavalid pulses high 5-10 times. The third cycle at t-550 shows the avs_waitrequest_n pulse low once followed by an extended low period which bleeds into the next cycle. This fourth cycle then fails be returning the data from the third cycle. The traces of the avs_waitrequest_n and avs_readdatavalid signals are registered versions of the signals, I didnt want to connect a probe directly. How come avs_waitrequest_n and avs_readdatavalid toggle like this? FPGA : Arria 10/10AX115N3F45E2SG Board : NALLATECH 510T DDR : DDR 4 Quartus : 16.0.2
Problem resolved, driver error.I created my own model for the memory controller and used it to verify the logic that drives the memory controller. I am using modelsim to verify my design which means I cant use the Avalon bus monitor to verify the correct behavior of the design because it uses features that are not supported by Modelsim. Which meant I was verifying a bus driver I designed with a model I designed. Not the way to go. My logic expected an active high avs_wait_request but QSYS generated a memory controller with a active low avs_wait_request_n port. But the design worked so I didn't think to investigate further. What is happening is that the memory controller accepts multiple read commands because the avs_read signal is kept high, but eventually cant accept anymore and drives the avs_wait_request_n port low. It will perform a read cycle to the DDR module for each read command it receives. This explains the multiple avs_readdatavalid pulses. The data is the same for all, so it doesn't toggle.