feat(hw/rtl): implement full Top-K CAM search pipeline with serial result output

- add TOPK_K, FIFO_DEPTH, RESULT_SERIAL parameters to cam_params
- add candidate_fifo: synchronous ready/valid FIFO for (row, score) candidates
- add topk_tracker: tracks top-K candidates with clear/ready handshake
- add result_serializer: serializes packed Top-K array into rank-ordered stream
- refactor match_engine_pipeline from 4-state to 8-state Top-K pipeline
- extend cam_top with serial Top-K interface (result_rank/row/score/last)
- add backward-compatible top1_index/top1_score aliases from rank-0 beat
- add comprehensive tests for all new modules
This commit is contained in:
2026-05-19 18:19:05 +08:00
parent 8bcad1f23f
commit e4cbb5e30d
21 changed files with 2152 additions and 124 deletions

View File

@@ -27,14 +27,20 @@ module cam_top #(
output logic query_ready,
input logic [(`HASH_BITS)-1:0] query_hash,
// Result interface
// Result interface (serial Top-K)
output logic result_valid,
input logic result_ready,
output logic [((`TOPK_K <= 1) ? 1 : $clog2(`TOPK_K))-1:0] result_rank,
output logic [(`ROW_BITS)-1:0] result_row,
output logic [(`SCORE_BITS)-1:0] result_score,
output logic result_last,
// Legacy Top-1 aliases (captured from rank-0 serial beat)
output logic [(`ROW_BITS)-1:0] top1_index,
output logic [(`SCORE_BITS)-1:0] top1_score,
`ifdef SIM_DEBUG
output logic [(`NUM_ROWS)*(`SCORE_BITS)-1:0] score_debug_flat,
output logic [$clog2(`NUM_ROWS+1)-1:0] consumed_candidates_debug,
`endif
output logic busy
@@ -101,8 +107,10 @@ module cam_top #(
.query_hash (query_hash),
.result_valid (result_valid),
.result_ready (result_ready),
.result_row (top1_index),
.result_score (top1_score),
.result_rank (result_rank),
.result_row (result_row),
.result_score (result_score),
.result_last (result_last),
.busy (match_busy),
.rd_valid_o (rd_req_valid),
.rd_base_row_o (rd_req_base_row),
@@ -111,8 +119,21 @@ module cam_top #(
.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)
,.consumed_candidates_debug (consumed_candidates_debug)
`endif
);
// ── Rank-0 (Top-1) aliases ──
// Capture first serial beat (rank==0) into legacy top1_index/top1_score outputs.
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
top1_index <= '0;
top1_score <= '0;
end else if (result_valid && result_ready && (result_rank == '0)) begin
top1_index <= result_row;
top1_score <= result_score;
end
end
endmodule