加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

HDB3编码的verilog实现

(2013-08-25 12:39:34)
标签:

杂谈

分类: FPGA

http://s4/middle/6831d971zx6C7XQwp0f13&690编码的基本规则:

  1. 检查消息码中"0"的个数。当连"0"的个数小于等于3时,http://s11/middle/6831d971zx6C7XQzD629a&690码与AMI码一样,+1与-1交替;
  2. 当连"0"的个数超过3个时,将每4个连"0"化作为1小节,定义为B00V,称为破坏节,其中V称为破坏脉冲,而B称为调节脉冲;
  3. V与前一个相邻的非"0"脉冲的极性相同,并且要求相邻V直接的符号必须交替。V的取值为+1或者-1;
  4. B的取值可选0,-1,+,以使V同时满足(3)的两个要求;
  5. V码后面的传号码极性也要交替。

http://s8/middle/6831d971zx6C7XQECEvc7&690编码过程是非常复杂的,如果我们根据其编码规则一步一步的设计编码电路,需要耗费非常多的寄存器,因为我们在判断是否加入V或者B的过程中,需要根据当前状态修改过去的状态,这样就需要用寄存器来存储前面的状态。这种方案在实时处理系统中是很难接受的。

本方案改变了http://s11/middle/6831d971zx6C7XQI54u6a&690编码的处理顺序,先对数据流进行填V操作,然后以流水线的方式对数据流填B,最后再将处理后的数据流进行AMI编码。这样做的好处在于一方面可以提高系统的实时性,一方面还能减少寄存器的数量,节省开发资源。

系统框图设计:整个编码过程分成3个模块来实现,第一个模块对数据流进行填"V";第二个模块对数据流进行填"B"操作;第三个模块复杂对填V、填B后的数据流做AMI编码操作。

http://s5/middle/6831d971zx6C7XQLia8e4&690

    各模块的具体实现:

  1. 填"V"模块的实现

该模块用一个计数器cnt来计数连0的个数,当连0个数为4时,对第个0所在的位置填V,同时计数器清零;如果当前数据不为0,在直接输出,同时计数器清零。

