http://blog.163.com/fantasy_sunny/blog/static/195918212201411831053602/

4.3.5 导频插入

在接收机中,虽然利用接收到的短训练序列、长训练序列可以进行信道均衡、频率偏差校正,但符号还会存在一定的剩余频率偏差,且偏差会随时间的积累而积累,会造成所有子载波产生一定的相位偏转。因此,还需要不断地对参考相位进行跟踪。要能够实现这一功能,需要在 52 个非零子载波中插入 4 个导频符号。

经过符号调制后的signal和data域数据,将二者合并,输入到导频插入模块。每48个分成一组,每一组将对应一个OFDM符号。4 个导频对应到 -21,-7, 7和 21这4 个子载波上,对应中心频率的0号子载波上填充零值。插入的 4 个导频信号一次为 1,1,1,-1。4个导频信号的极性需要根据 【规定序列】 作相应的变化。

当规定序列为1时,对应导频是1,1,1,-1;当规定序列是-1时,对应导频为-1,-1,-1,1。

规定序列是 IEEE 802.11a标准所规定的扰码器来生成的。如下图:

规定序列(扰码器生成模块verilog代码):

 

`timescale 1ns / 10ps
//
// Create Date: 14:01:46 10/13/2014
// Design Name: pilot_insertion
// Module Name: PI_scrambler
// Project Name: OFDM base on Xilinx KC705
// Description: OFDM 导频模块中的扰码器,符合IEEE 802.11a 标准。
// Revision: 1.0
// Copyright: 《基于xlinx FPGA的OFDM通信系统基带设计》
//

module PI_scrambler(
EN,
RST,
OUT
);
input EN;
input RST;
output OUT;

reg OUT;
reg [7:1] SCRAMBLER;

always @ (negedge RST or posedge EN)
begin
if(!RST)
begin
OUT <= 0;
SCRAMBLER <= 7'b1111111;
end
else
begin
OUT <= SCRAMBLER [7] + SCRAMBLER [4];
SCRAMBLER <= { SCRAMBLER[6:1], SCRAMBLER [7] + SCRAMBLER [4] };
end

end

endmodule

代码重要部分:

导频模块实现框图:


由于导频插入模块之后是IFFT模块,因此在本模块还实现了对数据顺序的变换,使其符合IFFT输入要求。

例如,当使用64点的IFFT时,输入的49个数据(标号为0~47),首先按照如下公式进行变换,映射为-26~26,其中标号-21,-7,7,21即为插入导频处(k为输入数据标号):

根据协议中对IFFT输入端口映射的规定,将变换后的M(k)为1 ~ 26的子载波映射到 IFFT 的输入端口 1 ~ 26, M(k)为-26~-1的子载波映射到 IFFT 的端口 38 ~ 63,而剩下的端口 27 ~ 37 和 0 则为零值。如下图:

插入都导频的位置-21,-7,7,21 分别对应到 IFFT 的输入端口 43,57,1,7。编程实现时,根据导频极性,在这4个位置插入导频。

所以,结合上述两步。写入RAM中的数据标号的变换公式,如下图所示:

verilog实现代码:

 

`timescale 1ns / 10ps
//
// Create Date: 11:26:21 10/13/2014
// Design Name: pilot_insertion
// Module Name: data_pilot_insertion
// Project Name: OFDM base on Xilinx KC705
// Description: OFDM 导频插入模块,符合IEEE 802.11a 标准。
//本模块之后是要进行IFFT,所以在本模块中,已经通过ROM来输出符合IFFT输入的数据顺序要求。(64点 IFFT)
//主要功能是:按OFDM符号来插入4个对应极性的导频,然后将52个数据按照IFFT的输入顺序进行排列存入RAM。
// Revision: 1.0
// Copyright: 《基于xlinx FPGA的OFDM通信系统基带设计》
//

module data_pilot_insertion (DPI_DIN_RE, DPI_DIN_IM, INDEX_IN, DPI_ND, DPI_START, DPI_RST,
DPI_CLK, DPI_RE, DPI_IM, DPI_RDY);

