Pipeline ML-KEM datapath bottlenecks

This commit is contained in:
2026-07-08 00:23:46 +08:00
parent 8c3f4317f5
commit 372a90e601
17 changed files with 776 additions and 176 deletions

View File

@@ -7,6 +7,8 @@ module tb_mlkem_kg_katK_xsim;
parameter KP = 2;
localparam EKB = 384*KP + 32;
localparam DKB = 768*KP + 96;
localparam integer CLK_PERIOD_NS = 100; // 10 MHz
localparam integer CLK_HALF_NS = CLK_PERIOD_NS / 2;
reg clk=0, rst_n=0, start_i=0;
reg [2:0] k_i;
@@ -33,7 +35,7 @@ module tb_mlkem_kg_katK_xsim;
.dbg_r_o(), .dbg_hek_o(),
.dbg_mprime_o(), .dbg_kbar_o(), .dbg_decz_o(), .dbg_dech_o()
);
always #5 clk = ~clk;
always #(CLK_HALF_NS) clk = ~clk;
reg [255:0] dmem [0:0];
reg [255:0] zmem [0:0];
@@ -42,8 +44,72 @@ module tb_mlkem_kg_katK_xsim;
reg [7:0] ek_got [0:EKB-1]; // ek bytes read back from DUT
reg [7:0] dk_got [0:DKB-1]; // dk bytes read back from DUT
integer c, i, errors, casenum, j;
integer state_cyc [0:31];
integer si;
reg [8*80-1:0] tag, dfile, zfile, ekfile, dkfile;
function [8*16-1:0] state_name;
input [4:0] s;
begin
case (s)
5'd0: state_name = "IDLE";
5'd1: state_name = "G";
5'd2: state_name = "A";
5'd3: state_name = "C";
5'd4: state_name = "N";
5'd5: state_name = "M";
5'd6: state_name = "E";
5'd7: state_name = "H";
5'd8: state_name = "ENC_LOAD";
5'd9: state_name = "ENC_H";
5'd10: state_name = "ENC_G";
5'd11: state_name = "ENC_A";
5'd12: state_name = "ENC_TDEC";
5'd13: state_name = "ENC_C";
5'd14: state_name = "ENC_N";
5'd15: state_name = "ENC_U";
5'd16: state_name = "ENC_C1";
5'd17: state_name = "ENC_V";
5'd18: state_name = "ENC_C2";
5'd19: state_name = "ENC_E2MV";
5'd20: state_name = "DEC_LOAD";
5'd21: state_name = "DEC_DECOMP";
5'd22: state_name = "DEC_SDEC";
5'd23: state_name = "DEC_NTT";
5'd24: state_name = "DEC_W";
5'd25: state_name = "DEC_MENC";
5'd26: state_name = "DEC_G";
5'd27: state_name = "DEC_J";
5'd28: state_name = "DEC_CMP";
5'd31: state_name = "DONE";
default: state_name = "UNKNOWN";
endcase
end
endfunction
task reset_timing;
begin
for (si = 0; si < 32; si = si + 1) state_cyc[si] = 0;
end
endtask
task print_timing;
input [8*16-1:0] op_name;
input integer cycles;
integer runtime_ns;
begin
runtime_ns = cycles * CLK_PERIOD_NS;
$display("TIME K=%0d CASE=%0d OP=%0s cycles=%0d clk=10MHz period=%0dns runtime=%0d ns (%0d.%03d us, %0d.%03d ms)",
KP, casenum, op_name, cycles, CLK_PERIOD_NS, runtime_ns,
runtime_ns/1000, runtime_ns%1000,
runtime_ns/1000000, (runtime_ns%1000000)/1000);
$display("TIME_BREAKDOWN K=%0d CASE=%0d OP=%0s", KP, casenum, op_name);
for (si = 0; si < 32; si = si + 1)
if (state_cyc[si] != 0)
$display(" STATE %-12s cycles=%0d time_ns=%0d", state_name(si[4:0]), state_cyc[si], state_cyc[si]*CLK_PERIOD_NS);
end
endtask
// Dump a byte array as offset-prefixed hex, 32 bytes/line.
task dump_bytes(input [8*16-1:0] name, input integer n);
integer a, b;
@@ -80,9 +146,12 @@ module tb_mlkem_kg_katK_xsim;
rst_n=0; repeat(4) @(posedge clk); rst_n=1; @(posedge clk);
start_i=1; @(posedge clk); start_i=0;
c=0; while(!done_o && c<2000000) begin @(posedge clk); c=c+1; end
#1;
reset_timing;
c=0; while(!done_o && c<2000000) begin state_cyc[dut.st] = state_cyc[dut.st] + 1; @(posedge clk); c=c+1; end
if(!done_o) begin $display("FAIL K=%0d case %0d: timeout", KP, casenum); $finish; end
$display("=== ML-KEM K=%0d KAT case %0d: KeyGen done in %0d cyc ===", KP, casenum, c);
print_timing("KeyGen", c);
errors = 0;
dbg_byte_sel_i = 1'b0;