module plus_v(

    clk,

    rst_n,

    data_in,

    data_out

);

    input clk;            //system clock 50MHz

    input rst_n;        //system reset, active low

    input data_in;        //data for coding

    output reg [1:0] data_out;    //data output after plus v

    

    reg [2:0] cnt;        //counter the number of 0

    

    always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            cnt <= 2'd0;

            data_out <= 2'b00;

        end

        else

    end begin

        case(data_in)

            1'b0 : begin

                if(cnt==2'b11)begin

                    data_out <= 2'b11;

                    cnt <= 2'b00;

                end

                else begin

                    data_out <= 2'b00;

                    cnt <= cnt + 2'b01;

                end

            end

            1'b1 : begin

                data_out <= 2'b01;

                cnt <= 2'b00;

            end

            default : begin

                data_out <= 2'b00;

                cnt <= 2'b00;

            end

        endcase

    end

endmodule    

该模块处理的数据流是50MHz的比特流,如果处理的数据流不为50MHz,则需要修改系统时钟,或者加入分频电路。

 

http://s2/middle/6831d971zx6C7XQMOE9a1&amp;690

  1. 填"B"模块的实现

数据处理流程图

http://s14/middle/6831d971zx6C7XQSM4lbd&amp;690

Verilog实现

module plus_b(

    clk,

    rst_n,

    

    data_in,

    data_out

);

 

input clk;

input rst_n;

input [1:0] data_in; //00:0; 01:1; 11:V.

output [1:0] data_out;

 

reg [3:0] D0;

reg [3:0] D1;

reg cnt;        //0: even number 1:odd number

reg flagv;        //0: the first V 1:not the first V

 

always @(posedge clk or negedge rst_n)begin

    if(!rst_n)begin

        D0 <= 4'd0;

        D1 <= 4'd0;

        cnt <= 1'b0;

        flagv <= 1'b0;

        data_out <= 2'b00;

    end

    else begin

        case(data_in)

        2'b00:begin

            D0 <= {D0[2:0],data_in[0]};

            D1 <= {D1[2:0],data_in[1]};

            data_out <= {D1[3],D0[3]};

        end

        2'b01:begin

            D0 <= {D0[2:0],data_in[0]};

            D1 <= {D1[2:0],data_in[1]};

            data_out <= {D1[3],D0[3]};

            cnt <= cnt + 1'b1;

        end

        2'b11:begin

            if(flagv!=1)begin

                cnt <= 1'b0;

                flagv <= 1'b1;

                D0 <= {D0[2:0],data_in[0]};

                D1 <= {D1[2:0],data_in[1]};

                data_out <= {D1[3],D0[3]};

            end

            else if(cnt!=0)begin

                cnt <= 1'b0;

                D0 <= {D0[2:0],data_in[0]};

                D1 <= {D1[2:0],data_in[1]};

                data_out <= {D1[3],D0[3]};

            end

            else begin

                D0 <= {1'b0,D0[1:0],data_in[0]};

                D1 <= {1'b1,D1[1:0],data_in[1]};

                data_out <= {D1[3],D0[3]};

            end

        end

        default:begin

            D0 <= 4'd0;

            D1 <= 4'd0;

            cnt <= 1'b0;

            flagv <= 1'b0;

            data_out <= 2'b00;

        end

        endcase

    end

end

 

endmodule

 

  1. AMI编码的实现

对数据流完成填V和填B操作后,就可以根据HDB3的编码规则将0原样输出,1和B用+1 -1交替代替。而V之间交替用+1 -1代替,且与前一个非0元素的符号保持一致。

 

系统框图如下:

http://s16/middle/6831d971zx6C7XQUedh4f&amp;690

Verilog设计源码

module ami_code(

    clk,

    rst_n,

    

    data_in,

    data_out

);

 

input clk;

input rst_n;

input [1:0] data_in;

output reg [1:0] data_out;

 

reg flag;

 

always @(posedge clk or negedge rst_n)begin

    if(!rst_n)begin

        flag <= 1'b0;

        data_out <= 2'b00;

    end

    else begin

        case(data_in)

            2'b00:begin

                data_out <= 2'b00;

            end

            2'b01,2'b10:begin

                if(flag==0)begin

                    data_out <= 2'b01;

                    flag <= 1;

                end

                else begin

                    data_out <= 2'b11;

                    flag <= 1'b0;

                end

            end

            2'b11:begin

                if(flag==0)begin

                    data_out <= 2'b11;

                end

                else begin

                    data_out <= 2'b01;

                end

            end

            default:begin

                flag <= 1'b0;

                data_out <= 2'b00;

            end

        endcase

    end

end

 

 

endmodule

 

至此,我们已经完成了HDB3编码各子模块的设计,最后的工作就是将这些子模块封装成一个模块。

module hdb3(

    clk,

    rst_n,

    

    data_in,

    data_out

);

input clk;        //50MHz

input rst_n;    //system reset, active at low

input data_in;    //

output[1:0] data_out;    //

 

wire [1:0] v_to_b,b_to_a;

 

 

plus_v U1(

    .clk(clk),

    .rst_n(rst_n),

    

    .data_in(data_in),

    .data_out(v_to_b)

);

 

plus_b U2(

    .clk(clk),

    .rst_n(rst_n),

    

    .data_in(v_to_b),

    .data_out(b_to_a)

);

 

ami_code U3(

    .clk(clk),

    .rst_n(rst_n),

    

    .data_in(b_to_a),

    .data_out(data_out)

);

 

endmodule

 

测试脚本如下:

`timescale 1 ns/ 1 ps

module hdb3_vlg_tst();

// constants

// general purpose registers

reg eachvec;

// test vector input registers

reg clk;

reg data_in;

reg rst_n;

// wires

wire [1:0] data_out;

 

// assign statements (if any)

reg [39:0]data_temp;

 

hdb3 i1 (

// port map - connection between master ports and signals/registers

    .clk(clk),

    .data_in(data_in),

    .data_out(data_out),

    .rst_n(rst_n)

);

initial begin

    clk = 0;

    forever #10 clk = ~clk;

end

 

initial begin

    rst_n = 0;

#1000 rst_n = 1;

#5000 $stop;

end

 

always @(posedge clk or negedge rst_n)begin

    if(!rst_n)begin

        data_temp <= 40'b1000_0100_0011_0000_0000_1110_0001_0000_1100_0011;

        data_in <= 1'b0;

    end

    else begin

            data_in <= data_temp[39];

            data_temp <= {data_temp[38:0],1'b0};

    end

end

 

endmodule

 

测试结果如下:

http://s13/middle/6831d971zx6C7XQYCQs0c&amp;690

从仿真结果可以看到,编码后的信号较输入信号有6个时钟周期的延时。

0

阅读 收藏 喜欢 打印举报/Report
前一篇:nano 命令集合
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有