话不多说,上料!
note:编码方式有以下五种
- fm0编码;
- 非归零编码;
- 非归零反转编码;
- 曼彻斯特编码;
- 差分曼彻斯特编码;
各种编码相关原理就在不多做解释(网上有原理,自行查找),本人喜欢用verilog来进行描述和交流!
整个编码器和解码器的设计是先进行发送,后接收。
verilog描述如下:
顶层:
module tx_encode(
input i_clk ,
input i_rstn ,
input [2:0] i_sel ,//bit select
input i_value ,//input encode
output reg o_value //result of encode
);
// reg [2:0] i_sel;
wire reset, rst;
wire en_nrz_data, en_nrzi_data, en_fm0_data;
wire en_manche_data, en_difmanche_data;
wire clk_freq;//频带
reg clk_base;//基带
//======================TOP task handle=================//
always @ (posedge i_clk)
begin
if (i_rstn)
begin
o_value <= 0;
end
else
case (i_sel)
3'b000 : o_value <= en_nrz_data ;
3'b001 : o_value <= en_nrzi_data ;
3'b010 : o_value <= en_fm0_data ;
3'b011 : o_value <= en_manche_data ;
3'b100 : o_value <= en_difmanche_data;
default : o_value <= en_nrz_data ;
endcase
end
//======================DOUBLE FREQENCE=================//
always @ (posedge i_clk)
clk_base <= ~clk_base;
//======================INITIAL clk_base================//
initial begin
clk_base <= 1;
// #100
// clk_base <= 1;
end
//======================NRZ=============================//
nrz_encode NE0(
.clk (i_clk ),
.rst (i_rstn ),
.dataIn (i_value ),
.dataOut (en_nrz_data )
);
//======================NRZI============================//
nrzi_encode NE1(
.clk (i_clk ),
.reset (i_rstn ),
.data (i_value ),
.encode_data (en_nrzi_data )
);
//======================FM0============================//
fm0 FM(
.clk (i_clk ),
.reset (i_rstn ),
.data_in (i_value ),
.fm0_encoded (en_fm0_data )
);
//======================MANCHESTER=====================//
manchester_encode ME(
.clk_base (clk_base ),
.clk_freq (i_clk ),
.rst_n (i_rstn ),
.ser_in (i_value ),
.ser_out (en_manche_data )
);
//======================DIF-MANCHESTER================//
dif_manchester_encode DME(
.clk (i_clk ),
.reset (i_rstn ),
.data (i_value ),
.encoded_data (en_difmanche_data )
);
endmodule
非归零编码:
module nrz_encode(
input clk , // 时钟输入
input rst , // 复位输入
input dataIn , // 输入数据
output reg dataOut // 输出数据
);
always @(posedge clk) begin
if (rst) begin
dataOut <= 1'b0; // 复位时输出低电平
end else if (dataIn) begin
dataOut <= 1'b1; // 输入为1时输出高电平
end else begin
dataOut <= 1'b0; // 输入为0时输出低电平
end
end
endmodule
非归零反转编码:
module nrzi_encode(
input clk ,
input reset ,
input data ,
output reg encode_data
);
reg last_data;//上一次数据
reg [1:0] state;
parameter S0 = 2'b00,//数据刚进来
S1 = 2'b01,//
S2 = 2'b10;//
always @ (posedge clk, negedge reset)
begin
if (reset)
last_data <= 0;
else
last_data <= data;
end
always @ (posedge clk, negedge reset)
begin
if (reset)
begin
encode_data <= 0;
state <= S0;
end
else
case (state)
S0 : if (last_data == 0)
state <= S1;
else
state <= S2;
S1 : begin
encode_data <= data;
state <= S2;
end
S2 : if (last_data == data)
begin
encode_data <= 1;
state <= S2;
end
else
begin
encode_data <= 0;
state <= S0;
end
endcase
end
endmodule
fm0编码:
module fm0(
input clk ,// Clock input
input reset ,// Reset input
input data_in ,// Serial input data
output reg fm0_encoded // Encoded output data
);
reg [1:0] state; // State variable for encoding
reg prev_data; // Previous input data
always @(posedge clk or posedge reset)
begin
if (reset)
state <= 2'b00; // Reset state to initial state
else
begin
case (state)
2'b00 : begin
fm0_encoded <= {data_in, 1'b0}; // Encode input data as is and append 0
state <= 2'b01; // Move to the next state
end
2'b01 : begin
fm0_encoded <= {data_in, ~data_in}; // Encode input data and its complement
state <= 2'b00; // Move back to the initial state
end
endcase
end
end
endmodule
曼彻斯特编码:
module manchester_encode(
input clk_base ,
input clk_freq ,
input rst_n ,
input ser_in ,
output reg ser_out
);
reg [1:0] state;
parameter S0 = 2'b00,
S1 = 2'b01,
S2 = 2'b10;
always @ (posedge clk_freq)
begin
if (rst_n)
begin
ser_out <= 0;
state <= S0;
end
else
case (state)
S0 : if (!clk_base)
state <= S0;
else if (ser_in)
begin
ser_out <= 1;
state <= S1;
end
else
begin
ser_out <= 0;
state <= S2;
end
S1 : begin
ser_out <= 0;
state <= S0;
end
S2 : begin
ser_out <= 1;
state <= S0;
end
endcase
end
endmodule
差分曼彻斯特编码:
module dif_manchester_encode(
input clk ,
input reset ,
input data ,
output reg encoded_data
);
reg previous_data;
reg previous_clk;
always @(posedge clk or posedge reset)
begin
if (reset)
begin
previous_data <= 1'b0;
previous_clk <= 1'b0;
end
else
begin
previous_data <= data;
previous_clk <= previous_clk;
end
end
always @(posedge clk)
begin
if (previous_clk == 1'b0)
begin
encoded_data <= (previous_data ^ data) ? 1'b1 : 1'b0;
end
else
begin
encoded_data <= (previous_data == 1'b1) ? 1'b1 : 1'b0;
end
end
endmodule
相应解码器下节更新!
大家有问题及时指出,共同进步,愿各位工作顺利,事业有成!