input [7:0] DPI_DIN_RE;
input [7:0] DPI_DIN_IM;
input [5:0] INDEX_IN;
input DPI_ND;
input DPI_START;
input DPI_RST;
input DPI_CLK;
output [7:0] DPI_RE;
output [7:0] DPI_IM;
output DPI_RDY;

//******************************************************************************//

reg [7:0] DIN_RE; // 输入数据实部缓存
reg [7:0] DIN_IM; // 输入数据虚部缓存
reg ND; // 输入使能信号寄存器
reg [5:0] INDEX; // 输入数据标号缓存
reg [6:0] WA; // DPI_RAM_RE/IM的写地址缓存
reg [7:0] RAMR_DIN; // DPI_RAM_RE的输入缓存
reg [7:0] RAMI_DIN; // DPI_RAM_IM的输入缓存
reg REN; // DPI_RAM_RE/IM的读使能信号寄存器
reg WEN; // DPI_RAM_RE/IM的写使能信号寄存器
reg WAC; // DPI_RAM_RE/IM的写地址控制藕偶拇嫫?
reg PIEN; // 导频插入使能信号寄存器
reg [3:0] STATE; // 导频插入处理状态机状态寄存器
reg DOUT_EN; // 模块输出使能信号寄存器
reg [7:0] DPI_RE; // 模块输出数据实部寄存器
reg [7:0] DPI_IM; // 模块输出数据虚部寄存器
reg DPI_RDY; // 模块输出有效信号寄存器

wire [6:0] RA; // DPI_RAM_RE/IM的读地址信号
wire [7:0] RAMR_DOUT; // DPI_RAM_RE的输入信号
wire [7:0] RAMI_DOUT; // DPI_RAM_IM的输入信号
wire RST;
wire PPC_RST;

assign RST = ~DPI_RST; // IP core的复位信号,高电平有效
assign PPC_RST = RST | DPI_START; // DPI_PPC既由全局复位信号控制,在新帧输入时也需复位

/**********************************************************************************/
/**************************** 输入信号缓存 ****************************/
//为保证模块所有输入信号同步,在模块输入端口为所有信号加1级缓存
always @ (negedge DPI_RST or posedge DPI_CLK)
if(!DPI_RST)
begin
DIN_RE <= 8'b00000000;
DIN_IM <= 8'b00000000;
ND <= 1'b0;
INDEX <= 6'b000000;
end

else
begin
if (DPI_ND)
begin
DIN_RE <= DPI_DIN_RE;
DIN_IM <= DPI_DIN_IM;
ND <= DPI_ND;
INDEX <= INDEX_IN;
end
else
begin
DIN_RE <= 8'b00000000;
DIN_IM <= 8'b00000000;
ND <= 1'b0;
INDEX <= 6'b000000;
end
end

/**********************************************************************************/
/**************************** DPI_RAM实例化 ****************************/
//两块1024bits(128×8bits)的双口块RAM,作为模块的存储器(数据实部和虚部各用一块),
//存放调整好顺序的数据信号和导频信号。为了实时处理数据的需要,RAM的存储深度为两个
//symbol的长度,每两个symbol依次写入前一半和后一半的地址空间中,保证前一symbol的读出
//与后一symbol的写入不发生冲突

dpi_ram DPI_RAM_RE (
.addra(WA),
.addrb(RA),
.clka(DPI_CLK),
.clkb(DPI_CLK),
.dina(RAMR_DIN),
.doutb(RAMR_DOUT),
.enb(REN),
.rstb(RST),
.wea(WEN) );

dpi_ram DPI_RAM_IM (
.addra(WA),
.addrb(RA),
.clka(DPI_CLK),
.clkb(DPI_CLK),
.dina(RAMI_DIN),
.doutb(RAMI_DOUT),
.enb(REN),
.rstb(RST),
.wea(WEN) );

/**********************************************************************************/
/******************* 导频极性控制信号生成模块实例化 *********************/
//实际上是一个初始状态为全“1”的扰码器,用来生成导频极性控制信号,如果输出“0”,则
//意味着4个导频信号的极性为“1、1、1、-1”,若输出为“1”,则表明导频信号的极性应为“-1、
//1、1、1”。
wire PPC_OUT;

