AnsweredAssumed Answered

AD7476 Interfacing Code in Verilog

Question asked by SuvanB on Apr 8, 2015
Latest reply on Apr 20, 2015 by jcolao

Hi,

    I am trying to use a PMOD AD1 from digilent, which has 2 AD7476s. I am using it with a Zedboard and need some kind of basic reference code for interfacing the ADC. I have posted my code below. I can see it converting the data, on the DataA pin digital (sequence of 1s and 0s). However, its not able to use the data to make a decision on the PWM signal of a buck converter. (module pwm, posted below the ADC7476 module).

 

module ADC7476_Int(clk,Sclk,CSb,DinA,DinB,DataA,DataB);

input clk;

output Sclk;

output reg CSb;

input DinA,DinB;

output reg signed[11:0] DataA,DataB;

reg [11:0] SDataA, SDataB; //Shift registers for serial read

reg [8:0] c=0;

reg flag=0;

always @(posedge clk)

begin

   if (c>=264)  // c counts 2.6uS, 379 kSpS. Each c increment is 20 nS.

   c <= 0;

     else

    c<=c+1;

  end

  assign Sclk = c[3]; //There are 66 Sclk cycles in one data acquisition. (fSclk = 6.25 MHz, since highest allowed is 12 MHz)

  always @(posedge clk)

  begin

       case(c)

     0 : begin  // tQUIET-t1 = 20 nS

     CSb <= 0;

     flag <= 0;

    end

      2 : begin //t1 = 40 nS

            CSb <= 1;

            flag <= 0;

           end

        6 : begin //4 preceding zeros = 640ns

            CSb <= 0;

            flag <= 0;

  end

      70 : begin // tCONVERT : DB11-DB0 -> 1920ns + t8 (20 ns) = 1940 ns

         CSb <= 0;

         flag <= 1;

         end 

   264 : begin

      CSb <= 0;

      flag <= 0;

  DataA <= SDataA;// actual data in SDataA - 4 preceding zeros

  DataB <= SDataB;

  end

        default: begin

       CSb <= CSb;

       flag <= flag;

   end

    endcase

   end

   always @(negedge Sclk)

  begin

     SDataA <= {SDataA[10:0],(flag & DinA)};// Serial read and shift, only when flag is high.

  SDataB <= {SDataB[10:0],(flag & DinB)};

  end

  endmodule

 

module pwm (clk_pin,clk_s,Su,Sl,Si,CSb,Sclk,DinA,DinB);

input clk_pin;

input DinA,DinB;

output reg clk_s, Si;

output Su,Sl;

output CSb,Sclk;

wire signed [11:0] DataA, DataB;

reg wu,wl;

 

dead_time inst1(.wu(wu),.wl(wl),.clk(clk_pin),.reset(1),.Su(Su),.Sl(Sl));

ADC7476_Int inst2(.clk(clk_pin),.Sclk(Sclk),.CSb(CSb),.DinA(DinA),.DinB(DinB),.DataA(DataA),.DataB(DataB));

 

 

reg [14:0] count = 0;

integer count_max=1000, duty=900;

 

always @(posedge CSb) //Control Code

begin

if (DataA<=2048)

duty = 700;

else

duty = 500;

end

 

 

always @(posedge clk_pin)

begin

if (count>=0 && count<=duty)

begin

clk_s <= 0;

count <=count +1;

end

 

 

else if (count>duty && count < count_max)

begin

clk_s <= 1;

count <= count + 1;

end

 

else

begin

clk_s <= clk_s;

count <= 0;

end

end  

 

always @(posedge clk_pin)

begin

wu<=clk_s;

wl<=~clk_s;

end            

endmodule

Outcomes