基于 ZYNQ 的双目视觉图像采集系统设计(四)

这篇具有很好参考价值的文章主要介绍了基于 ZYNQ 的双目视觉图像采集系统设计(四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于 ZYNQ 的双目视觉图像采集系统设计(四),fpga开发

1、axi_hp0_wr.v 模块代码解析

        该模块实现 AXI HP 总线写入数据到 DDR3 的操作。该模块的接口如下。rst_n 为系统复位信号;i_clki_data_rst_ni_data_en i_data FPGA 逻辑需要写入到 DDR3 的数据输入接口。i_clk 为同步时钟信号,i_data_rst_n 用于复位 FIFOi_data_en 拉高表示数据总线 i_data有效,将被写入到 FIFO 中缓存。余下的 AXI_*信号为 AXI HP 总线接口,读取 FIFO 中的数据,送往 DDR3 的指定地址空间。

module axi_hp0_wr#(
				parameter STAR_ADDR = 32'h0100_0000)
			(
				//系统信号
			input				rst_n,                   
				//写入DDR3的数据         
			input				i_clk,
			input 				i_data_rst_n,			
			input				i_data_en,
			input[15:0]			i_data,
			
				//AXI总线时钟
			input				AXI_clk,
				//AXI写地址通道
			output reg[31:0]	AXI_awaddr,		
			output[3:0] 		AXI_awlen,		
			output[2:0] 		AXI_awsize,		
			output[1:0] 		AXI_awburst,	
			output[1:0]			AXI_awlock,		
			output[3:0] 		AXI_awcache,	
			output[2:0] 		AXI_awprot,		
			output[3:0] 		AXI_awqos,		
			output reg			AXI_awvalid,	
			input 				AXI_awready,	
				//AXI写数据通道
			output[63:0] 		AXI_wdata,		
			output[7:0] 		AXI_wstrb,		
			output reg			AXI_wlast,		
			output reg			AXI_wvalid,		
			input 				AXI_wready,	
				//AXI写响应通道
			input[5:0] 			AXI_bid,
			input[1:0] 			AXI_bresp,
			input 				AXI_bvalid,	
			output 				AXI_bready		
		);
     以下代码定义内部信号。
//内部信号申明
wire[7:0] 	wrfifo_data_count;	//FIFO可读数据数量
reg 		wrfifo_rden;		//FIFO读数据使能信号
reg[7:0] 	wrdata_num;			//写入DDR3数据计数器
reg[3:0]    cstate,nstate;		//状态寄存器

parameter AXI_BURST_LEN	= 16;
parameter STATE_RST  = 4'h0;	
parameter STATE_IDLE = 4'h1; 
parameter STATE_WADD = 4'h2;
parameter STATE_WDAT = 4'h3; 	 
parameter WRITE_DONE = 4'h4;    
        FIFO 例化如下。写入位宽 16bit ,读出位宽 64bit 。该 FIFO 缓存 FPGA 逻辑送来的数据,  
通过 AXI HP 总线,按照 burst 数量写入到 DDR3 中。
//缓存 FIFO,将数据从 i_clk 转到 AXI_clk 时钟域,位宽从 16bit 转到 64bit 
 
fifo_generator_0 uut_fifo_generator_0 ( 
 .rst(~i_data_rst_n), // input wire rst 
 .wr_clk(i_clk), // input wire wr_clk 
 .rd_clk(AXI_clk), // input wire rd_clk 
 .din(i_data), // input wire [15 : 0] din 
 .wr_en(i_data_en), // input wire wr_en 
 .rd_en(wrfifo_rden), // input wire rd_en 
 .dout(AXI_wdata), // output wire [63 : 0] dout 
 .full(), // output wire full 
 .empty(), // output wire empty 
 .rd_data_count(wrfifo_data_count) // output wire [7 : 0] rd_data_count 
);
输入复位信号打一拍,从 i_clk 时钟域同步到 AXI_clk 时钟域。
//将i_data_rst_n在AXI_clk时钟域打一拍
reg w_data_rst_n;

always @(posedge AXI_clk)
	w_data_rst_n <= i_data_rst_n; 		
       以下状态机设计,根据复位信号的变化,从复位状态 STATE_RST 到空闲状态 STATE_IDLE , 判断当 FIFO 中数据数量满足 1 burst 写入要求时,依次从空闲状态 STATE_IDLE --> 写地状态 STATE_WADD --> 写数据状态 STATE_WDAT --> 写入完成状态 STATE_DONE --> 空闲状态STATE_IDLE,如此往复。

基于 ZYNQ 的双目视觉图像采集系统设计(四),fpga开发

//AXI写状态机

always @(posedge AXI_clk or negedge rst_n) begin
	if(~rst_n)begin
		cstate <= STATE_RST;
	end
	else begin
		cstate <= nstate;
	end
end 
                                                     																										
always @( * ) begin
	case(cstate)
    STATE_RST: begin
        if(w_data_rst_n) nstate = STATE_IDLE;
        else nstate = STATE_RST;
    end
    STATE_IDLE: begin
		if(!w_data_rst_n) nstate = STATE_RST;
		else if(wrfifo_data_count >= 8'd16) nstate = STATE_WADD;
        else nstate = STATE_IDLE;
    end
	
	STATE_WADD: begin
		if(AXI_awvalid && AXI_awready) nstate = STATE_WDAT;
		else nstate = STATE_WADD;
	end    
    
	STATE_WDAT: begin
		if(wrdata_num >= (AXI_BURST_LEN+1)) nstate = WRITE_DONE;
        else nstate = STATE_WDAT;
    end
	WRITE_DONE: begin
		nstate = STATE_IDLE;
	end
    
    default: begin
        nstate = STATE_RST;
    end
endcase
end
以下逻辑在写数据状态 STATE_WDAT 下,对数据写入数量进行计数。
 //1 个 burst 写入数据的个数计数 
always @(posedge AXI_clk) begin 
 if (!rst_n) wrdata_num <= 'b0; 
 else if(cstate == STATE_WDAT) begin 
 if(wrdata_num == 8'd0) wrdata_num <= wrdata_num + 1'b1; 
 else if((wrdata_num <= AXI_BURST_LEN) && AXI_wready && AXI_wvalid) 
wrdata_num <= wrdata_num + 1'b1; 
 else wrdata_num <= wrdata_num; 
 end 
 else wrdata_num <= 'b0; 
end
以下逻辑控制产生 FIFO 读数据信号的产生,配合 AXI HP 总线写入数据的时序要求。
//FIFO 读取使能信号产生 
 
always @(*) begin 
 if (cstate == STATE_WDAT) begin 
 if(wrdata_num == 8'd0) wrfifo_rden <= 1'b1; 
 else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN) && AXI_wready 
&& AXI_wvalid) wrfifo_rden <= 1'b1; 
 else wrfifo_rden <= 1'b0; 
 end 
 else wrfifo_rden <= 1'b0; 
end
       以下逻辑产生 AXI HP 总线的写地址 AXI_awaddr 、写地址有效信号 AXI_awvalid 和最后一个写入数据指示信号 AXI_wlast
//AXI总线写数据时序产生

	//写地址产生
always @(posedge AXI_clk)begin
	if(cstate == STATE_RST) AXI_awaddr <= STAR_ADDR;
	else if(AXI_awvalid && AXI_awready) AXI_awaddr <= AXI_awaddr + AXI_BURST_LEN * 8;
end

	//写地址有效信号产生
always @(posedge AXI_clk) begin                                                                
	if (!rst_n) AXI_awvalid <= 1'b0;                                                               
	else if(cstate == STATE_WADD) begin
		if(AXI_awvalid && AXI_awready) AXI_awvalid <= 1'b0;                                                        
		else AXI_awvalid <= 1'b1;
	end
	else AXI_awvalid <= 1'b0;                                 
end    

	//写数据有效信号产生
always @(posedge AXI_clk) begin                                                                
	if (!rst_n) AXI_wvalid <= 1'b0;
	else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN)) AXI_wvalid <= 1'b1; 
	else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wvalid <= 1'b1;
	else AXI_wvalid <= 1'b0;                                 
