module fifo_1d_64to32(
    input  wire         clk,
    input  wire         rst,
    // Incoming port
    input  wire [63:0]  a_data,
    input  wire         a_valid,
    output wire         a_ready,
    // Outgoing port
    output wire [31:0]  b_data,
    output wire         b_valid,
    input  wire         b_ready
);

    reg [63:0] fifo;
    reg fifo_full;
    reg fifo_empty;
    always @(posedge clk) begin
        if (fifo_empty) begin
            // Output invalid, if with valid input, fill input
            if (a_valid) begin
                fifo <= a_data;
                fifo_empty <= 1'b0;
                fifo_full <= 1'b1;
            end
        end
        else if (fifo_full) begin
            // Output valid, input not ready, if with valid output, shift
            if (b_ready) begin
                fifo <= {fifo[31:0], 32'b0};
                fifo_full <= 1'b0;
            end
        end
        else begin
            // Half empty, output valid, input ready only if output is ready
            if (b_ready && a_valid) begin
                fifo <= a_data;
                fifo_full <= 1'b1;
            end
            else if (b_ready) begin
                fifo_empty <= 1'b1;
            end
        end

        if (rst) begin
            fifo_full <= 1'b0;
            fifo_empty <= 1'b1;
        end
    end

    // RX data if fifo is empty
    assign a_ready = fifo_empty || (!fifo_full && b_ready);
    assign b_valid = !fifo_empty;
    assign b_data = fifo[63:32];

endmodule