AD7616驱动开发-FPGA

顶层测试代码


module top(
	input					i_clk			,
	input					i_rstn			,
	input		[15:0]		i_ch_din		,
	input					i_busy			,
	output					o_convst		,
	output		[1:0]		o_hw_rngsel		,
	output					o_ser1par0		,
	output					o_reset_n		,
	output		[2:0]		o_chsel			,
	output					o_burst			,
	output					o_cs			,
	output					o_rd			
    );

/* 	wire			w_clk200m	;
	wire			w_lock200m	;
	
pll200m 
pll200m (
    .clk_out1(w_clk200m),     
    .resetn(i_rstn), 
    .locked(w_lock200m),      
    .clk_in1(i_clk)
);  */  

	wire			w_clk125m	;
	wire			w_lock125m	;
	
pll125m 
pll125m (
    .clk_out1(w_clk125m),     
    .resetn(i_rstn), 
    .locked(w_lock125m),      
    .clk_in1(i_clk)
);

	localparam	CLK_PERIOD = 8;
	localparam	CH_SELECT = 0;
	
	wire				w_clk_used	;
	wire				w_rst_used	;
	
	assign	w_clk_used = w_clk125m;
	assign	w_rst_used = ~w_lock125m;
	
	wire	[15:0]		w_cha_dout0	;
	wire	[15:0]		w_chb_dout0	;
	wire	[15:0]		w_cha_dout7	;
	wire	[15:0]		w_chb_dout7	;
	wire				w_cha_vld	;
	wire				w_chb_vld	;
	
	reg					r_cha_vld	;
	reg					r_chb_vld	;
	reg		[15:0]		r_cha_data	;
	reg		[15:0]		r_chb_data	;
	
	always@(posedge w_clk_used or posedge w_rst_used) begin
		if(w_rst_used) begin
			r_cha_vld <= 'd0;
			r_cha_data <= 'd0;
		end
		else if(w_cha_vld) begin
			r_cha_vld <= 'd1;
			r_cha_data <= w_cha_dout0;
		end
		else begin
			r_cha_vld <= 'd0;
			r_cha_data <= r_cha_data;
		end
	end
	
	always@(posedge w_clk_used or posedge w_rst_used) begin
		if(w_rst_used) begin
			r_chb_vld <= 'd0;
			r_chb_data <= 'd0;
		end
		else if(w_chb_vld) begin
			r_chb_vld <= 'd1;
			r_chb_data <= w_chb_dout0;
		end
		else begin
			r_chb_vld <= 'd0;
			r_chb_data <= r_chb_data;
		end
	end
	
	reg			[2:0]	r_chsel		;
	reg					r_chsel_vld	;
	reg					r_chsel_req	;
	
	wire				w_chsel_req	;
	
	always@(posedge w_clk_used or posedge w_rst_used) begin
		if(w_rst_used)
			r_chsel_req <= 'd0;
		else 
			r_chsel_req <= w_chsel_req;
	end
	
	always@(posedge w_clk_used or posedge w_rst_used) begin
		if(w_rst_used) begin
			r_chsel 	<= 'd0;
			r_chsel_vld	<= 'd0;
		end
		else if({r_chsel_req, w_chsel_req} == 2'b01) begin
			r_chsel 	<= r_chsel + 1;
			r_chsel_vld <= 'd1;
		end
		else begin
			r_chsel 	<= r_chsel;
			r_chsel_vld <= 'd0;
		end
	end
	
ad7616_driver#(
	.CLK_PERIOD (CLK_PERIOD	))
