基于 Vivado 的 AD9680 FPGA 测试程序开发
在 FPGA 开发中,与高速 ADC 芯片如 AD9680 协同工作是一项挑战。本文探讨基于 Vivado 平台,针对 AD9680 实现 1G 采样率且 4 通道(Lane 4)的测试程序,使用 Verilog/SystemVerilog 完成配置、时钟及 JESD204B 接收逻辑。
配置 AD9680
AD9680 拥有一系列寄存器需要设置,以确保其按预期模式工作。下面是一个基础配置模块示例:
module ad9680_config (
input wire clk,
input wire rst,
output reg [15:0] ad9680_reg_data,
output reg ad9680_reg_wr
);
always @(posedge clk or posedge rst) begin
if (rst) begin
ad9680_reg_data <= 16'h0000;
ad9680_reg_wr <= 1'b0;
end else begin
// 写入寄存器配置值
ad9680_reg_data <= 16'h1234; // 示例值,需根据手册调整
ad9680_reg_wr <= 1'b1;
end
end
endmodule
该模块负责生成对 AD9680 寄存器的写操作。clk 是时钟信号,rst 用于复位。当复位有效时,寄存器数据和写信号清零。正常工作时,向 ad9680_reg_data 写入特定配置值并拉高 ad9680_reg_wr 完成写入。注意 16'h1234 仅为示例,实际应用中需依据手册设置正确的寄存器值,如采样模式、增益等参数。
配置时钟
稳定的时钟对于 AD9680 准确采样至关重要。在 FPGA 中,通常使用 PLL(锁相环)生成所需时钟信号。以下是一个基于 Xilinx FPGA 原语的 PLL 示例:
`timescale 1ns / 1ps
module clk_gen (
input wire clk_in,
output wire clk_out
);
(* DONT_TOUCH = "yes" *)
(* USE_POWER_PIN = "yes" *)
(* XILINX_LEGACY_PRIM = "PLL_BASE" *)
PLLE2_BASE #(
.BANDWIDTH("OPTIMIZED"),
.CLKFBOUT_MULT(10),
.CLKFBOUT_PHASE(0.0),
.CLKIN1_PERIOD(10.0),
.CLKOUT0_DIVIDE(10),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0.0),
.DIVCLK_DIVIDE(1)
) u_PLL (
.CLKFBIN(clk_fb),
.CLKIN1(clk_in),
.RST(1'b0),
.PWRDWN(1'b0),
.CLKOUT0(clk_out),
.CLKFBTOUT(clk_fb),
.LOCKED(locked)
);
endmodule
这段代码通过 PLLE2_BASE 原语实现 PLL。clk_in 是输入时钟,通过设置 CLKFBOUT_MULT 和 CLKOUT0_DIVIDE 等参数调整输出频率。假设输入时钟周期为 10ns,经过配置后输出频率将随之改变。实际应用中,需根据 AD9680 的 1G 采样率需求灵活调整参数,以获得合适的采样时钟。
JESD204B 接收
JESD204B 是 AD9680 常用的数据传输协议,实现其接收功能是测试程序的关键。下面是一个简化的接收模块框架:
module jesd204b_rx (
input wire clk,
input wire rst,
input wire [31:0] data_in,
output reg [31:0] data_out
);
typedef enum reg [2:0] {
IDLE,
SYNC,
RECEIVE
} jesd_state;
jesd_state current_state, next_state;
always @(posedge clk or posedge rst) begin
if (rst) begin
current_state <= IDLE;
data_out <= 32'h00000000;
end else begin
current_state <= next_state;
end
end
always @(*) begin
next_state = current_state;
case (current_state)
IDLE: begin
// 检测同步信号
if (data_in == 32'hABCD1234) begin
next_state = SYNC;
end
end
SYNC: begin
// 同步后准备接收数据
next_state = RECEIVE;
end
RECEIVE: begin
data_out = data_in;
// 此处可添加解串等数据处理逻辑
end
endcase
end
endmodule


