一、创建工程及文件
二、发送机主要模块
1、插入导频:虽然利用接收到的段训练序列、长训练序列可以进行信道均衡、频率偏差校正,但符号还会存在一定的剩余偏差,且偏差会随着时间的累积而累积,会造成所有子载波产生一定的相位偏移。因此,还需要不断地对参考相位进行跟踪。这样,就可以将数据经过映射后写进ram里面。
2、hermitian变换
通过共轭对称变换将数据的实部和虚部分开
3、ifft模块
IFFT (Inverse Fast Fourier Transform) 就是快速傅里叶逆变换。其为OFDM技术中的一个实现方式:各个子信道的正交调制和解调可以分别通过采用IDFT(Inverse Discrete Fourier Transform)和DFT实现,在子载波数很大的系统中,可以通过采用IFFT(Inverse Fast Fourier Transform)和FFT实现,随着大规模集成电路技术和DSP技术的发展,IFFT和FFT都是非常容易实现的。
4、添加循环前缀
在水声通信中,信道中存在大量干扰,为降低误码率,在发送机中添加循环前缀,在接收机中去除循环前缀,然后将数据存储在Ram里面,再读取,可以提高数据传输的准确性。
5、16QAM模块
16QAM是指包含16种符号的QAM调制方式。
16QAM 是用两路独立的正交 4ASK 信号叠加而成,4ASK 是用多电平信号去键控载波而得到的信号。它是 2ASK 调制的推广,和 2ASK 相比,这种调制的优点在于信息传输速率高。
16QAM是利用多进制振幅键控(MASK)和正交载波调制相结合产生的。
16QAM 是一种振幅相位联合键控信号。16QAM 的产生有 2 种方法:
(1)正交调幅法,它是有 2 路正交的四电平振幅键控信号叠加而成;
(2)复合相移法:它是用 2 路独立的四相位移相键控信号叠加而成
主要就是将数据映射到16qam中,再将16qam转化为ofdm编码
三、发送机主要代码
发送机主要代码如下:
module top_tra #(
parameter WIDTH = 16) //Q2.14格式,即1位符号位,1位整数位,14位小数位,归一化处理后的结果
//小数如何确定?即小数部分*2^14再转为二进制
(
input clk_10M,
input clk_2_5M,
input clk_50M,
input rst_n,
input tra_en,
output dout_valid,
output _CS,
output DOUT,
output _LDAC,
output SCLK
);
reg trig_en;
reg [8:0] tx_cnt;
wire rx_data;
wire map_pilot_valid;
wire prbs_map_valid;
wire pilot_her_valid;
wire her_ifft_valid;
wire ifft_cp_valid;
wire out_flag;
wire [5:0] map_pilot_index;
wire [5:0] ifft_cp_index;
wire [5:0] pilot_her_index;
wire [WIDTH-1:0] map_pilot_real;
wire [WIDTH-1:0] map_pilot_imag;
wire [WIDTH-1:0] pilot_her_real;
wire [WIDTH-1:0] pilot_her_imag;
wire [WIDTH-1:0] her_ifft_real;
wire [WIDTH-1:0] her_ifft_imag;
wire [WIDTH-1:0] ifft_cp_real;
wire [WIDTH-1:0] ifft_cp_imag;
wire [WIDTH-1:0] cp_dac_imag;
wire [WIDTH-1:0] cp_dac_real;
always@(posedge clk_10M) begin
if(!rst_n) begin
tx_cnt <= 1'b0;
end
else begin
if(tx_cnt == 319) begin
tx_cnt <= 1'b0;
end
else begin
tx_cnt <= tx_cnt + 1'b1;
end
end
end
always@(*) begin
if(tx_cnt < 192)
trig_en = 1'b1;
else
trig_en = 1'b0;
end
prbs15 prbs( //随机数产生
.prbs_clk(clk_10M),
.prbs_rst_n(rst_n),
.trig_en(trig_en),
.prbs15_en(tra_en),
.prbs_out(rx_data),
.dout_valid(prbs_map_valid));
QAM16_MAP map( //qam映射
.qam_clk(clk_10M),
.din_valid(prbs_map_valid),
.qam_din(rx_data),
.dout_valid(map_pilot_valid),
.qam_dout_imag(map_pilot_imag),
.qam_dout_real(map_pilot_real),
.qam_rst_n(rst_n),
.dout_index(map_pilot_index));
Insert_Pilot pilot (//导频
.pilot_clk(clk_2_5M),
.pilot_rst_n(rst_n),
.din_valid(map_pilot_valid),
.index(map_pilot_index),
.pilot_imag_din(map_pilot_imag),
.pilot_real_din(map_pilot_real),
.pilot_imag_dout(pilot_her_imag),
.pilot_real_dout(pilot_her_real),
.dout_valid(pilot_her_valid),
.dout_index(pilot_her_index));
hermitian her_ins(//厄米特变换
.her_clk(clk_2_5M),
.her_rst_n(rst_n),
.din_valid(pilot_her_valid),
.din_index(pilot_her_index),
.her_real_din(pilot_her_real),
.her_imag_din(pilot_her_imag),
.her_real_dout(her_ifft_real),
.her_imag_dout(her_ifft_imag),
.dout_valid(her_ifft_valid));
ifft_clac ifft(//ifft
.ifft_clk(clk_2_5M),
.ifft_rst_n(rst_n),
.din_valid(her_ifft_valid),
.ifft_real_din(her_ifft_real),
.ifft_imag_din(her_ifft_imag),
.dout_valid(ifft_cp_valid),
.ifft_real_dout(ifft_cp_real),
.ifft_imag_dout(ifft_cp_imag),
//.dout_exp(exp),
.dout_index(ifft_cp_index));
add_cyclic_prefix cp(//添加循环前缀
.cp_clk(clk_2_5M),
.cp_rst_n(rst_n),
.din_valid(ifft_cp_valid),
.cp_real_din(ifft_cp_real),
.cp_imag_din(ifft_cp_imag),
.din_index(ifft_cp_index),
.dout_valid(dout_valid),
.cp_real_dout(cp_dac_real//cp_real_dout
),
.cp_imag_dout(cp_imag_dout//cp_dac_imag
));
PmodDA da(//输出实部数据驱动pmodDA
.DATA(cp_dac_real),
.DA_dr