基于FPGA的OFDM-BPSK链路verilog实现,开发平台为quartusii
Posted fpga和matlab
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于FPGA的OFDM-BPSK链路verilog实现,开发平台为quartusii相关的知识,希望对你有一定的参考价值。
目录
一、理论基础
设OFDM信号发射时间周期为[0,T],子载波数为N,N也是符号序列的时间间隔。可以证明满足子载波正交的条件为:=1/T。(式中为子载波的频率间隔。)输入数据流首先被QAM调制器调制,这里其实是完成一个星座点的映射过程,并没有进行频谱搬移。经过星座映射后得到的符号,存在两个相互正交的分量和。设。所以再进行OFDM调制进行频谱搬移后,已调信号的数学表达式为:
由上式可知,恰好是的逆离散傅里叶变换(IDFT)。所以OFDM调制可以由IDFT实现,解调可以由DFT实现。
对于调制过程,输入数据流首先被QAM调制器调制,这里其实是完成一个星座点的映射过程,并没有进行频谱搬移。得到了一个复符号流d[0],d[1],…,d[N-1],复符号流通过串/并变换,得到一系列并行的QAM符号d[0],d[1],…,d[N-1]。经过IFFT变换,得到一系列并行的符号流,,…,,再将它们经过并/串变换,得到一串串行的符号流,,…,。由于此时符号流为离散的,所以要经过D/A转换,将其变为时间上连续的信号。最后再将信号搬移到射频。解调过程正好相反。
应此我们设计的数字系统是一个OFDM 通信系统中的基带数据处理部分,就是不包括变频,射频电路部分的设计,甚至没有加入同步的部分,而是只包括信道编码、交织、星座映射、FFT 和插入循环前缀的部分。。下面叙述一下发射和接收端的具体结构。
二、核心程序
`timescale 1 ns / 1 ps
module FFT_s2p(
i_clk,
i_rst,
i_I,
i_Q,
o_flag,
o_dout1,
o_dout2,
o_dout0,
test1,
test2
);
input i_clk;
input i_rst;
input signed[7:0]i_I;
input signed[7:0]i_Q;
output o_flag;
output [31:0]o_dout1;
output [31:0]o_dout2;
output [31:0]o_dout0;
output signed[7:0]test1;
output signed[7:0]test2;
reg signed[7:0]rt1,it1;
reg signed[7:0]rt2,it2;
reg signed[7:0]rt3,it3;
reg signed[7:0]rt4,it4;
reg signed[7:0]rt5,it5;
reg signed[7:0]rt6,it6;
reg signed[7:0]rt7,it7;
reg signed[7:0]rt8,it8;
reg signed[7:0]rt9,it9;
reg signed[7:0]rt10,it10;
reg signed[7:0]rt11,it11;
reg signed[7:0]rt12,it12;
reg signed[7:0]rt13,it13;
reg signed[7:0]rt14,it14;
reg signed[7:0]rt15,it15;
reg signed[7:0]rt16,it16;
reg signed[7:0]rt17,it17;
reg signed[7:0]rt18,it18;
reg signed[7:0]rt19,it19;
reg signed[7:0]rt20,it20;
reg signed[7:0]rt21,it21;
reg signed[7:0]rt22,it22;
reg signed[7:0]rt23,it23;
reg signed[7:0]rt24,it24;
reg signed[7:0]rt25,it25;
reg signed[7:0]rt26,it26;
reg signed[7:0]rt27,it27;
reg signed[7:0]rt28,it28;
reg signed[7:0]rt29,it29;
reg signed[7:0]rt30,it30;
reg signed[7:0]rt31,it31;
reg signed[7:0]rt32,it32;
reg signed[7:0]r1,i1;
reg signed[7:0]r2,i2;
reg signed[7:0]r3,i3;
reg signed[7:0]r4,i4;
reg signed[7:0]r5,i5;
reg signed[7:0]r6,i6;
reg signed[7:0]r7,i7;
reg signed[7:0]r8,i8;
reg signed[7:0]r9,i9;
reg signed[7:0]r10,i10;
reg signed[7:0]r11,i11;
reg signed[7:0]r12,i12;
reg signed[7:0]r13,i13;
reg signed[7:0]r14,i14;
reg signed[7:0]r15,i15;
reg signed[7:0]r16,i16;
reg signed[7:0]r17,i17;
reg signed[7:0]r18,i18;
reg signed[7:0]r19,i19;
reg signed[7:0]r20,i20;
reg signed[7:0]r21,i21;
reg signed[7:0]r22,i22;
reg signed[7:0]r23,i23;
reg signed[7:0]r24,i24;
reg signed[7:0]r25,i25;
reg signed[7:0]r26,i26;
reg signed[7:0]r27,i27;
reg signed[7:0]r28,i28;
reg signed[7:0]r29,i29;
reg signed[7:0]r30,i30;
reg signed[7:0]r31,i31;
reg signed[7:0]r32,i32;
reg[4:0]cnt;
reg o_flag;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
o_flag <= 1'b0;
cnt <= 5'd0;
r1<= 0;i1<= 0;
r2<= 0;i2<= 0;
r3<= 0;i3<= 0;
r4<= 0;i4<= 0;
r5<= 0;i5<= 0;
r6<= 0;i6<= 0;
r7<= 0;i7<= 0;
r8<= 0;i8<= 0;
r9<= 0;i9<= 0;
r10<= 0;i10<= 0;
r11<= 0;i11<= 0;
r12<= 0;i12<= 0;
r13<= 0;i13<= 0;
r14<= 0;i14<= 0;
r15<= 0;i15<= 0;
r16<= 0;i16<= 0;
r17<= 0;i17<= 0;
r18<= 0;i18<= 0;
r19<= 0;i19<= 0;
r20<= 0;i20<= 0;
r21<= 0;i21<= 0;
r22<= 0;i22<= 0;
r23<= 0;i23<= 0;
r24<= 0;i24<= 0;
r25<= 0;i25<= 0;
r26<= 0;i26<= 0;
r27<= 0;i27<= 0;
r28<= 0;i28<= 0;
r29<= 0;i29<= 0;
r30<= 0;i30<= 0;
r31<= 0;i31<= 0;
r32<= 0;i32<= 0;
rt1<= 0;it1<= 0;
rt2<= 0;it2<= 0;
rt3<= 0;it3<= 0;
rt4<= 0;it4<= 0;
rt5<= 0;it5<= 0;
rt6<= 0;it6<= 0;
rt7<= 0;it7<= 0;
rt8<= 0;it8<= 0;
rt9<= 0;it9<= 0;
rt10<= 0;it10<= 0;
rt11<= 0;it11<= 0;
rt12<= 0;it12<= 0;
rt13<= 0;it13<= 0;
rt14<= 0;it14<= 0;
rt15<= 0;it15<= 0;
rt16<= 0;it16<= 0;
rt17<= 0;it17<= 0;
rt18<= 0;it18<= 0;
rt19<= 0;it19<= 0;
rt20<= 0;it20<= 0;
rt21<= 0;it21<= 0;
rt22<= 0;it22<= 0;
rt23<= 0;it23<= 0;
rt24<= 0;it24<= 0;
rt25<= 0;it25<= 0;
rt26<= 0;it26<= 0;
rt27<= 0;it27<= 0;
rt28<= 0;it28<= 0;
rt29<= 0;it29<= 0;
rt30<= 0;it30<= 0;
rt31<= 0;it31<= 0;
rt32<= 0;it32<= 0;
end
else begin
cnt <= cnt + 5'd1;
rt1<= i_I;
rt2<= rt1;
rt3<= rt2;
rt4<= rt3;
rt5<= rt4;
rt6<= rt5;
rt7<= rt6;
rt8<= rt7;
rt9<= rt8;
rt10<= rt9;
rt11<= rt10;
rt12<= rt11;
rt13<= rt12;
rt14<= rt13;
rt15<= rt14;
rt16<= rt15;
rt17<= rt16;
rt18<= rt17;
rt19<= rt18;
rt20<= rt19;
rt21<= rt20;
rt22<= rt21;
rt23<= rt22;
rt24<= rt23;
rt25<= rt24;
rt26<= rt25;
rt27<= rt26;
rt28<= rt27;
rt29<= rt28;
rt30<= rt29;
rt31<= rt30;
rt32<= rt31;
it1<= i_Q;
it2<= it1;
it3<= it2;
it4<= it3;
it5<= it4;
it6<= it5;
it7<= it6;
it8<= it7;
it9<= it8;
it10<= it9;
it11<= it10;
it12<= it11;
it13<= it12;
it14<= it13;
it15<= it14;
it16<= it15;
it17<= it16;
it18<= it17;
it19<= it18;
it20<= it19;
it21<= it20;
it22<= it21;
it23<= it22;
it24<= it23;
it25<= it24;
it26<= it25;
it27<= it26;
it28<= it27;
it29<= it28;
it30<= it29;
it31<= it30;
it32<= it31;
if(cnt == 3)
begin
r1<= rt1;
r2<= rt2;
r3<= rt3;
r4<= rt4;
r5<= rt5;
r6<= rt6;
r7<= rt7;
r8<= rt8;
r9<= rt9;
r10<= rt10;
r11<= rt11;
r12<= rt12;
r13<= rt13;
r14<= rt14;
r15<= rt15;
r16<= rt16;
r17<= rt17;
r18<= rt18;
r19<= rt19;
r20<= rt20;
r21<= rt21;
r22<= rt22;
r23<= rt23;
r24<= rt24;
r25<= rt25;
r26<= rt26;
r27<= rt27;
r28<= rt28;
r29<= rt29;
r30<= rt30;
r31<= rt31;
r32<= rt32;
i1<= it1;
i2<= it2;
i3<= it3;
i4<= it4;
i5<= it5;
i6<= it6;
i7<= it7;
i8<= it8;
i9<= it9;
i10<= it10;
i11<= it11;
i12<= it12;
i13<= it13;
i14<= it14;
i15<= it15;
i16<= it16;
i17<= it17;
i18<= it18;
i19<= it19;
i20<= it20;
i21<= it21;
i22<= it22;
i23<= it23;
i24<= it24;
i25<= it25;
i26<= it26;
i27<= it27;
i28<= it28;
i29<= it29;
i30<= it30;
i31<= it31;
i32<= it32;
o_flag <= ~o_flag;
end
else begin
r1<= r1;
r2<= r2;
r3<= r3;
r4<= r4;
r5<= r5;
r6<= r6;
r7<= r7;
r8<= r8;
r9<= r9;
r10<= r10;
r11<= r11;
r12<= r12;
r13<= r13;
r14<= r14;
r15<= r15;
r16<= r16;
r17<= r17;
r18<= r18;
r19<= r19;
r20<= r20;
r21<= r21;
r22<= r22;
r23<= r23;
r24<= r24;
r25<= r25;
r26<= r26;
r27<= r27;
r28<= r28;
r29<= r29;
r30<= r30;
r31<= r31;
r32<= r32;
i1<= i1;
i2<= i2;
i3<= i3;
i4<= i4;
i5<= i5;
i6<= i6;
i7<= i7;
i8<= i8;
i9<= i9;
i10<= i10;
i11<= i11;
i12<= i12;
i13<= i13;
i14<= i14;
i15<= i15;
i16<= i16;
i17<= i17;
i18<= i18;
i19<= i19;
i20<= i20;
i21<= i21;
i22<= i22;
i23<= i23;
i24<= i24;
i25<= i25;
i26<= i26;
i27<= i27;
i28<= i28;
i29<= i29;
i30<= i30;
i31<= i31;
i32<= i32;
o_flag <= o_flag;
end
end
end
wire signed[15:0]rr1,ii1;
wire signed[15:0]rr2,ii2;
wire signed[15:0]rr3,ii3;
wire signed[15:0]rr4,ii4;
wire signed[15:0]rr5,ii5;
wire signed[15:0]rr6,ii6;
wire signed[15:0]rr7,ii7;
wire signed[15:0]rr8,ii8;
wire signed[15:0]rr9,ii9;
wire signed[15:0]rr10,ii10;
wire signed[15:0]rr11,ii11;
wire signed[15:0]rr12,ii12;
wire signed[15:0]rr13,ii13;
wire signed[15:0]rr14,ii14;
wire signed[15:0]rr15,ii15;
wire signed[15:0]rr16,ii16;
wire signed[15:0]rr17,ii17;
wire signed[15:0]rr18,ii18;
wire signed[15:0]rr19,ii19;
wire signed[15:0]rr20,ii20;
wire signed[15:0]rr21,ii21;
wire signed[15:0]rr22,ii22;
wire signed[15:0]rr23,ii23;
wire signed[15:0]rr24,ii24;
wire signed[15:0]rr25,ii25;
wire signed[15:0]rr26,ii26;
wire signed[15:0]rr27,ii27;
wire signed[15:0]rr28,ii28;
wire signed[15:0]rr29,ii29;
wire signed[15:0]rr30,ii30;
wire signed[15:0]rr31,ii31;
wire signed[15:0]rr32,ii32;
assign rr1 = 126*r1-25*i1;
assign ii1 = 25*r1+126*i1;
assign rr2 = 118*r2-49*i2;
assign ii2 = 49*r2+118*i2;
assign rr3 = 106*r3-71*i3;
assign ii3 = 71*r3+106*i3;
assign rr4 = 91*r4-91*i4;
assign ii4 = 91*r4+91*i4;
assign rr5 = 71*r5-106*i5;
assign ii5 = 106*r5+71*i5;
assign rr6 = 49*r6-118*i6;
assign ii6 = 118*r6+49*i6;
assign rr7 = 25*r7-126*i7;
assign ii7 = 126*r7+25*i7;
assign rr8 = 0*r8-128*i8;
assign ii8 = 128*r8+0*i8;
assign rr9 = -25*r9-126*i9;
assign ii9 = 126*r9+-25*i9;
assign rr10 = -49*r10-118*i10;
assign ii10 = 118*r10+-49*i10;
assign rr11 = -71*r11-106*i11;
assign ii11 = 106*r11+-71*i11;
assign rr12 = -91*r12-91*i12;
assign ii12 = 91*r12+-91*i12;
assign rr13 = -106*r13-71*i13;
assign ii13 = 71*r13+-106*i13;
assign rr14 = -118*r14-49*i14;
assign ii14 = 49*r14+-118*i14;
assign rr15 = -126*r15-25*i15;
assign ii15 = 25*r15+-126*i15;
assign rr16 = -128*r16-0*i16;
assign ii16 = 0*r16+-128*i16;
assign rr17 = -126*r17--25*i17;
assign ii17 = -25*r17+-126*i17;
assign rr18 = -118*r18--49*i18;
assign ii18 = -49*r18+-118*i18;
assign rr19 = -106*r19--71*i19;
assign ii19 = -71*r19+-106*i19;
assign rr20 = -91*r20--91*i20;
assign ii20 = -91*r20+-91*i20;
assign rr21 = -71*r21--106*i21;
assign ii21 = -106*r21+-71*i21;
assign rr22 = -49*r22--118*i22;
assign ii22 = -118*r22+-49*i22;
assign rr23 = -25*r23--126*i23;
assign ii23 = -126*r23+-25*i23;
assign rr24 = 0*r24--128*i24;
assign ii24 = -128*r24+0*i24;
assign rr25 = 25*r25--126*i25;
assign ii25 = -126*r25+25*i25;
assign rr26 = 49*r26--118*i26;
assign ii26 = -118*r26+49*i26;
assign rr27 = 71*r27--106*i27;
assign ii27 = -106*r27+71*i27;
assign rr28 = 91*r28--91*i28;
assign ii28 = -91*r28+91*i28;
assign rr29 = 106*r29--71*i29;
assign ii29 = -71*r29+106*i29;
assign rr30 = 118*r30--49*i30;
assign ii30 = -49*r30+118*i30;
assign rr31 = 126*r31--25*i31;
assign ii31 = -25*r31+126*i31;
assign rr32 = 128*r32-0*i32;
assign ii32 = 0*r32+128*i32;
assign test1 = r22;
assign test2 = i22;
assign o_dout1 = ~rr32[15],~rr31[15],~rr30[15],~rr29[15],~rr28[15],~rr27[15],~rr26[15],~rr25[15],
~rr24[15],~rr23[15],~rr22[15],~rr21[15],~rr20[15],~rr19[15],~rr18[15],~rr17[15],
~rr16[15],~rr15[15],~rr14[15],~rr13[15],~rr12[15],~rr11[15],~rr10[15],~rr9[15],
~rr8[15] ,~rr7[15] ,~rr6[15] ,~rr5[15] ,~rr4[15] ,~rr3[15] ,~rr2[15] ,~rr1[15];
assign o_dout2 = ~ii32[15],~ii31[15],~ii30[15],~ii29[15],~ii28[15],~ii27[15],~ii26[15],~ii25[15],
~ii24[15],~ii23[15],~ii22[15],~ii21[15],~ii20[15],~ii19[15],~ii18[15],~ii17[15],
~ii16[15],~ii15[15],~ii14[15],~ii13[15],~ii12[15],~ii11[15],~ii10[15],~ii9[15],
~ii8[15] ,~ii7[15] ,~ii6[15] ,~ii5[15] ,~ii4[15] ,~ii3[15] ,~ii2[15] ,~ii1[15];
assign o_dout0 = ~rr32[15]^ii32[15],rr31[15]^ii31[15],rr30[15]^ii30[15],rr29[15]^ii29[15],
rr28[15]^ii28[15],rr27[15]^ii27[15],rr26[15]^ii26[15],rr25[15]^ii25[15],
rr24[15]^ii24[15],rr23[15]^ii23[15],rr22[15]^ii22[15],rr21[15]^ii21[15],
rr20[15]^ii20[15],rr19[15]^ii19[15],rr18[15]^ii18[15],rr17[15]^ii17[15],
rr16[15]^ii16[15],rr15[15]^ii15[15],rr14[15]^ii14[15],rr13[15]^ii13[15],
rr12[15]^ii12[15],rr11[15]^ii11[15],rr10[15]^ii10[15],rr9[15]^ii9[15],
rr8[15]^ii8[15],rr7[15]^ii7[15],rr6[15]^ii6[15],rr5[15]^ii5[15],
rr4[15]^ii4[15],rr3[15]^ii3[15],rr2[15]^ii2[15],rr1[15]^ii1[15];
endmodule
`timescale 1 ns / 1 ps
module tops(
i_clk,
i_rst,
o_signals,
o_sp,
o_spflag,
o_Dreal,
o_Dimag,
o_flag_fft,
o_doutfft1,
o_Rec
);
input i_clk;
input i_rst;
output o_signals;
output[31:0]o_sp;
output o_spflag;
output signed[8:0]o_Dreal;
output signed[8:0]o_Dimag;
output o_flag_fft;
output[31:0]o_doutfft1;
output o_Rec;
signals signals_u(
.i_clk (i_clk),
.i_rst (i_rst),
.o_dout (o_signals)
);
//Transform
s2p s2p_u(
.i_clk (i_clk),
.i_rst (i_rst),
.i_din (o_signals),
.o_dout (o_sp),
.o_flag (o_spflag)
);
//IFFT & P2S
IFFTs_p2s IFFTs_p2s_u(
.i_clk (i_clk),
.i_rst (i_rst),
.i_en (o_spflag),
.i_dn (o_sp),
.o_Dreal (o_Dreal),
.o_Dimag (o_Dimag)
);
//Reciver
//FFT & S2P
FFT_s2p FFT_s2p_u(
.i_clk (i_clk),
.i_rst (i_rst),
.i_I (o_Dreal[7:0]),
.i_Q (o_Dimag[7:0]),
.o_flag (o_flag_fft),
.o_dout1 (o_doutfft1),
.o_dout2 (),
.o_dout0 (),
.test1 (),
.test2 ()
);
//P2SA01-119
p2s p2s_u(
.i_clk (i_clk),
.i_rst (i_rst),
.i_din (o_doutfft1),
.i_en (o_flag_fft),
.o_dout (o_Rec)
);
endmodule
三、测试结果
根据上面的设计原理,使用BPSK作为映射方式,最后获得如下的仿真结果:
以上是关于基于FPGA的OFDM-BPSK链路verilog实现,开发平台为quartusii的主要内容,如果未能解决你的问题,请参考以下文章
基于vivado(语言Verilog)的FPGA学习——FPGA理论知识
IDCT-FPGA基于FPGA的IDCT变换的verilog实现
FPGA教程案例45图像案例5——基于FPGA的图像均值滤波verilog实现,通过MATLAB进行辅助验证