ad7864_controller adc_ctrl(
clock_i,
reset_ni,
start_i,
started_o,
over_o,
data_o,
cs_no,
rd_no,
convst_no,
busy_i,
db_i
);
parameter data_width = 12;
input clock_i;
input reset_ni;
input start_i;
output reg started_o;
output reg over_o;
output reg [data_width-1:0] data_o;
output cs_no; // CS*
output reg rd_no; // RD*
output reg convst_no; // CONVST*
input busy_i;
input [data_width-1:0] db_i; // DB11 - DB0
reg [4:1] state;
localparam s_idle = 4'b0001;
localparam s_convst = 4'b0010; // start conversion
localparam s_wait_busy = 4'b0100; // wait busy's negative edge
localparam s_get_data = 4'b1000; // read the converted data
reg busy_former;
`define NEGATIVE_BUSY ((busy_former) && !(busy_i))
assign cs_no = 1'b0;
// state machine
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) state <= s_idle;
else case(state)
s_idle: if(start_i) state <= s_convst;
s_convst: state <= s_wait_busy;
s_wait_busy: if(`NEGATIVE_BUSY) state <= s_get_data;
s_get_data: state <= s_idle;
default: state <= s_idle;
endcase
end
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) busy_former <= 1'b0;
else busy_former <= busy_i;
end
// start conversion
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) convst_no <= 1'b1;
else case(state)
s_idle: if(start_i) convst_no <= 1'b0; // Note: clock period > 35ns
default: convst_no <= 1'b1;
endcase
end
// read from AD7864
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) rd_no <= 1'b1;
else case(state)
s_wait_busy: if(`NEGATIVE_BUSY) rd_no <= 1'b0;// Note: clock period > 35ns
default: rd_no <= 1'b1;
endcase
end
// register data comming from AD7864
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) data_o <= {data_width{1'b0}};
else case(state)
s_get_data: data_o <= db_i;
endcase
end
// indicating converion is over and data is read
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) over_o <= 1'b0;
else case(state)
s_get_data: over_o <= 1'b1;
default: over_o <= 1'b0;
endcase
end
// conversion started, analog signal has alread held,
// waiting for conversion finished
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) started_o <= 1'b0;
else case(state)
s_convst: started_o <= 1'b1;
default: started_o <= 1'b0;
endcase
end
endmodule
module xuxu (clock_i,
reset_ni,
start_i,
started_o,
over_o,
data_o,
cs_no,
rd_no,
convst_no,
busy_i,
db_i
);
parameter data_width = 12;
input clock_i;
input reset_ni;
input start_i;
output reg started_o;
output reg over_o;
output reg [data_width-1:0] data_o;
output cs_no; // CS*
output reg rd_no; // RD*
output reg convst_no; // CONVST*
input busy_i;
input [data_width-1:0] db_i; // DB11 - DB0
reg [4:1] state;
localparam s_idle = 4'b0001;
localparam s_convst = 4'b0010; // start conversion
localparam s_wait_busy = 4'b0100; // wait busy's negative edge
localparam s_get_data = 4'b1000; // read the converted data
reg busy_former;
`define NEGATIVE_BUSY ((busy_former) && !(busy_i))
assign cs_no = 1'b0;
// state machine
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) state <= s_idle;
else case(state)
s_idle: if(start_i) state <= s_convst;
s_convst: state <= s_wait_busy;
s_wait_busy: if(`NEGATIVE_BUSY) state <= s_get_data;
s_get_data: state <= s_idle;
default: state <= s_idle;
endcase
end
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) busy_former <= 1'b0;
else busy_former <= busy_i;
end
// start conversion
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) convst_no <= 1'b1;
else case(state)
s_idle: if(start_i) convst_no <= 1'b0; // Note: clock period > 35ns
default: convst_no <= 1'b1;
endcase
end
// read from AD7864
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) rd_no <= 1'b1;
else case(state)
s_wait_busy: if(`NEGATIVE_BUSY) rd_no <= 1'b0;// Note: clock period > 35ns
default: rd_no <= 1'b1;
endcase
end
// register data comming from AD7864
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) data_o <= {data_width{1'b0}};
else case(state)
s_get_data: data_o <= db_i;
endcase
end
// indicating converion is over and data is read
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) over_o <= 1'b0;
else case(state)
s_get_data: over_o <= 1'b1;
default: over_o <= 1'b0;
endcase
end
// conversion started, analog signal has alread held,
// waiting for conversion finished
always @(posedge clock_i or negedge reset_ni) begin
if(!reset_ni) started_o <= 1'b0;
else case(state)
s_convst: started_o <= 1'b1;
default: started_o <= 1'b0;
endcase
end
Endmodule
module fsm(clock_i,reset_n,busy_i,frstdata,eoc):
input clock_i,reset_n,busy_i,frstdata,eoc;
reg[2:0] state;
parameter idle=3’h0,sua=3’h1,sub=3’h2,suc=3’h3,sud=3’h4;
always@(posedge clock_i or negedge reset_n or state)
begin
if(!reset_n)
state=idle;
else begin
case(state)
idle:begin if(frstdata) state=sua;
else state=idle;
end
sua:begin if(!eoc)
state=sub;
else state=sua;
end
sub:begin if(!eoc)
state=suc;
else state=sub;
end
suc:begin if(!eoc)
state=sud;
else state=sud;
end
sud:begin if(busy)
state=sud;
else state=idle;
end
defalt:state=idle;
endcase |