2021-08-29

曼切斯特 编解码 实现


一、曼切斯特码简介

曼彻斯特编码,也叫做相位编码(PE),是一个同步时钟编码技术。

曼彻斯特码是通过电平的跳变来对二进制数据“0”和“1”进行编码的。有两种不同的数据约定:第一种约定是由G. E. Thomas,Andrew S. Tanenbaum等人在1949年提出的,它规定“0”是由低到高的电平跳变表示,“1”是由高到低的电平跳变;第二种约定则是在IEEE 802.4(令牌总线)以及IEEE 802.3 (以太网)中规定,按照这样的说法,由低到高的电平跳变表示“1”,由高到低的电平跳变表示“0”。

曼切斯特编码如下图所示

在这里插入图片描述

二、曼彻斯特编解码器设计

曼彻斯特编码:本文采用第二种编码约定,即“1”的时候输出“01”,“0”的时候输出“10”
曼彻斯特解码:由编码器的特定,当曼彻斯特编码数据流中出现“00”,则“00”前后的码元必定是“1”;如果曼彻斯特编码数据流中出现“11”,则“11”前后的码元必定是“0”,因此,我们可以将“00”与“11”作为曼彻斯特码译码的标志位。 我们使用缓存器,储存上一个时钟采集到的信号和当前时钟采集到的信号,当缓存器的内容是“01”时,输出“1”;当缓存器的内容是“10”时,输出“0”;当缓存器的内容是“00”或“11”时,输出维持不变。

三、曼彻斯特编解码器实现

1.曼切斯特编码

曼切斯特编码模块如下图所示
在这里插入图片描述
Bit_out:表示要编码的bit数据
Bit_out_valid:表示当前bit数据有效
Bit_out_tready:表示当前bit以完成编码输出
Mqst_BitOut:表示曼切斯特编码后输出

module Mqst_Module(
        input   clk,   //32M  
        
        input   Bit_out,
        input   Bit_out_valid,
        output  Bit_out_tready,
        
        output  Mqst_BitOut  //2M  
    );
    
   
    reg             Mqst_BitOut=0;
    reg     [1:0]   send_tmp  = 0; 
    reg     [7:0]   clk_cnt = 0;
    
    reg     [2:0]   state_reg = 0;
    
    reg             Bit_out_valid_r1 = 0;
    reg             Bit_out_valid_r2 = 0;
    wire            Bit_out_valid_posedge = Bit_out_valid_r1 && (~Bit_out_valid_r2);
    
    always @(posedge clk) begin
        Bit_out_valid_r1<=Bit_out_valid;
        Bit_out_valid_r2<=Bit_out_valid_r1;
    end
    
        
    always @ (posedge clk) begin  
        case (state_reg)    
        0:begin                 //数据有效后,开始编码
            if(Bit_out_valid_posedge)
                state_reg<=1;
        end
        
        1:begin
            if(clk_cnt==32/2-1)   begin//输入时钟32M、曼切斯特速率2M
                clk_cnt<=0;
                if(Bit_out_valid==0)
                    state_reg<=0;
            end                                    
            else
                clk_cnt<=clk_cnt+1;
        end
       endcase 
    end
    
    always @ (posedge clk) begin   //编码 0:编码为2'b10  1:编码为2’b01
        if(Bit_out_valid==1)
        begin
            if(Bit_out==0)
                send_tmp<=2'b10;
            else
                send_tmp<=2'b01;
         end
         else
                send_tmp<=2'b00; 
    end
    
    always @ (posedge clk) begin  //曼切斯特编码输出
        if(state_reg==1)
        begin
            if(clk_cnt==0)
                Mqst_BitOut<=send_tmp[1];
            else if(clk_cnt==8)
                Mqst_BitOut<=send_tmp[0];
        end
        else
                Mqst_BitOut<=0;
    end
    
    assign   Bit_out_tready = (clk_cnt==13) ? 1'b1 :1'b0;  //提前2个时钟置高
    
endmodule

2.曼切斯特解码

曼切斯特解码模块如下图所示

在这里插入图片描述

