AD5545_DAC 驱动,仿真上板验证都很满意

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date: 2025/08/29 11:35:42

// Design Name:

// Module Name: AD5545_DAC

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

// AD5545_DAC IOUTA IOUTB 输出2路电流

//////////////////////////////////////////////////////////////////////////////////
代码借鉴以下这位大佬

//https://blog.youkuaiyun.com/xiakunpei123/article/details/143864515

数模转换AD5545芯片驱动程序设计Verilog代码VIVADO仿真

module AD5545_DAC(

    input  wire        clk_200m,

    input  wire        rst_n,

    input  wire        data_en,

    input  wire [15:0] data_A,

    input  wire [15:0] data_B,

    output reg         DA_SDI,

    output reg         DA_CLK,

    output reg         DA_CS_n,

    output reg         DA_LDAC_n,

    output reg         DA_RS_n,

    output reg         send_done

);

reg         flag_AB  =       0;

reg  [1:0]  A1A0     =    2'd0;//01--A;10--B

reg [15:0]  data_DA  =   16'd0;//DA数据

reg  [7:0]  count;

reg [17:0]  data_all;

reg         data_en_r0;

reg         data_en_r1;

wire        data_en_pos;

reg         clear_flag;


 

assign data_en_pos = data_en_r0 & (~data_en_r1);

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)begin    

        data_en_r0   <= 1'd0;

        data_en_r1   <= 1'd0;        

    end

    else begin

        data_en_r0   <= data_en;

        data_en_r1   <= data_en_r0;  

    end

end

//作用是:防止data_en 信号来的时候,

//还没开始发data_A,data_B,

