今天介绍的是使用FPGA做OFDM的调制。
首先是OFDM调制的原理图,输入数据在输入系统后首先会经过扰码环节,在数字通信中数据中长连的“0”或“1”序列会对接收机的位同步产生重要影响,通过对要发送的数据进行扰码操作,可以解决其对接收机同步的影响。扰码器的实质是一个反馈的移位寄存器,输出结果是一个m序列,将输出的m序列域输入的数据进行异或运算,从而将输入的数据搅乱。
扰码模块根据使用的生成多项式完成对输入数据的扰码操作。这里使用的扰码器是通过一个7位的反馈移位寄存器来实现的,使用的扰码器生成多项式为:
上图为扰码器的硬件实现结构图,该扰码器输出序列的周期为127,首先将扰码器的初始值设置为1011101,每来一个时钟周期将扰码器的值右移一位,同时将第七位和第四位进行异或运算,将异或的结果作为最低位的值。同时也将得到的结果和输入的数据分别进行异或运算,从而实现对输入数据的扰码操作。
扰码器程序如下所示:
s_start为启动信号,s_coder为7位移位寄存器,s_yz为第七位和第四位异或后的结果,当时在程序中因为顺序问题我写的是s_coder[0]和s_coder[3]。s_out为移位寄存器s_coder[0]的输出,data_in为输入数据,data_out为输入数据data_in与移位寄存器输出s_out异或运算的结果,即为扰码后的输出。
这里因为我没做解调所以省去了信道编码部分,在需要添加冗余的部分我才用补零来进行补充。
对于64QAM调制,如下图所示为64QAM调制原理图
这里的2到8电平转换即为星座映射(8电平为-1,-3,-5,-7,1,3,5,7)。
对于64QAM的星座图,星座图中每一个点都由6bit数据表示,所以在程序中每6bit数据映射一次,下图为verilog仿真图。
s_start为起始信号,data_in为扰码之后的输入64QAM调制的信号data_index为存储输入的6bit数据,cnt为计数器,data_index每输入一个数据cnt自加一次;index为计算6bit数据后对应的映射状态,data_i和data_q为根据(index)的映射结果I/Q信号。这里我是根据状态机来写的,index为6bit信号的计算结果,然后根据index的大小来描写状态机进行映射。最后将data_i和data_q的结果存储到fifo中,即图中的data_fifo_in。
在FPGA上已经完成了星座映射后将I、Q信号送入fifo中存储,然后通过RAM地址进行加冗余以及添加导频,从而将一个OFDM符号中星座映射后的48个数据增加至128个数据,数据都写入RAM,然后通过地址读取RAM中的数据送入IFFT变换的输入端口,以及正常输出,在FPGA上实现频域至时域的转换。
下图中data_i和data_q为星座映射后得到I、Q数据,data_fifo_in为写入fifo的数据,由图二可以看出,data_fifo_in的前八位为data_i,data_fifo_in的后八位为data_q。
下图便是将数据写入RAM,并通过地址读写增加冗余以及插入导频。rd_en为读取fifo数据使能,data_fifo_out为读取的fifo数据。ram_en为RAM使能,ram_wea为高电平时向RAM中写入数据,ram_wea为低电平时向RAM中读取数据,ram_addr为写入/读取数据的地址。data_ram_in为写入ram中的数据,增加的冗余为前38个写入的数据为0以及后37个写入数据为0。中间插入四个导频。
在前38个写入数据0后便开始写入fifo中的数据,在地址为37时(0~37)打开fifo的读使能(rd_en),此时将fifo输出端(data_fifo_out)数据赋值给RAM写入端(data_ram_in)。图中的ram_addr为43时写入的数据为导频符号,在这里导频符号我是通过类似于m序列的扰码器来进行产生的。
导频的产生:
需要插入的4个导频符号分别为1,1,1,-1。OFDM数据中插入的导频符号并不都是一样的,需要根据公式对插入的导频符号的极性进行改变,这里我用的改变导频符号极性的公式为s(x)=x7+x4+1。
公式的实质是一个扰码器,首先将扰码器的初始状态设置为1111111,根据扰码器的输出结果对导频符号的极性进行修改,若扰码器的输出结果为0,则导频符号的极性不变,若扰码器的输出结果为1,则对导频符号的极性进行修改,修改规则为1 -> -1,-1 -> 1。
图七为导频产生数据波形图,其中data_m为扰码器序列,初始状态为1111111,每当需要插入导频时m_start便会使能置1,根据m_start可以看出图中一个OFDM符号中共插入四个导频。p寄存器中便是存放的四个原始导频数据,01表示导频1,11表示导频-1。data_m_out便是最终插入OFDM符号的导频数据,即写入ram中的导频数据。
ifft变换:
在数据都在RAM中存好之后便是将ram中的数据送入IFFT变换的输入端口,此时将ram的ena使能端置为高电平ram的wea置为低电平,开始读取ram中的数据。如下图所示,ram的ena为高,ram的wea为低,ram数据输出端为douta开始输出数据。
这里OFDM一次传输128个数据,在星座映射后为48个数据,插入四个导频后为52个数据,这里选择通过补零来添加冗余,如下图所示。
在上图中,ifft_s_data_tdata为ifft变换的输入端口,ifft_s_data_tvalid为输入使能,ifft_s_data_tvalid为高时输入ifft_s_data_tdata的数据才有效。
全部0条评论
快来发表一下你的评论吧 !