feat(hw): add XNOR-popcount CAM design with cocotb verification

Implement a multi-lane Content Addressable Memory (CAM) that scores
rows by XNOR popcount against a query hash and returns the top-1 match.

RTL modules:
- popcount: parallel group-based population count
- argmax_update: iterative best-match tracking with tie-break
- cam_core: parameterized scanning engine (NUM_ROWS/HASH_BITS/LANES)
  with optional SIM_NOISE and SIM_DEBUG ifdef guards
- cam_top: thin wrapper exposing cam_core ports

Verification:
- Python reference model (ref_model.py) for score-level golden comparison
- cocotb testbench (test_cam_basic.py) covering write/query/reset and
  external noise mask scenarios with score debug verification
- Noise sweep script (sweep_noise.py) measuring top-1 stability under
  configurable bit-flip rates
- Verilator-oriented Makefile with parameterizable compile options
This commit is contained in:
2026-05-02 17:49:22 +08:00
parent ad45123022
commit f71bf06484
8 changed files with 769 additions and 0 deletions

26
hw/rtl/argmax_update.sv Normal file
View File

@@ -0,0 +1,26 @@
`timescale 1ns/1ps
module argmax_update #(
parameter int ROW_BITS = 9,
parameter int SCORE_BITS = 10
) (
input logic [ROW_BITS-1:0] best_index_i,
input logic [SCORE_BITS-1:0] best_score_i,
input logic [ROW_BITS-1:0] cand_index_i,
input logic [SCORE_BITS-1:0] cand_score_i,
output logic [ROW_BITS-1:0] best_index_o,
output logic [SCORE_BITS-1:0] best_score_o
);
always_comb begin
best_index_o = best_index_i;
best_score_o = best_score_i;
if ((cand_score_i > best_score_i) ||
((cand_score_i == best_score_i) && (cand_index_i < best_index_i))) begin
best_index_o = cand_index_i;
best_score_o = cand_score_i;
end
end
endmodule