10-16-2013 06:56 AM
I am currently trying to set up the Xilinx FFT IP core. I am using the ZED Board to test my design. All I want to do at the moment is to send one frame of time domain data to the core and receive the corresponding frequency domain data.
I connected a DMA engine in SG mode to the ARM core in XPS. After that I declared the AXI stream pins as external ports in order to feed them to the PL side.
I then generated a FFT core and instantiated/connected it in the Top HDL file of my project. (I wasn't able to import the core via the import peripheral wizard in XPS)
I then adapted the example c code of the DMA (SG Mode Interrupt Based).
Now I am kind of stuck. I was wondering if this is the right way to achieve my goal or whether there is an easier one. ( I am completely new to Xilinx Tools, AXI, AXI stream, IP integration etc.)
Could you please tell me which files/information you need in order to help me?
Thanks in advance!
10-16-2013 09:23 AM
10-17-2013 12:24 AM
thanks for your reply. So far they have been more like fair-weather friends to me ;)
When I run the application in the debugger I see the following:
I receive the tx interrupt. The handler is able to transfer the BD from the post work to the free group. The global TxDone flag gets incremented.
Next I receive the rx interrupt. The handler looks for post work BD but doesn't find any hence the RxDone flag does not get incremented -> stuck in the NOP loop. (no more interrupts occurring)
I connected some buffered debug LED to the event signals. After running the code it shows the following status
signal event_tlast_unexpected (OFF)
signal event_tlast_missing (OFF)
I also connected debug LED to the handshake pins of the 3 stream interfaces like this
debug_dma_to_fft_handshake_payload : process (processing_system7_0_FCLK_CLK0_pin) begin if BTNC = '1' then LD7 <= '0'; elsif rising_edge(processing_system7_0_FCLK_CLK0_pin) and axi_dma_0_m_axis_mm2s_tready_pin = '1' and axi_dma_0_m_axis_mm2s_tvalid_pin = '1' then LD7 <= '1'; end if; end process;
My FFT is instantiated like this in the top HDL file
myFFT : xfft_v8_0 PORT MAP ( aclk => processing_system7_0_FCLK_CLK0_pin, aresetn => '1',--processing_system7_0_FCLK_RESET0_N_pin, s_axis_config_tdata => s_axis_config_tdata, s_axis_config_tvalid => axi_dma_0_m_axis_mm2s_cntrl_tvalid_pin, s_axis_config_tready => axi_dma_0_m_axis_mm2s_cntrl_tready_pin, s_axis_data_tdata => axi_dma_0_m_axis_mm2s_tdata_pin, s_axis_data_tvalid => axi_dma_0_m_axis_mm2s_tvalid_pin, s_axis_data_tready => axi_dma_0_m_axis_mm2s_tready_pin, s_axis_data_tlast => axi_dma_0_m_axis_mm2s_tlast_pin, m_axis_data_tdata => axi_dma_0_s_axis_s2mm_tdata_pin, m_axis_data_tvalid => axi_dma_0_s_axis_s2mm_tvalid_pin, m_axis_data_tready => axi_dma_0_s_axis_s2mm_tready_pin, m_axis_data_tlast => axi_dma_0_s_axis_s2mm_tlast_pin, event_frame_started => event_frame_started, event_tlast_unexpected => event_tlast_unexpected, event_tlast_missing => event_tlast_missing--, --event_status_channel_halt => event_status_channel_halt, --event_data_in_channel_halt => event_data_in_channel_halt, --event_data_out_channel_halt => event_data_out_channel_halt ); axi_dma_0_s_axis_s2mm_tkeep_pin <= "1111";--(others => axi_dma_0_s_axis_s2mm_tvalid_pin); s_axis_config_tdata <= axi_dma_0_m_axis_mm2s_cntrl_tdata_pin(23 downto 0);
signal axi_dma_0_s_axis_s2mm_tvalid_pin : std_logic; signal axi_dma_0_s_axis_s2mm_tdata_pin : std_logic_vector(31 downto 0); signal axi_dma_0_s_axis_s2mm_tready_pin : std_logic; signal axi_dma_0_s_axis_s2mm_tlast_pin : std_logic; signal axi_dma_0_s_axis_s2mm_tkeep_pin : std_logic_vector(3 downto 0); signal axi_dma_0_m_axis_mm2s_tdata_pin : std_logic_vector(31 downto 0); signal axi_dma_0_m_axis_mm2s_tlast_pin : std_logic; signal axi_dma_0_m_axis_mm2s_tvalid_pin : std_logic; signal axi_dma_0_m_axis_mm2s_tready_pin : std_logic; signal axi_dma_0_m_axis_mm2s_cntrl_tvalid_pin : std_logic; signal axi_dma_0_m_axis_mm2s_cntrl_tready_pin : std_logic; signal axi_dma_0_m_axis_mm2s_cntrl_tdata_pin : std_logic_vector(31 downto 0); signal processing_system7_0_FCLK_CLK0_pin : std_logic; signal processing_system7_0_FCLK_RESET0_N_pin : std_logic; signal s_axis_config_tdata : std_logic_vector(23 downto 0); signal event_frame_started : std_logic := '0'; signal event_tlast_unexpected : std_logic := '0'; signal event_tlast_missing : std_logic := '0';
Your help is very much apprechiated.
10-18-2013 04:45 AM
In the meantime I completed some ChipScope tutorials to learn how to set it up.
Here is a plot of the AXIS data channel (FFT--->DMA) trafic.
So apparently the core is outputing something and the handshake mechanism seems to work as well.
I also looked at the control stream:
I have some questions regarding the above graph
In the datasheet of the DMA v6.03a I can see that there should only be 5 user application fields per byte descriptor.
Does the fact that the zero-valued app words are transmitted imply that the FFT gets configured multiple times in inverse FFT mode without any scaling?
Your help is apprechiated!
10-24-2013 01:44 AM
some more observations:
I activated the XK_INDEX option of the FFT. When I trigger on XK_INDEX = 1023 I see that this is the last valid transmission from the FFT to the DMA so apparently the core is working correctly.
I also wrote some custom vhdl code to block all but one transmissions on the ctrl channel in order to prevent the FFT from queueing unwanted configurations. The DMA is supposed to send 5 application words on the control channel per frame but a measurement in chip scope reveals that it is in fact transmitting 6 words. You can see that in the following screenshot (I already adapted my code to block 5 out of 6 transmissions)
This is how I set the 5 app words
Status = XAxiDma_BdSetAppWord(BdCurPtr,0,0); Status = XAxiDma_BdSetAppWord(BdCurPtr,1,1); Status = XAxiDma_BdSetAppWord(BdCurPtr,2,2); Status = XAxiDma_BdSetAppWord(BdCurPtr,3,3); Status = XAxiDma_BdSetAppWord(BdCurPtr,XAXIDMA_LAST_APPWORD ,FFTCtrlSequence);