// retroDE_ps2 — gif_path_stub
//
// Narrow GIF ingress stub for Wave 2. Accepts qword payloads from
// dmac_reg_stub, interprets them as register-write packets (project-local
// format — see below), and forwards register writes into gs_stub.
//
// This is NOT real GIFtag decode. Real GIFtag/PACKED/REGLIST/IMAGE formats
// arrive in Wave 3. The wire format here is a project-local shortcut sized
// to the "programmable BGCOLOR via DMA/GIF" target in
// docs/wave2_dma_gif_plan.md.
//
// Project-local Wave 2 packet format (per qword):
//   bits [ 15:  0]   = target register offset within GS privileged block
//                      (e.g., 0x00E0 for BGCOLOR)
//   bits [ 79: 16]   = 64-bit register value (low 24 bits are RGB for BGCOLOR)
//   bits [127: 80]   = reserved, must be zero
//
// Each qword produced by the DMAC is treated as one standalone register
// write. This module is stateless with respect to packet framing —
// multi-beat transfers (Wave 2.6 onward) work transparently because every
// accepted qword is independently decoded. `in_last` is preserved as
// trace-visible metadata in ev_flags[0] but does not gate decode. Real
// GIFtag/PACKED/REGLIST/IMAGE format decode, along with tag-phase vs.
// data-phase state, is deferred to Wave 3.
//
// PATH selection is hard-scoped to the DMAC channel-2 path (PATH id 2)
// since no arbitration exists yet.
//
// Trace payload schema:
//   GIF GIFTAG  arg0=path_id arg1=packet_type arg2=reg_offset arg3=payload_lo

`timescale 1ns/1ps

module gif_path_stub
    import trace_pkg::*;
#(
    parameter logic [3:0] PATH_ID = 4'd2
) (
    input  logic          clk,
    input  logic          rst_n,

    // Upstream from DMAC
    input  logic          in_valid,
    input  logic [127:0]  in_data,
    input  logic          in_last,
    output logic          in_ready,

    // Downstream to gs_stub (register-write style)
    output logic          gs_wr_en,
    output logic [15:0]   gs_wr_addr,
    output logic [63:0]   gs_wr_data,

    // Trace
    output logic          ev_valid,
    output subsys_e       ev_subsys,
    output event_e        ev_event,
    output logic [63:0]   ev_arg0,
    output logic [63:0]   ev_arg1,
    output logic [63:0]   ev_arg2,
    output logic [63:0]   ev_arg3,
    output logic [31:0]   ev_flags
);

    // Wave 2 packet-type magic — one value for "register-write packet".
    // Future waves will add real GIFtag formats.
    localparam logic [15:0] PKT_TYPE_REG_WRITE = 16'hA01A;

    // Always ready in Wave 2 — no internal backpressure.
    assign in_ready = 1'b1;

    logic        accept;
    assign accept = in_valid && in_ready;

    // Decode fields from the qword.
    logic [15:0] decoded_offset;
    logic [63:0] decoded_value;

    assign decoded_offset = in_data[15:0];
    assign decoded_value  = in_data[79:16];

    // ------------------------------------------------------------------
    // Downstream to gs_stub (registered one-shot pulse)
    // ------------------------------------------------------------------

    always_ff @(posedge clk) begin
        if (!rst_n) begin
            gs_wr_en   <= 1'b0;
            gs_wr_addr <= 16'd0;
            gs_wr_data <= 64'd0;
        end else begin
            gs_wr_en   <= accept;
            if (accept) begin
                gs_wr_addr <= decoded_offset;
                gs_wr_data <= decoded_value;
            end
        end
    end

    // ------------------------------------------------------------------
    // Trace emission
    // ------------------------------------------------------------------

    always_ff @(posedge clk) begin
        if (!rst_n) begin
            ev_valid  <= 1'b0;
            ev_subsys <= SUBSYS_GIF;
            ev_event  <= EV_GIFTAG;
            ev_arg0   <= 64'd0;
            ev_arg1   <= 64'd0;
            ev_arg2   <= 64'd0;
            ev_arg3   <= 64'd0;
            ev_flags  <= 32'd0;
        end else if (accept) begin
            ev_valid  <= 1'b1;
            ev_subsys <= SUBSYS_GIF;
            ev_event  <= EV_GIFTAG;
            ev_arg0   <= {60'd0, PATH_ID};
            ev_arg1   <= {48'd0, PKT_TYPE_REG_WRITE};
            ev_arg2   <= {48'd0, decoded_offset};
            ev_arg3   <= {{32{1'b0}}, decoded_value[31:0]};
            // flags[0] marks end-of-packet (tracks DMAC's in_last)
            ev_flags  <= {31'd0, in_last};
        end else begin
            ev_valid <= 1'b0;
        end
    end

endmodule : gif_path_stub
