基于FPGA扰码的实现

项目简述

扰码就是作有规律的随机化处理后的信码。作为现代通信的关键技术之一,扰码是为了提高传输数据的定时恢复能力和保密性而在比特层对需要传输的数据进行随机化处理的技术。这与扰码为什么有利于定时恢复与保密性的功能,首先保密性是因为解密方不知道扰码的生成多项式会给破译带来困难;定时恢复是因为扰码会消除连续的0与1,这有利于时钟的恢复。

扰码在通信系统中的位置如下:
在这里插入图片描述
扰码的优点如下:
(1) 在基带的输入端通常需要原始信号进行扰码处理;
(2) 扰码将输入进行随机化处理,消除连续的 0 或者 1, 可较少码间干扰和抖动;
(3) 扰码有加密的作用;
(4) 扰码能改善定时恢复的质量, 与此同时, 扰码能使信号频谱弥散而保持稳恒, 将数字信号的功率频谱扩展, 实现能量的分散

扰码数学原理

扰码的实现特别简单,我们只需要先生成相应的扰码序列,然后将扰码序列与输入序列进行异或运算,生成的序列就是扰码之后的序列。于是,现在我们便可以把焦点放到扰码序列的生成。扰码序列的生成需要生成多项式和寄存器的初值,这里生成多项式的概念不多加赘述,如果不了解的同学可以学习通信原理与信息论,书本上的知识比我写的好太多。

这里以经典的例子为例进行讲解,扰码序列的生成多项式为 1 + X 14 + X 15 1+X^{14}+X^{15} ,初始序列为 100101010000000。这里稍微熟悉通信知识的可以知道这里的+其实就是异或运算。根据上面的生成多项式,扰码实现结构如下:
在这里插入图片描述
相信将上面的结构框图给出,大家写FPGA代码要比写MATLAB代码容易的多,因为FPGA本身特别适合描述这种结构。但是为了结构的完整性,我们将先进性MATLAB代码仿真,然后进行FPGA仿真,最后将两个仿真结果对比,从而验证我们实验的正确性。

扰码的MATLAB实现

从上面的介绍,相信大家可以明白扰码的生成分为两个步骤:
1、生成扰码序列
2、将扰码序列与输入序列进行相应的异或运算

这里不多说废话直接给出相应的代码,大家结合上面的原理介绍,相信可以看懂下面的代码,并且对扰码的生成会有更加深刻的认识。

clc;
clear all;
%------------------------------------------------------------------------------
% PLP-specific Parameters Definition
%------------------------------------------------------------------------------
K_BCH      = 7032;   % BCH unencoded block length
tx_nFrame = 1;

fid1 = fopen('scramble_data_in.txt','r');
DataIn = fscanf(fid1,'%d');
%------------------------------------------------------------------------------
% Procedure
%------------------------------------------------------------------------------
dataAux = DataIn;
% Get BB scrambling sequence

srBin = [1 0 0 1 0 1 0 1 0 0 0 0 0 0 0]; % Shift register content
bbPrbsBin = zeros(1,K_BCH); % Initialize output

% Generates PRBS sequence
for n=1:K_BCH
    fedBackBit = xor(srBin(14), srBin(15)); % XOR bits 14 and 15
    bbPrbsBin(n) = fedBackBit;  % Output
    srBin = [fedBackBit, srBin(1:14)];
end

bbPrbs = bbPrbsBin;

