本壓縮包中包含維特比編碼和譯碼的全部verilog代碼,包含測(cè)試代碼和部分仿真結(jié)果 Viterbi 算法是一種最大似然譯碼算法,它是通過計(jì)算累積漢明距離,在卷積網(wǎng)絡(luò)圖上尋找一條與接收碼字具有最小漢明距離的最大似然路徑。 Viterbi 譯碼算法不需要把每一條路徑都與接收碼字進(jìn)行比較,而是接收一組碼字,計(jì)算一組距離,比較一組路徑,選擇其中“最大”分支度量,再進(jìn)行下一輪的比較。當(dāng)接收完所有碼字(多組碼字)時(shí),幸存下來的那條路徑就是我們要尋找的最大似然路徑度量路徑。 Viterbi 譯碼的總體流程是比較各分支的度量值,選擇一段最可能的分支,更新狀態(tài)的度量,并根據(jù)比較結(jié)果獲得狀態(tài)轉(zhuǎn)移表,最后通過狀態(tài)轉(zhuǎn)移表的回溯算法完成譯碼
 總體:大致下面幾個(gè)模塊。我們的卷積碼是(2,1,9),所以有256個(gè)狀態(tài)。首先是control模塊輸出所有控制信號(hào),保證其他模塊有序譯碼。然后是bmg模塊,根據(jù)輸入的卷積碼CODE,判斷256個(gè)狀態(tài)512個(gè)分支的漢明距,即分支度量值,發(fā)送給acs.然后asc模塊從RAM里面的metricmemory里面取出前一級(jí)的256個(gè)狀態(tài)路徑度量值,與bmg送來的漢明距離,相加以后,進(jìn)行比較,選擇路徑度量值較小的分支,最終得到256個(gè)狀態(tài)的路徑度量值,存儲(chǔ)到RAM,并且把256個(gè)狀態(tài)里面最小狀態(tài)傳給TBU回溯模塊。把256個(gè)狀態(tài)的幸存比特信息傳給MMU。MMU一次從ACS得到4個(gè)狀態(tài)的幸存比特信息,將其拼接成8個(gè)狀態(tài),存入RAM中。然后當(dāng)TB-EN使能信號(hào)有效,開始回溯時(shí),TBU模塊給RAM發(fā)11位的地址,從RAM里面尋找當(dāng)前狀態(tài)的幸存比特信息,RAM把信息傳給MMU,通過MMU傳給TB模塊。最后TB模塊輸出解碼。 testbench.v建立原始時(shí)鐘信號(hào),時(shí)鐘周期是100ns,頻率10MHz。再建立復(fù)位信號(hào),低有效。Active信號(hào)為1,開始工作。創(chuàng)建編碼器時(shí)鐘D_CLOCK。 最后設(shè)置輸入碼字X或者卷積碼code。T=DPERIOD=64*400ns。實(shí)例化編碼器,輸出卷積碼。實(shí)例化解碼器,輸出解碼。 DPERIOD =128*200=64*400,ACS模塊時(shí)鐘是clock1,2,周期是400.ACS模塊里面有四個(gè)并行加比選單元,一個(gè)周期完成四個(gè)狀態(tài)的加比選。然后迭代64次,才完成256個(gè)狀態(tài)加比選,所以需要64個(gè)clock2。
仿真結(jié)果: 1.帶有編碼器。輸入碼字X給卷積編碼器,編碼器輸出卷積碼CODE給解碼器,解碼器輸出DECODEOUT。如圖正確解碼。 
下面兩圖是輸入碼字X,和解碼輸出碼字DecodeOut,我們可以直觀地看出兩者一致。 

2.不帶編碼器。直接輸入卷積碼CODE給解碼器,解碼器輸出DECODEOUT。如圖正確解碼,下圖的輸入卷積碼是和上圖X輸入,在編碼器生成的卷積碼一致。有圖可見,波形一致,仿真正確。  3.維特比譯碼有一定的糾錯(cuò)能力,下圖驗(yàn)證。因?yàn)榫S特比會(huì)選擇一個(gè)路徑度量最小的狀態(tài)回溯,也即差錯(cuò)最小。可以看到錯(cuò)誤代碼中,lowestmetric不再為0,說明有差錯(cuò),差錯(cuò)狀態(tài)的路徑度量值為10h. correctcode代碼 
errorcode代碼  control.v功能:控制器模塊//向各個(gè)模塊發(fā)送控制信號(hào),保證各模塊有序進(jìn)行解碼 input Reset, CLOCK, Active; //復(fù)位信號(hào),低有效;原始時(shí)鐘;開始工作信號(hào) output [`WD_FSM-1:0] ACSSegment; //迭代次數(shù)64, 6bit output [`WD_DEPTH-1:0] ACSPage; //輸出碼字信號(hào) 6bit output Clock1, Clock2; //clock的四分頻,有相位差 output Hold, Init, CompareStart; //碼字結(jié)束;開始;比較開始(ACS) output TB_EN; //開始回溯 控制單元使用Clock1更新ACSSegment(從而更新BMG單元和ACS單元的輸出)。 時(shí)鐘2用于指示何時(shí)將地址放置到地址總線。 仿真結(jié)果: - reset=0時(shí),異步復(fù)位,Clock1 <= 0; Clock2 <= 0; ACSSegment<=111_111;
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時(shí),Clock2=1001。 因?yàn)橛械男盘?hào)操作需要其他信號(hào)保持一段時(shí)間。所以利用相位差90度,將有些信號(hào)在使用前設(shè)置好,防止沖突延遲。 例如ASC里面最小路徑產(chǎn)生模塊。其功能是找出256個(gè)狀態(tài)中路徑度量最小的狀態(tài)。它在Clock2下降沿更新最小狀態(tài),最后在Clock1下降沿輸出。由于Clock2超前Clock1,剛好可以在更新完最后一個(gè)狀態(tài)與重新進(jìn)行下次256個(gè)狀態(tài)的比較之間,輸出最小狀態(tài)。

