ADC7606源代码

xiaoxiao2021-02-28  86

`timescale 1ns /  1ps module ADC7606Driver #( parameter CNVT_WIDTH = 8'd40, parameter BUSY_WIDTH = 16'd1800 // OS = 1, Oversampling by 2, MAX 10us ) ( input nRst , input ClkIn , input AD_DB , input clk2 , output reg AD_Rst , output reg AD_CS , output reg AD_Convst , output reg [2:0] OS , output reg convertoverflag,, input AD_BUSY , // not exist  ????? output reg [15 : 0] Ch0SampleData , //用于current:y奇数 output reg [15 : 0] Ch1SampleData , //用于current:f奇数 output reg [15 : 0] Ch2SampleData , //用于current:f偶数 output reg [15 : 0] Ch3SampleData , //用于current:y偶数 output reg [15 : 0] Ch4SampleData ,      //一下Ch_SampleData未用 output reg [15 : 0] Ch5SampleData , output reg [15 : 0] Ch6SampleData , output reg [15 : 0] Ch7SampleData , output reg [2 : 0] current_adc_state , output reg [3 : 0] rst_cntr , output reg AD_SCLK ); //定义状态机的状态 代码中使用case语句的状态机  同时也使用分模块相连接 localparam WAIT_CONST = 3'b000, //等待脉冲 START_CONVST = 3'b001, //开始转换 WAIT_BUSY = 3'b010, //等待忙碌 READ_DATA = 3'b011, //读数据 CONVST_FINISH = 3'b100, //数据转换完成 ADC_RESET = 3'b101; //数据复位 localparam RD_PULSE_WIDTH = 4'd10; //读脉冲宽度 parameter SCLK_count_value = 8'd128; reg [7 : 0] cnvt_cntr ; reg [15 : 0] busy_cntr ; reg      [3:0] rd_cntr ; reg [8:0] sclk_cntr ; reg [127:0] AD_DB_info; reg[7:0]cntr; reg  [3:0]OS_cntr; always @(posedge clk2 or negedge nRst) begin   if(!nRst) begin OS <= 3'b111; OS_cntr <= 0; end else   begin OS <= 3'b001; if(AD_BUSY ==0) begin if(OS_cntr < 4) begin OS_cntr <= OS_cntr + 1'b1; OS <= 3'b001; end else // if(OS_cntr == 4) begin // OS_cntr <= 0; OS <= 3'b111; end end else  begin OS <= 3'b001; OS_cntr <= 0; end end end wire posedge_AD_BUSY; wire negedge_AD_BUSY; reg AD_BUSY_buf1; reg AD_BUSY_buf2; /************************AD_BUSY上升沿的产生**************************/ always @(negedge clk2) begin AD_BUSY_buf1 <= AD_BUSY; AD_BUSY_buf2 <= AD_BUSY_buf1; end assign negedge_AD_BUSY = AD_BUSY_buf2 && (!AD_BUSY_buf1); //下降沿 assign posedge_AD_BUSY = (!AD_BUSY_buf2) && AD_BUSY_buf1; //上升沿 always @ (posedge clk2 or negedge nRst) // rd_cntr    begin if(!nRst) rd_cntr <= 4'd0; else begin if(current_adc_state == WAIT_CONST) begin if(rd_cntr < 4'd4) rd_cntr <= rd_cntr + 4'd1; else   rd_cntr <= 4'd0; end else; end  end always @ (posedge clk2 or negedge nRst) // sclk_cntr    begin if(!nRst) sclk_cntr <= 4'd0; else if(current_adc_state == READ_DATA) //判断状态机状态是否在读数据 begin if(sclk_cntr == (RD_PULSE_WIDTH - 1)) //从0累加到9 sclk_cntr <= 4'd0; else sclk_cntr <= sclk_cntr + 4'd1; end else   sclk_cntr <= 9'd0; end /**************结合上面程序   产生AD_SCL脉冲******************/ always @ (posedge clk2 or negedge nRst) // AD_SCLK  当rd_cntr = 5时  AD_SCLK = 1  也就是说片选为高电平 begin if(!nRst) AD_SCLK <= 1'b1; else begin if(current_adc_state == READ_DATA && AD_CS == 0) // 在读状态 begin if(sclk_cntr == 0) AD_SCLK <= 1'b0; else if(sclk_cntr == RD_PULSE_WIDTH / 2) AD_SCLK <= 1'b1; else; end else AD_SCLK <= 1'b1; end end always @ (posedge clk2 or negedge nRst)   begin if(!nRst) cntr <= 0; else  if(current_adc_state == READ_DATA && AD_CS == 0 ) // 在读状态 begin if(sclk_cntr == RD_PULSE_WIDTH / 2) cntr <= cntr + 1; else ; end else   cntr <= 0; end always @ (posedge clk2 or negedge nRst)//AD_CS begin if(!nRst) AD_CS <= 1; else begin if(current_adc_state == WAIT_BUSY || current_adc_state == READ_DATA) begin // if(negedge_AD_BUSY == 1 && AD_Convst == 1'b1)//&& CS_cntr < 9'd400) AD_CS <= 0; // else; end else AD_CS <= 1; end end always @ (posedge clk2 or negedge nRst)// cnvt_cntr  仅是START_CONVST 外部累加到cnvt_cntr = 10 转换到下一状态的过程 begin if(!nRst) cnvt_cntr <= 8'd0; else  begin if(current_adc_state == START_CONVST) cnvt_cntr <= cnvt_cntr + 4'd1; else cnvt_cntr <= 8'd0; end end always @ (posedge clk2 or negedge nRst)// busy_cntr  跟上述情况一样  是一个计数累加 转换到下一状态的过程 对应WAIT_BUSY begin if(!nRst) busy_cntr <= 16'd0; else begin if(current_adc_state == WAIT_BUSY) busy_cntr <= busy_cntr + 16'd1; else busy_cntr <= 16'd0; end end always @ (posedge clk2 or negedge nRst)//(posedge ClkIn or negedge nRst) // rst_cntr    累加的过程  等待 begin    if(!nRst) begin rst_cntr <= 4'd0; AD_Rst <= 1'b0; end else  if(current_adc_state == ADC_RESET) begin // if(rst_cntr < 4'd8) if(rst_cntr < 4'd15) begin AD_Rst <= 1'b1; rst_cntr <= rst_cntr + 4'd1; end else rst_cntr <= rst_cntr; end else begin rst_cntr <= 4'd0; AD_Rst <= 1'b0; end end always @ (posedge clk2 or negedge nRst)// adc_state begin if(!nRst) current_adc_state <= ADC_RESET; else begin case(current_adc_state) WAIT_CONST://0 begin if(rd_cntr == 4'd3) current_adc_state <= START_CONVST; else current_adc_state <= WAIT_CONST; end START_CONVST://1 begin if(cnvt_cntr <= (CNVT_WIDTH - 8'd1)) current_adc_state <= START_CONVST; else current_adc_state <= WAIT_BUSY; end WAIT_BUSY://2 begin if(busy_cntr < (BUSY_WIDTH - 16'd1)) current_adc_state <= WAIT_BUSY; else current_adc_state <= READ_DATA; end READ_DATA://3 begin if(cntr == 128) current_adc_state <= CONVST_FINISH; else current_adc_state <= READ_DATA; end CONVST_FINISH://4 begin if(convertoverflag) current_adc_state <= ADC_RESET; else current_adc_state <= CONVST_FINISH; end ADC_RESET://5 begin // if(rst_cntr == 4'd7) if(rst_cntr == 4'd14) current_adc_state <= WAIT_CONST; else current_adc_state <= ADC_RESET; end default: current_adc_state <= ADC_RESET; endcase end end always @ (posedge clk2 or negedge nRst)// AD_Convst begin if(!nRst) AD_Convst <= 1'b1; else begin if(current_adc_state == START_CONVST) AD_Convst <= 1'b0; else AD_Convst <= 1'b1; end end always @ (posedge clk2 or negedge nRst)// begin if(!nRst) begin Ch0SampleData[15:0] <= 16'd0; Ch1SampleData[15:0] <= 16'd0; Ch2SampleData[15:0] <= 16'd0; Ch3SampleData[15:0] <= 16'd0; Ch4SampleData[15:0] <= 16'd0; Ch5SampleData[15:0] <= 16'd0; Ch6SampleData[15:0] <= 16'd0; Ch7SampleData[15:0] <= 16'd0; convertoverflag<=0; AD_DB_info[127:0] <= 0; end else begin       case (current_adc_state)           WAIT_BUSY:  begin AD_DB_info[127:0] <= 0; end          READ_DATA:   begin convertoverflag<=0; if((sclk_cntr == RD_PULSE_WIDTH / 2 - 1) && cntr < 128 && AD_CS == 0) AD_DB_info[127:0] <= {AD_DB_info[126:0],AD_DB}; else AD_DB_info[127:0]<=AD_DB_info[127:0]; end CONVST_FINISH:  begin Ch0SampleData[15:0] <= AD_DB_info[127:112]; Ch1SampleData[15:0] <= AD_DB_info[111:96]; Ch2SampleData[15:0] <= AD_DB_info[95:80]; Ch3SampleData[15:0] <= AD_DB_info[79:64]; Ch4SampleData[15:0] <= AD_DB_info[63:48]; Ch5SampleData[15:0] <= AD_DB_info[47:32]; Ch6SampleData[15:0] <= AD_DB_info[31:16]; Ch7SampleData[15:0] <= AD_DB_info[15:0]; convertoverflag<=1; end          default:           AD_DB_info[127:0] <= 0; endcase    end end endmodule 
转载请注明原文地址: https://www.6miu.com/read-47568.html

最新回复(0)