环境:Quartus II13.1
开发板:EP3416Q240C8
任务:在开发板上实现DDS功能,要有加减及复位按键功能,复位时波形周期为(学号后两位*10)hz;加减时单号步进为10hz,双号步进为20hz。此处学号为双号。使用SignalTap II Log Analyzer观察波形变化。
1.rom_data.mif(可根据需要更改储存数据)
2.TLV5618.v
module TLV5618(Clk,Clk_165K,En,MOSI,nSS,SCK,PR_Data,DA_Data);
input Clk,Clk_165K,En;
input [3:0] PR_Data;
input [11:0] DA_Data;
output nSS,MOSI,SCK;
reg SCK;
reg nSS,MOSI;
reg [4:0] Cnt_R0;
always @(posedge Clk_165K)
begin
if(En == 0)
begin
if(Cnt_R0 < 8'h10)
begin
nSS <= 0;
case(Cnt_R0)
8'h00 : begin MOSI <= PR_Data[3]; Cnt_R0 <= 5'h01; end
8'h01 : begin MOSI <= PR_Data[2]; Cnt_R0 <= 5'h02; end
8'h02 : begin MOSI <= PR_Data[1]; Cnt_R0 <= 5'h03; end
8'h03 : begin MOSI <= PR_Data[0]; Cnt_R0 <= 5'h04; end
8'h04 : begin MOSI <= DA_Data[11]; Cnt_R0 <= 5'h05; end
8'h05 : begin MOSI <= DA_Data[10]; Cnt_R0 <= 5'h06; end
8'h06 : begin MOSI <= DA_Data[9]; Cnt_R0 <= 5'h07; end
8'h07 : begin MOSI <= DA_Data[8]; Cnt_R0 <= 5'h08; end
8'h08 : begin MOSI <= DA_Data[7]; Cnt_R0 <= 5'h09; end
8'h09 : begin MOSI <= DA_Data[6]; Cnt_R0 <= 5'h0A; end
8'h0A : begin MOSI <= DA_Data[5]; Cnt_R0 <= 5'h0B; end
8'h0B : begin MOSI <= DA_Data[4]; Cnt_R0 <= 5'h0C; end
8'h0C : begin MOSI <= DA_Data[3]; Cnt_R0 <= 5'h0D; end
8'h0D : begin MOSI <= DA_Data[2]; Cnt_R0 <= 5'h0E; end
8'h0E : begin MOSI <= DA_Data[1]; Cnt_R0 <= 5'h0F; end
8'h0F : begin MOSI <= DA_Data[0]; Cnt_R0 <= 5'h10; end
default : begin nSS <= 1; end
endcase
end
end
else
begin
Cnt_R0 <= 8'h00;
nSS <= 1;
end
end
always @(posedge Clk)
begin
if(nSS <= 0)
begin
SCK <= Clk_165K;
end
else
begin
SCK <= 0;
end
end
endmodule
- 将rom_data.mif和TLV5618添加到Project Navigator->Files下。
- Tools->MegaWizard Plug-In Manager->Memory Compiler:ROM 1-PORT。type为verilog HDL,name为rom。
点击next,出现ROM:1-PORT设置:
然后添加rom_data.mif,其他默认,最后finish。
分频:(n*32)可自由组合。256为rom_data.mif中数据位数,20为双号步进,n大约为306。
顶层文件DDS.v:
`define R1 1'b1
`define SPD 1'b1 //TLV5618 速度控制位,大于3us,快速模式1'b1.低速模式10us
`define PWR 1'b0
`define R0 1'b0
module DDS(Key1_Add,Key2_Sub,Key3_Rst,Clk,MOSI,nSS,SCK,Dout);
input Key1_Add,Key2_Sub,Key3_Rst,Clk;
output MOSI,nSS,SCK;
output [11:0] Dout;
wire Clk;
wire [11:0] q;
reg [7:0] address;
reg Clk_165K,En;//50e6hz,306分频约164k
reg [7:0] Cnt_R0;//306分频计数
reg [4:0] Cnt_R1;//32分频计数
reg [3:0] PR_Data;
reg [11:0] DA_Data;
reg Clk_Scan;
reg [12:0] CNT_R0;//按键扫描计数
reg [7:0] Data;
reg [3:0] Key1_CNT,Key2_CNT,Key3_CNT;//加减,复位按键
reg [1:0] Key1_Flag,Key2_Flag,Key3_Flag;//按键标志位
reg Key1_Flag_Clear,Key2_Flag_Clear,Key3_Flag_Clear;//按键清零标志位
rom u1(.address(address),.clock(Clk),.q(q));
TLV5618 u2(.Clk(Clk),.Clk_165K(Clk_165K),.En(En),.MOSI(MOSI),.nSS(nSS),.SCK(SCK),.PR_Data(PR_Data),.DA_Data(q));
initial//初始值,立即执行
begin
Data <= 8'h9;//学号末两位18,复位180hz=20hz*9
Cnt_R0 <= 0;
Cnt_R1 <= 0;
end
always @(posedge Clk)//按键扫描时钟
begin
CNT_R0 <= CNT_R0 + 1'b1;
if(CNT_R0 < 4096)
begin
Clk_Scan <= 1'b1;
end
else
begin
Clk_Scan <= 1'b0;
end
end
always @(posedge Clk)
begin
if(Cnt_R0 < 153)//步进20hz 50e6/(32*256*20)=306,即306分频
begin
Clk_165K <= 0;
end
else
begin
Clk_165K <= 1;
end
Cnt_R0 <= Cnt_R0 + 1;
end
always @(posedge Clk_165K)
begin
if(Cnt_R1 < 16)//32分频=16*2
begin
Cnt_R1 = Cnt_R1 + 1;
En = 0;
end
else
begin
Cnt_R1 = Cnt_R1 + 16;
En = 1;
end
end
always
begin
PR_Data[3] <= `R1;
PR_Data[2] <= `SPD;
PR_Data[1] <= `PWR;
PR_Data[0] <= `R0;
end
always @(posedge En)
begin
address = address + Data;
end
assign Dout = q;
always @(posedge Clk_Scan)//步进加按键
begin
if(Key1_Add == 1'b1)//判断按键是否按下,未按下按键标志位‘Key1_Flag’为0
begin
if(Key1_Flag_Clear == 1'b0)//判断按键清零标志位是否清0,未清0的话按键标志位‘Key1_Flag’为2
begin
if(Key1_Flag == 2'h0)//是否经过了防抖动处理,经过短暂延时,按键标志位‘Key1_Flag’赋值为1
begin
if(Key1_CNT < 4'hF)
begin
Key1_CNT <= Key1_CNT + 1'b1;
Key1_Flag <= 2'h0;//延时处理
end
else
begin
Key1_Flag = 2'h1; //防抖动结束,给按键标志位赋值为1
end
end
end
else
begin
Key1_Flag = 2'h2; //按键清零标志位未清零的过渡阶段
end
end
else
begin
Key1_CNT <= 4'h0;
Key1_Flag <= 2'h0;
end
end
always @(posedge Clk_Scan)//步进减按键
begin
if(Key2_Sub == 1'b1)
begin
if(Key2_Flag_Clear == 1'b0)
begin
if(Key2_Flag == 2'h0)
begin
if(Key2_CNT < 4'hF)
begin
Key2_CNT <= Key2_CNT + 1'b1;
Key2_Flag <= 2'h0;
end
else
begin
Key2_Flag = 2'h1;
end
end
end
else
begin
Key2_Flag = 2'h2;
end
end
else
begin
Key2_CNT <= 4'h0;
Key2_Flag <= 2'h0;
end
end
always @(posedge Clk_Scan)//复位按键
begin
if(Key3_Rst == 1'b1)
begin
if(Key3_Flag_Clear == 1'b1)
begin
if(Key3_Flag == 2'h0)
begin
if(Key3_CNT < 4'hF)
begin
Key3_CNT <= Key3_CNT + 1'b1;
Key3_Flag <= 2'h0;
end
else
begin
Key3_Flag = 2'h1;
end
end
end
else
begin
Key3_Flag = 2'h2;
end
end
else
begin
Key3_CNT <= 4'h0;
Key3_Flag <= 2'h0;
end
end
always @(posedge Clk_Scan)//实现加减20hz,Data每次加减1,复位键清零
begin
if((Key1_Flag == 2'h1)&&(Key1_Flag_Clear == 1'b0))//按键Key1_Add按下,步进加
begin
Data <=Data + 8'b1;
Key1_Flag_Clear <= 1'b1;//按键清零标志为1,未清零
end
else if(Key1_Flag == 2'h0)//按键未按下,按键标志位‘Key1_Flag’0
begin
Key1_Flag_Clear <= 1'b0;//按键清零标志为0,清零
end
if((Key2_Flag == 2'h1)&&(Key2_Flag_Clear == 1'b0))//按键Key2_Sub按下,步进减
begin
Data <=Data - 8'b1;
Key2_Flag_Clear <= 1'b1;
end
else if(Key2_Flag == 2'h0)
begin
Key2_Flag_Clear <= 1'b0;
end
if((Key3_Flag == 2'h1)&&(Key3_Flag_Clear == 1'b0))//按键Key3_Rst按下,复位
begin
Data <=8'h9;//学号末两位18,复位180hz=20hz*9
Key3_Flag_Clear <= 1'b1;
end
else if(Key3_Flag == 2'h0)
begin
Key3_Flag_Clear <= 1'b0;
end
end
endmodule
然后编译,添加引脚(Dout不用添加)。新建SignalTap II Log Analyzer File文件。双击空白添加DOUT,用来观察输出波形。
然后添加clock:EN,sample depth:8K;再将开发板usb添加。缩小界面,再次编译DDS.V,保存SignalTap II Log Analyzer File,并OK将其添加到工程。
将工程下载到开发板。然后将.sof文件添加到SignalTap II Log Analyzer File。
然后点击位置 1(左边单次运行,右边持续运行)出现波形。右击位置2->Bus Display Format->Singed Line Chart。右击位置3->Time units
输入[(32306)/50000000]S或者[50000000/(32306)]Hz。点击位置4停下运行,观察波形。
左击位置3(可多击),则出现移动标尺,观察两点之间的距离,看周期是否符合。
按下开发板的按键,重复以上位置的操作,可观察步进改变是否符合要求。