|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 christeas 于 2019-7-1 11:05 编辑
先说一下背景,FPGA是Xilinx Kintex UltraScale KU040,我这边要用到ADS42LB69这个AD器件,想使用的采样率为200MHz,但是由于管脚又受到限制,因此只能用QDR模式来做,这里可以看到QDR模式的时序,其中是用4根线传16bit的数据,每根线要传4bit,所以AD过来的数据是800MHz,需要缓存并拼成200MHz的数据送出去。
我把AD调成发送的数据从0-65535递增以方便定位,正确的通道波形如下,是个递增的斜线。
但是有些通道的波形很奇怪,用vivado看到出来的波形如下,这个通道很乱。
还有一些通道看着是有一定规律的,比如这个。
这个通道的数,7-4bit一直是和15-12bit一样,其他的bit还比较正常。
另外还有其他通道偶尔冒一个毛刺,说明可能某bit产生跳变。
我把我采数的代码贴上来,大家帮我看看是不是我代码写的有问题,不适合高速处理;还是说时序有问题?如果时序有问题,我应该怎么处理?这方面经验比较少,各位大神帮帮忙。
其中ad_clk对应DxCLK,ad_frm对应DxFRAME,输入CLKIN为200MHz,直接连到AD,上面使用vivado抓的数是data_adclk
module ad42lb69qdr_data_reg(
input clk_4x,//800M
input clk_1x,//200M
input ad_clk,//400M DCLK
input ad_frm,//200M FRM
input [3:0] ad_data_in,
output reg [15:0] ad_data_out
);
// register declaration
// reg channel a
reg ad_clk_reg0;
reg ad_clk_reg1;
reg ad_frm_reg0;
reg ad_frm_reg1;
reg [3:0] ad_data_reg0=4'b0000;
reg [3:0] ad_data_reg1=4'b0000;
reg ad_data_en_clk4x=1'b0;
reg signed [15:0] data_adclk=15'd0;
reg [3:0] tmp_ad_data_out1=4'd0;
reg [3:0] tmp_ad_data_out2=4'd0;
reg [3:0] tmp_ad_data_out3=4'd0;
reg [3:0] tmp_ad_data_out4=4'd0;
reg tmp_ad_data_en =1'd0;
reg tmp_ad_data_en_reg =1'd0;
reg ad_rd_en=1'b0;
reg [3:0] ad_rd_cnt=4'd0;
wire [15:0] ad_data_fifoout;
always@(posedge ad_clk)
begin
if(ad_frm)
begin
tmp_ad_data_out4[3:0] <= ad_data_in[3:0];
data_adclk <= {tmp_ad_data_out4[3:0],
tmp_ad_data_out3[3:0],
tmp_ad_data_out2[3:0],
tmp_ad_data_out1[3:0]};
end
else
begin
tmp_ad_data_out2[3:0] <= ad_data_in[3:0];
end
end
always@(negedge ad_clk)
begin
if(ad_frm)
begin
tmp_ad_data_out3[3:0] <= ad_data_in[3:0];
tmp_ad_data_en <= 1'b0;
end
else
begin
tmp_ad_data_out1[3:0] <= ad_data_in[3:0];
tmp_ad_data_en <= 1'b1;
end
end
always@(posedge clk_4x)
begin
if(ad_rd_cnt==4'd3)
begin
ad_rd_cnt <= 4'd0;
ad_rd_en <= 1'b1;
end
else
begin
ad_rd_cnt <= ad_rd_cnt + 4'd1;
ad_rd_en <= 1'b0;
end
ad_data_out <= ad_data_fifoout;
end
// fifo缓存到另一个时钟域送出
fifo_generator_0 fifo_ad(
.srst(1'b0),
.wr_clk(ad_clk),
.rd_clk(clk_4x),
.din(data_adclk),
.wr_en(tmp_ad_data_en),
.rd_en(ad_rd_en),
.dout(ad_data_fifoout),
.full(),
.empty(),
.wr_rst_busy(),
.rd_rst_busy()
);
endmodule
上面是采数模块的代码,然后我在外面是通过把差分信号合并成单路后直接连到这个模块的,外面是用原语将差分转的单端:
IBUFDS cha_1 (.I (cha_frm_p), .IB (cha_frm_n), .O (cha_frm));
IBUFDS cha_2 (.I (cha_data0_p), .IB (cha_data0_n), .O (cha_data[0]));
IBUFDS cha_3 (.I (cha_data1_p), .IB (cha_data1_n), .O (cha_data[1]));
IBUFDS cha_4 (.I (cha_data2_p), .IB (cha_data2_n), .O (cha_data[2]));
IBUFDS cha_5 (.I (cha_data3_p), .IB (cha_data3_n), .O (cha_data[3]));
这几个信号的IOSTANDARD全部设置的LVDS
|
|