基于Verilog语言的AD0809驱动

新手小白自己写的一个小代码,实际测试完毕,第一次写有什么写的不好的地方大神们多多关照,功能如题。
/*reg:synthesis noptune*/
/*wire:synthesis keep*/
 module AD_module
 (
	//输入端
	input	[7:0]	AD_data_in,			//输入AD转换完成数据进行处理
	input CLK_50M,						//主时钟输入
	input	CLK_1M,						//AD0809主频
	input RET,							//复位信号输入
	input	EOC,							//转换结束信号标志位,当转换结束时为高,开始转换时为低
	input data_sync,					//数据标志位,沟通串口和AD的数据同步
	
	//输出端
	output	[7:0]	AD_data_out,		//输出处理完的数据	
	output	OE,							//AD输出使能端
	output	read_clk,					//AD转换时钟
	output	STR							//AD转换启动信号输出端
	//output	ALE							//AD地址锁存允许信号输出端
 );
 //
 //--内部参数定义
 parameter set_time_200ns = 4'd10;	//定义ST端口最小延时200ns
 parameter set_time_400ns = 5'd20;	//定义ST端口周期延时400ns
 
 reg	[1:0]	detect_edge;				//定义延边检测寄存器,记录EOC端的电平变化情况
 wire	[1:0]	detect_edge_n;				//定义延边检测寄存器的下一个状态
 reg	[4:0]	time_cnt_st;				//定义时间寄存器,记录-st端高电平-定时时间
 reg	[4:0]	time_cnt_st_n;				//定义时间寄存器的下一个状态 
 wire [15:0]data_temp;					//定义数据缓存器,缓存正在处理的数据	
 reg	[4:0]	OE_time_cnt;				//定义OE计数器,记录OE电平拉高时间
 reg	[4:0]	OE_time_cnt_n;				//定义OE计数器的下一个状态
 reg	[7:0]	AD_data_temp;				//定义模数转换数据缓存器,缓存数据以便于发送
 reg	[7:0]	AD_data_temp_n;			//定义模数转换数据缓存器的下一个状态
 reg			ad_clk;						//定义AD时钟线,寄存AD需要的时钟
 reg			ad_clk_n;					//定义AD时钟线的下一个状态
 reg			OE_signal_temp;			//输出使能信号缓存器,缓存输出使能信号
 reg			OE_signal_temp_n;			//输出使能信号缓存器的下一个状态
 reg			time_cnt_st_em;			//时间计数使能,标志计数的使能和停止
 reg			time_cnt_st_em_n;			//时间计数使能的下一个状态
 reg			st_signal_temp;			//start conversion signal temp
 reg			st_signal_temp_n;			//start conversion signal temp next state


//
//--AD0809主频输出
 assign read_clk = CLK_1M;
  
//
//--处理转换完成的数据
//assign	data_temp = {data_temp[15:8] , AD_data_in};//将处理完成的数据写在缓存器中
//
//--寄存器AD_data_temp赋值
always @ (posedge CLK_50M or negedge RET)
begin
	if(!RET)
		AD_data_temp <= 8'h0;
	else
		AD_data_temp <= AD_data_temp_n;	
end
//寄存器AD_data_temp计数
always @ (*)
begin
	if(OE_signal_temp == 1'b1)			//当OE
		AD_data_temp_n = AD_data_in/*data_temp[7:0]*/;
	else
		AD_data_temp_n = AD_data_temp;
end
//
//--模数转换数据输出
assign AD_data_out = AD_data_temp;
//
//--寄存器OE_time_cnt赋值
always @ (posedge CLK_50M or negedge RET)
begin
	if(!RET)
		OE_time_cnt <=	5'h0;
	else
		OE_time_cnt <= OE_time_cnt_n;	
end
//寄存器OE_time_cnt计数
always @ (*)
begin
	if(OE_time_cnt == set_time_200ns || detect_edge == 2'b01)//当EOC上升沿时清零并开始计数
		OE_time_cnt_n = 5'h0;
	else
		OE_time_cnt_n = OE_time_cnt + 1'b1;	
end
//
//--寄存器time_cnt_st赋值
always @ (posedge CLK_50M or negedge RET)
begin
	if(!RET)
		time_cnt_st <=	5'h0;
	else
		time_cnt_st <= time_cnt_st_n;
end
// 寄存器time_cnt_st计数
always @ (*)
begin
								//当到达定时时间或者EOC端口和ST端口都为低电平时,清零
	if(time_cnt_st == set_time_400ns || EOC == 1'b0)
		time_cnt_st_n = 5'h0;
	else
		time_cnt_st_n = time_cnt_st + 1'b1;
end

//
//--寄存器st_signal_temp赋值
always @ (posedge CLK_50M or negedge RET)
begin
	if(!RET)
		st_signal_temp <= 1'b0;
	else
		st_signal_temp <= st_signal_temp_n;
end
//寄存器st_signal_temp计数
always @ (*)
begin
	if(time_cnt_st < set_time_200ns)		//当转换开始计数器达到数值时,信号取反
		st_signal_temp_n = 1'b0;
	else if(time_cnt_st >= set_time_200ns && time_cnt_st < set_time_400ns)
		st_signal_temp_n = 1'b1;
	else												//其他情况保持
		st_signal_temp_n = st_signal_temp;
end
//
//--输出STR信号
assign STR = st_signal_temp;
//
//-- 寄存器detect_edge赋值
always @ (posedge CLK_50M or negedge RET)
begin
	if(!RET)
		detect_edge <= 2'b11;
	else
		detect_edge <= detect_edge_n;
end
// 寄存器detect_edge计数
assign detect_edge_n = {detect_edge[0],EOC};	//detect_edge == 2'b01为上升沿
//
//--寄存器OE_signal_temp赋值 
always @ (posedge CLK_50M or negedge RET)
begin
	if(!RET) 
		OE_signal_temp <= 1'b0;
	else
		OE_signal_temp <= OE_signal_temp_n;
end
//寄存器OE_signal_temp计数
always @ (*)
begin
	if(detect_edge == 2'b01)	//当EOC产生上升沿时,OE输出高电平
		OE_signal_temp_n = 1'b1;
	else if(OE_time_cnt == set_time_200ns)//当电位时间达到时,拉低电平
		OE_signal_temp_n = 1'b0;
	else								//其他状态输出低电平
		OE_signal_temp_n = OE_signal_temp;
end
//
//--OE信号输出
assign OE = OE_signal_temp;

//
//--寄存器time_cnt_st_em赋值 
always @ (posedge CLK_50M or negedge RET)
begin
	if(!RET) 
		time_cnt_st_em <= 1'b0;
	else
		time_cnt_st_em <= time_cnt_st_em_n;
end
//寄存器time_cnt_st_em计数
always @ (*)
begin
	if(detect_edge == 2'b01)						//EOC为上升延时开始计时
		time_cnt_st_em_n = 1'b1;
	else if(time_cnt_st == set_time_200ns)		//当时间计满时,使能停止等待AD下一次数据处理完毕
		time_cnt_st_em_n = 1'b0;
	else													//其他情况保持
		time_cnt_st_em_n = time_cnt_st_em;
end

 
 endmodule 

猜你喜欢

转载自blog.csdn.net/qq_41902597/article/details/80642164