// =============================================================================
// q_mult.sv : Q7.25 signed multiplier with saturation
// -----------------------------------------------------------------------------
// 32-bit signed Q7.25 inputs, 32-bit signed Q7.25 output.
// Combinational. Will infer a DSP slice on Cyclone V.
//
// Widths are hard-coded as literals (32, 25, etc.) to avoid Quartus 21.1
// parameter-elaboration bugs with bit-selects and replication counts.
// =============================================================================
`default_nettype none

module q_mult (
    input  wire signed [31:0] a,
    input  wire signed [31:0] b,
    output reg  signed [31:0] p
);

    wire signed [63:0] full    = a * b;
    wire signed [63:0] shifted = full >>> 25;

    localparam signed [63:0] MAX_POS = 64'sh000000007FFFFFFF;
    localparam signed [63:0] MAX_NEG = 64'shFFFFFFFF80000000;

    always @* begin
        if (shifted > MAX_POS)
            p = 32'sh7FFFFFFF;
        else if (shifted < MAX_NEG)
            p = 32'sh80000000;
        else
            p = shifted[31:0];
    end

endmodule

`default_nettype wire