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: 
Explorer
Explorer
6,753 Views
Registered: ‎04-19-2016

AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hello,

 

I have created a custom-IP which has two axi interfaces :  one slave Axi-Lite ( for control&status registers access) and one master Axi-Stream (for data memory-map operation) interface. I can easily handle the generated Axi-Lite module, I can acces all registers without any problem. Because there is enough documantation to use a custom-IP generated AXi-Lite module(about the where should I connect the my registers in axi-lite module ...etc.).  

 

However, I can not find any directions(document) to handle the generated Axi-Stream module in custom IP. How can I connect the data signal to the this below AXI-Stream module ? Where and how can I drive the Tvalid and Tlast signal in this AXI-Stream module ? such things may be useful : you can connect the your data signal here in below module. and you can connect the your signals here to drive&generate the Tvalid and Tlast signals... for example; should I add some new ports into the this AXI-Stream module for coming data to this module? 

 

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity My_IP_v1_0_M00_AXIS is
	generic (
		-- Users to add parameters here

		-- User parameters ends
		-- Do not modify the parameters beyond this line

		-- Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_TDATA_WIDTH.
		C_M_AXIS_TDATA_WIDTH	: integer	:= 32;
		-- Start count is the numeber of clock cycles the master will wait before initiating/issuing any transaction.
		C_M_START_COUNT	: integer	:= 32
	);
	port (
		-- Users to add ports here
		
			-- User ports ends
		-- Do not modify the ports beyond this line

		-- Global ports
		M_AXIS_ACLK	: in std_logic;
		-- 
		M_AXIS_ARESETN	: in std_logic;
		-- Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. 
		M_AXIS_TVALID	: out std_logic;
		-- TDATA is the primary payload that is used to provide the data that is passing across the interface from the master.
		M_AXIS_TDATA	: out std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
		-- TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte.
		M_AXIS_TSTRB	: out std_logic_vector((C_M_AXIS_TDATA_WIDTH/8)-1 downto 0);
		-- TLAST indicates the boundary of a packet.
		M_AXIS_TLAST	: out std_logic;
		-- TREADY indicates that the slave can accept a transfer in the current cycle.
		M_AXIS_TREADY	: in std_logic
	);
end My_IP_v1_0_M00_AXIS;

architecture implementation of My_IP_v1_0_M00_AXIS is
	--Total number of output data.
	-- Total number of output data                                              
	constant NUMBER_OF_OUTPUT_WORDS : integer := 8;                                   

	 -- function called clogb2 that returns an integer which has the   
	 -- value of the ceiling of the log base 2.                              
	function clogb2 (bit_depth : integer) return integer is                  
	 	variable depth  : integer := bit_depth;                               
	 	variable count  : integer := 1;                                       
	 begin                                                                   
	 	 for clogb2 in 1 to bit_depth loop  -- Works for up to 32 bit integers
	      if (bit_depth <= 2) then                                           
	        count := 1;                                                      
	      else                                                               
	        if(depth <= 1) then                                              
	 	       count := count;                                                
	 	     else                                                             
	 	       depth := depth / 2;                                            
	          count := count + 1;                                            
	 	     end if;                                                          
	 	   end if;                                                            
	   end loop;                                                             
	   return(count);        	                                              
	 end;                                                                    

	 -- WAIT_COUNT_BITS is the width of the wait counter.                       
	 constant  WAIT_COUNT_BITS  : integer := clogb2(C_M_START_COUNT-1);               
	                                                                                  
	-- In this example, Depth of FIFO is determined by the greater of                 
	-- the number of input words and output words.                                    
	constant depth : integer := NUMBER_OF_OUTPUT_WORDS;                               
	                                                                                  
	-- bit_num gives the minimum number of bits needed to address 'depth' size of FIFO
	constant bit_num : integer := clogb2(depth);                                      
	                                                                                  
	-- Define the states of state machine                                             
	-- The control state machine oversees the writing of input streaming data to the FIFO,
	-- and outputs the streaming data from the FIFO                                   
	type state is ( IDLE,        -- This is the initial/idle state                    
	                INIT_COUNTER,  -- This state initializes the counter, ones        
	                                -- the counter reaches C_M_START_COUNT count,     
	                                -- the state machine changes state to INIT_WRITE  
	                SEND_STREAM);  -- In this state the                               
	                             -- stream data is output through M_AXIS_TDATA        
	-- State variable                                                                 
	signal  mst_exec_state : state;                                                   
	-- Example design FIFO read pointer                                               
	signal read_pointer : integer range 0 to bit_num-1;                               

	-- AXI Stream internal signals
	--wait counter. The master waits for the user defined number of clock cycles before initiating a transfer.
	signal count	: std_logic_vector(WAIT_COUNT_BITS-1 downto 0);
	--streaming data valid
	signal axis_tvalid	: std_logic;
	--streaming data valid delayed by one clock cycle
	signal axis_tvalid_delay	: std_logic;
	--Last of the streaming data 
	signal axis_tlast	: std_logic;
	--Last of the streaming data delayed by one clock cycle
	signal axis_tlast_delay	: std_logic;
	--FIFO implementation signals
	signal stream_data_out	: std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
	signal tx_en	: std_logic;
	--The master has issued all the streaming data stored in FIFO
	signal tx_done	: std_logic;


