⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecc_matrix_64bit.v

📁 本電子檔為 verilog cookbook,包含了通訊,影像,DSP等重要常用之verilog編碼,可作為工程師與初學者的參考手冊
💻 V
📖 第 1 页 / 共 2 页
字号:
  endgenerate

  // 32 terms
  wire [5:0] help_s4;
  xor6 help_s4_0 (help_s4[0],c[15],c[16],c[17],c[18],c[19],c[20]);
  xor6 help_s4_1 (help_s4[1],c[21],c[22],c[23],c[24],c[25],c[26]);
  xor6 help_s4_2 (help_s4[2],c[27],c[28],c[29],c[30],c[47],c[48]);
  xor6 help_s4_3 (help_s4[3],c[49],c[50],c[51],c[52],c[53],c[54]);
  xor6 help_s4_4 (help_s4[4],c[55],c[56],c[57],c[58],c[59],c[60]);
  xor6 help_s4_5 (help_s4[5],c[61],c[62],1'b0,1'b0,1'b0,1'b0);
  generate
    if (REGISTER) begin
      always @(posedge clk or posedge rst) begin
        if (rst) s[4] <= 0;
        else s[4] <= ^help_s4;
      end
    end else begin
      always @(help_s4) begin
        s[4] = ^help_s4;
      end
    end
  endgenerate

  // 32 terms
  wire [5:0] help_s5;
  xor6 help_s5_0 (help_s5[0],c[31],c[32],c[33],c[34],c[35],c[36]);
  xor6 help_s5_1 (help_s5[1],c[37],c[38],c[39],c[40],c[41],c[42]);
  xor6 help_s5_2 (help_s5[2],c[43],c[44],c[45],c[46],c[47],c[48]);
  xor6 help_s5_3 (help_s5[3],c[49],c[50],c[51],c[52],c[53],c[54]);
  xor6 help_s5_4 (help_s5[4],c[55],c[56],c[57],c[58],c[59],c[60]);
  xor6 help_s5_5 (help_s5[5],c[61],c[62],1'b0,1'b0,1'b0,1'b0);
  generate
    if (REGISTER) begin
      always @(posedge clk or posedge rst) begin
        if (rst) s[5] <= 0;
        else s[5] <= ^help_s5;
      end
    end else begin
      always @(help_s5) begin
        s[5] = ^help_s5;
      end
    end
  endgenerate

  // 8 terms
  wire [1:0] help_s6;
  xor6 help_s6_0 (help_s6[0],c[63],c[64],c[65],c[66],c[67],c[68]);
  xor6 help_s6_1 (help_s6[1],c[69],c[70],1'b0,1'b0,1'b0,1'b0);
  generate
    if (REGISTER) begin
      always @(posedge clk or posedge rst) begin
        if (rst) s[6] <= 0;
        else s[6] <= ^help_s6;
      end
    end else begin
      always @(help_s6) begin
        s[6] = ^help_s6;
      end
    end
  endgenerate

  // 72 terms
  wire [11:0] help_s7;
  xor6 help_s7_0 (help_s7[0],c[0],c[1],c[2],c[3],c[4],c[5]);
  xor6 help_s7_1 (help_s7[1],c[6],c[7],c[8],c[9],c[10],c[11]);
  xor6 help_s7_2 (help_s7[2],c[12],c[13],c[14],c[15],c[16],c[17]);
  xor6 help_s7_3 (help_s7[3],c[18],c[19],c[20],c[21],c[22],c[23]);
  xor6 help_s7_4 (help_s7[4],c[24],c[25],c[26],c[27],c[28],c[29]);
  xor6 help_s7_5 (help_s7[5],c[30],c[31],c[32],c[33],c[34],c[35]);
  xor6 help_s7_6 (help_s7[6],c[36],c[37],c[38],c[39],c[40],c[41]);
  xor6 help_s7_7 (help_s7[7],c[42],c[43],c[44],c[45],c[46],c[47]);
  xor6 help_s7_8 (help_s7[8],c[48],c[49],c[50],c[51],c[52],c[53]);
  xor6 help_s7_9 (help_s7[9],c[54],c[55],c[56],c[57],c[58],c[59]);
  xor6 help_s7_10 (help_s7[10],c[60],c[61],c[62],c[63],c[64],c[65]);
  xor6 help_s7_11 (help_s7[11],c[66],c[67],c[68],c[69],c[70],c[71]);

  // the parity bit has too much fanin
  // register it a bit higher for balance
  reg [11:0] help_s7_r;
  generate
    if (REGISTER) begin
      always @(posedge clk or posedge rst) begin
        if (rst) help_s7_r <= 0;
        else help_s7_r <= help_s7;
      end
    end else begin
      always @(help_s7) begin
        help_s7_r = help_s7;
      end
    end
  endgenerate

  // group the parity helper XORs
  wire par_0, par_1;
  xor6 par_0x (par_0,help_s7_r[0],help_s7_r[1],help_s7_r[2],help_s7_r[3],help_s7_r[4],help_s7_r[5]);
  xor6 par_1x (par_1,help_s7_r[6],help_s7_r[7],help_s7_r[8],help_s7_r[9],help_s7_r[10],help_s7_r[11]);

  always @(par_0 or par_1) begin
    s[7] = par_0 ^ par_1;
  end