//就开始send_done == 1'b1 了

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)begin    

        clear_flag   <= 1'd0;

    end

    else if(count == 8'd199)begin

        clear_flag   <= 1'd0;        

    end

    else if(data_en_pos == 1'b1)begin

        clear_flag   <= 1'd1;

    end

end

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)begin    

        DA_RS_n   <= 1'd0;

    end

    else begin

        DA_RS_n   <= 1'd1;

    end

end

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)

        count   <= 8'd0;        

    else if(count == 8'd199)  

        count   <= 8'd0;  

    else if(count < 8'd199)     //flag_AB==0时输出A数据,=1时输出B数据

        count   <= count + 1'b1;

end

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)

        send_done   <= 1'd0;

    else if(clear_flag == 1'b1)

        send_done   <= 1'd0;                  

    else if(count >= 8'd189 && count <= 8'd195)//Synchronized to a 40M, 25ns/5ns = 5,10 >(195 -189) >5

        send_done   <= 1'd1;          

    else

        send_done   <= 1'd0;  

end

//count=   0~5   --- cs=1 ldac=1;

//count=   6~150 --- cs=0 ldac=1;

//count= 160~200 --- cs=1 ldac=0;

//控制DA_CS_n

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)

        DA_CS_n <= 1;

    else if(count < 8'd6)

        DA_CS_n <= 1;

    else if(count >= 8'd6  && count < 8'd160)

        DA_CS_n <= 0;        

    else

        DA_CS_n <= 1;

end

//控制DA_LDAC_n

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)

        DA_LDAC_n <= 1;

    else if(count < 8'd160)

        DA_LDAC_n <= 1;

    else

        DA_LDAC_n <= 0;

end

//可以按照频率来改,不一定要按照count == 8'd199

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)begin

        flag_AB <= 1'd0;        

    end

    else if(count == 8'd199)begin

        flag_AB <= ~flag_AB;  //flag_AB==0时输出A数据,=1时输出B数据

    end

end

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)begin

        A1A0    <= 2'b10;      //01--DACA;10--DACB

        data_DA <= data_A;        

    end

    else if(flag_AB == 0)begin //flag_AB==0时输出A数据,=1时输出B数据

        A1A0    <= 2'b10;      //01--DACA;10--DACB

        data_DA <= data_A;

    end

    else begin

        A1A0    <=  2'b01;     //01--DACA;10--DACB;

        data_DA <= data_B;

    end

end



 

always@(posedge clk_200m  or negedge rst_n)begin

    if(~rst_n)

        data_all <= 18'd0;    

    else

        data_all <= {A1A0,data_DA};

end

//控制DA_CLK 50mhz

//数据速率为1M,AB分别0.5M,500khz,电子负载最多50khz ,要记得转换

always@(posedge clk_200m or negedge rst_n)begin

    if(~rst_n)begin

        DA_SDI <= data_all[17];

        DA_CLK <= 0;      

    end

    else begin

    case(count)

        8'd0:  begin DA_CLK <= 0;    end

        8'd10: begin DA_CLK <= 0;    DA_SDI <= data_all[17]; end//第1个时钟

        8'd14: begin DA_CLK <= 1;    end

        8'd18: begin DA_CLK <= 0;    DA_SDI <= data_all[16]; end//第2个时钟

        8'd22: begin DA_CLK <= 1;    end

        8'd26: begin DA_CLK <= 0;    DA_SDI <= data_all[15]; end//第3个时钟

        8'd30: begin DA_CLK <= 1;    end

        8'd34: begin DA_CLK <= 0;    DA_SDI <= data_all[14]; end//第4个时钟

        8'd38: begin DA_CLK <= 1;    end

        8'd42: begin DA_CLK <= 0;    DA_SDI <= data_all[13]; end//第5个时钟

        8'd46: begin DA_CLK <= 1;    end

        8'd50: begin DA_CLK <= 0;    DA_SDI <= data_all[12]; end//第6个时钟

        8'd54: begin DA_CLK <= 1;    end

        8'd58: begin DA_CLK <= 0;    DA_SDI <= data_all[11]; end//第7个时钟

        8'd62: begin DA_CLK <= 1;    end

        8'd66: begin DA_CLK <= 0;    DA_SDI <= data_all[10]; end//第8个时钟

        8'd70: begin DA_CLK <= 1;    end

        8'd74: begin DA_CLK <= 0;    DA_SDI <= data_all[9];  end//第9个时钟

        8'd78: begin DA_CLK <= 1;    end

        8'd82: begin DA_CLK <= 0;    DA_SDI <= data_all[8];  end//第10个时钟

        8'd86: begin DA_CLK <= 1;    end

        8'd90: begin DA_CLK <= 0;    DA_SDI <= data_all[7];  end//第11个时钟

        8'd94: begin DA_CLK <= 1;    end

        8'd98: begin DA_CLK <= 0;    DA_SDI <= data_all[6];  end//第12个时钟

        8'd102:begin DA_CLK <= 1;    end

        8'd106:begin DA_CLK <= 0;    DA_SDI <= data_all[5];  end//第13个时钟

        8'd110:begin DA_CLK <= 1;    end

        8'd114:begin DA_CLK <= 0;    DA_SDI <= data_all[4];  end//第14个时钟

        8'd118:begin DA_CLK <= 1;    end

        8'd122:begin DA_CLK <= 0;    DA_SDI <= data_all[3];  end//第15个时钟

        8'd126:begin DA_CLK <= 1;    end

        8'd130:begin DA_CLK <= 0;    DA_SDI <= data_all[2];  end//第16个时钟

        8'd134:begin DA_CLK <= 1;    end

        8'd138:begin DA_CLK <= 0;    DA_SDI <= data_all[1];  end//第17个时钟

        8'd142:begin DA_CLK <= 1;    end

        8'd146:begin DA_CLK <= 0;    DA_SDI <= data_all[0];  end//第18个时钟

        8'd150:begin DA_CLK <= 1;    end

        8'd154:begin DA_CLK <= 0;    end        

        default:;

    endcase

    end

end

endmodule
上板测试过,结果很满意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值