/******************************************************************************/
/* */
/* 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
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
This page: |
Created: | Thu Aug 19 12:00:28 1999 |
| From: |
../../../sparc_v8/ssparc/clk_misc/rl_clk_cntl/rtl/rl_clk_cntl.v
|