源码来自:https://bbs.21ic.com/icview-3013846-1-1.html
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
module adc1118
#
(
parameter SPI_SCK_CYCLE = 50,
parameter SPI_BIT_NUM = 16
)
(
input i_clk,
input i_rsto_power_on,
//
input [1 : 0] i_fpga_spi_cs_0_s,
output o_fpga_spi_sck,
output o_fpga_spi_cs,
input i_fpga_spi_miso,
output o_fpga_spi_mosi,
//
output [15 : 0] o_adc_c1_data,
output [15 : 0] o_adc_c2_data
);
reg [7 : 0] cs_cnt;
reg [5 : 0] ws;//work state
reg fpga_spi_miso_d;
reg [6:0] basic_clk_cnt ;
reg [4:0] fpga_spi_clk_cnt;
reg [3:0] spi_byte_cnt ;
wire [2:0] spi_bit_index;
reg fpga_spi_sck = 0;
reg fpga_spi_cs = 1;
reg fpga_spi_mosi = 0;
wire sample_point;
reg sample_point_d;
reg [15 : 0] adc_c1_data;
reg [15 : 0] adc_c2_data;
reg [15 : 0] adc_c1_data_r;
reg [15 : 0] adc_c2_data_r;
wire clk = i_clk;
wire rsto_power_on = i_rsto_power_on;
wire [1 : 0] fpga_spi_cs_0_s = i_fpga_spi_cs_0_s;
wire fpga_spi_miso = i_fpga_spi_miso;
//------------------------------------------------------------------------------
//datasheet: "The next time CS is taken low, data transmission starts with the currently buffered conversion result
//on the first SCLK rising edge. If DOUT/DRDY is low when data retrieval starts, the conversion buffer is
//already updated with a new result. Otherwise, if DOUT/DRDY is high, the same result from the previous data
//transmission cycle is read."
//
parameter S_IDLE = 6'b00_0001;
parameter S_IN_RD = 6'b00_0010;
parameter S_ADC_WR_FRONT = 6'b00_0100;
parameter S_ADC_WR_WAIT = 6'b00_1000;
parameter S_ADC_WR = 6'b01_0000;
parameter S_ADC_WR_BACK = 6'b10_0000;
//
//
//8ms is 128sps of ADC.
//"fpga_spi_cs_0_s_cnt" is used to count the number of 0.6ms.
reg [9:0] fpga_spi_cs_0_s_cnt;
//
always @(posedge clk)
begin
if (~rsto_power_on) fpga_spi_cs_0_s_cnt <= 10'd0;
else if(fpga_spi_cs_0_s == 2'b01) fpga_spi_cs_0_s_cnt <= fpga_spi_cs_0_s_cnt + 1;
else fpga_spi_cs_0_s_cnt <= fpga_spi_cs_0_s_cnt;
end
//
//channel_change_flag "0": send AN2-3 command; "1" send AN0-1 command.
//
reg channel_change_flag;
always @(posedge clk)
begin
if (~rsto_power_on) channel_change_flag <= 1'b0;
else if(fpga_spi_cs_0_s == 2'b01)
begin
if(&fpga_spi_cs_0_s_cnt) channel_change_flag <= ~channel_change_flag;
end
end
//
//
always @(posedge clk)
begin
if (~rsto_power_on) ws <= S_IDLE;
else
case(ws)
S_IDLE : ws <= S_IN_RD;
//
S_IN_RD : if(fpga_spi_cs_0_s == 2'b01)
begin
if(&fpga_spi_cs_0_s_cnt[3:0]) ws <= S_ADC_WR_FRONT;
end
//
S_ADC_WR_FRONT : if(&cs_cnt) ws <= S_ADC_WR;
//S_ADC_WR_WAIT : if(~fpga_spi_miso) ws <= S_ADC_WR;
S_ADC_WR : if((basic_clk_cnt == SPI_SCK_CYCLE - 1)&(fpga_spi_clk_cnt == SPI_BIT_NUM - 1)) ws <= S_ADC_WR_BACK;
S_ADC_WR_BACK : if(&cs_cnt) ws <= S_IDLE;
default: ;
endcase
end