veryl-std 0.20.0

A modern hardware description language
Documentation
/// Enocdes a vector for single-error correction using a linear Hamming code.
module linear_sec_encoder #(
    /// Number of parity bits
    param P: u32 = 4,
    /// Length of codeword
    param K: u32 = (1 << P) - 1,
    /// Length of data
    param N: u32 = K - P,
) (
    i_word    : input  logic<N>,
    o_codeword: output logic<K>,
) {

    // Generate H Matrix
    var h: logic<P, K>;
    for p in 0..P :gen_vector {
        for k in 0..K :gen_bit {
            const IDX    : u32 = k + 1;
            assign h[p][k] = IDX[p];
        }
    }

    // Move data from input word to its larger k-bit length vector
    var codeword_data_only: logic<K>;
    for k in 1..K + 1 :gen_move_data {
        const CODEWORD_IDX: u32 = k - 1;
        if !$onehot(k) :gen_move_data_bit {
            const WORD_IDX                        : u32 = k - $clog2(k) - 1;
            assign codeword_data_only[CODEWORD_IDX] = i_word[WORD_IDX];
        } else {
            assign codeword_data_only[CODEWORD_IDX] = 1'b0;
        }
    }

    // Compute parity bits
    var codeword_parity_only: logic<K>;
    for p in 0..P :gen_parities {
        const CODEWORD_IDX                      : u32 = (1 << p) - 1;
        assign codeword_parity_only[CODEWORD_IDX] = ^(h[p] & codeword_data_only);
    }
    for k in 0..K :gen_zeros {
        if !$onehot(k + 1) :gen_zero_bit {
            assign codeword_parity_only[k] = 1'b0;
        }
    }

    assign o_codeword = codeword_data_only | codeword_parity_only;
}

#[test(test_3_1_hamming_encode)]
embed (inline) sv{{{
module test_3_1_hamming_code;
  bit i_word;
  logic [2:0] o_codeword;

  std_linear_sec_encoder#(.P(2)) dut(.*);

  initial begin
    $display("enc.h[0]: %b\n", dut.h[0]);
    $display("enc.h[1]: %b\n", dut.h[1]);
    $monitor("word: %b\n", i_word, "cwrd: %3b\n", o_codeword,
    "cwrd_dataonly: %b\n", dut.codeword_data_only,
    "cwrd_parionly: %b\n\n", dut.codeword_parity_only,
    );
    i_word = 1'b0;
    #1 assert(o_codeword == 3'b000);
    i_word = 1'b1;
    #1 assert(o_codeword == 3'b111);
    $finish;
  end

endmodule
}}}