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

相关推荐
坏孩子的诺亚方舟4 小时前
FPGA系统架构设计实践13_FPGA系统功能安全
fpga开发·系统架构·功能安全概念
ALINX技术博客4 小时前
【新品解读】5G/6G 基带系统级验证,AXVU13G 如何缩短高速系统研发周期
5g·fpga开发·fpga
hkhkhkhkh1234 小时前
Linux 内核三大核心结构体详解(驱动开发视角)
linux·数据结构·驱动开发·字符设备
坏孩子的诺亚方舟5 小时前
FPGA系统架构设计实践12_FPGA系统ECM0
fpga开发·系统架构·ecm·功能安全
Coder_Boy_14 小时前
业务导向型技术日志首日记录(业务中使用的技术栈)
java·驱动开发·微服务
福尔摩斯张18 小时前
C++核心特性精讲:从C语言痛点出发,掌握现代C++编程精髓(超详细)
java·linux·c语言·数据结构·c++·驱动开发·算法
s090713618 小时前
FPGA中同步与异步复位
fpga开发·verilog·xilinx·zynq
DeeplyMind1 天前
第5章:并发与竞态条件-15:Atomic Variables
linux·驱动开发·ldd
tiantianuser1 天前
RDMA设计15:连接管理模块设计2
网络协议·fpga开发·rdma·高速传输·cmac