从零在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域的数据帧格式。

从零在FPGA上实现OFDM(三)_第1张图片

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

模块设计的框图:

从零在FPGA上实现OFDM(三)_第2张图片

 

写fifo时序思路:

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

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

// fifo写时序  主要就是在前面加入2个8bit 的0 ,就是增加16比特0
assign fifo_generator_8to1_inst_wren = send_data_valid | send_data_valid_dly2;
//delay 2 clk
always @(posedge clk_User ) begin
    {send_data_valid_dly2,send_data_valid_dly1} <= {send_data_valid_dly1,send_data_valid};
end
//send_data_dly1 
always @(posedge clk_User ) begin
    send_data_dly1 <= send_data;
end

 //locked signals
 always @(posedge clk_User ) begin
    if(reset == 1'b1) begin
        fifo_generator_8to1_inst_din <= 1'b0;
    end else if(send_data_valid_dly1 == 1'b1) begin
        fifo_generator_8to1_inst_din <= send_data_dly1;
    end else begin
        fifo_generator_8to1_inst_din <= 1'b0;
    end
 end

//

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

这是一些802.11a中的一些表

从零在FPGA上实现OFDM(三)_第3张图片

 

 

首先这里使用的是

//编码效率为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的一些代码

assign send_data_valid_flag = (~send_data_valid_dly1)& send_data_valid;//上一拍为低,当前拍为高
// valid_bits_length
always @(posedge clk_User ) begin
    if(reset == 1'b1) begin
        valid_bits_length <= 'd0;
end else if(send_data_valid_flag == 1'b1) begin
        valid_bits_length <= (packetlength << 3) +22;//packetlen 是多少字节,这里是多少bit,22 == service + tail;
end else begin
        valid_bits_length <= valid_bits_length; 
end
end
//send_data_valid_flag_dly1;
always @(posedge clk_User) begin
   send_data_valid_flag_dly1 <= send_data_valid_flag; //作为除法的标志位
end
//bits_ofdm_sym  //一个OFDM 中的符号的bit个数
assign bits_ofdm_sym = tx_Rate <<2; //


//data_bit_valid podg
//always @(posedge clk_Modulation ) begin
//    data_bit_valid <= fifo_generator_8to1_inst_rden;
//end

//div 
div_gen_0 div_gen_16_8_isnt (
  .aclk(clk_User),                                      // input wire aclk
  .s_axis_divisor_tvalid(send_data_valid_flag_dly1),    // input wire s_axis_divisor_tvalid
  .s_axis_divisor_tdata(bits_ofdm_sym),      // input wire [7 : 0] s_axis_divisor_tdata
  .s_axis_dividend_tvalid(send_data_valid_flag_dly1),  // input wire s_axis_dividend_tvalid
  .s_axis_dividend_tdata(valid_bits_length),    // input wire [15 : 0] s_axis_dividend_tdata
  .m_axis_dout_tvalid(pad_num_div_valid),          // output wire m_axis_dout_tvalid
  .m_axis_dout_tdata(pad_num_div)            // output wire [23 : 0] m_axis_dout_tdata
);
assign num_ofdm_all = ((pad_num_div[7:0] == 8'd0) ? pad_num_div[23:8] :pad_num_div[23:8] +1);
mult_padnum_16x8 mult_padnum_16x8_inst (
  .CLK(clk_User),  // input wire CLK
  .A(num_ofdm_all),      // input wire [15 : 0] A
  .B(bits_ofdm_sym),      // input wire [7 : 0] B 216 = 54x4 = 216
  .CE(pad_num_div_valid),    // input wire CE
  .P(num_all_data_bits)      // output wire [23 : 0] P    //总的bit的个数
);
//pad_num_div_valid_dly1
always @(posedge clk_User ) begin
    pad_num_div_valid_dly1 <= pad_num_div_valid;  //由于乘法器有一个时钟的延时才会出结果
end
//pad_num
always @(posedge clk_User) begin
    if(reset== 1'b1)begin
        pad_num <= 'd0;
    end else if(pad_num_div_valid_dly1 == 1'b1)begin        //由于乘法器有一个时钟的延时才会出结果,这里对齐
        pad_num <= num_all_data_bits - valid_bits_length;   //我们需要的个数

读fifo

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

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

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

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

你可能感兴趣的:(AD936x,初始化,OFDM,FPGA,大数据)