begin
	-- I/O Connections assignments

	M_AXIS_TVALID	<= axis_tvalid_delay;
	M_AXIS_TDATA	<= stream_data_out;
	M_AXIS_TLAST	<= axis_tlast_delay;
	M_AXIS_TSTRB	<= (others => '1');


	-- Control state machine implementation                                               
	process(M_AXIS_ACLK)                                                                        
	begin                                                                                       
	  if (rising_edge (M_AXIS_ACLK)) then                                                       
	    if(M_AXIS_ARESETN = '0') then                                                           
	      -- Synchronous reset (active low)                                                     
	      mst_exec_state      <= IDLE;                                                          
	      count <= (others => '0');                                                             
	    else                                                                                    
	      case (mst_exec_state) is                                                              
	        when IDLE     =>                                                                    
	          -- The slave starts accepting tdata when                                          
	          -- there tvalid is asserted to mark the                                           
	          -- presence of valid streaming data                                               
	          --if (count = "0")then                                                            
	            mst_exec_state <= INIT_COUNTER;                                                 
	          --else                                                                              
	          --  mst_exec_state <= IDLE;                                                         
	          --end if;                                                                           
	                                                                                            
	          when INIT_COUNTER =>                                                              
	            -- This state is responsible to wait for user defined C_M_START_COUNT           
	            -- number of clock cycles.                                                      
	            if ( count = std_logic_vector(to_unsigned((C_M_START_COUNT - 1), WAIT_COUNT_BITS))) then
	              mst_exec_state  <= SEND_STREAM;                                               
	            else                                                                            
	              count <= std_logic_vector (unsigned(count) + 1);                              
	              mst_exec_state  <= INIT_COUNTER;                                              
	            end if;                                                                         
	                                                                                            
	        when SEND_STREAM  =>                                                                
	          -- The example design streaming master functionality starts                       
	          -- when the master drives output tdata from the FIFO and the slave                
	          -- has finished storing the S_AXIS_TDATA                                          
	          if (tx_done = '1') then                                                           
	            mst_exec_state <= IDLE;                                                         
	          else                                                                              
	            mst_exec_state <= SEND_STREAM;                                                  
	          end if;                                                                           
	                                                                                            
	        when others    =>                                                                   
	          mst_exec_state <= IDLE;                                                           
	                                                                                            
	      end case;                                                                             
	    end if;                                                                                 
	  end if;                                                                                   
	end process;                                                                                


	--tvalid generation
	--axis_tvalid is asserted when the control state machine's state is SEND_STREAM and
	--number of output streaming data is less than the NUMBER_OF_OUTPUT_WORDS.
	axis_tvalid <= '1' when ((mst_exec_state = SEND_STREAM) and (read_pointer < NUMBER_OF_OUTPUT_WORDS)) else '0';
	                                                                                               
	-- AXI tlast generation                                                                        
	-- axis_tlast is asserted number of output streaming data is NUMBER_OF_OUTPUT_WORDS-1          
	-- (0 to NUMBER_OF_OUTPUT_WORDS-1)                                                             
	axis_tlast <=  '1' when (read_pointer = NUMBER_OF_OUTPUT_WORDS-1) else '0';                     
	                                                                                               
	-- Delay the axis_tvalid and axis_tlast signal by one clock cycle                              
	-- to match the latency of M_AXIS_TDATA                                                        
	process(M_AXIS_ACLK)                                                                           
	begin                                                                                          
	  if (rising_edge (M_AXIS_ACLK)) then                                                          
	    if(M_AXIS_ARESETN = '0') then                                                              
	      axis_tvalid_delay <= '0';                                                                
	      axis_tlast_delay <= '0';                                                                 
	    else                                                                                       
	      axis_tvalid_delay <= axis_tvalid;                                                        
	      axis_tlast_delay <= axis_tlast;                                                          
	    end if;                                                                                    
	  end if;                                                                                      
	end process;                                                                                   


	--read_pointer pointer

	process(M_AXIS_ACLK)                                                       
	begin                                                                            
	  if (rising_edge (M_AXIS_ACLK)) then                                            
	    if(M_AXIS_ARESETN = '0') then                                                
	      read_pointer <= 0;                                                         
	      tx_done  <= '0';                                                           
	    else                                                                         
	      if (read_pointer <= NUMBER_OF_OUTPUT_WORDS-1) then                         
	        if (tx_en = '1') then                                                    
	          -- read pointer is incremented after every read from the FIFO          
	          -- when FIFO read signal is enabled.                                   
	          read_pointer <= read_pointer + 1;                                      
	          tx_done <= '0';                                                        
	        end if;                                                                  
	      elsif (read_pointer = NUMBER_OF_OUTPUT_WORDS) then                         
	        -- tx_done is asserted when NUMBER_OF_OUTPUT_WORDS numbers of streaming data
	        -- has been out.                                                         
	        tx_done <= '1';                                                          
	      end  if;                                                                   
	    end  if;                                                                     
	  end  if;                                                                       
	end process;                                                                     


	--FIFO read enable generation 

	tx_en <= M_AXIS_TREADY and axis_tvalid;                                   
	                                                                                
	-- FIFO Implementation                                                          
	                                                                                
	-- Streaming output data is read from FIFO                                      
	  process(M_AXIS_ACLK)                                                          
	  variable  sig_one : integer := 1;                                             
	  begin                                                                         
	    if (rising_edge (M_AXIS_ACLK)) then                                         
	      if(M_AXIS_ARESETN = '0') then                                             
	    	stream_data_out <= std_logic_vector(to_unsigned(sig_one,C_M_AXIS_TDATA_WIDTH));  
	      elsif (tx_en = '1') then -- && M_AXIS_TSTRB(byte_index)                   
	        stream_data_out <= std_logic_vector( to_unsigned(read_pointer,C_M_AXIS_TDATA_WIDTH) + to_unsigned(sig_one,C_M_AXIS_TDATA_WIDTH));
	      end if;                                                                   
	     end if;                                                                    
	   end process;                                                                 

	-- Add user logic here
		

	-- User logic ends

end implementation;

 

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
Moderator
Moderator
9,987 Views
Registered: ‎11-09-2015

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hi @doner_t,

 

So you just need to create a Slave AXI-stream interface for your IP.

 

If you package a new IP, you can use a given template for your interface


Florent
Product Application Engineer - Xilinx Technical Support EMEA
**~ Don't forget to reply, give kudos, and accept as solution.~**
10 Replies
Moderator
Moderator
6,716 Views
Registered: ‎11-09-2015

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hi @doner_t,

 

Could you draw what you are trying to do with your IP? At least the interfaces.

 

What are the datas. Where are they coming and where will they go


Florent
Product Application Engineer - Xilinx Technical Support EMEA
**~ Don't forget to reply, give kudos, and accept as solution.~**
0 Kudos
Explorer
Explorer
6,702 Views
Registered: ‎04-19-2016

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hello @florentw,

 

Thank you for reply. 

 

You can see a rough drawing in attached photo. As you see, I have an 18bit in and 18bit out fifo. Data is 16-bit pixel data. I am writing this pixel data into the fifo as in this format ;  data_in [17:0] =  FRAME_START & LINE_END & data[15:0]. 

 

I want to take this video data ( readed video data from fifo) as in Axi-Stream format. When I created the my custom-IP, I added one Master Axi-Stream port in my custom-design IP, to through out the video data from IP as in Axi-Stream. 

 

