林坤优秀作者
原创内容 来源:小居数码网 时间:2024-07-28 19:37:01 阅读() 收藏:34 分享:73 爆
导读:您正在阅读的是关于【数码知识】的问题,本文由科普作家协会,生活小能手,著名生活达人等整理监督编写。本文有1794个文字,大小约为7KB,预计阅读时间5分钟。
实验简述将输入的数据流经过曼彻斯特编码器编码后经过解码器恢复为原来的输入序列。
一、曼彻斯特码简介
曼彻斯特码(Manchester code),又称数字双向码、分相码或相位编码(PE),是一种常用的二源码线路编码方式之一,被物理层使用来编码一个同步位流的时钟和数据。在通信技术中,用来表示所要发送比特流中的数据宇定时信号所结合起来的代码。常用在以太网通信,列车总线控制,工业总线等领域。
有两个输入时钟,一个是基带时钟(起同步信号作用),一个是频带时钟。输入的数据流是基带时钟域信号,经过编码后变成频带时钟域信号输出。曼彻斯特编码是将输入为1的变成输出前半拍为1,后半拍为0,输入为0的变成前半拍为0,后半拍为1的频带信号。
输入序列以101为例,经过编码后应为100110
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
采用状态机来实现编码模块。
当检测到编码使能为高时,状态机开始执行,判断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
解码模块也采用状态机实现,当检测到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
tb文件参考工程文件夹中的sim文件夹
输入的数据流enc_in为1011,对应的曼彻斯特码应为10011010
我们看到输入到编码模块的enc_in与解码模块的dec_out的输出是一样的
再来看编码之后的数据流
enc_out为10011010与结果一致
解码模块图形
上面就是小居数码小编今天给大家介绍的关于(fpga曼彻斯特译码器设计)的全部内容,希望可以帮助到你,想了解更多关于数码知识的问题,欢迎关注我们,并收藏,转发,分享。
94%的朋友还想知道的:
(209)个朋友认为回复得到帮助。
部分文章信息来源于以及网友投稿,转载请说明出处。
本文标题:fpga编解码(fpga曼彻斯特译码器设计):http://sjzlt.cn/shuma/152423.html