高级会员
- 积分
- 800
- 金钱
- 800
- 注册时间
- 2016-11-25
- 在线时间
- 93 小时
|
//=============================================================
// Module : ad7606_driver.v
// Function : ADC7606驱动模块,8通道输入,并行模式输出16bit
// Author : snjshping
// Date : 20191208
// Version : 1.0
//=============================================================
module ad7606_driver
(
input Clock ,
input Rst_n ,
input iAd_start_en ,
input iAd_frstdata ,
input iAd_busy ,
input [15:0] iAd_data ,
output [2:0] oAd_os ,
output reg oAd_cs_n ,
output reg oAd_rd_n ,
output reg oAd_reset_p ,
output reg oAd_convest_ab,
output reg [15:0] oAd_ch1_vaule ,
output reg [15:0] oAd_ch2_vaule ,
output reg [15:0] oAd_ch3_vaule ,
output reg [15:0] oAd_ch4_vaule ,
output reg [15:0] oAd_ch5_vaule ,
output reg [15:0] oAd_ch6_vaule ,
output reg [15:0] oAd_ch7_vaule ,
output reg [15:0] oAd_ch8_vaule ,
output beep ,
output reg oAd_conv_done
);
//=============================================================
// parameter define
//=============================================================
localparam ST_IDLE = 12'b0000_0000_0001;
localparam ST_AD_CONV = 12'b0000_0000_0010;
localparam ST_WAIT_BUSY = 12'b0000_0000_0100;
localparam ST_RD_CH1 = 12'b0000_0000_1000;
localparam ST_RD_CH2 = 12'b0000_0001_0000;
localparam ST_RD_CH3 = 12'b0000_0010_0000;
localparam ST_RD_CH4 = 12'b0000_0100_0000;
localparam ST_RD_CH5 = 12'b0000_1000_0000;
localparam ST_RD_CH6 = 12'b0001_0000_0000;
localparam ST_RD_CH7 = 12'b0010_0000_0000;
localparam ST_RD_CH8 = 12'b0100_0000_0000;
localparam ST_RD_END = 12'b1000_0000_0000;
//=============================================================
// wire define
//=============================================================
//=============================================================
// reg define
//=============================================================
reg [11:0] rCurr_state ;
reg [11:0] rNext_state ;
reg rSkip_en ;
reg [15:0] rRst_cnt ;
reg [5:0] rClk_cnt ;
//-------------------------------------------------------------
// don't use oversampling with os[2:0] = 3'b000
//-------------------------------------------------------------
assign oAd_os[2:0] = 3'b000;
assign beep = 1'b1;
//-------------------------------------------------------------
// generating reset signal to reset ad7606 with high level
//-------------------------------------------------------------
always@(posedge Clock or negedge Rst_n)
begin
if(Rst_n == 1'b0)
begin
rRst_cnt[15:0] <= 16'd0;
end
else
begin
rRst_cnt[15:0] <= (rRst_cnt[15:0] == 16'hffff) ? rRst_cnt[15:0] : (rRst_cnt[15:0] + 16'd1);
end
end
always@(posedge Clock or negedge Rst_n)
begin
if(Rst_n == 1'b0)
begin
oAd_reset_p <= 1'b0;
end
else
begin
oAd_reset_p <= (rRst_cnt[15:0] < 16'hffff) ? 1'b1 : 1'b0;
end
end
//-------------------------------------------------------------
// Temporal logic describes state transitions
//-------------------------------------------------------------
always @ ( posedge Clock or negedge Rst_n )
begin
rCurr_state[11:0] <= (Rst_n == 1'b0) ? ST_IDLE : rNext_state[11:0];
end
//-------------------------------------------------------------
// combination logic describes state transitions
//-------------------------------------------------------------
always @ ( * )
begin
case(rCurr_state[11:0])
ST_IDLE : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_AD_CONV : ST_IDLE;
ST_AD_CONV : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_WAIT_BUSY : ST_AD_CONV;
ST_WAIT_BUSY : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH1 : ST_WAIT_BUSY;
ST_RD_CH1 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH2 : ST_RD_CH1;
ST_RD_CH2 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH3 : ST_RD_CH2;
ST_RD_CH3 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH4 : ST_RD_CH3;
ST_RD_CH4 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH5 : ST_RD_CH4;
ST_RD_CH5 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH6 : ST_RD_CH5;
ST_RD_CH6 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH7 : ST_RD_CH6;
ST_RD_CH7 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_CH8 : ST_RD_CH7;
ST_RD_CH8 : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_RD_END : ST_RD_CH8;
ST_RD_END : rNext_state[11:0] = (rSkip_en == 1'b1) ? ST_IDLE : ST_RD_END;
default : rNext_state[11:0] = ST_IDLE;
endcase
end
//-------------------------------------------------------------
// Temporal logic describes output
//-------------------------------------------------------------
always @ ( posedge Clock )
begin
if(oAd_reset_p == 1'b1)
begin
rSkip_en <= 1'b0;
rClk_cnt[5:0] <= 6'd0;
oAd_cs_n <= 1'b1;
oAd_rd_n <= 1'b1;
oAd_convest_ab <= 1'b1;
oAd_ch1_vaule[15:0] <= 16'd0;
oAd_ch2_vaule[15:0] <= 16'd0;
oAd_ch3_vaule[15:0] <= 16'd0;
oAd_ch4_vaule[15:0] <= 16'd0;
oAd_ch5_vaule[15:0] <= 16'd0;
oAd_ch6_vaule[15:0] <= 16'd0;
oAd_ch7_vaule[15:0] <= 16'd0;
oAd_ch8_vaule[15:0] <= 16'd0;
oAd_conv_done <= 1'b0;
end
else
begin
case(rCurr_state[11:0])
ST_IDLE : begin
oAd_cs_n <= 1'b1;
oAd_rd_n <= 1'b1;
oAd_convest_ab <= 1'b1;
oAd_conv_done <= 1'b0;
rClk_cnt[5:0] <= 6'd0;
rSkip_en <= ((iAd_start_en == 1'b1) && (rNext_state[11:0] == ST_IDLE)) ? 1'b1 : 1'b0;
// 注意:若只写rSkip_en <= (iAd_start_en == 1'b1) ? 1'b1 : 1'b0;
// 则产生两个时钟周期的rSkip_en信号,导致下一个状态逻辑错误
end
ST_AD_CONV : begin
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd9) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_convest_ab <= (rClk_cnt[5:0] <= 6'd1) ? 1'b0 : 1'b1;
rSkip_en <= (rClk_cnt[5:0] == 6'd8) ? 1'b1 : 1'b0;
end
ST_WAIT_BUSY : begin
rClk_cnt[5:0] <= 6'd0;
rSkip_en <= ((iAd_busy == 1'b0) && (rNext_state[11:0] == ST_WAIT_BUSY)) ? 1'b1 : 1'b0;
end
ST_RD_CH1 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch1_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch1_vaule[15:0];
end
ST_RD_CH2 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch2_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch2_vaule[15:0];
end
ST_RD_CH3 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch3_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch3_vaule[15:0];
end
ST_RD_CH4 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch4_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch4_vaule[15:0];
end
ST_RD_CH5 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch5_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch5_vaule[15:0];
end
ST_RD_CH6 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch6_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch6_vaule[15:0];
end
ST_RD_CH7 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch7_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch7_vaule[15:0];
end
ST_RD_CH8 : begin
oAd_cs_n <= 1'b0;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd3) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_rd_n <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd2) ? 1'b1 : 1'b0;
oAd_ch8_vaule[15:0] <= (rClk_cnt[5:0] == 6'd3) ? iAd_data[15:0] : oAd_ch8_vaule[15:0];
end
ST_RD_END : begin
oAd_rd_n <= 1'b1;
rClk_cnt[5:0] <= (rClk_cnt[5:0] == 6'd1) ? 6'd0 : (rClk_cnt[5:0] + 6'd1);
oAd_cs_n <= (rClk_cnt[5:0] == 6'd1) ? 1'b1 : 1'b0;
rSkip_en <= (rClk_cnt[5:0] == 6'd0) ? 1'b1 : 1'b0;
oAd_conv_done <= ((rClk_cnt[5:0] == 6'd0) && (rNext_state[11:0] == ST_RD_END)) ? 1'b1 : 1'b0;
end
default : ;
endcase
end
end
endmodule
/************************************************
ad7606_driver inst_ad7606_driver (
.Clock (Clock),
.Rst_n (Rst_n),
.iAd_start_en (iAd_start_en),
.iAd_frstdata (iAd_frstdata),
.iAd_busy (iAd_busy),
.iAd_data (iAd_data),
.oAd_reset_p (oAd_reset_p),
.oAd_os (oAd_os),
.oAd_convest_ab (oAd_convest_ab),
.oAd_cs_n (oAd_cs_n),
.oAd_rd_n (oAd_rd_n),
.oAd_ch1_vaule (oAd_ch1_vaule),
.oAd_ch2_vaule (oAd_ch2_vaule),
.oAd_ch3_vaule (oAd_ch3_vaule),
.oAd_ch4_vaule (oAd_ch4_vaule),
.oAd_ch5_vaule (oAd_ch5_vaule),
.oAd_ch6_vaule (oAd_ch6_vaule),
.oAd_ch7_vaule (oAd_ch7_vaule),
.oAd_ch8_vaule (oAd_ch8_vaule),
.oAd_conv_done (oAd_conv_done)
);
*************************************************/
|
|