Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

axi_dma_wr seems to give done status before fully writing to DDR? #80

Open
abarajithan11 opened this issue Jul 16, 2024 · 6 comments
Open

Comments

@abarajithan11
Copy link

abarajithan11 commented Jul 16, 2024

On Zynq Ultrascale (ZCU 104), we are using axi_dma_wr to write to the off-chip DDR.
We set a register when m_axis_write_desc_status_valid & (m_axis_write_desc_status_error !=0).
From the C firmware running on the PS, we check for this register in a while loop, then flush the cache, and start processing the data in the DDR.

We found that doing this results in the final output being wrong. When we added sleep_us(0) after the while loop checking for that register, the final output is correct.

Therefore, it seems the DMA gives the done status before data gets fully written into off-chip DDR.
But in #13 you mention:

However, the DMA write module should not indicate that the operation is complete until all of the AXI write responses come back, otherwise you could get into a situation where you are operating on data that is not completely written (ask me how I know that....).

@alexforencich Does this mean the DMA should give the status after the data is fully written?

@alexforencich
Copy link
Owner

The only place the status output is set is here, in response to bvalid being set: https://github.com/alexforencich/verilog-axi/blob/master/rtl/axi_dma_wr.v#L771 . So yes, it should only indicate that the operation has completed after receiving the AXI write response. Is it possible that the AXI write response is not being generated correctly in your setup?

@alexforencich
Copy link
Owner

The other possibility could be reordering if multiple AXI operations were issued, but the core currently only uses ID 0 to prevent reordering.

@abarajithan11
Copy link
Author

abarajithan11 commented Jul 19, 2024 via email

@alexforencich
Copy link
Owner

The only thing the DMA module can look at is the B channel which carries the write response. What's supposed to happen is the write request and write data (AW and W channels) propagate the request through the interconnect to the destination (memory controller), then the destination responds with the write response that gets routed back to the DMA engine. In this way, the DMA engine will report that the operation is complete when it receives the write response. But it's possible that there is some intermediate component that generates the write response before the operation actually arrives at the memory controller, perhaps a cache or something similar. In this case, it is impossible for the DMA module to know when the operation has actually reached the memory controller. I thought the Zynq PS would work in this way and report that the write operation is complete only after the memory controller has accepted it, but I could be mistaken. And if the PS does not work in this way, then I'm not sure what the solution is.

@alexforencich
Copy link
Owner

Also, don't forget that on the Zynq MPSoC, the burst length is limited to 16, so you'll need to make sure that the AXI_MAX_BURST_LEN is set to 16 or less. I'm not sure what happens if this limit is exceeded - with Corundum, it seems to still work, but maybe write responses are not reported correctly.

@abarajithan11
Copy link
Author

abarajithan11 commented Jul 20, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants