一种在block design中,使用dma+fifo+触发模块的采集模式记录

  这个方式其实比较麻烦,但是确实是可用的,简单来讲,就是用普通FIFO代替了stream fifo 来实现稳定,大容量的dma传输(代码在最后面),这边做下记录(实际最好还是用stream fifo),不过还是建议使用我另一篇随笔里的方法。https://www.cnblogs.com/daydaygood/p/18811676

  Get_trigger_and_data模块是用来给fifo产生数据、写时钟和写使能,在fifo full信号满的时候停止写使能,在外部start_flag信号为高的时候开始写使能。
  jesd_data_parse模块是自定义axi模块,用来给fifo产生读时钟和读使能,读时钟是固定的,读使能来自后级dma驱动的ready和jesd_daa_parse模块里vallid信号的耦合,这里其实做了一步数据位宽转换,64-32。

  jesd_data_parse模块与后级的dma模块相连接。

  所有关联的模块的复位信号来自于dma的复位信号输出。写时钟250MHz,数据64位宽,读时钟100MHz,数据32位宽。

  下面是IP核具体设置,实际可根据经验和需求自行打磨。

  下面是rtl和自定义IP核代码,实际可根据经验和需求自行打磨。

点击查看代码
`timescale 1ns / 1ps

module Get_trigger_and_data_generate(
    input   wire            M_AXIS_ACLK,
    input   wire            M_AXIS_ARESETN,

    input   wire            glblclk,
    input 	wire	[63:0]	rx_data,
    input 	wire			start_flag,
    input   wire            full,

    output  wire    [63:0]  adc_data_64,
    output  reg             wr_en,    
    output  wire            wr_clk  
    );

wire	[15:0]	adc_sample_1;
wire	[15:0]	adc_sample_2;
wire	[15:0]	adc_sample_3;
wire	[15:0]	adc_sample_4;

assign	adc_sample_1	=	{{2{rx_data[31]}}, rx_data[31:24], rx_data[63:58]};
assign	adc_sample_2	=	{{2{rx_data[23]}}, rx_data[23:16], rx_data[55:50]};
assign	adc_sample_3	=	{{2{rx_data[15]}}, rx_data[15: 8], rx_data[47:42]};
assign	adc_sample_4	=	{{2{rx_data[ 7]}}, rx_data[7 : 0], rx_data[39:34]};

assign adc_data_64 = {adc_sample_4,adc_sample_3,adc_sample_2,adc_sample_1};

	// for fifo wr_en 
always @(posedge M_AXIS_ACLK) begin
    if (!M_AXIS_ARESETN) begin
        wr_en	<=	1'd0;
    end	else	if (full) begin
        wr_en	<=	1'd0;
    end	else	if (start_flag) begin
        wr_en	<=	1'd1;
    end
end

assign wr_clk = glblclk;

endmodule

点击查看代码

`timescale 1 ns / 1 ps

	module jesd_data_parse_v1_0_M00_AXIS #
	(
		// 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.
		parameter integer C_M_AXIS_TDATA_WIDTH	= 32,
		// Start count is the number of clock cycles the master will wait before initiating/issuing any transaction.
		parameter integer C_M_START_COUNT	= 32
	)
	(
		// Users to add ports here
		output 	wire			rd_clk,
		output 	wire 			rd_en,
		input	wire	[31:0]	data,
		
		// User ports ends
		// Do not modify the ports beyond this line

		// Global ports
		input wire  M_AXIS_ACLK,
		// 
		input wire  M_AXIS_ARESETN,
		// Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. 
		output wire  M_AXIS_TVALID,
		// TDATA is the primary payload that is used to provide the data that is passing across the interface from the master.
		output wire [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA,
		// 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.
		output wire [(C_M_AXIS_TDATA_WIDTH/8)-1 : 0] M_AXIS_TSTRB,
		// TLAST indicates the boundary of a packet.
		output wire  M_AXIS_TLAST,
		// TREADY indicates that the slave can accept a transfer in the current cycle.
		input wire  M_AXIS_TREADY
	);
	// Total number of output data                                                 
	localparam NUMBER_OF_OUTPUT_WORDS = 8192;                                               
	                                                                                     
	// function called clogb2 that returns an integer which has the                      
	// value of the ceiling of the log base 2.                                           
	function integer clogb2 (input integer bit_depth);                                   
	  begin                                                                              
	    for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                                      
	      bit_depth = bit_depth >> 1;                                                    
	  end                                                                                
	endfunction                                                                          
	                                                                                     
	// WAIT_COUNT_BITS is the width of the wait counter.                                 
	localparam integer WAIT_COUNT_BITS = clogb2(C_M_START_COUNT-1);                      
	                                                                                     
	// bit_num gives the minimum number of bits needed to address 'depth' size of FIFO.  
	localparam bit_num  = clogb2(NUMBER_OF_OUTPUT_WORDS);                                
	                                                                                     
	// 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                                      
	localparam [1:0] IDLE = 2'b00,        // This is the initial/idle state               
	                                                                                     
	                INIT_COUNTER  = 2'b01, // This state initializes the counter, once   
	                                // the counter reaches C_M_START_COUNT count,        
	                                // the state machine changes state to SEND_STREAM     
	                SEND_STREAM   = 2'b10; // In this state the                          
	                                     // stream data is output through M_AXIS_TDATA   
	// State variable                                                                    
	reg [1:0] mst_exec_state;                                                            
	// Example design FIFO read pointer                                                  
	reg [bit_num-1:0] read_pointer;                                                      

	// AXI Stream internal signals
	//wait counter. The master waits for the user defined number of clock cycles before initiating a transfer.
	reg [WAIT_COUNT_BITS-1 : 0] 	count;
	//streaming data valid
	wire  	axis_tvalid;
	//streaming data valid delayed by one clock cycle
	reg  	axis_tvalid_delay;
	//Last of the streaming data 
	wire  	axis_tlast;
	//Last of the streaming data delayed by one clock cycle
	reg  	axis_tlast_delay;
	//FIFO implementation signals
	wire 	[C_M_AXIS_TDATA_WIDTH-1 : 0] 	stream_data_out;
	wire  	tx_en;
	//The master has issued all the streaming data stored in FIFO
	reg  	tx_done;
	// I/O Connections assignments

	assign M_AXIS_TVALID	= axis_tvalid_delay;
	assign M_AXIS_TDATA		= stream_data_out;
	assign M_AXIS_TLAST		= axis_tlast_delay;
	assign M_AXIS_TSTRB		= {(C_M_AXIS_TDATA_WIDTH/8){1'b1}};


	// Control state machine implementation                             
	always @(posedge M_AXIS_ACLK)                                             
	begin                                                                     
	  if (!M_AXIS_ARESETN)                                                    
	  // Synchronous reset (active low)                                       
	    begin                                                                 
	      mst_exec_state <= IDLE;                                             
	      count    <= 0;                                                      
	    end                                                                   
	  else                                                                    
	    case (mst_exec_state)                                                 
	      IDLE:                                                               
	        // The slave starts accepting tdata when                          
	        // there tvalid is asserted to mark the                           
	        // presence of valid streaming data                               
	        //if ( count == 0 )                                                 
		  	begin                                                           
				mst_exec_state  <= INIT_COUNTER;
				count    <= 0;                               
			end                                                             
	        //else                                                              
	        //  begin                                                           
	        //    mst_exec_state  <= IDLE;                                      
	        //  end                                                                                                                                
	      INIT_COUNTER:                                                       
	        // The slave starts accepting tdata when                          
	        // there tvalid is asserted to mark the                           
	        // presence of valid streaming data                               
	        if ( count == C_M_START_COUNT - 1 )                               
	          begin                                                           
	            mst_exec_state  <= SEND_STREAM;                               
	          end                                                             
	        else                                                              
	          begin                                                           
	            count <= count + 1;                                           
	            mst_exec_state  <= INIT_COUNTER;                              
	          end                                                             
	                                                                          
	      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)                                                      
	          begin                                                           
	            mst_exec_state <= IDLE;                                       
	          end                                                             
	        else                                                              
	          begin                                                           
	            mst_exec_state <= SEND_STREAM;                                
	          end                                                             
	    endcase                                                               
	end                                                                       


	//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.
	assign axis_tvalid = ((mst_exec_state == SEND_STREAM) && (read_pointer < NUMBER_OF_OUTPUT_WORDS));
	                                                                                               
	// 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)                                                             
	assign axis_tlast = (read_pointer == NUMBER_OF_OUTPUT_WORDS-1);                                                                                                            
	                                                                                               
	// Delay the axis_tvalid and axis_tlast signal by one clock cycle                              
	// to match the latency of M_AXIS_TDATA                                                        
	always @(posedge M_AXIS_ACLK)                                                                  
	begin                                                                                          
	  if (!M_AXIS_ARESETN)                                                                         
	    begin                                                                                      
	      axis_tvalid_delay <= 1'b0;                                                               
	      axis_tlast_delay <= 1'b0;                                                                
	    end                                                                                        
	  else                                                                                         
	    begin                                                                                      
	      axis_tvalid_delay <= axis_tvalid;                                                        
	      axis_tlast_delay <= axis_tlast;                                                          
	    end                                                                                        
	end                                                                                            


	//read_pointer pointer

	always@(posedge M_AXIS_ACLK)   begin                                                                            
	    if(!M_AXIS_ARESETN)   begin                                                                        
	      read_pointer  <= 0;                                                         
	      tx_done       <= 1'b0;                                                           
	    end else  case (mst_exec_state)
        SEND_STREAM :begin
            if (read_pointer <= NUMBER_OF_OUTPUT_WORDS-1)   begin               
              tx_done <= 1'b0;                                                           
              if (tx_en)                                                               
                // read pointer is incremented after every read from the FIFO          
                // when FIFO read signal is enabled.                                   
                begin                                                                  
                  read_pointer <= read_pointer + 1;                                                                                     
                end                                                                    
            end else    begin                                                                      
              // tx_done is asserted when NUMBER_OF_OUTPUT_WORDS numbers of streaming data
              // has been out.                                                      
              tx_done 	 <= 1'b1;                                                         
            end                        
        end
        default: begin
            read_pointer    <= 0;
            tx_done         <= 1'b0;  
        end
      endcase                                                                           
end                                                                           

assign tx_en = M_AXIS_TREADY && axis_tvalid;
assign rd_clk	= 	M_AXIS_ACLK;
assign rd_en	=	tx_en;
assign stream_data_out = data;

	//FIFO read enable generation 	
	// Add user logic here


endmodule