通訊原理---FPGA---HDB3譯碼
參考我的上兩篇HDB3編碼,給出HDB3譯碼的Verilog實現
https://blog.csdn.net/dengfenglai123/article/details/79674063(編碼)
https://blog.csdn.net/dengfenglai123/article/details/79675933(編碼--續)
譯碼規則主要參考下面的資料
https://baike.baidu.com/item/HDB3%E7%A0%81/3815309?fr=aladdin(譯碼主要參考資料)
(1)若3連“0”前後非零脈衝同極性,則將最後一個非零元素譯為零,如+1000+1 就應該譯成“10000;若2連 “0”前後非零脈衝極性相同,則兩零前後都譯為零,如-100-1應譯為0000
(2)將-1、+1變成1,0就輸出0,即輸入為“10”或“01”時輸出“1”,輸入為“00”時輸出“0”
在判斷過程中需要對正在判斷的碼的前面的碼進行操作,需要使用移位暫存器(否則前面的碼已經輸出,無法更改),在判斷時需要特別注意在比較3連“0”或2連“0”時的前後脈衝極性時,要找準當前的codein和誰比,在3連“0”時要和buffer3(前面第4個數)比,在在2連“0”時要和buffer2(前面第3個數)比,這部分涉及時序的問題,和非阻塞賦值“<=”有關,大家如果弄不清楚可以畫個移位暫存器的圖或者波形圖,我在這地方耗費了不少時間,最後畫個圖就清楚自己錯在哪了
此外,還有一個Verilog的語法問題以前沒有注意到,這次程式設計遇到了,記錄一下,作為我的學習筆記,也希望大家不要犯這種錯誤。
Error (10028): Can't resolve multiple constant drivers for net "buffer1[0]" at decode.v(47)
原本移位暫存器寫在一個單獨的always裡面的,這樣在判斷到需要將原來的V和B變為0時,因為是並行的,就會有兩個訊號同時要操作buffer0(或者buffer3),那麼就沒有辦法判斷到底該接收哪一個的賦值,這是不允許的,所以將移位暫存器和對buffer的操作放在了一個always裡,這時候,對於“<=”來說,若有多個賦值,會接收最後一個賦值的訊號。
always @ ( posedge clk or negedge rst_n )
begin
if( !rst_n ) begin
count0 <= 0;
end
else begin
buffer0 <= codein; //移位暫存器延時
buffer1 <= buffer0;
buffer2 <= buffer1;
buffer3 <= buffer2;
buffer4 <= buffer3;
if( codein == 2'b01 || codein == 2'b10 ) begin //輸入1
if( count0 == 2'b10 ) begin
if( codein == buffer2 ) begin //此處非常關鍵
buffer0 <= 2'b00;
buffer3 <= 2'b00;
end
end
else if( count0 == 2'b11 ) begin
if( codein == buffer3 ) //此處非常關鍵
buffer0 <= 2'b00;
end
count0 <= 0;
codeout_2 <= buffer4;
end
else if( codein == 2'b00 ) begin //0
count0 <= count0 + 1;
codeout_2 <= buffer4;
end
end
end
always @ ( posedge clk )
begin
if( codeout_2 == 2'b00 ) begin
codeout <= 1'b0;
end
else if( codeout_2 == 2'b10 || codeout_2 == 2'b01 ) begin
codeout <= 1'b1;
end
end
原輸入:
訊息碼: 1 0 0 1 1 0 0 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 1 0
AMI碼: +1 0 0 -1 +1 0 0 0 0 -1 0 +1 -1 0 +1 0 0 0 0 -1 +1 -1 +1 0
加V : +1 0 0 -1 +1 0 0 0 +V -1 0 +1 -1 0 +1 0 0 0 +V-1 +1 -1 +1 0
加B : +1 0 0 -1 +1 0 0 0 +V -1 0 +1 -1 0 +1 -B 0 0 -V -1 +1 -1 +1 0