Table of Contents
生成多项式
g(x) = [1 1 0 0 1]
编码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Fansen
// Engineer: Fansen
//
// Create Date: 2022/05/05 19:56:59
// Design Name:
// Module Name: eHamming_n16_k11_encoder_v3
// Project Name:
// Target Devices:
// Tool Versions:
// Description: g(x) = 【1 1 0 0 1】
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module eHamming_n16_k11_encoder(
clk,
rst,
start,
din,
din_clk_p,
dout,
dout_clk_p
);
input clk;
input rst;
input start;
input din;
input din_clk_p;
output dout;
output dout_clk_p;
//////////////////////////////////////////////////////////////////////////////////
// eHamming parameter
parameter N = 16;
parameter K = 11;
//////////////////////////////////////////////////////////////////////////////////
reg delay_din;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_din<=1'd0;
end
else
begin
delay_din<=din;//对输入信号延时一拍
end
end
reg delay_din_clk_p;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_din_clk_p<=1'd0;
end
else
begin
delay_din_clk_p<=din_clk_p;//对输入信号延时一拍
end
end
//////////////////////////////////////////////////////////////////////////////////
// Control
reg [7:0] cnts;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
cnts <= 8'hff;
end
else if (start)
begin
cnts <= 8'd0;
end
else if(cnts <= N)
begin
cnts <= cnts + 1'b1;
end
else
begin
cnts <= cnts;
end
end
//////////////////////////////////////////////////////////////////////////////////
reg [3:0] Reg;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
Reg <= 4'h0;
end
else if (start)
begin
Reg <= 4'h0;
end
else if(cnts < K)
begin
Reg[0] <= Reg[3] ^ delay_din;
Reg[1] <= Reg[0] ^ Reg[3] ^ delay_din;
Reg[2] <= Reg[1];
Reg[3] <= Reg[2];
end
else
begin
Reg <= Reg;
end
end
reg Check;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
Check <= 1'b0;
end
else if (start)
begin
Check <= 1'b0;
end
else
begin
case (cnts)
16'd0: begin Check <= Check ^ delay_din; end
16'd1: begin Check <= Check ^ delay_din; end
16'd2: begin Check <= Check ^ delay_din; end
16'd3: begin Check <= Check ^ delay_din; end
16'd4: begin Check <= Check ^ delay_din; end
16'd5: begin Check <= Check ^ delay_din; end
16'd6: begin Check <= Check ^ delay_din; end
16'd7: begin Check <= Check ^ delay_din; end
16'd8: begin Check <= Check ^ delay_din; end
16'd9: begin Check <= Check ^ delay_din; end
16'd10: begin Check <= Check ^ delay_din;end
16'd11: begin Check <= Check ^ Reg[3]; end
16'd12: begin Check <= Check ^ Reg[2]; end
16'd13: begin Check <= Check ^ Reg[1]; end
16'd14: begin Check <= Check ^ Reg[0]; end
default: begin Check <= Check; end
endcase
end
end
reg dout;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
dout <= 1'b0;
end
else
begin
case (cnts)
16'd0: begin dout <= delay_din; end
16'd1: begin dout <= delay_din; end
16'd2: begin dout <= delay_din; end
16'd3: begin dout <= delay_din; end
16'd4: begin dout <= delay_din; end
16'd5: begin dout <= delay_din; end
16'd6: begin dout <= delay_din; end
16'd7: begin dout <= delay_din; end
16'd8: begin dout <= delay_din; end
16'd9: begin dout <= delay_din; end
16'd10: begin dout <= delay_din; end
16'd11: begin dout <= Reg[3]; end
16'd12: begin dout <= Reg[2]; end
16'd13: begin dout <= Reg[1]; end
16'd14: begin dout <= Reg[0]; end
16'd15: begin dout <= Check; end
default: begin dout <= 1'b0; end
endcase
end
end
reg dout_clk_p;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
dout_clk_p <= 1'b0;
end
else
begin
case (cnts)
16'd0: begin dout_clk_p <= 1'b1; end
16'd16: begin dout_clk_p <= 1'b0; end
default: begin dout_clk_p <= dout_clk_p; end
endcase
end
end
endmodule
解码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2022/05/09 17:41:18
// Design Name:
// Module Name: eHamming_n16_k11_decoder_v31
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module eHamming_n16_k11_decoder(
clk,
rst,
start,
din,
din_clk_p,
dout,
dout_clk_p,
code_num
);
input clk;
input rst;
input start;
input din;
input din_clk_p;
output dout;
output dout_clk_p;
output [1:0] code_num;
//////////////////////////////////////////////////////////////////////////////////
// eHamming parameter
parameter N = 16;
parameter K = 11;
// ECC
reg pa_news; reg [3:0] temp; reg [1:0] code_num;
//////////////////////////////////////////////////////////////////////////////////
reg delay_din;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_din <= 1'd0;
end
else
begin
delay_din <= din;//对输入信号延时一拍
end
end
reg delay_din_clk_p;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_din_clk_p <= 1'd0;
end
else
begin
delay_din_clk_p <= din_clk_p;//对输入信号延时一拍
end
end
//////////////////////////////////////////////////////////////////////////////////
// Control
reg [7:0] cnts;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
cnts <= 8'hff;
end
else if (start)
begin
cnts <= 8'd0;
end
else if(cnts <= 35)
begin
cnts <= cnts + 1'b1;
end
else
begin
cnts <= cnts;
end
end
//////////////////////////////////////////////////////////////////////////////////
// din_m
reg [15:0] din_m;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
din_m <= 16'd0;
end
else
begin
case (cnts)
16'd0: begin din_m[15] <= delay_din;end
16'd1: begin din_m[14] <= delay_din;end
16'd2: begin din_m[13] <= delay_din;end
16'd3: begin din_m[12] <= delay_din;end
16'd4: begin din_m[11] <= delay_din;end
16'd5: begin din_m[10] <= delay_din;end
16'd6: begin din_m[9] <= delay_din;end
16'd7: begin din_m[8] <= delay_din;end
16'd8: begin din_m[7] <= delay_din;end
16'd9: begin din_m[6] <= delay_din;end
16'd10: begin din_m[5] <= delay_din;end
16'd11: begin din_m[4] <= delay_din;end
16'd12: begin din_m[3] <= delay_din;end
16'd13: begin din_m[2] <= delay_din;end
16'd14: begin din_m[1] <= delay_din;end
16'd15: begin din_m[0] <= delay_din;end
default: begin din_m <= din_m; end
endcase
end
end
//////////////////////////////////////////////////////////////////////////////////
reg [3:0] Reg; // 1 1 0 0 1
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
Reg <= 4'h0;
end
else if (start)
begin
Reg <= 4'h0;
end
else if(cnts < 15)
begin
Reg[0] <= Reg[3] ^ delay_din;
Reg[1] <= Reg[0] ^ Reg[3] ^ delay_din ;
Reg[2] <= Reg[1];
Reg[3] <= Reg[2];
end
else
begin
Reg <= Reg;
end
end
reg Check;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
Check <= 1'b0;
end
else if (start)
begin
Check <= 1'b0;
end
else
begin
case (cnts)
16'd0: begin Check <= Check ^ delay_din; end
16'd1: begin Check <= Check ^ delay_din; end
16'd2: begin Check <= Check ^ delay_din; end
16'd3: begin Check <= Check ^ delay_din; end
16'd4: begin Check <= Check ^ delay_din; end
16'd5: begin Check <= Check ^ delay_din; end
16'd6: begin Check <= Check ^ delay_din; end
16'd7: begin Check <= Check ^ delay_din; end
16'd8: begin Check <= Check ^ delay_din; end
16'd9: begin Check <= Check ^ delay_din; end
16'd10: begin Check <= Check ^ delay_din;end
16'd11: begin Check <= Check ^ delay_din; end
16'd12: begin Check <= Check ^ delay_din; end
16'd13: begin Check <= Check ^ delay_din; end
16'd14: begin Check <= Check ^ delay_din; end
default: begin Check <= Check; end
endcase
end
end
//////////////////////////////////////////////////////////////////////////////////
reg [15:0] din_trt;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
din_trt <= 16'd0;
end
else if (start)
begin
din_trt <= 16'd0;
end
else
begin
case (cnts)
16'd15:
begin
case(Reg)
4'b0000:din_trt<=16'b000_0000_0000_0000;//1
4'b0001:din_trt<=16'b000_1000_0000_0000;//2
4'b0010:din_trt<=16'b001_0000_0000_0000;//3
4'b0011:din_trt<=16'b000_0000_0000_0001;//4
4'b0100:din_trt<=16'b010_0000_0000_0000;//5
4'b0101:din_trt<=16'b000_0000_0001_0000;//6
4'b0110:din_trt<=16'b000_0000_0000_0010;//7
4'b0111:din_trt<=16'b000_0000_0100_0000;//8
4'b1000:din_trt<=16'b100_0000_0000_0000;//9
4'b1001:din_trt<=16'b000_0100_0000_0000;//10
4'b1010:din_trt<=16'b000_0000_0010_0000;//11
4'b1011:din_trt<=16'b000_0000_0000_1000;//12
4'b1100:din_trt<=16'b000_0000_0000_0100;//13
4'b1101:din_trt<=16'b000_0010_0000_0000;//14
4'b1110:din_trt<=16'b000_0000_1000_0000;//15
4'b1111:din_trt<=16'b000_0001_0000_0000;//16
default: begin din_trt <= din_trt; end
endcase
end
16'd16: begin din_trt <= din_trt << 1; end // 上文造成的
default: begin din_trt <= din_trt; end
endcase
end
end
//////////////////////////////////////////////////////////////////////////////////
// dout_m
reg [15:0] dout_m;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
dout_m <= 16'd0;
end
else
begin
case (cnts)
16'd18:
begin
if(code_num == 2'b01) // 错一位 进行纠错
begin
dout_m <= din_m ^ din_trt;
end
else if(code_num == 2'b11) // 错一位 校验位纠错
begin
dout_m <= din_m ^ 1'b1;
end
else
begin
dout_m <= din_m; // 保持
end
end
default: begin dout_m <= dout_m; end
endcase
end
end
//////////////////////////////////////////////////////////////////////////////////
// dout
reg dout;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
dout <= 1'b0;
end
else
begin
case (cnts)
16'd19: begin dout <= dout_m[15]; end
16'd20: begin dout <= dout_m[14]; end
16'd21: begin dout <= dout_m[13]; end
16'd22: begin dout <= dout_m[12]; end
16'd23: begin dout <= dout_m[11]; end
16'd24: begin dout <= dout_m[10]; end
16'd25: begin dout <= dout_m[9]; end
16'd26: begin dout <= dout_m[8]; end
16'd27: begin dout <= dout_m[7]; end
16'd28: begin dout <= dout_m[6]; end
16'd29: begin dout <= dout_m[5]; end
16'd30: begin dout <= dout_m[4]; end
16'd31: begin dout <= dout_m[3]; end
16'd32: begin dout <= dout_m[2]; end
16'd33: begin dout <= dout_m[1]; end
16'd34: begin dout <= dout_m[0]; end
default: begin dout <= 1'b0; end
endcase
end
end
// dout_clk_p
reg dout_clk_p;
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
dout_clk_p <= 1'b0;
end
else
begin
case (cnts)
16'd19: begin dout_clk_p <= 1'b1; end
// 16'd30: begin dout_clk_p <= 1'b0; end
16'd35: begin dout_clk_p <= 1'b0; end
default: begin dout_clk_p <= dout_clk_p; end
endcase
end
end
//////////////////////////////////////////////////////////////////////////////////
// ECC
// pa_news
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
pa_news <= 1'b0;
end
else
begin
case (cnts)
16'd16: begin pa_news <= Check ^ din_m[0]; end
default: begin pa_news <= pa_news; end
endcase
end
end
// temp
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
temp <= 4'b0;
end
else
begin
case (cnts)
16'd15: begin temp <= Reg; end
default: begin temp <= temp; end
endcase
end
end
// code_num
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
code_num <= 2'd0;
end
else
begin
case (cnts)
16'd17:
begin
if (pa_news == 1'b0)
begin
if (temp == 4'b0)
begin
code_num <= 2'b00;// 无错误
end
else
begin
code_num <= 2'b10;// 错误2个
end
end
else
begin
if (temp == 4'b0)
begin
code_num <= 2'b11;// 校验位错误
end
else
begin
code_num <= 2'b01; // 错误1个
end
end
end
default: begin code_num <= code_num; end
endcase
end
end
endmodule