当前位置:   article > 正文

从零在FPGA上实现OFDM(三)_fpga ofdm

fpga ofdm

OFDM 调制 PLCP 子层数据字段的生成

说明:PLCP层的数据,我们这里只是实现data域,其余的现在先不考虑

        这是将我们上一个产生的数据每一帧数据,经生成的数据进行处理使之满足 data 域(serive 域 +psdu + tail bits + pad bits) 的数据结构要求。

其中serive 域中前7个为0,用来初始化接收机部分的解扰码器的初始值,因为前 7bit 为 0 时加扰器会输出加扰器的初试状态。后 9 个 bits 预留以便将来使用。

PSDU:其实就是我们实际传输的数据(bit);

tail bits + pad bits :Psdu 后面跟随的尾 bits 的作用和 signal 域的尾比特作用相同,都是为了卷积编码器的移位寄存器的清零。

Pad bits :Pad bits 的意义在于使整个 data 域的比特流长度刚好调整为每一个 ofdm符号数据比特长度的整数倍,如果 data 域的比特数不足 ofdm 符号的整数倍,要适当补零。

总的来说就是将我们的数据进行处理,使满足data域的帧格式。

总的思路:我们上一个模块产生的数据是每字节的数据,而经过这里的转换之后就会转化为单bit的数据,就是8转1,然后进行输出,且满足data域的数据帧格式。

具体思路:总的数据是8转1,所以使用一个异步fifo,将数据进行转换。

模块设计的框图:

 

写fifo时序思路:

1:psdu其实就是我们实际的数据,我么要在前面加上16bit 的serive域的数据,其实我们这里只需要在前面加上2个8bit的0就行了。

