`timescale 1ns / 1ps `include "cam_params.svh" module noise_mask_grouped #( parameter int HASH_BITS = `HASH_BITS, parameter int NOISE_BITS = 8, parameter int NOISE_RATE_NUM = 1, parameter int NOISE_RATE_DEN = 100 ) ( input logic [127:0] random_i, output logic [HASH_BITS-1:0] mask_o ); localparam int GROUP_BITS = HASH_BITS / NOISE_BITS; localparam int BIT_INDEX_BITS = 6; localparam int SAMPLE_BITS = 8; localparam int GROUP_RAND_BITS = BIT_INDEX_BITS + SAMPLE_BITS; localparam int SAMPLE_RANGE = 1 << SAMPLE_BITS; localparam int THRESHOLD = (NOISE_RATE_NUM * SAMPLE_RANGE) / NOISE_RATE_DEN; initial begin if (NOISE_BITS <= 0) $fatal(1, "NOISE_BITS must be > 0"); if (HASH_BITS % NOISE_BITS != 0) $fatal(1, "HASH_BITS must be divisible by NOISE_BITS"); if (GROUP_BITS != 64) $fatal(1, "GROUP_BITS must be 64 for 6-bit grouped noise"); if (NOISE_BITS * GROUP_RAND_BITS > 128) $fatal(1, "NOISE_BITS consumes more than 128 random bits"); if (NOISE_RATE_DEN <= 0) $fatal(1, "NOISE_RATE_DEN must be > 0"); if (NOISE_RATE_NUM < 0 || NOISE_RATE_NUM > NOISE_RATE_DEN) $fatal(1, "NOISE_RATE_NUM out of range"); end always_comb begin mask_o = '0; for (int i = 0; i < NOISE_BITS; i++) begin if (random_i[i * GROUP_RAND_BITS + BIT_INDEX_BITS +: SAMPLE_BITS] < THRESHOLD) begin mask_o[i * GROUP_BITS + random_i[i * GROUP_RAND_BITS +: BIT_INDEX_BITS]] = 1'b1; end end end endmodule