mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
- 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
86 lines
3.3 KiB
Systemverilog
86 lines
3.3 KiB
Systemverilog
`timescale 1ns / 1ps
|
|
`include "cam_params.svh"
|
|
|
|
module cam_read_noise #(
|
|
parameter bit READ_NOISE_EN = 1'b1,
|
|
parameter int READ_NOISE_RATE_NUM = 1,
|
|
parameter int READ_NOISE_RATE_DEN = 100,
|
|
parameter int READ_NOISE_BITS = 8,
|
|
parameter logic [63:0] READ_NOISE_SEED = 64'h6A09_E667_F3BC_C909
|
|
) (
|
|
input logic clk,
|
|
input logic rst_n,
|
|
input logic valid_i,
|
|
input logic [(`LANES)*(`ROW_BITS)-1:0] row_ids_i,
|
|
input logic [(`LANES)*(`HASH_BITS)-1:0] hashes_i,
|
|
input logic [(`LANES)-1:0] lane_valid_i,
|
|
output logic valid_o,
|
|
output logic [(`LANES)*(`ROW_BITS)-1:0] row_ids_o,
|
|
output logic [(`LANES)*(`HASH_BITS)-1:0] hashes_noisy_o,
|
|
output logic [(`LANES)-1:0] lane_valid_o
|
|
);
|
|
logic valid_q;
|
|
logic [(`LANES)*(`ROW_BITS)-1:0] row_ids_q;
|
|
logic [(`LANES)*(`HASH_BITS)-1:0] hashes_q;
|
|
logic [(`LANES)-1:0] lane_valid_q;
|
|
|
|
logic [127:0] random_num [0:`LANES-1];
|
|
logic [(`HASH_BITS)-1:0] mask [0:`LANES-1];
|
|
|
|
initial begin
|
|
if (READ_NOISE_SEED == 64'd0) $fatal(1, "READ_NOISE_SEED must be nonzero");
|
|
end
|
|
|
|
generate
|
|
for (genvar lane = 0; lane < `LANES; lane++) begin : gen_lane_noise
|
|
localparam logic [63:0] LANE_SALT = 64'(lane + 1) * 64'h9E37_79B9_7F4A_7C15;
|
|
random128 u_random_read (
|
|
.clk (clk),
|
|
.rst_n (rst_n),
|
|
.enable(valid_i && lane_valid_i[lane] && READ_NOISE_EN && (READ_NOISE_RATE_NUM > 0)),
|
|
.seed ({(READ_NOISE_SEED ^ LANE_SALT), (READ_NOISE_SEED ^ LANE_SALT)}),
|
|
.out (random_num[lane])
|
|
);
|
|
|
|
noise_mask_grouped #(
|
|
.HASH_BITS (`HASH_BITS),
|
|
.NOISE_BITS (READ_NOISE_BITS),
|
|
.NOISE_RATE_NUM (READ_NOISE_RATE_NUM),
|
|
.NOISE_RATE_DEN (READ_NOISE_RATE_DEN)
|
|
) u_mask (
|
|
.random_i(random_num[lane]),
|
|
.mask_o (mask[lane])
|
|
);
|
|
end
|
|
endgenerate
|
|
|
|
always_ff @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
valid_q <= 1'b0;
|
|
row_ids_q <= '0;
|
|
hashes_q <= '0;
|
|
lane_valid_q <= '0;
|
|
valid_o <= 1'b0;
|
|
row_ids_o <= '0;
|
|
hashes_noisy_o <= '0;
|
|
lane_valid_o <= '0;
|
|
end else begin
|
|
valid_q <= valid_i;
|
|
row_ids_q <= row_ids_i;
|
|
hashes_q <= hashes_i;
|
|
lane_valid_q <= lane_valid_i;
|
|
|
|
valid_o <= valid_q;
|
|
row_ids_o <= row_ids_q;
|
|
lane_valid_o <= lane_valid_q;
|
|
for (int lane = 0; lane < `LANES; lane++) begin
|
|
if (READ_NOISE_EN && (READ_NOISE_RATE_NUM > 0) && lane_valid_q[lane]) begin
|
|
hashes_noisy_o[lane*`HASH_BITS +: `HASH_BITS] <= hashes_q[lane*`HASH_BITS +: `HASH_BITS] ^ mask[lane];
|
|
end else begin
|
|
hashes_noisy_o[lane*`HASH_BITS +: `HASH_BITS] <= hashes_q[lane*`HASH_BITS +: `HASH_BITS];
|
|
end
|
|
end
|
|
end
|
|
end
|
|
endmodule
|