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: 
Adventurer
Adventurer
1,023 Views
Registered: ‎03-30-2017

C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

Let's say DUT has both AXI_M writer and AXI_M reader:

 

 

 

void video_flt (
axi_sword_t wr_ram[AXI_WORDS_PER_FRAME],
axi_sword_t rd_ram[AXI_WORDS_PER_FRAME]
) {
#pragma HLS INTERFACE m_axi port=wr_ram offset=direct bundle=ddr_ram num_read_outstanding=2 num_write_outstanding=2
#pragma HLS INTERFACE m_axi port=rd_ram offset=direct bundle=ddr_ram num_read_outstanding=2 num_write_outstanding=2
...
...

 The TB is passing the same pointer to both: wr_ram and rd_ram:

 

 

u16* ext_ram;
ext_ram = new u16[PIX_PER_FRAME];

video_flt(ext_ram, ext_ram);

 

What I see in the C/RTL COSIM is that wr_ram and rd_ram are getting different address - that's wrong!!! it doesn't match the TB!

 

I believe that's a bug and needs to be fixed

 

0 Kudos
11 Replies
Xilinx Employee
Xilinx Employee
972 Views
Registered: ‎09-05-2018

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

Hey @ifutritski,

How do you want to provide the addresses of those arrays?

The reason I'm asking is - right now, you've specified AXI master with direct offsets, meaning that the offset is passed in as an input into the IP, you've got two separate bidirectional inputs there. So those addresses should be different so as to allow concurrent reads and writes to different locations in the memory.

But also you've got the interfaces bundled, which indicates you might actually be looking for AXI slave interfaces to group the signals together? In such a case, the bundled start address would be the same, and the offsets for each interfaces would change as dictated by the IP.

You can read more about AXI interfaces on page 130 of UG902.

 

Nicholas Moellers

Xilinx Worldwide Technical Support
0 Kudos
Adventurer
Adventurer
966 Views
Registered: ‎03-30-2017

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

Nicholas,

you're missing the point, in my 2nd code snippet I show how the function is called in the TB:

video_flt(ext_ram, ext_ram);

That means I am passing the same address to both AXI interfaces!

The reason I have 2 different AXI interfaces is that this is the only way for concurrent access using DATAFLOW. So, 1st AXI interface is only reading while the 2nd is writing, then I bundle them up. 

Igor

0 Kudos
Xilinx Employee
Xilinx Employee
955 Views
Registered: ‎09-05-2018

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

@ifutritski,

I understand your point, and there is no problem with using two different AXI interfaces for the same memory. Because you are using AXI with direct offsets, the address you see in the co-sim will change for each access to that memory, and the address you see won't point to the base of the memory, but rather the base plus the offset, in effect.

 

Nicholas Moellers

Xilinx Worldwide Technical Support
0 Kudos
Adventurer
Adventurer
951 Views
Registered: ‎03-30-2017

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

So, do you agree that this is a bug and needs to be fixed?
0 Kudos
Xilinx Employee
Xilinx Employee
945 Views
Registered: ‎09-05-2018

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

@ifutritski,

The behavior you are describing to me sounds like what I would expect to see in the RTL co-simulation based on what is documented on page 130 of UG902. If you require that the addresses be the same in RTL co-simulation, then you may want to use the slave -offset options instead. 

 

Nicholas Moellers

Xilinx Worldwide Technical Support
0 Kudos
Adventurer
Adventurer
940 Views
Registered: ‎03-30-2017

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

Nicholas,
It doesn't matter if you use offset=slave or offset=direct!
What does matter, is that when the top level function is called from the TB, and given the same offset (pointer ext_ram) to both AXI interfaces:

video_flt(ext_ram, ext_ram);

IT SHOULD PROPAGATE TO THE RTL/COSIM!!! But it's not, I see different offset values for WRITER and READER AXI interfaces.
0 Kudos
Xilinx Employee
Xilinx Employee
929 Views
Registered: ‎09-05-2018

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

@ifutritski,

Maybe lets try - if you could please post an image of your waveform or attach the waveform file, I could see what you're seeing, and we could better determine if this is a bug or expected behavior. If you don't mind, please do try this with both offset modes.

Nicholas Moellers

Xilinx Worldwide Technical Support
0 Kudos
Adventurer
Adventurer
917 Views
Registered: ‎03-30-2017

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

I am attaching example design.

1. unzip it to some folder

2. open command prompt and run: vivado_hls -i -f axi_ptr.tcl

it will create vivado_hls project in the prj folder

3. open vivado_hls in gui mode

4. open/project  choose your_folder/prj

5. look at the waveform - see that wr_ram and rd_ram are getting a different pointer value, while the testbench demand it to be the same.axi_ptr.png

0 Kudos
Xilinx Employee
Xilinx Employee
814 Views
Registered: ‎09-05-2018

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

Ah,

So it's an entirely different address space, rather than just one address being different. I gotcha.

So here's my question now. This seems like a convoluted way to make this IP. AXI is already bidirectional. Data can move in both directions between the master and slave simultaneously. The only difference between the IP is that instead of separate rd_ram and wr_ram offsets, you'll only synthesize one. Why not just have AXI master and use it for both the writes and the reads? Another way of saying this is - I don't understand this statement: 

"The reason I have 2 different AXI interfaces is that this is the only way for concurrent access using DATAFLOW."

Nicholas Moellers

Xilinx Worldwide Technical Support
0 Kudos
Adventurer
Adventurer
810 Views
Registered: ‎03-30-2017

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

Nicholas,

When DATAFLOW directive is used in the design, the design must comply to set of rules, one of which is: "Single producer - Single consumer", see 192 of ug902.

So, if you'll have 1 variable, rw_ram and will try to read and write to/from it in the DATAFLOW region, it will violate Single producer - Single consumer" rule.

The only way is to have wr_ram and rd_ram.

All that doesn't matter, because I am pointing out to the problem in HLS, where the functionality is changed between C and RTL testbench!

It's a bug that needs to be fixed!!!

 

0 Kudos
Xilinx Employee
Xilinx Employee
794 Views
Registered: ‎09-05-2018

Re: C/RTL COSIM doesn't pass m_axi pointers from TB to DUT correctly

@ifutritski,

Okay. I understand now that you're trying to work around the single producer single consumer restriction of dataflow regions. However, I am seeing that as of Vivado HLS 2014.1, the tool was enhanced to ensure that a bundled AXI master (as in your example) is processed as one. At the time, this was done to ensure one could not split and bundle the read and write directions and bundle them back together, and that it would trigger and dataflow config warning/error. However, there are no warnings with your example, so I experimented with the following code that seems to work:

#include "axi_ptr.h"
void p1( int axi[1024], int buff[1024]) {
       int reg;
       for (int i=0; i<1024; i++) {
              reg = axi[i];
              buff[i] = reg + i;
       }
}
void p2( int buff[1024], int axi[1024] ) {
       int reg;
       for (int i=0; i<1024; i++) {
                     reg = buff[i];
                     axi[i] = reg+1;
              }
}

void axi_ptr ( int ddr_ram[1024] ) { 
#pragma HLS DATAFLOW
#pragma HLS INTERFACE m_axi port=ddr_ram offset=direct
      int data_in_rg[1024];
       p1( ddr_ram, data_in_rg );
       p2( data_in_rg, ddr_ram );
}

That code compiles without warnings, and the console confirms that p1 and p2 are being put into a dataflow region. And here is the resulting dataflow view:Capture.PNG

Unfortunately, I could not find any resource which confirms that HLS now understands that AXI contains separate producer and consumer channels, but empirically, it seems to be the case. Would you be willing to give this a try?

Nicholas Moellers

Xilinx Worldwide Technical Support
0 Kudos