// (C) 2001-2024 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other 
// software and tools, and its AMPP partner logic functions, and any output 
// files from any of the foregoing (including device programming or simulation 
// files), and any associated documentation or information are expressly subject 
// to the terms and conditions of the Intel Program License Subscription 
// Agreement, Intel FPGA IP License Agreement, or other applicable 
// license agreement, including, without limitation, that your use is for the 
// sole purpose of programming logic devices manufactured by Intel and sold by 
// Intel or its authorized distributors.  Please refer to the applicable 
// agreement for further details.


`timescale 1ns / 100ps

// this module has zero ready latency input and non zero latency output


module ready_latency_adapter # (
 parameter READY_LATENCY_OUT = 2,
 parameter PAYLOAD_WIDTH = 256,
 parameter LOG_DEPTH = 3


) (  
 output logic         in_ready,
 input  logic            in_valid,
 input  logic   [PAYLOAD_WIDTH-1: 0]  in_data,
 // Interface: out
 input  logic             out_ready,
 output logic          out_valid,
 output logic [PAYLOAD_WIDTH-1: 0] out_data,
  // Interface: clk
 input logic          clk,
 // Interface: reset
 input logic           reset

 /*AUTOARG*/);

   // ---------------------------------------------------------------------
   //| Signal Declarations
   // ---------------------------------------------------------------------
   
   logic [PAYLOAD_WIDTH-1:0]   in_payload;
   logic [PAYLOAD_WIDTH-1:0]   out_payload;
   logic            in_ready_wire;
   logic            out_valid_wire;
   logic [2:0]      fifo_fill;
   logic    rdreq;
   logic empty;   

   logic [READY_LATENCY_OUT-1:0] in_ready_dly_reg;
   logic in_ready_dly;
   assign in_ready_dly = (READY_LATENCY_OUT > 0) ? in_ready_dly_reg[0] : in_ready;
 
   localparam DEPTH = 2 ** LOG_DEPTH -1 ;

   // ---------------------------------------------------------------------
   //| Payload Mapping
   // ---------------------------------------------------------------------
   always @* begin
     in_payload = {in_data};
     {out_data} = out_payload;
   end

   // ---------------------------------------------------------------------
   //| FIFO
   // ---------------------------------------------------------------------                           
    scfifo_s # (
      .LOG_DEPTH (LOG_DEPTH),
      .WIDTH (PAYLOAD_WIDTH),
      .ALMOST_FULL_VALUE (DEPTH-1),
      .SHOW_AHEAD (1),
      .FAMILY ("Agilex")
    ) fifo_inst ( 
       .clock        (clk),
       .aclr       (reset),
       .sclr (1'b0),
       //.in_ready   (),
       .wrreq  (in_valid && in_ready_dly),      
       .data    (in_payload),
      //.out_ready  (out_ready),
       .rdreq      (rdreq),
       .q (out_payload),
       .usedw (fifo_fill),
       .empty (empty),
       .full (full),
       .almost_empty (),
       .almost_full ()
       );

   // ---------------------------------------------------------------------
   //| Ready & valid signals.
   // ---------------------------------------------------------------------
   always @* begin
      in_ready = ( DEPTH- fifo_fill > READY_LATENCY_OUT);
   end

    always @(posedge clk) begin
        in_ready_dly_reg[READY_LATENCY_OUT-1] <= in_ready;
        for (int i = 0; i < READY_LATENCY_OUT - 1; i++) begin
            in_ready_dly_reg[i] <= in_ready_dly_reg[i+1];
        end
    end

assign rdreq = out_ready && !empty;

assign out_valid = !empty;


endmodule


`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "Vd3tEFjpZj96rI/+F/VvE60mTEymAEQpoSTBEGkPZDn8vLE37C5u3t6a/YuDWdcpDICg4yaS41BVZL43rgMWoo/ODQa6HJ+98xz96XdaxZoH7knVWHHmdjwNoot126KwBXxYxMAyWcKq2a9b9HntBfzAKtQF4cCehbSzlUccpMg8lYZJJ73s4nMHdujybKqOU3uA0uLLaEuflzNF5/A5MXI1hPhdpBgL5/hYcV95h9MZz2XBFGd3B/4payq0691LPJabv3AERZ3X5Tz034Wb5BO+TQ5Dd/W27oDp9QjurA4tq8QDmLwkscyHJHCTGdzA0dRtIwkY2MdWu9ZiNZ6ttZigOpFfmn19wjMzYNvcb0EMu/zAY5EJEYejDCAjeSrZaTQXeqYHqdNnnYH4FG9Ce2PNbxsj1/ED5O90vdB/HxMbQTUzOw0gWLDvrFGjCZ8xG8rBK1CKkfPfQWTMHBx+ugPuXLY3CSb1MTcPW0omwRYKTq5KBpwbDQODj0EcifzfLqSUaVYh2w4LWr9wrFXmMSZaWBpV1EiLW+KjYtLZlgXq7pTiRMfB2Ker8E2anvCAmH1FO8zxcFfL5FOHLsCLc6D3HOZYxsin1HQu/Hk0h8NYFu22dhWVtCJpJtX9ws4fKjZoJt/gEZr3aR499B7oscOfYGWzcx1H8lDE370i5EkIOSB3rC3wOQRGrZBJjUE18ZhKTgEBoIyqY3H5vlFvl6G0cpMQkb3ZI2u0FLEgFES+31BBdvYAbT9usJjViVbkBG5roQEp+sYVUXpdautssjkHkdQRmVnFC2HT5LL2YffO4l7kEuxzYAPxNd1fszGeFy7nbMTsW0H83THzl0y07neW5wuZTsH5cQwP9ws0+IretVzJm1a3N/HUqsjl+6dEWM2HZebx+GyJLYWQTJNWnVGK79s8GY0jWP6UbdRPS5+c2HgNPMtLprlPvW/88Qr9ikNTAV8Wk7XpQFA9qUBnwo6cfIu/7xLCCIgPToXEwZCSz/zC84jYjCwWNPMNEmhz"
`endif