end

	//写最后一个数据有效信号产生
always @(posedge AXI_clk) begin                                                                
	if (!rst_n) AXI_wlast <= 1'b0;                                                               
	else if((wrdata_num == (AXI_BURST_LEN - 1)) && AXI_wready && AXI_wvalid) AXI_wlast <= 1'b1;  
	else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wlast <= 1'b1;
	else AXI_wlast <= 1'b0;                                 
end
以下逻辑对 AXI HP 总线的一些信号赋常量值。
//-----------------------------------------------------------------------------
-- 
//AXI HP 总线固定赋值设置 
 
assign AXI_awsize = 3'b011; //8 Bytes per burst 
assign AXI_awburst = 2'b01; 
assign AXI_awlock = 2'b00; 
assign AXI_awcache = 4'b0010; 
assign AXI_awprot = 3'h0; 
assign AXI_awqos = 4'h0; 
assign AXI_wstrb = 8'hff; 
assign AXI_bready = 1'b1; 
assign AXI_awlen = AXI_BURST_LEN - 1; 

axi_hp0_wr.v

module axi_hp0_wr#(
				parameter STAR_ADDR = 32'h0100_0000)
			(
				//系统信号
			input				rst_n,                   
				//写入DDR3的数据         
			input				i_clk,
			input 				i_data_rst_n,			
			input				i_data_en,
			input[15:0]			i_data,
			
				//AXI总线时钟
			input				AXI_clk,
				//AXI写地址通道
			output reg[31:0]	AXI_awaddr,		
			output[3:0] 		AXI_awlen,		
			output[2:0] 		AXI_awsize,		
			output[1:0] 		AXI_awburst,	
			output[1:0]			AXI_awlock,		
			output[3:0] 		AXI_awcache,	
			output[2:0] 		AXI_awprot,		
			output[3:0] 		AXI_awqos,		
			output reg			AXI_awvalid,	
			input 				AXI_awready,	
				//AXI写数据通道
			output[63:0] 		AXI_wdata,		
			output[7:0] 		AXI_wstrb,		
			output reg			AXI_wlast,		
			output reg			AXI_wvalid,		
			input 				AXI_wready,	
				//AXI写响应通道
			input[5:0] 			AXI_bid,
			input[1:0] 			AXI_bresp,
			input 				AXI_bvalid,	
			output 				AXI_bready		
		);
 
