NRZ(不归零码)转换位Manchester码的verilog实现


码字转换器能够将数据流变换成一种已编码的格式,使接受机能够恢复数据。接下来介绍四种常用的串行编码方法。

如果非归零码(NRZ)格式的数据流中,没有1或0的长序列,那么采用锁相环电路PLL就可以从该线数据中恢复出时钟(即将其自身与数据时钟同步);如果非归零反转码(NRZI)或者归零码(RZ)格式的数据流中不存在0的长序列,时钟就可以从数据流中恢复出来。由于曼彻斯特(Manchester)码从数据中恢复时钟时与数据无关,因而很有吸引力,不过它需要更大的带宽。

首先给出Mealy型状态机表示的转换器代码及其测试代码

/*Mealy型状态机输出不仅与当前状态有关,还与输入有关*/
module NRZ_to_Manchester_Mealy(
    output reg B_out,
    input B_in, clk, reset_b
);
    parameter S_0=2'd0,
        S_1=2'd1,
        S_2=2'd2,
        dont_care_state=2'bx,
        dont_care_out=1'bx;
    reg[1:0] state, next_state;
    always@(posedge clk or negedge reset_b)
        if(!reset_b)
            state<=S_0;
        else
            state<=next_state;
    always @(state, B_in)begin
        //这里的敏感列表最好不要包含B_in,否则会有无效输出
        //Mealy型状态机输出虽然与输入有关,但不一定因输入而变化,只会
        //因输入有不同的变化
        B_out=0;
        case(state)
            S_0:if(B_in)begin
                B_out=1;
                next_state=S_1;
            end
            else
                next_state=S_2;
            S_1:
                next_state=S_0;
            S_2:begin
                next_state=S_0;
                B_out=1;
            end
            default:begin
                next_state=dont_care_state;
                B_out=dont_care_out;
            end
        endcase
    end
endmodule

测试代码:

module NRZ_to_Manchester_Mealy_tb;
    reg clk, reset_b;
    reg B_in;
    wire B_out;
    
    reg count;
    
    initial begin
        clk=0;
        reset_b=1;
        B_in=0;
        count=0;
        #20 reset_b=0;
        #10 reset_b=1;
        #10000 $finish;
    end
    
    initial begin
        $dumpfile("dump.lxt");
        $dumpvars(0,NRZ_to_Manchester_Mealy_tb);
    end

    initial
        forever #10 clk=!clk;

    always @(posedge clk)
        count=count+1;
    always @(negedge clk)
        if(count)
            B_in={$random}%2;
    
    NRZ_to_Manchester_Mealy uut(
        .B_out(B_out),
        .B_in(B_in),
        .clk(clk),
        .reset_b(reset_b)
    );
endmodule

对于Moore型状态机所表示的转换器,输出只与状态有关,而与输入无关。在下面的代码中B_out只受next_state影响,如果由state确定B_out,输出会增加一个时钟周期的延时。

同时Moore型状态机必须为每一种情况定义一个状态,以便输出能够完全依靠状态决定。转换器代码如下:

module NRZ_to_Manchester_Moore(
    output reg B_out,
    input B_in,
    input clk,reset_b
);
    parameter S_0=2'b00,
        S_1=2'b01,
        S_2=2'b10,
        S_3=2'b11,
        dont_care_state=2'bxx,
        dont_care_out=1'bx;
    reg[1:0] state, next_state;
    always @(posedge clk or negedge reset_b)
        if(!reset_b)
            state<=S_0;
        else
            state<=next_state;
    always @(state)begin
        case(state)
            S_0:if(B_in)
                next_state=S_1;
            else
                next_state=S_2;
            S_1:
                next_state=S_3;
            S_2:
                next_state=S_0;
            S_3:if(B_in)
                next_state=S_1;
            else
                next_state=S_2;
        endcase
    end
    always @(next_state)begin
        B_out=0;
        case(next_state)
            S_0:B_out=1;
            S_1:B_out=1;
            S_2:B_out=0;
            S_3:B_out=0;
        endcase
    end
endmodule

测试代码同Mealy型转换器相同,不再赘述。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM