module BLK_MEM_GEN_V2_1_output_stage
  #(parameter C_DATA_WIDTH       = 32,
    parameter C_HAS_SSR          = 1,
    parameter C_SINIT_VAL        = "0",
    parameter C_HAS_REGCE        = 1,
    parameter C_HAS_EN           = 1,
    parameter C_FAMILY           = "virtex5",
    parameter num_stages         = 1,
    parameter flop_delay         = 100)
  (input                         CLK,
   input                         SSR,
   input                         REGCE,
   input                         EN,
   input      [C_DATA_WIDTH-1:0] DIN,
   output reg [C_DATA_WIDTH-1:0] DOUT);

  localparam reg_stages  = (num_stages == 0) ? 0 : num_stages-1;
  reg [C_DATA_WIDTH*reg_stages-1:0] out_regs;
  reg [C_DATA_WIDTH*8-1:0]          sinit_str = C_SINIT_VAL;
  reg [C_DATA_WIDTH-1:0]            sinit_val;

  // Wire off optional inputs based on parameters
  //---------------------------------------------
  wire                              en_i;
  wire                              regce_i;
  wire                              ssr_i;
  assign   en_i    = (C_HAS_EN==0 || EN);
  assign   regce_i = ((C_HAS_REGCE==1) && REGCE) ||
                     ((C_HAS_REGCE==0) && (C_HAS_EN==0 || EN));
  assign   ssr_i   = (C_HAS_SSR==1) && SSR;

  initial begin
    // Power on: load up the output registers and latches
    if (!($sscanf(sinit_str, "%h", sinit_val))) begin
      sinit_val = 0;
    end
    DOUT = sinit_val;
    // This will be one wider than need, but 0 is an error
    out_regs = {(reg_stages+1){sinit_val}};
  end

  generate if (num_stages == 0) begin : zero_stages
    always @* begin
      DOUT = DIN;
    end
  end
  endgenerate

 generate if (num_stages == 1) begin : one_stages
    always @(posedge CLK) begin
        if (regce_i && ssr_i) begin
           DOUT <= #flop_delay sinit_val;
        end else if (regce_i) begin
           DOUT <= #flop_delay DIN;
        end
    end
    end
  endgenerate

 generate if (num_stages > 1) begin : multi_stage
    always @(posedge CLK) begin
        if (regce_i && ssr_i) begin
            DOUT           <= #flop_delay sinit_val;
        end else if (regce_i) begin
           DOUT         <= #flop_delay
                        out_regs[C_DATA_WIDTH*(num_stages-2)+:C_DATA_WIDTH];
        end

      if (en_i) begin
        out_regs <= #flop_delay
                    (out_regs << C_DATA_WIDTH) | DIN;
      end
    end
  end
  endgenerate
endmodule