4.PS配置VDMA改PL配置VDMA

1.简介

  在没有arm核的情况下,PL端IP核需要自己编写axi_lite协议来配置IP核,在VDMA视频流通路搭建项目中,arm核的作用是提供DDR3控制接口以及用axi_lite来配置VDMA IP核,这里我们将配置IP核的部分放到PL端来实现。实现了一个axi_master_lite IP核接口,以后其他的axi_slave_lite 都可以使用此IP核进行控制。

2.AXI_MASTER_LITE

`timescale 1 ns / 1 ps

	module axi_lite_master #
	(
		// Users to add parameters here		
		// User parameters ends
		// Do not modify the parameters beyond this line

		// The master requires a target slave base address.
    // The master will initiate read and write transactions on the slave with base address specified here as a parameter.
		parameter  C_M_TARGET_SLAVE_BASE_ADDR	= 32'h00000000,
		// Width of M_AXI address bus. 
    // The master generates the read and write addresses of width specified as C_M_AXI_ADDR_WIDTH.
		parameter integer C_M_AXI_ADDR_WIDTH	= 32,
		// Width of M_AXI data bus. 
    // The master issues write data and accept read data where the width of the data bus is C_M_AXI_DATA_WIDTH
		parameter integer C_M_AXI_DATA_WIDTH	= 32
    // and read transactions the master will perform as a part of this example memory test.
	)
	(
		// Users to add ports here
 		input 	wire  [C_M_AXI_ADDR_WIDTH-1: 0]		wr_addr 	,
  		input  	wire   		 						wr_start 	,
 		input 	wire  [C_M_AXI_ADDR_WIDTH-1 :0]		wr_data 	,
 		output 	reg  		 						wr_done  	,

 		input  	wire  [C_M_AXI_ADDR_WIDTH-1 :0] 	rd_addr 	,
 		input 	wire   		 	  					rd_start 	,
 		output 	reg   [C_M_AXI_ADDR_WIDTH-1 :0]		rd_data 	,
 		output 	reg   		 						rd_done 	,
		// User ports ends
		// Do not modify the ports beyond this line

		// Initiate AXI transactions
		// Asserts when ERROR is detected
		// Asserts when AXI transactions is complete
		// AXI clock signal
		input wire  M_AXI_ACLK,
		// AXI active low reset signal
		input wire  M_AXI_ARESETN,
		// Master Interface Write Address Channel ports. Write address (issued by master)
		output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
		// Write channel Protection type.
    // This signal indicates the privilege and security level of the transaction,
    // and whether the transaction is a data access or an instruction access.
		output wire [2 : 0] M_AXI_AWPROT,
		// Write address valid. 
    // This signal indicates that the master signaling valid write address and control information.
		output wire  M_AXI_AWVALID,
		// Write address ready. 
    // This signal indicates that the slave is ready to accept an address and associated control signals.
		input wire  M_AXI_AWREADY,
		// Master Interface Write Data Channel ports. Write data (issued by master)
		output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA,
		// Write strobes. 
    // This signal indicates which byte lanes hold valid data.
    // There is one write strobe bit for each eight bits of the write data bus.
		output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
		// Write valid. This signal indicates that valid write data and strobes are available.
		output wire  M_AXI_WVALID,
		// Write ready. This signal indicates that the slave can accept the write data.
		input wire  M_AXI_WREADY,
		// Master Interface Write Response Channel ports. 
    // This signal indicates the status of the write transaction.
		input wire [1 : 0] M_AXI_BRESP,
		// Write response valid. 
    // This signal indicates that the channel is signaling a valid write response
		input wire  M_AXI_BVALID,
		// Response ready. This signal indicates that the master can accept a write response.
		output wire  M_AXI_BREADY,
		// Master Interface Read Address Channel ports. Read address (issued by master)
		output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
		// Protection type. 
    // This signal indicates the privilege and security level of the transaction, 
    // and whether the transaction is a data access or an instruction access.
		output wire [2 : 0] M_AXI_ARPROT,
		// Read address valid. 
    // This signal indicates that the channel is signaling valid read address and control information.
		output wire  M_AXI_ARVALID,
		// Read address ready. 
    // This signal indicates that the slave is ready to accept an address and associated control signals.
		input wire  M_AXI_ARREADY,
		// Master Interface Read Data Channel ports. Read data (issued by slave)
		input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA,
		// Read response. This signal indicates the status of the read transfer.
		input wire [1 : 0] M_AXI_RRESP,
		// Read valid. This signal indicates that the channel is signaling the required read data.
		input wire  M_AXI_RVALID,
		// Read ready. This signal indicates that the master can accept the read data and response information.
		output wire  M_AXI_RREADY
	);

	// 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

	// TRANS_NUM_BITS is the width of the index counter for 
	// number of write or read transaction.

	// Example State machine to initialize counter, initialize write transactions, 
	// initialize read transactions and comparison of read data with the 
	// written data words.

	 reg [1:0] mst_exec_state;

	// AXI4LITE signals
	//write address valid
	reg  	axi_awvalid;
	//write data valid
	reg  	axi_wvalid;
	//read address valid
	reg  	axi_arvalid;
	//read data acceptance
	reg  	axi_rready;
	//write response acceptance
	reg  	axi_bready;
	//write address
	reg [C_M_AXI_ADDR_WIDTH-1 : 0] 	axi_awaddr;
	//write data
	reg [C_M_AXI_DATA_WIDTH-1 : 0] 	axi_wdata;
	//read addresss
	reg [C_M_AXI_ADDR_WIDTH-1 : 0] 	axi_araddr;
	//Asserts when there is a write response error
	wire  	write_resp_error;
	//Asserts when there is a read response error
	wire  	read_resp_error;
	//A pulse to initiate a write transaction
	reg  	start_single_write;
	//A pulse to initiate a read transaction
	reg  	start_single_read;
	//Asserts when a single beat write transaction is issued and remains asserted till the completion of write trasaction.
	reg  	write_issued;
	//Asserts when a single beat read transaction is issued and remains asserted till the completion of read trasaction.
	reg  	read_issued;
	//flag that marks the completion of write trasactions. The number of write transaction is user selected by the parameter C_M_TRANSACTIONS_NUM.
	reg  	writes_done;
	//flag that marks the completion of read trasactions. The number of read transaction is user selected by the parameter C_M_TRANSACTIONS_NUM
	reg  	reads_done;
	//The error register is asserted when any of the write response error, read response error or the data mismatch flags are asserted.
	reg  	error_reg;
	//Expected read data used to compare with the read data.
	//Flag marks the completion of comparison of the read data with the expected read data
	// I/O Connections assignments

	//Adding the offset address to the base addr of the slave
	assign M_AXI_AWADDR	= C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr;
	//AXI 4 write data
	assign M_AXI_WDATA	= axi_wdata;
	assign M_AXI_AWPROT	= 3'b000;
	assign M_AXI_AWVALID	= axi_awvalid;
	//Write Data(W)
	assign M_AXI_WVALID	= axi_wvalid;
	//Set all byte strobes in this example
	assign M_AXI_WSTRB	= 4'b1111;
	//Write Response (B)
	assign M_AXI_BREADY	= axi_bready;
	//Read Address (AR)
	assign M_AXI_ARADDR	= C_M_TARGET_SLAVE_BASE_ADDR + axi_araddr;
	assign M_AXI_ARVALID	= axi_arvalid;
	assign M_AXI_ARPROT	= 3'b001;
	//Read and Read Response (R)
	assign M_AXI_RREADY	= axi_rready;   

	//--------------------
	//Write Address Channel
	//--------------------
	  always @(posedge M_AXI_ACLK)										      
	  begin                                                                        
	    //Only VALID signals must be deasserted during reset per AXI spec          
	    //Consider inverting then registering active-low reset for higher fmax     
	    if (M_AXI_ARESETN == 0)                                                   
	      begin                                                                    
	        axi_awvalid <= 1'b0;                                                   
	      end                                                                      
	      //Signal a new address/data command is available by user logic           
	    else                                                                       
	      begin                                                                    
	        if (wr_start)                                                
	          begin                                                                
	            axi_awvalid <= 1'b1;                                               
	          end                                                                  
	     //Address accepted by interconnect/slave (issue of M_AXI_AWREADY by slave)
	        else if (M_AXI_AWREADY && axi_awvalid)                                 
	          begin                                                                
	            axi_awvalid <= 1'b0;                                               
	          end                                                                  
	      end                                                                      
	  end                                                                                                                                                   

	//--------------------
	//Write Data Channel
	//--------------------

	//The write data channel is for transfering the actual data.
	//The data generation is speific to the example design, and 
	//so only the WVALID/WREADY handshake is shown here

	   always @(posedge M_AXI_ACLK)                                        
	   begin                                                                         
	     if (M_AXI_ARESETN == 0)                                                    
	       begin                                                                     
	         axi_wvalid <= 1'b0;                                                     
	       end                                                                       
	     //Signal a new address/data command is available by user logic              
	     else if (wr_start)                                                
	       begin                                                                     
	         axi_wvalid <= 1'b1;                                                     
	       end                                                                       
	     //Data accepted by interconnect/slave (issue of M_AXI_WREADY by slave)      
	     else if (M_AXI_WREADY && axi_wvalid)                                        
	       begin                                                                     
	        axi_wvalid <= 1'b0;                                                      
	       end                                                                       
	   end  

	  always @(posedge M_AXI_ACLK)                                  
	      begin                                                     
	        if (M_AXI_ARESETN == 0 )                                
	          begin                                                 
	            wr_done <= 0;             
	          end                                                   
	          // Signals a new write address/ write data is         
	          // available by user logic                            
	        else if (M_AXI_WREADY && axi_wvalid)                    
	          begin                                                 
	            wr_done <= 1;
	          end
	        else 
	          begin                                                 
	            wr_done <= 0;
	          end                                               
	      end                                                               


	//----------------------------
	//Write Response (B) Channel
	//----------------------------

	//The write response channel provides feedback that the write has committed
	//to memory. BREADY will occur after both the data and the write address
	//has arrived and been accepted by the slave, and can guarantee that no
	//other accesses launched afterwards will be able to be reordered before it.

	//The BRESP bit [1] is used indicate any errors from the interconnect or
	//slave for the entire write burst. This example will capture the error.

	//While not necessary per spec, it is advisable to reset READY signals in
	//case of differing reset latencies between master/slave.

	  always @(posedge M_AXI_ACLK)                                    
	  begin                                                                
	    if (M_AXI_ARESETN == 0)                                           
	      begin                                                            
	        axi_bready <= 1'b0;                                            
	      end                                                              
	    // accept/acknowledge bresp with axi_bready by the master          
	    // when M_AXI_BVALID is asserted by slave                          
	    else if (M_AXI_BVALID && ~axi_bready)                              
	      begin                                                            
	        axi_bready <= 1'b1;                                            
	      end                                                              
	    // deassert after one clock cycle                                  
	    else if (axi_bready)                                               
	      begin                                                            
	        axi_bready <= 1'b0;                                            
	      end                                                              
	    // retain the previous value                                       
	    else                                                               
	      axi_bready <= axi_bready;                                        
	  end                                                                  
	                                                                       
	//Flag write errors                                                    
	assign write_resp_error = (axi_bready & M_AXI_BVALID & M_AXI_BRESP[1]);


	//----------------------------
	//Read Address Channel
	//----------------------------                                                                                                                                                              
	  // A new axi_arvalid is asserted when there is a valid read address              
	  // available by the master. start_single_read triggers a new read                
	  // transaction                                                                   
	  always @(posedge M_AXI_ACLK)                                                     
	  begin                                                                            
	    if (M_AXI_ARESETN == 0)                                                       
	      begin                                                                        
	        axi_arvalid <= 1'b0;                                                       
	      end                                                                          
	    //Signal a new read address command is available by user logic                 
	    else if (rd_start)                                                    
	      begin                                                                        
	        axi_arvalid <= 1'b1;                                                       
	      end                                                                          
	    //RAddress accepted by interconnect/slave (issue of M_AXI_ARREADY by slave)    
	    else if (M_AXI_ARREADY && axi_arvalid)                                         
	      begin                                                                        
	        axi_arvalid <= 1'b0;                                                       
	      end                                                                          
	    // retain the previous value                                                   
	  end                                                                              


	//--------------------------------
	//Read Data (and Response) Channel
	//--------------------------------

	//The Read Data channel returns the results of the read request 
	//The master will accept the read data by asserting axi_rready
	//when there is a valid read data available.
	//While not necessary per spec, it is advisable to reset READY signals in
	//case of differing reset latencies between master/slave.

	  always @(posedge M_AXI_ACLK)                                    
	  begin                                                                 
	    if (M_AXI_ARESETN == 0)                                            
	      begin                                                             
	        axi_rready <= 1'b0;                                             
	      end                                                               
	    // accept/acknowledge rdata/rresp with axi_rready by the master     
	    // when M_AXI_RVALID is asserted by slave                           
	    else if (M_AXI_RVALID && ~axi_rready)                               
	      begin                                                             
	        axi_rready <= 1'b1;                                             
	      end                                                               
	    // deassert after one clock cycle                                   
	    else if (axi_rready)                                                
	      begin                                                             
	        axi_rready <= 1'b0;                                             
	      end                                                               
	    // retain the previous value                                        
	  end                                                                   
	                                                                        
	//Flag write errors                                                     
	assign read_resp_error = (axi_rready & M_AXI_RVALID & M_AXI_RRESP[1]);  


	//--------------------------------
	//User Logic
	//--------------------------------

	//Address/Data Stimulus

	//Address/data pairs for this example. The read and write values should
	//match.
	//Modify these as desired for different address patterns.

	  //Write Addresses                                        
	  always @(posedge M_AXI_ACLK)                                  
	      begin                                                     
	        if (M_AXI_ARESETN == 0)                                
	          begin                                                 
	            axi_awaddr <= 0;                                    
	          end                                                   
	          // Signals a new write address/ write data is         
	          // available by user logic                            
	        else if (wr_start)                  
	          begin                                                 
	            axi_awaddr <= wr_addr;                                                        
	          end                                                   
	      end                                                       
	                                                                
	  // Write data generation                                      
	  always @(posedge M_AXI_ACLK)                                  
	      begin                                                     
	        if (M_AXI_ARESETN == 0)                                
	          begin                                                 
	            axi_wdata <= 0;                  
	          end                                                   
	        // Signals a new write address/ write data is           
	        // available by user logic                              
	        else if (wr_start)                    
	          begin                                                 
	            axi_wdata <= wr_data;    
	          end                                                   
	        end          	                                       
	                                                                
	  //Read Addresses                                              
	  always @(posedge M_AXI_ACLK)                                  
	      begin                                                     
	        if (M_AXI_ARESETN == 0)                                
	          begin                                                 
	            axi_araddr <= 0;                                    
	          end                                                   
	          // Signals a new write address/ write data is         
	          // available by user logic                            
	        else if (rd_start)                  
	          begin                                                 
	            axi_araddr <= rd_addr;            
	          end                                                   
	      end                                                       
	                                                                
	                                                                
	                                                                
	  always @(posedge M_AXI_ACLK)                                  
	      begin                                                     
	        if (M_AXI_ARESETN == 0 )                                
	          begin                                                 
	            rd_data <= 0;             
	          end                                                   
	          // Signals a new write address/ write data is         
	          // available by user logic                            
	        else if (M_AXI_RVALID && axi_rready)                    
	          begin                                                 
	            rd_data <= M_AXI_RDATA;
	          end                                                   
	      end 

	  always @(posedge M_AXI_ACLK)                                  
	      begin                                                     
	        if (M_AXI_ARESETN == 0 )                                
	          begin                                                 
	            rd_done <= 0;             
	          end                                                   
	          // Signals a new write address/ write data is         
	          // available by user logic                            
	        else if (M_AXI_RVALID && axi_rready)                    
	          begin                                                 
	            rd_done <= 1;
	          end
	        else 
	          begin                                                 
	            rd_done <= 0;
	          end                                               
	      end                                                                                                        
	// Add user logic here

	// User logic ends

	endmodule

VMDA_CONFIG

module 	vdma_config(
 	input 	wire 	 		clk 		,
 	input 	wire 	 		rst_n 		,
 	
 	output 	reg 			wr_start 	,
 	output 	wire 	[31:0] 	wr_addr 	,
 	output 	wire 	[31:0] 	wr_data 	,
 	input 	wire  			wr_done 	,

 	output 	wire 			rd_start 	,
 	output 	wire 	[31:0] 	rd_addr 	,
 	input 	wire 	[31:0] 	rd_data 	,
 	input 	wire  			rd_done 				
);
localparam 	REG_NUM 	 	= 	14 	 		;
localparam 	VDMA_BASEADDR 	= 	32'h43000000;

localparam  VIDEO_BASEADDR0 = 	32'h01000000;
localparam  VIDEO_BASEADDR1 = 	32'h02000000;
localparam  VIDEO_BASEADDR2 = 	32'h03000000;

localparam  H_ACTIVE		= 	32'h780		;
localparam  V_ACTIVE		= 	32'h438		;
localparam  H_STRIDE		= 	32'h780		;

reg 	[$clog2(REG_NUM) - 1:0] 	wr_cnt;
reg 	[$clog2(REG_NUM) - 1:0] 	rd_cnt;

reg 	[1:0] 	config_valid_r ;
always @(posedge clk)begin
	config_valid_r <= {config_valid_r[0],rst_n};
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 0) begin
 		wr_start 	<= 0;
	end
	else if ((wr_done == 1 && wr_cnt != REG_NUM) || config_valid_r == 2'b01) begin
		wr_start 	<= 1'b1;
	end
	else begin
		wr_start 	<= 1'b0;
	end
end

always @(posedge clk or negedge rst_n) begin
	if(rst_n ==0) begin
		wr_cnt 	<= 0;
	end
	else if(wr_start)begin
		wr_cnt 	<= wr_cnt + 1;
	end
end

reg 	[63:0] 	vdma_data;
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		vdma_data 	<= 	64'h0 ;
	end
	else begin
		case(wr_cnt)
		 	10'd0 	: 	vdma_data <= {VDMA_BASEADDR + 32'h030,32'h108B};
		 	10'd1 	: 	vdma_data <= {VDMA_BASEADDR + 32'h0AC,VIDEO_BASEADDR0};
		 	10'd2 	: 	vdma_data <= {VDMA_BASEADDR + 32'h0B0,VIDEO_BASEADDR1};
		 	10'd3 	: 	vdma_data <= {VDMA_BASEADDR + 32'h0B4,VIDEO_BASEADDR2};
		 	10'd4 	: 	vdma_data <= {VDMA_BASEADDR + 32'h0A8,H_STRIDE};
		 	10'd5 	: 	vdma_data <= {VDMA_BASEADDR + 32'h0A4,H_ACTIVE};
		 	10'd6 	: 	vdma_data <= {VDMA_BASEADDR + 32'h0A0,V_ACTIVE};

		 	10'd7 	: 	vdma_data <= {VDMA_BASEADDR + 32'h000,32'h8B};
		 	10'd8 	: 	vdma_data <= {VDMA_BASEADDR + 32'h05C,VIDEO_BASEADDR0};
		 	10'd9 	: 	vdma_data <= {VDMA_BASEADDR + 32'h060,VIDEO_BASEADDR1};
		 	10'd10 	: 	vdma_data <= {VDMA_BASEADDR + 32'h064,VIDEO_BASEADDR2};
		 	10'd11	: 	vdma_data <= {VDMA_BASEADDR + 32'h058,H_STRIDE};
		 	10'd12	: 	vdma_data <= {VDMA_BASEADDR + 32'h054,H_ACTIVE};
		 	10'd13	: 	vdma_data <= {VDMA_BASEADDR + 32'h050,V_ACTIVE};
		 	default: 	vdma_data <= 0;
		endcase
	end
end

assign 	wr_addr 	= 	vdma_data[63:32];
assign 	wr_data 	= 	vdma_data[31:0 ];
assign 	rd_start 	= 	0;
assign  rd_addr     =   0;
endmodule

改造后的接线图

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值