ad7616_driver_U(
	.i_clk			(w_clk_used	),
	.i_rst			(w_rst_used	),
	.i_en			(1'b1		),
	.i_chsel		(CH_SELECT	),
	.i_chsel_vld	(r_chsel_vld),
	.i_ch_din		(i_ch_din	),
	.i_busy			(i_busy		),
	.o_cha_dout0	(w_cha_dout0),
	.o_cha_dout1	(),
	.o_cha_dout2	(),
	.o_cha_dout3	(),
	.o_cha_dout4	(),
	.o_cha_dout5	(),
	.o_cha_dout6	(),
	.o_cha_dout7	(w_cha_dout7),
	.o_chb_dout0	(w_chb_dout0),
	.o_chb_dout1	(),
	.o_chb_dout2	(),
	.o_chb_dout3	(),
	.o_chb_dout4	(),
	.o_chb_dout5	(),
	.o_chb_dout6	(),
	.o_chb_dout7	(w_chb_dout7),
	.o_cha_vld		(w_cha_vld	),
	.o_chb_vld		(w_chb_vld	),
	.o_convst		(o_convst	),
	.o_hw_rngsel	(o_hw_rngsel),
	.o_os			(),
	.o_ser1par0		(o_ser1par0	),
	.o_reset_n		(o_reset_n	),
	.o_chsel		(o_chsel	),
	.o_burst		(o_burst	),
	.o_seqen		(),
	.o_cs			(o_cs		),
	.o_rd           (o_rd		),
	.o_chsel_req	(w_chsel_req)
);

ila_top your_instance_name (
	.clk(w_clk_used), // input wire clk


	.probe0(r_cha_data), // input wire [15:0]  probe0  
	.probe1(r_chb_data), // input wire [15:0]  probe1 
	.probe2(w_cha_vld), // input wire [0:0]  probe2 
	.probe3(w_chb_vld) // input wire [0:0]  probe3
);
endmodule

驱动代码

(*max_fanout=20, keep="true"*)
module ad7616_driver#(
	parameter	CLK_PERIOD = 20		
)(
	input					i_clk		,
	input					i_rst		,
	input					i_en		,
	input		[2:0]		i_chsel		,
	input					i_chsel_vld	,
	input		[15:0]		i_ch_din	,
	input					i_busy		,
	output	reg	[15:0]		o_cha_dout0	,
	output	reg	[15:0]		o_cha_dout1	,
	output	reg	[15:0]		o_cha_dout2	,
	output	reg	[15:0]		o_cha_dout3	,
	output	reg	[15:0]		o_cha_dout4	,
	output	reg	[15:0]		o_cha_dout5	,
	output	reg	[15:0]		o_cha_dout6	,
	output	reg	[15:0]		o_cha_dout7	,
	output	reg	[15:0]		o_chb_dout0	,
	output	reg	[15:0]		o_chb_dout1	,
	output	reg	[15:0]		o_chb_dout2	,
	output	reg	[15:0]		o_chb_dout3	,
	output	reg	[15:0]		o_chb_dout4	,
	output	reg	[15:0]		o_chb_dout5	,
	output	reg	[15:0]		o_chb_dout6	,
	output	reg	[15:0]		o_chb_dout7	,
	output	reg				o_cha_vld	,
	output	reg				o_chb_vld	,
	output	reg				o_convst	,
	output	reg	[1:0]		o_hw_rngsel	,
	output	reg	[2:0]		o_os		,
	output	reg				o_ser1par0	,
	output	reg				o_reset_n	,
	output	reg	[2:0]		o_chsel		,
	output	reg				o_burst		,
	output	reg				o_seqen		,
	output	reg				o_cs		,
	output	reg				o_rd		,
	output	reg				o_chsel_req
    );
	/*
		序列器开启后每拉高一次convst,等待busy下降后就可以通过cs↓rd↓rd↑cs↑反复循环,从第一个通道顺序读取最后一个通道,然后再次拉高convst进行下一轮读取
		序列器关闭后可以更加灵活的控制单通道的读取,每次读取一个通道前都需要配置chsel,然后拉高convst,等待busy下降后通过cs↓rd↓rd↑cs↑读取单个通道数据,
		如需切换通道则再次配置chsel	hw_rngsel1	hw_rngsel0	模拟输入范围
		0			1			±2.5V
		1			0			±5V
		1			1			±10V
	*/
	
	/*
		通道选择输入引脚			|模拟输入通道
		CHSEL2	|CHSEL1	|CHSEL0	|
		------------------------------------------
		0		|0		|0		|V0A,V0B
		0		|0		|1		|V1A,V1B
		0		|1		|0		|V2A,V2B
		0		|1		|1		|V3A,V3B
		1		|0		|0		|V4A,V4B
		1		|0		|1		|V5A,V5B
		1		|1		|0		|V6A,V6B
		1		|1		|1		|V7A,V7B
	*/
	initial begin 
		o_os		= 3'b000;
		o_ser1par0	= 1'b0;
		o_seqen		= 1'b0;//序列器开启或关闭
		o_burst     = 1'b0;//硬件模式下burst不用配置
		o_hw_rngsel = 2'b01;
	end
	
	localparam	TIME_RESET_L  	= 1_200			;//1.2μs
	localparam	TIME_RESET_H  	= 15_000_000	;//15ms
	localparam	TIME_CONVST_H 	= 50			;//50ns
	localparam	TIME_CH_SETUP	= 50			;//50ns	
	localparam	TIME_CH_HOLD	= 20			;//20ns
	localparam	TIME_RD_LOW		= 30			;//30ns
	localparam	TIME_RD_HIGH	= 10			;//30ns增强稳定性
	localparam	TIME_CS_SETUP	= 20			;//20ns
	localparam	TIME_QUIET		= 50			;//50ns 
	localparam	TIME_RD_SETUP	= 10			;//10ns
	localparam	TIME_RD_HOLD	= 10			;//10ns
	localparam	TIME_DOUT_SETUP = 20			;//20ns
	
	reg			[13:0]	r_cstate	;
	reg			[13:0]	r_nstate	;
	
	localparam	S_IDLE		= 14'b00_0000_0000_0001	,
				S_RESET		= 14'b00_0000_0000_0010	,
				S_CHSEL		= 14'b00_0000_0000_0100	,
				S_CONVST	= 14'b00_0000_0000_1000	,
				S_BUSY		= 14'b00_0000_0001_0000	,
				S_CS_SETUP	= 14'b00_0000_0010_0000	,
				S_RD_SETUP	= 14'b00_0000_0100_0000	,
				S_SETUP_CHA	= 14'b00_0000_1000_0000 ,
				S_DOUT_CHA	= 14'b00_0001_0000_0000 ,
				S_RD_HIGH	= 14'b00_0010_0000_0000 ,
				S_SETUP_CHB	= 14'b00_0100_0000_0000 ,
				S_DOUT_CHB	= 14'b00_1000_0000_0000 ,
				S_RD_HOLD	= 14'b01_0000_0000_0000 ,
				S_QUIET		= 14'b10_0000_0000_0000	;

	//	复位 start
	reg			[31:0]	r_rst_cnt	;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_rst_cnt <= 'd0;
		else if(r_cstate == S_RESET)
			r_rst_cnt <= r_rst_cnt + 'd1;
		else 
			r_rst_cnt <= r_rst_cnt;
	end
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_reset_n <= 'd1;
		else if(r_rst_cnt < (TIME_RESET_L + TIME_RESET_H) / CLK_PERIOD)
			o_reset_n <= 'd0;
		else
			o_reset_n <= 'd1;
	end
	// 	复位 end
	
	// 	采样通道选择 start
	reg			[7:0]	r_chsel_cnt	;
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_chsel_cnt <= 'd0;
		else if(r_cstate == S_CHSEL)
			r_chsel_cnt <= r_chsel_cnt + 1;
		else 
			r_chsel_cnt <= 'd0;
	end

	reg			[2:0]	r_chsel;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_chsel <= 'd0;
		else if(o_chsel_req & i_chsel_vld)
			r_chsel <= i_chsel;
		else
			r_chsel <= r_chsel;
	end

	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_chsel <= 'd0;//默认第一对输入引脚
		else if(r_nstate == S_CHSEL)//硬件模式每进行一对通道采集就切换一次
			o_chsel <= r_chsel;
		else 
			o_chsel <= o_chsel;
	end
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_chsel_req <= 'd1;
		else if(o_chsel_req & i_chsel_vld)
			o_chsel_req <= 'd0;
		else if(r_nstate == S_QUIET & r_cstate != r_nstate)
			o_chsel_req <= 'd1;
		else 
			o_chsel_req <= o_chsel_req;
	end
	//	采样通道选择 end
	
	//	模数转换 start
	reg		[7:0]	r_cvst_cnt	;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_cvst_cnt <= 'd0;
		else if(r_cstate == S_CONVST)
			r_cvst_cnt <= r_cvst_cnt + 1;
		else 
			r_cvst_cnt <= 'd0;
	end
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_convst <= 'd0;
		else if(r_cstate == S_CONVST)
			o_convst <= 'd1;
		else 
			o_convst <= 'd0;
	end
	//	模数转换 end
	
	//	转换完成 start
	reg		[1:0]	r_busy_shreg	;
	
	always@(posedge i_clk) begin
		r_busy_shreg[0] <= i_busy;
		r_busy_shreg[1] <= r_busy_shreg[0];
	end
	wire			w_busy_nedge	;
	assign	w_busy_nedge = r_busy_shreg == 2'b10;	//下降沿检查
	//	转换完成 end
	//	读取数据 start
	reg			[3:0]	r_cs_setup_cnt	;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_cs_setup_cnt <= 'd0;
		else if(r_cstate == S_CS_SETUP)
			r_cs_setup_cnt <= r_cs_setup_cnt + 1;
		else 
			r_cs_setup_cnt <= 'd0;
	end
	
	reg			[3:0]	r_rd_setup_cnt	;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_rd_setup_cnt <= 'd0;
		else if(r_cstate == S_RD_SETUP)
			r_rd_setup_cnt <= r_rd_setup_cnt + 1;
		else 
			r_rd_setup_cnt <= 'd0;
	end
	
	reg			[3:0]	r_setupa_cnt;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_setupa_cnt <= 'd0;
		else if(r_cstate == S_SETUP_CHA)
			r_setupa_cnt <= r_setupa_cnt + 1;
		else 
			r_setupa_cnt <= 'd0;
	end
	
	reg			[3:0]	r_douta_cnt	;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_douta_cnt <= 'd0;
		else if(r_cstate == S_DOUT_CHA)
			r_douta_cnt <= r_douta_cnt + 1;
		else 
			r_douta_cnt <= 'd0;
	end
	
	reg			[3:0]	r_rd_high_cnt;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_rd_high_cnt <= 'd0;
		else if(r_cstate == S_RD_HIGH)
			r_rd_high_cnt <= r_rd_high_cnt + 1;
		else 
			r_rd_high_cnt <= 'd0;
	end
	
	reg			[3:0]	r_setupb_cnt;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_setupb_cnt <= 'd0;
		else if(r_cstate == S_SETUP_CHB)
			r_setupb_cnt <= r_setupb_cnt + 1;
		else 
			r_setupb_cnt <= 'd0;
	end
	
	reg			[3:0]	r_doutb_cnt	;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_doutb_cnt <= 'd0;
		else if(r_cstate == S_DOUT_CHB)
			r_doutb_cnt <= r_doutb_cnt + 1;
		else 
			r_doutb_cnt <= 'd0;
	end
	
	reg			[3:0]	r_rd_hold_cnt;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_rd_hold_cnt <= 'd0;
		else if(r_cstate == S_RD_HOLD)
			r_rd_hold_cnt <= r_rd_hold_cnt + 1;
		else 
			r_rd_hold_cnt <= 'd0;
	end
	
	reg			[3:0]	r_quiet_cnt	;
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_quiet_cnt <= 'd0;
		else if(r_cstate == S_QUIET)
			r_quiet_cnt <= r_quiet_cnt + 1;
		else 
			r_quiet_cnt <= 'd0;
	end
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_cs <= 'd1;
		else if(r_cstate == S_CS_SETUP & r_nstate == S_RD_SETUP)
			o_cs <= 'd0;
		else if(r_cstate == S_RD_HOLD & r_nstate == S_QUIET)
			o_cs <= 'd1;
		else
			o_cs <= o_cs;
	end
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_rd <= 'd1;
		else if(r_cstate == S_RD_SETUP & r_nstate == S_SETUP_CHA)
			o_rd <= 'd0;
		else if(r_cstate == S_DOUT_CHA & r_nstate == S_RD_HIGH)
			o_rd <= 'd1;
		else if(r_cstate == S_RD_HIGH & r_nstate == S_SETUP_CHB)
			o_rd <= 'd0;
		else if(r_cstate == S_DOUT_CHB & r_nstate == S_RD_HOLD)
			o_rd <= 'd1;
		else 
			o_rd <= o_rd;
	end
	
	task CHA_DOUT;
	input	[15:0]	cha_0;
	input	[15:0]	cha_1;
	input	[15:0]	cha_2;
	input	[15:0]	cha_3;
	input	[15:0]	cha_4;
	input	[15:0]	cha_5;
	input	[15:0]	cha_6;
	input	[15:0]	cha_7;
	begin
		o_cha_dout0 <= cha_0;
		o_cha_dout1 <= cha_1;
		o_cha_dout2 <= cha_2;
		o_cha_dout3 <= cha_3;
		o_cha_dout4 <= cha_4;
		o_cha_dout5 <= cha_5;
		o_cha_dout6 <= cha_6;
		o_cha_dout7 <= cha_7;
	end
	endtask
	
	task CHB_DOUT;
	input	[15:0]	chb_0;
	input	[15:0]	chb_1;
	input	[15:0]	chb_2;
	input	[15:0]	chb_3;
	input	[15:0]	chb_4;
	input	[15:0]	chb_5;
	input	[15:0]	chb_6;
	input	[15:0]	chb_7;
	begin
		o_chb_dout0 <= chb_0;
		o_chb_dout1 <= chb_1;
		o_chb_dout2 <= chb_2;
		o_chb_dout3 <= chb_3;
		o_chb_dout4 <= chb_4;
		o_chb_dout5 <= chb_5;
		o_chb_dout6 <= chb_6;
		o_chb_dout7 <= chb_7;
	end
	endtask
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst) 
			CHA_DOUT('d0,'d0,'d0,'d0,'d0,'d0,'d0,'d0);
		else if(r_nstate == S_DOUT_CHA & r_cstate == S_SETUP_CHA)
			case(o_chsel)
				3'b000:		CHA_DOUT(o_cha_dout0,o_cha_dout1,o_cha_dout2,o_cha_dout3,o_cha_dout4,o_cha_dout5,o_cha_dout6,i_ch_din);
				3'b001:		CHA_DOUT(i_ch_din,o_cha_dout1,o_cha_dout2,o_cha_dout3,o_cha_dout4,o_cha_dout5,o_cha_dout6,o_cha_dout7);
				3'b010:		CHA_DOUT(o_cha_dout0,i_ch_din,o_cha_dout2,o_cha_dout3,o_cha_dout4,o_cha_dout5,o_cha_dout6,o_cha_dout7);
				3'b011:		CHA_DOUT(o_cha_dout0,o_cha_dout1,i_ch_din,o_cha_dout3,o_cha_dout4,o_cha_dout5,o_cha_dout6,o_cha_dout7);
				3'b100:		CHA_DOUT(o_cha_dout0,o_cha_dout1,o_cha_dout2,i_ch_din,o_cha_dout4,o_cha_dout5,o_cha_dout6,o_cha_dout7);
				3'b101:		CHA_DOUT(o_cha_dout0,o_cha_dout1,o_cha_dout2,o_cha_dout3,i_ch_din,o_cha_dout5,o_cha_dout6,o_cha_dout7);
				3'b110:		CHA_DOUT(o_cha_dout0,o_cha_dout1,o_cha_dout2,o_cha_dout3,o_cha_dout4,i_ch_din,o_cha_dout6,o_cha_dout7);
				3'b111:		CHA_DOUT(o_cha_dout0,o_cha_dout1,o_cha_dout2,o_cha_dout3,o_cha_dout4,o_cha_dout5,i_ch_din,o_cha_dout7);
				default:	CHA_DOUT(o_cha_dout0,o_cha_dout1,o_cha_dout2,o_cha_dout3,o_cha_dout4,o_cha_dout5,o_cha_dout6,o_cha_dout7);
			endcase
		else
			CHA_DOUT(o_cha_dout0,o_cha_dout1,o_cha_dout2,o_cha_dout3,o_cha_dout4,o_cha_dout5,o_cha_dout6,o_cha_dout7);
	end																																																																																												
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_cha_vld <= 'd0;
		else if(r_nstate == S_DOUT_CHA & r_cstate == S_SETUP_CHA)
			o_cha_vld <= 'd1;
		else 
			o_cha_vld <= 'd0;
	end

	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst) 
			CHB_DOUT('d0,'d0,'d0,'d0,'d0,'d0,'d0,'d0);
		else if(r_nstate == S_DOUT_CHB & r_cstate == S_SETUP_CHB)
			case(o_chsel)
				3'b000:		CHB_DOUT(o_chb_dout0,o_chb_dout1,o_chb_dout2,o_chb_dout3,o_chb_dout4,o_chb_dout5,o_chb_dout6,i_ch_din);
				3'b001:		CHB_DOUT(i_ch_din,o_chb_dout1,o_chb_dout2,o_chb_dout3,o_chb_dout4,o_chb_dout5,o_chb_dout6,o_chb_dout7);
				3'b010:		CHB_DOUT(o_chb_dout0,i_ch_din,o_chb_dout2,o_chb_dout3,o_chb_dout4,o_chb_dout5,o_chb_dout6,o_chb_dout7);
				3'b011:		CHB_DOUT(o_chb_dout0,o_chb_dout1,i_ch_din,o_chb_dout3,o_chb_dout4,o_chb_dout5,o_chb_dout6,o_chb_dout7);
				3'b100:		CHB_DOUT(o_chb_dout0,o_chb_dout1,o_chb_dout2,i_ch_din,o_chb_dout4,o_chb_dout5,o_chb_dout6,o_chb_dout7);
				3'b101:		CHB_DOUT(o_chb_dout0,o_chb_dout1,o_chb_dout2,o_chb_dout3,i_ch_din,o_chb_dout5,o_chb_dout6,o_chb_dout7);
				3'b110:		CHB_DOUT(o_chb_dout0,o_chb_dout1,o_chb_dout2,o_chb_dout3,o_chb_dout4,i_ch_din,o_chb_dout6,o_chb_dout7);
				3'b111:		CHB_DOUT(o_chb_dout0,o_chb_dout1,o_chb_dout2,o_chb_dout3,o_chb_dout4,o_chb_dout5,i_ch_din,o_chb_dout7);
				default:	CHB_DOUT(o_chb_dout0,o_chb_dout1,o_chb_dout2,o_chb_dout3,o_chb_dout4,o_chb_dout5,o_chb_dout6,o_chb_dout7);
			endcase
		else
			CHB_DOUT(o_chb_dout0,o_chb_dout1,o_chb_dout2,o_chb_dout3,o_chb_dout4,o_chb_dout5,o_chb_dout6,o_chb_dout7);
	end
	
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			o_chb_vld <= 'd0;
		else if(r_nstate == S_DOUT_CHB & r_cstate == S_SETUP_CHB)
			o_chb_vld <= 'd1;
		else 
			o_chb_vld <= 'd0;
	end
	
	//	读取数据 end
	always@(posedge i_clk or posedge i_rst) begin
		if(i_rst)
			r_cstate <= S_IDLE;
		else if(i_en)
			r_cstate <= r_nstate;
		else 
			r_cstate <= S_IDLE;
	end
	
	always@(*) begin
		case(r_cstate)
			S_IDLE		:	r_nstate = i_en ? S_RESET : S_IDLE;
			S_RESET		:	r_nstate = r_rst_cnt >= (TIME_RESET_H + TIME_RESET_L) / CLK_PERIOD ? S_CHSEL : S_RESET;
			S_CHSEL		:	r_nstate = r_chsel_cnt >= TIME_CH_SETUP / CLK_PERIOD ? S_CONVST : S_CHSEL;
			S_CONVST	:	r_nstate = r_cvst_cnt >= TIME_CONVST_H  / CLK_PERIOD ? S_BUSY : S_CONVST;
			S_BUSY		:	r_nstate = w_busy_nedge ? S_CS_SETUP : S_BUSY;
			S_CS_SETUP	:	r_nstate = r_cs_setup_cnt >= TIME_CS_SETUP / CLK_PERIOD ? S_RD_SETUP : S_CS_SETUP;
			S_RD_SETUP	:	r_nstate = r_rd_setup_cnt >= TIME_RD_SETUP / CLK_PERIOD ? S_SETUP_CHA : S_RD_SETUP;
			S_SETUP_CHA	:	r_nstate = r_setupa_cnt >= TIME_DOUT_SETUP / CLK_PERIOD ? S_DOUT_CHA : S_SETUP_CHA;
			S_DOUT_CHA	:	r_nstate = r_douta_cnt >= (TIME_RD_LOW - TIME_DOUT_SETUP) / CLK_PERIOD ? S_RD_HIGH : S_DOUT_CHA;
			S_RD_HIGH	:	r_nstate = r_rd_high_cnt >= TIME_RD_HIGH / CLK_PERIOD ? S_SETUP_CHB : S_RD_HIGH;
			S_SETUP_CHB	:	r_nstate = r_setupb_cnt >= TIME_DOUT_SETUP / CLK_PERIOD ? S_DOUT_CHB : S_SETUP_CHB;
			S_DOUT_CHB	:	r_nstate = r_doutb_cnt >= (TIME_RD_LOW - TIME_DOUT_SETUP) / CLK_PERIOD ? S_RD_HOLD : S_DOUT_CHB;
			S_RD_HOLD	:	r_nstate = r_rd_hold_cnt >= TIME_RD_HOLD / CLK_PERIOD ? S_QUIET : S_RD_HOLD;
			S_QUIET		:	r_nstate = r_quiet_cnt >= TIME_QUIET / CLK_PERIOD ? S_CHSEL : S_QUIET;
			default:	r_nstate = S_IDLE;
		endcase
	end
