我是靠谱客的博主 曾经水池,这篇文章主要介绍FPGA实现DAC驱动设计(以TLV5618为例),现在分享给大家,希望可以做个参考。

 

目录

step1:查询器件手册,了解TLV5618基本信息。

step2:引脚功能及输出电压范围

 step3 16位控制字数据格式

  step4 接口时序

   step5 系统框图

 step6 verilog代码

step7 testbench

step8 仿真结果


DAC(Digital to Analog Conver),即数模转换器D/A,简称ADC,是指将数字信号转变为模拟信号的电子元件。

step1:查询器件手册,了解TLV5618基本信息。

TLV5618是一个基于电压输出型的双通道 的12 位单电源数模转换器,其由串行接口、一个速度和电源控制器、 电阻网络、2 倍增益的输出缓冲器组成。

 TLV5618 使用 CMOS 电平兼容的三线制SPI串行总线与各种处理器进行连接接收控制器发送的 16 位的控制字,这 16 位的控制字被分为 2 个部分,包括 4 位的编程位,12 位的数据位。

step2:引脚功能及输出电压范围

 TLV5618 的参考电压由 LM4040-2.0 提供,LM4040-2.0 是一个专用于12 位精度场合的精密参考源,输出电压为 2.048V。

 TLV5618芯片实际输出电压范围为0~2*VREF。在AC620开发板上,对应为0~4.096V。当芯片上电时,DAC 的值全部被复位到0。每个 DAC 通道的输出可由下列公式计算得出:

 其中,REF 是基准电压,本电路中为 2.048V;CODE 是数字电压输入值,范围 0 到2^12 - 1。

 step3 16位控制字数据格式

 

  step4 接口时序

   step5 系统框图

 step6 verilog代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
