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

AD4134 Verilog驱动

chanra1n2个月前 (10-31)FPGA429
`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://myfpga.cn/index.php/post/431.html

分享给朋友:

“AD4134 Verilog驱动” 的相关文章

FPGA ALARM FPGA多功能闹钟 完整项目 内含上位机

FPGA ALARM FPGA多功能闹钟 完整项目 内含上位机

一、项目简述本项目使用苏州硬禾信息科技有限公司设计的小脚丫FPGA开发板设计了一个完成定时、测温、报警、控制的小项目,并通过上位机显示、下发音乐配置数据。本项目B站介绍:https://www.bilibili.com/video/BV1Vh411k7QV/二、研究进展(一)研究内容:l ...

SOC 在线修改设备树和FPGA配置文件 并在线配置FPGA

SOC 在线修改设备树和FPGA配置文件 并在线配置FPGA

测试过的平台:     1、DE-10 Cyclone V开发板              ...

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

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

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

Xilinx FIFO和ILA学习

Xilinx FIFO和ILA学习

`timescale 1ns / 1ps//-------------------------------------------------------//Filename       ﹕ FIFO_TOP.v//Author      ...

CDC 单脉冲信号处理

CDC 单脉冲信号处理

代码中的Sys_clk其实是没有用到的,项目文件:cdc_single.zip//------------------------------------------------------// File Name        : cdc.v// Autho...