本文最后更新于:2022年11月5日 凌晨
基于FPGA的ASK信号生成及测量分析技术
) 随机信号实验选到了这个,就当学 Verilog
了。
(以下内容围绕西电通院随机信号实验:《基于FPGA的ASK信号生成及测量分析技术》展开。
模块框图
2ASK调制电路组成框图
2ASK调制的FPGA程序框图
模块分解
梳理一下:
- 分频模块
- 载波产生模块
- m序列产生模块
- 键控开关
- DAC输出模块(给了)
- 拓展输出口(给了)
所以需要编写5个模块。
1. 分频模块设计
2.1.1按原理2.1节设计分频器a(4分频、6分频、10分频等)将系统时钟sys_clk分频,作为载波产生模块的时钟,则载波频率为sys_clk/(分频值a*一个载波周期的存储点数n)(Hz)。(sys_clk=26MHz)
2.1.2按原理2.1节设计分频器b(分频值应设置为上步中a*n的整数倍)将系统时钟分频,作为m序列产生模块的时钟,则基带码元速率为sys_clk/b(bit/s)。
可以知道要设计两个分频模块,其中主频为 26MHz。
分频模块端口示意图:
clk端为系统时钟信号输入,从out8、out16、out256可分别得到系统时钟的8分频、16分频和256分频信号。
经历了一晚上的折磨,我终于悟出了:所谓X分频,就是把时钟原来每一下变一次,变成现在是每X下变一次。 (有时候很明显的事情就是转不过来弯
所以就可以顺着这个思路编写 fenpin.v
:
testbench
仿真波形:
2. 载波产生模块
载波产生模块示意图:
载波产生模块示意图如上图所示,其中clock为载波采样时钟,q[2:0]为计数器输出,q[7:0]输出为载波信号。载波产生模块由一个计数器和一个ROM构成,其中ROM中存储着一个载波周期的样点值,则计数器的进制设置为一个载波周期包含的样点数。本实验中一个载波周期取八个样点,计数器设置为八进制计数器,ROM和计数器均可使用IP核实现。
结合示意图可以知道,载波产生模块又分为两部分:八进制计数器和ROM。分开来写。
1) 八进制计数器
q 的值每个时钟加1,从0加到7。
lpm_counter0.v
:
testbench
仿真波形
2)ROM
使用 IP核 ,照着野火的教程学了学。
46-第二十六讲-ROM-IP核的调用(一)_哔哩哔哩_bilibili
经过大概分析,可以知道本实验使用 单端口ROM ,数据为 8位宽 ,地址为 3位宽 ,至少包含 8个 数据(采样了8个点),使用单时钟。
输出添加一个寄存器会延后两个周期输出。(原来延后一个,经过寄存器再延后一个。)
写操作是时钟的上升沿,读也是时钟的上升沿。
产生 mif 文件
matlab生成.mif文件 产生正弦信号数据_橘子FPGA的博客-CSDN博客_matlab生成正弦信号
本实验中一个载波周期取八个样点。
本次使用 python
进行生成(就8个点手写也行。
根据 .mif
文件的格式一句一句打印出来。
一个普通余弦信号周期为 $2\pi$ ,取样8个点,就是 $cos(2{\pi}\times\frac{x}{8})$ ;
数据位宽为8位,所表示的数据在0~255之间,所以需要将 $cos(2{\pi}\times\frac{x-1}{8})$ 的幅值**-1~+1变化到0~255**。
具体做法是将 $cos(2{\pi}\times\frac{x}{8})\times128+128$ 。就是将原幅值变换至-128~+128,然后加上128,范围变为0~256。
python
代码:
效果(如果发现quartus报错就生成一个标准的mif文件然后把下面的复制进去替换:
生成IP核
注意深度选择的时候下拉没有8深度的选择,但是可以手动输入。
)不过我在其他文件调用ip核的时候一直仿真失败emm,所以ip核就直接用了,等我找到问题再看看。
编写代码及仿真
添加IP核,进行仿真。
testbench
仿真波形
3.m序列产生模块
m序列产生原理及其性质_Angelo_pj的博客-CSDN博客_m序列
【verilog杂谈(一)】 2-16位长度的m序列发生器 - 知乎 (zhihu.com)
要求:按原理2.3节设计m序列产生模块,要求产生不同长度的m序列。
代码根据实验要求修改自参考链接,可以产生2~16位的m序列。
mxulie.v
testbench
仿真波形
4.键控开关
键控开关示意图图上图所示,其中data[7:0]端输入载波信号,gate端输入基带码元,当gate信号为1时,载波信号通过,如果gate信号为0时,载波信号不能通过。模块的输出端q[7:0]输出2ASK已调信号。
lpm_gate.v
整合以及整体仿真
将以上各个模块添加进实验给定的模板,并生成原理图,然后连线。
要整体仿真,所以要先把原理图转换为 Verilog
(File -> Create / Update -> Create HDL Design File from Current File…),之后从工程文件移除原理图,设置生成的 verilog
文件为顶层文件进行编译,然后仿真。
通过对比编译出来的 RTL 视图,符合给定框图。
整体仿真,只要注意 clk
, m_squence
, two_ask[7...0]
这几个信号就行。 testbench
如下:
仿真波形:
管脚分配
管脚分配啥的给的模板文件里已经分配好了,直接用就行。
总结
毕竟是主要是记录 verilog
的一个学习过程,剩下的就不分析了,属于是实验报告里的活。这算是第一次用 verilog
干这种比较综合的活?接触到了一些新玩意,IP核,mif文件之类的。也锻炼了从s一样实验指导手册里提炼信息的能力?
(然后细节和要补充的等后面想起来再说
(我超突然想起来线下验收完忘了拍时域波形