Best Regards,

 

 

 

Tags (3)
Axi_Stream_Usage.png
0 Kudos
Moderator
Moderator
9,988 Views
Registered: ‎11-09-2015

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hi @doner_t,

 

So you just need to create a Slave AXI-stream interface for your IP.

 

If you package a new IP, you can use a given template for your interface


Florent
Product Application Engineer - Xilinx Technical Support EMEA
**~ Don't forget to reply, give kudos, and accept as solution.~**
Highlighted
Explorer
Explorer
6,621 Views
Registered: ‎04-19-2016

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hello @florentw,

 

I connected the FIFO outputs (Read_En, data_out[17:0], valid (fifo can generate a valid signal)) to the Axi-Stream modules as below: 

 

 

fifo_ouput                 Axi-Stream module

 

FRAME_START --> M00_TUSER

LINE_END         -->  M00_TLAST

DATA                  -->  M00_data

valid                   --> M00_TVALID

Read_En           --> M00_TREADY

 

It seems that Axi-Stream module and fifo works properly now. 

 

Thank you again,

 

0 Kudos
Contributor
Contributor
6,155 Views
Registered: ‎07-09-2014

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hi,

 

The title was is related to my question so I asked here instead of creating a new subject.

 

My question is the same how to use AXI4-Stream custom ip ?

 

In my situation I read MAX2769 IC, it gives 4-bit data and a clock. The clock rate is 16.384 MHz so the BW is like 64 Mbps. For this problem first I created an AXI4-Lite ip, sampling the incoming data and when it reaches to 16 bytes long I give interrupt to PS and and in SW it reads the data by simple Xil_In() functions. However I noticed I miss data samples, so BW is not enough for AXI-Lite and GP port.

 

Then I implemented PS DMA, with the same IP (AXI4-Lite) I read IP registers by initiating a DMA transfer whenever an interrupt of my custom IP occurs and increase the destination address. This scenario was OK up to 32 Mbps but not enough up to 64 Mbps.

 

Then for final solution I wanted to implement AXI_DMA and use HP port of Zynq. I read the documentation about AXI DMA and created an AXI4-Stream version of my custom IP. It buffers 32 bytes of data and then stream them via the Master stream port.

 

IP

 

Then I implemented it on Vivado and try to do the SW part. However, couldn't be able to receive right data. I stream example data like AABBCCDD and the SW get some of it but not at all. Probably I misunderstand how AXI DMA work, but I couldn't be able to figure out where is the problem, in PL or SW? The core part of the SW code is:

 

/* Send a packet */
for(Index = 0; Index < Tries; Index ++) {

Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);

if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,
MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);

if (Status != XST_SUCCESS) {
return XST_FAILURE;
}


/*
* Wait TX done and RX done
*/
while (!TxDone && !RxDone && !Error) {
/* NOP */
}

//RxBufferPtr = (u8 *)RX_BUFFER_BASE+(MAX_PKT_LEN*(Index+1));

if (Error) {
xil_printf("Failed test transmit%s done, "
"receive%s done\r\n", TxDone? "":" not",
RxDone? "":" not");

goto Done;

}

/*
* Test finished, check data
*/
Status = CheckData(MAX_PKT_LEN, 0xC);
if (Status != XST_SUCCESS) {
// xil_printf("Data check failed\r\n");
goto Done;
}
}


