设计要求
1、设计一个双通道的信号发生器输出
2、能够简单的调整每个通道的频率输出(通过按键来循环切换几个固定频率输出)
3、能够简单的调整每个通道的输出相位(通过按键来循环切换几个固定相位输出)
4、能够简单的调整输出的波形形式(正弦波、方波、三角波)
仿真波形
设计文件程序
`timescale 1ns / 1ns
module DDS_Module(
Clk,
Reset_N,
Model_Sel,
Fword,
Pword,
Data
);
input Clk;
input Reset_N;
input [1:0]Model_Sel;
input [31:0]Fword;
input [11:0]Pword;
output reg [13:0]Data;
wire [31:0]Data_Sine;
wire [31:0]Data_Triangular;
wire [31:0]Data_Square;
//频率控制字的同步寄存器
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;
//波形数据表的地址
//查ROM表输出序列
wire [11:0]Rom_Addr;
assign Rom_Addr = Freq_ACC[31:20] + Pword_r;
Rom_Sine Rom_Sine (
.clka(Clk),
.addra(Rom_Addr),
.douta(Data_Sine)
);
Rom_Triangular Rom_Triangular (
.clka(Clk),
.addra(Rom_Addr),
.douta(Data_Triangular)
);
Rom_Square Rom_Square (
.clka(Clk),
.addra(Rom_Addr),
.douta(Data_Square)
);
always@(*)
case(Model_Sel)
0:Data <= Data_Sine;
1:Data <= Data_Triangular;
2:Data <= Data_Square;
3:Data <= 8192;
endcase
endmodule
`timescale 1ns / 1ns
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 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]R_Key;
reg [1:0]Sync_Key;
wire Pedge_Key;
wire Nedge_Key;
always@(posedge Clk)begin
Sync_Key <= #1 {Sync_Key[0],Key};
end
always@(posedge Clk)begin
R_Key <= #1 {R_Key[0],Sync_Key[1]};
// R_Key[0] <= Key;
// R_Key[1] <= R_Key[0];
end
//Posedge Check
assign Pedge_Key = (R_Key == 2'b01);
//Negedge Check
assign Nedge_Key = (R_Key == 2'b10);
reg [19:0]Counter;
localparam IDLE = 0;
reg [1:0]state;
always@(posedge Clk or negedge Reset_N)
if(!Reset_N)begin
state <= #1 0;
Counter <= #1 0;
Key_P_Flag <= #1 0;
Key_R_Flag <= #1 0;
Key_State <= #1 1;
end
else begin
case(state)
0:
begin
Key_R_Flag <= #1 0;
if(Nedge_Key)
state <= #1 1;
else
state <= #1 0;
end
1:
if((Pedge_Key)&&(Counter < 1000000 - 1))begin
state <= #1 0;
Counter <= #1 0;
end
else if(Counter >= 1000000 - 1)begin
state <= #1 2;
Counter <= #1 0;
Key_P_Flag <= #1 1;
Key_State <= #1 0;
end
else begin
Counter <= #1 Counter + 1'd1;
state <= #1 1;
end
2:
begin
Key_P_Flag <= #1 0;
if(Pedge_Key)
state <= #1 3;
else
state <= #1 2;
end
3:
if((Nedge_Key)&&(Counter < 1000000 - 1))begin
state <= #1 2;
Counter <= #1 0;
end
else if(Counter >= 1000000 -1)begin
state <= #1 0;
Counter <= #1 0;
Key_R_Flag <= #1 1;
Key_State <= #1 1;
end
else begin
Counter <= #1 Counter + 1'd1;
state <= #1 3;
end
endcase
end
endmodule
`timescale 1ns / 1ns
module DDS_AD9767(
Clk,
Reset_N,
Model_SelA,
Model_SelB,
Key,
DataA,
DataB
);
input Clk;
input Reset_N;
input [1:0]Model_SelA;
input [1:0]Model_SelB;
input [3:0]Key;
output [13:0]DataA;
output [13:0]DataB;
wire [3:0]Key_Flag;
wire [3:0]Key_State;
reg [31:0]FwordA,FwordB;
reg [11:0]PwordA,PwordB;
DDS_Module DDS_ModuleA(
Clk,
Reset_N,
Model_SelA,
FwordA,
PwordA,
DataA
);
DDS_Module DDS_ModuleB(
Clk,
Reset_N,
Model_SelB,
FwordB,
PwordB,
DataB
);
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;
always@(posedge Clk or negedge Reset_N)
if(!Reset_N)
CHA_Fword_Sel <= 0;
// Key_Flag == 1 发生按键按下或释放动作
// Key_State == 0 低电平标志位
else if(Key_Flag[0] && (Key_State[0] == 0))
CHA_Fword_Sel <= CHA_Fword_Sel + 1'b1;
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'b1;
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'b1;
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'b1;
always@(*)
case(CHA_Fword_Sel)
0: FwordA = 86;
1: FwordA = 859;
2: FwordA = 8590;
3: FwordA = 85899;
4: FwordA = 858993;
5: FwordA = 8589935;
6: FwordA = 85899346;
7: FwordA = 429496730;
endcase
always@(*)
case(CHB_Fword_Sel)
0: FwordB = 86;
1: FwordB = 859;
2: FwordB = 8590;
3: FwordB = 85899;
4: FwordB = 858993;
5: FwordB = 8589935;
6: FwordB = 85899346;
7: FwordB = 429496730;
endcase
always@(*)
case(CHA_Pword_Sel)
0: PwordA = 0;
1: PwordA = 341;
2: PwordA = 683;
3: PwordA = 1024;
4: PwordA = 1707;
5: PwordA = 2048;
6: PwordA = 3072;
7: PwordA = 3641;
endcase
always@(*)
case(CHB_Pword_Sel)
0: PwordB = 0;
1: PwordB = 341;
2: PwordB = 683;
3: PwordB = 1024;
4: PwordB = 1707;
5: PwordB = 2048;
6: PwordB = 3072;
7: PwordB = 3641;
endcase
endmodule
仿真文件程序
`timescale 1ns / 1ns
module DDS_AD9767_tb();
reg Clk;
reg Reset_N;
reg [1:0]Model_SelA;
reg [1:0]Model_SelB;
reg [3:0]Key;
wire [13:0]DataA;
wire [13:0]DataB;
DDS_AD9767 DDS_AD9767(
Clk,
Reset_N,
Model_SelA,
Model_SelB,
Key,
DataA,
DataB
);
initial Clk = 1;
always #10 Clk = !Clk;
initial begin
Reset_N = 0;Key = 4'b1111;
#201;
Reset_N = 1;
Model_SelA = 1;
Model_SelB = 0;
#2000;
Key = 4'b1100;
#50000000;
Key = 4'b1111;
#50000000;
Key = 4'b0000;
#50000000;
Key = 4'b1111;
#20000000;
$stop;
end
endmodule