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:
@@ -2,11 +2,16 @@
|
||||
`include "cam_params.svh"
|
||||
|
||||
module cam_top #(
|
||||
parameter bit NOISE_EN = 1'b1,
|
||||
parameter int NOISE_RATE_NUM = 1,
|
||||
parameter int NOISE_RATE_DEN = 100,
|
||||
parameter int NOISE_BITS = 8,
|
||||
parameter logic [63:0] NOISE_SEED = 64'hB504_F32D_B504_F32D
|
||||
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,
|
||||
parameter bit READ_NOISE_EN = 1'b0,
|
||||
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,
|
||||
@@ -36,7 +41,7 @@ module cam_top #(
|
||||
);
|
||||
|
||||
// ── Internal signals ──
|
||||
logic storage_wr_ready; // cam_noisy idle
|
||||
logic storage_wr_ready; // cam_noisy write-side ready
|
||||
logic match_query_ready; // match_engine idle
|
||||
logic match_busy; // match_engine scanning/result pending
|
||||
|
||||
@@ -45,8 +50,8 @@ module cam_top #(
|
||||
logic match_query_valid;
|
||||
|
||||
// ── Half-duplex arbitration (write-priority) ──
|
||||
// When both wr_valid and query_valid are high, write wins.
|
||||
assign wr_ready = storage_wr_ready && match_query_ready;
|
||||
// Active query scan blocks new writes.
|
||||
assign wr_ready = storage_wr_ready && match_query_ready && !match_busy;
|
||||
assign query_ready = storage_wr_ready && match_query_ready && !wr_valid;
|
||||
assign busy = (!storage_wr_ready) || match_busy || (!match_query_ready);
|
||||
|
||||
@@ -54,42 +59,59 @@ module cam_top #(
|
||||
assign storage_wr_valid = wr_valid && wr_ready;
|
||||
assign match_query_valid = query_valid && query_ready;
|
||||
|
||||
// ── Shared read bus ──
|
||||
wire [(`LANES)*(`ROW_BITS)-1:0] rd_addr_lanes_flat;
|
||||
wire [(`LANES)*(`HASH_BITS)-1:0] rd_hash_lanes_flat;
|
||||
// ── Read request/response bus between cam_noisy and match_engine_pipeline ──
|
||||
wire rd_req_valid;
|
||||
wire [(`ROW_BITS)-1:0] rd_req_base_row;
|
||||
wire rd_resp_valid;
|
||||
wire [(`LANES)*(`ROW_BITS)-1:0] rd_resp_row_ids;
|
||||
wire [(`LANES)*(`HASH_BITS)-1:0] rd_resp_hashes;
|
||||
wire [(`LANES)-1:0] rd_resp_lane_valid;
|
||||
|
||||
cam_noisy #(
|
||||
.NOISE_EN (NOISE_EN),
|
||||
.NOISE_RATE_NUM (NOISE_RATE_NUM),
|
||||
.NOISE_RATE_DEN (NOISE_RATE_DEN),
|
||||
.NOISE_BITS (NOISE_BITS),
|
||||
.NOISE_SEED (NOISE_SEED)
|
||||
.WRITE_NOISE_EN (WRITE_NOISE_EN),
|
||||
.WRITE_NOISE_RATE_NUM (WRITE_NOISE_RATE_NUM),
|
||||
.WRITE_NOISE_RATE_DEN (WRITE_NOISE_RATE_DEN),
|
||||
.WRITE_NOISE_BITS (WRITE_NOISE_BITS),
|
||||
.WRITE_NOISE_SEED (WRITE_NOISE_SEED),
|
||||
.READ_NOISE_EN (READ_NOISE_EN),
|
||||
.READ_NOISE_RATE_NUM (READ_NOISE_RATE_NUM),
|
||||
.READ_NOISE_RATE_DEN (READ_NOISE_RATE_DEN),
|
||||
.READ_NOISE_BITS (READ_NOISE_BITS),
|
||||
.READ_NOISE_SEED (READ_NOISE_SEED)
|
||||
) u_noisy (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.wr_valid (storage_wr_valid),
|
||||
.wr_ready (storage_wr_ready),
|
||||
.wr_addr (wr_addr),
|
||||
.write_hash (write_hash),
|
||||
.rd_addr_lanes_flat (rd_addr_lanes_flat),
|
||||
.rd_hash_lanes_flat (rd_hash_lanes_flat)
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.wr_valid (storage_wr_valid),
|
||||
.wr_ready (storage_wr_ready),
|
||||
.wr_addr (wr_addr),
|
||||
.write_hash (write_hash),
|
||||
.rd_valid_i (rd_req_valid),
|
||||
.rd_base_row_i (rd_req_base_row),
|
||||
.rd_valid_o (rd_resp_valid),
|
||||
.rd_row_ids_o (rd_resp_row_ids),
|
||||
.rd_hashes_o (rd_resp_hashes),
|
||||
.rd_lane_valid_o (rd_resp_lane_valid)
|
||||
);
|
||||
|
||||
match_engine u_match (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.query_valid (match_query_valid),
|
||||
.query_ready (match_query_ready),
|
||||
.query_hash (query_hash),
|
||||
.result_valid (result_valid),
|
||||
.result_ready (result_ready),
|
||||
.result_row (top1_index),
|
||||
.result_score (top1_score),
|
||||
.busy (match_busy),
|
||||
.rd_addr_lanes_flat (rd_addr_lanes_flat),
|
||||
.rd_hash_lanes_flat (rd_hash_lanes_flat)
|
||||
match_engine_pipeline u_match (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
.query_valid (match_query_valid),
|
||||
.query_ready (match_query_ready),
|
||||
.query_hash (query_hash),
|
||||
.result_valid (result_valid),
|
||||
.result_ready (result_ready),
|
||||
.result_row (top1_index),
|
||||
.result_score (top1_score),
|
||||
.busy (match_busy),
|
||||
.rd_valid_o (rd_req_valid),
|
||||
.rd_base_row_o (rd_req_base_row),
|
||||
.rd_valid_i (rd_resp_valid),
|
||||
.rd_row_ids_i (rd_resp_row_ids),
|
||||
.rd_hashes_i (rd_resp_hashes),
|
||||
.rd_lane_valid_i (rd_resp_lane_valid)
|
||||
`ifdef SIM_DEBUG
|
||||
,.score_debug_flat (score_debug_flat)
|
||||
,.score_debug_flat (score_debug_flat)
|
||||
`endif
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user