/// *****************************************************************
// ******                       RESET BRIDGE                   ******
// ******************************************************************
//
// File:        reset_bridge.v 
// Revision:    1.0
// Project:     Reset Methodology Lab
// Company:     Xilinx
// Date:        Feb 4, 2013 
// Author:      Andy Norton
//
//
//---------------------------------------------------------------------  
// Description:
//---------------------------------------------------------------------  
//    This is a specialized metastability hardener intended for use in the
//    reset path. The reset will assert ASYNCHRONOUSLY when the input reset is
//    asserted, but will deassert synchronously.
//
//    In designs with asynchronous reset flip-flops, this generates a reset
//    that can meet the "recovery time" requirement of the flip-flop (be sure
//    to enable the recovery time arc checking - ENABLE=reg_sr_r).
//
//    In designs with synchronous resets, it ensures that the reset is
//    available before the first valid clock pulse arrives.
//
//   NOTE: Multicycle and False Paths, Timing Exceptions
//    A tighter timing constraint should be placed between the rst_meta
//    and rst_dst flip-flops to allow for meta-stability settling time
//

`timescale 1ns/1ps


module reset_bridge (
  input            clk,             // Destination clock
  input            ext_reset_in,    // Asynchronous reset signal
  input            lock,            // lock input from MMCM
  output reg       sync_reset_out   // Synchronized reset signal
);


//***************************************************************************
// Register declarations
//***************************************************************************

    reg     rst_meta=0;             // After sampling the async rst, this has
                                    // a high probability of being metastable.
                                    // The second sampling (rst_dst) has
                                    // a much lower probability of being
                                    // metastable
    wire    async_reset;

//***************************************************************************
// Code
//***************************************************************************

// use lock if present
  assign async_reset = ext_reset_in || !lock;

  always @(posedge clk or posedge async_reset)
  begin
    if (async_reset)
    begin
      rst_meta        <= 1'b1;
      sync_reset_out  <= 1'b1;
    end
    else // if !sync_reset_out
    begin
      rst_meta        <= 1'b0;
      sync_reset_out  <= rst_meta;
    end // if rst
  end // always

endmodule

