UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer maria@tbg
Observer
6,836 Views
Registered: ‎01-31-2017

polled simple DMA example with VHDL interface

Jump to solution

Hi all

 

Apologizes being a newbie. 

 

I'm trying to write a very simple DMA transfer from PL to PS on Zynq (Zedboard).

I just modified the simple dma project from (https://www.xilinx.com/support/answers/57561.html) which worked fine before I modified it.

 

I'm not even near a success so it would be very much appreciated if someone could help me out.

 

The goal is to transfer 32bits I generated in my VHDL IP block to PS.

I've got one self written IP block with a counter starting from 12 (hex C) to 44 (hex 2C) == 32bits.

I'm writing these 32bits to the "AXI Stream Data FIFO" block which is connected to the AXI DMA block.

I think all three blocks are running on the "axi_aclk" of 50MHz.

 

1) What exact values do "s_axis_tkeep" have to be?

2) Could someone please look at my code and see what I'm doing wrong regarding timing. Only parts of the data I write in the DMA are read which are interleaved with '0's {i.e. I would expect 12, 13, 14 ... but at the mucontroller I read 15,0,0,0,16,0,0,0,...}

 

 

Many thanks in advance,

Maria

screenshot_block_design.png
0 Kudos
1 Solution

Accepted Solutions
Observer maria@tbg
Observer
9,240 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

Solved it.

 

Data is converted: so it's four u8 numbers combined into one u32.

s_axis_tdata <= std_logic_vector(index_counter_u8+3) & std_logic_vector(index_counter_u8+2) & std_logic_vector(index_counter_u8+1) & std_logic_vector(index_counter_u8) ;

 

If I change that in my VHDL and read u8 in C, it works.

 

Thanks ronnywebers, learnt a lot from your posts though.

0 Kudos
19 Replies
Scholar ronnywebers
Scholar
6,806 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

hello Maria,

 

I'm not yet sure if the error is related to your firmware or VHDL code. But here are some ideas :

 

I checked your vhdl file, first of all : the ZED_CLK seems to be unused, is that on purpose? It just connects to a clocking wizard, but the 10Mhz output is unsed.

 

Regarding TKEEP and TSTRB, I think in your case you can simply connect them to '1' all the time.  Use TVALID to indicate valid data or not. TLAST indicates a packet end, and will trigger the DMA to do the transfer.

 

I recommend to read through the AXI4 Stream spec, it tells you everything about TKEEP, TSTRB, ... you can find it at ARM : http://infocenter.arm.com/help/index.jsp, then AMBA -> AMBA Specifications -> AMBA4

 

You should also put an ILA (analyser) on the AXI4S stream, you will learn a lot from that. You can for example trigger on the TVALID line. Or even on the AXI4 - Lite interface where you set slv_reg0(0) = '1'. The ILA is one of the best teachers :-)

 

 

 

 

 

 

 

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
Observer maria@tbg
Observer
6,789 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

Hi ronnywebers

 

thanks for your response.

 

I'm sorry for the confusion, it is not on purpose. (I tried using other clocks for the counter IP but it didn't make a difference; I also deleted ZED_CLK and clocking wizard already, but still no difference)

 

From what you said, I think the interface between my IP (containing the counter) and the FIFO should be ok, at least what testbench suggests (see attachment).

 

I'm having troubles finding some guidance on how to use ILA in block designs (as I use "Create HDL Wrapper" and I don't want to fiddle around with the auto generated VHDL files). By chance to you know a good source explaining how to use ILA block IP in block designs?

 

Thanks again,

Maria

screenshot_VHDL_code.png
0 Kudos
Scholar ronnywebers
Scholar
6,783 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

You can directly put an ILA from the IP catalog on your block design. Double click it to configure the debug ports as you need, and wire up the connections.

 

the create hdl wrapper should work fine with an ILA though ...

 

Honestly xilinx should write more tutorials, I had a hard time finding one that uses an ILA.

 

You can have a look at :

 

1) this video : https://www.xilinx.com/video/hardware/logic-debug-in-vivado.html

it gives an overview of debugging possibilities. you can just put an ILa on your block diagram, configure it, and wire up the connections. That's what I use a lot. But the 'mark debug' way is sometimes also interesting / easier.

 

2) UG940, Lab 1 uses the 'mark debug' approach. Lab 2 explains the more advanced cross triggering.

3) UG908 chapter 10 (debugging logic designs in hardware) explains some more details on the ILA core

 

