HierarchyFilesModulesSignalsTasksFunctionsHelp

/******************************************************************************/ 
/*                                                                            */ 
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved.             */ 
/*                                                                            */ 
/* The contents of this file are subject to the current version of the Sun    */ 
/* Community Source License, microSPARCII ("the License"). You may not use    */ 
/* this file except in compliance with the License.  You may obtain a copy    */ 
/* of the License by searching for "Sun Community Source License" on the      */ 
/* World Wide Web at http://www.sun.com. See the License for the rights,      */ 
/* obligations, and limitations governing use of the contents of this file.   */ 
/*                                                                            */ 
/* Sun Microsystems, Inc. has intellectual property rights relating to the    */ 
/* technology embodied in these files. In particular, and without limitation, */ 
/* these intellectual property rights may include one or more U.S. patents,   */ 
/* foreign patents, or pending applications.                                  */ 
/*                                                                            */ 
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos,   */ 
/* Solaris, Java and all Java-based trademarks and logos are trademarks or    */ 
/* registered trademarks of Sun Microsystems, Inc. in the United States and   */ 
/* other countries. microSPARC is a trademark or registered trademark of      */ 
/* SPARC International, Inc. All SPARC trademarks are used under license and  */ 
/* are trademarks or registered trademarks of SPARC International, Inc. in    */ 
/* the United States and other countries. Products bearing SPARC trademarks   */ 
/* are based upon an architecture developed by Sun Microsystems, Inc.         */ 
/*                                                                            */ 
/******************************************************************************/ 
/***************************************************************************
****************************************************************************
***
***  Program File:  @(#)rl_clk_cntl.v
***
***
****************************************************************************
****************************************************************************/
// @(#)rl_clk_cntl.v	1.19 9/14/93

// Clock Control state machine

// Removed sbus_clk -  6/20/96

[Up: clk_misc clk_cntl]
module rl_clk_cntl (
    logic_0,
    tmr_clk,
    gclk_unbuf,
    gclk_unbuf_,
    gclk_phase_late_a1,
    testclken,
    jtag_trst_l,
    input_reset_l,
    rcc_rst_l,
    tc_scan_clk,
// add this to fix testability 
    pll_byp_l,

    stop,
    stop_after_0,
    stop_after_1,
    stop_after_2,
    stop_after_3,
    stop_after_4,
    start,
    stopped,
    rcc_clk_unbuf,
    rs_dsbl_clocks_in,
    ss_clock_unbuf,
    rfr_clock,
    rfr_late,
    standby_dsbl_sysclk_a1,
    free_phase_late_a1,
    clk_rst_l,
    //sbus_clk,
    sboclk,
    pci_refclk_unbuf,
    pci_refclk_unbuf_,
    div_ctl,
    input_clock
) ;

    /*--------------------- I/O declarations -----------------*/


    // Used as scan_mode by auto-inserted spare FFs
    input logic_0 ;

    // Programmable input pins for sys_clk:sbclk frequency ratio
    // changed to below  00 -   2:1
    // 00 -   6:1
    // 01 -   3:1
    // 10 -   4:1
    // 11 -   5:1
    input [1:0] div_ctl ;

    // Clocks for refresh logic
    output rfr_clock ;
    output rfr_late ;

    // This stops ss_clock.  It must be latched here on the next-to-last
    //     input_clock edge of the sbclk cycle.
    input standby_dsbl_sysclk_a1 ;

    // These are here for synchronization
    input testclken ;
    input jtag_trst_l ;
    input input_reset_l ;
    output rcc_rst_l ;
 
    // Free-running clock input (from VCO)
    input input_clock ;

    // jtag scan clock
    input tc_scan_clk ;

    // add this so that pci clocks are reset only when in bypass mode.
    input pll_byp_l;

    // Stop clocks at next ss_clock rising edge.  It is driven only by
    //    the internal event logic.  It can come on in any phase.  Unless
    //    it stops clocks in phase 000, an extra sbclk pulse will have been
    //    issued - the system should be reset after one of these stops.
    input stop ;

    // Stop clocks after the given phase
    input stop_after_0 ;
    input stop_after_1 ;
    input stop_after_2 ;
    input stop_after_3 ;
    input stop_after_4 ;

    // Start clocks
    input start ;

    // Driven by jtag controller, this resets the clock state machine.
    //    Used to facilitate deterministic testing.
    input clk_rst_l ;

    // State machine bits, to be scanned out
    output stopped ;

    // Delayed version, for SBC
    output [2:0] free_phase_late_a1 ;

    // This input from the reset state machine temporarily disables the
    //     ss_clock and sbus_clk outputs.  It must be latched here on the
    //     next-to-last input_clock edge of the sbclk cycle, to produce a
    //     12.5-ns advanced copy of rs_dsbl_clocks, for use as an input to
    //     the clock-control state machine.
    input rs_dsbl_clocks_in ;

    // System clock, muxed with tc_scan_clk for scan
    output ss_clock_unbuf ;

    // SBus clock
    //output sbus_clk ;

    // Clock used by SBus output registers .  Same frequency as
    //     sbus_clk, but late by 1 input_clock cycles.
    output sboclk ;

    // PCI reference clock
    output pci_refclk_unbuf;
    output pci_refclk_unbuf_;
 
    // sysclk-frequency clock for reset state machine and clock control
    // This output is delayed for use in rl_clk_stop, rl_rst_cntl so that
    // the skew matches ss_clock.  All internal uses of rcc_clk must use
    // the output right out of the div by 2 flop (rcc_clk_ff)
    output rcc_clk_unbuf ;

   // free running timer clock, system clock divided by 4, not turned off in standby
    output tmr_clk ;
    
    // Graphics clock - ss_clock divided by 3
    output gclk_unbuf ;
    output gclk_unbuf_ ;
    output [1:0] gclk_phase_late_a1 ;

    /*-------------- end of I/O declarations ------------------*/

    wire gated_clk_rst_l = pll_byp_l | clk_rst_l;

    wire div_by_6 = (div_ctl[1:0] == 2'b00) ;
    wire div_by_3 = (div_ctl[1:0] == 2'b01) ;
    wire div_by_4 = (div_ctl[1:0] == 2'b10) ;
    wire div_by_5 = (div_ctl[1:0] == 2'b11) ;

    wire [2:0] free_phase, free_phase_a1, phase_a1,
	free_phase_late_a1, phase, initial_phase ;

    // Free-running clock, half the frequency of input_clock
//    Mflipflop_r fc_ff(free_clock, ~free_clock, clk_rst_l, input_clock) ;
    Mflipflop_r fc_ff(free_clock, ~free_clock, gated_clk_rst_l, input_clock) ;

    // (forward)
    wire rs_dsbl_clocks, tcen_sync, stopped, stopped_a1, stopped_cycle,
	    standby_dsbl_sysclk, last_free_phase, last_phase ;

    // Clock holds
    // For sysclk, rfr_clock, and rcc_clk, we can use 'stopped' instead
    //     of 'stopped_a1', because these clock signals are always high the
    //     cycle of a transition on 'stopped'.
    wire hold_sysclk =
	stopped | rs_dsbl_clocks | tcen_sync | standby_dsbl_sysclk ;
    wire hold_rfr_clock = stopped | rs_dsbl_clocks | tcen_sync ;
    wire hold_rcc_clk = stopped | tcen_sync ;

    // This one is more complex because each rising edge must be preceded
    //     by a low pulse of exactly half the free_phase period.
    // This signal is sample only on the input_clock edge which coincides
    //     with the falling edge of a (hypothetical) free sbclk, i.e.:
    //         div_by_2: end of free_phase 0
    //         div_by_3: middle of free_phase 1
    //         div_by_4: end of free_phase 1
    //         div_by_5: middle of free_phase 2

// sbus clocks no longer used 
/*
    wire hold_sbus_clock =

	// Hold sbclk high if we're stopped and not starting up.
	stopped_cycle

	// These terms used when we're running for at least part of the
	//     free sbclk cycle.
	// Don't bring sbclk low unless we can get all the way through the
	//     sbclk cycle without stopping.  Ignore the stop_after_* signals
	//     for phases less than the phase that we started the free_sbclk
	//     cycle in.
	// initial_phase and the stop_after_* signals change only at the
	//     beginning of the free_sbclk cycle, and hold_sbus_clock is used
	//     no earlier than the 2nd half of free_phase 001; thus these
	//     terms are 2-cycle MCPs.
	| (stop_after_0 & (initial_phase[2:0]==3'd0))
	| (~div_by_2 & stop_after_1 & (initial_phase[2:1]==2'b00))
	| ((div_by_4|div_by_5) & stop_after_2 & (initial_phase[2:1]==2'b00))
	| ((div_by_4|div_by_5) & stop_after_2 & (initial_phase[1:0]==2'd2))
	| (div_by_5 & stop_after_3 & (initial_phase[2]==1'b0))

	// Hold sbclk high when rst_cntl is disabling clocks
	// This transitions only at the start of the free sbclk cycle.
	| rs_dsbl_clocks

	// Hold sbclk high when JTAG is driving on-chip clocks, so SBC
	//     doesn't get out of sync.
	// This transitions only at the start of the free sbclk cycle.
	| tcen_sync
	;
*/

    // system clock
    wire sysclk_a1 = ~free_clock | hold_sysclk ;
    Mflipflop_r gc_ff(sysclk, sysclk_a1, clk_rst_l, input_clock) ;
    wire ss_clock_unbuf = ~(~sysclk | ~tc_scan_clk) ;

    // refresh clock - not stopped by standby, but otherwise controlled 
    //     exactly like sysclk.
    wire rfr_clock_ff_a1 = ~free_clock | hold_rfr_clock ;
    Mflipflop_r rc_ff(rfr_clock_ff, rfr_clock_ff_a1,
	clk_rst_l, input_clock) ;
    wire rfr_clock = ~(~rfr_clock_ff | ~tc_scan_clk) ;

    // One-input_clock-cycle late refresh clock
    Mflipflop_r rl_ff(rfr_late_ff, rfr_clock_ff,
	clk_rst_l, input_clock) ;
    wire rfr_late = ~(~rfr_late_ff | ~tc_scan_clk) ;

    // tmr_clk - also not stopped by standby, but otherwise controlled
    //     exactly like sysclk, but divided by four.  9-12-96
    wire tmr_clk_in1, tmr_clk_in2 ;
    Mflipflop_r tmr_ff1(tmr_clk_ff1, tmr_clk_in1, clk_rst_l, input_clock) ;
    Mflipflop_r tmr_ff2(tmr_clk_ff2, tmr_clk_in2, clk_rst_l, input_clock) ;
    assign tmr_clk_in1 = (~rfr_clock_ff & ~tmr_clk_ff1) | 
			(rfr_clock_ff & tmr_clk_ff1) ;
    assign tmr_clk_in2 = (~rfr_clock_ff & ~tmr_clk_ff1 & ~tmr_clk_ff2) |
			(rfr_clock_ff & tmr_clk_ff1 & tmr_clk_ff2) |
			(~rfr_clock_ff & tmr_clk_ff1 & tmr_clk_ff2) |
			(rfr_clock_ff & ~tmr_clk_ff1 & tmr_clk_ff2) ;
    wire tmr_clk = ~(~tmr_clk_ff2 | ~tc_scan_clk) ;

    // Reset controller clock
    wire rcc_clk_ff_a1 = ~free_clock | hold_rcc_clk ;

//  This flop feeds all internal uses.  The external uses of rcc_clk in
//  rl_clk_stop and rl_rst_cntl use a delayed (skew matched) version
    Mflipflop_r grc_ff(rcc_clk_ff, rcc_clk_ff_a1,
	clk_rst_l, input_clock) ;
    wire rcc_clk_unbuf = ~(~rcc_clk_ff | ~tc_scan_clk) ;

    // Free-running phase counter, effectively clocked by free_clock.  Its
    //     period is the same as that of sbclk.
    //
    // Five-phase mode:   000 001 010 011 100
    // Four-phase mode:   000 001 010 011
    // Three-phase mode:  000 001 010
    // Two-phase mode:    000 001
    assign free_phase_a1[2:0] = next_phase(free_phase[2:0], last_free_phase) ;
	
    Mflipflop_rh_3 fp_reg(free_phase[2:0], free_phase_a1[2:0],
	free_clock, clk_rst_l, input_clock) ;

    // FF which indicates last phase of free cycle
    //
    // Modified scaling of sbus clock -  6/6/96

    wire last_free_phase_a1 =
	//(div_by_2 & ~free_phase[0] & ~last_free_phase)  // Prevent deadlock
	//| (div_by_3 & free_phase[0])
	//| (div_by_4 & (free_phase[1:0]==2'h2))
	//| (div_by_5 & (free_phase[1:0]==2'h3))
	//(div_by_2 & free_phase[0])                   // divide by 3
        | (div_by_3 & (free_phase[1:0]==2'h2))       // divide by 4
        | (div_by_4 & (free_phase[1:0]==2'h3))       // divide by 5
        | (div_by_5 & (free_phase[2:0]==3'h4))       // divide by 6
        | (div_by_6 & (free_phase[2:0]==3'h5))       // divide by 6
	;
    Mflipflop_rh lfp_ff(last_free_phase, last_free_phase_a1,
	free_clock, clk_rst_l, input_clock) ;

    // Modified to scale with PCI clock -  7/12/96

    // Phase counter, effectively clocked by rcc_clk
    //Mflipflop_rh_3 gpc_reg(phase[2:0], free_phase_a1[2:0],
	//rcc_clk_ff, clk_rst_l, input_clock) ;
    //Mflipflop_rh lp_ff(last_phase, last_free_phase_a1,
	//rcc_clk_ff, clk_rst_l, input_clock) ;

    wire    [2:0]   free_phase_pci, free_phase_pci_next;
    wire    last_free_phase_pci_in, last_free_phase_pci ;

    Mflipflop_rh_3 gpc_reg(phase[2:0], free_phase_pci_next[2:0],
        rcc_clk_ff, clk_rst_l, input_clock) ;
    Mflipflop_rh lp_ff(last_phase, last_free_phase_pci_in,
        rcc_clk_ff, clk_rst_l, input_clock) ;

    //wire last_phase_2nd_half = last_free_phase & ~free_clock ;

    wire last_phase_2nd_half = last_free_phase_pci & ~free_clock ;

    // This register, latched at the end of each free_sbclk cycle, holds
    //     the initial value of phase[2:0].  It is used for sbclk generation.
    Mflipflop_rh_3 ip_reg(initial_phase[2:0],
	(rcc_clk_ff ? phase[2:0] : 3'b0),
	~last_phase_2nd_half, clk_rst_l, input_clock) ;

    // Sbus clock
// sbus clocks no longer used - 
/*
    wire sbus_clk_a1 = last_free_phase | hold_sbus_clock ;

    wire sbclk_enbl = 
	last_phase_2nd_half
//	| (~free_clock & div_by_2)
	| (free_clock & div_by_3 & free_phase[0])
	| (~free_clock & div_by_4 & free_phase[0])
	| (free_clock & div_by_5 & (free_phase[1:0]==2'h2))
	| (~free_clock & div_by_6 & (free_phase[1:0]==2'h2))
	;
*/
    //Mflipflop_rh gsc_ff(sbus_clk, sbus_clk_a1,
	//~sbclk_enbl, clk_rst_l, input_clock) ;

    // SBus output clock.  Rising edge is *late* version of sbclk
    //     rising edge:
    //         div_by_2: one input_clock cycle late
    //         div_by_3: one input_clock cycle late
    //         div_by_4: two input_clock cycles late
    //         div_by_5: two input_clock cycles late
    // For implementation convenience, falling edge always coincides
    //     with the sbclk rising edge.
    wire sboclk_ff ; // (forward)
    // It's low the cycle after a last-phase rfr_clock pulse.

// Modified to scale to PCI clock -  7/12/96

    //wire sboclk_ff_a1 = ~( last_free_phase & ~rfr_clock_ff) ;
    wire sboclk_ff_a1 = ~( last_free_phase_pci & ~rfr_clock_ff) ;
    Mflipflop_r goc_ff(sboclk_ff, sboclk_ff_a1,
	clk_rst_l, input_clock) ;
    wire sboclk = ~(~sboclk_ff | ~tc_scan_clk) ;

        // PCI reference clock
        // needs new signals for free_phase_pci

        assign  free_phase_pci_next[2:0] =
                        next_phase(free_phase_pci[2:0], last_free_phase_pci) ;
//        Mflipflop_rh_3 fppci_reg(free_phase_pci[2:0], free_phase_pci_next[2:0],
//                                        free_clock, clk_rst_l, input_clock) ;
        Mflipflop_rh_3 fppci_reg(free_phase_pci[2:0], free_phase_pci_next[2:0],
                                        free_clock, gated_clk_rst_l, input_clock) ;
 
        // Modified scaling the PCI clock -   6/6/96
        //
        assign  last_free_phase_pci_in  =
//                        (div_by_2 & ~free_phase_pci[0] & ~last_free_phase_pci) |
                        //(div_by_3 & ~free_phase_pci[0] & ~last_free_phase_pci) |
                        //(div_by_4 & free_phase_pci[0]) |
                        //(div_by_5 & (free_phase_pci[1:0]==2'h2)) ;
                        (div_by_3 & free_phase_pci[0]) |
			(div_by_4 & (free_phase_pci[1:0]==2'h2)) |
			(div_by_5 & (free_phase_pci[1:0]==2'h3)) |
			(div_by_6 & (free_phase_pci[2:0]==3'h4)) ;

//        Mflipflop_rh lfppci_ff(last_free_phase_pci, last_free_phase_pci_in,
//                                        free_clock, clk_rst_l, input_clock) ;

        Mflipflop_rh lfppci_ff(last_free_phase_pci, last_free_phase_pci_in,
                                        free_clock, gated_clk_rst_l, input_clock) ;

        wire    last_phase_pci_2nd_half = last_free_phase_pci & ~free_clock ;
 
// Remove PCIHOLD since it stops pci clock - 7/16/96

        //Mflipflop_r dlyhld_ff(pcihold, hold_sysclk, clk_rst_l, input_clock) ;
 
 	// Modified the pci clock enable -  6/18/96
        wire    pciclk_enbl =
                        //~pcihold &
                        (last_phase_pci_2nd_half |
                        //(div_by_2 & ~free_clock) |
                        //(div_by_3 & ~free_clock) |
                        //(div_by_4 & free_clock & free_phase_pci[0]) |
                        //(div_by_5 & ~free_clock & free_phase_pci[0])) ;
			(div_by_3 & free_clock & free_phase_pci[0]) |
			(div_by_4 & ~free_clock & free_phase_pci[0]) |
			(div_by_5 & free_clock & (free_phase_pci[1:0]==2'h2)) |
			(div_by_6 & ~free_clock & (free_phase_pci[1:0]==2'h2))) ;
 
//        Mflipflop_rh pciclk_ff(pci_refclk_unbuf_ndly, last_free_phase_pci,
//                                ~pciclk_enbl, clk_rst_l, input_clock) ;

        Mflipflop_rh pciclk_ff(pci_refclk_unbuf_ndly, last_free_phase_pci,
                                ~pciclk_enbl, gated_clk_rst_l, input_clock) ;
 
//        Mflipflop_r pciclk_dly_ff(pci_refclk_unbuf, pci_refclk_unbuf_ndly,
//                                        clk_rst_l, input_clock) ;

        Mflipflop_r pciclk_dly_ff(pci_refclk_unbuf, pci_refclk_unbuf_ndly,
                                        gated_clk_rst_l, input_clock) ;
 
//        Mflipflop_r pciclk_dly_ff_(pci_refclk_unbuf_, ~pci_refclk_unbuf_ndly,
//                                        clk_rst_l, input_clock) ;
 
        Mflipflop_r pciclk_dly_ff_(pci_refclk_unbuf_, ~pci_refclk_unbuf_ndly,
                                        gated_clk_rst_l, input_clock) ;

    // Copy of phase_a1[2:0] used by clk_stop.
    // To avoid races, first latch on the falling edge of free_clock, then
    //     send to clk_stop module to be latched in a rcc_clk reg.
    assign phase_a1[2:0] = next_phase(phase[2:0], last_phase) ;
    // Note that we changed the hold input from ~rcc_clk_ff to rcc_clk_ff -
    //     this delays the output transition by one input_clock cycle, to
    //     compensate for the several-ns rcc_clock distribution delay.
    //     This path is now an 'intentional race' into the destination
    //     register in clk_stop - the same input_clock edge which changes
    //     this output also causes the rcc_clock edge which latches it at
    //     the destination.  See Bug 597.
    Mflipflop_rh_3 lpc1_reg(free_phase_late_a1[2:0], phase_a1[2:0],
	rcc_clk_ff, clk_rst_l, input_clock) ;

    // Clock Stop logic

    // NOTE: 'stop' may chop the sbclk pulse - software should reset the
    //       system after stopping this way.

    // Modified to scale with PCI clock -  7/10/96

    wire stop_clocks =
	stop
	//| (stop_after_0 & (free_phase[2:0]==3'h0))
	//| (stop_after_1 & (free_phase[1:0]==2'h1))
	//| (stop_after_2 & (free_phase[1:0]==2'h2))
	//| (stop_after_3 & (free_phase[1:0]==2'h3))
	//| (stop_after_4 & free_phase[2])

        | (stop_after_0 & (free_phase_pci[2:0]==3'h0))
        | (stop_after_1 & (free_phase_pci[1:0]==2'h1))
        | (stop_after_2 & (free_phase_pci[1:0]==2'h2))
        | (stop_after_3 & (free_phase_pci[1:0]==2'h3))
        | (stop_after_4 & free_phase_pci[2])
	;

    // Start clocks when we reach the right phase, but don't start yet them
    //     if the sbclk logic thinks we won't.
    //wire start_clocks = (start & (free_phase_a1[2:0]==phase[2:0])) ;

    wire start_clocks = (start & (free_phase_pci_next[2:0]==phase[2:0])) ;

    // Don't change 'stopped' state when clocks are driven by jtag (tcen, i.e.
    //     Shift or capture), or when jtag trst is asserted.  Force to 0 on
    //     input reset.
    wire trst_sync_l, reset_sync_l ; // (forward)
    assign stopped_a1 =
	~reset_sync_l ? 0 : (
	(tcen_sync | ~trst_sync_l) ? stopped : (
	stopped ? ~start_clocks : (
	stop_clocks ))) ;
    Mflipflop_rh stopped_ff(stopped, stopped_a1,
	free_clock, clk_rst_l, input_clock) ;

    // Next-state of start FF: set by scan, reset on the first rcc_clk
    wire start_a1 = start & hold_rcc_clk ;

    // This flipflop tells us that clocks are stopped and will not be started
    //     during this free sbclk cycle.  It is used for sbclk generation.
    Mflipflop_rh sc_ff(stopped_cycle, stopped_a1 & ~start_a1,
	~last_phase_2nd_half, clk_rst_l, input_clock) ;

    // These three synchronizers must produce clean outputs which can be
    //     used as inputs to the input_clock-frequency state machine.  The
    //     synchronized outputs must transition at most once per
    //     freerunning sbclk-frequency cycle, on the input_clock edge which
    //     *precedes* the input_clock edge which causes positive edges on
    //     both the freerunning sbclk- and sysclk-frequency clocks.
    // Use special metastable-hardened flops for these.

    // Modified to match to PCI clock and not SBUS clock - 7/10/96

    //wire last_phase_1st_half = last_free_phase & free_clock ;
    //wire first_phase_2nd_half = (free_phase[2:0]==3'h0) & ~free_clock ;

    wire last_phase_1st_half = last_free_phase_pci & free_clock ;
    wire first_phase_2nd_half = (free_phase_pci[2:0]==3'h0) & ~free_clock ;

    Mflipflop_rh scmode1_ff(tcen_sync1, testclken,
	~last_phase_1st_half, clk_rst_l, input_clock) ;
    Mflipflop_rh scmode_ff(tcen_sync, tcen_sync1,
	~last_phase_1st_half, clk_rst_l, input_clock) ;
 
    Mflipflop_rh jtrst1_ff(trst_sync1_l, jtag_trst_l,
	~last_phase_1st_half, clk_rst_l, input_clock) ;
    Mflipflop_rh jtrst_ff(trst_sync_l, trst_sync1_l,
	~last_phase_1st_half, clk_rst_l, input_clock) ;
 
    Mflipflop_rh rst1_ff(reset_sync1_l, input_reset_l,
	~last_phase_1st_half, clk_rst_l, input_clock) ;
    Mflipflop_rh rst_ff(reset_sync_l, reset_sync1_l,
	~last_phase_1st_half, clk_rst_l, input_clock) ;

    // Delay this sbclk-frequency-clocked signal so we can use it as input to
    //   the clock control state machine. This FF will change in the
    //   input_clock cycle which precedes the 1->0 transition on
    //   last_free_phase.
    Mflipflop_rh rs_dsbl_ff(rs_dsbl_clocks, rs_dsbl_clocks_in,
	~last_phase_1st_half, clk_rst_l, input_clock) ;

    // This signal is one input_clock cycle earlier than the signal of the
    //     same name in rl_clk_stop.
    Mflipflop_rh pdm_ff(standby_dsbl_sysclk,
	standby_dsbl_sysclk_a1 & rcc_rst_l,
	~last_phase_1st_half, clk_rst_l, input_clock) ;

    // This is used to reset the reset state machine and the clock control
    //     register.  Don't reset them during scan.
    //
    // *** The following paragraph contains some lies - see note below ***
    // To assure proper operation of the reset state machine, this signal
    //     should transition after the falling edge of last_free_phase.
    //     It must meet setup and hold requirements on rcc_clk-clocked FFs.
    //     Since its inputs transition one input_clock cycle before the 
    //     falling edge of last_free_phase, the following implementation
    //     should work:  this FF's inputs are set up and held for at least
    //     two input_clock cycles; its output is held for one
    //     input_clock cycle after the 1->0 transition of last_free_phase, and
    //     is setup for one cycle before the next rcc_clk (i.e. free_clock)
    //     rising edge.  Since the rcc_clk edge is late w.r.t. the input_clk
    //     edge which generates it, we must carefully analyze the
    //     destinations of this signal for races.
    //
    // Note that we changed the hold input from ~first_phase_1st_half to
    //     first_phase_2nd_half - this delays the output transition by one
    //     input_clock cycle, to compensate for the several-ns rcc_clock
    //     distribution delay.  This path is now an 'intentional race' into
    //     the destination register in clk_stop - the same input_clock edge
    //     which changes this output also causes the rcc_clock edge which
    //     latches it at the destination.  See Bug 597.
    //
    Mflipflop_rh rcc_rst_ff(rcc_rst_l, ~(~reset_sync_l & ~tcen_sync),
	~first_phase_2nd_half, clk_rst_l, input_clock) ;

    // Mod-DIV_RATIO increment.
    //
    // Modified on 6/5/96 to count upto 5. This is for divide by 6 for the 
    // sbus_clk when ss_clk is at 150 MHz.  
    //
    // Six-phase mode:    000 001 010 011 100 101
    // Five-phase mode:   000 001 010 011 100
    // Four-phase mode:   000 001 010 011
    // Three-phase mode:  000 001 010
    // Two-phase mode:    000 001
    //
    function [2:0] next_phase ;
	input [2:0] phase ;
	input last_phase ;
	next_phase[2:0] = {
	    //(((phase[1:0]==2'h3) | (phase[2:0] == 3'h4)) & ~last_phase),

// Modified to take care of clock reset problem - 
// make the state machine to count up to 7 and then reset to 0

            (((phase[2:0]==3'h3) | (phase[2:0] == 3'h4) | (phase[2:0] == 3'h5) | (phase[2:0] == 3'h6)) & ~last_phase),
	    ((phase[1]^phase[0]) & ~last_phase),
	    ( ~phase[0] & ~last_phase)
	}  ;
    endfunction

    // Graphics clock - sysclk divided by 3, 50% duty cycle.
    wire [1:0] gclk_phase, gclk_phase_a1 ;

    //Fix for bug 595  gclk/sbclk phase relationship.  
    //   Force gclk_phase to 00 in next clock when last_phase and div_by_3 mode.
    //   This makes gclk and sbclk always have the same phase
    //   Note that this fix is only good in div_by_3 mode.
    //   Fix for div_by_4 and 5 are done in reset state machine.

    //assign gclk_phase_a1[1:0] = next_phase(gclk_phase, gclk_phase[1]) ;
    // Changed here so that gclk is no longer in phase with sbclk
    // 6/18/96 

// put this back to the way it was originally .   change could cause 
// the pci and gclk to be out of phase which could cause the reset state machine to
// not function since it requires the phases to be aligned before proceeding.
// We did not see this in simulation, because we always go through the clk_rst_l sequence.

 assign gclk_phase_a1[1:0] = next_phase(gclk_phase, gclk_phase[1] | ((div_by_3 | div_by_6) & last_phase)) ;
//    assign gclk_phase_a1[1:0] = next_phase(gclk_phase, gclk_phase[1]);

    Mflipflop_rh_2 gcp_reg(gclk_phase, gclk_phase_a1,
	sysclk, clk_rst_l, input_clock) ;

    // Toggle gclk in first half of phase 1 and last half of phase 2.
    wire toggle_gclk =
	(gclk_phase[0] & ~sysclk_a1) | (gclk_phase[1] & ~sysclk) ;

    Mflipflop_rh gck_ff(gclk_unbuf, ~sysclk,
	~toggle_gclk, clk_rst_l, input_clock) ;

    Mflipflop_rh gck_ff_(gclk_unbuf_, sysclk,
	~toggle_gclk, clk_rst_l, input_clock) ;

    // This will be latched in an rcc_clk FF to make gclk_phase[1:0].
    // Note that we changed the hold input from ~sysclk to sysclk -
    //     this delays the output transition by one input_clock cycle, to
    //     compensate for the several-ns rcc_clock distribution delay.
    //     This path is now an 'intentional race' into the destination
    //     register in clk_stop - the same input_clock edge which changes
    //     this output also causes the rcc_clock edge which latches it at
    //     the destination.  See Bug 597.
    Mflipflop_rh_2 gpl1_ff(gclk_phase_late_a1[1:0], gclk_phase_a1[1:0],
	sysclk, clk_rst_l, input_clock) ;

endmodule
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 12:00:28 1999
From: ../../../sparc_v8/ssparc/clk_misc/rl_clk_cntl/rtl/rl_clk_cntl.v

Verilog converted to html by v2html 5.0 (written by Costas Calamvokis).Help