Tengo un ADC (ADS1672 hoja de datos ) (20MHz) con interfaz serial y xilinx spartan 3 XC3S400-208 (50MHz)
en su hoja de datos para la recuperación de datos viene esto:
para eso implementé este código:
entradas y salidas:
input wire DRDY;
input DOUT;
input OTRD;
input wire SCLK;
output CS_ADS;
output reg START;
output [1:0]DRATE;
output FPATH;
output LL_CONFIG;
output LVDS;
output SCLK_SEL;
output PDWN;
reg DRDY1=0,DRDY0=0;
reg [4:0] ADS_bit=0;
reg [23:0] ADS_buff=24'b0000_0000_0000_0000_0000_0000;
reg [23:0] ADS_buff_last=24'b0000_0000_0000_0000_0000_0000;
reg onetime =1'b1;
parámetros:
parameter PWRDWN=1'b0, PWRUP=1'b1 , FPATH_LowLatency=1'b1 , FPATH_WideBand=1'b0 , LL_CONFIG_SingleCycle=1'b0 , LL_CONFIG_FastResponse=1'b1;
parameter DRATE_00=2'b00 ,DRATE_01=2'b01 , DRATE_10=2'b10 , DRATE_11=2'b11, SCLK_SEL_Internal=1'b0 , SCLK_SEL_External=1'b1 , LVDS_LVDS=1'b0 ,LVDS_CMOS=1'b1;
Configuración:
assign DRATE = DRATE_00;
assign FPATH = FPATH_LowLatency;
assign LL_CONFIG = LL_CONFIG_SingleCycle;
assign LVDS = CMOS;
assign SCLK_SEL = SCLK_SEL_Internal;
assign PDWN = PWRUP;
assign CS_ADS = 1'b0;
assign START = 1'b1;
Segmento de recuperación de datos:
always @(posedge SCLK)
begin
START<=1'b1; //hold start hi
DRDY1 <= DRDY;
DRDY0 <= DRDY1;
if((DRDY1==1) && (DRDY0==0)) //rising edge of DRDY to start retrieval
begin
ADS_buff[23]<=DOUT; //First bit is comes with posedge DRDY
ADS_bit<=5'd23; //bit index Counter
onetime<=1'b0;
end
else if(ADS_bit==5'b00000 && onetime==1'b0)
begin
ADS_buff_last<=ADS_buff[23:0]; //Update last final buffer value
ADS_buff<=24'b0; //flush buffer
onetime<=1'b1; // to prevent run this again
end
if(ADS_bit!=5'b00000)
begin
ADS_buff[ADS_bit-1]<=DOUT; //get data
ADS_bit<=ADS_bit-1'b1; //count down (MSB to LSB)
end
end
cuando establezco SCLK internamente (i significa SCLK_SEL = 0, hago que ads1672 lo genere), nunca obtengo el valor correcto (los valores no son cero)
pero cuando lo configuro externamente (y genero SCLK desde FPGA) por la misma recuperación de datos, ¡algunas veces obtengo el valor correcto y otras veces cero!
la diferencia justa es la frecuencia, cuando es externamente es 12.5 MHz. y cuando es internamente es 19.9 MHz.
SCLK Generator (para cuando está externamente):
always @(posedge main_clk)
begin
SCLK_cnt <= SCLK_cnt + 8'd1;
if(SCLK_cnt>=(8'd4-1)) //divide per 4(50MHz/4=12.5MHz)
SCLK_cnt <= 8'd0;
end
assign SCLK = (SCLK_cnt<8'4/2)?1'b0:1'b1;
¿alguien tiene idea de por qué sucede esto?