• HDB3编码器


    一、HDB3 码介绍

    三阶高密度双极性码(英语:High Density Bipolar of Order 3 code,简称:HDB3码)是一种适用于基带传输的编码方式。它是一种 AMI 码的改进型, HDB3 码保持了 AMI 码极性反转的特点, 且减少了连 “0” 的长度,有利于接收端从基带信号中提取定时信息,低频成分少, 提取同步时钟方便, 有内在检错能力等优点, 是 CCITT(国际电报电话咨询委员会) 推荐的使用码型之一, 广泛的应用于数字基带通信。

    HDB3 码有以下特点 :基带信号无直流成分,且只有很小的低频成分;连 0串符号最多只有 3 个,利于定时信息的提取;不受信源统计特性的影响,对定时信号的恢复十分有利,而成为普遍使用的基带传输码之一。 在 AMI 码中,如果连续的较长的一段序列为 “0”码, 则接收端会因为长时间无交替变化波形的控制而失去同步信号,而 HDB3 码克服了 AMI 码的上述缺点。此外, HDB3码还具有频谱能量主要集中在基波频率以下,占用频带较窄等特点。

    二、编码规则

    1、连0的个数不超过3时,规则与AMI相同,即0不变,1变为-1、+1交替;

    2、若连0的个数超过3,则将每4个0看作一小节,定义为B00V,B可以是-1、0、+1,V可以是-1、+1;

    3、B和V具体值满足以下条件:V和前面相邻非0符号极性相同;不看V时极性交替;V与V之间极性交替;

    4、一般第一个B取0,第一个非0符取-1。

    由于V会破坏极性交替的规律、B有3种变化以满足规则,所以V称为破坏脉冲、B称为调节脉冲,B00V称为取代节、破坏节。

    HDB3编码举例

    代码

    1

    0

    0

    0

    0

    1

    1

    0

    0

    0

    0

    0

    1

    HDB3

    +1

    0

    0

    0

    +1

    -1

    +1

    -1

    0

    0

    -1

    0

    +1

    V/B

           

    +V

       

    -B

       

    -V

       

    三、HDB3 码编程实现

    3.1、编码器要求

    HDB3编码器输入信号为: 一路串行2.048MB/S合路数据流,一路2.048MB/S位同步时钟脉冲。

    HDB3编码器输出信号为: 一路串行2.048MB/S合路HDB3编码的正极性数据流H+,一路串行2.048MB/S合路HDB3编码的负极性数据流H-,一路2.048MB/S位同步时钟脉冲。

    3.2、编码器总体思想

    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码元同极性,即:在同端口输出。

    3.3、HDB3编码VHDL语言设计方案提示:

    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的时候同时把信息流变成双相码)。本设计的HDB3码的编码器模型框图见图 1。

    image

    3.3.1、插 V模块实现

    当出现 4个连 0串时, 把第 4个 0变换成符号 V(V可以是逻辑 1———高电平 ), 而在其他情况下,则保持消息代码的原样输出。同时 ,为了减少后面工作的麻烦,在进行插 V时, V用 11标识, 1用01标识, 0用 00标识。插 V符号的流程见图 2。

    image

     

    3.3.2、插 B模块实现

    插 B模块的功能是保证附加 V符号后的序列不破坏“极性交替反转”造成的无直流特性 ,即当相邻 V符号之间有偶数个非 0符号时, 把后一小段的第 1个0变换成一个非破坏符号———B符号 。图 3所示为实现插 B功能的流程图 。

    image

    3.3.3、单极性变双极性的实现

    根据 HDB3码的编码规则 ,V的极性是正负交替翻转的,余下的 1和 B看成为一体且是正负交替翻转的 ,同时满足 V的极性与前面的非 0码极性一致,由此可以单极性变双极性的实现。V、B、1前面进程已经分别用双相码 11、10、01表示, 所以在此基础上从单极性变双极性的实现比较简单。根据编码规则, B符号的极性与前一非零符号相反, V极性符号与前一非零符号一致。因此将 V单独拿出来进行极性变换,余下的 1和 B看成一体进行正负交替 ,这样就完成了 HDB3的编码。

    3.4、HDB3编码器代码

    --hdb3编码器
    --输入:一路串行2.408mb/s的合路数据流和一路2.048mb/s的时钟脉冲.
    --输出:2.048mb/s hdb3编码正负极性的数据流,和一路2.048mb/s时钟脉冲.
    -- hdb3码用两位矢量表示:用01表示+1,用00表示00,用10表示-1.
    library ieee;
    use ieee.std_logic_1164.all;
    entity hdb3_encoder is
    port(codein:in std_logic;
        clk:in std_logic;
        clr:in std_logic;
        codeout:out std_logic_vector(1 downto 0)
    );
    end entity hdb3_encoder;
    
    architecture encoder of hdb3_encoder is
        signal codeoutv:std_logic_vector(1 downto 0);        --作为插入的v进程存储处理的编码,用11
        signal count0:integer:=0;                            --数4个连0
        signal s0:std_logic_vector(4 downto 0):="00000";      --两个5位寄存器
        signal s1:std_logic_vector(4 downto 0):="00000";    
        signal count1:integer range 1 downto 0;             --数两个v之间1的奇偶
        signal codeoutb:std_logic_vector(1 downto 0);
        signal clkb:std_logic;
        signal s3:std_logic_vector(1 downto 0);
        signal flag1b:integer range 1 downto 0;
        signal flagv:integer range 1 downto 0;
        signal firstv:integer range 0 to 1;
        component dff                            --实例化d触发器,用来移位
            port(d:in std_logic;
            clk:in std_logic;
            q:out std_logic);
        end component;
    begin
    --插入V
    process(clk,clr)        begin
                if(rising_edge(clk))then    --上升沿触发
                    if(clr='1')then
                        codeoutv<="00";
                        count0<=0;
                    else
                    case codein is                  --clr=0时,才编码
                        when '1' => codeoutv<="01";
                               count0<=0;               
                        when '0'=>
                                if(count0=3)then
                                    codeoutv<="11";   --4个连0插入v
                                    count0<=0;       
                                else
                                    count0<=count0+1;
                                    codeoutv<="00";
                                end if;
                        when others=>
                            codeoutv<="00";
                            count0<=count0;
                    end case;
                    end if;
                end if;
    end process ;
    s0(0)<=codeoutv(0);
    s1(0)<=codeoutv(1);
    ds11:dff port map(s1(0), clk, s1(1));           --移位
    ds01:dff port map(s0(0), clk, s0(1));
    ds12:dff port map(s1(1), clk, s1(2));
    ds02:dff port map(s0(1), clk, s0(2));
    ds13:dff port map(s1(2), clk, s1(3));
    ds03:dff port map(s0(2), clk, s0(3));
    bclk: clkb<= not clk;
    --插入B
    process(clkb)
    begin
        if(rising_edge(clkb))then    
            if(codeoutv="11")then    
                if(firstv=0)then        
                    count1<=0;
                    firstv<=1;
                    s1(4)<=s1(3);
                    s0(4)<=s0(3);
                else
                    if(count1=0)then
                        s1(4)<='1';            --插入b
                        s0(4)<='0';
                        count1<=0;
                    else
                        s1(4)<=s1(3);
                        s0(4)<=s0(3);
                        count1<=0;
                    end if;
                end if;
            elsif(codeoutv="01")then 
                count1<=count1+1;
                s1(4)<=s1(3);
                s0(4)<=s0(3);
            else
                s1(4)<=s1(3);
                s0(4)<=s0(3);
                count1<=count1;
            end if;
        end if;
    end process ;
    codeoutb<=s1(4)&s0(4);
    --极性翻转
    process(clk)
    begin
        if(rising_edge(clk))then
            if((codeoutb="01")or(codeoutb="10"))then
                if(flag1b=1)then                    --fla1b标志1和V的极性
                    codeout<="01";                --输出+1
                    flag1b<=0;
                else
                    codeout<="10";                --输出-1
                    flag1b<=1;
                end if;
            elsif(codeoutb="11")then                --V的极性变化
                    if(flag1b=1)then
                        codeout<="10";
                    else
                        codeout<="01";
                    end if;
            else
                codeout<="00";                    --0的极性不需要变化
                flag1b<=flag1b;
            end if;
        end if;
    end process ;
    end encoder;

    仿真波形图:

    1、输入 1 0 0 0 0 1 1 0000000000…

    image

    2、输入全0

    image

    3、输入全1

    image

  • 相关阅读:
    【转】extern "C"的含义和用法
    python的shelve库
    【转】TCP是流传输协议,UDP是包传输协议
    【转】TCP慢启动、拥塞避免、快速重传、快速恢复
    【转】C/C++多线程编程中什么情况下需要加volatile?
    【转】C++对象是创建在堆上,还是在栈上?
    【转】腾讯高级工程师:一道面试题引发的高并发性能调试思考
    【转】C++类的sizeof大小
    【转】C编译器内存对齐
    【转】c++中使用memset初始化类对象
  • 原文地址:https://www.cnblogs.com/kwinwei/p/9373957.html
Copyright © 2020-2023  润新知