endmodule

//////////////////////////////////////////
// From the syndrome compute the correction
// needed to fix the data, or set fatal = 1
// and no correction if there are too many.
//////////////////////////////////////////
module ecc_correction_64bit (s,e,fatal);

input [7:0] s;
output [63:0] e;
output fatal;
wire [63:0] e;

  // decode the lower part of syndrome
  reg [63:0] d;
  wire [63:0] dw /* synthesis keep */;
  always @(s) begin
    d = 64'b0;
    d[s[5:0]] = 1'b1;
  end
  assign dw = d;

  // Identify uncorrectable errors
  // and unroll the s[6] ODC condition to help
  // synthesis get minimum depth
  wire or_syn50 = |(s[5:0]) /* synthesis keep */;
  wire fatal = (s[6] & !s[7]) | (or_syn50 & !s[7]);
  wire fatal_s6_cold = (or_syn50 & !s[7]);
  wire fatal_s6_hot = !s[7];
  assign e = {
    dw[7] & s[6] & !fatal_s6_hot,dw[6] & s[6] & !fatal_s6_hot,dw[5] & s[6] & !fatal_s6_hot,dw[4] & s[6] & !fatal_s6_hot,
    dw[3] & s[6] & !fatal_s6_hot,dw[2] & s[6] & !fatal_s6_hot,dw[1] & s[6] & !fatal_s6_hot,dw[63] & !s[6] & !fatal_s6_cold,
    dw[62] & !s[6] & !fatal_s6_cold,dw[61] & !s[6] & !fatal_s6_cold,dw[60] & !s[6] & !fatal_s6_cold,dw[59] & !s[6] & !fatal_s6_cold,
    dw[58] & !s[6] & !fatal_s6_cold,dw[57] & !s[6] & !fatal_s6_cold,dw[56] & !s[6] & !fatal_s6_cold,dw[55] & !s[6] & !fatal_s6_cold,
    dw[54] & !s[6] & !fatal_s6_cold,dw[53] & !s[6] & !fatal_s6_cold,dw[52] & !s[6] & !fatal_s6_cold,dw[51] & !s[6] & !fatal_s6_cold,
    dw[50] & !s[6] & !fatal_s6_cold,dw[49] & !s[6] & !fatal_s6_cold,dw[48] & !s[6] & !fatal_s6_cold,dw[47] & !s[6] & !fatal_s6_cold,
    dw[46] & !s[6] & !fatal_s6_cold,dw[45] & !s[6] & !fatal_s6_cold,dw[44] & !s[6] & !fatal_s6_cold,dw[43] & !s[6] & !fatal_s6_cold,
    dw[42] & !s[6] & !fatal_s6_cold,dw[41] & !s[6] & !fatal_s6_cold,dw[40] & !s[6] & !fatal_s6_cold,dw[39] & !s[6] & !fatal_s6_cold,
    dw[38] & !s[6] & !fatal_s6_cold,dw[37] & !s[6] & !fatal_s6_cold,dw[36] & !s[6] & !fatal_s6_cold,dw[35] & !s[6] & !fatal_s6_cold,
    dw[34] & !s[6] & !fatal_s6_cold,dw[33] & !s[6] & !fatal_s6_cold,dw[31] & !s[6] & !fatal_s6_cold,dw[30] & !s[6] & !fatal_s6_cold,
    dw[29] & !s[6] & !fatal_s6_cold,dw[28] & !s[6] & !fatal_s6_cold,dw[27] & !s[6] & !fatal_s6_cold,dw[26] & !s[6] & !fatal_s6_cold,
    dw[25] & !s[6] & !fatal_s6_cold,dw[24] & !s[6] & !fatal_s6_cold,dw[23] & !s[6] & !fatal_s6_cold,dw[22] & !s[6] & !fatal_s6_cold,
    dw[21] & !s[6] & !fatal_s6_cold,dw[20] & !s[6] & !fatal_s6_cold,dw[19] & !s[6] & !fatal_s6_cold,dw[18] & !s[6] & !fatal_s6_cold,
    dw[17] & !s[6] & !fatal_s6_cold,dw[15] & !s[6] & !fatal_s6_cold,dw[14] & !s[6] & !fatal_s6_cold,dw[13] & !s[6] & !fatal_s6_cold,
    dw[12] & !s[6] & !fatal_s6_cold,dw[11] & !s[6] & !fatal_s6_cold,dw[10] & !s[6] & !fatal_s6_cold,dw[9] & !s[6] & !fatal_s6_cold,
    dw[7] & !s[6] & !fatal_s6_cold,dw[6] & !s[6] & !fatal_s6_cold,dw[5] & !s[6] & !fatal_s6_cold,dw[3] & !s[6] & !fatal_s6_cold
    };


