5 / 5 (1 vote cast)
Page creation - November 11th 2010
Altera offers several external memory controller IPs that use the Avalon interface specification on the local side, this is the interface that is connected to the user's logic. One of the signals in the interface is an output "local_ready" which lets the user logic know if the controller is ready to accept a transfer command, or if it is busy and thus the user logic must wait. A common issue with the local_ready signal is it permanently goes low preventing any further commands from being accepted by the controller, effectively resulting in the controller being "locked up". This article will examine a common cause of this lock up, how to debug why it is occurring and how to fix it. A Quartus project using HPCII and UniPHY with a modified driver is attached to demonstrate the issue in a real simulation as a reference.
Design files are located here.
The table below lists the specifications for this design:
|Quartus version||QuartusII v10.1b141a (customer beta)|
|Kit||Stratix IV GX FPGA Development kit (DK-DEV-4SGX230N/C2)|
|Memory device||DDR3 (Micron MT41J64M16LA-15E)|
|Memory topology||single component, x16|
|IP used||UniPHY with HPCII and generated example top Quartus project and modified driver|
The external memory controller output "local_ready" goes low indicating the controller is busy. However it never goes high again effectively locking up the controller and preventing any further accesses.
The most common cause of this issue is illegal accesses to the controller from the driver/user logic. In particular, a bursts of writes was requested but not all beats of that write were provided to the controller before another command was requested. As the controller waits for the missing write beat, it's command fifo will fill up with other commands (usually reads) and once full it will de-assert local_ready. At this point nothing can start the controller again other than a reset.
The following diagram shows the correct waveform for an Avalon MM write which is the interface specification used by Altera's external memory controller IP. Note that beginbursttransfer must go high for only one clock cycle when the command is being requested and all beats of the write burst (in this case 4) are presented to the slave. Also note that the Avalon specification uses "waitrequest", this signal is called "local_ready" on Altera external memory controller IP and has the inverse behavior.
Avalon_MM_write_waveform.JPG (Click here for image)
Determining if a write burst is incomplete at one particular point in a design can be difficult. Two signals from the controller's command FIFO can be used to assess if a write beat was missed.
These signals are located in the file
<IP instance name>/<>_controller/<>_alt_ddrx_controller_inst/<>_state_machine_inst
Monitor these signals in simulation or using Signal Tap on hardware at the timestamp were local_ready is stuck low. If enough_data_to_write is stuck low and proper_beats_in_fifo is stuck at a value that is not zero (probably 1) then this indicates that the FIFO is requiring more data at some point. This data can then be used to go back in time and find the point when a write burst was incomplete. This may of occurred significantly earlier and thus it may be easier to add a counter in the user logic to track each write beat entering the controller. An example debug is provided in the next section.
Below is a Modelsim Wave screen capture of this issue occurring with Altera's HPCII and UniPHY IP. The simulation shows all write and read accesses to the controller. The example_top project generated by the IP was used and the driver was changed with one that drives the controller illegally as described above. Click here for full resolution image.
Local_ready_issue_with_altera_EMI_IP.jpg (Click here for image)
The driver is designed to do 8 writes, each having a burst length of 4, followed by 16 read requests. After 5 reads local_ready has gone low and doesn't go high again.
Using the timestamp at the bottom on the image the following is a list of events occurring in the simulation
Using this information it seems likely that there was a problem with the final write burst. If we look at this write between the driver and the controller earlier in the simulation (43.81us) it's obvious to see that this write only has 3 beats before the driver starts issuing read requests. To assist in this a counter was added to the driver to count the write bursts, counting down to zero during each burst, here however it stops at 1 implying 1 beat is still required. The controller will fill the command FIFO with these reads until it can't accept any further commands and then de-asserts local_ready.
Examining the driver code its likely there is a problem when it switches from write to read. This is the case here where the change in state is occurring 1 cycle too early. Fixing this behavior results is a full write being issued and the system simulates as expected
UniPHY, HPCII, DDR3, Design Example, External Memory, local_ready, local ready, local side interface, controller
© 2010 Altera Corporation. The material in this wiki page or document is provided AS-IS and is not
supported by Altera Corporation. Use the material in this document at your own risk; it might be, for example, objectionable,
misleading or inaccurate.Retrieved from http://www.alterawiki.com/wiki/Altera_Wiki