Files
Mini-Nav/hw/rtl/cam_core_banked.sv
SikongJueluo 8f59a287c4 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
2026-05-13 18:22:28 +08:00

58 lines
2.0 KiB
Systemverilog

`timescale 1ns / 1ps
`include "cam_params.svh"
module cam_core_banked (
input logic clk,
input logic rst_n,
input logic wr_valid,
output logic wr_ready,
input logic [(`ROW_BITS)-1:0] wr_row,
input logic [(`HASH_BITS)-1:0] wr_hash,
input logic rd_valid_i,
input logic [(`ROW_BITS)-1:0] rd_base_row_i,
output logic rd_valid_o,
output logic [(`LANES)*(`ROW_BITS)-1:0] rd_row_ids_o,
output logic [(`LANES)*(`HASH_BITS)-1:0] rd_hashes_o,
output logic [(`LANES)-1:0] rd_lane_valid_o
);
localparam int BANKS = `LANES;
localparam int BANK_DEPTH = `NUM_ROWS / `LANES;
(* ram_style = "block" *) logic [(`HASH_BITS)-1:0] bank_mem [0:BANKS-1][0:BANK_DEPTH-1];
assign wr_ready = 1'b1;
initial begin
if (`NUM_ROWS % `LANES != 0) $fatal(1, "NUM_ROWS must be divisible by LANES");
end
always_ff @(posedge clk) begin
if (wr_valid) begin
bank_mem[wr_row % `LANES][wr_row / `LANES] <= wr_hash;
end
end
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rd_valid_o <= 1'b0;
rd_row_ids_o <= '0;
rd_hashes_o <= '0;
rd_lane_valid_o <= '0;
end else begin
rd_valid_o <= rd_valid_i;
rd_lane_valid_o <= rd_valid_i ? {`LANES{1'b1}} : '0;
if (rd_valid_i && ((rd_base_row_i % `LANES) != 0)) begin
$fatal(1, "rd_base_row_i must be LANES-aligned");
end
for (int lane = 0; lane < `LANES; lane++) begin
rd_row_ids_o[lane*`ROW_BITS +: `ROW_BITS] <= rd_base_row_i + lane[(`ROW_BITS)-1:0];
rd_hashes_o[lane*`HASH_BITS +: `HASH_BITS] <= bank_mem[lane][rd_base_row_i / `LANES];
end
end
end
endmodule