`timescale 1ns / 1ps `include "cam_params.svh" module cam_write_noise #( parameter bit WRITE_NOISE_EN = 1'b1, parameter int WRITE_NOISE_RATE_NUM = 1, parameter int WRITE_NOISE_RATE_DEN = 100, parameter int WRITE_NOISE_BITS = 8, parameter logic [63:0] WRITE_NOISE_SEED = 64'hB504_F32D_B504_F32D ) ( input logic clk, input logic rst_n, input logic wr_valid, output logic wr_ready, input logic [(`ROW_BITS)-1:0] wr_row, input logic [(`HASH_BITS)-1:0] wr_hash, output logic core_wr_valid, output logic [(`ROW_BITS)-1:0] core_wr_row, output logic [(`HASH_BITS)-1:0] core_wr_hash ); logic pending_q; logic [(`ROW_BITS)-1:0] row_q; logic [(`HASH_BITS)-1:0] hash_q; logic [127:0] random_num; logic [(`HASH_BITS)-1:0] flip_mask; assign wr_ready = !pending_q; random128 u_random_write ( .clk (clk), .rst_n (rst_n), .enable(wr_valid && wr_ready && WRITE_NOISE_EN && (WRITE_NOISE_RATE_NUM > 0)), .seed ({WRITE_NOISE_SEED, WRITE_NOISE_SEED}), .out (random_num) ); noise_mask_grouped #( .HASH_BITS (`HASH_BITS), .NOISE_BITS (WRITE_NOISE_BITS), .NOISE_RATE_NUM (WRITE_NOISE_RATE_NUM), .NOISE_RATE_DEN (WRITE_NOISE_RATE_DEN) ) u_mask ( .random_i(random_num), .mask_o (flip_mask) ); initial begin if (WRITE_NOISE_SEED == 64'd0) $fatal(1, "WRITE_NOISE_SEED must be nonzero"); end always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin pending_q <= 1'b0; row_q <= '0; hash_q <= '0; core_wr_valid <= 1'b0; core_wr_row <= '0; core_wr_hash <= '0; end else begin core_wr_valid <= pending_q; core_wr_row <= row_q; if (WRITE_NOISE_EN && (WRITE_NOISE_RATE_NUM > 0)) begin core_wr_hash <= hash_q ^ flip_mask; end else begin core_wr_hash <= hash_q; end pending_q <= wr_valid && wr_ready; if (wr_valid && wr_ready) begin row_q <= wr_row; hash_q <= wr_hash; end end end endmodule