//------------------------------------------------------------------------------------
//内部信号申明
wire[7:0] 	wrfifo_data_count;	//FIFO可读数据数量
reg 		wrfifo_rden;		//FIFO读数据使能信号
reg[7:0] 	wrdata_num;			//写入DDR3数据计数器
reg[3:0]    cstate,nstate;		//状态寄存器

parameter AXI_BURST_LEN	= 16;
parameter STATE_RST  = 4'h0;	
parameter STATE_IDLE = 4'h1; 
parameter STATE_WADD = 4'h2;
parameter STATE_WDAT = 4'h3; 	 
parameter WRITE_DONE = 4'h4;    

//-------------------------------------------------------------------------------
//缓存FIFO,将数据从i_clk转到AXI_clk时钟域,位宽从16bit转到64bit

fifo_generator_0 uut_fifo_generator_0 (
  .rst(~i_data_rst_n),                      // input wire rst
  .wr_clk(i_clk),                // input wire wr_clk
  .rd_clk(AXI_clk),                // input wire rd_clk
  .din(i_data),                      // input wire [15 : 0] din
  .wr_en(i_data_en),                  // input wire wr_en
  .rd_en(wrfifo_rden),                  // input wire rd_en
  .dout(AXI_wdata),                    // output wire [63 : 0] dout
  .full(),                    // output wire full
  .empty(),                  // output wire empty
  .rd_data_count(wrfifo_data_count)  // output wire [7 : 0] rd_data_count
);

//------------------------------------------------------------------------------------
//将i_data_rst_n在AXI_clk时钟域打一拍
reg w_data_rst_n;

always @(posedge AXI_clk)
	w_data_rst_n <= i_data_rst_n; 		

//-------------------------------------------------------------------------------
//AXI写状态机

always @(posedge AXI_clk or negedge rst_n) begin
	if(~rst_n)begin
		cstate <= STATE_RST;
	end
	else begin
		cstate <= nstate;
	end
end 
                                                     																										