PI_scrambler DPI_PPC (
.EN(ND), //ND信号作为DPI_PPC的工作触发信号。需要DPI_PPC每一个symbol
.RST(~PPC_RST), //输出一个极性控制信号,而ND每个Symbol拉高1次,且比DPI_START
.OUT(PPC_OUT) ); //(用来控制DPI_PPC的复位)晚一个周期拉高。

/**********************************************************************************/
/******************* 数据顺序调整和导频信号插入 ***********************/

always @ (negedge DPI_RST or posedge DPI_CLK)
if (!DPI_RST)
begin
WAC <= 1'b0;
WA <= 7'b0000000;
WEN <= 1'b0;
RAMR_DIN <= 8'b00000000;
RAMI_DIN <= 8'b00000000;
PIEN <= 1'b0;
STATE <= 4'b0001;
REN <= 1'b0;
DOUT_EN <= 1'b0;
end
else
begin
if (ND) //在输入使能信号的控制下,待处理数据经过地址变换后写入DPI_RAM_RE/IM
begin
WA[6] <= WAC; //将WAC信号作为RAM写地址缓存的最高位以控制数据写入RAM的不同部分,WAC
case(INDEX) //为0时写入RAM的低64bytes,反之,写入RAM的高64bytes
0,1,2,3,4 : //对输入数据标识INDEX进行处理生成相应数据的写地址,从而将输入数据按照
WA[5:0] <= INDEX + 38 ; //所需调整的顺序直接写入RAMs中
5,6,7,8,9,10,11,12,13,14,15,16,17 :
WA[5:0] <= INDEX + 39 ;
18,19,20,21,22,23 :
WA[5:0] <= INDEX + 40 ;
24,25,26,27,28,29 :
WA[5:0] <= INDEX - 23 ;
30,31,32,33,34,35,36,37,38,39,40,41,42 :
WA[5:0] <= INDEX - 22 ;
43,44,45,46,47 :
WA[5:0] <= INDEX - 21 ;
default :
WA[5:0] <= 0;
endcase

WEN <= 1'b1; //生成写地址信号的同时,将写使能信号置高,并将数据写入RAMs的数据写入寄存器
RAMR_DIN <= DIN_RE;
RAMI_DIN <= DIN_IM;

if (INDEX == 47)
PIEN <= 1'b1; //数据写入操作完成后,将PIEN拉高,模块开始进行导频插入操作
end

else if (PIEN) //在PIEN的控制下,导频信号被写入RAM的相应地址空间中
if (!PPC_OUT) //具体插入导频的极性由PPC_OUT控制,其值为0时插入1、-1、1、1
case (STATE) //插入过程由一个Moore有限状态机来实现
4'b0001: //STATE为4'b0001、4'b0010、4'b0100、4'b1000时,将各个状态应插入的导频信号及其对应
begin//的地址信号写入RAM的写入寄存器和写地址寄存器中,同时将写使能信号拉高,状态也相应
WA[5:0] <= 7; //转入下一个
RAMR_DIN <= 8'b01000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b0010;
end
4'b0010:
begin
WA[5:0] <= 21;
RAMR_DIN <= 8'b11000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b0100;
end
4'b0100:
begin
WA[5:0] <= 43;
RAMR_DIN <= 8'b01000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b1000;
end
4'b1000:
begin
WA[5:0] <= 57;
RAMR_DIN <= 8'b01000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b0001;
PIEN <= 1'b0; //第4个导频输入完成时,WAC取反,准备下一Symbol数据的输入,同时将导频插入使能信号
REN <= 1'b1; //拉低,完成这个symbol的导频插入操作。并将读使能信号拉高,以开始完成处理的数据的
WAC <= ~WAC; //输出
end
endcase
else //PPC_OUT为1时插入-1、1、-1、-1
case (STATE)
4'b0001:
begin
WA[5:0] <= 7;
RAMR_DIN <= 8'b11000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b0010;
end
4'b0010:
begin
WA[5:0] <= 21;
RAMR_DIN <= 8'b01000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b0100;
end
4'b0100:
begin
WA[5:0] <= 43;
RAMR_DIN <= 8'b11000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b1000;
end
4'b1000:
begin
WA[5:0] <= 57;
RAMR_DIN <= 8'b11000000;
RAMI_DIN <= 8'b00000000;
STATE <= 4'b0001;
PIEN <= 1'b0;
REN <= 1'b1;
WAC <= ~WAC;
end
endcase
else
begin
WA[5:0] <= 10'b000000;
WEN <= 1'b0;
RAMR_DIN <= 8'b00000000;
RAMI_DIN <= 8'b00000000;
end