In the Xilinx documentation application, check 'design hub view', and then 'programming and debug design hub', the hub centralizes the doc around subjects, so it's easier to find a document. Also search for 'tutorial' in the document application, there's about 10 of them, and I suggest to do as many as possible of them, you'll learn a lot from it.

 

 

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
Scholar ronnywebers
Scholar
6,780 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

I would even recommend to start with the Silica speedway workshops first, they are very hands-on, and I learned a lot from it. They also use the Zedboard which you seem to have, so that's great

 

http://zedboard.org/support/trainings-and-videos

 

if you go to the second workshop (SoC hardware), and download the labs, you will see that lab 8 and lab 9 use an ILA instantiated on a block design. That will perfectly explain what you need, but I would start with lab 1 :-)

 

 

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
Observer maria@tbg
Observer
6,777 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

Many thanks for all the references!

 

I'll look into that and hopefully learn what I'm doing incorrectly.

0 Kudos
Scholar ronnywebers
Scholar
6,768 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

going through the tutorials will set you back a while, but you will learn many things that will save you time further down the road.

 

The ILA should help you find wether your issue is hardware / vhdl related or software. The ILA allows you to see the AXI4 Stream data, with VALID flags etc, but also the acutal DMA transfer to memory, it's just a matter of putting the right signals on the ILA.

 

maybe a list tip with the ILA : unfortunately you cannot mix 'AXI' or 'Native' probes (see the Monitor type in the ILA config dialog).

 

So if you need both native and AXI probes, you need to use 2 (or more)  ILA's, and connect the trigger output port of one ila to the trigger input port of the other ila. Or if you need multiple AXI ports, you need multiple ILA's. I hope they improve this in later Vivado versions. Note that you need to enable the trigger ports on your ILA. Also in hardware manager, you need to set the trigger sources, but you'll learn that from the tutorials. It's not that hard to get them working.

** kudo if the answer was helpful. Accept as solution if your question is answered **
Observer maria@tbg
Observer
6,644 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

ronnywebers thanks very much again - your tutorial references were extremely helpful.

With the ILAs I figured out that something is going wrong between FIFO and DMA.

 

The first attachment shows ILA results at the interface between my self written counter IP and FIFO which works expected I'd say.

The second attachment shows the interface between FIFO and DMA.

If I understood it correctly, for some reasons the memory is not ready (TREADY) and therefore data (TDATA) is "paused".

 

I mainly use source code of https://www.xilinx.com/support/answers/57561.html

most of the things are untouched (I deleted transmit data on PS / Read DMA on PL / added my counter IP).

So I'm a bit at a loss what's going wrong.

 

ila_output_myIP.png
ila_output_FIFO.png
0 Kudos
Scholar ronnywebers
Scholar
6,628 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

a) first regarding the 'hardware'

 

I checked your screenshots :

 

screenshot 1 : I think it's hidden underneath the yellow cursor, but there should be a TLAST pulse at the very last counter value

 

screenshot 2 : although it's quiet zoomed out, I think this is expected signal behaviour. It looks kinda strange at first, but one important thing to understand is that :

 

an axi4-stream transaction takes only place when both TREADY and TVALID are '1'.

 

So your source (the AXI4-S fifo), who on it's turn has the data from your counter) says : hey I'm ready, I have data, as long as not all 32 words are shifted out.

 

Your receiving side, the DMA, does not have a real buffer memory (that's why you need an AXI4-S data fifo :-), just a few pipeline registers, so it needs to arbitrate with the ARM cores for access to the DDR3 memory. That is why you see some 'hick-up' in the TREADY, it's not continously high for 32 words in this case. This TREADY behaviour will thus depend on bus load etc. Nothing to worry about too much, but just know that it doesn't have to be continously high. This is actually the 'throttling mechanism' behind AXI4-S streams, the DMA cannot guarantee to be ready all the time.

 

Also know that TREADY can be high '1', while TVALID is not. In that case, a transfer doesn't take place either. If you read a few times through the AXI4S standard from ARM you get all the details.

 

Same goes for your fifo : if you have a continous stream, and the fifo gets full, it will set TREADY to '0'. That would mean that with an ADC, you'll loose samples. That's why for performance measurement it's good to have a counter indeed instead of ADC data, where it might not be that obvious that you're missing data.

 

b) now as far as I can see from the screenshots, everything looks fine. So it looks like your issue is firmware related. I checked the .c file that you attached : I saw this pointer to U8 definition, without looking too much into the other details, is there a reason this is not a (u32 *) ? as TDATA is 32-bit.

 

