cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Visitor
Visitor
4,347 Views
Registered: ‎08-30-2015

Issues implementing AXi4-Lite Master interface (Verilog)

Hello Everyone,

 

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:

 

0x500007CC: ABC00001

400007D0: 00000000
400007D4: ABC00003
400007D8: 00000000
400007DC: ABC00005
400007E0: 00000000
400007E4: ABC0000B
400007E8: 00000000
400007EC: ABC0000D
400007F0: 00000000

 

 

Expected Output in BRAM:

 

0x500007CC: ABC00001

400007D0: ABC00002
400007D4: ABC00003
400007D8: ABC00004
400007DC: ABC00005
400007E0: ABC0000A
400007E4: ABC0000B
400007E8: ABC0000C
400007EC: ABC0000D
400007F0: ABC0000E

 

 

Data read from BRAM (uploaded via coe file):

 

40000000: 00000001
40000004: 00000002
40000008: 00000003
4000000C: 00000004
40000010: 00000005
40000014: 0000000A
40000018: 0000000B
4000001C: 0000000C
40000020: 0000000D
40000024: 0000000E

 

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.

 

Thank you!

 

 

 

0 Kudos
Reply
3 Replies
Xilinx Employee
Xilinx Employee
4,300 Views
Registered: ‎08-02-2011

Hello,

Your use case is possible and it sounds like you are almost there!

What I would do is probe the AXI signals with an ILA and look at exactly the transactions that are coming out of the custom module. That should help you determine what's going on.

My first thought is that it's an issue with your data width vs the burst size of the request coming out of the AXI. Something like that is what I'd be looking for at first.
www.xilinx.com
0 Kudos
Reply
Visitor
Visitor
4,282 Views
Registered: ‎08-30-2015

Thank you. I am going to do this. I'll post an update soon.

0 Kudos
Reply
Visitor
Visitor
4,220 Views
Registered: ‎08-30-2015

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).