mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
- Replace NOISE_GEN_BITS/NOISE_SAMPLE_BITS parameters with unified NOISE_BITS
- Use xorshift128 (random128) instead of xorshift64 for PRNG
- Add flip_mask_next combinational helper for single-cycle mask computation
- Add random_enable signal to advance PRNG only on accepted noisy writes
- Simplify FSM by removing mask_group_idx counter
- Update parameter validation: GROUP_BITS (= HASH_BITS/NOISE_BITS) must equal 64
- Update ref_model.py and tests to match new seed convention: {seed, seed}
- Update Makefile and sweep_noise.py with renamed parameters
97 lines
3.3 KiB
Systemverilog
97 lines
3.3 KiB
Systemverilog
`timescale 1ns/1ps
|
|
`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
|
|
) (
|
|
input logic clk,
|
|
input logic rst_n,
|
|
|
|
// Write interface (handshake)
|
|
input logic wr_valid,
|
|
output logic wr_ready,
|
|
input logic [(`ROW_BITS)-1:0] wr_addr,
|
|
input logic [(`HASH_BITS)-1:0] write_hash,
|
|
|
|
// Query interface
|
|
input logic query_valid,
|
|
output logic query_ready,
|
|
input logic [(`HASH_BITS)-1:0] query_hash,
|
|
|
|
// Result interface
|
|
output logic result_valid,
|
|
input logic result_ready,
|
|
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,
|
|
`endif
|
|
|
|
output logic busy
|
|
);
|
|
|
|
// ── Internal signals ──
|
|
logic storage_wr_ready; // cam_noisy idle
|
|
logic match_query_ready; // match_engine idle
|
|
logic match_busy; // match_engine scanning/result pending
|
|
|
|
// ── Internal valid forwarding ──
|
|
logic storage_wr_valid;
|
|
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;
|
|
assign query_ready = storage_wr_ready && match_query_ready && !wr_valid;
|
|
assign busy = (!storage_wr_ready) || match_busy || (!match_query_ready);
|
|
|
|
// ── Internal valid forwarding (only assert to sub-modules when top-level accepts) ──
|
|
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;
|
|
|
|
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)
|
|
) 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)
|
|
);
|
|
|
|
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)
|
|
`ifdef SIM_DEBUG
|
|
,.score_debug_flat (score_debug_flat)
|
|
`endif
|
|
);
|
|
|
|
endmodule
|