refactor(cam): remove read noise from noise architecture (Phase 2)

- Make cam_read_noise a pass-through module, removing all noise injection logic
- Switch write noise to use noise_mask_bernoulli instead of noise_mask_grouped
- Add state machine to cam_write_noise for mask generation timing
- Remove noise_mask_grouped.sv (no longer needed)
- Remove read noise parameters from cam_noisy and cam_top
- Update simulation and benchmark code to reflect read noise removal
- Sync documentation to reflect Phase 2 architecture
This commit is contained in:
2026-05-26 23:02:22 +08:00
parent e5d13917b2
commit 8b4d4c1b57
29 changed files with 277 additions and 863 deletions

View File

@@ -12,10 +12,8 @@ import numpy as np
from cocotb.clock import Clock
from model.ref_model import (
lane_seed_128,
match_topk,
match_topk_from_scores,
score_rows_with_read_noise,
)
from tests.top.utils import (
dut_hash_bits,
@@ -199,13 +197,9 @@ def compute_metrics(topk_indices: list[int], row_labels: list[int], query_label:
return precision, recall, f1
def mode_from_params(write_noise_en: int, read_noise_en: int) -> str:
if write_noise_en and read_noise_en:
return "write_read_noise"
def mode_from_params(write_noise_en: int) -> str:
if write_noise_en:
return "write_noise"
if read_noise_en:
return "read_noise"
return "no_noise"
@@ -228,8 +222,8 @@ def write_outputs(out_dir: Path, result: dict) -> None:
fieldnames = [
"run_id", "mode", "num_rows", "hash_bits", "lanes", "topk_k",
"write_noise_en", "read_noise_en", "write_noise_rate_num",
"write_noise_rate_den", "read_noise_rate_num", "read_noise_rate_den",
"write_noise_en", "write_noise_rate_num",
"write_noise_rate_den",
"num_queries", "k", "macro_precision", "retrieval_recall", "macro_f1",
"recall@k", "exact_match_rate", "status",
]
@@ -245,11 +239,8 @@ def write_outputs(out_dir: Path, result: dict) -> None:
"lanes": result["params"]["lanes"],
"topk_k": result["params"]["topk_k"],
"write_noise_en": result["params"]["write_noise_en"],
"read_noise_en": result["params"]["read_noise_en"],
"write_noise_rate_num": result["params"]["write_noise_rate_num"],
"write_noise_rate_den": result["params"]["write_noise_rate_den"],
"read_noise_rate_num": result["params"]["read_noise_rate_num"],
"read_noise_rate_den": result["params"]["read_noise_rate_den"],
"num_queries": result["dataset"]["num_queries"],
"k": int(k),
"macro_precision": metrics["macro_precision"],
@@ -293,13 +284,9 @@ async def cam_retrieval_benchmark(dut):
hash_bits = dut_hash_bits(dut)
lanes = dut_lanes(dut)
write_noise_en = int(get_param(dut, "WRITE_NOISE_EN", 0) or 0)
read_noise_en = int(get_param(dut, "READ_NOISE_EN", 0) or 0)
write_noise_rate_num = int(get_param(dut, "WRITE_NOISE_RATE_NUM", 0) or 0)
write_noise_rate_den = int(get_param(dut, "WRITE_NOISE_RATE_DEN", 100) or 100)
read_noise_rate_num = int(get_param(dut, "READ_NOISE_RATE_NUM", 0) or 0)
read_noise_rate_den = int(get_param(dut, "READ_NOISE_RATE_DEN", 100) or 100)
read_noise_bits = int(get_param(dut, "READ_NOISE_BITS", 8) or 8)
mode = mode_from_params(write_noise_en, read_noise_en)
mode = mode_from_params(write_noise_en)
if write_noise_en:
raise AssertionError("First retrieval benchmark version only supports WRITE_NOISE_EN=0")
@@ -315,7 +302,6 @@ async def cam_retrieval_benchmark(dut):
await write_rows(dut, dataset.rows)
accumulators = {k: MetricAccumulator() for k in BENCHMARK_KS}
read_lane_states = [lane_seed_128(0x6A09_E667_F3BC_C909, lane) for lane in range(lanes)]
for query, query_label in zip(dataset.queries, dataset.query_labels):
beats, _, _, _ = await query_topk_once(dut, query)
@@ -324,15 +310,7 @@ async def cam_retrieval_benchmark(dut):
dut_topk = [int(beat[1]) for beat in beats[: max(BENCHMARK_KS)]]
if read_noise_en:
scores, read_lane_states = score_rows_with_read_noise(
query, dataset.rows, lane_states=read_lane_states,
width=hash_bits, lanes=lanes, noise_bits=read_noise_bits,
rate_num=read_noise_rate_num, rate_den=read_noise_rate_den,
)
golden_topk = match_topk_from_scores(scores, max(BENCHMARK_KS))
else:
golden_topk, _ = match_topk(query, dataset.rows, width=hash_bits, k=max(BENCHMARK_KS))
golden_topk, _ = match_topk(query, dataset.rows, width=hash_bits, k=max(BENCHMARK_KS))
for k in BENCHMARK_KS:
precision, recall, f1 = compute_metrics(dut_topk, dataset.row_labels, query_label, k)
@@ -352,11 +330,8 @@ async def cam_retrieval_benchmark(dut):
"lanes": lanes,
"topk_k": max(BENCHMARK_KS),
"write_noise_en": write_noise_en,
"read_noise_en": read_noise_en,
"write_noise_rate_num": write_noise_rate_num,
"write_noise_rate_den": write_noise_rate_den,
"read_noise_rate_num": read_noise_rate_num,
"read_noise_rate_den": read_noise_rate_den,
},
"dataset": {
"num_classes": dataset.num_classes,