int XAxiDma_SimplePollExample(u16 DeviceId)
{
     ....

	RxBufferPtr = (u8 *)RX_BUFFER_BASE;

As you showed initially, you have one out of 4 values correct, looks to me that you're displaying U8 data of out a 32-bit value, so that could be why you see the zero values in between?

0x00000012 -> 0x12, 0x00, 0x00, 0x00 ?

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
Observer maria@tbg
Observer
6,623 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

thanks very much for the detailed explanation and looking through my code !!

 

Yes there is a TLAST at the last counter value. (attached with new cursor position)

No, there is no reason - great for pointing it out. I've got success in a small step, it works until 9th bit. (see attachment)

There is nothing suspicious in hardware happening at the 9th bit. (see attachment)

 

 

ila_output_myIP_zoomed.png
ila_output_FIFO_zoomed.png
output_PS.png
0 Kudos
Scholar ronnywebers
Scholar
5,391 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

this looks like a cache (flush) issue, can you try to change this :

 

		Xil_DCacheInvalidateRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN);

into this :

 

		Xil_DCacheInvalidateRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN*4);

and let me know if this helps?

 

looks like you only flush 32 bytes, instead of 32 x a 32-bit word ...

 

also a minor remark : in your printf you call your words 'bit' data, but a bit is acutally '0' or '1', I would call it 'word' or '32-bit word' or just 'value'

** kudo if the answer was helpful. Accept as solution if your question is answered **
Observer maria@tbg
Observer
5,388 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

Thank you so much!

 

It works now.

Only the last value ("bit") is wrong but this might be that TLAST needs to be '1' after the next clock cycle (i.e. one rising edge after the rising edge of the last value)?

ila_output_myIP_zoomed2.png
ila_output_FIFO_zoomed2.png
0 Kudos
Scholar ronnywebers
Scholar
5,379 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

correct me if I'm wrong, but I think you also want to transfer the value '43' as your last value (?)

 

in that case TLAST is ok in your waveform, because it falls together with '43', but your TKEEP should be '1' too. I would tie TKEEP to '1' all the time, they are not really required signals, unless I believe you want to send 'user data', but I should check the ARM spec to be sure.

 

if the last value should be '42' then TLAST comes 1 cycle too late.

 

so review your VHDL code

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Observer maria@tbg
Observer
5,341 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

Thanks again for your help!

 

Yes, 43 should be the last one.

I'll look into TKEEP.

0 Kudos
Observer maria@tbg
Observer
5,274 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

It seems like changing " Xil_DCacheInvalidateRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN*4);" was only an intermittent solution.

 

Today when I run the project, I didn't work (i.e. I only received 8 correct values as last week).

Out of source control, I took the project from last week and I got the same behaviour.

I then changed it back to "Xil_DCacheInvalidateRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN);" and it worked.

After a simple "switching board off/on" test, it stopped working again and until now I can't get it running.

Since the re-start I receive "random" data in between (see attachment).

 

results_15052017.png
0 Kudos
Observer maria@tbg
Observer
5,264 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

When I compare ILA results, the ILA who shows the interface between FIFO and DMA, has changed.

I'm using the same code but I needed to re-compile.

Before there were some (expected) 'hick-ups' in the TREADY. Now there are none.

 

Does this tell me anything?

ILA2.png
0 Kudos
Observer maria@tbg
Observer
9,241 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

Solved it.

 

Data is converted: so it's four u8 numbers combined into one u32.

s_axis_tdata <= std_logic_vector(index_counter_u8+3) & std_logic_vector(index_counter_u8+2) & std_logic_vector(index_counter_u8+1) & std_logic_vector(index_counter_u8) ;

 

If I change that in my VHDL and read u8 in C, it works.

 

Thanks ronnywebers, learnt a lot from your posts though.

0 Kudos
Scholar ronnywebers
Scholar
4,899 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

good news maria@tbg that you solved it!

 

i try to grasp what you changed in your VHDL code - s_axis_tdata was and still is a 32-bit std_logic_vector? so why does that make a difference now when reading that in C?

 

In the code you posted you had :

 

s_axis_tdata <= std_logic_vector(index_counter_1+12);
** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Observer maria@tbg
Observer
4,886 Views
Registered: ‎01-31-2017

Re: polled simple DMA example with VHDL interface

Jump to solution

The problem is that in the C code (i.e. memory allocation) was only configured for u8 data.

I debugged the example project, and saw that the data looked weird. From this I figured out that four u8 are combined to one u32.

 

One of our C experts made modifications in C to read u32 data properly (i.e. using my original code from previous post). 

Before modifications in C, only 32 bytes of memory was read - only enough for 32 u8 data types.

Scholar ronnywebers
Scholar
4,879 Views
Registered: ‎10-10-2014

Re: polled simple DMA example with VHDL interface

Jump to solution

ok clear

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos