OpenCores
URL https://opencores.org/ocsvn/boundaries/boundaries/trunk

Subversion Repositories boundaries

[/] [boundaries/] [trunk/] [rtl/] [verilog/] [clock_detect.v] - Rev 4

Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
//// clock_detect.v                                               ////
////                                                              ////
//// This file is part of the boundaries opencores effort.        ////
//// <http://www.opencores.org/cores/boundaries/>                 ////
////                                                              ////
//// Module Description:                                          ////
////                                                              ////
////   Use a stable, faster clock to detect whether a slower      ////
////  input clock (sclk_i) is actually running.                   ////
////                                                              ////
////   If there is no change is the suspect clock for (1<<CW)     ////
////  clk_i periods; the alive_o output will be de-asserted.      ////
////                                                              ////
////   For example, if clk_i has a period of 1us, and CW=8: when  ////
////  there is no transition on sclk_i for 256us, the alive_o     ////
////  output will be de-asserted.                                 ////
////                                                              ////
////   For the alive_o output to be asserted, there must be       ////
////   2 changes in sclk_i within (1<<CW) clock periods.          ////
////                                                              ////
////   The "alive_o" output is synchronous with clk_i.            ////
////                                                              ////
//// To Do:                                                       ////
//// Verify in silicon.                                           ////
////                                                              ////
//// Author(s):                                                   ////
//// - Shannon Hill                                               ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2004 Shannon Hill and OPENCORES.ORG            ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE. See the GNU Lesser General Public License for more  ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from <http://www.opencores.org/lgpl.shtml>                   ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
// $Id: clock_detect.v,v 1.1 2004-07-07 12:41:17 esquehill Exp $
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
module clock_detect( /*AUTOARG*/
// Outputs
alive_o, 
// Inputs
rst_i, clk_i, sclk_i
);
 
input     rst_i;
input     clk_i;
 
input     sclk_i;   // suspect clock
output    alive_o;
 
parameter CW = 8;   // if (1<<CW) clk_i's occur with no sclk_i change, it's stopped.
 
reg   [2:0]          synchro;
wire                 changed = synchro[2] ^ synchro[1];
 
reg              nxt_alive_o;
reg                  alive_o;
 
reg   [CW-1:0]   nxt_counter;
reg   [CW-1:0]       counter;
wire  [CW-1:0]       counter_inc =  counter + 1'b1;
wire                 timeout     = &counter;
 
reg    [1:0]     nxt_state;
reg    [1:0]     cur_state;
 
parameter [1:0] STOPPED  = 2'd0;
parameter [1:0] CHECKING = 2'd1;
parameter [1:0] RUNNING  = 2'd2;
 
always @( /*AUTOSENSE*/changed or counter_inc or cur_state or timeout)
begin
                         nxt_alive_o = 1'b0;
                         nxt_state   = cur_state;
                         nxt_counter = {CW{1'b0}};
 
     case( cur_state )
 
     STOPPED:  if( changed )                          // wait for an sclk_i change...
                         nxt_state   = CHECKING;
 
     CHECKING:  casex( { changed, timeout } )
                2'b00:   nxt_counter = counter_inc;   // waiting for another change...
                2'b01:   nxt_state   = STOPPED;       // give up.
                2'b1X:   nxt_state   = RUNNING;       // changed again!
                default: ;
                endcase
 
     RUNNING:  begin
                         nxt_alive_o = 1'b1;
 
                casex( { changed, timeout } )
                2'b00:   nxt_counter = counter_inc;   // waiting for another change...
                2'b01:   nxt_state   = STOPPED;       // give up.
                2'b1X:   ;                            // changed; still alive...
                default: ;
                endcase
 
               end
 
     default:            nxt_state   = STOPPED;
     endcase
end
 
 
always @( posedge clk_i or posedge rst_i)
if( rst_i )
begin
                cur_state <= STOPPED;
                counter   <= {CW{1'b0}};
                alive_o   <= 1'b0;
                synchro   <= 3'b0;
end
else
begin
                cur_state <= nxt_state;
                counter   <= nxt_counter;
                alive_o   <= nxt_alive_o;
 
                synchro   <= { synchro[1:0], sclk_i }; // async input; sclk_i consumed as data
 
//
// synopsys translate_off
//              case( { nxt_alive_o, alive_o } )
//              2'b01:  $display( "%d:%m: clock dead.", $time);
//              2'b10:  $display( "%d:%m: clock alive.", $time);
//              default: ;
//              endcase
// synopsys translate_on
//
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.