// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Combine InW data and write to OutW data if packed to full word or stop signal

`include "prim_assert.sv"

module prim_packer #(
  parameter int InW  = 32,
  parameter int OutW = 32
) (
  input clk_i ,
  input rst_ni,

  input                   valid_i,
  input        [InW-1:0]  data_i,
  input        [InW-1:0]  mask_i,
  output                  ready_o,

  output logic            valid_o,
  output logic [OutW-1:0] data_o,
  output logic [OutW-1:0] mask_o,
  input                   ready_i,

  input                   flush_i,  // If 1, send out remnant and clear state
  output logic            flush_done_o
);

  localparam int Width = InW + OutW;
  localparam int PtrW = $clog2(Width+1);
  localparam int MaxW = (InW > OutW) ? InW : OutW;
  localparam int IdxW = $clog2(InW) + ~|$clog2(InW);

  logic valid_next, ready_next;
  logic [MaxW-1:0]  stored_data, stored_mask;
  logic [Width-1:0] concat_data, concat_mask;
  logic [Width-1:0] shiftl_data, shiftl_mask;

  logic [PtrW-1:0]        pos, pos_next; // Current write position
  logic [IdxW-1:0]          lod_idx;       // result of Leading One Detector
  logic [$clog2(InW+1)-1:0] inmask_ones;   // Counting Ones for mask_i

  logic ack_in, ack_out;

  logic flush_ready; // flush_i is pulse, so only when the output is ready flush_ready assets

  // Computing next position
  always_comb begin
    // counting mask_i ones
    inmask_ones = '0;
    for (int i = 0 ; i < InW ; i++) begin
      inmask_ones = inmask_ones + mask_i[i];
    end
  end

  assign pos_next = (valid_i) ? pos + PtrW'(inmask_ones) : pos;  // pos always stays (% OutW)

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      pos <= '0;
    end else if (flush_ready) begin
      pos <= '0;
    end else if (ack_out) begin
      `ASSERT_I(pos_next_gte_outw_p, pos_next >= OutW)
      pos <= pos_next - OutW;
    end else if (ack_in) begin
      pos <= pos_next;
    end
  end

  // Leading one detector for mask_i
  always_comb begin
    lod_idx = 0;
    for (int i = InW-1; i >= 0 ; i--) begin
      if (mask_i[i] == 1'b1) begin
        lod_idx = i;
      end
    end
  end

  assign ack_in  = valid_i & ready_o;
  assign ack_out = valid_o & ready_i;

  // Data process
  assign shiftl_data = (valid_i) ? Width'(data_i >> lod_idx) << pos : '0;
  assign shiftl_mask = (valid_i) ? Width'(mask_i >> lod_idx) << pos : '0;
  assign concat_data = {{(Width-MaxW){1'b0}}, stored_data & stored_mask} |
                       (shiftl_data & shiftl_mask);
  assign concat_mask = {{(Width-MaxW){1'b0}}, stored_mask} | shiftl_mask;

  logic [MaxW-1:0] stored_data_next, stored_mask_next;

  if (InW >= OutW) begin : gen_stored_in
    assign stored_data_next = concat_data[OutW+:InW];
    assign stored_mask_next = concat_mask[OutW+:InW];
  end else begin : gen_stored_out
    assign stored_data_next = {{(OutW-InW){1'b0}}, concat_data[OutW+:InW]};
    assign stored_mask_next = {{(OutW-InW){1'b0}}, concat_mask[OutW+:InW]};
  end

  // Store the data temporary if it doesn't exceed OutW
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      stored_data <= '0;
      stored_mask <= '0;
    end else if (flush_ready) begin
      stored_data <= '0;
      stored_mask <= '0;
    end else if (ack_out) begin
      stored_data <= stored_data_next;
      stored_mask <= stored_mask_next;
    end else if (ack_in) begin
      // When the requested size is smaller than OutW or output isn't ready
      // Assume when output isn't ready, the module  holds the input request
      stored_data <= concat_data[MaxW-1:0];
      stored_mask <= concat_mask[MaxW-1:0];
    end
  end

  // flush_ready handling
  typedef enum logic {
    FlushIdle,
    FlushWait
  } flush_st_e;
  flush_st_e flush_st, flush_st_next;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      flush_st <= FlushIdle;
    end else begin
      flush_st <= flush_st_next;
    end
  end

  always_comb begin
    flush_st_next = FlushIdle;

    flush_ready = 1'b0;

    unique case (flush_st)
      FlushIdle: begin
        if (flush_i && !ready_i) begin
          // Wait until hold released
          flush_st_next = FlushWait;

          flush_ready = 1'b0;
        end else if (flush_i && ready_i) begin
          // Can write right away!
          flush_st_next = FlushIdle;

          flush_ready = 1'b1;
        end else begin
          flush_st_next = FlushIdle;
        end
      end

      FlushWait: begin
        // TODO: Add timeout and force flush
        if (ready_i) begin
          // Ready to write
          flush_st_next = FlushIdle;

          flush_ready = 1'b1;
        end else begin
          // Wait ...
          flush_st_next = FlushWait;

          flush_ready = 1'b0;
        end
      end

      default: begin
        flush_st_next = FlushIdle;

        flush_ready = 1'b0;
      end
    endcase
  end

  assign flush_done_o = flush_ready;

  assign valid_next = (pos_next >= OutW) ? 1'b 1 : flush_ready & (pos != '0);
  assign ready_next = ack_out ? 1'b1 : pos_next <= MaxW; // New `we` needs to be hold.

  // Output request
  assign valid_o = valid_next;
  assign data_o  = concat_data[OutW-1:0];
  assign mask_o  = concat_mask[OutW-1:0];

  // ready_o
  assign ready_o = ready_next;

  // TODO: Implement Pipelined logic
  //       Need to change pos logic, mask&data calculation logic too

  //////////////////////////////////////////////
  // Assertions, Assumptions, and Coverpoints //
  //////////////////////////////////////////////
  // Assumption: mask_i should be contiguous ones
  // e.g: 0011100 --> OK
  //      0100011 --> Not OK
  if (InW > 1) begin : gen_mask_assert
    `ASSUME(ContiguousOnesMask_M,
            valid_i |-> $countones(mask_i ^ {mask_i[InW-2:0],1'b0}) <= 2)
  end

  // Assume data pattern to reduce FPV test time
  //`ASSUME_FPV(FpvDataWithin_M,
  //            data_i inside {'0, '1, 32'hDEAD_BEEF},
  //            clk_i, !rst_ni)

  // Flush and Write Enable cannot be asserted same time
  `ASSUME(ExFlushValid_M, flush_i |-> !valid_i)

  // While in flush state, new request shouldn't come
  `ASSUME(ValidIDeassertedOnFlush_M,
          flush_st == FlushWait |-> $stable(valid_i))

  // If not acked, input port keeps asserting valid and data
  `ASSUME(DataIStable_M,
          ##1 valid_i && $past(valid_i) && !$past(ready_o)
          |-> $stable(data_i) && $stable(mask_i))
  `ASSUME(ValidIPairedWithReadyO_M,
          valid_i && !ready_o |=> valid_i)

  `ASSERT(FlushFollowedByDone_A,
          ##1 $rose(flush_i) && !flush_done_o |-> !flush_done_o [*0:$] ##1 flush_done_o)

  // If not acked, valid_o should keep asserting
  `ASSERT(ValidOPairedWidthReadyI_A,
          valid_o && !ready_i |=> valid_o)

  // If input mask + stored data is greater than output width, valid should be asserted
  `ASSERT(ValidOAssertedForInputGTEOutW_A,
          valid_i && (($countones(mask_i) + $countones(stored_mask)) >= OutW) |-> valid_o)

  // If output port doesn't accept the data, the data should be stable
  `ASSERT(DataOStableWhenPending_A,
          ##1 valid_o && $past(valid_o)
          && !$past(ready_i) |-> $stable(data_o))

  // If input data & stored data are greater than OutW, remained should be stored
  // TODO: Find out how the FPV time can be reduced.
  //`ASSERT(ExcessiveDataStored_A,
  //        ack_in && (($countones(mask_i) + $countones(stored_mask)) > OutW) |=>
  //          (($past(data_i) &  $past(mask_i)) >>
  //          ($past(lod_idx)+OutW-$countones($past(stored_mask))))
  //          == stored_data,
  //        clk_i, !rst_ni)
  `ASSERT(ExcessiveMaskStored_A,
          ack_in && (($countones(mask_i) + $countones(stored_mask)) > OutW) |=>
          ($past(mask_i) >>
          ($past(lod_idx)+OutW-$countones($past(stored_mask))))
            == stored_mask)

endmodule
