试验说明:
笔者复现FSK调制、解调的过程中,在网上查了很多很多相关文章,至少在本文之前,没发现能在参考一篇博文的情况下能完整复现实验结果的。总之,全乎的基本没有。
本笔记(文)的目标是让入门者或者说小白在参考本文的基础上,能一步一步完整复现实验结果,少走弯路,尽力节省时间,因为时间很宝贵。
另:本实验只是复现参考博文的结果,有关概念、原理相关知识请参考原文。
实验目标:
达成和博文中最终仿真结果基本一致,先看一下本次实验的最终的仿真结果吧!
注意:
FSK调制信号生成步骤
简单说明:
连续相位调制时,配置1个DDS产生两个代表1和0的单频信号(要调制–非连续相位的要产生2个信号)即可,非连续相位的内容具体参考原文。
有关概念、原理相关知识请参考原文
DDS IP核的配置过程:
ISE14.7新建工程:
注意:器件选择高端点的,在试验过程中被坑过,因为器件选的低。
工程建立后,添加DDS IP核:
上图参数简要说明:
DDS的频率分辨率设置为976.5625Hz,正好对应相位位宽为15Bits
本实验使用连续相位FSK(CPFSK)只需要使用一个DDS Compiler IP核,比FSK要节省不少资源。
因此,CPFSK配置如下:
注意上图参数
CPFSK (连续相位FSK)调制的仿真结果:
----------------------------------------------------华丽的分割线---------------------------------------------------------------------------------
FSK解调部分实验
首先
在命令行窗口输入:fdatool
简要说明一下:
A:(6Mhz-h×1Mhz)–6Mhz。
带通滤波器A的配置如上图所示。配置完成后,就可以导出coe文件了。
导出coe文件:
B的配置、导出COE文件的方法同A----即上图,这里省略截图了。
低通滤波器的配置:
注:
至此,所有的滤波器系数经过量化后存储为txt(coe)文件,供后面在FPGA设计中调用。
bpf1_fir.coe、bpf2_fir.coe、lpf_fir.coe
ISE14.7配置IP核:
新建工程,关键步骤如下:
输入采用频率和系统时钟:
输出位数:32
bpf2_fir配置方法和步骤一样(略过)
lpf_fir的配置方法和步骤也一样(略过)
全部生成后,到ipcore_dir目录内,复制文件
bpf1_fir.mif bpf1_fir.mif lpf_fir.mif 该文件放入modelsim工程模板的sim目录
bpf1_fir.v bpf2_fir.v 、lpf_fir.v 该文件放入modelsim工程模板的src目录
----------------------------------------------------华丽的分割线---------------------------------------------------------------------------------
开始仿真
modelsim工程结构:
目录结构说明:
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@echo off @cls title FPGA Auto Simulation batch script echo ModelSim simulation echo. echo Press '1' to start simulation echo. :input set INPUT= set /P INPUT=Type test number: %=% if "%INPUT%"=="1" goto run1 goto end :run1 @cls echo Start Simulation; echo. echo. cd sim vsim -do "do compile.do" goto clean_workspace :clean_workspace rmdir /S /Q work del vsim.wlf del transcript. :end
src目录内---- 存源文件
注意:
sim目录内— 存激励文件和2个do文件及1个ini文件
wave.do文件内容:
1
2
3
4
5add wave -divider {cpfsk_modulate_demodulate_tb} add wave -position insertpoint sim:/cpfsk_modulate_demodulate_tb/*
compile.do文件内容:
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
26vlib work vmap work work vlog -work work glbl.v #library #vlog -work work ../../library/artix7/*.v #IP #vlog -work work ../../../source_code/ROM_IP/rom_controller.v #SourceCode vlog -work work ../src/*.v #Testbench vlog -work work cpfsk_modulate_demodulate_tb.v #vsim -voptargs=+acc -L unisims_ver -L unisim -L work -Lf unisims_ver work.glbl work.cpfsk_modulate_demodulate_tb vsim -voptargs=+acc work.glbl work.cpfsk_modulate_demodulate_tb #Add signal into wave window do wave.do #run -all run 1ms
Modelsim.ini文件内容:
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[Library] others = $MODEL_TECH/../modelsim.ini work = work [vcom] VHDL93 = 2002 Explicit = 1 [vlog] LibrarySearchPath = mtiAvm mtiOvm mtiUvm mtiUPF [sccom] [vopt] [vsim] VoptFlow = 1 Resolution = ns UserTimeUnit = default RunLength = 100 IterationLimit = 5000 BreakOnAssertion = 3 ShowFunctions = 1 DefaultRadix = symbolic TranscriptFile = transcript PathSeparator = / DatasetSeparator = : UnbufferedOutput = 0 ConcurrentFileLimit = 40 ScTimeUnit = ns ScMainStackSize = 10 Mb ScMainFinishOnQuit = 1 ScvPhaseRelationName = mti_phase OnFinish = ask DumpportsCollapse = 1 MvcHome = $MODEL_TECH/.. [lmc] libsm = $MODEL_TECH/libsm.sl libhm = $MODEL_TECH/libhm.sl [msg_system] suppress = 8780
最后附上调制、解调文件和激励文件如下:
cpfsk_modulate_demodulate.v,该文件放入src目录内,文件内容:
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100`timescale 1ns / 1ps //-------------------------------------------------------- // 包络检波法(非相干解调)实现FSK信号解调 //-------------------------------------------------------- module cpfsk_modulate_demodulate ( input clk , //32MHz系统时钟 input rst_n , input din , //基带信号输入,码元速率1MHz output [15:0] dout //FSK解调数据输出 ); //----------------------------------------------------- // CPFSK调制,连续相位,h=3.5 //----------------------------------------------------- wire [15:0] fsk; digital_adds fskmod ( .clk (clk ) , .rst_n (rst_n ) , .din (din ) , .dout (fsk ) ); //assign dout = fsk ; //**加上句是为了单独测试CPFSK的调整信号输出--即下面的代码都未添加时--注释掉到98行。** //-------------------------------------------------------- // 带通滤波器分为两路ASK信号 //-------------------------------------------------------- wire signed [31:0] data1, data2; wire signed [15:0] bpf1 = data1[29:14]; wire signed [15:0] bpf2 = data2[29:14]; bpf1_fir fir1 ( .aclk (clk ) , .s_axis_data_tvalid (1'b1 ) , .s_axis_data_tready ( ) , .s_axis_data_tdata (fsk ) , .m_axis_data_tvalid ( ) , .m_axis_data_tdata (data1 ) ); bpf2_fir fir2 ( .aclk (clk ) , .s_axis_data_tvalid (1'b1 ) , .s_axis_data_tready ( ) , .s_axis_data_tdata (fsk ) , .m_axis_data_tvalid ( ) , .m_axis_data_tdata (data2 ) ); //-------------------------------------------------------- // 整流,即求绝对值 //-------------------------------------------------------- reg signed [15:0] bpf1_abs, bpf2_abs; always @ (posedge clk or posedge rst_n) if (rst_n) begin bpf1_abs <= 'd0; bpf2_abs <= 'd0; end else begin if (bpf1[15]) bpf1_abs <= -bpf1; else bpf1_abs <= bpf1; if (bpf2[15]) bpf2_abs <= -bpf2; else bpf2_abs <= bpf2; end //-------------------------------------------------------- // 低通滤波得到基带信号包络 //-------------------------------------------------------- wire signed [31:0] lpf1, lpf2; lpf_fir fir3 ( .aclk (clk ) , .s_axis_data_tvalid (1'b1 ) , .s_axis_data_tready ( ) , .s_axis_data_tdata (bpf1_abs ) , .m_axis_data_tvalid ( ) , .m_axis_data_tdata (lpf1 ) ); lpf_fir fir4 ( .aclk (clk ) , .s_axis_data_tvalid (1'b1 ) , .s_axis_data_tready ( ) , .s_axis_data_tdata (bpf2_abs ) , .m_axis_data_tvalid ( ) , .m_axis_data_tdata (lpf2 ) ); //-------------------------------------------------------- // 减法得到解调信号 //-------------------------------------------------------- reg signed [15:0] sub; always @ (posedge clk or posedge rst_n) if (rst_n) sub <= 'd0; else sub <= lpf1[29:14] - lpf2[29:14]; assign dout = sub; endmodule
激励文件
cpfsk_modulate_demodulate_tb.v,该文件放sim目录中,内容如下:
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//测试文件 `timescale 1ns/1ps module cpfsk_modulate_demodulate_tb(); reg clk ; reg rst_n ; reg din ; wire [15:0] dout ; cpfsk_modulate_demodulate cpfsk_modulate_demodulate_inst( .clk (clk ) , .rst_n (rst_n ) , .din (din ) , .dout (dout ) ); initial clk = 1 ; always #16 clk = !clk ; always #1100 din=!din ; initial begin rst_n = 1 ; #100 rst_n = 0 ; din =1 ; #500000 $stop; end endmodule
最终仿真结果:
----------------------------------------------------华丽的分割线---------------------------------------------------------------------------------
附录:
仿真工程里,还提供了单独仿真FSK调制的文件和激励文件,也可在cpfsk_modulate_demodulate.v中只仿真查看fsk输出,这种方式具体见cpfsk_modulate_demodulate.v文件中注释部分描述。
先看单独的实现:
FSK调制信号的仿真
digital_adds.v和digital_adds_tb.v文件即可
digital_adds.v文件内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24//顶层 module digital_adds( input clk , input rst_n , input din , output [15:0] dout ); //----------------------------------------------------- // 载波Fc=6MHz,h=3.5,则f1=4.25MHz、f2=7.75Mhz //----------------------------------------------------- wire [14:0] phase; dds_cpfsk2 dds_cpfsk2_inst( .aclk (clk ), .s_axis_phase_tvalid (1'b1 ), .s_axis_phase_tdata ({1'b0,phase} ), .m_axis_data_tvalid ( ), .m_axis_data_tdata (dout ) ); assign phase = din ? 'd4351:'d7935 ; endmodule
digital_adds_tb.v文件内容:
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//测试文件 `timescale 1ns/1ps module digital_adds_tb(); reg clk ; reg rst_n ; reg din ; wire [15:0] dout ; digital_adds digital_adds_inst( .clk (clk ) , .rst_n (rst_n ) , .din (din ) , .dout (dout ) ); initial clk = 1; always #16 clk = !clk; initial begin //同步复位信号需要时钟上升沿检测 rst_n = 0; #100 rst_n = 1; din =1; #1000 din=0 ; #1000 din=1 ; #1000; din =0; #1000 din=0 ; #1000 din=1 ; #1000; din =0; #500000 $stop; end endmodule
仿真时,注意还要修改2个do文件。
1
2
3add wave -divider {digital_adds_tb} add wave -position insertpoint sim:/digital_adds_tb/*
compile.do修改如下:
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
26vlib work vmap work work vlog -work work glbl.v #library #vlog -work work ../../library/artix7/*.v #IP #vlog -work work ../../../source_code/ROM_IP/rom_controller.v #SourceCode vlog -work work ../src/*.v #Testbench vlog -work work digital_adds_tb.v #vsim -voptargs=+acc -L unisims_ver -L unisim -L work -Lf unisims_ver work.glbl work.digital_adds_tb vsim -voptargs=+acc work.glbl work.digital_adds_tb #Add signal into wave window do wave.do #run -all run 1ms
另,仿真时可能报类似如下的错误:
Module ‘RAMB36E1’ is not defined.
解决办法:
缺少其他文件之类的(注意看编译时的错误提示信息确定是否缺少文件问题),也可这么操作。
结束语
不夸张的话,这应该是全网最详细的关于FSK调制与解调的笔记了,如果看到这里还没复现实验结果,只有两种可能:
本次实验环境和工具说明:
猜测一下,如果复现实验的过程真有坑话,也可能是在modelsim编译、仿真这里出问题,若一语成谶,就不要借鉴文中的方法,老老实实的自行打开modelsim,一步一步的按常规做法,新建项目,添加文件…等,去完成编译和仿真查看波形,具体可自行网络查阅。
能看到末了这的,说明我们有缘分啊,浪费你一秒的时间,给个鼓励,点关注,下次更新不迷路。
最后
以上就是冷傲含羞草最近收集整理的关于FPGA 数字信号处理之 FSK 调制、解调的实现与仿真基于 verilog + ise + modelsim + matlab (保姆级)的全部内容,更多相关FPGA内容请搜索靠谱客的其他文章。
发表评论 取消回复