bbPrbs = bi2de(reshape(bbPrbs,8,[])','left-msb'); % convert to bytes

dataAux = bi2de(reshape(dataAux,8,[])','left-msb');
dataAux = reshape(dataAux, K_BCH/8, []); % One column per BBFrame
for bbFrameIdx = 1:size(dataAux,2)
    dataAux(:,bbFrameIdx) = bitxor(dataAux(:,bbFrameIdx), bbPrbs);
end

data_lab = de2bi(dataAux, 8, 'left-msb');
data_lab = reshape(data_lab.', [], 1); 

下面对上面的代码进行简要的介绍:
在这里插入图片描述
生成相应的输入序列,每7032个数据作为一个生成扰码的独立的块,即,连续的7032个数据序列之后,扰码序列就需要进行初始化操作。
在这里插入图片描述
上面的代码是生成扰码序列。
在这里插入图片描述
上面的代码是为了加快MATLAB的仿真速度,先将上面的扰码序列和输入序列每8位转换成十进制,然后分别对生成的十进制数进行异或运算,这可以加快MATLAB的速度。至于为什么,博主也不清楚,当然这也不是重点,不进行相应的转换,直接对二进制进行异或运算,这是完全正确的。

扰码的FPGA实现

扰码FPGA的代码

上面已经把原理介绍的比较清楚,这里直接给出相应的FPGA代码:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : tx_scramble.v
// Create Time  : 2020-05-22 15:29:47
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module tx_scramble
(
	input            	sclk                        ,
	input            	rst_n                       ,
	input            	s_data_tvalid              	,
	input            	s_data_tdata               	,
	output reg       	s_data_tready              	,
	input            	s_data_tlast 				,
						
	output reg       	m_data_tvalid 				,
	output reg       	m_data_tdata 				,
	input            	m_data_tready 				,
	output reg       	m_data_tlast	
); 
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/

reg                     s_data_tvalid_reg           ;
reg                     s_data_tdata_reg            ;
reg                     s_data_tlast_reg            ;
reg         [14:0]      Init_cram_Sequ              ;
reg                     data_ordy                   ;
wire                    start_data_invld            ;
 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign start_data_invld = ~s_data_tvalid_reg && s_data_tvalid;
	
always@(posedge sclk)
begin
	s_data_tvalid_reg 			<=  				s_data_tvalid;
	s_data_tdata_reg 			<=   				s_data_tdata;
	s_data_tlast_reg 			<=   				s_data_tlast;
end
	
always@(posedge sclk)
	if(~rst_n)
		Init_cram_Sequ[14:0] 	<=   				15'b000_0000_101010_01; 
	else if(s_data_tvalid)begin
		Init_cram_Sequ[0]  		<=   				Init_cram_Sequ[14] ^ Init_cram_Sequ[13];
		Init_cram_Sequ[14:1]  	<=   				Init_cram_Sequ[13:0];
	end else
		Init_cram_Sequ[14:0] 	<=   				15'b000_0000_101010_01; 	
	
always@(posedge sclk)
	if(s_data_tvalid_reg)
		m_data_tdata 			<=  				Init_cram_Sequ[0]^s_data_tdata_reg;
	else
		m_data_tdata 			<=  				0;
	
always@(posedge sclk)
begin
	m_data_tvalid		 		<=  				s_data_tvalid_reg;
	m_data_tlast 				<=   				s_data_tlast_reg;
end

always@(posedge sclk)
	if(~rst_n)
		data_ordy 				<=   				1;
	else if(start_data_invld)
		data_ordy 				<=   				0;
	else if(m_data_tlast)
		data_ordy 				<=   				1;
	
always@(posedge sclk)
	s_data_tready <=   data_ordy && m_data_tready;
	
endmodule


该代码是符合AXI-Stream协议,可以很容易进行与上下级的级联,也可以封装成容易使用的模块。

FPGA测试代码

如果只给出扰码的源码,不给出相应的测试代码,大家不方便学习,所以这里我们给出相应的测试代码供大家学习。

tb_tx_scrable模块:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : tb_tx_scrable.v
// Create Time  : 2020-05-22 15:56:09
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module tb_tx_scrable;

parameter 		N 		= 		2		;

reg 			sclk            		;
reg 			rst_n           		;//
					
reg 			s_data_tdata    		;//
wire 			s_data_tready 			;
reg 			s_data_tlast    		;


wire 			m_data_tvalid 			;
wire 			m_data_tdata 			;//
reg  			m_data_tready 			;
wire 			m_data_tlast 			;
			
wire 			event_status_missing	;//

reg 			s_data_tvalid_delay		;
reg 			s_data_tvalid  			;//
 
integer 		file 					;
integer 		i=0 					;

reg 	[15:0] 	cnt = 16'd0				;
reg 	     	test[0:7032*N-1]		;

// sclk rst_n Gen
initial begin
	sclk 			=  			1'b0;
	rst_n 			<= 			1'b0;
	m_data_tready 	<= 			1'b1;
	#1000;
	rst_n 			<= 			1'b1;	
end
always #10 sclk 	=			~sclk;

initial begin
		s_data_tvalid 	<= 		1'b0;
	#2000;
	repeat(10) @(posedge sclk);
		s_data_tvalid 	<= 		1'b1;
	repeat(7032) @(posedge sclk);
		s_data_tvalid 	<= 		1'b0;	
	repeat(10) @(posedge sclk);
		s_data_tvalid 	<= 		1'b1;
	repeat(7032) @(posedge sclk);
		s_data_tvalid 	<= 		1'b0;		
end

initial begin
		s_data_tlast 	<= 		1'b0;
	#2000;
	repeat(7042) @(posedge sclk);
		s_data_tlast 	<=  	1'b1;
	repeat(1) @(posedge sclk);
		s_data_tlast 	<= 		1'b0;
	repeat(7041) @(posedge sclk);
		s_data_tlast 	<= 		1'b1;	
	repeat(1) @(posedge sclk);
		s_data_tlast 	<= 		1'b0;			
end

always @(posedge sclk)
	if(s_data_tvalid != 1'b1)
		cnt <=   16'd0;
	else 
		cnt <=   cnt + 1'b1;
		

initial begin 	
		$readmemb("scramble_data_in.txt",test);	
end

always @(posedge sclk)	
	if(s_data_tvalid)
			i<=   i+1;
	else
			i<=   i;
			

always@(posedge sclk)
begin
		s_data_tdata <=   test[i];			
end

//output 
initial
begin
	#0;
	file = $fopen("ms_scramble_out.txt","w+");	
	forever @(posedge sclk) 
	if(m_data_tvalid)
	begin
	$fdisplay(file,"%b",m_data_tdata);//
	end
	$fclose(file);	
	#100;
	$stop;
end

always@(posedge sclk)
begin
	s_data_tvalid_delay <=   s_data_tvalid;
end

tx_scramble tx_scramble_inst(
.sclk                 	(sclk                 	),
.rst_n                	(rst_n                	),//
.s_data_tvalid       	(s_data_tvalid_delay 	),//
.s_data_tdata        	(s_data_tdata        	),//
.s_data_tready       	(s_data_tready       	),
.s_data_tlast         	(s_data_tlast         	),

.m_data_tvalid        	(m_data_tvalid        	),
.m_data_tdata        	(m_data_tdata        	),//
.m_data_tready       	(m_data_tready       	),
.m_data_tlast         	(m_data_tlast         	)
); 



//



endmodule

上面测试模块的写法非常经典,使用了将数据从txt文件读出与写入txt文件的方法,很值得大家学习,一定要试着学习这种方法。

仿真结果

我们利用Modelsim进行上面的仿真,可以得到下图:
在这里插入图片描述
然后将上面的数据与MATLAB生成的数据进行对比:
在这里插入图片描述
从上面可以看出我们Modelsim的仿真结果与MATLAB完全相同,从而验证了实验的正确性。从上面我们就已经成功将扰码的知识学会并利用的MATLAB与Modelsim交叉仿真验证。

参考文献

[1]、电子发烧友学院

总结

创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。为行业贡献及其微小的一部分。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zhangningning1996/article/details/106279660