加2个8bit 0思路:由于上一个模块会同是输出数据有效和数据,我们只需要将数据有效信号延迟2个拍,然后当数据有效信号延迟1拍的信号有效时,fifo的输入信号就是上一个模块发出的有效数据,其他时刻fifo的输入数据就是0;fifo 的写使能就是上一个数据有效再或上上一个数据有效延迟的2拍的信号。

  1. // fifo写时序 主要就是在前面加入28bit0 ,就是增加16比特0
  2. assign fifo_generator_8to1_inst_wren = send_data_valid | send_data_valid_dly2;
  3. //delay 2 clk
  4. always @(posedge clk_User ) begin
  5. {send_data_valid_dly2,send_data_valid_dly1} <= {send_data_valid_dly1,send_data_valid};
  6. end
  7. //send_data_dly1
  8. always @(posedge clk_User ) begin
  9. send_data_dly1 <= send_data;
  10. end
  11. //locked signals
  12. always @(posedge clk_User ) begin
  13. if(reset == 1'b1) begin
  14. fifo_generator_8to1_inst_din <= 1'b0;
  15. end else if(send_data_valid_dly1 == 1'b1) begin
  16. fifo_generator_8to1_inst_din <= send_data_dly1;
  17. end else begin
  18. fifo_generator_8to1_inst_din <= 1'b0;
  19. end
  20. end

//

其实我们在读fifo时,我们需要在读出的数据的尾端加上tail bits + pad bits这两个部分的数据,我们在读fifo之前,就应该将要在后面补多少0,做好准备,计算好。

这是一些802.11a中的一些表

 

 

首先这里使用的是

//编码效率为3/4,带宽20Mhz,数据传输信道为48,调制模式为64QAM,每一个OFDM的符号

//周期统一定义为4us,就是一个OFDM 周期为4us

//传输速率:3/4*48*6*1/48e6 = 54Mb/s 也就是理想总带宽

//每一个ofdm 符号的编码比特(Ncbps):6*48 = 288;//这里的6是由于用的64QAM,2^6 = 64

//由于是3/4编码,所以每一个ofdm数据比特(Ndbps)为288*3/4 = 216

//Nsym = ceiling[(16 + 8 * length + 6)/Ndbps]; Nsym为OFDM符号数。

Ndbps 数据速率,可以查表得这个为tx_Rate的 4倍。

所以就需要用到一个乘法和除法ip将我们所需要的数据计算出来,算出最后需要填充的数据。

实际的传输的bit数:(packetlength << 3) +22 //packetlen 是多少字节,这里是多少bit,22 == service + tail;

//计算的pad bits的一些代码

  1. assign send_data_valid_flag = (~send_data_valid_dly1)& send_data_valid;//上一拍为低,当前拍为高
  2. // valid_bits_length
  3. always @(posedge clk_User ) begin
  4. if(reset == 1'b1) begin
  5. valid_bits_length <= 'd0;
  6. end else if(send_data_valid_flag == 1'b1) begin
  7. valid_bits_length <= (packetlength << 3) +22;//packetlen 是多少字节,这里是多少bit,22 == service + tail;
  8. end else begin
  9. valid_bits_length <= valid_bits_length;
  10. end
  11. end
  12. //send_data_valid_flag_dly1;
  13. always @(posedge clk_User) begin
  14. send_data_valid_flag_dly1 <= send_data_valid_flag; //作为除法的标志位
  15. end
  16. //bits_ofdm_sym //一个OFDM 中的符号的bit个数
  17. assign bits_ofdm_sym = tx_Rate <<2; //
  18. //data_bit_valid podg
  19. //always @(posedge clk_Modulation ) begin
  20. // data_bit_valid <= fifo_generator_8to1_inst_rden;
  21. //end
  22. //div
  23. div_gen_0 div_gen_16_8_isnt (
  24. .aclk(clk_User), // input wire aclk
  25. .s_axis_divisor_tvalid(send_data_valid_flag_dly1), // input wire s_axis_divisor_tvalid
  26. .s_axis_divisor_tdata(bits_ofdm_sym), // input wire [7 : 0] s_axis_divisor_tdata
  27. .s_axis_dividend_tvalid(send_data_valid_flag_dly1), // input wire s_axis_dividend_tvalid
  28. .s_axis_dividend_tdata(valid_bits_length), // input wire [15 : 0] s_axis_dividend_tdata
  29. .m_axis_dout_tvalid(pad_num_div_valid), // output wire m_axis_dout_tvalid
  30. .m_axis_dout_tdata(pad_num_div) // output wire [23 : 0] m_axis_dout_tdata
  31. );
  32. assign num_ofdm_all = ((pad_num_div[7:0] == 8'd0) ? pad_num_div[23:8] :pad_num_div[23:8] +1);
  33. mult_padnum_16x8 mult_padnum_16x8_inst (
  34. .CLK(clk_User), // input wire CLK
  35. .A(num_ofdm_all), // input wire [15 : 0] A
  36. .B(bits_ofdm_sym), // input wire [7 : 0] B 216 = 54x4 = 216
  37. .CE(pad_num_div_valid), // input wire CE
  38. .P(num_all_data_bits) // output wire [23 : 0] P //总的bit的个数
  39. );
  40. //pad_num_div_valid_dly1
  41. always @(posedge clk_User ) begin
  42. pad_num_div_valid_dly1 <= pad_num_div_valid; //由于乘法器有一个时钟的延时才会出结果
  43. end
  44. //pad_num
  45. always @(posedge clk_User) begin
  46. if(reset== 1'b1)begin
  47. pad_num <= 'd0;
  48. end else if(pad_num_div_valid_dly1 == 1'b1)begin //由于乘法器有一个时钟的延时才会出结果,这里对齐
  49. pad_num <= num_all_data_bits - valid_bits_length; //我们需要的个数

读fifo

读取fifo的使能信号就是empty信号取反,只要一空了就开始读取。

由于我们最后要加多少个0的已经算出,所以这里使用fifo 读信号延迟一拍来的到一个读取结束信号,使之开始填充0,并且设置一个计数器,来计算我们补了多少个0;

我们最后的需要的补充的数据是tail ,即6个bits的0还有就是pad bits,两个加起来就行了。

说明:这只是本人学习的OFD的一些思路,记录下来,格式什么都没注意,只是单纯的记录

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号