Bit_in:表示解码的bit数据
Bit_in_valid:表示解码的bit数据有效
Mqst_BitIn:表示要解码的曼切斯特编码输入

module Mqst_Demodule(
        input   clk,   //32M  
        
        output   Bit_in,
        output   Bit_in_valid,        
        input    Mqst_BitIn       //2M  
    );
    
    
    reg             Bit_in  = 0;
    reg             Bit_in_valid  = 0;
    reg     [7:0]   clk_cnt = 0;
    reg             bit_cnt = 0;
    reg     [2:0]   Mqst_BitIn_tmp = 0;
    
    reg             Bit_sync  = 0;  //同步  当收到2'b00或2'b11  作为解码的同步标志
    
    reg     [2:0]   state_reg = 0;
    
    reg             Mqst_BitIn_r1 = 0;
    wire            Mqst_BitIn_posedge = Mqst_BitIn && (~Mqst_BitIn_r1);

    always @(posedge clk) begin
        Mqst_BitIn_r1<=Mqst_BitIn;
    end
    
        
    always @ (posedge clk) begin
        case (state_reg)
        0:begin
            clk_cnt<=0;
            Bit_sync<=0;
            if(Mqst_BitIn_posedge)
                state_reg<=1;
        end
        
        1:begin 
            if(clk_cnt==7)  //输入时钟32M、曼切斯特速率2M
                clk_cnt<=0;                                                         
            else
                clk_cnt<=clk_cnt+1; 
                             
            if(clk_cnt==7)
            begin                
                if((Mqst_BitIn_tmp[1:0]==2'b00 || Mqst_BitIn_tmp[1:0]==2'b11) && Bit_sync==0)//寻找 同步头   
                    Bit_sync<=1;                    
                else if((Mqst_BitIn_tmp[1:0]==2'b00 || Mqst_BitIn_tmp[1:0]==2'b11) && bit_cnt==1) //同步头 丢失后 重新寻找同步头
                    Bit_sync<=0;
                else if(Mqst_BitIn_tmp[2:0] == 3'b000)  //当收到3个零时,数据错误,重新开始解码
                    state_reg<=0;                 
            end   
                              
        end       
       endcase 
    end
    

    always @ (posedge clk) begin    //当 bit_cnt==1 时,才解码输出
        if(clk_cnt==4 && Bit_sync==1)
            bit_cnt<=bit_cnt+1;
    end
    
    
    always @ (posedge clk) begin  //数据缓存
        if(clk_cnt==4)
            Mqst_BitIn_tmp[2:0]<={Mqst_BitIn_tmp[1:0],Mqst_BitIn};
    end
    
    always @ (posedge clk) begin  //曼切斯特解码
        if(clk_cnt==7 && bit_cnt==1) begin
            case(Mqst_BitIn_tmp[1:0])
                2'b01:Bit_in<=1;
                2'b10:Bit_in<=0;
                default:Bit_in<=0;
         endcase
       end
    end
    
    always @ (posedge clk) begin  //曼切斯特 解码正确后Bit_in_valid有效
        if(bit_cnt==1 && clk_cnt==7) begin
            if(Mqst_BitIn_tmp[1:0]==2'b01 || Mqst_BitIn_tmp[1:0]==2'b10)  
                Bit_in_valid<=1;
             else
                Bit_in_valid<=0;               
        end
        else
               Bit_in_valid<=0; 

    end


        
endmodule 

3.曼切斯特编解码仿真

编写曼切斯特编解码顶层模块,顶层模块如下图所示,顶层模块使用AXI-Lite接口。

在这里插入图片描述
仿真时,将Mqst_BitOut与Mqst_BitIn直接相连

module Mqst_top(
    input   clk,
    input   rst_p,
    
    input [7:0]   data_in,
    input         data_in_valid,
    output        data_tready,
    
    output  [7:0] data_out,
    output        data_out_valid,  
    
    input         Mqst_BitIn,
    output        Mqst_BitOut    
    );
    
    
    reg         Bit_out =0 ;      //1bit发送数据
    reg         Bit_out_valid =0 ;//1bit发送数据有效信号
    wire        Bit_out_tready;  //发送1bit结束
    
    wire        Bit_in  ;        //1bit解码数据
    wire        Bit_in_valid;    //1bit解码数据有效信号
    
    reg     [7:0]   data_in_reg;
    reg     [7:0]   bit_cnt = 0;
    reg     [2:0]   state_reg = 0;
    
    reg             data_in_valid_r1 = 0;
    reg             data_in_valid_r2 = 0;
    wire            data_in_valid_posedge = data_in_valid_r1 && (~data_in_valid_r2);
    
    
/    
    always @(posedge clk) begin
        data_in_valid_r1<=data_in_valid;
        data_in_valid_r2<=data_in_valid_r1;
    end
    
    
        always @ (posedge clk) begin  //编码8bit,
        case (state_reg)
        0:begin
            if(data_in_valid_posedge)
            begin
                Bit_out_valid<=1;
                state_reg<=1;
            end
        end
        
        1:begin
            if(Bit_out_tready)  begin              
                if(bit_cnt==7)   begin
                    bit_cnt<=0;
                    if(data_in_valid==0) begin
                        Bit_out_valid<=0;
                        state_reg<=0;
                    end
                end                                    
                else
                    bit_cnt<=bit_cnt+1;
            end
        end
       endcase 
    end
    
     always @ (posedge clk) begin  //字节数据输入
        if(bit_cnt==0)
            data_in_reg<=data_in;
     end
     
     always @ (posedge clk) begin  //bit数据  进入曼切斯特编码模块
        case(bit_cnt)
            0:Bit_out<=data_in_reg[7];
            1:Bit_out<=data_in_reg[6];
            2:Bit_out<=data_in_reg[5];
            3:Bit_out<=data_in_reg[4];
            4:Bit_out<=data_in_reg[3];
            5:Bit_out<=data_in_reg[2];
            6:Bit_out<=data_in_reg[1];
            7:Bit_out<=data_in_reg[0];
        endcase
     end
    
    assign    data_tready  = (bit_cnt==7)   ?  1: 0;
    
///曼切斯特 编码//    
    
    
    Mqst_Module Mqst_tx(
        .clk(clk),
        .Bit_out(Bit_out),
        .Bit_out_valid(Bit_out_valid),
        .Bit_out_tready(Bit_out_tready),
        .Mqst_BitOut(Mqst_BitOut)    
    );
       
 ///曼切斯特 解码//    
   Mqst_Demodule Mqst_rx(
        .clk(clk),
        .Bit_in(Bit_in),
        .Bit_in_valid(Bit_in_valid),
  
        .Mqst_BitIn(Mqst_BitOut)//Mqst_BitIn    
    );
    
    
    
    
   
endmodule

仿真文件入下所示,每次发送完8bit,data_in[7:0]加1

module test_mqst(

    );
    
    
    reg   clk;
    reg   rst_p;
    
    reg [7:0]   data_in = 0;
    reg         data_in_valid;
    wire        data_tready;
    
    wire  [7:0] data_out;
    wire        data_out_valid;  
    
    reg         Mqst_BitIn;
    wire        Mqst_BitOut; 
    
        Mqst_top Mqst_top(
        .clk(clk),
        .rst_p(rst_p),
        .data_in(data_in),
        .data_in_valid(data_in_valid),
        .data_tready(data_tready) ,
        .data_out(data_out),
        .data_out_valid(data_out_valid),
        .Mqst_BitIn(Mqst_BitIn) ,
        .Mqst_BitOut(Mqst_BitOut)
           
    );
    
    initial   begin
        #0
        clk = 0;
        rst_p =1;
        data_in_valid = 0;
        #100
        
        rst_p = 0;
        data_in_valid = 1;
      
    end
    
    always #15 clk =~clk;
   
    always @ (posedge data_tready) begin
        if(data_in==11)
        begin
            data_in<=0;
            data_in_valid<=0;
        end
        else
            data_in<=data_in+1;
     end
    
    
endmodule

仿真结果如下图所示

在这里插入图片描述
图中,解码时,只有同步上之后数据才会输出,当连续收到3个0时,重新开始解码

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mhlicq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值