AXI4_Stream ADC DAC代码 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

ADC


`timescale 1 ns / 1 ps

	module adc_v1_0_M00_AXIS #
	(
		// Users to add parameters here
		parameter IDLE = 3'b001,
		parameter ARBIT = 3'b010,
		parameter READ = 3'b100,
		parameter BURST_MAX = 2048 - 1,
		parameter THRESHOLD = 1022,
		// 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
		input	wire 			adc_clk 	,
		input	wire 			adc_data_vld,
		input	wire 	[7:0]	adc_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
	);

	wire 			axis_tvalid;
	wire 	[7:0]	axis_tdata;
	wire 			axis_tlast;

	wire 			rd_en 		;
	reg             tx_en      ;
	wire 	[7:0]	dout 		;
	wire 			full 		;
	wire 			empty	 	;
	wire 	[10:0]	rd_data_count;
	reg 	[12:0]	cnt_data 	;
	wire 			add_cnt_data;
	wire 			end_cnt_data; 


	reg 	[2:0] 	state 		;//鐘舵?佸瘎瀛樺櫒
	reg 			rd_start 	;
	// I/O Connections assignments

	assign M_AXIS_TVALID	      = axis_tvalid;
	assign M_AXIS_TDATA		= axis_tdata;
	assign M_AXIS_TLAST		= axis_tlast;
	assign M_AXIS_TSTRB		= {(C_M_AXIS_TDATA_WIDTH/8){1'b1}};

    assign rd_en = tx_en & M_AXIS_TREADY;
	assign axis_tdata = dout;
	assign axis_tlast = end_cnt_data;
	assign axis_tvalid = tx_en;

adc inst_adc_fifo (
  	.wr_clk(adc_clk),                // input wire wr_clk
  	.rd_clk(M_AXIS_ACLK),                // input wire rd_clk
  	.din(adc_data),                      // input wire [7 : 0] din
  	.wr_en(adc_data_vld),                  // input wire wr_en
  	.rd_en(rd_en),                  // input wire rd_en
  	.dout(dout),                    // output wire [7 : 0] dout
  	.full(full),                    // output wire full
  	.empty(empty),                  // output wire empty
  	.rd_data_count(rd_data_count)  // output wire [10 : 0] rd_data_count
);

//----------------state machine------------------
always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
	if (M_AXIS_ARESETN==1'b0) begin
		state <= IDLE;
	end
	else begin
		case(state)
			IDLE : begin
				state <= ARBIT;
			end

			ARBIT : begin
				if(rd_data_count >= THRESHOLD && M_AXIS_TREADY == 1'b1)begin
					state <= READ;
				end
				else begin
					state <= ARBIT;
				end
			end

			READ : begin
				if (end_cnt_data == 1'b1) begin
					state <= ARBIT;
				end
				else begin
					state <= READ;
				end
			end

			default :begin
				state <= IDLE;
			end
		endcase
	end
end

//----------------rd_start------------------
	always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN)begin                                                                          
	    if (M_AXIS_ARESETN == 0 )begin
	    	rd_start <= 1'b0;
	    end                  
	    else if (state == ARBIT && rd_data_count >= THRESHOLD && M_AXIS_TREADY == 1'b1) begin
	    	rd_start <= 1'b1;
	    end                                                             
	    else begin  
	    	rd_start <= 1'b0;
	    end                                                                      
	end   

//----------------tx_en------------------
	always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN)begin                                                                          
	    if (M_AXIS_ARESETN == 0 )begin
	    	tx_en <= 1'b0;
	    end                  
	    else if (rd_start == 1'b1) begin
	    	tx_en <= 1'b1;
	    end                                                             
	    else if (end_cnt_data == 1'b1) begin  
	    	tx_en <= 1'b0;
	    end                                                                      
	end   

//----------------cnt_data------------------
always @(posedge M_AXIS_ACLK or negedge M_AXIS_ARESETN) begin
	if (M_AXIS_ARESETN == 1'b0) begin
		cnt_data <= 'd0;
	end
	else if (add_cnt_data) begin
		if(end_cnt_data)
			cnt_data <= 'd0;
		else
			cnt_data <= cnt_data + 1'b1;
	end
end

assign add_cnt_data = tx_en & M_AXIS_TREADY ;
assign end_cnt_data = add_cnt_data && cnt_data == BURST_MAX;

wire    [31:0]  probe0;
assign probe0 = {
     axis_tvalid,
	 axis_tdata,
	 rd_data_count,
	 axis_tlast,
	 adc_data,
	 rd_start,
	 rd_en,
	 full,
	 M_AXIS_TREADY,
	 empty,
	 state
};

ila_0 inst_ila (
	.clk(M_AXIS_ACLK), // input wire clk


	.probe0(probe0) // input wire [31:0] probe0
);

	endmodule

DAC


`timescale 1 ns / 1 ps

	module dac_v1_0_S00_AXIS #
	(
		// Users to add parameters here
		parameter IDLE = 3'b001,
		parameter ARBIT = 3'b010,
		parameter READ = 3'b100,
		parameter THRESHOLD = 1022,
		// User parameters ends
		// Do not modify the parameters beyond this line

		// AXI4Stream sink: Data Width
		parameter integer C_S_AXIS_TDATA_WIDTH	= 32
	)
	(
		// Users to add ports here
		input 	wire			dac_clk_in 	,
		output 	wire  			dac_clk_out ,
		output  wire 	[7:0]	dac_data 	,	
		// User ports ends
		// Do not modify the ports beyond this line

		// AXI4Stream sink: Clock
		input wire  S_AXIS_ACLK,
		// AXI4Stream sink: Reset
		input wire  S_AXIS_ARESETN,
		// Ready to accept data in
		output wire  S_AXIS_TREADY,
		// Data in
		input wire [C_S_AXIS_TDATA_WIDTH-1 : 0] S_AXIS_TDATA,
		// Byte qualifier
		input wire [(C_S_AXIS_TDATA_WIDTH/8)-1 : 0] S_AXIS_TSTRB,
		// Indicates boundary of last packet
		input wire  S_AXIS_TLAST,
		// Data is in valid
		input wire  S_AXIS_TVALID
	);

