module axi_stream_wrapper #(
    parameter DATA_WIDTH = 32
)(
    input wire aclk,
    input wire aresetn,

    // AXI Stream Slave (Input Data)
    input wire [DATA_WIDTH-1:0] s_axis_tdata,
    input wire s_axis_tvalid,
    output wire s_axis_tready,

    // AXI Stream Master (Output Data)
    output reg [DATA_WIDTH-1:0] m_axis_tdata,
    output reg m_axis_tvalid,
    input wire m_axis_tready
);

    // Simple pass-through or processing wrapper
    // Integrates RNS Core

    wire [7:0] rns_out_0, rns_out_1, rns_out_2;

    // Deconstruct input (Assuming packed 3x8bit residues + opcode)
    wire [7:0] in_a0 = s_axis_tdata[7:0];
    wire [7:0] in_b0 = s_axis_tdata[15:8];
    wire [1:0] opcode = s_axis_tdata[17:16];

    // Core Instantiation
    rns_core core (
        .clk(aclk),
        .rst_n(aresetn),
        .opcode(opcode),
        .a_0(in_a0), .a_1(8'h0), .a_2(8'h0), // Simplified
        .b_0(in_b0), .b_1(8'h0), .b_2(8'h0),
        .res_0(rns_out_0), .res_1(rns_out_1), .res_2(rns_out_2)
    );

    // FIFO for Backpressure Handling (1-depth skid buffer)
    reg [DATA_WIDTH-1:0] skid_buffer;
    reg skid_valid;

    // Logic:
    // If downstream (master) is ready, we output directly or from skid.
    // If downstream is NOT ready, we store in skid.

    assign s_axis_tready = !skid_valid; // We can accept if skid is empty

    always @(posedge aclk or negedge aresetn) begin
        if (!aresetn) begin
            m_axis_tvalid <= 0;
            m_axis_tdata <= 0;
            skid_valid <= 0;
        end else begin
            // Output Logic
            if (m_axis_tready) begin
                // Downstream took data, drain skid or processing output
                if (skid_valid) begin
                    m_axis_tvalid <= 1;
                    m_axis_tdata <= skid_buffer;
                    skid_valid <= 0;
                end else if (s_axis_tvalid) begin
                    m_axis_tvalid <= 1;
                    m_axis_tdata <= {24'h0, rns_out_0}; // Processed data
                end else begin
                    m_axis_tvalid <= 0;
                end
            end else begin
                // Downstream busy. If we have new data and skid is empty, fill skid.
                if (s_axis_tvalid && !skid_valid) begin
                    skid_buffer <= {24'h0, rns_out_0};
                    skid_valid <= 1;
                    // m_axis_tvalid remains whatever it was (likely 1, waiting for ready)
                end
            end
        end
    end

endmodule
