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

AD4134 Verilog驱动

chanra1n5个月前 (10-31)FPGA1051
`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驱动” 的相关文章

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

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

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

基础实验十三,DS18B20温度传感器

基础实验十三,DS18B20温度传感器

//==========================================================================// Author     : ChanRa1n// Description: Training for Intel FPGA/...

Verilog实现串并转换

Verilog实现串并转换

项目文件:SIPO.zip//------------------------------------------------------// File Name        : SIPO.v// Author       &n...

多路选择器

多路选择器

多路选择器:在多路数据传送过程中,能够根据需要将其中任意一路选出来的电路。二选一多路选择器 --- 模块框图in_1:输入信号in_2:输入信号sel:控制选择信号out:输出信号二选一多路选择器 --- 波形图in_1、in_2、sel 的波形是随机的。out 的波形根据控制选通信号而定。当 se...

3-8译码器

3-8译码器

译码:译码是编码的逆过程,在编码时,每一种二进制的代码,都赋予了特殊的含义,即都表示了一个确定的信号或者对象。把代码状态的特定含义翻译出来的过程叫做译码,实现译码操作的电路称为译码器。译码器:一类多输入多输出的组合逻辑电路器件,其可以分为:变量译码和显示译码两类3-8译码器 模块框图:输出信号定义为...