always @( * ) begin
	case(cstate)
    STATE_RST: begin
        if(w_data_rst_n) nstate = STATE_IDLE;
        else nstate = STATE_RST;
    end
    STATE_IDLE: begin
		if(!w_data_rst_n) nstate = STATE_RST;
		else if(wrfifo_data_count >= 8'd16) nstate = STATE_WADD;
        else nstate = STATE_IDLE;
    end
	
	STATE_WADD: begin
		if(AXI_awvalid && AXI_awready) nstate = STATE_WDAT;
		else nstate = STATE_WADD;
	end    
    
	STATE_WDAT: begin
		if(wrdata_num >= (AXI_BURST_LEN+1)) nstate = WRITE_DONE;
        else nstate = STATE_WDAT;
    end
	WRITE_DONE: begin
		nstate = STATE_IDLE;
	end
    
    default: begin
        nstate = STATE_RST;
    end
endcase
end

	//1个burst写入数据的个数计数
always @(posedge AXI_clk) begin                                                                
	if (!rst_n) wrdata_num <= 'b0;                                                           
	else if(cstate == STATE_WDAT) begin 
		if(wrdata_num == 8'd0) wrdata_num <= wrdata_num + 1'b1; 
		else if((wrdata_num <= AXI_BURST_LEN) && AXI_wready && AXI_wvalid) wrdata_num <= wrdata_num + 1'b1;              
		else wrdata_num <= wrdata_num;
	end                                                              
	else wrdata_num <= 'b0;                                               
end 
	
//-------------------------------------------------------------------------------
//FIFO读取使能信号产生

always @(*) begin                                                                
	if (cstate == STATE_WDAT) begin
		if(wrdata_num == 8'd0) wrfifo_rden <= 1'b1;
		else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN) && AXI_wready && AXI_wvalid) wrfifo_rden <= 1'b1;
		else wrfifo_rden <= 1'b0;
	end
	else wrfifo_rden <= 1'b0;                                 
end

//-------------------------------------------------------------------------------
//AXI总线写数据时序产生

	//写地址产生
always @(posedge AXI_clk)begin
	if(cstate == STATE_RST) AXI_awaddr <= STAR_ADDR;
	else if(AXI_awvalid && AXI_awready) AXI_awaddr <= AXI_awaddr + AXI_BURST_LEN * 8;
end

	//写地址有效信号产生
always @(posedge AXI_clk) begin                                                                
	if (!rst_n) AXI_awvalid <= 1'b0;                                                               
	else if(cstate == STATE_WADD) begin
		if(AXI_awvalid && AXI_awready) AXI_awvalid <= 1'b0;                                                        
		else AXI_awvalid <= 1'b1;
	end
	else AXI_awvalid <= 1'b0;                                 
end    

	//写数据有效信号产生
always @(posedge AXI_clk) begin                                                                
	if (!rst_n) AXI_wvalid <= 1'b0;
	else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN)) AXI_wvalid <= 1'b1; 
	else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wvalid <= 1'b1;
	else AXI_wvalid <= 1'b0;                                 
end

	//写最后一个数据有效信号产生
always @(posedge AXI_clk) begin                                                                
	if (!rst_n) AXI_wlast <= 1'b0;                                                               
	else if((wrdata_num == (AXI_BURST_LEN - 1)) && AXI_wready && AXI_wvalid) AXI_wlast <= 1'b1;  
	else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wlast <= 1'b1;
	else AXI_wlast <= 1'b0;                                 
end

//-------------------------------------------------------------------------------
//AXI HP总线固定赋值设置

assign AXI_awsize	= 3'b011;	//8 Bytes per burst
assign AXI_awburst	= 2'b01;
assign AXI_awlock	= 2'b00;
assign AXI_awcache	= 4'b0010;
assign AXI_awprot	= 3'h0;
assign AXI_awqos	= 4'h0;
assign AXI_wstrb	= 8'hff;
assign AXI_bready 	= 1'b1;
assign AXI_awlen 	= AXI_BURST_LEN - 1; 
	
endmodule

2、axi_hp0_rd.v 模块代码解析

     该模块实现 AXI HP 总线从 DDR3 读数据的操作。该模块的接口如下。rst_n 为系统复位信号;i_clk、i_data_rst_n、i_data_rden 和 o_data 为 FPGA 逻辑从该模块读取 DDR3 的控制和数据接口。i_clk 为同步时钟信号,i_data_rst_n 用于复位 FIFO,i_data_rden 拉高表示读取 FIFO 中的数据,随后 i_data 上将输出 FIFO 中缓存的数据。余下的 AXI_*信号为 AXI HP 总线接口,写入数据到 FIFO 中供读取。
