//==============================================================================
`define UD #1
`define ADC_HALF_CLK_TIME 6'h17
`define ADC_CLK_TIME 6'h2E
`define ADC_CONV_TIME 10'h352
//1.1M ,t = 909ns, 909/20=46=0x2e,0x2e/2=0x17
//17us ,17000ns/20=850,0x352
module ADC_TLC549_CTL
(
SYSCLK,
RST_B,
ADC_EN,
ADC_CS,
ADC_CLK,
ADC_DATA,
VOL_INT,
VOL_DEC
);
//==============================================================================
//Input and output declaration
//==============================================================================
input SYSCLK;
input RST_B;
input ADC_EN;
output ADC_CS;
output ADC_CLK;
input ADC_DATA;
output [3:0] VOL_INT;
output [3:0] VOL_DEC;
//==============================================================================
//Wire and reg declaration
//==============================================================================
wire SYSCLK;
wire RST_B;
wire ADC_EN;
reg ADC_CS;
reg ADC_CLK;
wire ADC_DATA;
reg [3:0] VOL_INT;
reg [3:0] VOL_DEC;
//==============================================================================
//Wire and reg in the module
//==============================================================================
reg [5:0] TIME_CNT;
reg [5:0] TIME_CNT_N;
reg ADC_CS_N;
reg ADC_CLK_N;
reg [5:0] BIT_CNT;
reg [5:0] BIT_CNT_N;
reg [1:0] ADC_FSM_CS;
reg [1:0] ADC_FSM_NS;
reg [7:0] DATA_R;
wire [7:0] DATA_R_N;
reg [7:0] DATA_REG_R;
reg [7:0] DATA_REG_R_N;
wire [3:0] VOL_INT_N;
wire [3:0] VOL_DEC_N;
wire [11:0] MID1;
wire [11:0] MID2;
parameter FSM_IDLE = 3'h0;
parameter FSM_READY = 3'h1;
parameter FSM_READ = 3'h2;
parameter FSM_WAIT_CONV = 3'h3;
//==============================================================================
//Logic
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
TIME_CNT <= `UD 6'h0;
else
TIME_CNT <= `UD TIME_CNT_N;
end
always @ (*)
begin
if(!ADC_EN)
TIME_CNT_N = 6'h0;
else if(TIME_CNT == `ADC_CLK_TIME)
TIME_CNT_N = 6'h0;
else
TIME_CNT_N = TIME_CNT + 6'h1;
end
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
BIT_CNT <= `UD 6'h0;
else
BIT_CNT <= `UD BIT_CNT_N;
end
always @ (*)
begin
if(!ADC_EN)
BIT_CNT_N = 6'h0;
else if(ADC_FSM_CS != ADC_FSM_NS)
BIT_CNT_N = 6'h0;
else if(TIME_CNT == `ADC_HALF_CLK_TIME)
BIT_CNT_N = BIT_CNT + 6'h1;
else
BIT_CNT_N = BIT_CNT;
end
//==============================================================================
//Fsm of ADC
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
ADC_FSM_CS <= `UD FSM_IDLE;
else
ADC_FSM_CS <= `UD ADC_FSM_NS;
end
always @ (*)
begin
case(ADC_FSM_CS)
FSM_IDLE:
if((BIT_CNT == 6'h2 ) && (TIME_CNT == `ADC_CLK_TIME) && ADC_EN)
ADC_FSM_NS = FSM_READY;
else
ADC_FSM_NS = ADC_FSM_CS;
FSM_READY:
if((BIT_CNT == 6'h1 ) && (TIME_CNT == `ADC_CLK_TIME))
ADC_FSM_NS = FSM_READ;
else
ADC_FSM_NS = ADC_FSM_CS;
FSM_READ:
if((BIT_CNT == 6'h8 ) && (TIME_CNT == `ADC_CLK_TIME))
ADC_FSM_NS = FSM_WAIT_CONV;
else
ADC_FSM_NS = ADC_FSM_CS;
FSM_WAIT_CONV:
if((BIT_CNT == 6'h12) && (TIME_CNT == `ADC_CLK_TIME))
ADC_FSM_NS = FSM_READY;
else
ADC_FSM_NS = ADC_FSM_CS;
default:
ADC_FSM_NS = FSM_IDLE;
endcase
end
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
ADC_CLK <= `UD 1'h0;
else
ADC_CLK <= `UD ADC_CLK_N;
end
always @ (*)
begin
if(ADC_FSM_CS != FSM_READ)
ADC_CLK_N = 1'h0;
else if(TIME_CNT == `ADC_HALF_CLK_TIME)
ADC_CLK_N = 1'h1;
else if(TIME_CNT == `ADC_CLK_TIME)
ADC_CLK_N = 1'h0;
else
ADC_CLK_N = ADC_CLK;
end
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
ADC_CS <= `UD 1'h0;
else
ADC_CS <= `UD ADC_CS_N;
end
always @ (*)
begin
if(!ADC_EN)
ADC_CS_N = 1'h1;
else if((ADC_FSM_CS == FSM_READ) || (ADC_FSM_CS == FSM_READY))
ADC_CS_N = 1'h0;
else
ADC_CS_N = 1'h1;
end
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
DATA_REG_R <= `UD 8'h0;
else
DATA_REG_R <= `UD DATA_REG_R_N;
end
always @(*)
begin
if((ADC_FSM_CS == FSM_READ) && (!ADC_CLK) && (ADC_CLK_N))
DATA_REG_R_N = {DATA_REG_R[6:0],ADC_DATA};
else
DATA_REG_R_N = DATA_REG_R;
end
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
DATA_R <= `UD 8'h0;
else
DATA_R <= `UD DATA_R_N;
end
assign DATA_R_N = (ADC_FSM_CS == FSM_READY) ? DATA_REG_R : DATA_R;
//assign DATA_R_N = 8'h80;//for modelsim test
//==============================================================================
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
VOL_INT <= `UD 4'h0;
else
VOL_INT <= `UD VOL_INT_N;
end
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
VOL_DEC <= `UD 4'h0;
else
VOL_DEC <= `UD VOL_DEC_N;
end
assign VOL_INT_N = MID1[11:8];//整数部分
assign VOL_DEC_N = MID2[11:8];//小数部分
//==============================================================================
// ADC Voltage calculate
// DATA_R / FF = voltage / 5 (the ADC ref voltage is 5V)
// so. voltage = 5DATA_R / FF
// so .voltage = 5DATA_R >> 8
// so .voltage(整数部分) = ((DATA_R << 2) + DATA_R) >> 8
// so .voltage(小数部分) = ((5DATA_R & 0XFF) X 10 ) >> 8
assign MID1 = {2'h0,DATA_R[7:0],2'h0} + {4'h0,DATA_R[7:0] };//5DATA_R = (DATA_R << 2) + DATA_R
assign MID2 = {1'h0, MID1[7:0],3'h0} + {3'h0, MID1[7:0],1'h0};// X 10
endmodule
//==============================================================================
// END OF FILE
//==============================================================================
评论0