银月
HDB3编码解码

HDB3编码解码

HDB3编码解码

编码方案

HDB3编码规则

1、对输入为1码元交替翻转编码,即:依次在H+和H-端口输出1;

2、对输入为0码元同时在H+和H-端口输出0;

3、当连续输入4个0码元,且与上一个连续0码元之间1码元为奇数个时,第四个0码元改为1码元,且与之前1码元的最后一个1码元同极性,即:在同端口输出;

4、当连续输入4个0码元,且与上一个连续4个0码元之间1码元为偶数个时,第一个0码元改为1码元,与之前1码元的最后一个1码元反极性,即:在不同端口输出,第四个0码元改为1码元,且与之前1码元的最后一个1码元同极性,即:在同端口输出。

HDB3编码设计方案

1、逐位处理输入输出数据,即:每输入一比特数据就判断处理,并在H+和H-端口同时输出一位比特脉冲.

2、为了能修改含本时钟之前4个时钟周期的输出比特,至少应移位缓存4比特输出

3、为了能处理本时刻输入的比特,应该至少已知以下状态信息:
1)、输出“1”时,确定下次1码元输出端口的确定,即极性是+或-;每输入一个“1”,极性反转一次,记录信息X
2)、更新“B00V”时,记录信息Y=1,当Y=1时,极性再反转一次X,(两次反转即同极性)
3)、开辟一个当前是否为连续“0000”;

记录两个连续“0000”之前连续1的个数记数,(即奇偶数)Z。

如何准确识别电路中的 1、V、B。因为 V和B符号是人为标志的符号, 但在电路中最终的表现形式还是逻辑电平 “1”。解决的方法是利用双相码 , 将其用二进制代码分别表示 。双相码的编码规则是:对每个二进制代码分别利用 2个不同相位的二进制码取代 。利用双相码就可以识别电路中的 1、V、B。也可以人为地加入一个标志符(其最终目的也是选择输出“1”的极性), 控制一个开关 ,使输出“1”的极性能按照编码规则进行变化。

本设计的总体思想并不是首先把消息代码变成 AMI码 ,而是进行 V符号的插入, B符号的操作, 最后完成单极性信号变成双极性信号的转换 (在插入V的时候同时把信息流变成双相码)

方案代码


//两个V之间1的个数是偶数个,要加B
always @(posedge clk_sys or negedge rst_n)
begin
    if(rst_n == 1'b0)
        polar_flag_4dly <= 1'b0 ;
    else if( (data_in_4dly == 1'b1)
            ||( (data_in_4dly == 1'b0)&&(mzero_flag == 1'b1)&&(mzero_flag_cnt == 2'h0)&&(odd_flag_4dly == 1'b0))
           )
        polar_flag_4dly <=#U_DLY ~polar_flag_4dly   ;
end
//输出1有3种情况:
//1.本身码流里的1 
//2.连0个数超过3个,至少4个,可能是000V,也可能是B00V
always @(posedge clk_sys or negedge rst_n)
begin
    if(rst_n == 1'b0)
        hdb3_data0_pre  <= 1'b0  ;
    else if(data_in_4dly == 1'b1)
        hdb3_data0_pre <=#U_DLY 1'b1    ;
    else if(mzero_flag == 1'b1)
    begin
        if( ((mzero_flag_cnt == 2'h0)&&(odd_flag_4dly == 1'b0))
            ||(mzero_flag_cnt == 2'h3)
          )
            hdb3_data0_pre <=#U_DLY 1'b1    ;
        else
            hdb3_data0_pre <=#U_DLY 1'b0    ;
    end
    else
        hdb3_data0_pre <=#U_DLY 1'b0    ;
end
//输出1的符号,是+1,还是-1。
always @(posedge clk_sys or negedge rst_n)
begin
    if(rst_n == 1'b0)
        hdb3_data1 <= 1'b0  ;
    else if(hdb3_data0_pre == 1'b1)
        hdb3_data1 <=#U_DLY polar_flag_4dly ;
    else
        hdb3_data1 <=#U_DLY 1'b0    ;
end
//输出是1,还是0
always @(posedge clk_sys or negedge rst_n)
begin
    if(rst_n == 1'b0)
        hdb3_data0 <= 1'b0   ;
    else
        hdb3_data0 <=#U_DLY hdb3_data0_pre  ;
        
end

解码方案

对于HDB3的编码来说,解码是相对比较简单的,主要实现内容就是寻找连续两个零与连续三个的零。插入V/B的情况是有两种,两个或三个零两端同极性,也就是要把代码二进制表示的“+1 0 0 0 +1”或“-1 0 0 0 -1”变成“1 0 0 0”,把“+1 0 0 +1”或“-1 0 0 -1”变成“0 0 0 0”,最后再把两位二进制表示的+1和-1都变成‘1’,两位二进制表示的0都变成一位二进制表示的‘0’就可以了。

方案代码


always@(posedge clk )begin
    if(data_vild)
        if(temp_reg1==5'b10001 && temp_reg0==5'b10001)
            temp_regout <=#U_DLY  5'b10000;
        else if(temp_reg1==5'b00000 && temp_reg0==5'b10001)
            temp_regout <=#U_DLY  5'b10000;
        else if(temp_reg1[3:0]==4'b1001 && temp_reg0[3:0]==4'b1001) 
            temp_regout <=#U_DLY  {temp_regout[4],4'b0000};
        else if(temp_reg1[3:0]==4'b0000 && temp_reg0[3:0]==4'b1001)   
            temp_regout <=#U_DLY  {temp_regout[4],4'b0000};
        else
            temp_regout <=#U_DLY  {temp_regout[3:0],temp_reg0[0]} ;
            
end
本文作者:银月
本文链接:https://qs77544.top/HDB3编码解码/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可