Files
Mini-Nav/hw/rtl/cam_write_noise.sv
SikongJueluo 8f59a287c4 feat(hw): add banked CAM pipeline with grouped read/write noise
- Add cam_core_banked.sv with 8-lane banked CAM core
- Add cam_write_noise.sv and cam_read_noise.sv for grouped noise injection
- Add noise_mask_grouped.sv generating grouped flip masks from 128-bit PRNG
- Add match_engine_pipeline.sv with multi-stage pipelined top-1 selection
- Add popcount_pipeline.sv for pipelined popcount operations
- Refactor test_cam_basic.py with parametrized DUT introspection helpers
- Add Python ref_model match_top1_with_read_noise() for read noise verification
- Update Makefile with separate WRITE_NOISE_* and READ_NOISE_* parameter groups
- Add new testbenches: test_cam_core_banked, test_cam_read_noise,
  test_cam_write_noise, test_match_engine_pipeline, test_ref_model_noise
  
breaking change hint: NUM_ROWS default changed from 512→4096, LANES from 16→8
2026-05-13 18:22:28 +08:00

76 lines
2.4 KiB
Systemverilog

`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