天天看點

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 倍增益的輸出緩沖器組成。

FPGA實作DAC驅動設計(以TLV5618為例)

 TLV5618 使用 CMOS 電平相容的三線制SPI串行總線與各種處理器進行連接配接,接收控制器發送的 16 位的控制字,這 16 位的控制字被分為 2 個部分,包括 4 位的程式設計位,12 位的資料位。

step2:引腳功能及輸出電壓範圍

FPGA實作DAC驅動設計(以TLV5618為例)

 TLV5618 的參考電壓由 LM4040-2.0 提供,LM4040-2.0 是一個專用于12 位精度場合的精密參考源,輸出電壓為 2.048V。

FPGA實作DAC驅動設計(以TLV5618為例)

 TLV5618晶片實際輸出電壓範圍為0~2*VREF。在AC620開發闆上,對應為0~4.096V。當晶片上電時,DAC 的值全部被複位到0。每個 DAC 通道的輸出可由下列公式計算得出:

FPGA實作DAC驅動設計(以TLV5618為例)

 其中,REF 是基準電壓,本電路中為 2.048V;CODE 是數字電壓輸入值,範圍 0 到2^12 - 1。

 step3 16位控制字資料格式

FPGA實作DAC驅動設計(以TLV5618為例)
FPGA實作DAC驅動設計(以TLV5618為例)

  step4 接口時序

FPGA實作DAC驅動設計(以TLV5618為例)
FPGA實作DAC驅動設計(以TLV5618為例)

   step5 系統框圖

FPGA實作DAC驅動設計(以TLV5618為例)

 step6 verilog代碼

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

`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為例)

繼續閱讀