module tlv5618( input sys_clk_i,//50M input ext_Rst_n, input start_en,//模块使能信号 input [15:0]DAC_DATA,//控制器控制字 output reg DAC_DIN,//TLV5618的DAC_DIN接口 output reg DAC_SCLK,//TLV5618的DAC_SCLK接口,不高于20M设置12.5M output reg DAC_CS_N,//TLV5618的DAC_CS_N接口 output reg set_done,//更新DAC完成标志,1表示完成 output DAC_state//模块状态表示,1表示空闲,0表示忙碌 ); assign DAC_state = DAC_CS_N;//开始工作DAC_CS_N为0 reg [1:0]div_cnt;//25M分频计数器 parameter cnt_max = 2; reg en; wire trans_done; //转换序列完成标志信号 always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) en <= 1'b0; else if(start_en) en <= 1'b1; else if(trans_done) en <= 1'b0; else en <= en; always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) div_cnt <= 2'd0; else if(en) begin if(div_cnt< 1'b1) div_cnt <= div_cnt +1'b1; else div_cnt <= 2'd0;end else div_cnt <= 2'd0; reg SCLK2x;//25M时钟信号 always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) SCLK2x <= 1'b0; else if(en && (div_cnt == 2'd1)) SCLK2x <= 1'b1; else SCLK2x <= 1'b0; /*25M信号的第二种写法 always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) div_cnt <= 2'd0; else if(start_en) begin if(div_cnt<= 2'd0) div_cnt <= 2'd0; else div_cnt <= 2'd0;end else div_cnt <= 2'd0; reg SCLK2x;//25M时钟信号 always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) SCLK2x <= 1'b0; else if(div_cnt == 2'd0) SCLK2x <= ~SCLK2x; else SCLK2x <= SCLK2x; */ /*12.5M信号的写法 always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) div_cnt <= 2'd0; else if(start_en) begin if(div_cnt< 2'd1) div_cnt <= div_cnt +1'b1; else div_cnt <= 2'd0;end else div_cnt <= 2'd0; reg SCLK2x;//25M时钟信号 always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) SCLK2x <= 1'b0; else if(div_cnt == 2'd1) SCLK2x <= ~SCLK2x; else SCLK2x <= SCLK2x; */ reg [5:0]SCLK2x_num; always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) SCLK2x_num <= 6'd0; else if(en&&SCLK2x) begin if(SCLK2x_num <= 6'd32) SCLK2x_num <= SCLK2x_num +1'b1; else SCLK2x_num <= 6'd0;end else SCLK2x_num <= SCLK2x_num; /*计数至33,33自加一清0(此时en和sclk的有效信号最后一次被采集), 此后,en无效,div_cnt不计数,sclk2x保持为0*/ reg [15:0]r_DAC_DATA; always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) r_DAC_DATA <= 16'd0; else if(start_en) r_DAC_DATA <= DAC_DATA;//收到开始发送命令时,寄存DAC_DATA值 else r_DAC_DATA <= r_DAC_DATA; always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n)begin DAC_DIN <= 1'b1;//空闲拉高 DAC_SCLK <= 1'b0; DAC_CS_N <= 1'b1;//空闲拉高 end else if(!set_done&&SCLK2x)begin case(SCLK2x_num) 0:begin DAC_DIN <=r_DAC_DATA[15]; DAC_SCLK <=1'b1; DAC_CS_N <=1'b0;//空闲拉高 end 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31: DAC_SCLK <=1'b0; 2:begin DAC_DIN <=r_DAC_DATA[14];DAC_SCLK <= 1'b1;end 4:begin DAC_DIN <=r_DAC_DATA[13];DAC_SCLK <= 1'b1;end 6:begin DAC_DIN <=r_DAC_DATA[12];DAC_SCLK <= 1'b1;end 8:begin DAC_DIN <=r_DAC_DATA[11];DAC_SCLK <= 1'b1;end 10:begin DAC_DIN <=r_DAC_DATA[10];DAC_SCLK <= 1'b1;end 12:begin DAC_DIN <=r_DAC_DATA[9];DAC_SCLK <= 1'b1;end 14:begin DAC_DIN <=r_DAC_DATA[8];DAC_SCLK <= 1'b1;end 16:begin DAC_DIN <=r_DAC_DATA[7];DAC_SCLK <= 1'b1;end 18:begin DAC_DIN <=r_DAC_DATA[6];DAC_SCLK <= 1'b1;end 20:begin DAC_DIN <=r_DAC_DATA[5];DAC_SCLK <= 1'b1;end 22:begin DAC_DIN <=r_DAC_DATA[4];DAC_SCLK <= 1'b1;end 24:begin DAC_DIN <=r_DAC_DATA[3];DAC_SCLK <= 1'b1;end 26:begin DAC_DIN <=r_DAC_DATA[2];DAC_SCLK <= 1'b1;end 28:begin DAC_DIN <=r_DAC_DATA[1];DAC_SCLK <= 1'b1;end 30:begin DAC_DIN <=r_DAC_DATA[0];DAC_SCLK <= 1'b1;end 32: DAC_SCLK <= 1'b1; 33: DAC_CS_N <=1'b1; endcase end assign trans_done = (SCLK2x_num==6'd33)&&SCLK2x;//assign 和clk对齐的信号,立即有效操作 always@(posedge sys_clk_i or negedge ext_Rst_n) if(!ext_Rst_n) set_done <= 1'b0; else if(trans_done) set_done <= 1'b1;//和clk对齐的信号,需要等待下一个clk到来时,进行有效操作 else set_done <= 1'b0; endmodule

step7 testbench

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
`timescale 1ns/1ns `define clk_period 20 module tlv5618_tb; reg sys_clk_i;//50M reg ext_Rst_n; reg start_en;//模块使能信号 reg [15:0]DAC_DATA;//控制器控制字 wire DAC_DIN;//TLV5618的DAC_DIN接口 wire DAC_SCLK;//TLV5618的DAC_SCLK接口,不高于20M设置12.5M wire DAC_CS_N;//TLV5618的DAC_CS_N接口 wire set_done;//更新DAC完成标志,1表示完成 wire DAC_state;//模块状态表示,1表示空闲,0表示忙碌 tlv5618 tlv5618( .sys_clk_i(sys_clk_i), .ext_Rst_n(ext_Rst_n), .start_en(start_en), .DAC_DATA(DAC_DATA), .DAC_DIN(DAC_DIN), .DAC_SCLK(DAC_SCLK), .DAC_CS_N(DAC_CS_N), .set_done(set_done), .DAC_state(DAC_state) ); initial sys_clk_i = 0; always#(`clk_period/2) sys_clk_i = ~sys_clk_i; initial begin ext_Rst_n = 0; start_en = 0; DAC_DATA = 0; #201; ext_Rst_n = 1; #200; DAC_DATA = 16'hC_AAA; start_en = 1; #20; start_en = 0; wait(set_done); #20000; DAC_DATA = 16'h4_555; start_en = 1; #20; start_en = 0; wait(set_done); #20000; DAC_DATA = 16'h1_555; start_en = 1; #20; start_en = 0; wait(set_done); #20000; DAC_DATA = 16'hF_555; start_en = 1; #20; start_en = 0; wait(set_done); $stop; end endmodule

step8 仿真结果

 

最后

以上就是曾经水池最近收集整理的关于FPGA实现DAC驱动设计(以TLV5618为例)的全部内容,更多相关FPGA实现DAC驱动设计(以TLV5618为例)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(77)

评论列表共有 0 条评论

立即
投稿
返回
顶部