140 lines
3.0 KiB
Verilog
140 lines
3.0 KiB
Verilog
module AD9226(
|
||
|
||
clk,
|
||
rst_n,
|
||
En_Conv,
|
||
DIV_PARAM,
|
||
AD_IN,
|
||
|
||
clk_out,
|
||
Conv_Done,
|
||
ADC_State,
|
||
AD_OUT
|
||
|
||
|
||
);
|
||
|
||
|
||
input clk;
|
||
input rst_n;
|
||
input En_Conv;
|
||
input [7:0]DIV_PARAM;//分频
|
||
input [11:0] AD_IN;
|
||
|
||
|
||
output reg clk_out;//时钟输出
|
||
output reg Conv_Done;//转化完成
|
||
output ADC_State;//转换状态
|
||
output reg [11:0] AD_OUT;
|
||
|
||
parameter FILTER_PARAM = 3'd5; //除以32 == 右移5位
|
||
parameter CON_CNT = 6'd35;
|
||
|
||
|
||
|
||
reg en;
|
||
reg [7:0] DIV_CNT;
|
||
reg [5:0] con_cnt;
|
||
|
||
reg [11:0] AD_MAX,AD_MIN;
|
||
reg [17:0] AD_SUM;
|
||
reg [2:0] adc_clked;
|
||
wire adc_pedge,adc_nedge;
|
||
|
||
assign ADC_State = en;
|
||
assign adc_nedge = !adc_clked[1] & adc_clked[2];
|
||
assign adc_pedge = adc_clked[1] & (!adc_clked[2]);
|
||
|
||
always @(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
adc_clked <= 3'd0;
|
||
else
|
||
adc_clked <= {adc_clked[1:0],clk_out};
|
||
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
con_cnt <= 6'd0;
|
||
else if (Conv_Done)
|
||
con_cnt <= 6'd0;
|
||
else if (adc_pedge)
|
||
con_cnt <= con_cnt + 1'd1;
|
||
|
||
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
Conv_Done <= 1'b0;
|
||
else if((con_cnt == CON_CNT - 1'b1) && adc_nedge)
|
||
Conv_Done <= 1'b1;
|
||
else
|
||
Conv_Done <= 1'b0;
|
||
|
||
//产生使能转换信号
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
en <= 1'b0;
|
||
else if(En_Conv)
|
||
en <= 1'b1;
|
||
else if(Conv_Done)
|
||
en <= 1'b0;
|
||
else
|
||
en <= en;
|
||
|
||
//生成SCLK使能时钟计数器
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
DIV_CNT <= 8'd0;
|
||
else if(en)
|
||
begin
|
||
if(DIV_CNT == (DIV_PARAM - 1'b1))
|
||
DIV_CNT <= 8'd0;
|
||
else
|
||
DIV_CNT <= DIV_CNT + 1'b1;
|
||
end
|
||
else
|
||
DIV_CNT <= 8'd0;
|
||
|
||
//生成SCLK使能时钟
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
clk_out <= 1'b0;
|
||
else if(en && (DIV_CNT == (DIV_PARAM - 1'b1)))
|
||
clk_out <= (~clk_out);
|
||
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
AD_MAX <= 12'd0;
|
||
else if(Conv_Done || en == 1'b0)
|
||
AD_MAX <= 12'd0;
|
||
else if(adc_pedge)begin//转换完成,转换计数为奇数,判断当前值是否大于已存最大值
|
||
if(AD_IN > AD_MAX)
|
||
AD_MAX <= AD_IN;
|
||
end
|
||
|
||
//记录采样的最小值
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
AD_MIN <= 12'd0;
|
||
else if(Conv_Done || en == 1'b0)
|
||
AD_MIN <= 12'd4095;
|
||
else if(adc_pedge)begin//转换完成,转换计数为奇数,判断当前值是否小于已存最小值
|
||
if(AD_IN < AD_MIN)
|
||
AD_MIN<= AD_IN;
|
||
end
|
||
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
AD_SUM <= 18'd0;
|
||
else if(Conv_Done || en == 1'b0)
|
||
AD_SUM <= 18'd0;
|
||
else if(adc_pedge)//转换完成,转换计数为偶数,将转换结果累加到Y临时寄存器
|
||
AD_SUM <= AD_SUM + AD_IN;
|
||
|
||
always@(posedge clk or negedge rst_n)
|
||
if(!rst_n)
|
||
AD_OUT <= 12'd0;
|
||
else if((con_cnt == CON_CNT - 1'b1) && adc_nedge)
|
||
AD_OUT <= (AD_SUM - AD_MIN - AD_MAX) >> FILTER_PARAM;
|
||
|
||
|
||
endmodule
|