ila_2 your_instance_name (
	.clk(i_clk), // input wire clk


	.probe0(o_cha_dout0), // input wire [15:0]  probe0  
	.probe1(o_cha_dout1), // input wire [15:0]  probe1 
	.probe2(o_cha_dout2), // input wire [15:0]  probe2 
	.probe3(o_cha_dout3), // input wire [15:0]  probe3 
	.probe4(o_cha_dout4), // input wire [15:0]  probe4 
	.probe5(o_cha_dout5), // input wire [15:0]  probe5 
	.probe6(o_cha_dout6), // input wire [15:0]  probe6 
	.probe7(o_cha_dout7), // input wire [15:0]  probe7 
	.probe8(o_chb_dout0), // input wire [15:0]  probe8 
	.probe9(o_chb_dout1), // input wire [15:0]  probe9 
	.probe10(o_chb_dout2), // input wire [15:0]  probe10 
	.probe11(o_chb_dout3), // input wire [15:0]  probe11 
	.probe12(o_chb_dout4), // input wire [15:0]  probe12 
	.probe13(o_chb_dout5), // input wire [15:0]  probe13 
	.probe14(o_chb_dout6), // input wire [15:0]  probe14 
	.probe15(o_chb_dout7), // input wire [15:0]  probe15 
	.probe16(o_convst), // input wire [0:0]  probe16 
	.probe17(o_cs), // input wire [0:0]  probe17 
	.probe18(o_rd), // input wire [0:0]  probe18 
	.probe19(i_busy) // input wire [0:0]  probe19
);
endmodule

讲解视频:

【FPGA AD7616驱动编写】https://www.bilibili.com/video/BV1LDWyz8EnX?vd_source=2a95e4ac8a0ef48f2fbe2990bba31cec

本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值