Add (* use_dsp = "no" *) to all modules containing multiplication operators to force LUT-based multiplication instead of DSP inference: - barrett_mul.v (3 multipliers x 7 instances = 21 ops) - comp_decomp_sync.v, sample_ntt_sync*.v, mlkem_top.v Also fix duplicate wire declaration of ct_bytes_rt in mlkem_top.v.
55 lines
1.5 KiB
Verilog
55 lines
1.5 KiB
Verilog
// barrett_mul.v - Barrett modular multiplication (a * b mod Q)
|
|
//
|
|
// Computes product = a * b mod Q using Barrett reduction.
|
|
// Q = 3329, k = floor(2^24 / Q) = 5039
|
|
//
|
|
// Pure combinational, single-cycle latency.
|
|
// All multiplication widths explicitly controlled to avoid Verilog truncation.
|
|
|
|
(* use_dsp = "no" *)
|
|
module barrett_mul (
|
|
input [11:0] a,
|
|
input [11:0] b,
|
|
output [11:0] product
|
|
);
|
|
localparam Q = 3329;
|
|
localparam K = 5039; // floor(2^24 / 3329)
|
|
localparam R = 24;
|
|
|
|
// Full product: a * b (both < 3329, product < 11,082,241 < 2^24)
|
|
// Force 24-bit evaluation by extending operand
|
|
wire [23:0] p;
|
|
assign p = {12'd0, a} * b;
|
|
|
|
// Extend p to 37 bits for multiplication with K
|
|
wire [36:0] p_ext;
|
|
assign p_ext = {13'd0, p};
|
|
|
|
// Compute t_shifted = (p * K) >> 24
|
|
// Use explicit wire for the product to control width
|
|
/* verilator lint_off UNUSEDSIGNAL */
|
|
wire [36:0] t_product;
|
|
/* verilator lint_on UNUSEDSIGNAL */
|
|
assign t_product = p_ext * K;
|
|
wire [12:0] t_shifted;
|
|
assign t_shifted = t_product[36:R];
|
|
|
|
// q_approx = t_shifted * Q
|
|
wire [24:0] q_approx;
|
|
assign q_approx = t_shifted * Q;
|
|
|
|
// r = p - q_approx
|
|
wire [24:0] r0;
|
|
assign r0 = {1'b0, p} - q_approx;
|
|
|
|
// Conditional subtract Q (at most twice)
|
|
wire [24:0] r1;
|
|
assign r1 = (r0 >= Q) ? (r0 - Q) : r0;
|
|
|
|
wire [11:0] r2;
|
|
assign r2 = (r1[11:0] >= Q) ? (r1[11:0] - Q) : r1[11:0];
|
|
|
|
assign product = (r1 >= Q) ? r2 : r1[11:0];
|
|
|
|
endmodule
|