基于AD9767高速DAC的DDS信号发生器
前言
基于AD9767高速DAC的DDS信号发生器
提示:以下是本篇文章正文内容,下面案例可供参考
一、 实现效果
1.做一个双通道的信号发生器;
2.简单调整每个通道的频率输出;
3.能够调整每个通道的输出相位;
4.能够输出正弦波,三角波,方波。
二、DDS_AD9767(顶层模块)
代码如下(示例):
`timescale 1ns / 1ps
module DDS_AD9767(
Clk,
Reset_n,
Mode_SelA,
Mode_SelB,
DataA,
ClkA, //AD9767高速DAC驱动需要
WRTA,
DataB, //AD9767高速DAC驱动需要
WRTB, //AD9767高速DAC驱动需要
ClkB, //AD9767高速DAC驱动需要
Key
);
input Clk;
input Reset_n;
input [1:0]Mode_SelA;//实现通道1的波形选择
input [1:0]Mode_SelB;//实现通道的波形选择
input [3:0]Key; //按键实现Fword Pward切换
output [13:0]DataA;
output ClkA;
output WRTA;
output [13:0]DataB;
output ClkB;
output WRTB;
assign ClkA = Clk;
assign ClkB = Clk;
assign WRTA = ClkA;
assign WRTB = ClkB;
reg [31:0]FwordA,FwordB;
reg [11:0]PwordA,PwordB;
//----------------------------------------------------------------------------
//双通道例化两次
DDS_Module DDS_ModuleA(
.Clk(Clk),
.Reset_n(Key_State[2] & Key_State[3]), //切换时保持统一频率
.Mode_Sel(Mode_SelA),
.Fword(FwordA),
.Pword(PwordA),
.Data(DataA)
);
DDS_Module DDS_ModuleB(
.Clk(Clk),
.Reset_n(Key_State[2] & Key_State[3]),
.Mode_Sel(Mode_SelB),
.Fword(FwordB),
.Pword(PwordB),
.Data(DataB)
);
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//四个key按键的按键消抖
wire [3:0]Key_Flag;
wire [3:0]Key_State;
//按键消抖
key_filter key_filter0(
.Clk(Clk),
.Reset_n(Reset_n),
.Key(Key[0]),
.Key_Flag(Key_Flag[0]),
.Key_State(Key_State[0])
);
//按键消抖
key_filter key_filter1(
.Clk(Clk),
.Reset_n(Reset_n),
.Key(Key[1]),
.Key_Flag(Key_Flag[1]),
.Key_State(Key_State[1])
);
//按键消抖
key_filter key_filter2(
.Clk(Clk),
.Reset_n(Reset_n),
.Key(Key[2]),
.Key_Flag(Key_Flag[2]),
.Key_State(Key_State[2])
);
//按键消抖
key_filter key_filter3(
.Clk(Clk),
.Reset_n(Reset_n),
.Key(Key[3]),
.Key_Flag(Key_Flag[3]),
.Key_State(Key_State[3])
);
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//实现按键切换
reg [2:0]CHA_Fword_Sel;
reg [2:0]CHB_Fword_Sel;
reg [2:0]CHA_Pword_Sel;
reg [2:0]CHB_Pword_Sel;
//按键切换Fword
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
CHA_Fword_Sel <= 0;
else if(Key_Flag[0] && (Key_State[0] == 0))
CHA_Fword_Sel <= CHA_Fword_Sel + 1'd1;
//按键切换Fword
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
CHB_Fword_Sel <= 0;
else if(Key_Flag[1] && (Key_State[1] == 0))
CHB_Fword_Sel <= CHB_Fword_Sel + 1'd1;
//按键切换Pword
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
CHA_Pword_Sel <= 0;
else if(Key_Flag[2] && (Key_State[2] == 0))
CHA_Pword_Sel <= CHA_Pword_Sel + 1'd1;
//按键切换Pword
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
CHB_Pword_Sel <= 0;
else if(Key_Flag[3] && (Key_State[3] == 0))
CHB_Pword_Sel <= CHB_Pword_Sel + 1'd1;
always@(*)
case(CHA_Fword_Sel)
0:FwordA = 86;//2**32 / 50000000; 85.89934592
1:FwordA = 859;//2**32 / 5000000;
2:FwordA = 8590;//2**32 / 500000;
3:FwordA = 85899;//2**32 / 50000;
4:FwordA = 858993;//2**32 / 5000;
5:FwordA = 8589935;//2**32 / 500;
6:FwordA = 85899346;//2**32 / 50;
7:FwordA = 429496730;//2**32 / 10;
endcase
always@(*)
case(CHB_Fword_Sel)
0:FwordB = 86;//2**32 / 50000000; 85.89934592
1:FwordB = 859;//2**32 / 5000000;
2:FwordB = 8590;//2**32 / 500000;
3:FwordB = 85899;//2**32 / 50000;
4:FwordB = 858993;//2**32 / 5000;
5:FwordB = 8589935;//2**32 / 500;
6:FwordB = 85899346;//2**32 / 50;
7:FwordB = 429496730;//2**32 / 10;
endcase
always@(*)
case(CHA_Pword_Sel)
0:PwordA = 0; //0
1:PwordA = 341; //30
2:PwordA = 683; //60
3:PwordA = 1024; //90
4:PwordA = 1707; //150
5:PwordA = 2048; //180
6:PwordA = 3072; //270
7:PwordA = 3641; //320
endcase
always@(*)
case(CHB_Pword_Sel)
0:PwordB = 0; //0
1:PwordB = 341; //30
2:PwordB = 683; //60
3:PwordB = 1024; //90
4:PwordB = 1707; //150
5:PwordB = 2048; //180
6:PwordB = 3072; //270
7:PwordB = 3641; //320
endcase
//----------------------------------------------------------------------------
endmodule
三、DDS_Module
代码如下(示例):
module DDS_Module(
Clk,
Reset_n,
Mode_Sel,
Fword,
Pword,
Data
);
input Clk;
input Reset_n;
input [1:0]Mode_Sel;
input [31:0]Fword;
input [11:0]Pword;
output reg[13:0]Data;
//频率控制字同步寄存器
reg [31:0]Fword_r;
always@(posedge Clk)
Fword_r <= Fword;
//相位控制字同步寄存器
reg [11:0]Pword_r;
always@(posedge Clk)
Pword_r <= Pword;
//相位累加器
reg [31:0]Freq_ACC;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Freq_ACC <= 0;
else
Freq_ACC <= Fword_r + Freq_ACC;
//波形数据表地址
wire [11:0]Rom_Addr;
assign Rom_Addr = Freq_ACC[31:20] + Pword_r;
//---------------------------------------------------------------------------
//实现波形选择
wire [13:0]Data_sine,Data_square,Data_triangular;
rom_sine rom_sine(
.clka(Clk),
.addra(Rom_Addr),
.douta(Data_sine)
);
rom_square rom_square(
.clka(Clk),
.addra(Rom_Addr),
.douta(Data_square)
);
rom_triangular rom_triangular(
.clka(Clk),
.addra(Rom_Addr),
.douta(Data_triangular)
);
always@(*)
case(Mode_Sel)
0:Data = Data_sine;
1:Data = Data_square;
2:Data = Data_triangular;
3:Data = 8192;
endcase
//---------------------------------------------------------------------------
endmodule
四、key_filter
module key_filter(
Clk,
Reset_n,
Key,
// Key_P_Flag,
// Key_R_Flag,
Key_Flag,
Key_State
);
input Clk;
input Reset_n;
input Key;
// output reg Key_P_Flag;
// output reg Key_R_Flag;
output Key_Flag;
output reg Key_State;
reg Key_P_Flag;
reg Key_R_Flag;
assign Key_Flag = Key_P_Flag | Key_R_Flag;
//-----------------------------------------------------------
//两个寄存器防止亚稳态
reg [1:0]sync_Key;
always@(posedge Clk)
sync_Key <= {sync_Key[0],Key};
reg [1:0] r_Key;
always@(posedge Clk)
r_Key <= {r_Key[0],sync_Key[1]};
//-----------------------------------------------------------
wire pedge_key;
assign pedge_key = r_Key == 2'b01;
wire nedge_key;
assign nedge_key = r_Key == 2'b10;
reg [19:0]cnt;
reg [1:0]state;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)begin
state <= 0;
Key_R_Flag <= 1'b0;
Key_P_Flag <= 1'b0;
cnt <= 0;
Key_State <= 1;
end
else begin
case(state)
0:
begin
Key_R_Flag <= 1'b0;
if(nedge_key)
state <= 1;
else
state <= 0;
end
1:
if((pedge_key)&&(cnt <1000000 -1))begin
state <= 0;
cnt <= 0;
end
else if(cnt >= 1000000 -1)begin
state <= 2;
cnt <= 0;
Key_P_Flag <= 1;
Key_State <= 0;
end
else begin
cnt <= cnt + 1'b1;
state <= 1;
end
2:
begin
Key_P_Flag <= 0;
if(pedge_key)
state <= 3;
else
state <= 2;
end
3:
if((nedge_key)&&(cnt <1000000 -1))begin
state <= 2;
cnt <= 0;
end
else if(cnt >= 1000000 -1)begin
state <= 0;
cnt <= 0;
Key_R_Flag <= 1'b1;
Key_State <= 1;
end
else begin
cnt <= cnt + 1'b1;
state <= 3;
end
endcase
end
endmodule
五、上板演示
【附件:】链接:https://pan.baidu.com/s/1dGSAj9wV1GpYPKa4Fl6KuA?pwd=ncix
提取码:ncix