当前位置:首页 > FPGA > 正文内容

AD4134 Verilog驱动

chanra1n7天前FPGA68
`timescale 1ns / 1ps

module ad4134 (
// Physical Interface
input  wire        ADC_DCLK_I,      // ADC Clock Input
input  wire        ADC_ODR_I,       // ADC Output Data Rate input
input  wire [ 3:0] ADC_DOUT_I,      // ADC Data Output
// User Interface
input  wire        sys_clk_200mhz,  // System Clock
input  wire        sys_rst_n,       // System Reset (active low)
output wire [23:0] adc_data0,       // Channel 0 Data Output
output wire [23:0] adc_data1,       // Channel 1 Data Output
output wire [23:0] adc_data2,       // Channel 2 Data Output
output wire [23:0] adc_data3,       // Channel 3 Data Output
output reg         adc_data_vld     // Data Valid Output 
);
// Internal Signals
reg [23:0] temp_data[3:0];  // Temporary storage for each channel data
reg [23:0]
adc_data0_reg1,
adc_data1_reg1,
adc_data2_reg1,
adc_data3_reg1;  // The purpose of the two-stage delay of the multi bit signal here is to synchronize with the effective signal, rather than weaken the metastable state
reg [23:0]
adc_data0_reg2,
adc_data1_reg2,
adc_data2_reg2,
adc_data3_reg2;  // The purpose of the two-stage delay of the multi bit signal here is to synchronize with the effective signal, rather than weaken the metastable state
assign adc_data0 = adc_data0_reg2;
assign adc_data1 = adc_data1_reg2;
assign adc_data2 = adc_data2_reg2;
assign adc_data3 = adc_data3_reg2;

wire adc_clk;  // Buffer for ADC Clock
wire adc_odr;  // Buffer for ADC ODR

// Buffering ADC Clock and ODR
BUFG BUFG_ADC_CLK (
.I(ADC_DCLK_I),
.O(adc_clk)
);

BUFG BUFG_ADC_ODR (
.I(ADC_ODR_I),
.O(adc_odr)
);

// Initialization and Reset Logic
always @(posedge adc_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
// Reset all registers to initial values
adc_data_vld <= 1'b0;
temp_data[0] <= 24'b0;
temp_data[1] <= 24'b0;
temp_data[2] <= 24'b0;
temp_data[3] <= 24'b0;
end else begin
// Shift in data on DCLK rising edge
temp_data[0] <= {temp_data[0][22:0], ADC_DOUT_I[0]};
temp_data[1] <= {temp_data[1][22:0], ADC_DOUT_I[1]};
temp_data[2] <= {temp_data[2][22:0], ADC_DOUT_I[2]};
temp_data[3] <= {temp_data[3][22:0], ADC_DOUT_I[3]};
end
end

// Two-stage synchronization for adc_odr signal
reg adc_odr_sync1;
reg adc_odr_sync2;

always @(posedge sys_clk_200mhz or negedge sys_rst_n) begin
if (!sys_rst_n) begin
adc_odr_sync1 <= 1'b0;
adc_odr_sync2 <= 1'b0;
end else begin
adc_odr_sync1 <= adc_odr;  // First stage synchronization
adc_odr_sync2 <= adc_odr_sync1;  // Second stage synchronization
end
end

// Output Logic on ODR Rising Edge
always @(posedge sys_clk_200mhz) begin
if (adc_odr_sync1 != adc_odr_sync2 && adc_odr_sync2 == 1'b0) begin
adc_data_vld <= 1'b1;  // Set data valid signal
end else begin
adc_data_vld <= 1'b0;
end
end

always @(posedge sys_clk_200mhz) begin // The purpose of the two-stage delay of the multi bit signal here is to synchronize with the effective signal, rather than weaken the metastable state
adc_data0_reg1 <= temp_data[0];
adc_data1_reg1 <= temp_data[1];
adc_data2_reg1 <= temp_data[2];
adc_data3_reg1 <= temp_data[3];
adc_data0_reg2 <= adc_data0_reg1;
adc_data1_reg2 <= adc_data1_reg1;
adc_data2_reg2 <= adc_data2_reg1;
adc_data3_reg2 <= adc_data3_reg1;
end

endmodule

output (1).png


image.png

仿真文件:

`timescale 1ns / 1ps

module tb_ad4134;

// Testbench Signals
  reg         ADC_DCLK_I;  // ADC Clock Input
  reg         ADC_ODR_I;  // ADC Output Data Rate Input
  reg  [ 3:0] ADC_DOUT_I;  // ADC Data Output
  reg         sys_clk_200mhz;  // System Clock
  reg         sys_rst_n;
  wire [23:0] adc_data0;  // Channel 0 Data Output
  wire [23:0] adc_data1;  // Channel 1 Data Output
  wire [23:0] adc_data2;  // Channel 2 Data Output
  wire [23:0] adc_data3;  // Channel 3 Data Output
  wire        adc_data_vld;  // Data Valid Output

// Instantiate the Device Under Test (DUT)
ad4134 dut (
.ADC_DCLK_I(ADC_DCLK_I),
.ADC_ODR_I(ADC_ODR_I),
.ADC_DOUT_I(ADC_DOUT_I),
.sys_clk_200mhz(sys_clk_200mhz),
.sys_rst_n(sys_rst_n),
.adc_data0(adc_data0),
.adc_data1(adc_data1),
.adc_data2(adc_data2),
.adc_data3(adc_data3),
.adc_data_vld(adc_data_vld)
);

