完整版交织器解交织器设计.docx
《完整版交织器解交织器设计.docx》由会员分享,可在线阅读,更多相关《完整版交织器解交织器设计.docx(27页珍藏版)》请在冰点文库上搜索。
![完整版交织器解交织器设计.docx](https://file1.bingdoc.com/fileroot1/2023-7/13/8bd26dfa-44ff-46af-bec8-82d4202bfc6c/8bd26dfa-44ff-46af-bec8-82d4202bfc6c1.gif)
完整版交织器解交织器设计
交织器/解交织器设计
卷积交织:
交织深度I=12,形成相互交迭的误码保护数据包,以抵抗信道中突发的干扰。
1卷积交织和解交织的原理
交织过程可算作一个编码过程,他把经过纠错编码的数据进行一定的
排列组合,提高原有纠错编码的纠突发错误的能力。
数字通信中一般采取
的同步交织有2种:
(1)块交织
也叫矩阵行列转置法。
可以表述为一个二维存储器阵列(N×B)。
交织过程是数据先按行写入,再按列读出;解交织过程则相反,是数据先按
列写入,再按行读出。
块交织结构简单,但数据延时时间长而且所需的存储器比较大。
(2)卷积交织
交织器的输入端的输入符号数据按顺序分别进入B条支路延时器,每一路延时不同的符号周期。
第一路无延时,第二路延时M个符号周期,第三路延时2M个符号周期,…,第B路延时(B-1)M个符号周期。
交织器的输出端按输入端的工作节拍分别同步输出对应支路经延时的数据。
卷积交织每条支路符号数据的延时节拍为di=(i-1)MB,i=1,2,…,B。
解交织器的延时数与交织器相反。
在仔细对比块交织和卷积交织两种方法之后,考虑到缩短延时和减小器件体积,小组决定采用卷积交织的方法来设计。
然而实现卷积交织的延时方法有多种,一是采用移位寄存器法,直接利用FIFO实现每条支路的延时,这种方法实现简单,但是当B与M值较大时,需要消耗大量的寄存器(图2所示);二是利用RAM来实现移位寄存器的功能,通过控制读/写地址来实现每条支路延迟。
第一种方法,因为其设计思路和做法都相对简单,但是当需要较大的延时数时,移位寄存器变得很大,占用大量的编译时间和芯片空间,实际中并不可取,最终采用了RAM来实现移位,合理地设计读写地址按规律变化,即可实现所要的延时。
下面将阐述设计细节
设计要求,交织深度B=12,M=17,即有12条数据通路。
采用RAM来实现输入数据的时延,按照一定的读写地址规律同时读写RAM中。
交织器各通道的写地址如图4所示,读地址则在写地址的数值上加1,通过计算可以知道,第0通道无延时;第1通道延时17*1个时钟周期;第2通道延时17*2个时钟周期......依此类推,第11通道延时17*11个时钟周期。
总共所需存储单元数为1+18+....+188=1134,相应的要用到地址总线为11b。
也就是说要用到2k的RAM。
交织器的设计:
交织器由以上四个模块构成:
AddrGen(交织器读写地址),RAM,WRcon(产生读写控制信号),DataLock(数据锁存),工作过程是clk一个上升沿到来时,AddrGen产生了读写地址AddrW和AddrR,与此同时WRcon模块WE=0,RE=’1’,产生写入控制信号,RAM便在AddrW地址单元存储发送过来的数据DataIn。
接着clk下降沿到来,WRcon模块WE=’1’,RE=‘0’,产生读取控制信号,RAM便读取AddrR地址单元内的数据,DataLock模块进行数据锁存。
接着clk又是上升沿到来,如此循环。
交织器模块的代码:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityInterLeaveris
port(clk:
instd_logic;
DataIn:
instd_logic_vector(7downto0);
DataOut:
outstd_logic_vector(7downto0));
endentity;
architecturestruofInterLeaveris
componentAddrGenis
port(clk:
instd_logic;
AddrR:
outintegerrange0to2047;
AddrW:
outintegerrange0to2047
);
endcomponent;
componentRAMis
port(AddrR:
inintegerrange0to2047;
AddrW:
inintegerrange0to2047;
DataIn:
instd_logic_vector(7downto0);
DataOut:
outstd_logic_vector(7downto0);
CS,RE,WE:
instd_logic);
endcomponent;
componentWRconis
port(clk:
instd_logic;
WE,RE:
outstd_logic);
endcomponent;
componentDataLockis
port(Data:
instd_logic_vector(7downto0);
DataLock:
outstd_logic_vector(7downto0);
RE:
instd_logic);
endcomponent;
signaladr,adw:
integerrange0to2047;
signalwe,re:
std_logic;
signald:
std_logic_vector(7downto0);
begin
u0:
AddrGenportmap(clk,adr,adw);
u1:
WRconportmap(clk,we,re);
u2:
RAMportmap(adr,adw,DataIn,d,'0',re,we);
u3:
DataLockportmap(d,DataOut,re);
endstru;
交织器读写地址模块:
RAM读写地址产生的一种办法就是将读写地址映射到ROM里,另一种办法就是通过电路计算得到读写地址。
这里采用后一方法设计交织器/解交织器读写地址产生模块,但其中应用了ROM存储读写地址的思想。
交织器读写地址VHDL代码:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityAddrGenis
port(clk:
instd_logic;
AddrR:
outintegerrange0to2047;
AddrW:
outintegerrange0to2047
);
endAddrGen;
architecturebehavofAddrGenis
signalcount:
integerrange0to11:
=0;
begin
C:
process(clk)
variablec:
integerrange0to11:
=0;
begin
if(rising_edge(clk))then
c:
=(c+1)mod12;
endif;
count<=c;
endprocess;
addr:
process(clk)
constanta0:
integer:
=0;
constanta1:
integer:
=1;
constantc1:
integer:
=18;
constanta2:
integer:
=19;
constantc2:
integer:
=53;
constanta3:
integer:
=54;
constantc3:
integer:
=105;
constanta4:
integer:
=106;
constantc4:
integer:
=174;
constanta5:
integer:
=175;
constantc5:
integer:
=260;
constanta6:
integer:
=261;
constantc6:
integer:
=363;
constanta7:
integer:
=364;
constantc7:
integer:
=483;
constanta8:
integer:
=484;
constantc8:
integer:
=620;
constanta9:
integer:
=621;
constantc9:
integer:
=774;
constanta10:
integer:
=775;
constantc10:
integer:
=945;
constanta11:
integer:
=946;
constantc11:
integer:
=1133;
variableb1:
integerrange0to17:
=0;
variableb2:
integerrange0to34:
=0;
variableb3:
integerrange0to51:
=0;
variableb4:
integerrange0to68:
=0;
variableb5:
integerrange0to85:
=0;
variableb6:
integerrange0to102:
=0;
variableb7:
integerrange0to119:
=0;
variableb8:
integerrange0to136:
=0;
variableb9:
integerrange0to153:
=0;
variableb10:
integerrange0to170:
=0;
variableb11:
integerrange0to187:
=0;
begin
if(rising_edge(clk))then
casecountis
when0=>AddrW<=a0;AddrR<=a0;
when1=>
b1:
=(b1+1)mod18;
if(b1=0)then
AddrW<=c1;
AddrR<=a1;
else
AddrR<=a1+b1;
AddrW<=a1+b1-1;
endif;
when2=>
b2:
=(b2+1)mod35;
if(b2=0)then
AddrW<=c2;
AddrR<=a2;
else
AddrR<=a2+b2;
AddrW<=a2+b2-1;
endif;
when3=>
b3:
=(b3+1)mod52;
if(b3=0)then
AddrW<=c3;
AddrR<=a3;
else
AddrR<=a3+b3;
AddrW<=a3+b3-1;
endif;
when4=>
b4:
=(b4+1)mod69;
if(b4=0)then
AddrW<=c4;
AddrR<=a4;
else
AddrR<=a4+b4;
AddrW<=a4+b4-1;
endif;
when5=>
b5:
=(b5+1)mod86;
if(b5=0)then
AddrW<=c5;
AddrR<=a5;
else
AddrR<=a5+b5;
AddrW<=a5+b5-1;
endif;
when6=>
b6:
=(b6+1)mod103;
if(b6=0)then
AddrW<=c6;
AddrR<=a6;
else
AddrR<=a6+b6;
AddrW<=a6+b6-1;
endif;
when7=>
b7:
=(b7+1)mod120;
if(b7=0)then
AddrW<=c7;
AddrR<=a7;
else
AddrR<=a7+b7;
AddrW<=a7+b7-1;
endif;
when8=>
b8:
=(b8+1)mod137;
if(b8=0)then
AddrW<=c8;
AddrR<=a8;
else
AddrR<=a8+b8;
AddrW<=a8+b8-1;
endif;
when9=>
b9:
=(b9+1)mod154;
if(b9=0)then
AddrW<=c9;
AddrR<=a9;
else
AddrR<=a9+b9;
AddrW<=a9+b9-1;
endif;
when10=>
b10:
=(b10+1)mod171;
if(b10=0)then
AddrW<=c10;
AddrR<=a10;
else
AddrR<=a10+b10;
AddrW<=a10+b10-1;
endif;
when11=>
b11:
=(b11+1)mod188;
if(b11=0)then
AddrW<=c11;
AddrR<=a11;
else
AddrR<=a11+b11;
AddrW<=a11+b11-1;
endif;
endcase;
endif;
endprocess;
endbehav;
产生读写控制信号模块:
有了读写地址,还需要有读写控制信号。
在一个时钟周期内,令clk=’1’时,将待发送数据写入RAM地址为AddrW的单元,clk=’0’时,读取RAM地址为AddrR的单元里的数据并发送。
VHDL代码:
libraryieee;
useieee.std_logic_1164.all;
entityWRConis
port(clk:
instd_logic;
WE,RE:
outstd_logic);
endentity;
architecturebehavofWRconis
begin
process(clk)
begin
if(clk'eventandclk='1')then
WE<='0';RE<='1';
else
WE<='1';RE<='0';
endif;
endprocess;
endbehav;
RAM模块如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityRAMis
port(AddrR:
inintegerrange0to2047;
AddrW:
inintegerrange0to2047;
DataIn:
instd_logic_vector(7downto0);
DataOut:
outstd_logic_vector(7downto0);
CS,RE,WE:
instd_logic);
endRAM;
architecturebehavofRAMis
begin
process(AddrW,RE,WE)
typeram_arrayisarray(0to2047)ofstd_logic_vector(7downto0);
variablemem:
ram_array:
=(others=>"00000000");
begin
if(CS='0')then
if(RE='0')thenDataOut<=mem(AddrR);
elsif(WE='0')thenmem(AddrW):
=DataIn;
endif;
endif;
endprocess;
endbehav;
数据锁存模块:
由于数据读取控制信号RE只占半个时钟周期,故需要将输出数据进行锁存,保证输出信号稳定。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityDataLockis
port(Data:
instd_logic_vector(7downto0);
DataLock:
outstd_logic_vector(7downto0);
RE:
instd_logic);
endDataLock;
architecturebehavofDataLockis
begin
process(Data,RE)
begin
if(RE='0')thenDataLock<=Data;
endif;
endprocess;
endbehav;
解交织器
解交织器也又四个模块组成:
DeAddrGen,WRcon,RAM,DataLock。
DeAddrGen模块根据图5产生读写地址。
接着便要验证从解交织器得到的数据是否与发送数据DataIn相同。
经过分析发现,交织器输出的第一个数据是无效数据(RAM还没有输出,是DataLock初始输出信号),故解交织器应该比交织器延迟一个时钟。
解交织器模块代码:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityDeInterLeaveris
port(clk:
instd_logic;
DataIn:
instd_logic_vector(7downto0);
DataOut:
outstd_logic_vector(7downto0));
endentity;
architecturestruofDeInterLeaveris
componentDeAddrGenis
port(clk:
instd_logic;
AddrR:
outintegerrange0to2047;
AddrW:
outintegerrange0to2047
);
endcomponent;
componentRAMis
port(AddrR:
inintegerrange0to2047;
AddrW:
inintegerrange0to2047;
DataIn:
instd_logic_vector(7downto0);
DataOut:
outstd_logic_vector(7downto0);
CS,RE,WE:
instd_logic);
endcomponent;
componentWRconis
port(clk:
instd_logic;
WE,RE:
outstd_logic);
endcomponent;
componentDataLockis
port(Data:
instd_logic_vector(7downto0);
DataLock:
outstd_logic_vector(7downto0);
RE:
instd_logic);
endcomponent;
signaladr,adw:
integerrange0to2047;
signalwe,re:
std_logic;
signald:
std_logic_vector(7downto0);
begin
u0:
DeAddrGenportmap(clk,adr,adw);
u1:
WRconportmap(clk,we,re);
u2:
RAMportmap(adr,adw,DataIn,d,'0',re,we);
u3:
DataLockportmap(d,DataOut,re);
endstru;
解交织器读写地址VHDL代码:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityDeAddrGenis
port(clk:
instd_logic;
AddrR:
outintegerrange0to2047;
AddrW:
outintegerrange0to2047
);
endDeAddrGen;
architecturebehavofDeAddrGenis
signalcount:
integerrange0to11:
=0;
begin
C:
process(clk)
variablec:
integerrange0to11:
=0;
begin
if(rising_edge(clk))then
c:
=(c+1)mod12;
endif;
count<=c;
endprocess;
addr:
process(clk)
constanta11:
integer:
=0;
constanta10:
integer:
=1;
constantc10:
integer:
=18;
constanta9:
integer:
=19;
constantc9:
integer:
=53;
constanta8:
integer:
=54;
constantc8:
integer:
=105;
constanta7:
integer:
=106;
constantc7:
integer:
=174;
constanta6:
integer:
=175;
constantc6:
integer:
=260;
constanta5:
integer:
=261;
constantc5:
integer:
=363;
constanta4:
integer:
=364;
constantc4:
integer:
=483;
constanta3:
integer:
=484;
constantc3:
integer:
=620;
constanta2:
integer:
=621;
constantc2:
integer:
=774;
constanta1:
integer:
=775;
constantc1:
integer:
=945;
constanta0:
integer:
=946;
constantc0:
integer:
=1133;
variableb10:
integerrange0to17:
=0;
variableb9:
integerrange0to34:
=0;
variableb8:
integerrange0to51:
=0;
variableb7:
integerrange0to68:
=0;
variableb6:
integerrange0to85:
=0;
variableb5:
integerrange0to102:
=0;
variableb4:
integerrange0to119:
=0;
variableb3:
integerrange0to136:
=0;
variableb2:
integer