mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
feat(hw/rtl): add xorshift PRNG modules and refactor cam_noisy FSM
- Add random32, random64 and random128 xorshift PRNG modules - Refactor cam_noisy FSM: split state register, next-state logic, and datapath into distinct blocks - Rename state_q/state_d to curr_state/next_state for clarity - Add MASK_GROUPS localparam and fix type casting in noise generation - Update .gitignore to exclude docs/superpowers
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -219,6 +219,7 @@ outputs/
|
|||||||
.claude/settings.local.json
|
.claude/settings.local.json
|
||||||
openspec/changes/
|
openspec/changes/
|
||||||
.logs/
|
.logs/
|
||||||
|
docs/superpowers
|
||||||
|
|
||||||
# Devenv
|
# Devenv
|
||||||
.devenv*
|
.devenv*
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ module cam_noisy #(
|
|||||||
S_COMMIT
|
S_COMMIT
|
||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
state_t state_q, state_d;
|
state_t curr_state, next_state;
|
||||||
|
|
||||||
// ── Latch registers ──
|
// ── Latch registers ──
|
||||||
logic [(`ROW_BITS)-1:0] addr_q;
|
logic [(`ROW_BITS)-1:0] addr_q;
|
||||||
@@ -60,6 +60,7 @@ module cam_noisy #(
|
|||||||
// ── Noise generation ──
|
// ── Noise generation ──
|
||||||
logic [63:0] prng_state;
|
logic [63:0] prng_state;
|
||||||
logic [(`HASH_BITS)-1:0] flip_mask;
|
logic [(`HASH_BITS)-1:0] flip_mask;
|
||||||
|
localparam int MASK_GROUPS = `HASH_BITS / NOISE_GEN_BITS;
|
||||||
logic [($clog2(`HASH_BITS/NOISE_GEN_BITS+1))-1:0] mask_group_idx; // 0..HASH_BITS/NOISE_GEN_BITS-1
|
logic [($clog2(`HASH_BITS/NOISE_GEN_BITS+1))-1:0] mask_group_idx; // 0..HASH_BITS/NOISE_GEN_BITS-1
|
||||||
|
|
||||||
// ── Precomputed threshold ──
|
// ── Precomputed threshold ──
|
||||||
@@ -81,47 +82,54 @@ module cam_noisy #(
|
|||||||
assign noisy_hash = write_hash_q ^ flip_mask;
|
assign noisy_hash = write_hash_q ^ flip_mask;
|
||||||
|
|
||||||
// ── wr_ready: only in IDLE ──
|
// ── wr_ready: only in IDLE ──
|
||||||
assign wr_ready = (state_q == S_IDLE);
|
assign wr_ready = (curr_state == S_IDLE);
|
||||||
|
|
||||||
// ── FSM combinational logic ──
|
// ── FSM block 1: state register ──
|
||||||
|
always_ff @(posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
curr_state <= S_IDLE;
|
||||||
|
end else begin
|
||||||
|
curr_state <= next_state;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// ── FSM block 2: next-state logic ──
|
||||||
always_comb begin
|
always_comb begin
|
||||||
state_d = state_q;
|
next_state = curr_state;
|
||||||
case (state_q)
|
case (curr_state)
|
||||||
S_IDLE: begin
|
S_IDLE: begin
|
||||||
if (wr_valid && wr_ready) begin
|
if (wr_valid && wr_ready) begin
|
||||||
if (NOISE_EN && (NOISE_RATE_NUM > 0))
|
if (NOISE_EN && (NOISE_RATE_NUM > 0))
|
||||||
state_d = S_GEN_MASK;
|
next_state = S_GEN_MASK;
|
||||||
else
|
else
|
||||||
state_d = S_COMMIT;
|
next_state = S_COMMIT;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
S_GEN_MASK: begin
|
S_GEN_MASK: begin
|
||||||
if (mask_group_idx == (`HASH_BITS / NOISE_GEN_BITS - 1))
|
if (int'(mask_group_idx) == (MASK_GROUPS - 1))
|
||||||
state_d = S_COMMIT;
|
next_state = S_COMMIT;
|
||||||
end
|
end
|
||||||
|
|
||||||
S_COMMIT: begin
|
S_COMMIT: begin
|
||||||
state_d = S_IDLE;
|
next_state = S_IDLE;
|
||||||
end
|
end
|
||||||
|
|
||||||
default: state_d = S_IDLE;
|
default: next_state = S_IDLE;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
// ── Sequential logic ──
|
// ── FSM block 3: state actions / datapath registers ──
|
||||||
always_ff @(posedge clk or negedge rst_n) begin
|
always_ff @(posedge clk or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
state_q <= S_IDLE;
|
|
||||||
addr_q <= '0;
|
addr_q <= '0;
|
||||||
write_hash_q <= '0;
|
write_hash_q <= '0;
|
||||||
flip_mask <= '0;
|
flip_mask <= '0;
|
||||||
prng_state <= NOISE_SEED;
|
prng_state <= NOISE_SEED;
|
||||||
mask_group_idx <= '0;
|
mask_group_idx <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
state_q <= state_d;
|
|
||||||
|
|
||||||
case (state_q)
|
case (curr_state)
|
||||||
S_IDLE: begin
|
S_IDLE: begin
|
||||||
flip_mask <= '0;
|
flip_mask <= '0;
|
||||||
mask_group_idx <= '0;
|
mask_group_idx <= '0;
|
||||||
@@ -141,7 +149,7 @@ module cam_noisy #(
|
|||||||
for (int b = 0; b < NOISE_GEN_BITS; b++) begin
|
for (int b = 0; b < NOISE_GEN_BITS; b++) begin
|
||||||
logic [NOISE_SAMPLE_BITS-1:0] sample;
|
logic [NOISE_SAMPLE_BITS-1:0] sample;
|
||||||
sample = prng_next[b * NOISE_SAMPLE_BITS +: NOISE_SAMPLE_BITS];
|
sample = prng_next[b * NOISE_SAMPLE_BITS +: NOISE_SAMPLE_BITS];
|
||||||
if (sample < THRESHOLD) begin
|
if (int'(sample) < THRESHOLD) begin
|
||||||
flip_mask[mask_group_idx * NOISE_GEN_BITS + b] <= 1'b1;
|
flip_mask[mask_group_idx * NOISE_GEN_BITS + b] <= 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -164,7 +172,7 @@ module cam_noisy #(
|
|||||||
logic [(`ROW_BITS)-1:0] core_wr_row;
|
logic [(`ROW_BITS)-1:0] core_wr_row;
|
||||||
logic [(`HASH_BITS)-1:0] core_wr_hash;
|
logic [(`HASH_BITS)-1:0] core_wr_hash;
|
||||||
|
|
||||||
assign core_wr_en = (state_q == S_COMMIT);
|
assign core_wr_en = (curr_state == S_COMMIT);
|
||||||
assign core_wr_row = addr_q;
|
assign core_wr_row = addr_q;
|
||||||
assign core_wr_hash = noisy_hash;
|
assign core_wr_hash = noisy_hash;
|
||||||
|
|
||||||
|
|||||||
57
hw/rtl/random/random128.sv
Normal file
57
hw/rtl/random/random128.sv
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module random128 (
|
||||||
|
input logic clk,
|
||||||
|
input logic rst_n,
|
||||||
|
input logic enable,
|
||||||
|
input logic [127:0] seed,
|
||||||
|
output logic [127:0] out
|
||||||
|
);
|
||||||
|
|
||||||
|
// xorshift128:
|
||||||
|
// state = {x, y, z, w}
|
||||||
|
//
|
||||||
|
// t = x ^ (x << 11)
|
||||||
|
// x = y
|
||||||
|
// y = z
|
||||||
|
// z = w
|
||||||
|
// w = w ^ (w >> 19) ^ t ^ (t >> 8)
|
||||||
|
//
|
||||||
|
// 注意:seed 不能为全 0,否则会永久输出 0。
|
||||||
|
function automatic logic [127:0] xorshift128(input logic [127:0] state);
|
||||||
|
logic [31:0] x;
|
||||||
|
logic [31:0] y;
|
||||||
|
logic [31:0] z;
|
||||||
|
logic [31:0] w;
|
||||||
|
logic [31:0] t;
|
||||||
|
logic [31:0] next_x;
|
||||||
|
logic [31:0] next_y;
|
||||||
|
logic [31:0] next_z;
|
||||||
|
logic [31:0] next_w;
|
||||||
|
|
||||||
|
begin
|
||||||
|
x = state[127:96];
|
||||||
|
y = state[95:64];
|
||||||
|
z = state[63:32];
|
||||||
|
w = state[31:0];
|
||||||
|
|
||||||
|
t = x ^ (x << 11);
|
||||||
|
|
||||||
|
next_x = y;
|
||||||
|
next_y = z;
|
||||||
|
next_z = w;
|
||||||
|
next_w = w ^ (w >> 19) ^ t ^ (t >> 8);
|
||||||
|
|
||||||
|
return {next_x, next_y, next_z, next_w};
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
always_ff @(posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
out <= seed;
|
||||||
|
end else if (enable) begin
|
||||||
|
out <= xorshift128(out);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
28
hw/rtl/random/random32.sv
Normal file
28
hw/rtl/random/random32.sv
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module random32 (
|
||||||
|
input logic clk,
|
||||||
|
input logic rst_n,
|
||||||
|
input logic enable,
|
||||||
|
input logic [31:0] seed,
|
||||||
|
output logic [31:0] out
|
||||||
|
);
|
||||||
|
|
||||||
|
function automatic logic [31:0] xorshift32(input logic [31:0] x);
|
||||||
|
logic [31:0] s;
|
||||||
|
s = x;
|
||||||
|
s ^= s << 13;
|
||||||
|
s ^= s >> 17;
|
||||||
|
s ^= s << 5;
|
||||||
|
return s;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
always_ff @(posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
out <= seed;
|
||||||
|
end else if (enable) begin
|
||||||
|
out <= xorshift32(out);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
28
hw/rtl/random/random64.sv
Normal file
28
hw/rtl/random/random64.sv
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module random64 (
|
||||||
|
input logic clk,
|
||||||
|
input logic rst_n,
|
||||||
|
input logic enable,
|
||||||
|
input logic [63:0] seed,
|
||||||
|
output logic [63:0] out
|
||||||
|
);
|
||||||
|
|
||||||
|
function automatic logic [63:0] xorshift64(input logic [63:0] x);
|
||||||
|
logic [63:0] s;
|
||||||
|
s = x;
|
||||||
|
s ^= s << 13;
|
||||||
|
s ^= s >> 7;
|
||||||
|
s ^= s << 17;
|
||||||
|
return s;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
always_ff @(posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
out <= seed;
|
||||||
|
end else if (enable) begin
|
||||||
|
out <= xorshift64(out);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Reference in New Issue
Block a user