if(RA==63 || RA==127) //根据读地址信号判断读操作是否完成,以将读使能信号拉低。注意,由于每2个symbol
REN <= 1'b0; //的数据共用一个存储器,所以它们的读操作完成对应不同的RA值

if(REN) //数据读出存储器
DOUT_EN <= 1'b1; //在读出使能信号的控制下RAM开始输出数据,同时将输出使能信号拉高。因为IP核输出
else //数据刚好比读使能信号晚一个时钟,因此与第一级输出使能信号同步
DOUT_EN <= 1'b0;
end

/**********************************************************************************/
/**************************** DPI_COUNT实例化 ****************************/
//周期为128的计数器单元,输出计数信号作为DPI_RAM的读地址信号,帮助完成处理的数据依次读出

counter_128 DPI_RAGEN (
.q(RA), //计数器单元的输出作为RAMs的读地址信号,控制数据按顺序读出
.clk(DPI_CLK),
.ce(REN), //读使能信号作为计数器单元的时钟使能信号以控制其工作
.sclr(RST) );

/**********************************************************************************/
/**************************** 数据输出控制 ****************************/

always @ (negedge DPI_RST or posedge DPI_CLK)
if(!DPI_RST)
begin
DPI_RE <= 8'b00000000;
DPI_IM <= 8'b00000000;
DPI_RDY <= 1'b0;
end
else
begin
if (DOUT_EN) //数据数出
begin //在输出使能信号的控制下将数据DINT_RAM_2输出的数据写入其
DPI_RE <= RAMR_DOUT; //输出寄存器中,同时将这一级的输出有效信号拉高
DPI_IM <= RAMI_DOUT;
DPI_RDY <= 1'b1;
end
else
begin
DPI_RE <= 8'b00000000;
DPI_IM <= 8'b00000000;
DPI_RDY <= 1'b0;
end
end

endmodule

