您的位置:首页 > 数码常识数码常识

fpga编解码(fpga曼彻斯特译码器设计)

2025-05-10人已围观

fpga编解码(fpga曼彻斯特译码器设计)
  实验简述将输入的数据流经过曼彻斯特编码器编码后经过解码器恢复为原来的输入序列。

  fpga曼彻斯特译码器设计实验简述

  一、曼彻斯特码简介

  曼彻斯特码(Manchester code),又称数字双向码、分相码或相位编码(PE),是一种常用的二源码线路编码方式之一,被物理层使用来编码一个同步位流的时钟和数据。在通信技术中,用来表示所要发送比特流中的数据宇定时信号所结合起来的代码。常用在以太网通信,列车总线控制,工业总线等领域。

  二、编码规则

  有两个输入时钟,一个是基带时钟(起同步信号作用),一个是频带时钟。输入的数据流是基带时钟域信号,经过编码后变成频带时钟域信号输出。曼彻斯特编码是将输入为1的变成输出前半拍为1,后半拍为0,输入为0的变成前半拍为0,后半拍为1的频带信号。

  三、时序图

  输入序列以101为例,经过编码后应为100110

  四、FPGA实现

  1、顶层架构

  2、信号说明

  3、顶层代码

  module manchester(clk_b, clk_f, rst_n, enc_in, enc_en, dec_out, dec_en);

  input clk_b, clk_f, rst_n;

  input enc_in;

  input enc_en;

  output dec_out;

  input dec_en;

  wire enc_out;

  manchester_enc ENC(

  .clk_f(clk_f),

  .clk_b(clk_b),

  .rst_n(rst_n),

  .enc_en(enc_en),

  .enc_in(enc_in),

  .enc_out(enc_out)

  );

  manchester_dec DEC(

  .clk_f(clk_f),

  .clk_b(clk_b),

  .rst_n(rst_n),

  .dec_en(dec_en),

  .enc_out(enc_out),

  .dec_out(dec_out)

  );

  endmodule

  4、编码模块

  采用状态机来实现编码模块。

  当检测到编码使能为高时,状态机开始执行,判断clk_b的值为1时,在S1状态等待,当clk_b的值为0时,判断输入的值是1还是0。(clk_b主要起基频同步作用)如果是1,跳转到S2状态,并将enc_out赋值为1。到S2状态后,无条件跳回S1状态,并将enc_out赋值为0。如果是0,跳转到S3状态,并将enc_out赋值为0。到S3状态后,无条件跳回S1状态,并将enc_out赋值为1。

  状态转移图如下:

  说明:圆圈代表状态,→ 代表转移,转移下面的文本框代表转移时的动作。以后文章的状态转移图均按此绘制。

  编码模块代码

  module manchester_enc(clk_f, clk_b, rst_n, enc_en, enc_in, enc_out);

  input clk_f, clk_b, rst_n;

  input enc_en;

  input enc_in;

  output reg enc_out;

  reg [2:0] state_c, state_n;

  localparam S1=3'b001;

  localparam S2=3'b010;

  localparam S3=3'b100;

  wire S12S2_start ;

  wire S12S3_start ;

  wire S22S1_start ;

  wire S33S1_start ;

  //四段式状态机

  //第一段:同步时序always模块,格式化描述次态寄存器迁移到现态寄存器(不需更改-

  always@(posedge clk_f or negedge rst_n)begin

  if(!rst_n)begin

  state_c <=S1;

  end

  else begin

  state_c <=state_n;

  end

  end

  //第二段:组合逻辑always模块,描述状态转移条件判斍

  always@(*)begin

  if(enc_en)

  case(state_c)

  S1:begin

  if(S12S2_start)begin

  state_n=S2;

  end

  else if(S12S3_start)begin

  state_n=S3;

  end

  else begin

  state_n=state_c;

  end

  end

  S2:begin

  if(S22S1_start)begin

  state_n=S1;

  end

  else begin

  state_n=state_c;

  end

  end

  S3:begin

  if(S33S1_start)begin

  state_n=S1;

  end

  else begin

  state_n=state_c;

  end

  end

  default:begin

  state_n=S1;

  end

  endcase

  else

  state_n=S1;

  end

  //第三段:设计转移条件

  assign S12S2_start=state_c==S1 && clk_b && !enc_in;

  assign S12S3_start=state_c==S1 && clk_b && enc_in;

  assign S22S1_start=state_c==S2 && 1;

  assign S33S1_start=state_c==S3 && 1;

  //第四段:同步时序always模块,格式化描述寄存器输出(可有多个输出-

  always @(posedge clk_f or negedge rst_n)begin

  if(!rst_n)begin

  enc_out <=1'b0; //初始匍

  end

  else if(enc_en)

  if((state_c==S1 && !enc_in) || (state_c==S3))begin

  enc_out <=1'b0;

  end

  else if((state_c==S1 && enc_in) || (state_c==S2))begin

  enc_out <=1'b1;

  end

  else begin

  enc_out <=1'b0;

  end

  else

  enc_out <=1'b0;

  end

  endmodule

  5、 解码模块

  解码模块也采用状态机实现,当检测到dec_en为高时,状态机才执行,判断clk_b的值,当clk_b为0时,在S1上等待,当clk_b为1时,判断enc_out的值,为1时跳转到S2状态,并将dec_out赋值为。S2状态无条件跳转到S1状态。为0时,跳转到S3状态并将dec_out赋值为0。S3状态无条件跳转到S1状态。

  状态转移图如下:

  解码模块代码

  module manchester_dec(clk_f, clk_b, rst_n, dec_en, enc_out, dec_out);

  input clk_f, clk_b, rst_n;

  input dec_en;

  input enc_out;

  output reg dec_out;

  reg [2:0] state_c, state_n;

  localparam S1=3'b001;

  localparam S2=3'b010;

  localparam S3=3'b100;

  wire S12S2_start ;

  wire S12S3_start ;

  wire S22S1_start ;

  wire S33S1_start ;

  always@(posedge clk_f or negedge rst_n)begin

  if(!rst_n)begin

  state_c <=S1;

  end

  else begin

  state_c <=state_n;

  end

  end

  //第二段:组合逻辑always模块,描述状态转移条件判斍

  always@(*)begin

  if(dec_en)

  case(state_c)

  S1:begin

  if(S12S2_start)begin

  state_n=S2;

  end

  else if(S12S3_start)begin

  state_n=S3;

  end

  else begin

  state_n=state_c;

  end

  end

  S2:begin

  if(S22S1_start)begin

  state_n=S1;

  end

  else begin

  state_n=state_c;

  end

  end

  S3:begin

  if(S33S1_start)begin

  state_n=S1;

  end

  else begin

  state_n=state_c;

  end

  end

  default:begin

  state_n=S1;

  end

  endcase

  else

  state_n=S1;

  end

  //第三段:设计转移条件

  assign S12S2_start=state_c==S1 && (!clk_b) && enc_out;

  assign S12S3_start=state_c==S1 && (!clk_b) && (!enc_out);

  assign S22S1_start=state_c==S2 && 1;

  assign S33S1_start=state_c==S3 && 1;

  //第四段:同步时序always模块,格式化描述寄存器输出(可有多个输出-

  always @(posedge clk_f or negedge rst_n)begin

  if(!rst_n)begin

  dec_out <=1'b0; //初始匍

  end

  else if(dec_en)

  if(state_c==S1 && (!clk_b) && enc_out)begin

  dec_out <=1'b1;

  end

  else if((state_c==S1 && (!clk_b) && (!enc_out)))begin

  dec_out <=1'b0;

  end

  else begin

  dec_out <=dec_out;

  end

  else

  dec_out <=1'b0;

  end

  endmodule

  6、仿真验证

  tb文件参考工程文件夹中的sim文件夹

  输入的数据流enc_in为1011,对应的曼彻斯特码应为10011010

  我们看到输入到编码模块的enc_in与解码模块的dec_out的输出是一样的

  再来看编码之后的数据流

  enc_out为10011010与结果一致

  解码模块图形

  上面就是小居数码小编今天给大家介绍的关于(fpga曼彻斯特译码器设计)的全部内容,希望可以帮助到你,想了解更多关于数码知识的问题,欢迎关注我们,并收藏,转发,分享。

  94%的朋友还想知道的:



  152423
 

很赞哦! ()

随机图文