// (C) 2001-2025 Altera Corporation. All rights reserved.
// Your use of Altera 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 Altera Program License Subscription 
// Agreement, Altera 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 Altera and sold by 
// Altera or its authorized distributors.  Please refer to the applicable 
// agreement for further details.


// $File: //acds/prototype/mm_s10/ip/avalon_st/altera_avalon_st_pipeline_stage/altera_avalon_st_pipeline_base.v $
// $Revision: #2 $
// $Date: 2015/05/15 $
// $Author: jyeap $
//------------------------------------------------------------------------------

`timescale 1ns / 1ns

module alt_hiconnect_pipeline_base (
                                       clk,
                                       reset,
                                       in_ready,
                                       in_valid,
                                       in_data,
                                       out_ready,
                                       out_valid,
                                       out_data
                                       );

   parameter SYMBOLS_PER_BEAT = 1;
   parameter BITS_PER_SYMBOL  = 8;
   parameter PIPELINE_READY   = 1;
   localparam DATA_WIDTH = SYMBOLS_PER_BEAT * BITS_PER_SYMBOL;
   
   input clk;
   input reset;
   
   output in_ready;
   input  in_valid;
   input [DATA_WIDTH-1:0] in_data;
   
   input                  out_ready;
   output                 out_valid;
   output [DATA_WIDTH-1:0] out_data;
   
   reg                     internal_sclr;
   reg                     full0;
   reg                     full1;
   reg [DATA_WIDTH-1:0]    data0;
   reg [DATA_WIDTH-1:0]    data1;

   assign out_valid = full1;
   assign out_data  = data1;    

   always @(posedge clk) begin
      internal_sclr <= reset;
   end
   
   generate if (PIPELINE_READY == 1) 
     begin : REGISTERED_READY_PLINE
        
        assign in_ready  = !full0;

        always @(posedge clk) begin
           // ----------------------------
           // always load the second slot if we can
           // ----------------------------
           if (~full0)
             data0 <= in_data;
           // ----------------------------
           // first slot is loaded either from the second,
           // or with new data
           // ----------------------------
           if (~full1 || (out_ready && out_valid)) begin
              if (full0)
                data1 <= data0;
              else
                data1 <= in_data;
           end
        end
        
        always @(posedge clk) begin
           if (internal_sclr) begin
              full0 <= 1'b0;
              full1 <= 1'b0;
           end else begin
              // no data in pipeline
              if (~full0 & ~full1) begin
                 if (in_valid) begin
                    full1 <= 1'b1;
                 end
              end // ~f1 & ~f0

              // one datum in pipeline 
              if (full1 & ~full0) begin
                 if (in_valid & ~out_ready) begin
                    full0 <= 1'b1;
                 end
                 // back to empty
                 if (~in_valid & out_ready) begin
                    full1 <= 1'b0;
                 end
              end // f1 & ~f0
              
              // two data in pipeline 
              if (full1 & full0) begin
                 // go back to one datum state
                 if (out_ready) begin
                    full0 <= 1'b0;
                 end
              end // end go back to one datum stage
           end
        end

     end 
   else 
     begin : UNREGISTERED_READY_PLINE
        
        // we're ready if the slot is unoccupied, or if the output is ready
        assign in_ready = (~full1) | out_ready;
        
        always @(posedge clk) begin
           if (in_ready) begin
              data1 <= in_data;
           end
        end                

        always @(posedge clk) begin
           if (internal_sclr) begin
              full1 <= 1'b0;
           end
           else begin
              if (in_ready) begin
                 full1 <= in_valid;
              end
           end
        end

     end
   endgenerate
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "HVwoXV44HvrqLCcyrRLKSPYKBkDWFb/QkVjwDEQ824LbpdY1lpyfSDRh2R2XXI3HT559WzzSGaylMrfix9K0v8D4bP8N/5F2s7q2IVIU3Zbvvtm48IozW/C3YtteWjdzPbWSHrpgM8/tQexSu730vbHbwtI/7bmZ6hVhmDj7iMt/1xxbYHvxq//o4LrluwXjtRNow/nPFObAl3yz5rR4pw9RiExjXrLroBGh1KHp3EPKlbhY+BQepbGO0V1DSCmQ4XokfmSWavhlcQTJscCeklENK7ep3yHwRDW7d0zOcZkKm4iEQnx3cO8liP7/8Ukpm5hQ+ywBK1CM3ANZx8zP7Hjphl41jM67BFTqINI+i9JAfeo0JghFvly1muGxQq6oM4bI1ATjScKgYYq/IlloEuftVUAQbIHDjiMy7mBGyEXoDnXcN0wLxtDobEBOYyGxSanCVjynMd9ALc3ARQTNCNRVLM1jvNi71eIJGTpHDNwOL1vSxrxwInblIRxVIJlJoIKceDZ0ogpwfkY64AlNeQyQrf2nKIZJ5ZZJHOLYbvdf7BSTVZcRUe6ZN8duA0nJGCY4XO+wSyMDqPql4c7YY4Ht4xO7vE0MtdPAe4MreU+SCSDj54sHaXLSjxLZJzksoW5sEClmMNBTxDp1iVY/+rTSnWAs/24GD7kRNv+hwl6wgsiYZxSGF2iiD/mUZS77G9vEPgnFczHTQ1FxqybJqhw8/qZeSR+Sz0+35cVyZDIrqxQpkPcZSIVkVWGtywD7dy1++cp0YnGM7JDgDYeSl8/eB/z2R2Dcp1qF39RdbPP4jK/Hr2diSbdRvDqlY9cU0iZM1u+h8WjpXyrEyTP0djGu6wva74mCefoRAQkURtyrgRRDi8qp1whn93jig/fKjHk2sImEPixBy3laLcQxZASzq7z4LfvQ4JrtjZGeBECzOdaF43b/rbLVtZAGkLJxdhE4OMJ53VmpAb1wmPuSLeq5Vlw9kpqcT2D1a2aJWnAUQ38lEleI14OSYZ5woZ+S"
`endif