FPGA控制AD5754R DAC芯片

分享一个自己写的AD5754R DAC驱动。

芯片时序图:
在这里插入图片描述

上板调试图:
在这里插入图片描述
核心代码:

`timescale 1 ns / 1 ns
//
// Company: 
// Engineer: felixgao
// 
// Create Date: 
// Design Name: 
// Module Name: ad5754r_ctrl
// Project Name: 
// Target Devices: 
// Tool Versions:  
// Description:  
// 
// Dependencies: 
// 
// Revision:
//  date       version		  author		
//           
//				//module ad5754r_ctrl (input            i_clk                         ,  // 输入50MHZ 时钟input            i_rstn                        ,input            i_mmda_conv_flag              ,input            i_mmda_ch_valid               ,input            i_mmda_data_valid             ,input   [31:0]   i_reg0x4c_mmda_data           ,  // 33MHZinput   [31:0]   i_reg0x50_mmda_ch             ,     output           o_ad5754r_sync                ,output           o_ad5754r_ldac                ,    output           o_ad5754r_sclk                ,output           o_ad5754r_sdin                ,input            i_ad5754r_sdo                );parameter   P_DIV             = 10               , // 10 分频  ---> 5MHZ // 50MHZP_DIV_CNT_MAX     = (P_DIV >> 1) - 1 , // 计数器最大值P_DIV_CNT_WIDTH   = 3                , P_CLK_CNT_WIDTH   = 5                ,P_TRANS_BIT_WIDTH = 24               ;wire                           w_run_fall                      ;
wire                           w_end_flag                      ;reg                            ro_ad5754r_sync                 ; 
reg                            ro_ad5754r_ldac                 ; 
reg                            ro_ad5754r_sclk                 ; 
reg                            ro_ad5754r_sdin                 ; 
reg                            r_run                           ;
reg                            r_run_1d                        ;
reg [P_DIV_CNT_WIDTH - 1:0]    r_div_cnt                       ;
reg [23:0]                     r_data                          ;
reg [P_CLK_CNT_WIDTH - 1:0]    r_clk_cnt                       ;
reg [4:0]                      r_ld_cnt                        ;
reg [1:0]                      r_ld_delay_cnt                  ;
reg                            r_clk_flag                      ;
reg                            ri_mmda_data_valid              ;
reg                            ri_mmda_data_valid_1d           ;
reg                            ri_mmda_data_valid_2d           ;// reg ri_mmda_conv_flag      ;
// reg ri_mmda_conv_flag_1d   ;assign w_run_fall      = !r_run && r_run_1d  ;
assign w_end_flag      = (r_clk_cnt == P_TRANS_BIT_WIDTH) && (r_div_cnt == P_DIV_CNT_MAX ) && (!r_clk_flag);assign o_ad5754r_sync  = ro_ad5754r_sync     ; 
assign o_ad5754r_ldac  = ro_ad5754r_ldac     ; 
assign o_ad5754r_sclk  = ro_ad5754r_sclk     ; 
assign o_ad5754r_sdin  = ro_ad5754r_sdin     ; always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn) beginr_run_1d              <= 0;// ri_mmda_conv_flag     <= 0;// ri_mmda_conv_flag_1d  <= 0;ri_mmda_data_valid    <= 0;ri_mmda_data_valid_1d <= 0;ri_mmda_data_valid_2d <= 0;end else begin r_run_1d              <= r_run;// ri_mmda_conv_flag     <= i_mmda_conv_flag;// ri_mmda_conv_flag_1d  <= ri_mmda_conv_flag;ri_mmda_data_valid    <= i_mmda_data_valid;ri_mmda_data_valid_1d <= ri_mmda_data_valid;ri_mmda_data_valid_2d <= ri_mmda_data_valid_1d ;end
end//运行标志
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)r_run <= 0;else if (w_end_flag)r_run <= 0;else if (!ro_ad5754r_sync)r_run <= 1;elser_run <= r_run;
end// 分频计数器
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)r_div_cnt <= 0;else if (w_end_flag)r_div_cnt <= 0;else if (r_div_cnt == P_DIV_CNT_MAX)r_div_cnt <= 0;else if (r_run)r_div_cnt <= r_div_cnt + 1;elser_div_cnt <= r_div_cnt;
end//同步信号sync
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)ro_ad5754r_sync <= 1;else if (w_end_flag)ro_ad5754r_sync <= 1;else if (ri_mmda_data_valid_1d)ro_ad5754r_sync <= 0;elsero_ad5754r_sync <= ro_ad5754r_sync;
end//SCLK
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)ro_ad5754r_sclk <= 1;else if (r_div_cnt == P_DIV_CNT_MAX)ro_ad5754r_sclk <= ~ro_ad5754r_sclk;elsero_ad5754r_sclk <= ro_ad5754r_sclk;
end//辅助信号
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)r_clk_flag <= 1;else if (r_div_cnt == P_DIV_CNT_MAX)r_clk_flag <= ~r_clk_flag;elser_clk_flag <= r_clk_flag;
end//时钟计数
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)r_clk_cnt <= 0;else if (w_end_flag)r_clk_cnt <= 0;    else if (r_div_cnt == P_DIV_CNT_MAX && r_clk_flag)r_clk_cnt <= r_clk_cnt + 1;elser_clk_cnt <= r_clk_cnt;
end//传输的数据
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)r_data <= 0;else if (ri_mmda_data_valid_1d)r_data <= i_reg0x4c_mmda_data[23:0];    else if (!r_clk_flag && r_div_cnt == 2)r_data <= r_data << 1;elser_data <= r_data;
end//串行输出的信号 23bit,MSB --> LSB
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)ro_ad5754r_sdin <= 0;else if (ri_mmda_data_valid_2d)ro_ad5754r_sdin <= r_data[23];    else if (!r_clk_flag && r_div_cnt == P_DIV_CNT_MAX)ro_ad5754r_sdin <= r_data[23];elsero_ad5754r_sdin <= ro_ad5754r_sdin;
end//sync 拉高后需要至少130ns时间延时 拉低LDAC,这里延时超过130ns
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)r_ld_cnt <= 0;else if (r_ld_cnt == 20)r_ld_cnt <= 0;else if (w_run_fall || r_ld_cnt)r_ld_cnt <= r_ld_cnt + 1;elser_ld_cnt <= r_ld_cnt;    
endalways @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)r_ld_delay_cnt <= 0;else if (r_ld_cnt == 20 || r_ld_delay_cnt)r_ld_delay_cnt <= r_ld_delay_cnt + 1;elser_ld_delay_cnt <= r_ld_delay_cnt;    
end//LDAC 持续60ns
always @ (posedge i_clk or negedge i_rstn)
beginif (!i_rstn)ro_ad5754r_ldac <= 1;else if (r_ld_delay_cnt == 3)ro_ad5754r_ldac <= 1;   else if (r_ld_cnt == 20)ro_ad5754r_ldac <= 0;elsero_ad5754r_ldac <= ro_ad5754r_ldac;    
endendmodule