feat(top): add shared keccak variants, arbiter, and mlkem_top integration
- sha3_chain_top_shared.v: external keccak_core interface (6 ports) - sample_cbd_sync_shared.v: shared keccak variant (6 ports) - sample_ntt_sync_shared.v: shared keccak variant (6 ports) - keccak_arbiter.v: fixed-priority arbiter for 3 keccak consumers - mlkem_top.v: 1403-line monolithic FSM with KeyGen/Encaps/Decaps Architecture: keccak_arbiter → keccak_core → keccak_round (shared) sha3_chain_top_shared (consumer 0) sample_cbd_sync_shared (consumer 1) sample_ntt_sync_shared (consumer 2) sha3_top (separate, own keccak_core) rng_sync, ntt_core, poly_arith, poly_mul, comp_decomp, mod_add sd_bram for polynomial storage All original RTL files preserved unchanged.
This commit is contained in:
115
sync_rtl/sha3_chain/sha3_chain_top_shared.v
Normal file
115
sync_rtl/sha3_chain/sha3_chain_top_shared.v
Normal file
@@ -0,0 +1,115 @@
|
||||
// sha3_chain_top_shared.v - SHA3-512 chain: G(d||k=2) → rho, sigma
|
||||
//
|
||||
// Refactored version that accepts an external keccak_core interface instead
|
||||
// of instantiating sha3_top internally. Designed for shared-keccak top-level
|
||||
// integration where a single keccak_core is time-multiplexed via an arbiter.
|
||||
//
|
||||
// The internal logic replicates sha3_top's G-mode absorb-state construction
|
||||
// and keccak sequencing, but exposes keccak_core signals through the port
|
||||
// list so the arbiter can route them.
|
||||
//
|
||||
// 3-state FSM: IDLE → BUSY → DONE
|
||||
//
|
||||
// Interface:
|
||||
// clk, rst_n - clock, active-low reset
|
||||
// d_in[255:0] - 256-bit d input (external, NOT from RNG)
|
||||
// start_i - start computation
|
||||
// done_o - computation complete (pulsed for duration of DONE)
|
||||
// rho_out[255:0] - G output first 256 bits
|
||||
// sigma_out[255:0] - G output next 256 bits
|
||||
// kc_state_o[1599:0]- from keccak_core output (post-permutation state)
|
||||
// kc_valid_o - from keccak_core (permutation complete)
|
||||
// kc_ready_i - to keccak_core (always accept output = 1'b1)
|
||||
// kc_state_i[1599:0]- to keccak_core input (pre-permutation state)
|
||||
// kc_valid_i - to keccak_core (start permutation pulse)
|
||||
// kc_ready_o - from keccak_core (core is idle / can accept)
|
||||
|
||||
module sha3_chain_top_shared (
|
||||
input clk,
|
||||
input rst_n,
|
||||
input [255:0] d_in,
|
||||
input start_i,
|
||||
output done_o,
|
||||
output [255:0] rho_out,
|
||||
output [255:0] sigma_out,
|
||||
// keccak_core interface (connect to shared arbiter)
|
||||
input [1599:0] kc_state_o,
|
||||
input kc_valid_o,
|
||||
output kc_ready_i,
|
||||
output [1599:0] kc_state_i,
|
||||
output kc_valid_i,
|
||||
input kc_ready_o
|
||||
);
|
||||
|
||||
localparam ST_IDLE = 2'd0;
|
||||
localparam ST_BUSY = 2'd1;
|
||||
localparam ST_DONE = 2'd2;
|
||||
|
||||
reg [1:0] state_r, state_next;
|
||||
|
||||
// ================================================================
|
||||
// Absorb state: message || suffix || pad10*1 into rate bits
|
||||
//
|
||||
// Replicates sha3_top G-mode absorb_state construction:
|
||||
// data_i = {248'b0, k=8'd2, d_in}
|
||||
// G: padded_block = {1'b1, {308{1'b0}}, 1'b1, 2'b10, data_i[263:0]}
|
||||
// absorb_state = {1024'b0, padded_block_576}
|
||||
// ================================================================
|
||||
wire [511:0] sha3_data_i;
|
||||
wire [575:0] g_pad;
|
||||
wire [1599:0] absorb_state;
|
||||
|
||||
assign sha3_data_i = {248'b0, 8'd2, d_in};
|
||||
assign g_pad = {1'b1, {308{1'b0}}, 1'b1, 2'b10, sha3_data_i[263:0]};
|
||||
assign absorb_state = {{(1600-576){1'b0}}, g_pad};
|
||||
|
||||
// ================================================================
|
||||
// keccak_core interface connections
|
||||
// ================================================================
|
||||
assign kc_ready_i = 1'b1; // always accept output
|
||||
assign kc_state_i = absorb_state; // feed absorb state combinationally
|
||||
assign kc_valid_i = (state_next == ST_BUSY); // start keccak on IDLE → BUSY
|
||||
|
||||
// done_o: asserted for duration of DONE state
|
||||
assign done_o = (state_r == ST_DONE);
|
||||
|
||||
// ================================================================
|
||||
// Output registers
|
||||
// ================================================================
|
||||
reg [255:0] rho_out_r, sigma_out_r;
|
||||
assign rho_out = rho_out_r;
|
||||
assign sigma_out = sigma_out_r;
|
||||
|
||||
// ================================================================
|
||||
// FSM combinational next-state
|
||||
// ================================================================
|
||||
always @(*) begin
|
||||
state_next = state_r;
|
||||
case (state_r)
|
||||
ST_IDLE: if (start_i && kc_ready_o) state_next = ST_BUSY;
|
||||
ST_BUSY: if (kc_valid_o) state_next = ST_DONE;
|
||||
ST_DONE: if (!start_i) state_next = ST_IDLE;
|
||||
default: state_next = ST_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// ================================================================
|
||||
// Sequential logic
|
||||
// ================================================================
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
state_r <= ST_IDLE;
|
||||
rho_out_r <= 256'd0;
|
||||
sigma_out_r <= 256'd0;
|
||||
end else begin
|
||||
state_r <= state_next;
|
||||
|
||||
// Capture squeezed output when BUSY → DONE
|
||||
if (state_r == ST_BUSY && kc_valid_o) begin
|
||||
rho_out_r <= kc_state_o[255:0];
|
||||
sigma_out_r <= kc_state_o[511:256];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user