08-30-2015 04:49 PM
I am having difficulty implementing a master port AXi4-Lite interface in Verilog. My design consists of a custom module that reads data (32 bits wide) from a BRAM: Custom module -> Axi Internconnect -> BRAM Controller-->stand alone BRAM (data uploaded via coe file). Then custom module modifies the data just read, and then writes this new data back to the BRAM on different address.
Custom module, AXI Interconnect, BRAM controller, and stand alone BRAM are located on the PL side.
The custom module only has an AXI4-Lite Master port.
For debugging purposes, I have the ZYNQ attached to the AXi interconnect. This allows the Zynq to read the BRAM contents via XMD (i.e.: connect arm hw; then mrd 0x500007cc 20 ).
My custom module reads one entry from the BRAM, then internally, invokes a function, and adds a constant to the value just read (My local function simply adds 32'hABC00000 to the value read). Then writes this data successfully in the new BRAM destination.
Now, the problem I am having occurs when attempting to repeat these steps. For example, I make my verilog code (within the axi4-lite_master.v file) to read+modify+write 10 times. Once a write ends, a read begins. The expected outputs are 10 new values in the BRAM. Instead, my Verilog code skips reading every other value, meaning:
Wrong Output in BRAM:
Expected Output in BRAM:
Data read from BRAM (uploaded via coe file):
I realize i am having a zynchronization issue. I have read the protocols and do know that every channel has a ready and validity signal. I am using the default implementation of an AXI4-Lite Master port that gets autogenerated when creating the custom module, and even found a very simple write/read AXi4-Lite example from the AR37425 (http://www.xilinx.com/support/answers/37425.html , file ax4-lite_master.v).
Unfortunatelly, both examples only compare the value read by M_AXI_RDATA with an expected value. The example, ends there.
In my case, I want to read the data, modify it locally via a function, and then write the output generated by the function back to the BRAM, and repeat this process an arbitraty number of times without the skipping shown above.
Is it possible to accomplish this, or am I forcing the protocols to do more than what they are expected to do. I am aware I am implementing a hdl Verilog program, not a c/c++ program, so how do I include the repeat condition and avoid circular logic?
The custom module initiates on its own, reads, modifies, and writes, and like I mentioned above, repeats these steps 10 times. What will be the best approach to invoke axi_awaddr, axi_araddr, axi_wdata, M_AXI_RDATA, etc, properly? Am I missing something else?
An simple example, would be helpful, too.
08-31-2015 06:56 AM
10-21-2015 04:36 PM
Here is an update. I solved my problem by not initializing the rdata variable to zero. You only want to update rdata when you have to. Otherwise, unwanted data gets written to memory (i.e.: bram).