
2018.5.17更新如下
作为小透明,没想到随手一写的学习过程也能被看见,看到有人点赞也还是很高兴的,希望能以后自己忘了,还能来看懂,如果对大家能有所帮助,那就再好不过了。
对于输出的正弦波周期有两种算法,在这里记录一下。
因为和昨天使用的不是同一个文件,所以名称会和昨天的不一样,不过原理一样。
另外,在仿真的时候可以不用添加约束文件,只需要仿真时可以直接跳过,如果需要下载进板子的话就必须要写了。下一篇会介绍。
1.使用DDS输出的最高位去计算,具体操作如图

点击两次上图3的图标

可能会觉得频率控制字可以控制输出波形的频率,而输出位宽又可以计算输出波形周期,那改变输出波形会影响什么呢?会影响输出波形周期吗?答案是不会。
具体看图,我将输出位宽改为10位的仿真结果。

输出位宽影响的是输出波形的幅度(0^◇^0)/
了解DDS的原理就明白了。
2.第二种就是昨天解释原理时用频率控制字控制输出频率时,fre_word取1的值。
具体算法见原答案。
两种区别就是一个取最高位,一个取最低位,刚开始容易理不清。
原答案如下
信号调制和解调功能。写下其中过程当做自己的学习记录吧。本篇讲的是如何产生一个正弦波。
- 使用的软件是Vivado 2016.4
- 实验室板卡是Nexys Video
1.原理说明
采用的是自带DDS IP核,DDS直接数字式频率合成器(Direct Digital Synthesizer),相信所有人看到这个名字就觉得不会陌生。
DDS由频率控制字(Frequency Control Word)寄存器、相位累加器(Phase Accumulator)和正余弦查找表(Sine/Cosine LUT)三部分组成,通过控制相位累加器的位宽和查找表的位宽,可以实现不同频率和动态范围的正弦信号的产生。
关于DDS是如何产生我们需要的波形信号可以查看这篇文章:
用FPGA实现DDS任意波形发生器 | 电子创新网赛灵思中文社区xilinx.eetrend.com
而我们现在不用关心太多原理,经过实验的过程,自然就能明白其工作原理。
我们只需要知道如何控制其输出频率就行了,首先记住两个术语(jargon):
a. 相位累加器:Phase = Phase + fre_word,可以暂且理解为i = i + 1一样的东西。
b. 频率控制字:fre_word,这个东西的值直接影响输出信号的频率。
我们的输出频率就是由fre_word来控制。
具体怎么算的呢?
DDS核频率分辨率计算公式如下:

其中Δθ就是我们的频率控制字取值后文用fre_word表示,Bθ(n)是相位累加器位宽后文用B表示,fclk为DDS工作时钟。
频率分辨率就是当Δθ=1时的fout。
先假如我们需要的信号频率范围:1M-10MHz,分辨率0.01MHz。
取Δθ=1,fout=0.01MHz,B=10bit,我们可得DDS工作时钟fclk=10.24MHz。
到这里我们就知道,产生一个正弦波信号需要2部分即可:
- 时钟分频器(因为我们的软件系统时钟为100MHz,而我们算出的DDS工作时钟为10.24MHz)
- DDS IP核
2.具体操作过程
打开vivado,新建工程

给工程命名,路径不能出现中文

如图勾选,我们后面自己建源文件

选择板卡(这个板卡需要在安装后自己添加了才会有),点击接下来的next,finish。

添加源文件

取名

现在不用添加管脚,点击ok,yes即可

添加IP 核,找到DDS,蓝色的都是一样的,随便选一个双击

命名,选择dds工作时钟10.24MHz,选择使用硬件参数,位宽根据前面计算的结果填写(相位位宽就是我们的频率控制字位宽,而输出位宽影响ROM表深度 (大小为

选择可编程(因为由fre_word控制),输出sine,不需要观测相位输出

因为是10位,改为0000000001

查看summary,可知最小频率为0.01MHz,点击ok

点击生成

用时钟管理核生成时钟分频模块,步骤如图,不再描述




咦,,,,好像点击图片可以直接描述,第一次用知乎写,还不会。。。。后面的图片描述在图片下方的描述区。。。















3.代码只要所建名字一样,可以直接复制使用
1
2主程序
顶层约束文件
1
2
3
4
5set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sysclk] ############################ #https://mp.weixin.qq.com/s/3WoAO4aHYTqTWLTnF56zMA关于时序约束# ############################ create_clock -period 10.000 -name sysclk -waveform {0.000 5.000} [get_ports sysclk]
仿真文件
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`timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2018/05/16 19:29:18 // Design Name: // Module Name: ZXB_tb // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module ZXB_tb( ); reg clk; // wire [7:0] data; reg [9:0] fw_z; ZXB dut( .sysclk(clk), .fw_z(fw_z), // .led(data)); // 初始化 initial begin clk = 0; fw_z = 10'b0000000001; end //产生100MHz时钟信号 always begin #5 clk = ~clk; end endmodule
4.本来应该添上VIO和ILA的,不过没有板子在,写了也用不了,就不写了,大概和这个差不多,主要区别就是VIO是外部板子给信号,而仿真就是软件假装的,所以在主程序中会有所不同。会Verilog就懂了。
5.第一次写,很简单的一个功能,居然写了这么多,说明理解还不是很到位,表达也不是很简洁明了,ε=(´ο`*)))唉溜了溜了
最后
以上就是难过冰淇淋最近收集整理的关于verilog设计简易正弦波信号发生器_FPGA学习(一)——产生频率可控的正弦波的全部内容,更多相关verilog设计简易正弦波信号发生器_FPGA学习(一)——产生频率可控内容请搜索靠谱客的其他文章。
发表评论 取消回复