// tb_mlkem_two_inst_xsim.v - ML-KEM hello_world on TWO mlkem_top instances. // // Models the real two-party split: // * Instance A (u_genenc): Alice/Bob side that does KeyGen THEN Encaps. // - KeyGen(d,z) writes ek into A's own ek_bram and produces dk. // - Encaps(m) reuses that same ek_bram (no re-streaming) -> shared_key, ct. // * Instance B (u_dec): Alice side that does Decaps. // - receives dk (read out of A via dbg_dk) and ct (read out of A via // dbg_ct), streamed into B's input ports -> recovered_key. // // Then XOR-encrypt/decrypt "hello world" and verify both keys + message match. // Each step prints its inputs and outputs. // // xelab tb_mlkem_two_inst_xsim ; xsim `timescale 1ns/1ps module tb_mlkem_two_inst_xsim; localparam KP = 2; // ML-KEM-512 localparam EKB = 384*KP + 32; // 800 localparam DKB = 768*KP + 96; // 1632 localparam CTB = 32*(10*KP + 4); // 768 localparam MLEN = 11; // "hello world" reg clk=0; always #5 clk = ~clk; // ---------------- Instance A: KeyGen + Encaps ---------------- reg a_rst_n=0, a_start=0; reg [1:0] a_op=0; reg [255:0] a_d=0, a_z=0, a_msg=0; wire a_busy, a_done; wire [255:0] a_ss; reg [10:0] a_ct_idx=0; wire [7:0] a_ct_o; reg a_byte_sel=0; reg [10:0] a_byte_idx=0; wire [7:0] a_byte_o; reg [11:0] a_dk_idx=0; wire [7:0] a_dk_o; wire [255:0] a_rho,a_sigma,a_r,a_hek,a_mp,a_kbar,a_dz,a_dh; mlkem_top u_genenc ( .clk(clk), .rst_n(a_rst_n), .k_i(KP[2:0]), .op_i(a_op), .d_i(a_d), .z_i(a_z), .msg_i(a_msg), .start_i(a_start), .busy_o(a_busy), .done_o(a_done), .ek_in_we(1'b0), .ek_in_addr(11'd0), .ek_in_byte(8'd0), .dk_in_we(1'b0), .dk_in_addr(12'd0), .dk_in_byte(8'd0), .c_in_we(1'b0), .c_in_addr(11'd0), .c_in_byte(8'd0), .ss_o(a_ss), .dbg_ct_idx_i(a_ct_idx), .dbg_ct_o(a_ct_o), .dbg_slot_i(6'd0), .dbg_idx_i(8'd0), .dbg_coeff_o(), .dbg_byte_sel_i(a_byte_sel), .dbg_byte_idx_i(a_byte_idx), .dbg_byte_o(a_byte_o), .dbg_dk_idx_i(a_dk_idx), .dbg_dk_o(a_dk_o), .dbg_rho_o(a_rho), .dbg_sigma_o(a_sigma), .dbg_r_o(a_r), .dbg_hek_o(a_hek), .dbg_mprime_o(a_mp), .dbg_kbar_o(a_kbar), .dbg_decz_o(a_dz), .dbg_dech_o(a_dh) ); // ---------------- Instance B: Decaps ---------------- reg b_rst_n=0, b_start=0; wire b_busy, b_done; wire [255:0] b_ss; reg b_dk_we=0; reg [11:0] b_dk_addr=0; reg [7:0] b_dk_byte=0; reg b_c_we=0; reg [10:0] b_c_addr=0; reg [7:0] b_c_byte=0; wire [255:0] b_rho,b_sigma,b_r,b_hek,b_mp,b_kbar,b_dz,b_dh; wire [7:0] b_byte_o, b_dk_o, b_ct_o; mlkem_top u_dec ( .clk(clk), .rst_n(b_rst_n), .k_i(KP[2:0]), .op_i(2'd2), .d_i(256'd0), .z_i(256'd0), .msg_i(256'd0), .start_i(b_start), .busy_o(b_busy), .done_o(b_done), .ek_in_we(1'b0), .ek_in_addr(11'd0), .ek_in_byte(8'd0), .dk_in_we(b_dk_we), .dk_in_addr(b_dk_addr), .dk_in_byte(b_dk_byte), .c_in_we(b_c_we), .c_in_addr(b_c_addr), .c_in_byte(b_c_byte), .ss_o(b_ss), .dbg_ct_idx_i(11'd0), .dbg_ct_o(b_ct_o), .dbg_slot_i(6'd0), .dbg_idx_i(8'd0), .dbg_coeff_o(), .dbg_byte_sel_i(1'b0), .dbg_byte_idx_i(11'd0), .dbg_byte_o(b_byte_o), .dbg_dk_idx_i(12'd0), .dbg_dk_o(b_dk_o), .dbg_rho_o(b_rho), .dbg_sigma_o(b_sigma), .dbg_r_o(b_r), .dbg_hek_o(b_hek), .dbg_mprime_o(b_mp), .dbg_kbar_o(b_kbar), .dbg_decz_o(b_dz), .dbg_dech_o(b_dh) ); // shuttle storage (the wire between the two instances) reg [7:0] dk_b [0:DKB-1]; reg [7:0] ct_b [0:CTB-1]; reg [7:0] msg_b [0:MLEN-1]; reg [7:0] enc_b [0:MLEN-1]; reg [7:0] dec_b [0:MLEN-1]; reg [255:0] shared_key, recovered_key; integer c, i, j, errors; task wait_a; begin c=0; while(!a_done && c<4000000) begin @(posedge clk); c=c+1; end if(!a_done) begin $display("FAIL: instance A timeout (op=%0d)", a_op); $finish; end end endtask task wait_b; begin c=0; while(!b_done && c<4000000) begin @(posedge clk); c=c+1; end if(!b_done) begin $display("FAIL: instance B timeout"); $finish; end end endtask task print_hex32; input [255:0] v; begin for (j=0;j<32;j=j+1) $write("%02x", v[8*j +: 8]); $write("\n"); end endtask initial begin errors = 0; msg_b[0]="h"; msg_b[1]="e"; msg_b[2]="l"; msg_b[3]="l"; msg_b[4]="o"; msg_b[5]=" "; msg_b[6]="w"; msg_b[7]="o"; msg_b[8]="r"; msg_b[9]="l"; msg_b[10]="d"; $display("=== ML-KEM hello_world (TWO instances: genenc + dec, ML-KEM-512) ==="); $write("Original: \""); for(i=0;i \""); for(i=0;i