// =============================================================================
// q_addsub.sv : 32-bit signed Q7.25 add/sub with saturation
// sub=0 -> y = a + b
// sub=1 -> y = a - b
// Combinational.
// =============================================================================
`default_nettype none

module q_addsub (
    input  wire                sub,
    input  wire signed [31:0]  a,
    input  wire signed [31:0]  b,
    output reg  signed [31:0]  y
);

    // One extra bit catches overflow.
    wire signed [32:0] a_ext = {a[31], a};
    wire signed [32:0] b_ext = {b[31], b};
    wire signed [32:0] sum   = sub ? (a_ext - b_ext) : (a_ext + b_ext);

    // 33-bit comparison values for +max and -max
    localparam signed [32:0] POS_LIMIT = 33'sh07FFFFFFF;  // sign-extended +0x7FFFFFFF
    localparam signed [32:0] NEG_LIMIT = 33'sh180000000;  // sign-extended -0x80000000

    always @* begin
        if (sum > POS_LIMIT)
            y = 32'sh7FFFFFFF;
        else if (sum < NEG_LIMIT)
            y = 32'sh80000000;
        else
            y = sum[31:0];
    end

endmodule

`default_nettype wire