4.3.5 导频插入相关推荐

  1. 单载波频域均衡matlab仿真,包括卷积编码维特比译码,矩阵交织,QPSK调制解调,导频插入,MMSE-FDE频域均衡

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 频域均衡是从校正系统的频率特性出发,利用一个可调滤波器的频率的频率特性去补偿信道或系统的频率特性,使 ...

  2. OFDM系统Simulink仿真,包括RS编译码,16qam,循环前缀,导频插入,串并并串等模块

    目录 1.算法概述 2.仿真效果 3.MATLAB仿真源码 1.算法概述 在通信系统中,信道所能提供的带宽通常比传送一路信号所需的带宽要宽得多.如果一个信道只传送一路信号是非常浪费的,为了能够充分利用 ...

  3. 5G NR OFDM链路层仿真及Matlab代码实现(1):LDPC信道编译码之5G Tollbox中相关函数使用介绍

    目录 0. 写在前面 1. 信道编码 2. 经过信道(❤) 3. LDPC译码 0. 写在前面 这是OFDM链路仿真系列的第一部分. 第一次写博客,望前辈们多多指教!!! 本来想着一口气写完整个过程, ...

  4. 低信噪比MIMO SC-FDE系统中信道估计的研究与实现

    单载波频域均衡(SC-FDE技术是一种新型的宽带无线通信技术,它结合了单载波传输和正交频分复用(OFDM)的优点,具有抗衰落能力强.传输可靠的特点. 信道估计技术作为MIMO SC-FDE系统中的关键 ...

  5. 【学习笔记】OFDM中信道估计技术分析与实现

    目录 一.信道估计概念 二.信道估计作用 三.相干检测与非相干检测 (一)非相干检测 (二)相干检测 (三)注意 四.影响信道估计算法性能的重要因素 五.信道估计方法的划分 (一)根据处理域的不同, ...

  6. 【Python】Python 仿真OFDM发射机、信道和接收机-实现多种调制方式

    目录 1 引言 2 Python实现 2.1 初始化和定义函数 2.1.1 初始化参数 2.1.2 可视化导频插入的格式 2.1.3 定义调制和解调方式 2.1.4 定义信道 2.2 OFDM仿真过程 ...

  7. 试简述smtp通信的三个阶段的过程_通信原理简答题汇总

    模拟调制的主要方式有哪些,他们各有什么优点和缺点 AM调制:优点是接收设备简单:缺点是功率利用率低,抗干扰能力差,信号带宽较宽,频带利用率不高.因此,AM制式用于通信质量要求不高的场合,目前主要用在中 ...

  8. 基于OFDM的水声通信系统设计

    基于OFDM的水声通信系统设计 正交频分复用技术(OFDM)具有抗频率选择性衰减和提高频带利用率的良好特点.本文设计了基于OFDM技术的水声通信系统,此系统通过IFFT/FFT算法来实现,利用保护间隔 ...

  9. 【实践】多径效应CIR估计

    这周最紧要任务,写多径效应的CIR估计,故将思路历程收集于一个 blog 中,以供今后参考 文章目录 1 题目解读 2 信道估计初探 Reference 1 题目解读 首先这个任务题目就看不懂,啥叫 ...

  10. 通信原理知识点汇总1

    1.写出香农信道容量公式及所能得出的结论,和在实际生活中的体现? ①香农信道容量公式: ②结论: a.时,且时: b.时,且时: c.时,但时:(存在极限) ③实际应用中的体现: a.; 例:实时通信 ...

最新文章

  1. [Linux] PHP程序员玩转Linux系列-Linux和Windows安装nginx
  2. c语言程序设计A课程试,自学考试有关论文范文,与C语言程序设计A课程辅导相关硕士毕业论文范文...
  3. python有哪些常用的package_个人Python常用Package及其安装
  4. [面试] Thread 中 start() 和 run() 的区别都不知道,还怎么混?
  5. 需求分析的初稿出来了
  6. 【动态规划】LeetCode 63. Unique Paths II
  7. 关于一些信息学数论问题例题的讨论
  8. python安装第三方库太慢,很容易失败报错?教你如何提速
  9. 通信与信息系统专业排名全国前十的…
  10. wget 下载百度网盘文件
  11. 使用文档检查器后,think-cell 元素损坏
  12. 计算机桌面放大了,电脑桌面好像被放大了,怎么处理?
  13. [转] vagrant学习笔记 - provision
  14. 腾讯云阿里云vps nc: getnameinfo: Temporary failure in name resolution
  15. 中职双师型教师计算机培训总结,双师型教师计算机培训心得体会.docx
  16. RabbitMQ 之集群模式
  17. 基于JavaSpringboot+vue国风汉服文化交流宣传系统
  18. java-常量和变量
  19. 面向Android的开发基于Tensorflow Lite框架深度学习的应用(一)
  20. 简单日志(公开日记)

热门文章

  1. Autodesk 3ds Max 2011 / 3ds Max Design 2011)简体中文版 32位+64位
  2. SSM实现会议室预约管理系统
  3. 2020年日历电子版(打印版)_2020年日历打印版下载
  4. 实现企业微信机器人自动发消息
  5. python写入文件出现空行
  6. 【神经网络】综合篇——人工神经网络、卷积神经网络、循环神经网络、生成对抗网络
  7. 对抗神经网络(Adversarial Nets)的介绍[1]
  8. 人工智能简史—学习笔记
  9. 如何解决ueditor乱码问题
  10. js定义对象的多个属性值