// Clock Generation for System Clock (200 MHz)
initial begin
sys_clk_200mhz = 0;
forever #2.5 sys_clk_200mhz = ~sys_clk_200mhz;  // 200 MHz
end

initial begin
sys_rst_n = 1'b0;
#5;
sys_rst_n = 1'b1;
end

parameter DCLK_PERIOD = 10.416666666667; // 1000/48/2,half period
// DCLK Generation and Data Simulation
initial begin
// Initialize signals
ADC_DCLK_I = 0;
ADC_ODR_I  = 0;
ADC_DOUT_I = 4'b0;

// Simulation process
#5;
    repeat (1000000) generate_data;
end

task generate_data;  // Master Mode
    integer i;
    reg [23:0] expected_data[0:3];  // To store expected data

// Generate expected data
expected_data[0] = $urandom_range(0, 24'hFFFFFF);
expected_data[1] = $urandom_range(0, 24'hFFFFFF);
expected_data[2] = $urandom_range(0, 24'hFFFFFF);
expected_data[3] = $urandom_range(0, 24'hFFFFFF);

ADC_ODR_I = 1;
    repeat (6) #DCLK_PERIOD;  // t1 ODR high time 
ADC_ODR_I = 0;
    repeat (2) #DCLK_PERIOD;  // t3 ODR falling edge to DCLK rising edge

for (i = 23; i >= 0; i = i - 1) begin
ADC_DCLK_I = 1;
ADC_DOUT_I[0] = expected_data[0][i];
ADC_DOUT_I[1] = expected_data[1][i];
ADC_DOUT_I[2] = expected_data[2][i];
ADC_DOUT_I[3] = expected_data[3][i];
#DCLK_PERIOD;
ADC_DCLK_I = 0;
#DCLK_PERIOD;
end

    repeat (4) #DCLK_PERIOD;  // t4 Last data DCLK falling edge to ODR rising edge
// Check for mismatches and throw exceptions
if (adc_data0 !== expected_data[0]) begin
$display("Mismatch on Channel 0: Expected %h, Got %h", expected_data[0], adc_data0);
$fatal("Error: Mismatch on Channel 0!");
end
if (adc_data1 !== expected_data[1]) begin
$display("Mismatch on Channel 1: Expected %h, Got %h", expected_data[1], adc_data1);
$fatal("Error: Mismatch on Channel 1!");
end
if (adc_data2 !== expected_data[2]) begin
$display("Mismatch on Channel 2: Expected %h, Got %h", expected_data[2], adc_data2);
$fatal("Error: Mismatch on Channel 2!");
end
if (adc_data3 !== expected_data[3]) begin
$display("Mismatch on Channel 3: Expected %h, Got %h", expected_data[3], adc_data3);
$fatal("Error: Mismatch on Channel 3!");
end
endtask

endmodule


扫描二维码推送至手机访问。

版权声明:本文由我的FPGA发布,如需转载请注明出处。

本文链接:https://world.myfpga.cn/index.php/post/431.html

分享给朋友:

“AD4134 Verilog驱动” 的相关文章

ALGO C4MB V11引脚参照表(持续更新)

ALGO C4MB V11引脚参照表(持续更新)

功能:常用引脚CLKPIN_E1LED0PIN_G15LED1PIN_F16LED2PIN_F15LED3PIN_D16KEY1PIN_E15KEY2PIN_E16KEY3PIN_M15KEY4PIN_M16RXDPIN_M2TXDPIN_G1功能:VGA引脚VGA_BLUE[0]PIN_C15VG...

Verilog实现时钟分频(奇数分频,偶数分频)二分频 三分频 四分频 五分频

Verilog实现时钟分频(奇数分频,偶数分频)二分频 三分频 四分频 五分频

完整工程文件:clkdiv.zip//------------------------------------------------------// File Name        : clkdiv.v// Author     &nb...

半加器

半加器

半加器:两个输入数据位相加,输出一个结果位和进位,没有进位输入的加法器电路。即两个一位二进制数的加法运算电路。半加器 模块框图:sum:结果位count:进位半加器 真值表:半加器 波形图:代码部分:选择器代码:在Src文件夹中新建 half_adder.v文件module half_adder...

FPGA时序分析和时序约束

FPGA时序分析和时序约束

时序分析:时序分析的目的就是通过分析FPGA设计中各个寄存器之间的数据和时钟传输路径,来分析数据延迟和时钟延迟之间的关系。一个设计OK的系统,必然能够保证整个系统中所有的寄存器都能够正确的寄存数据。数据和时钟传输路径是由EDA软件,通过针对特定器件布局布线得到的。时序约束:两个作用告知 EDA 软件...

时序约束(TCL脚本)

时序约束(TCL脚本)

get_ports的使用方法如下:# 获取所有端口 get_ports *   # 获取名称中包含data的端口 get_ports *data*   # 获取所有输出端口 get_ports -filter {DIRECTION == OUT}   # 获取所有输入端口 all...

CDC跨时钟域信号处理

CDC跨时钟域信号处理

保证时序电路的时序要求:建立时间:在有效的时钟沿到来之前,输入端的输入信号需要保持稳定不变的最小时间保持时间:在有效的时钟沿到来之后,输入端的输入信号需要保持稳定不变的最小时间CDC问题1:亚稳态亚稳态原因:亚稳态解决方法:对于单信号来说,使用 Double FF来进行信号同步CDC问题2:数据收敛...