module axi_hp0_rd(
				//系统信号
			input				rst_n,                   
				//写入DDR3的数据         
			input				i_clk,
			input 				i_data_rst_n,
			input				i_data_rden,
			output[15:0]		o_data,
			
				//AXI总线时钟
			input				AXI_clk,
				//AXI读地址通道
			output reg[31:0]	AXI_araddr,
			output[1:0]			AXI_arburst,
			output[3:0]			AXI_arcache,			
			output[3:0]			AXI_arlen,
			output[1:0]			AXI_arlock,
			output[2:0]			AXI_arprot,
			output[3:0]			AXI_arqos,
			input				AXI_arready,
			output[2:0]			AXI_arsize,
			output reg			AXI_arvalid,
				//AXI读数据通道
			input[63:0]			AXI_rdata,
			input[5:0]			AXI_rid,
			input 				AXI_rlast,
			output 				AXI_rready,
			input[1:0]			AXI_rresp,
			input 				AXI_rvalid			
		);
内部信号、参数的申明如下。
//参数、信号申明 
parameter STAR_ADDR = 32'h0100_0000; 
parameter AXI_BURST_LEN = 16; 
parameter STATE_RST = 4'h0; 
parameter STATE_IDLE = 4'h1; 
parameter STATE_RADD = 4'h2; 
parameter READ_DONE = 4'h3; 
reg[3:0] cstate,nstate; 
wire[7:0] fifo_wrdata_count;
将 i_data_rst_n 在 AXI_clk 时钟域打 2 拍
//将 i_data_rst_n 在 AXI_clk 时钟域打 2 拍 
 
wire w_data_rst_n,pos_data_rst_n,neg_data_rst_n; 
 
pulse_detection uut_pulse_detection_odrn( 
 .clk(AXI_clk), 
 .in_sig(i_data_rst_n), //输入信号 
 .out_sig(w_data_rst_n), //将输入信号同步到本地时钟域后的输出 
 .pos_sig(pos_data_rst_n),//输入信号的上升沿检测,高脉冲保持一个时钟周期 
 .neg_sig(neg_data_rst_n)//输入信号的下降沿检测,高脉冲保持一个时钟周期 
 );
       以下状态机实现 AXI HP 总线读取 DDR3 数据的控制。上电初始为复位状态 STATE_RST ,复位结束后(wr_data_rst=1 ),进入空闲状态 STATE_IDLE ,若 FIFO 中数据数量少于 128
fifo_wrdata_counter<128 ),则进入写地址状态 STATE_RADD ,该状态产生 AXI HP 总线写入
DDR3 要读取数据所在的地址,写入成功后( AXI_arready=1 ),进入读数据状 STATE_DONE
该状态下所有读取到的数据送入 FIFO 中,最后一个数据输出完成( AXI_rlast=1 ),回到空闲
状态,如此反复。

基于 ZYNQ 的双目视觉图像采集系统设计(四),fpga开发

//AXI读状态机

always @(posedge AXI_clk or negedge rst_n)begin
	if(~rst_n)begin
		cstate <= STATE_RST;
	end
	else begin
		cstate <= nstate;
	end
end 
                                                     																										
