mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
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
This commit is contained in:
70
hw/sim/tests/test_ref_model_noise.py
Normal file
70
hw/sim/tests/test_ref_model_noise.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from model.ref_model import (
|
||||
generate_grouped_flip_mask,
|
||||
match_top1_with_read_noise,
|
||||
xnor_popcount_score,
|
||||
)
|
||||
|
||||
|
||||
def test_grouped_flip_mask_full_rate_one_bit_per_64_bit_group():
|
||||
random_value = 0
|
||||
for group in range(8):
|
||||
bit_idx = group + 1
|
||||
sample = 0
|
||||
random_value |= bit_idx << (group * 14)
|
||||
random_value |= sample << (group * 14 + 6)
|
||||
|
||||
mask = generate_grouped_flip_mask(
|
||||
random_value=random_value,
|
||||
hash_bits=512,
|
||||
noise_bits=8,
|
||||
rate_num=1,
|
||||
rate_den=1,
|
||||
)
|
||||
|
||||
expected = 0
|
||||
for group in range(8):
|
||||
expected |= 1 << (group * 64 + group + 1)
|
||||
|
||||
assert mask == expected
|
||||
assert mask.bit_count() == 8
|
||||
|
||||
|
||||
def test_grouped_flip_mask_zero_rate_no_flips():
|
||||
mask = generate_grouped_flip_mask(
|
||||
random_value=(1 << 128) - 1,
|
||||
hash_bits=512,
|
||||
noise_bits=8,
|
||||
rate_num=0,
|
||||
rate_den=100,
|
||||
)
|
||||
assert mask == 0
|
||||
|
||||
|
||||
def test_score_is_bit_match_popcount_not_hamming_distance():
|
||||
query = 0b1010
|
||||
stored = 0b1000
|
||||
assert xnor_popcount_score(query, stored, width=4) == 3
|
||||
|
||||
|
||||
def test_read_noise_model_is_reproducible_after_reset_seed():
|
||||
rows = [0, (1 << 512) - 1, 0x1234, 0x5678, 0x9ABC, 0xDEF0, 0x1357, 0x2468]
|
||||
query = rows[2]
|
||||
kwargs = dict(
|
||||
query=query,
|
||||
rows=rows,
|
||||
width=512,
|
||||
lanes=8,
|
||||
noise_bits=8,
|
||||
rate_num=1,
|
||||
rate_den=100,
|
||||
seed=0x6A09_E667_F3BC_C909,
|
||||
)
|
||||
|
||||
first = match_top1_with_read_noise(**kwargs)
|
||||
second = match_top1_with_read_noise(**kwargs)
|
||||
|
||||
assert first.top1_index == second.top1_index
|
||||
assert first.top1_score == second.top1_score
|
||||
assert first.scores.tolist() == second.scores.tolist()
|
||||
Reference in New Issue
Block a user