基于FPGA的16QAM调制器verilog实现,包括testbench,并通过MATLAB显示FPGA输出信号的星座图

目录

1.算法仿真效果

2.verilog核心程序

3.算法涉及理论知识概要

4.完整verilog


1.算法仿真效果

matlab2022a/vivado2019.2仿真结果如下:

 将FPGA仿真的数据导出,然后在matlab中将数据通过噪声之后,可以得到如下的星座图效果。

fpga工程版本信息:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2019.2.1 (64-bit)              -->
<!--                                                         -->
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.   -->

<Project Version="7" Minor="44" Path="E:/A_FPGA_proj/project_13/project_13/project_13.xpr">
  <DefaultLaunch Dir="$PRUNDIR"/>
  <Configuration>
    <Option Name="Id" Val="618ebbc110dd42b9abe407c3328144d0"/>
    <Option Name="Part" Val="xc7vx485tffg1157-1"/>
    <Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
    <Option Name="CompiledLibDirXSim" Val=""/>
    <Option Name="CompiledLibDirModelSim" Val="$PCACHEDIR/compile_simlib/modelsim"/>
    <Option Name="CompiledLibDirQuesta" Val="$PCACHEDIR/compile_simlib/questa"/>
    <Option Name="CompiledLibDirIES" Val="$PCACHEDIR/compile_simlib/ies"/>
    <Option Name="CompiledLibDirXcelium" Val="$PCACHEDIR/compile_simlib/xcelium"/>
    <Option Name="CompiledLibDirVCS" Val="$PCACHEDIR/compile_simlib/vcs"/>
    <Option Name="CompiledLibDirRiviera" Val="$PCACHEDIR/compile_simlib/riviera"/>
    <Option Name="CompiledLibDirActivehdl" Val="$PCACHEDIR/compile_simlib/activehdl"/>
    <Option Name="BoardPart" Val=""/>
    <Option Name="ActiveSimSet" Val="sim_1"/>
    <Option Name="DefaultLib" Val="xil_defaultlib"/>
    <Option Name="ProjectType" Val="Default"/>
    <Option Name="IPOutputRepo" Val="$PCACHEDIR/ip"/>
    <Option Name="IPCachePermission" Val="read"/>
    <Option Name="IPCachePermission" Val="write"/>
    <Option Name="EnableCoreContainer" Val="FALSE"/>
    <Option Name="CreateRefXciForCoreContainers" Val="FALSE"/>
    <Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
    <Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
    <Option Name="EnableBDX" Val="FALSE"/>
    <Option Name="WTXSimLaunchSim" Val="87"/>
    <Option Name="WTModelSimLaunchSim" Val="0"/>
    <Option Name="WTQuestaLaunchSim" Val="0"/>
    <Option Name="WTIesLaunchSim" Val="0"/>
    <Option Name="WTVcsLaunchSim" Val="0"/>
    <Option Name="WTRivieraLaunchSim" Val="0"/>
    <Option Name="WTActivehdlLaunchSim" Val="0"/>
    <Option Name="WTXSimExportSim" Val="2"/>
    <Option Name="WTModelSimExportSim" Val="2"/>
    <Option Name="WTQuestaExportSim" Val="2"/>
    <Option Name="WTIesExportSim" Val="2"/>
    <Option Name="WTVcsExportSim" Val="2"/>
    <Option Name="WTRivieraExportSim" Val="2"/>
    <Option Name="WTActivehdlExportSim" Val="2"/>
    <Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
    <Option Name="XSimRadix" Val="hex"/>
    <Option Name="XSimTimeUnit" Val="ns"/>
    <Option Name="XSimArrayDisplayLimit" Val="1024"/>
    <Option Name="XSimTraceLimit" Val="65536"/>
    <Option Name="SimTypes" Val="rtl"/>
    <Option Name="SimTypes" Val="bfm"/>
    <Option Name="SimTypes" Val="tlm"/>
    <Option Name="SimTypes" Val="tlm_dpi"/>
    <Option Name="MEMEnableMemoryMapGeneration" Val="TRUE"/>
    <Option Name="DcpsUptoDate" Val="TRUE"/>

2.verilog核心程序

