以下の内容はhttps://msyksphinz.hatenablog.com/entry/2025/10/08/040000より取得しました。


Common CellsのECCエンコーダーの実装詳細解析:ecc_encode.sv の実装詳細

ecc_encode.svの実装詳細

モジュール入出力

module ecc_encode import ecc_pkg::*; #(
  parameter  int unsigned DataWidth   = 64,
  parameter type data_t         = logic [DataWidth-1:0],
  parameter type parity_t       = logic [get_parity_width(DataWidth)-1:0],
  parameter type code_word_t    = logic [get_cw_width(DataWidth)-1:0],
  parameter type encoded_data_t = struct packed {
                                    logic parity;
                                    code_word_t code_word;
                                  }
) (
  input  data_t         data_i,
  output encoded_data_t data_o
);

このモジュールは以下のパラメータを使用している:

  • DataWidth:エンコード対象のデータ幅 (デフォルト64ビット)
  • data_t:入力データの型 (デフォルトでは logic [DataWidth-1: 0]
  • parity_t:パリティビットの型 (デフォルトでは logic [get_parity_width(DataWidth)-1: 0] )
  • code_word_t:コードワード(データ+パリティ)の型 (logic [get_cw_width(DataWidth)-1: 0])
  • encoded_data_t:最終的なエンコードデータの型(パリティビット+コードワード)

例えば、 DataWidth = 64 の場合、それぞれのパラメータは以下のように計算できる。

  • DataWidth = 64
  • data_t = logic [63: 0]
  • parity_t = logic[get_parity_width(64)-1: 0] = logic [7-1: 0] = logic [ 6: 0]
  • code_word_t = logic [get_cw_width(DataWidth)-1: 0] = logic [64+7-1: 0] = logic [70: 0]
  • encoded_data_t = struct packed {logic parity; logic [70: 0] code_word; }

ちなみに、 get_parity_width() は以下のように定義されている。コメントは自分の計算。

  // Calculate required ECC parity width:
  function automatic int unsigned get_parity_width (input int unsigned data_width);
    // data_width + cw_width + 1 <= 2**cw_width
    int unsigned cw_width = 2;
    while (unsigned'(2**cw_width) < cw_width + data_width + 1) cw_width++;
    // data_width = 64
    // cw_width = 2 -> 2**2 < 2 + 64 + 1 = 4 < 67 -> True
    // cw_width = 3 -> 2**3 < 3 + 64 + 1 = 8 < 68 -> True
    // cw_width = 4 -> 2**4 < 4 + 64 + 1 = 16 < 70 -> True
    // cw_width = 5 -> 2**5 < 5 + 64 + 1 = 32 < 71 -> True
    // cw_width = 6 -> 2**6 < 6 + 64 + 1 = 64 < 72 -> True
    // cw_width = 7 -> 2**7 < 7 + 64 + 1 = 128 < 73 -> False
    // cw_width = 7
    return cw_width;
  endfunction

  // Calculate required ECC codeword width:
  function automatic int unsigned get_cw_width (input int unsigned data_width);
    // data width + parity width + one additional parity bit (for double error detection)
    return data_width + get_parity_width(data_width);
    // data_width = 64
    // cw_width = 64 + 7 = 70
  endfunction

実装の3つの主要ステップ

1. データの展開(expand_data)

// data_i は入力ビット列
//  input  data_t         data_i, logic [63: 0]

always_comb begin : expand_data
  automatic int unsigned idx;
  data = '0;
  idx = 0;
  for (int unsigned i = 1; i < unsigned'($bits(code_word_t)) + 1; i++) begin
    // if it is not a power of two word it is a normal data index
    if (unsigned'(2**$clog2(i)) != i) begin // iが2の累乗の時だけ非成立
      data[i - 1] = data_i[idx];
      idx++;
    end
  end
end
//  63| 62| 61|...|  8|  7|  6|  5|  4|  3|  2|  1|  0|
// d63|d62|d61|...| d8| d7| d6| d5| d4| d3| d2| d1| d0|
//             ...| P | d4| d3| d2| P | d1| P | P | d0|

この処理では、入力データをコードワード幅に展開している。ハミング符号では、パリティビットは2のべき乗の位置(1, 2, 4, 8, ...)に配置されるため、データビットはそれ以外の位置に配置される。

2. シンドローム計算(calculate_syndrome)

always_comb begin : calculate_syndrome
  parity_code_word = 0;
  // もっとも外側のループは parity_t (Data=64-bit の場合は 6-bit) だけ回される
  for (int unsigned i = 0; i < unsigned'($bits(parity_t)); i++) begin
    // 次のループは、 code_word_t (Data=64-bit の場合は 70-bit) だけ回される
    for (int unsigned j = 1; j < unsigned'($bits(code_word_t)) + 1; j++) begin
      // たとえば、
      // i = 0 -> j = 1 がXOR対象
      // i = 1 -> j = 2, 3 が XOR対象
      if (|(unsigned'(2**i) & j)) parity_code_word[i] = parity_code_word[i] ^ data[j - 1];
    end
  end
end

この処理では、各パリティビットを計算している。パリティビット i は、位置 j のビットが条件|(unsigned'(2**i) & j)を満たす場合にXOR演算に含まれる。これは、ハミング符号のパリティ計算規則に基づいている。

3. コードワード生成(generate_codeword)

always_comb begin : generate_codeword
    codeword = data;
    for (int unsigned i = 0; i < unsigned'($bits(parity_t)); i++) begin
      codeword[2**i-1] = parity_code_word[i];
    end
end

この処理では、計算されたパリティビットをコードワードの適切な位置に配置している。

最終出力

assign data_o.code_word = codeword;
assign data_o.parity = ^codeword;

最終的に、コードワードと全体のパリティビット(全ビットのXOR)を出力している。この全体パリティビットにより、二重エラー検出が可能になる。




以上の内容はhttps://msyksphinz.hatenablog.com/entry/2025/10/08/040000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14