// xil_printf("AXI DMA interrupt example test passed\r\n");


/* Disable TX and RX Ring interrupts and return success */

DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);

Done:
//xil_printf("--- Exiting main() --- \r\n");
for (i = 0; i < MAX_PKT_LEN*Tries; i++)
{
XUartPs_SendByte(UARTPS_BASEADDR,RxBufferPtr[i]);
}

return XST_SUCCESS;
}

 

And the state machine process of master port of IP

 

-- Control state machine implementation
sm_pr : process(M_AXIS_ACLK)
begin
if (rising_edge (M_AXIS_ACLK)) then

MAX2769_CLK_temp <= MAX2769_CLK_sync;

case (state) is

when IDLE =>

INTERRUPT <= '0';

if(MAX2769_CLK_temp = '1' and MAX2769_CLK_sync = '0') then

if (IQbits = 1) then

if (count = 255) then
totalCntr <= totalCntr + 1;
count <= 1;
state <= SEND_STREAM;
-- INTERRUPT <= '1';

if (testMode = 1) then
--r_Assignment_Buffer <= totalCntr & r_Temp_buffer(247 downto 0);
r_Assignment_Buffer <=
totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree &
totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo &
totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne &
totalCntr & totalCntr & totalCntr & totalCntr & totalCntr & totalCntr & totalCntr & totalCntr;


else
r_Assignment_Buffer <= MAX2769_I1_sync & MAX2769_Q1_sync & r_Temp_buffer(253 downto 0);
end if;

else
r_Temp_buffer(count downto count-1) <= MAX2769_I1_sync & MAX2769_Q1_sync; -- Package format.
count <= count + 2;
end if;

end if;

if (IQbits = 2) then

if (count = 255) then
totalCntr <= totalCntr + 1;
count <= 3;
state <= SEND_STREAM;
-- INTERRUPT <= '1';

if (testMode = 1) then
--r_Assignment_Buffer <= totalCntr & r_Temp_buffer(247 downto 0);
r_Assignment_Buffer <=
totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree & totalCntr_plusThree &
totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo & totalCntr_plusTwo &
totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne & totalCntr_plusOne &
totalCntr & totalCntr & totalCntr & totalCntr & totalCntr & totalCntr & totalCntr & totalCntr;
else
r_Assignment_Buffer <= MAX2769_I0_sync & MAX2769_I1_sync & MAX2769_Q0_sync & MAX2769_Q1_sync & r_Temp_buffer(251 downto 0);
end if;

else
r_Temp_buffer(count downto count-3) <= MAX2769_I0_sync & MAX2769_I1_sync & MAX2769_Q0_sync & MAX2769_Q1_sync; -- Package format.
count <= count + 4;
end if;

end if;

end if;


tvalid <= '0';
tlast <= '0';
packet_len_cnt <= 0;

when SEND_STREAM =>

-- continue data logging
if(MAX2769_CLK_temp = '1' and MAX2769_CLK_sync = '0') then

if (IQbits = 1) then
r_Temp_buffer(count downto count-1) <= MAX2769_I1_sync & MAX2769_Q1_sync; -- Package format.
count <= count + 2;
end if;

if (IQbits = 2) then
r_Temp_buffer(count downto count-3) <= MAX2769_I0_sync & MAX2769_I1_sync & MAX2769_Q0_sync & MAX2769_Q1_sync; -- Package format.
count <= count + 4;
end if;

end if;

data(C_M_AXIS_TDATA_WIDTH-1 downto 0) <= r_Assignment_Buffer(C_M_AXIS_TDATA_WIDTH-1 downto 0);
r_Assignment_Buffer(223 downto 0) <= r_Assignment_Buffer(255 downto 32);
tvalid <= '1';
packet_len_cnt <= packet_len_cnt + 1;

if (packet_len_cnt = PACKET_LEN-1 ) then
packet_len_cnt <= 0;
INTERRUPT <= '1';
tlast <= '1';
state <= IDLE;
end if;

when others =>

state <= IDLE;

end case;
end if;
end process sm_pr;

 

If anyone can help me or give some clue about AXI4-Stream custom ip and SW part I will be very gladful.

 

The codes are in attachments.

 

Thanks in advance,

 

bbinb

AXI_DMA_TEST.PNG
0 Kudos
Explorer
Explorer
6,141 Views
Registered: ‎04-19-2016

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hello @bbinb,

 

Do you want to write your MAX2769 IC 4-bit output to the Zynq-DDR3 memory  ? 

 

Regards,

 

Tags (4)
0 Kudos
Contributor
Contributor
6,113 Views
Registered: ‎07-09-2014

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution
That is exactly my intention. 2769 has two adc, each 2 bit resolution, gives data @16.384 mhz. I need approximately 1,2 mb of data total, first i tried axi lite and xil_in functions but couldnt achieve that data rate, i miss samples, then tried ps dma which works on gp port of zynq, has some improvements but still not enough. So i decided to axi stream and dma with hp ports of zynq, i designed pl part and try to use xaxi_dma functions but couldnt figure out how to use exactly.

Regards,
0 Kudos
Explorer
Explorer
6,108 Views
Registered: ‎04-19-2016

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Dear @bbinb,

 

first i tried axi lite and xil_in functions but couldnt achieve that data rate

*You can use Axi-Lite interface basicly,  in order to reach an IP's control & status registers in PL-side. Not feasible for large data streaming purposes. 

 

So i decided to axi stream and dma with hp ports of zynq

*Sure. You are correct. You can receive your gps receiver data to Zynq-PS-side DDR3 by this way. However ;

 

- You should put your quadrature and in-phase data output (4-bit) in Axi-Stream format. Axi-Stream commonly 32-bit(16-bit also OK)  

- Axi-Stream has a basic handshake principle. Data transaction will start if both Tready & Tvalid signals asserted.

- You should code a small VHDL in order to convert your gps receiver 4-bit output to 32 (or 16-bit) Axi-Stream format. Please see attached file. You should make proper connections between fifo and  Axi-stream module in your top-module Max2769_to_AxiStream.vhd 

- In my case I have used an AXI-VDMA IP due to I received a video data. You can use a AXI-DMA IP to write this gps data to Zynq PS-side DDR3. 

 

Regards,

 

Tags (4)
max2769_to_axi_stream.JPG
0 Kudos
Contributor
Contributor
5,982 Views
Registered: ‎07-09-2014

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

Hello @doner_t

 

Thanks for the reply.

 

Actually, before I dwelve into the AXI_DMA I decided to rework on PS DMA (PL 330). Before, I created a custom IP of MAX2769 driver with AXI4-Lite slave interface. It buffers 16 bytes of data and gives an interrupt. In C code, I wrote an ISR for this interrupt and start DMA transfer for 16 bytes. It couldn't achieve my expected performance, I need 64 mbps BW. This time I redesigned the custom IP and buffer 128 bytes of data instead of 16 bytes and give interrupt to the PS. In ISR I start DMA transfer for 128 bytes of data. And luckily it works this time and achieve 64 mbps data rate. So for now it is OK for me, I will try AXI_DMA later.

 

P_20180103_141204.jpg

 

What I wonder still is, what is the reason for performance improvement in PS DMA after I increased DMA transfer from 16 bytes to 128 bytes? And a beter question is what is the optimum data length for DMA transfer both for PS DMA and AXI_DMA?

 

Also In Vivado there is a section when you double click Zynq SoC module, DMA Controller -> Peripheral Request Interface 0,1,2,3. I did not use these ports for interrupt. I use IRQ_F2P port of PS. I think my approach is somehow unorthodox, not the best practice?

 

I will look the answers of these questions.

 

Regards,

 

bbinb

0 Kudos
Contributor
Contributor
2,684 Views
Registered: ‎07-09-2014

Re: AXI4-Stream module in custom IP [How to use?]

Jump to solution

I created a new post about PS DMA baremetal example and share my codes there in Zynq All Programmable SoC part of the forum.

 

link

0 Kudos