OFDM802.11a的FPGA实现(八)二级交织(含verilog和matlab代码)

本文介绍了在OFDM802.11a系统中,如何使用Verilog实现二级交织,通过串并转换、并串转换模块以及计数器,确保数据处理的正确性,并结合Matlab和ModelSim进行仿真验证。
摘要由CSDN通过智能技术生成

1.前言

  上一节实现了一级交织:分组交织器,这节接着进行第二级交织的实现。需要注意的是只有data域需要第二级交织,而signal域不需要。二级交织比较简单,作者直接调用了前面的模块来实现,这也体现了FPGA设计的模块化复用思想。当然重新写也是可以的,但是有现成的可以调用干嘛不用呢是不是?

  第二次交织是在第一次交织的基础上进行的,交织基本过程是每24个比特为一单元,前12个顺序保持不变,后12个每相邻两位交换位置,这样就保证了相邻的编码比特被分别映射到星座图中的重要和次要位置,因此LSB长时间的低可靠性将被避免。

2.Verilog代码

  二级交织模块的接口如下所示:

  设计上,直接调用前面的串并转换模块和并串转换模块,设置位宽为2(不清楚的看之前的文章:基于valid-ready双向握手机制的串并和并串转换)。具体实现方式如下:

  (1)首先数据进来使用串并转换,将串行变为2bit的并行。

  (2)然后再例化两个并串转换模块一个设置为LSB优先,一个设置为MSB优先。

  (3)例化一个模24的计数器(FPGA搭积木之计数器

  (4)当计数值小于12时,使用LSB优先的并串转换输出,否则使用MSB优先的并串转换输出。

代码如下:

assign	intv2_dout_rdy 	= S2P_dout_rdy									;
assign	intv2_dout 		= cnt < 12 ? u1_P2S_dout 	 : u2_P2S_dout		;
assign	intv2_dout_vld  = cnt < 12 ? u1_P2S_dout_vld : u2_P2S_dout_vld	;

assign	En_cnt = (u2_P2S_dout_vld & u2_P2S_din_rdy) | u1_P2S_dout_vld & u1_P2S_din_rdy;

counter #(.CNT_NUM('d24),
		.ADD(1'b1))
u_counter(
	.clk		(clk				),	
	.rst_n		(rst_n				),
	.En_cnt		(En_cnt				),      
	.cnt		(cnt				),	
	.cnt_last	(cnt_last			)
);

assign	S2P_din		 	= intv2_din    		;
assign	S2P_din_vld  	= intv2_din_vld		;
assign  S2P_din_rdy		= u1_P2S_dout_rdy &	u2_P2S_dout_rdy;

Ser2Par	#(	.WIDTH		(2),
			.LSB_FIRST	(1'b1))
u_Ser2Par(
	.clk		(clk			),
	.rst_n		(rst_n			),
	.din		(S2P_din		),
	.din_vld	(S2P_din_vld	),
	.din_rdy	(S2P_din_rdy	),
	.dout		(S2P_dout		),
	.dout_vld	(S2P_dout_vld	),
	.dout_rdy   (S2P_dout_rdy	)
);

assign u1_P2S_din		= S2P_dout			;
assign u1_P2S_din_vld 	= S2P_dout_vld		;
assign u1_P2S_din_rdy	= intv2_din_rdy		;

Par2Ser	#(	.WIDTH		(2),
			.LSB_FIRST	(1))
u1_Par2Ser(
	.clk		(clk			),
	.rst_n		(rst_n			),
	.din		(u1_P2S_din		),
	.din_vld	(u1_P2S_din_vld	),
	.din_rdy	(u1_P2S_din_rdy	),
	.dout		(u1_P2S_dout	),
	.dout_vld	(u1_P2S_dout_vld),
	.dout_rdy   (u1_P2S_dout_rdy)
);

assign u2_P2S_din		= S2P_dout			;
assign u2_P2S_din_vld 	= S2P_dout_vld		;
assign u2_P2S_din_rdy	= intv2_din_rdy		;
Par2Ser	#(	.WIDTH		(2),
			.LSB_FIRST	(0))
u2_Par2Ser(
	.clk		(clk			),
	.rst_n		(rst_n			),
	.din		(u2_P2S_din		),
	.din_vld	(u2_P2S_din_vld	),
	.din_rdy	(u2_P2S_din_rdy	),
	.dout		(u2_P2S_dout	),
	.dout_vld	(u2_P2S_dout_vld),
	.dout_rdy   (u2_P2S_dout_rdy)
);

//输出Map_Type,作为后面调制映射的输入,确定调制方式
always@(posedge clk or negedge rst_n ) begin
    if(!rst_n) begin 
        Map_Type_o <= 0;        
    end    
    else if(u2_P2S_dout_vld | u1_P2S_dout_vld) begin 
        Map_Type_o <= Map_Type_i ; 
    end   
end 

3.Matlab仿真

%% 二级交织
int_lea_2_out = int_lea_1_out;
for index = 1:symbol_Len*k         %数据前12个不变,接下来12个两两交换位置
  if(mod((ceil(index/12)-1),2)==1)    %判断数据是不是在后12个位置
      if(mod(index,2) == 0)           %在偶数位置时,将前一个位置的数据给他
          int_lea_2_out(index) = int_lea_1_out(index-1);
      else                            %在奇数位置时,将后一个位置的数据给他
          int_lea_2_out(index) = int_lea_1_out(index+1);
      end
  else
      int_lea_2_out(index) = int_lea_1_out(index);    
  end
end

4.ModelSim仿真

  按照如下图所示方式进行连接仿真:

  为了验证模块的正确性,仿真使用4个OFDM符号输入,调制方式位BPSK(其他调制方式数据太多,不方便展示),测试数据如下:

test_data =

  列 1 至 27

     0     1     1     0     0     0     0     1     0     0     0     0     0     0     0     0     1     0     0     1     1     1     0     0     1     1     1

  列 28 至 54

     1     0     1     1     0     1     1     1     1     1     0     0     1     1     1     0     1     1     1     0     0     0     0     1     0     1     0

  列 55 至 81

     0     0     0     0     0     1     0     1     1     1     1     0     1     1     0     0     1     1     0     0     1     1     0     1     0     0     1

  列 82 至 108

     0     0     0     1     0     1     1     0     0     0     1     0     1     0     1     0     1     1     1     1     0     0     1     1     0     1     0

  列 109 至 135

     1     1     1     1     1     0     1     1     1     0     0     1     0     0     0     0     1     0     1     1     1     0     0     0     1     1     0

  列 136 至 144

     1     0     0     1     1     1     1     1     1

matlab仿真的二级交织结果如下:

int_lea_2_out =

  列 1 至 27

     0     0     1     0     0     1     0     0     0     0     0     0     0     0     0     0     1     0     1     1     0     1     0     0     1     1     0

  列 28 至 54

     0     1     0     1     1     1     0     0     1     0     0     1     1     1     0     1     1     0     1     0     0     1     1     1     1     0     0

  列 55 至 81

     1     1     0     0     0     1     1     1     1     0     1     1     1     0     1     0     1     0     0     0     0     0     0     0     1     1     1

  列 82 至 108

     1     0     1     0     0     0     1     0     0     0     0     0     1     0     0     0     1     1     0     0     0     0     1     0     0     0     0

  列 109 至 135

     1     1     0     0     1     0     1     1     1     1     1     1     1     1     1     0     0     1     0     1     0     1     1     1     1     1     1

  列 136 至 162

     1     1     1     1     1     1     1     1     0     0     0     0     1     1     0     0     1     1     1     1     0     0     1     1     1     1     1

  列 163 至 189

     0     1     0     0     0     1     1     0     0     0     0     1     0     0     1     0     0     1     1     0     0     0     1     1     1     0     1

  列 190 至 192

     1     0     0

FPGA输出的二级交织结果如下:

FPGA_intv2_dout =

  列 1 至 27

     0     0     1     0     0     1     0     0     0     0     0     0     0     0     0     0     1     0     1     1     0     1     0     0     1     1     0

  列 28 至 54

     0     1     0     1     1     1     0     0     1     0     0     1     1     1     0     1     1     0     1     0     0     1     1     1     1     0     0

  列 55 至 81

     1     1     0     0     0     1     1     1     1     0     1     1     1     0     1     0     1     0     0     0     0     0     0     0     1     1     1

  列 82 至 108

     1     0     1     0     0     0     1     0     0     0     0     0     1     0     0     0     1     1     0     0     0     0     1     0     0     0     0

  列 109 至 135

     1     1     0     0     1     0     1     1     1     1     1     1     1     1     1     0     0     1     0     1     0     1     1     1     1     1     1

  列 136 至 162

     1     1     1     1     1     1     1     1     0     0     0     0     1     1     0     0     1     1     1     1     0     0     1     1     1     1     1

  列 163 至 189

     0     1     0     0     0     1     1     0     0     0     0     1     0     0     1     0     0     1     1     0     0     0     1     1     1     0     1

  列 190 至 192

     1     0     0

Matlab的对比代码如下:

clc;
%% 串并转换
test_data = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/test_data.txt')';
display(test_data);
FPGA_S2P2S = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/u2_data_out.txt')';
display(FPGA_S2P2S);
check_S2P = test_data == FPGA_S2P2S; 
display(check_S2P);
%% 扰码
FPGA_scram_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/scram_data_out.txt')';
display(scram_out0);
display(FPGA_scram_dout);
check_scram = FPGA_scram_dout == scram_out0;
display(check_scram);
%% 卷积编码
FPGA_conv_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/conv_data_out.txt')';
display(conv_out0);
display(FPGA_conv_dout);
check_conv = FPGA_conv_dout == conv_out0;
display(check_conv);
%% 删余
FPGA_punt_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/punt_data_out.txt')';
display(conv_out);
display(FPGA_punt_dout);
check_punt = FPGA_punt_dout == conv_out;
display(check_punt);
%% 一级交织
FPGA_intv1_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/intv1_data_out.txt')';
display(int_lea_1_out);
display(FPGA_intv1_dout);
check_intv1 = FPGA_intv1_dout == int_lea_1_out;
display(check_intv1);
%% 二级交织
FPGA_intv2_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/intv2_data_out.txt')';
display(int_lea_2_out);
display(FPGA_intv2_dout);
check_intv2 = FPGA_intv2_dout == int_lea_2_out;
display(check_intv2);

对比结果为:

check_intv2 =

  1×192 logical 数组

  列 1 至 40

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  列 41 至 80

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  列 81 至 120

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  列 121 至 160

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  列 161 至 192

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

对比逻辑值全为1,说明设计是正确的。

原文连接(相关文章合集)OFDM 802.11a的xilinx FPGA实现

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值