- 在Clock1的上升沿。{ACSPage,ACSSegment} <= {ACSPage,ACSSegment} + 1;所以ACSSegment由000_000到111_111,然后ACSPage再加一,ACSPage對(duì)應(yīng)一個(gè)碼字的輸入時(shí)間。
一個(gè)碼字的輸入時(shí)間就是計(jì)數(shù)64個(gè)ACSSegment。一個(gè)碼字在4個(gè)并行ACS單元下迭代64次,才能完成256個(gè)狀態(tài)的路徑度量值比較。 Init信號(hào)標(biāo)志著一個(gè)碼元處理的開始,在Clock1的上升沿,且ACSSegment=3F的時(shí)候?yàn)?,持續(xù)一個(gè)Clock1。 Hold信號(hào)標(biāo)志著一個(gè)碼元處理的結(jié)束,在Clock1的上升沿,且ACSSegment=3EH的時(shí)候?yàn)?,持續(xù)一個(gè)Clock1. 
5.ACSPage = 'h3E且ACSSegment = 'h3F時(shí),TB_EN為1,TB單元使能,路徑開始回溯。 
6.在Clock2的上升沿。comparecount計(jì)數(shù)到8以后并且ACSSegment = 6'h3F(init)。CompareStart <= 1,開始比較。對(duì)于前8個(gè)碼字不進(jìn)行比較。幸存者來自“0”分支,上支路。 
從全0狀態(tài)起始點(diǎn)開始討論。到9級(jí)及以后,每個(gè)狀態(tài)都有兩支路,才需要加比選。 
acs.v
ASCUNIT模塊分為三塊。一是四個(gè)并行的ASC單元,二是RAM Interface(RAM 接口模塊),三是Lowest Pick block(最小路徑選擇模塊)。
功能:ACS 單元從路徑度量存儲(chǔ)模單元中取出前一時(shí)刻幸存路徑的度量值, 然后與送入 ACS 單元的分支度量值累計(jì)相加進(jìn)行比較,相加度量值較小的作為該狀態(tài)新的路徑度量值存入RAM里的MetricMemory以備下一時(shí)刻加比選使用。并產(chǎn)生幸存比特信息survivor 給MMU模塊。這個(gè)幸存信息表示在加比選操作中,表征該狀態(tài)是由前一時(shí)刻進(jìn)入該狀態(tài)的哪條分支轉(zhuǎn)移而來的,當(dāng) survivor =0 時(shí)表示該狀態(tài)是由偶狀態(tài)(即上支路)轉(zhuǎn)移而來,當(dāng) survivor =1 時(shí)表示該狀態(tài)是由奇狀態(tài)(即下支路)轉(zhuǎn)移而來。 最后把256個(gè)狀態(tài)里面最小狀態(tài)傳給TBU回溯模塊。 - module ACSUNIT (Reset, Clock1, Clock2, Active, Init, Hold, CompareStart,ACSSegment, Distance, Survivors,LowestState,MMReadAddress, MMWriteAddress, MMBlockSelect, MMMetric, MMPathMetric);
- input Reset, Clock1, Clock2, Active, Init, Hold, CompareStart; //由control產(chǎn)生的控制信號(hào)。復(fù)位;時(shí)鐘1,2;開始工作;碼字開始;碼字結(jié)束;比較開始
- input [`WD_FSM-1:0] ACSSegment; //由control產(chǎn)生,指明當(dāng)前的迭代次數(shù) input [`WD_DIST*2*`N_ACS-1:0] Distance; //來自BMG,8個(gè)距離,16位
- //連接幸存路徑存儲(chǔ)器Survivor Memory ,MMU
- output [`N_ACS-1:0] Survivors; // 4個(gè)1bit的survivor輸出 // 連接路徑回溯單元TB Unit
- output [`WD_STATE-1:0] LowestState; //// 連接度量記憶單元 MetricMemory output [`WD_FSM-2:0] MMReadAddress; //5位,一次讀入8個(gè)狀態(tài)。32*8=64*4= output [`WD_FSM-1:0] MMWriteAddress; //6位,一次寫入4個(gè)狀態(tài)。64*4
- output MMBlockSelect; //選擇RAMA或RAMB,乒乓操作
- output [`WD_METR*`N_ACS-1:0] MMMetric; //存入MM路徑度量值,4個(gè)狀態(tài),32位
- input [`WD_METR*2*`N_ACS-1:0] MMPathMetric; //來自MM的路徑度量值,8個(gè)狀態(tài),64位
復(fù)制代碼
仿真結(jié)果: - 當(dāng)輸入漢明距離Distance為16'b1000_0101_0010_0101時(shí),即8個(gè)分支的漢明距離為2 0 1 1 0 2 1 1。如圖Distance顯示8525。并且路徑度量值MMPathMetric為全0時(shí),進(jìn)行四個(gè)狀態(tài)的加比選。經(jīng)過加比選,得到四狀態(tài)的路徑度量值和幸存路徑信息,如下圖,輸出MMMetric=00_01_00_01,Survivors=0111(7),與分析相符。


