ADC7606源代码

`timescale 1ns /  1ps


module ADC7606Driver
#(
parameter CNVT_WIDTH = 8'd40,
parameter BUSY_WIDTH = 16'd1800 // OS = 1, Oversampling by 2, MAX 10us
)
(
input nRst ,
input ClkIn ,
input AD_DB ,
input clk2 ,
output reg AD_Rst ,
output reg AD_CS ,
output reg AD_Convst ,
output reg [2:0] OS ,
output reg convertoverflag,,
input AD_BUSY , // not exist  ?????
output reg [15 : 0] Ch0SampleData , //用于current:y奇数
output reg [15 : 0] Ch1SampleData , //用于current:f奇数
output reg [15 : 0] Ch2SampleData , //用于current:f偶数
output reg [15 : 0] Ch3SampleData , //用于current:y偶数

output reg [15 : 0] Ch4SampleData ,      //一下Ch_SampleData未用
output reg [15 : 0] Ch5SampleData ,
output reg [15 : 0] Ch6SampleData ,
output reg [15 : 0] Ch7SampleData ,
output reg [2 : 0] current_adc_state ,
output reg [3 : 0] rst_cntr ,
output reg AD_SCLK
);
//定义状态机的状态 代码中使用case语句的状态机  同时也使用分模块相连接
localparam WAIT_CONST = 3'b000, //等待脉冲
START_CONVST = 3'b001, //开始转换
WAIT_BUSY = 3'b010, //等待忙碌
READ_DATA = 3'b011, //读数据
CONVST_FINISH = 3'b100, //数据转换完成
ADC_RESET = 3'b101; //数据复位
localparam RD_PULSE_WIDTH = 4'd10; //读脉冲宽度
parameter SCLK_count_value = 8'd128;
reg [7 : 0] cnvt_cntr ;
reg [15 : 0] busy_cntr ;
reg      [3:0] rd_cntr ;
reg [8:0] sclk_cntr ;
reg [127:0] AD_DB_info;

reg[7:0]cntr;

reg  [3:0]OS_cntr;
always @(posedge clk2 or negedge nRst)
begin  
if(!nRst)
begin
OS <= 3'b111;
OS_cntr <= 0;
end
else 
 begin
OS <= 3'b001;
if(AD_BUSY ==0)
begin
if(OS_cntr < 4)
begin
OS_cntr <= OS_cntr + 1'b1;
OS <= 3'b001;
end
else
// if(OS_cntr == 4)
begin
// OS_cntr <= 0;
OS <= 3'b111;
end
end
else 
begin
OS <= 3'b001;
OS_cntr <= 0;
end
end
end


wire posedge_AD_BUSY;
wire negedge_AD_BUSY;


reg AD_BUSY_buf1;
reg AD_BUSY_buf2;
/************************AD_BUSY上升沿的产生**************************/
always @(negedge clk2)
begin
AD_BUSY_buf1 <= AD_BUSY;
AD_BUSY_buf2 <= AD_BUSY_buf1;
end
assign negedge_AD_BUSY = AD_BUSY_buf2 && (!AD_BUSY_buf1); //下降沿
assign posedge_AD_BUSY = (!AD_BUSY_buf2) && AD_BUSY_buf1; //上升沿


always @ (posedge clk2 or negedge nRst) // rd_cntr   
begin
if(!nRst)
rd_cntr <= 4'd0;
else
begin
if(current_adc_state == WAIT_CONST)
begin
if(rd_cntr < 4'd4)
rd_cntr <= rd_cntr + 4'd1;
else   rd_cntr <= 4'd0;
end
else;
end 
end




always @ (posedge clk2 or negedge nRst) // sclk_cntr   
begin
if(!nRst)
sclk_cntr <= 4'd0;
else if(current_adc_state == READ_DATA) //判断状态机状态是否在读数据
begin
if(sclk_cntr == (RD_PULSE_WIDTH - 1)) //从0累加到9
sclk_cntr <= 4'd0;
else
sclk_cntr <= sclk_cntr + 4'd1;
end
else   sclk_cntr <= 9'd0;
end


/**************结合上面程序   产生AD_SCL脉冲******************/
always @ (posedge clk2 or negedge nRst) // AD_SCLK  当rd_cntr = 5时  AD_SCLK = 1  也就是说片选为高电平
begin
if(!nRst)
AD_SCLK <= 1'b1;
else
begin
if(current_adc_state == READ_DATA && AD_CS == 0) // 在读状态
begin
if(sclk_cntr == 0)
AD_SCLK <= 1'b0;
else if(sclk_cntr == RD_PULSE_WIDTH / 2)
AD_SCLK <= 1'b1;
else;
end
else
AD_SCLK <= 1'b1;
end
end


always @ (posedge clk2 or negedge nRst)  
begin
if(!nRst)
cntr <= 0;
else 
if(current_adc_state == READ_DATA && AD_CS == 0 ) // 在读状态
begin
if(sclk_cntr == RD_PULSE_WIDTH / 2)
cntr <= cntr + 1;
else ;
end
else   cntr <= 0;
end


always @ (posedge clk2 or negedge nRst)//AD_CS
begin
if(!nRst)
AD_CS <= 1;
else
begin
if(current_adc_state == WAIT_BUSY || current_adc_state == READ_DATA)
begin
// if(negedge_AD_BUSY == 1 && AD_Convst == 1'b1)//&& CS_cntr < 9'd400)
AD_CS <= 0;
// else;
end
else
AD_CS <= 1;
end
end

always @ (posedge clk2 or negedge nRst)// cnvt_cntr  仅是START_CONVST 外部累加到cnvt_cntr = 10 转换到下一状态的过程
begin
if(!nRst)
cnvt_cntr <= 8'd0;
else 
begin
if(current_adc_state == START_CONVST)
cnvt_cntr <= cnvt_cntr + 4'd1;
else
cnvt_cntr <= 8'd0;
end
end


always @ (posedge clk2 or negedge nRst)// busy_cntr  跟上述情况一样  是一个计数累加 转换到下一状态的过程 对应WAIT_BUSY
begin
if(!nRst)
busy_cntr <= 16'd0;
else
begin
if(current_adc_state == WAIT_BUSY)
busy_cntr <= busy_cntr + 16'd1;
else
busy_cntr <= 16'd0;
end
end


always @ (posedge clk2 or negedge nRst)//(posedge ClkIn or negedge nRst) // rst_cntr    累加的过程  等待
begin   
if(!nRst)
begin
rst_cntr <= 4'd0;
AD_Rst <= 1'b0;
end
else 
if(current_adc_state == ADC_RESET)
begin
// if(rst_cntr < 4'd8)
if(rst_cntr < 4'd15)
begin
AD_Rst <= 1'b1;
rst_cntr <= rst_cntr + 4'd1;
end
else
rst_cntr <= rst_cntr;
end
else
begin
rst_cntr <= 4'd0;
AD_Rst <= 1'b0;
end
end

always @ (posedge clk2 or negedge nRst)// adc_state
begin
if(!nRst)
current_adc_state <= ADC_RESET;
else
begin
case(current_adc_state)
WAIT_CONST://0
begin
if(rd_cntr == 4'd3)
current_adc_state <= START_CONVST;
else
current_adc_state <= WAIT_CONST;
end
START_CONVST://1
begin
if(cnvt_cntr <= (CNVT_WIDTH - 8'd1))
current_adc_state <= START_CONVST;
else
current_adc_state <= WAIT_BUSY;
end
WAIT_BUSY://2
begin
if(busy_cntr < (BUSY_WIDTH - 16'd1))
current_adc_state <= WAIT_BUSY;
else
current_adc_state <= READ_DATA;
end
READ_DATA://3
begin
if(cntr == 128)
current_adc_state <= CONVST_FINISH;
else
current_adc_state <= READ_DATA;
end
CONVST_FINISH://4
begin
if(convertoverflag)
current_adc_state <= ADC_RESET;
else current_adc_state <= CONVST_FINISH;
end
ADC_RESET://5
begin
// if(rst_cntr == 4'd7)
if(rst_cntr == 4'd14)
current_adc_state <= WAIT_CONST;
else
current_adc_state <= ADC_RESET;
end
default:
current_adc_state <= ADC_RESET;
endcase
end
end




always @ (posedge clk2 or negedge nRst)// AD_Convst
begin
if(!nRst)
AD_Convst <= 1'b1;
else
begin
if(current_adc_state == START_CONVST)
AD_Convst <= 1'b0;
else
AD_Convst <= 1'b1;
end
end


always @ (posedge clk2 or negedge nRst)//
begin
if(!nRst)
begin
Ch0SampleData[15:0] <= 16'd0;
Ch1SampleData[15:0] <= 16'd0;
Ch2SampleData[15:0] <= 16'd0;
Ch3SampleData[15:0] <= 16'd0;
Ch4SampleData[15:0] <= 16'd0;
Ch5SampleData[15:0] <= 16'd0;
Ch6SampleData[15:0] <= 16'd0;
Ch7SampleData[15:0] <= 16'd0;
convertoverflag<=0;
AD_DB_info[127:0] <= 0;
end
else
begin 
     case (current_adc_state) 
         WAIT_BUSY: 
begin
AD_DB_info[127:0] <= 0;
end
         READ_DATA:  
begin
convertoverflag<=0;
if((sclk_cntr == RD_PULSE_WIDTH / 2 - 1) && cntr < 128 && AD_CS == 0)
AD_DB_info[127:0] <= {AD_DB_info[126:0],AD_DB};
else
AD_DB_info[127:0]<=AD_DB_info[127:0];
end
CONVST_FINISH: 
begin
Ch0SampleData[15:0] <= AD_DB_info[127:112];
Ch1SampleData[15:0] <= AD_DB_info[111:96];
Ch2SampleData[15:0] <= AD_DB_info[95:80];
Ch3SampleData[15:0] <= AD_DB_info[79:64];
Ch4SampleData[15:0] <= AD_DB_info[63:48];
Ch5SampleData[15:0] <= AD_DB_info[47:32];
Ch6SampleData[15:0] <= AD_DB_info[31:16];
Ch7SampleData[15:0] <= AD_DB_info[15:0];
convertoverflag<=1;
end
         default:          
AD_DB_info[127:0] <= 0;
endcase
   end
end

endmodule 

你可能感兴趣的:(ADC7606源代码)