`timescale 1ns / 1ns
module TEST;

	reg clk;
	reg rst;
	reg start;
    wire [15:0]sin;
    wire [15:0]cos;
	wire signed[19:0]  I_com;
	wire signed[19:0]  Q_com;

	// DUT
	tops_16QAM_mod  top(
	   .clk(clk),
	   .rst(rst),
	   .start(start),
	   .sin(sin),
	   .cos(cos),
	   .I_com(I_com),
	   .Q_com(Q_com)
	   );

	initial begin
		clk = 0;
		rst = 0;
		start = 1;
		#10;
		rst = 1;
	end
	
	always #5
	clk <= ~clk;
	
integer fout1;
integer fout2;
initial begin
 fout1 = $fopen("II.txt","w");
 fout2 = $fopen("QQ.txt","w"); 
end

always @ (posedge clk)
 begin
     if(rst==1)
     begin
   	 $fwrite(fout1,"%d\n",I_com);
	 $fwrite(fout2,"%d\n",Q_com);
	 end
end

endmodule
`timescale 1ns / 1ns
module tops_16QAM_mod(
  input clk,
  input rst,
  input start,
  output [15:0]sin,
  output [15:0]cos,
  output  [19:0]  I_com,
  output  [19:0]  Q_com
  );

	// Outputs
	wire [3:0] parallel_data;
	wire       serial_in;
	wire       data_flag;
 
	integer  mixed_out;
 
	bit_signals bit_signals_U(
	   .clk       (clk),
	   .rst       (rst),
	   .enable    (start),
	   .serial_in (serial_in),
	   .data_flag (data_flag)
	   );
	   
	s2p s2p_U(
		.clk           (clk), 
		.rst           (rst), 
		.start         (start), 
		.serial_in     (serial_in),
		.data_flag     (data_flag),
		.parallel_data (parallel_data)
	);
	
	
............................................................................
	   
	mod16QAM mod16QAM_u(
      .clk(clk),
      .rst(rst),
      .start(start),
      .parallel_data(parallel_data),
      .sin(sin),
      .cos(cos),
      .I_com(I_com),
      .Q_com(Q_com)
      );
endmodule
A514

3.算法涉及理论知识概要

      16QAM全称正交幅度调制是英文Quadrature Amplitude Modulation的缩略语简称,意思是正交幅度调制,是一种数字调制方式。产生的方法有正交调幅法和复合相移法。

16QAM是指包含16种符号的QAM调制方式。
16QAM 调制解调原理方框图如右图1:
      16QAM 是用两路独立的正交 4ASK 信号叠加而成,4ASK 是用多电平信号去键控载波而得到的信号。它是 2ASK 调制的推广,和 2ASK 相比,这种调制的优点在于信息传输速率高。
正交幅度调制是利用多进制振幅键控(MASK)和正交载波调制相结合产生的。
16 进制的正交振幅调制是一种振幅相位联合键控信号。16QAM 的产生有 2 种方法:
(1)正交调幅法,它是有 2 路正交的四电平振幅键控信号叠加而成;
(2)复合相移法:它是用 2 路独立的四相位移相键控信号叠加而成。
这里采用正交调幅法。
        串/并变换器将速率为Rb的二进制码元序列分为两路,速率为Rb/2.2-4电平变换为Rb/2 的二进制码元序列变成速率为RS=Rb/log216 的 4 个电平信号,4 电平信号与正交载波相乘,完成正交调制,两路信号叠加后产生 16QAM信号.在两路速率为Rb/2 的二进制码元序列中,经 2-4 电平变换器输出为 4 电平信号,即M=16.经 4 电平正交幅度调制和叠加后,输出 16 个信号状态,即 16QAM.
RS=Rb/log216=RB/4.
2. 16QAM 解调原理
       16QAM 信号采取正交相干解调的方法解调,解调器首先对收到的 16QAM 信号进行正交相干解调,一路与 cos ω c t 相乘,一路与 sin ω c t 相乘。然后经过低通滤波器,低通滤波器 LPF 滤除乘法器产生的高频分量,获得有用信号,低通滤波器LPF 输出经抽样判决可恢复出电平信号。

4.完整verilog

V

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱C编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值