always @( * )begin
	case(cstate)
    STATE_RST: begin
        if(w_data_rst_n) nstate = STATE_IDLE;
        else nstate = STATE_RST;
    end
    STATE_IDLE: begin
		if(!w_data_rst_n) nstate = STATE_RST;
		else if(fifo_wrdata_count < 8'd128) nstate = STATE_RADD;
		else nstate = STATE_IDLE;
    end
	
	STATE_RADD: begin
		if(AXI_arready) nstate = READ_DONE;
		else nstate = STATE_RADD;
	end    
    
	READ_DONE: begin
		if(AXI_rlast) nstate = STATE_IDLE;
		else nstate = READ_DONE;
	end
    
    default: begin
        nstate = STATE_RST;
    end
endcase
end
以下逻辑产生读数据的地址 AXI_araddr 和地址有效信号 AXI_arvalid
//AXI HP读时序产生

	//读地址有效信号产生
always @(posedge AXI_clk)begin
	if(nstate == STATE_RADD) AXI_arvalid <= 1'b1;
	else AXI_arvalid <= 1'b0;
end

	//读地址产生
always @(posedge AXI_clk)begin
	if(cstate == STATE_RST) AXI_araddr <= STAR_ADDR;
	else if(AXI_arvalid && AXI_arready) AXI_araddr <= AXI_araddr + AXI_BURST_LEN * 8; 
end	
FIFO 例化如下。
//DDR3读出数据缓存到FIFO,LCD显示模块读取FIFO数据,位宽从64bit转16bit

fifo_generator_2 uut_fifo_generator_2 (
  .rst(~i_data_rst_n),                      // input wire rst
  .wr_clk(AXI_clk),                // input wire wr_clk
  .rd_clk(i_clk),                // input wire rd_clk
  .din(AXI_rdata),                      // input wire [63 : 0] din
  .wr_en(AXI_rvalid),                  // input wire wr_en
  .rd_en(i_data_rden),                  // input wire rd_en
  .dout(o_data),                    // output wire [15 : 0] dout
  .full(full),                    // output wire full
  .empty(empty),                  // output wire empty
  .wr_data_count(fifo_wrdata_count)  // output wire [7 : 0] wr_data_count
);
以下逻辑对 AXI HP 总线的一些信号赋常量值。
//AXI HP总线固定配置

assign AXI_arsize	= 3'b011;	//8 Bytes per burst
assign AXI_arburst	= 2'b01;
assign AXI_arlock	= 2'b00;
assign AXI_arcache	= 4'b0010;
assign AXI_arprot	= 3'h0;
assign AXI_arqos	= 4'h0;
assign AXI_rready 	= 1'b1;
assign AXI_arlen 	= AXI_BURST_LEN - 1; 

axi_hp0_rd.v

module axi_hp0_rd(
				//系统信号
			input				rst_n,                   
				//写入DDR3的数据         
			input				i_clk,
			input 				i_data_rst_n,
			input				i_data_rden,
			output[15:0]		o_data,
			
				//AXI总线时钟
			input				AXI_clk,
				//AXI读地址通道
			output reg[31:0]	AXI_araddr,
			output[1:0]			AXI_arburst,
			output[3:0]			AXI_arcache,			
			output[3:0]			AXI_arlen,
			output[1:0]			AXI_arlock,
			output[2:0]			AXI_arprot,
			output[3:0]			AXI_arqos,
			input				AXI_arready,
			output[2:0]			AXI_arsize,
			output reg			AXI_arvalid,
				//AXI读数据通道
			input[63:0]			AXI_rdata,
			input[5:0]			AXI_rid,
			input 				AXI_rlast,
			output 				AXI_rready,
			input[1:0]			AXI_rresp,
			input 				AXI_rvalid			
		);
		
//------------------------------------------------------------------------------------
//参数、信号申明 

parameter STAR_ADDR = 32'h0100_0000;
parameter AXI_BURST_LEN	= 16;

parameter STATE_RST  = 4'h0;	
parameter STATE_IDLE = 4'h1; 
parameter STATE_RADD = 4'h2; 	 
parameter READ_DONE = 4'h3; 
reg[3:0]    cstate,nstate;

wire[7:0] fifo_wrdata_count;

//------------------------------------------------------------------------------------
//将i_data_rst_n在AXI_clk时钟域打2拍

wire w_data_rst_n,pos_data_rst_n,neg_data_rst_n;	
	
pulse_detection		uut_pulse_detection_odrn(
						.clk(AXI_clk),       	
						.in_sig(i_data_rst_n),	//输入信号
						.out_sig(w_data_rst_n),	//将输入信号同步到本地时钟域后的输出
						.pos_sig(pos_data_rst_n),	//输入信号的上升沿检测,高脉冲保持一个时钟周期
						.neg_sig(neg_data_rst_n)	//输入信号的下降沿检测,高脉冲保持一个时钟周期
					);

//-------------------------------------------------------------------------------
//AXI读状态机

always @(posedge AXI_clk or negedge rst_n)begin
	if(~rst_n)begin
		cstate <= STATE_RST;
	end
	else begin
		cstate <= nstate;
	end
end 
                                                     																										
always @( * )begin
	case(cstate)
    STATE_RST: begin
        if(w_data_rst_n) nstate = STATE_IDLE;
        else nstate = STATE_RST;
    end
    STATE_IDLE: begin
		if(!w_data_rst_n) nstate = STATE_RST;
		else if(fifo_wrdata_count < 8'd128) nstate = STATE_RADD;
		else nstate = STATE_IDLE;
    end
	
	STATE_RADD: begin
		if(AXI_arready) nstate = READ_DONE;
		else nstate = STATE_RADD;
	end    
    
	READ_DONE: begin
		if(AXI_rlast) nstate = STATE_IDLE;
		else nstate = READ_DONE;
	end
    
    default: begin
        nstate = STATE_RST;
    end
endcase
end


//------------------------------------------------------------------------------------
//AXI HP读时序产生

	//读地址有效信号产生
always @(posedge AXI_clk)begin
	if(nstate == STATE_RADD) AXI_arvalid <= 1'b1;
	else AXI_arvalid <= 1'b0;
end

	//读地址产生
always @(posedge AXI_clk)begin
	if(cstate == STATE_RST) AXI_araddr <= STAR_ADDR;
	else if(AXI_arvalid && AXI_arready) AXI_araddr <= AXI_araddr + AXI_BURST_LEN * 8; 
end	

//------------------------------------------------------------------------------------
//DDR3读出数据缓存到FIFO,LCD显示模块读取FIFO数据,位宽从64bit转16bit

fifo_generator_2 uut_fifo_generator_2 (
  .rst(~i_data_rst_n),                      // input wire rst
  .wr_clk(AXI_clk),                // input wire wr_clk
  .rd_clk(i_clk),                // input wire rd_clk
  .din(AXI_rdata),                      // input wire [63 : 0] din
  .wr_en(AXI_rvalid),                  // input wire wr_en
  .rd_en(i_data_rden),                  // input wire rd_en
  .dout(o_data),                    // output wire [15 : 0] dout
  .full(full),                    // output wire full
  .empty(empty),                  // output wire empty
  .wr_data_count(fifo_wrdata_count)  // output wire [7 : 0] wr_data_count
);

//------------------------------------------------------------------------------------
//AXI HP总线固定配置

assign AXI_arsize	= 3'b011;	//8 Bytes per burst
assign AXI_arburst	= 2'b01;
assign AXI_arlock	= 2'b00;
assign AXI_arcache	= 4'b0010;
assign AXI_arprot	= 3'h0;
assign AXI_arqos	= 4'h0;
assign AXI_rready 	= 1'b1;
assign AXI_arlen 	= AXI_BURST_LEN - 1; 
	
endmodule

pulse_detection.v文章来源地址https://www.toymoban.com/news/detail-765923.html

//对输入信号打2拍,做边沿检测
module pulse_detection(
		input clk,       	
		input in_sig,	//输入信号
		output out_sig,	//将输入信号同步到本地时钟域后的输出
		output pos_sig,	//输入信号的上升沿检测,高脉冲保持一个时钟周期
		output neg_sig	//输入信号的下降沿检测,高脉冲保持一个时钟周期
	);
		
reg[1:0] in_sig_r;

always @(posedge clk)
	in_sig_r <= {in_sig_r[0],in_sig};

assign pos_sig = ~in_sig_r[1] & in_sig_r[0];
assign neg_sig = in_sig_r[1] & ~in_sig_r[0];
assign out_sig = in_sig_r[1];
	
	
endmodule

到了这里,关于基于 ZYNQ 的双目视觉图像采集系统设计(四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于FPGA的ADC7768数据采集系统设计

    基于FPGA的ADC7768数据采集系统设计 随着科技的不断发展,数字信号处理在各个领域中的应用越来越广泛。而模拟信号的采集和转换成数字信号是数字处理的第一步。本文将介绍基于FPGA的ADC7768数据采集系统设计,该系统能够高效、准确地采集模拟信号并将其转换为数字信号。

    2024年02月11日
    浏览(47)
  • 基于FPGA的多通道数据采集系统Verilog设计

    基于FPGA的多通道数据采集系统Verilog设计 随着科技的不断发展,数据采集在许多领域变得越来越重要。为了满足高速、高精度和多通道数据采集的需求,基于FPGA的多通道数据采集系统成为了一种常见的解决方案。本文将介绍如何使用Verilog语言设计一个基于FPGA的多通道数据采

    2024年02月09日
    浏览(58)
  • 基于STM32与FPGA的数据采集系统的设计与实现

    数据采集系统在现代工程中起着至关重要的作用,用于实时获取和处理各种传感器或外部设备的数据。在本文中,我们将探讨如何基于STM32微控制器和FPGA(现场可编程门阵列)实现一个高效的数据采集系统。我们将详细介绍系统设计的关键步骤,并提供相应的源代码示例。

    2024年02月06日
    浏览(51)
  • 基于FPGA的多通道数据采集系统Verilog设计嵌入式

    基于FPGA的多通道数据采集系统Verilog设计嵌入式 在本文中,我们将介绍基于FPGA的多通道数据采集系统的Verilog设计,该系统可用于同时采集和处理多个通道的数据。我们将详细讨论系统的设计原理和实现步骤,并提供相应的Verilog源代码。 系统概述 多通道数据采集系统是一种

    2024年02月07日
    浏览(71)
  • ZYNQ+AD8285高速毫米波雷达数据采集系统设计

    传统的毫米波雷达采用 DSP+FPGA 的处理模 块,通过FPGA 增加采集数据吞吐能力,通过 DSP 器件完成数据处理算法。为满足如今毫米波雷达 低功耗小型化的指标要求,同时保证数据接口的 稳定性和速度,本设计提出一种基于 Xilinx 公司的ZYNQ采集系统,具有高集成度,高可靠性的

    2024年02月03日
    浏览(39)
  • 基于Zynq的雷达10Gbps高速PCIE数据采集卡方案(一)总体设计

    2.1 引言 本课题是来源于雷达辐射源识别项目,需要对雷达辐射源中频信号进行采集传输 和存储。本章基于项目需求,介绍采集卡的总体设计方案。采集卡设计包括硬件设计 和软件设计。首先对采集卡的性能和指标进行分析,接着提出硬件的总体设计,在硬 件设计基础上提

    2024年02月05日
    浏览(49)
  • 基于FPGA的图像数据采集(一)

    一、实验简介   前面我们已经介绍了IIC的基本时序和相关代码配置。下面我们将要通过对OV5640配置(支持SCCB协议),从摄像头的数据端口读出数据,由于我手上没有屏幕,做不了图像的验证,所以读出的数据会通过串口发送到电脑。 二、实验目标   通过对OV5640的相关接口和

    2024年04月22日
    浏览(66)
  • 光刻机基于dsp+fpga+ad+endac光纤传输的高速数据采集与伺服接口系统设计(一)

    光刻机双工件台运动控制系统,控制任务相当复杂,要求极高的速度和精度,且设 备体积庞大,各传感器执行器空间距离较远,线缆众多现场电磁干扰严重。 为满足控制系统要求,本文利用 DSP 的高速浮点运算能力、 FPGA 强大的并行处理 能力及光纤通信传输距离远、抗干扰

    2024年02月03日
    浏览(54)
  • (16)双目视觉的图像获取

    (1)摄像头参数 https://blog.csdn.net/crazty/article/details/107365147 (2)双目标定方法,过程参照了一下 双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python_AI吃大瓜的博客-CSDN博客_双目三维重建 (3)直接放源码的都是好人啊,下面的大佬代码参照了一下,大家仔细看看

    2024年02月05日
    浏览(34)
  • 基于FPGA的数据采集、编码、通讯和存储系统设计(即FPGA+RTL8211千兆以太网+SD卡存储+RTC+Uart+AD7606数模转换+电流放大采集等硬件设计与程序验证)

    介绍一个小项目,加强对FPGA相关接口的整体把握。 硬件及软件代码梳理: 硬件系统的主要功能框图,其中FPGA作为处理单元,实现了包括电流和电压的采集、千兆以太网通讯、SD卡本地数据存储和串口通讯等。已经过板级测试,测试包含:千兆网通讯收发测试、AD采集的数据

    2024年04月13日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包