// RSPU Core: Upgraded Tagged-Word ALU
// High-performance 64-bit unit using masked-range optimization.

def alu_core(
    clk: signal in bool,
    op: signal in u32,
    d1: signal in u64,
    t1: signal in u64,
    p1: signal in u64,
    d2: signal in u64,
    t2: signal in u64,
    p2: signal in u64,
    out_data: signal out u64,
    out_tag:  signal out u64,
    out_prov: signal out u64,
    trap: signal out bool
) {
    reflect {
        // --- Internal Accumulators ---
        signal res_data: internal u64;
        signal res_tag:  internal u64;
        signal res_prov: internal u64;
        signal is_trap:  internal bool;

        // Default values
        reflex default_vals {
            on always {
                res_data = d2;
                res_tag  = t1;
                res_prov = p1;
                is_trap  = false;
            }
        }

        // Logic guards
        let is_add: bool = (${op} == 0) && (t1 == t2);
        let is_sub: bool = (${op} == 1) && (t1 == t2);
        let is_relu_pos: bool = (${op} == 3) && ((d1 >> 31) == 0);
        let is_relu_neg: bool = (${op} == 3) && ((d1 >> 31) == 1);
        let is_tag_gate: bool = (${op} == 5);

        guard is_add_g { when is_add for 1 cycles; }
        guard is_sub_g { when is_sub for 1 cycles; }
        guard is_relu_pos_g { when is_relu_pos for 1 cycles; }
        guard is_relu_neg_g { when is_relu_neg for 1 cycles; }
        guard is_tag_gate_g { when is_tag_gate for 1 cycles; }

        reflex do_add {
            on is_add_g {
                res_data = (d1 & 0xFFFFFFFF) + (d2 & 0xFFFFFFFF);
            }
        }

        reflex do_sub {
            on is_sub_g {
                res_data = (d1 & 0xFFFFFFFF) - (d2 & 0xFFFFFFFF);
            }
        }

        reflex do_relu_pos {
            on is_relu_pos_g {
                res_data = d1;
            }
        }

        reflex do_relu_neg {
            on is_relu_neg_g {
                res_data = 0;
            }
        }

        reflex do_tag_gate {
            on is_tag_gate_g {
                // d1(32) * p1(4) = 36 bits. 36 < 64. PASS.
                res_data = ((d1 & 0xFFFFFFFF) * (p1 & 15)) >> 4;
            }
        }

        reflex finalize {
            on always {
                ${out_data} = res_data & 0xFFFFFFFF;
                ${out_tag}  = res_tag & 15;
                ${out_prov} = res_prov & 15;
                ${trap}     = is_trap;
            }
        }
    }
}

module alu {}
