73 lines
1.9 KiB
Verilog
73 lines
1.9 KiB
Verilog
// barrett_mul_pipe.v - DSP-friendly pipelined Barrett modular multiply
|
|
//
|
|
// Computes product = a * b mod Q with fixed latency. This module is used on
|
|
// timing-critical NTT paths; the legacy barrett_mul remains combinational for
|
|
// older users.
|
|
|
|
module barrett_mul_pipe (
|
|
input clk,
|
|
input rst_n,
|
|
input valid_i,
|
|
input [11:0] a,
|
|
input [11:0] b,
|
|
output [11:0] product,
|
|
output valid_o
|
|
);
|
|
localparam [24:0] Q25 = 25'd3329;
|
|
localparam [12:0] K13 = 13'd5039;
|
|
|
|
reg [23:0] p_s1;
|
|
|
|
reg [23:0] p_s2;
|
|
reg [36:0] tk_s2;
|
|
|
|
reg [23:0] p_s3;
|
|
reg [12:0] q_s3;
|
|
|
|
reg [24:0] p_s4;
|
|
reg [24:0] qprod_s4;
|
|
|
|
reg [24:0] r0_s5;
|
|
reg [24:0] r1_s6;
|
|
reg [11:0] product_r;
|
|
reg [6:0] valid_sr;
|
|
|
|
assign product = product_r;
|
|
assign valid_o = valid_sr[6];
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
p_s1 <= 24'd0;
|
|
p_s2 <= 24'd0; tk_s2 <= 37'd0;
|
|
p_s3 <= 24'd0; q_s3 <= 13'd0;
|
|
p_s4 <= 25'd0; qprod_s4 <= 25'd0;
|
|
r0_s5 <= 25'd0; r1_s6 <= 25'd0;
|
|
product_r <= 12'd0;
|
|
valid_sr <= 7'd0;
|
|
end else begin
|
|
valid_sr <= {valid_sr[5:0], valid_i};
|
|
|
|
// S1: full product.
|
|
p_s1 <= {12'd0, a} * b;
|
|
|
|
// S2: quotient-estimate product.
|
|
p_s2 <= p_s1;
|
|
tk_s2 <= {13'd0, p_s1} * K13;
|
|
|
|
// S3: quotient estimate.
|
|
p_s3 <= p_s2;
|
|
q_s3 <= tk_s2[36:24];
|
|
|
|
// S4: q * Q.
|
|
p_s4 <= {1'b0, p_s3};
|
|
qprod_s4 <= q_s3 * Q25;
|
|
|
|
// S5/S6/S7: subtract q*Q and conditionally subtract Q twice.
|
|
r0_s5 <= p_s4 - qprod_s4;
|
|
r1_s6 <= (r0_s5 >= Q25) ? (r0_s5 - Q25) : r0_s5;
|
|
product_r <= (r1_s6 >= Q25) ? (r1_s6 - Q25) : r1_s6[11:0];
|
|
end
|
|
end
|
|
|
|
endmodule
|