- 當(dāng)輸入漢明距離Distance為16'b1000_1000_0000_0000時(shí),即8個(gè)分支的漢明距離為2 0 2 0 0 0 0 0。如圖Distance顯示8800。并且路徑度量值MMPathMetric為1 2 3 4 b c d e時(shí),進(jìn)行四個(gè)狀態(tài)的加比選。經(jīng)過加比選,得到四狀態(tài)的路徑度量值和幸存路徑信息,如下圖,輸出MMMetric=02_04_0b_0d,Survivors=0011(3),與分析相符。


3.找到256個(gè)狀態(tài)最小狀態(tài)的功能。如圖,只有在前四個(gè)狀態(tài)八個(gè)分支輸入的Distance=16'b1000_0101_0110_0101; //2 0 1 1 1 2 1 1 ;其余情況漢明距離均為1.又因?yàn)槌跏即鎯?chǔ)的路徑度量值為0.故其,路徑度量值最小的狀態(tài)為0對(duì)應(yīng)的狀態(tài),狀態(tài)號(hào)為3,和仿真一致。 
4.和RAM接口模塊,存入和讀取路徑度量值。MMBlockSelect=0為A寫B(tài)讀。在下一個(gè)碼字輸入時(shí),MMBlockSelect翻轉(zhuǎn)。例如,寫A讀B時(shí),實(shí)現(xiàn)先讀取B中上一級(jí)的256個(gè)狀態(tài)路徑度量值,用于加比選,同時(shí)把加比選的結(jié)果存入A。然后下一狀態(tài)讀A寫B(tài),交替操作,實(shí)現(xiàn)同時(shí)讀寫。 A,B都是64個(gè)32bit的存儲(chǔ)模塊。64*4*8
下圖仿真中,可以看到先是寫A讀B,在第一個(gè)碼字輸入時(shí),取出的MMpathmetirc為0。然后第一個(gè)碼字結(jié)束后,全部存入256個(gè)狀態(tài)的路徑度量值在A中。在一個(gè)碼字來時(shí),讀A, MMpathmetirc先為64H0101010100010101,可以看到3-0狀態(tài),路徑度量值為0111,和之前輸入一致。其余時(shí)刻均為64H0101010101010101(路徑度量值都是1) 
- output [`WD_FSM-2:0] MMReadAddress; //5位,一次讀入8個(gè)狀態(tài)。32*8=64*4
output [`WD_FSM-1:0] MMWriteAddress; //6位,一次寫入4個(gè)狀態(tài)。64*4=256 MMReadAddress <= ACSSegment [`WD_FSM-2:0]; //低五位。0-31 MMWriteAddress = ACSSegment; //寫地址6bit 為什么讀地址是五位,寫地址是6位。 因?yàn)樗膫(gè)狀態(tài),有8個(gè)分支,對(duì)應(yīng)著前面8個(gè)狀態(tài)。所以需要讀出8個(gè)狀態(tài)的路徑度量值。 如當(dāng) ACSSegment為ABCDEF時(shí),他對(duì)應(yīng)的4個(gè)狀態(tài)是這樣,它對(duì)應(yīng)的前八個(gè)狀態(tài)一定是BCDEF對(duì)應(yīng)的8個(gè)狀態(tài)。前后狀態(tài)只有一位不同,相當(dāng)于右移一位,輸入放最高位。所以只需要ACSSegment低五位,就可以讀出對(duì)應(yīng)的前8個(gè)狀態(tài)路徑度量值。另一方面,讀地址5BIT,尋址32個(gè),即32*8=256,實(shí)現(xiàn)256個(gè)狀態(tài)的讀取。32個(gè),32*8=256個(gè)狀態(tài)。寫地址6BIT,尋址64個(gè),一次寫4個(gè)狀態(tài),64*4=256,完成256個(gè)狀態(tài)的存入。 

以上8個(gè).v文件下載(verilog程序):
維特比編碼譯碼器.zip
(1.49 MB, 下載次數(shù): 87)
2022-3-28 20:27 上傳
點(diǎn)擊文件名下載附件
|