我是靠谱客的博主 冷傲含羞草,最近开发中收集的这篇文章主要介绍FPGA 数字信号处理之 FSK 调制、解调的实现与仿真基于 verilog + ise + modelsim + matlab (保姆级),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

试验说明:

笔者复现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工程结构:
目录结构说明:

@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文件内容:


add wave -divider {cpfsk_modulate_demodulate_tb}
add wave -position insertpoint sim:/cpfsk_modulate_demodulate_tb/*

compile.do文件内容:

vlib 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文件内容:

[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目录内,文件内容:

`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目录中,内容如下:

//测试文件
`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文件内容:


//顶层
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文件内容:

//测试文件
`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文件。

add wave -divider {digital_adds_tb}
add wave -position insertpoint sim:/digital_adds_tb/*

compile.do修改如下:

vlib 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 数字信号处理之 FSK 调制、解调的实现与仿真基于 verilog + ise + modelsim + matlab (保姆级)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(78)

评论列表共有 0 条评论

立即
投稿
返回
顶部