//==========================================
//user signals
//==========================================
wire			wr_en		   	;
wire 			rd_en 		   	;
wire 			full 		   	;
wire 			empty 		   	;
wire 	[10:0]	rd_data_count 	;

reg 	[2:0] 	state 			;



assign S_AXIS_TREADY = 1'b1;	//一直准备好接收数据
assign wr_en = S_AXIS_TVALID & S_AXIS_TREADY;//向FIFO中写入数据
assign dac_clk_out = dac_clk_in;


dac_fifo inst_dac_fifo (
  	.wr_clk(S_AXIS_ACLK),                // input wire wr_clk
  	.rd_clk(dac_clk_in),                // input wire rd_clk
  	.din(S_AXIS_TDATA),                      // input wire [7 : 0] din
  	.wr_en(wr_en),                  // input wire wr_en
  	.rd_en(rd_en),                  // input wire rd_en
  	.dout(dac_data),                    // output wire [7 : 0] dout
  	.full(full),                    // output wire full
  	.empty(empty),                  // output wire empty
  	.rd_data_count(rd_data_count)  // output wire [10 : 0] rd_data_count
);

//----------------state machine------------------
always @(posedge dac_clk_in or negedge S_AXIS_ARESETN) begin
	if (S_AXIS_ARESETN==1'b0) begin
		state <= IDLE;
	end
	else begin
		case(state)
			IDLE : begin
				state <= ARBIT;
			end

			ARBIT : begin
				if(rd_data_count >= THRESHOLD)begin
					state <= READ;
				end
				else begin
					state <= ARBIT;
				end
			end

			READ : begin
				state <= READ;
			end

			default :begin
				state <= IDLE;
			end
		endcase
	end
end


//----------------rd_en------------------
assign rd_en = state==READ;



endmodule