endmodule

//////////////////////////////////////////
// select the (uncorrected) data bits out
// of the code word.
//////////////////////////////////////////

module ecc_raw_data_64bit (clk,rst,c,d);
parameter REGISTER = 0;
input clk,rst;
input [71:0] c;
output [63:0] d;
reg [63:0] d;

wire [63:0] d_int;

  // pull out the pure data bits
  assign d_int = {
    c[70],c[69],c[68],c[67],c[66],c[65],c[64],c[62],
    c[61],c[60],c[59],c[58],c[57],c[56],c[55],c[54],
    c[53],c[52],c[51],c[50],c[49],c[48],c[47],c[46],
    c[45],c[44],c[43],c[42],c[41],c[40],c[39],c[38],
    c[37],c[36],c[35],c[34],c[33],c[32],c[30],c[29],
    c[28],c[27],c[26],c[25],c[24],c[23],c[22],c[21],
    c[20],c[19],c[18],c[17],c[16],c[14],c[13],c[12],
    c[11],c[10],c[9],c[8],c[6],c[5],c[4],c[2]
    };

  // conditional output register
  generate
  if (REGISTER) begin
    always @(posedge clk or posedge rst) begin
      if (rst) d <= 0;
      else d <= d_int;
    end
  end else begin
    always @(d_int) begin
      d <= d_int;
    end
  end
  endgenerate

endmodule

//////////////////////////////////////////
// 72 bit to 64 bit ECC decoder
//////////////////////////////////////////

module ecc_decode_64bit (clk,rst,c,d,no_err,err_corrected,err_fatal);

// optional pipeline registers at the halfway
// point and on the outputs
parameter MIDDLE_REG = 0;
parameter OUTPUT_REG = 0;

input clk,rst;
input [71:0] c;
output [63:0] d;
output no_err, err_corrected, err_fatal;

reg [63:0] d;
reg no_err, err_corrected, err_fatal;

  // Pull the raw (uncorrected) data from the codeword
  wire [63:0] raw_bits;
  ecc_raw_data_64bit raw (.clk(clk),.rst(rst),.c(c),.d(raw_bits));

    defparam raw .REGISTER = MIDDLE_REG;
  // Build syndrome, which will be 0 for correct
  // correct codewords, otherwise a pointer to the
  // error.
  wire [7:0] syndrome;
  ecc_syndrome_64bit syn (.clk(clk),.rst(rst),.c(c),.s(syndrome));
    defparam syn .REGISTER = MIDDLE_REG;

  // Use the the syndrome to find a correction, or 0 for no correction
  wire [63:0] err_flip;
  wire fatal;
  ecc_correction_64bit cor (.s(syndrome),.e(err_flip),.fatal(fatal));

  // Classify error types and correct data as appropriate
  // If there is a multibit error take care not to make 
  // the data worse.
  generate
    if (OUTPUT_REG) begin
      always @(posedge clk or posedge rst) begin
        if (rst) begin
          no_err <= 1'b0;
          err_corrected <= 1'b0;
          err_fatal <= 1'b0;
          d <= 1'b0;
        end else begin
          no_err <= ~| syndrome;
          err_corrected <= syndrome[7];
          err_fatal <= fatal;

          d <= err_flip ^ raw_bits;
        end
      end
    end else begin
      always @(*) begin
          no_err = ~| syndrome;
          err_corrected = syndrome[7];
          err_fatal = fatal;

          d = err_flip ^ raw_bits;
      end
    end
  endgenerate

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -