总体:大致下面几个模块。我们的卷积码是(2,1,9),所以有256个状态。首先是control模块输出所有控制信号,保证其他模块有序译码。然后是bmg模块,根据输入的卷积码CODE,判断256个状态512个分支的汉明距,即分支度量值,发送给acs.然后asc模块从RAM里面的metricmemory里面取出前一级的256个状态路径度量值,与bmg送来的汉明距离,相加以后,进行比较,选择路径度量值较小的分支,最终得到256个状态的路径度量值,存储到RAM,并且把256个状态里面最小状态传给TBU回溯模块。把256个状态的幸存比特信息传给MMU。MMU一次从ACS得到4个状态的幸存比特信息,将其拼接成8个状态,存入RAM中。然后当TB-EN使能信号有效,开始回溯时,TBU模块给RAM发11位的地址,从RAM里面寻找当前状态的幸存比特信息,RAM把信息传给MMU,通过MMU传给TB模块。最后TB模块输出解码。
testbench.v建立原始时钟信号,时钟周期是100ns,频率10MHz。再建立复位信号,低有效。Active信号为1,开始工作。创建编码器时钟D_CLOCK。
最后设置输入码字X或者卷积码code。T=DPERIOD=64*400ns。实例化编码器,输出卷积码。实例化解码器,输出解码。
DPERIOD =128*200=64*400,ACS模块时钟是clock1,2,周期是400.ACS模块里面有四个并行加比选单元,一个周期完成四个状态的加比选。然后迭代64次,才完成256个状态加比选,所以需要64个clock2。
仿真结果:
1.带有编码器。输入码字X给卷积编码器,编码器输出卷积码CODE给解码器,解码器输出DECODEOUT。如图正确解码。
下面两图是输入码字X,和解码输出码字DecodeOut,我们可以直观地看出两者一致。
2.不带编码器。直接输入卷积码CODE给解码器,解码器输出DECODEOUT。如图正确解码,下图的输入卷积码是和上图X输入,在编码器生成的卷积码一致。有图可见,波形一致,仿真正确。
3.维特比译码有一定的纠错能力,下图验证。因为维特比会选择一个路径度量最小的状态回溯,也即差错最小。可以看到错误代码中,lowestmetric不再为0,说明有差错,差错状态的路径度量值为10h.
correctcode代码
errorcode代码
仿真结果:
ACSPage<=111_111;Hold<= 0;Init <=0; TB_EN <= 0;CompareStart <= 0;
2.CLOCK周期为100ns
3.看出count为二分频,最终Clock1,Clock2都为Clock的四分频,T=400ns。
并且,Clock2超前Clock1,90度。Clock1=1100时,Clock2=1001。
因为有的信号操作需要其他信号保持一段时间。所以利用相位差90度,将有些信号在使用前设置好,防止冲突延迟。
例如ASC里面最小路径产生模块。其功能是找出256个状态中路径度量最小的状态。它在Clock2下降沿更新最小状态,最后在Clock1下降沿输出。由于Clock2超前Clock1,刚好可以在更新完最后一个状态与重新进行下次256个状态的比较之间,输出最小状态。
一个码字的输入时间就是计数64个ACSSegment。一个码字在4个并行ACS单元下迭代64次,才能完成256个状态的路径度量值比较。
Init信号标志着一个码元处理的开始,在Clock1的上升沿,且ACSSegment=3F的时候为1,持续一个Clock1。
Hold信号标志着一个码元处理的结束,在Clock1的上升沿,且ACSSegment=3EH的时候为1,持续一个Clock1.
5.ACSPage = 'h3E且ACSSegment = 'h3F时,TB_EN为1,TB单元使能,路径开始回溯。
6.在Clock2的上升沿。comparecount计数到8以后并且ACSSegment = 6'h3F(init)。CompareStart <= 1,开始比较。对于前8个码字不进行比较。幸存者来自“0”分支,上支路。
从全0状态起始点开始讨论。到9级及以后,每个状态都有两支路,才需要加比选。
ASCUNIT模块分为三块。一是四个并行的ASC单元,二是RAM Interface(RAM 接口模块),三是Lowest Pick block(最小路径选择模块)。
功能:ACS 单元从路径度量存储模单元中取出前一时刻幸存路径的度量值, 然后与送入 ACS 单元的分支度量值累计相加进行比较,相加度量值较小的作为该状态新的路径度量值存入RAM里的MetricMemory以备下一时刻加比选使用。并产生幸存比特信息survivor 给MMU模块。这个幸存信息表示在加比选操作中,表征该状态是由前一时刻进入该状态的哪条分支转移而来的,当 survivor =0 时表示该状态是由偶状态(即上支路)转移而来,当 survivor =1 时表示该状态是由奇状态(即下支路)转移而来。
最后把256个状态里面最小状态传给TBU回溯模块。
仿真结果:
3.找到256个状态最小状态的功能。如图,只有在前四个状态八个分支输入的Distance=16'b1000_0101_0110_0101; //2 0 1 1 1 2 1 1 ;其余情况汉明距离均为1.又因为初始存储的路径度量值为0.故其,路径度量值最小的状态为0对应的状态,状态号为3,和仿真一致。
4.和RAM接口模块,存入和读取路径度量值。MMBlockSelect=0为A写B读。在下一个码字输入时,MMBlockSelect翻转。例如,写A读B时,实现先读取B中上一级的256个状态路径度量值,用于加比选,同时把加比选的结果存入A。然后下一状态读A写B,交替操作,实现同时读写。
A,B都是64个32bit的存储模块。64*4*8
下图仿真中,可以看到先是写A读B,在第一个码字输入时,取出的MMpathmetirc为0。然后第一个码字结束后,全部存入256个状态的路径度量值在A中。在一个码字来时,读A,
MMpathmetirc先为64H0101010100010101,可以看到3-0状态,路径度量值为0111,和之前输入一致。其余时刻均为64H0101010101010101(路径度量值都是1)
output [`WD_FSM-1:0] MMWriteAddress; //6位,一次写入4个状态。64*4=256
MMReadAddress <= ACSSegment [`WD_FSM-2:0]; //低五位。0-31
MMWriteAddress = ACSSegment; //写地址6bit 为什么读地址是五位,写地址是6位。
因为四个状态,有8个分支,对应着前面8个状态。所以需要读出8个状态的路径度量值。
如当 ACSSegment为ABCDEF时,他对应的4个状态是这样,它对应的前八个状态一定是BCDEF对应的8个状态。前后状态只有一位不同,相当于右移一位,输入放最高位。所以只需要ACSSegment低五位,就可以读出对应的前8个状态路径度量值。另一方面,读地址5BIT,寻址32个,即32*8=256,实现256个状态的读取。32个,32*8=256个状态。写地址6BIT,寻址64个,一次写4个状态,64*4=256,完成256个状态的存入。
以上8个.v文件下载(verilog程序):
维特比编码译码器.zip
(1.49 MB, 下载次数: 87)
欢迎光临 (http://www.51hei.com/bbs/) | Powered by Discuz! X3.1 |