Coolquest, Inc. Home Products Support About Contact
cbold_logo_gif C++BOLD Example Design: IROD cbold_logo_gif

Design Home <<  File View  >> Class View Output (partial) Parts Library Examples Home

 

// THIS FILE IS IN THE PUBLIC DOMAIN.
// IT IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
// NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
#ifndef _ClockGenerationH_
#define _ClockGenerationH_
 
#include "jtag.h"
#include "clockdriverscdc.h"
#include "std_drivers.h"
#include "lvds.h"
#include "sn74cbtlv3253.h"
#include "w170_01.h"
#include "std_syn.h"
#include "noisy_pld.h"
#include "quiet_pld.h"
#include "monopins.h"
 
// Clock Generation subsystem
 
// All necessary decoupling capacitors are already included.  See table below.
 
// nomenclature note:
//   BK only applies to the interface to the Backplane subsystem
//   BP applies to components and signals within the Clock Generation subsystem that are related to the Backplane subystem
//   FP applies to components and signals within the Clock Generation subsystem that are related to the Front Panel
 
class  CB_PWR_CG : public TBundle {
public:
  port DSP_VCOK;     // many clocks are disabled until DSP_VCC is OK
 
  virtual void Register() {
    reg( DSP_VCOK );
  }
};
 
 
// CB_Back_CG: interface between Backplane and ClockGeneration
class CB_Back_CG : public TBundle {
public:
  port RCLKOP;  // LVDS clock outputs to backplane
  port RCLKON;
 
  port SCLKOP;
  port SCLKON;
 
  port TCLKOP;
  port TCLKON;
 
  port DCLKOP;
  port DCLKON;
 
  port RCLKIP;  // inputs from backplane (CM range = -2 to 4.4V --> compatible with ECL, PECL, LVDS)
  port RCLKIN;
 
  port TCLKIP;
  port TCLKIN;
 
  virtual void Register() {
    reg( RCLKOP );
    reg( RCLKON );
 
    reg( SCLKOP );
    reg( SCLKON );
 
    reg( TCLKOP );
    reg( TCLKON );
 
    reg( DCLKOP );
    reg( DCLKON );
 
    reg( RCLKIP );
    reg( RCLKIN );
 
    reg( TCLKIP );
    reg( TCLKIN );
  }
};
 
 
// CB_DX_CG: interface between DataExchange and ClockGeneration
class CB_DX_CG : public TBundle {
public:
  port DX_CLK;     // DX clock (front end)
  port DXINT_CLK;  // DX internal clock
  port DCLK;       // DX output clock
 
  virtual void Register() {
    regb( DX_CLK,    1, 0 );
    regb( DXINT_CLK, 3, 0 );  // one extra clock for DX's Host FIFO
    regb( DCLK,      2, 0 );
  }
};
 
 
// CB_DC_CG: interface between DPU_Control and ClockGeneration
class CB_DC_CG : public TBundle {
public:
  port DX_CLK;   // DX clock (front end)
  port DC_CLK;   // DPU Control clock
  port RCLK;     // general-purpose clock (also available to DPU XB FPGA)
  port SCLK;     // general-purpose clock (also available to DPU XB FPGA)
 
  virtual void Register() {
    reg( DX_CLK );
    reg( DC_CLK );
    reg( RCLK );
    reg( SCLK );
  }
};
 
 
// CB_Front_CG: interface between FrontPanel and ClockGeneration
class CB_Front_CG : public TBundle {
public:
  port RCLKIP;  // inputs from backplane (CM range = -2 to 4.4V --> compatible with ECL, PECL, LVDS)
  port RCLKIN;
 
  port TCLKIP;
  port TCLKIN;
 
  port CKOE_DIPSW;     // dip switch signal for enabling most clocks
  port VBOE_DIPSW;     // dip switch signal for enabling VME_CLK and BASE_CLK (BASE_OSC)
 
  virtual void Register() {
    reg( RCLKIP );
    reg( RCLKIN );
    reg( TCLKIP );
    reg( TCLKIN );
    reg( CKOE_DIPSW );
    reg( VBOE_DIPSW );
  }
};
 
 
// CB_Half_CG: interface between HalfROD and ClockGeneration
class CB_Half_CG : public TBundle {
public:
  port DC_CLK;   // DPU Control clock
  port RCLK;     // general-purpose clock
  port SCLK;     // general-purpose clock
  port DPU_CLK;  // CPU clock for DPU's
  port DX_CLK;   // Data Exchange clock (front end)
 
// for best layout, SCLK, DPU_CLK, DX_CLK are shared in some cases:
// B0          no sharing, 10 pF load capacitor added
// B2 <--> B1  clocks shared
// B3 <--> B4  clocks shared
// B5 <--> A0  clocks shared
// A2 <--> A1  clocks shared
// A3 <--> A4  clocks shared
// A5          no sharing, 10 pF load capacitor added
 
  virtual void Register() {
    regb( DC_CLK,  5, 0 );   // one clock per DPU
    regb( RCLK,    5, 0 );   // one clock per DPU
    regb( SCLK,    5, 0 );   // one clock per DPU, some shared between DPU pairs
    regb( DPU_CLK, 5, 0 );   // one clock per DPU, some shared between DPU pairs
    regb( DX_CLK,  5, 0 );   // one clock per DPU, some shared between DPU pairs
  }
};
 
 
// CB_Host_CG: interface between Host and ClockGeneration
class CB_Host_CG : public TBundle {
public:
  port HPU_CLK;  // CPU clock for HPU
  port DX_CLK;   // Data Exchange clock (front end)
  port DC_CLK;   // DPU Control clock
  port RCLK;     // general-purpose clock
  port SCLK;     // general-purpose clock
 
  port NSTB_N;        // one strobe to Noisy PLD      --Noisy PLD creates QSTB_N for QuietPLD
  port WR_N;          // one read/write* to Noisy PLD --Noisy PLD creates QWR_N  for QuietPLD
  port D;             // data                         --Noisy PLD creates QD     for QuietPLD
  port A;             // two address bits:            --Noisy PLD creates QA     for QuietPLD (one bit derived from A0)
                      //   A1  A0     register addressed
                      //   --  --     -------------------
                      //    0   0     QuietPLD   pointer
                      //    0   1     QuietPLD (*pointer)
                      //    1   0     NoisyPLD   pointer
                      //    1   1     NoisyPLD (*pointer)
 
  virtual void Register() {
    reg(  HPU_CLK );
    reg(  DX_CLK );
    reg(  DC_CLK );
    reg(  RCLK );
    reg(  SCLK );
 
    reg(  NSTB_N );
    reg(  WR_N  );
    regb( D, 7, 0 );
    regb( A, 1, 0 );
  }
};
 
 
// CB_IC_CG: interface between Interconnect and ClockGeneration
class CB_IC_CG : public TBundle {
public:
  port RCLK;     // general-purpose clock (also available to both DPU FPGA's)
  port SCLK;     // general-purpose clock (also available to DPU's XB FPGA)
  port TCLK;     // TTC clock             (not  available to DPU's)
 
  virtual void Register() {
    regb( RCLK,   3, 0 );
    regb( SCLK,   3, 0 );
    regb( TCLK,   3, 0 );
  }
};
 
 
// CB_VME_CG: interface between Host and ClockGeneration
class CB_VME_CG : public TBundle {
public:
  port VME_CLK;       // VME Interface clock
  port BOOT_CLK;      // 6.25 MHz clock used to configure FPGA's, etc., during HPU bootstrap
  port SOFTRESET_N;   // from flash PLD, to CG PLD's
 
  virtual void Register() {
    regb( VME_CLK, 2, 0 );
    reg(  BOOT_CLK      );
    reg(  SOFTRESET_N   );
  }
};
 
 
class CM_ClockGeneration : public TModule {    // Clock Generation Subsystem
public:
// ***** member bundles ***** //
  CB_Back_CG  BK;        // interface to Backplane
  CB_DX_CG    DX;        // interface to DataExchange
  CB_DC_CG    DC;        // interface to DPU_Control
  CB_Front_CG FP;        // interface to FrontPanel
  CB_Half_CG  A;         // interface to Half A
  CB_Half_CG  B;         // interface to Half B
  CB_Host_CG  HO;        // interface to Host
  CB_IC_CG    IC;        // interface to Interconnect
  CB_CG_JT    JT;        // interface to JTAG
  CB_PWR_CG   PWR;       // interface to Power
  CB_VME_CG   VME;       // interface to VME_Interface
 
 
// ***** member ports ***** //
  port MB_VCC;      // 3.3V
  port GND;
 
// ***** member modules and parts ***** //
  CM_NoisyPLD       NoisyPLD;
  CM_QuietPLD       QuietPLD;
                                 // 3.3V oscillators
  CP_XOSC_25M       OscT_HPU;    // thru-hole oscillators are wired in parallel with...
  CP_XOSC_25M       OscT_BASE;
  CP_XOSC_50M       OscT_VME;
  CP_XOSC_SMT_25M   OscS_HPU;    // ... surface-mount oscillators
  CP_XOSC_SMT_25M   OscS_BASE;
  CP_XOSC_SMT_50M   OscS_VME;
 
  CP_R30            STerm_Osc_HPU;   // series termination for oscillator outputs (they drive capacitive loads)
  CP_R30            STerm_Osc_BASE;
// no terminator needed for VME_CLK
 
  CP_R30            STerm_BOOT_CLK;  // series termination
 
 
// for more readable views, this design uses individual parts rather than arrays
 
  CM_StdSyn         Syn_RCLK;        // Synthesizers
  CM_StdSyn         Syn_SCLK;
  CM_StdSyn         Syn_TCLK;
  CM_StdSyn         Syn_DCLK;
  CM_StdSyn         Syn_DC_CLK;
  CM_StdSyn         Syn_DX_CLK;
  CM_StdSyn         Syn_HPU_CLK;
  CM_StdSyn         Syn_DPU_CLK;
  CM_StdSyn         Syn_DXINT_CLK;
 
 
  CP_SN74CBTLV3253  Mux_RCLK;          // primary multiplexers
  CP_SN74CBTLV3253  Mux_SCLK;
  CP_SN74CBTLV3253  Mux_TCLK;
  CP_SN74CBTLV3253  Mux_DCLK;
  CP_SN74CBTLV3253  Mux_DC_CLK;
  CP_SN74CBTLV3253  Mux_DX_CLK;
  CP_SN74CBTLV3253  Mux_HPU_CLK;
  CP_SN74CBTLV3253  Mux_SYN_BASE;
 
  CP_SN74CBTLV3253  SMux_RCLK;         // secondary multiplexers
  CP_SN74CBTLV3253  SMux_TCLK;
  CP_SN74CBTLV3253  SMux_HPU_CLK;
  CP_SN74CBTLV3253  SMux_SYN_BASE;
 
  CP_W170_01        Mpy_IRCLK;         // multipliers, which also remove delay of CDC319's
  CP_W170_01        Mpy_ISCLK;
  CP_W170_01        Mpy_ITCLK;
 
  CP_R30            STerm_Mpy_IRCLK;   // series termination for multiplier output allows CDC319 to be distant from multipliers
  CP_R30            STerm_Mpy_ISCLK;
  CP_R30            STerm_Mpy_ITCLK;
 
                                       // clock drivers
  CM_STD_CDC319     Drv_IRCLK;        // internal clocks
  CM_STD_CDC319     Drv_ISCLK;
  CM_STD_CDC319     Drv_ITCLK;
  CM_STD_CDC319     Drv_SYN_BASE;     // synthesizer base clock
 
  CP_CDC2510        Drv_RCLK0;
  CP_CDC2510        Drv_RCLK1;         // register this one last to preserve existing reference designators
  CP_CDC2516        Drv_SCLK;
  CP_CDC2510        Drv_TCLK;
  CP_CDC2510        Drv_DCLK;
  CP_CDC2516        Drv_DC_CLK;
  CP_CDC2516        Drv_DX_CLK;
  CP_CDC2510        Drv_HPU_CLK;
  CP_CDC2510        Drv_DPU_CLK;
  CP_CDC2510        Drv_DXINT_CLK;
  CP_CDC2510        Drv_VME_CLK;
 
  CP_SN65LVDS1      Drv_BP_RCLKO;      // backplane LVDS clock drivers
  CP_SN65LVDS1      Drv_BP_SCLKO;
  CP_SN65LVDS1      Drv_BP_TCLKO;
  CP_SN65LVDS1      Drv_BP_DCLKO;
 
 
  CP_SN65LVDS9637B  Rcv_BP_RCLKI;      // backplane and front panel differential clock receivers (LVDS, PECL, ECL)
  CP_SN65LVDS9637B  Rcv_BP_TCLKI;
  CP_SN65LVDS9637B  Rcv_FP_RCLKI;
  CP_SN65LVDS9637B  Rcv_FP_TCLKI;
 
  CP_R110           DTerm_BP_RCLKI;     // differential termination for input of clock receivers--installation of these terminators is optional
  CP_R110           DTerm_BP_TCLKI;
  CP_R110           DTerm_FP_RCLKI;
  CP_R110           DTerm_FP_TCLKI;
 
  CP_R30            STerm_BP_RCLKI;     // series termination for output of clock receivers (always installed)
  CP_R30            STerm_BP_TCLKI;
  CP_R30            STerm_FP_RCLKI;
  CP_R30            STerm_FP_TCLKI;
  CP_R30            STerm_DERIVED_BASE;
 
  enum { clc_count = 12 };             // clock load capacitors  >>> place all CLC, CLC_... at end of transmission line
  CP_C10PF          CLC_IRCLK;
  CP_C10PF          CLC_ISCLK;
  CP_C10PF          CLC_ITCLK;
  CP_C33PF          CLC_DC_CLK;        // on clock to DC FPGA
  CP_C10PF          CLC[ clc_count ];  // at miscellaneous locations
 
  CP_R10K           PulldownSyn_HPU;   // pulldown for output of HPU synthesizer
  CP_R4_7K          PullupOsc_BASE;    // pullup in case Osc_BASE output is floated
  CP_R4_7K          PullupVB_OE;       // pullup in case oscillator's internal pullup is not strong enough (e.g., oscillator w/o pullup is used)
  CP_R1K            SeriesVCOK;        // series resistor that allows DIP switch override of DSP_VCOK
 
  enum { mono_count = 51 };            // monopins for routing far-end cluster of some clock nets
  CP_MONOPIN25      Mono[ mono_count ];
 
  enum { ferrite_count =  11 + 3 + 3 };  // ferrites for PLL drivers, PLL multipliers, and oscillators
 
  CP_FERRITE120     Ferrite[  ferrite_count ];     // filters            for CDC25xx AVCC, W-170 AVCC, oscillator AVCC
  CP_CDC_POS        AVCC_CDC[ ferrite_count ];
 
//  Standard Decoupling
//  ----------------------------------------------
//  PLD's:           0  included in PLD classes
//  synthesizers:    0  included in CM_StdSyn class
//  oscillators:     0  AVCC_CDC used
//  multipliers      0  AVCC_CDC used
//  mux's           12  1 CDC * 12 chips
//  CDC319          16  4 CDC *  4 chips
//  CDC2516         12  4 CDC *  3 chips
//  CDC2510         24  3 CDC *  8 chips
//  SN65LVDS1        4  1 CDC *  4 chips
//  SN65LVDS9637B    4  1 CDC *  4 chips
//  ----------------------------------------------
//  Total CDC's     72
//  Total TDC's:     5 (arbitrary number)
 
  enum { vc_cdc_count = 72,
         vc_tdc_count =  3 };
  CP_CDC_POS  VC_CDC[ vc_cdc_count ];    // ceramic decoupling
  CP_TDC_POS  VC_TDC[ vc_tdc_count ];    // tantalum decoupling
 
  CP_CDC_POS  OSC_CDC[ 3 ];              // three more CDC's, one for each duplicate oscillator
 
 
  virtual void Register() {
// bundles
    reg( BK );
    reg( DX );
    reg( DC );
    reg( FP );
    reg( A );
    reg( B );
    reg( HO );
    reg( IC );
    reg( JT );
    reg( PWR );
    reg( VME );
 
// ports
    reg( MB_VCC );
    reg( GND );
 
// parts and modules
    reg( NoisyPLD );
    reg( QuietPLD );
 
    reg( OscT_HPU );
    reg( OscT_BASE );
    reg( OscT_VME );
    reg( OscS_HPU );
    reg( OscS_BASE );
    reg( OscS_VME );
 
    reg( STerm_Osc_HPU );
    reg( STerm_Osc_BASE );
    reg( STerm_BOOT_CLK );
 
    reg( Syn_RCLK );
    reg( Syn_SCLK );
    reg( Syn_TCLK );
    reg( Syn_DCLK );
    reg( Syn_DC_CLK );
    reg( Syn_DX_CLK );
    reg( Syn_HPU_CLK );
    reg( Syn_DPU_CLK );
    reg( Syn_DXINT_CLK );
 
    reg( Mux_RCLK );
    reg( Mux_SCLK );
    reg( Mux_TCLK );
    reg( Mux_DCLK );
    reg( Mux_DC_CLK );
    reg( Mux_DX_CLK );
    reg( Mux_HPU_CLK );
    reg( Mux_SYN_BASE );
 
    reg( SMux_RCLK );
    reg( SMux_TCLK );
    reg( SMux_HPU_CLK );
    reg( SMux_SYN_BASE );
 
    reg( Mpy_IRCLK );
    reg( Mpy_ISCLK );
    reg( Mpy_ITCLK );
 
    reg( STerm_Mpy_IRCLK );
    reg( STerm_Mpy_ISCLK );
    reg( STerm_Mpy_ITCLK );
 
    reg( Drv_IRCLK );
    reg( Drv_ISCLK );
    reg( Drv_ITCLK );
    reg( Drv_SYN_BASE );
 
    reg( Drv_RCLK0 );
    reg( Drv_SCLK  );
    reg( Drv_TCLK  );
    reg( Drv_DCLK  );
    reg( Drv_DC_CLK );
    reg( Drv_DX_CLK );
    reg( Drv_HPU_CLK );
    reg( Drv_DPU_CLK );
    reg( Drv_DXINT_CLK );
    reg( Drv_VME_CLK );
 
    reg( Drv_BP_RCLKO );
    reg( Drv_BP_SCLKO );
    reg( Drv_BP_TCLKO );
    reg( Drv_BP_DCLKO );
 
    reg( Rcv_BP_RCLKI );
    reg( Rcv_BP_TCLKI );
    reg( Rcv_FP_RCLKI );
    reg( Rcv_FP_TCLKI );
 
    reg( Drv_RCLK1    );       // register this one here to preserve existing reference designators
 
    reg( DTerm_BP_RCLKI );
    reg( DTerm_BP_TCLKI );
    reg( DTerm_FP_RCLKI );
    reg( DTerm_FP_TCLKI );
 
    reg( STerm_BP_RCLKI );
    reg( STerm_BP_TCLKI );
    reg( STerm_FP_RCLKI );
    reg( STerm_FP_TCLKI );
    reg( STerm_DERIVED_BASE );
 
    reg(  CLC_IRCLK  );
    reg(  CLC_ISCLK  );
    reg(  CLC_ITCLK  );
    reg(  CLC_DC_CLK );
    rega( CLC, clc_count );
 
    reg( PulldownSyn_HPU );
    reg( PullupOsc_BASE );
    reg( PullupVB_OE );
    reg( SeriesVCOK );
 
    rega( Mono,     mono_count );
 
    rega( Ferrite,  ferrite_count );
    rega( AVCC_CDC, ferrite_count );
 
    rega( VC_CDC, vc_cdc_count );
    rega( VC_TDC, vc_tdc_count );
    rega( OSC_CDC, 3 );
  }

  void ConnectDefault( CP_SN74CBTLV3253& Mux ) {   // wiring that is similar for several components
    GND        << Mux.OE1_N  << Mux.OE2_N;         // always OE'd
    merge( GND,   Mux.B2 );                        // mux 2 never used
    "/NC"      << Mux.A2;
  }
 
  virtual void Connect() {    // wiring proceeds approximately left to right, top to bottom of Clock Generation block diagram
    wireall( MB_VCC, "VCC" );
    wireall( GND );
    wireall( GND, "AGND" );   // CDC25xx parts have AGND pins
 
    for ( int i = 0; i < vc_cdc_count; ++ i )  MB_VCC << VC_CDC[ i ].POS;
    for ( int i = 0; i < vc_tdc_count; ++ i )  MB_VCC << VC_TDC[ i ].POS;
 
    // crystal oscillators and all devices containing PLL:  wire AVCC via ferrite bead
    int f = 0;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC0"   <<  AVCC_CDC[ f ].POS  <<      Drv_RCLK0.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC1"   <<  AVCC_CDC[ f ].POS  <<      Drv_RCLK1.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC2"   <<  AVCC_CDC[ f ].POS  <<       Drv_SCLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC3"   <<  AVCC_CDC[ f ].POS  <<       Drv_TCLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC4"   <<  AVCC_CDC[ f ].POS  <<       Drv_DCLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC5"   <<  AVCC_CDC[ f ].POS  <<     Drv_DC_CLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC6"   <<  AVCC_CDC[ f ].POS  <<     Drv_DX_CLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC7"   <<  AVCC_CDC[ f ].POS  <<    Drv_HPU_CLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC8"   <<  AVCC_CDC[ f ].POS  <<    Drv_DPU_CLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC9"   <<  AVCC_CDC[ f ].POS  <<  Drv_DXINT_CLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC10"  <<  AVCC_CDC[ f ].POS  <<    Drv_VME_CLK.AVCC;  f++;
 
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC11"  <<  AVCC_CDC[ f ].POS  <<      Mpy_IRCLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC12"  <<  AVCC_CDC[ f ].POS  <<      Mpy_ISCLK.AVCC;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC13"  <<  AVCC_CDC[ f ].POS  <<      Mpy_ITCLK.AVCC;  f++;
 
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC14"  <<  AVCC_CDC[ f ].POS  <<   OscT_HPU.AVCC  <<   OscS_HPU.AVCC  <<  OSC_CDC[ 0 ].POS;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC15"  <<  AVCC_CDC[ f ].POS  <<  OscT_BASE.AVCC  <<  OscS_BASE.AVCC  <<  OSC_CDC[ 1 ].POS;  f++;
    MB_VCC  ^  Ferrite[ f ]  ^  "AVCC16"  <<  AVCC_CDC[ f ].POS  <<   OscT_VME.AVCC  <<   OscS_VME.AVCC  <<  OSC_CDC[ 2 ].POS;  f++;
 
 
// same for all muxes:
    ConnectDefault( Mux_RCLK      );
    ConnectDefault( Mux_SCLK      );
    ConnectDefault( Mux_TCLK      );
    ConnectDefault( Mux_DCLK      );
    ConnectDefault( Mux_DC_CLK    );
    ConnectDefault( Mux_DX_CLK    );
    ConnectDefault( Mux_HPU_CLK   );
    ConnectDefault( Mux_SYN_BASE  );
    ConnectDefault( SMux_RCLK     );
    ConnectDefault( SMux_TCLK     );
    ConnectDefault( SMux_HPU_CLK  );
    ConnectDefault( SMux_SYN_BASE );
 
// PLD's
    VME.SOFTRESET_N  <<  NoisyPLD.SOFTRESET_N;
    VME.SOFTRESET_N  <<  QuietPLD.SOFTRESET_N;
 
    JT.NoisyPLD      <<  NoisyPLD.JTAG;    // JTAG for PLD ISP and boundary scan
    JT.QuietPLD      <<  QuietPLD.JTAG;
    JT.PROGRAM_N     <<  NoisyPLD.PROGRAM_N;  // one PROGRAM_N line for each FPGA on the motherboard except HPU FPGA's
 
    wire( HO, NoisyPLD );   // host EMIF to Noisy PLD
 
    "QD"         <<  NoisyPLD.QD      <<  QuietPLD.QD;      // quiet version of host EMIF
    "QA"         <<  NoisyPLD.QA      <<  QuietPLD.QA;
    "QWR_N"      <<  NoisyPLD.QWR_N   <<  QuietPLD.QWR_N;
    "QSTB_N"     <<  NoisyPLD.QSTB_N  <<  QuietPLD.QSTB_N;
 
    "OSC_BASE"   <<  NoisyPLD.BASE_CLK;   // 25 MHz input clock
 
    VME.BOOT_CLK  ^  STerm_BOOT_CLK  ^  "LOC_BOOT_CLOCK"  <<  NoisyPLD.BOOT_CLK;
 
 
    // NoisyPLD.MEAS_IN:  see connections below
 
    "QPLD_IRCLK"        <<  QuietPLD.IRCLK  <<  Drv_IRCLK.OUT( 8 );   // can be used by PLD to generate DERIVED_BASE
    "QPLD_ISCLK"        <<  QuietPLD.ISCLK  <<  Drv_ISCLK.OUT( 8 );
    "QPLD_ITCLK"        <<  QuietPLD.ITCLK  <<  Drv_ITCLK.OUT( 8 );
 
    "DERIVED_BASE"      ^ STerm_DERIVED_BASE ^  "LOC_DERIVED_BASE"  <<  QuietPLD.DERIVED_BASE;         // attached below to Mux_SYN_BASE
 
    "MUXA_RCLK"         <<  QuietPLD.MuxA_RCLK         <<  Mux_RCLK.S;
    "MUXA_SCLK"         <<  QuietPLD.MuxA_SCLK         <<  Mux_SCLK.S;
    "MUXA_TCLK"         <<  QuietPLD.MuxA_TCLK         <<  Mux_TCLK.S;
    "MUXA_DCLK"         <<  QuietPLD.MuxA_DCLK         <<  Mux_DCLK.S;
    "MUXA_DC_CLK"       <<  QuietPLD.MuxA_DC_CLK       <<  Mux_DC_CLK.S;
    "MUXA_DX_CLK"       <<  QuietPLD.MuxA_DX_CLK       <<  Mux_DX_CLK.S;
    "MUXA_HPU_CLK"      <<  QuietPLD.MuxA_HPU_CLK      <<  Mux_HPU_CLK.S(  1 );     // see below:  S( 0 ) tied high
    "MUXA_SYN_BASE"     <<  QuietPLD.MuxA_SYN_BASE     <<  Mux_SYN_BASE.S( 1 );     // see below:  S( 0 ) tied high
 
    "SMUXA_RCLK"        <<  QuietPLD.SMuxA_RCLK        <<  SMux_RCLK.S;
    "SMUXA_TCLK"        <<  QuietPLD.SMuxA_TCLK        <<  SMux_TCLK.S;
 
    "MPYFS_IRCLK"       <<  QuietPLD.MpyFS_IRCLK       <<  Mpy_IRCLK.FS;
    "MPYFS_ISCLK"       <<  QuietPLD.MpyFS_ISCLK       <<  Mpy_ISCLK.FS;
    "MPYFS_ITCLK"       <<  QuietPLD.MpyFS_ITCLK       <<  Mpy_ITCLK.FS;
 
    "DRVSCK_IRCLK"      <<  QuietPLD.DrvSCK_IRCLK      <<  Drv_IRCLK.SCLOCK;
    "DRVSCK_ISCLK"      <<  QuietPLD.DrvSCK_ISCLK      <<  Drv_ISCLK.SCLOCK;
    "DRVSCK_ITCLK"      <<  QuietPLD.DrvSCK_ITCLK      <<  Drv_ITCLK.SCLOCK;
    "DRVSCK_SYN_BASE"   <<  QuietPLD.DrvSCK_SYN_BASE   <<  Drv_SYN_BASE.SCLOCK;
 
    "SYNSCK_RCLK"       <<  QuietPLD.SynSCK_RCLK       <<  Syn_RCLK.SCLOCK;
    "SYNSCK_SCLK"       <<  QuietPLD.SynSCK_SCLK       <<  Syn_SCLK.SCLOCK;
    "SYNSCK_TCLK"       <<  QuietPLD.SynSCK_TCLK       <<  Syn_TCLK.SCLOCK;
    "SYNSCK_DCLK"       <<  QuietPLD.SynSCK_DCLK       <<  Syn_DCLK.SCLOCK;
    "SYNSCK_DC_CLK"     <<  QuietPLD.SynSCK_DC_CLK     <<  Syn_DC_CLK.SCLOCK;
    "SYNSCK_DX_CLK"     <<  QuietPLD.SynSCK_DX_CLK     <<  Syn_DX_CLK.SCLOCK;
    "SYNSCK_HPU_CLK"    <<  QuietPLD.SynSCK_HPU_CLK    <<  Syn_HPU_CLK.SCLOCK;
    "SYNSCK_DPU_CLK"    <<  QuietPLD.SynSCK_DPU_CLK    <<  Syn_DPU_CLK.SCLOCK;
    "SYNSCK_DXINT_CLK"  <<  QuietPLD.SynSCK_DXINT_CLK  <<  Syn_DXINT_CLK.SCLOCK;
 
    "SYNSEL_CD"         <<  QuietPLD.SynSEL_CD;   // see connections below
    "SD"                <<  QuietPLD.SD;          // see connections below
    "OSCOE_HPU"         <<  QuietPLD.OscOE_HPU;   // see connections below
 
// CDC319 serial data
    "SD"             <<      Drv_IRCLK.SDATA
                     <<      Drv_ISCLK.SDATA
                     <<      Drv_ITCLK.SDATA
                     <<   Drv_SYN_BASE.SDATA;
 
// synthesizer controls:
    "SD"             <<       Syn_RCLK.SDATA
                     <<       Syn_SCLK.SDATA
                     <<       Syn_TCLK.SDATA
                     <<       Syn_DCLK.SDATA
                     <<     Syn_DC_CLK.SDATA
                     <<     Syn_DX_CLK.SDATA
                     <<    Syn_HPU_CLK.SDATA
                     <<    Syn_DPU_CLK.SDATA
                     <<  Syn_DXINT_CLK.SDATA;
 
    "SYNSEL_CD"      <<       Syn_RCLK.SEL_CD
                     <<       Syn_SCLK.SEL_CD
                     <<       Syn_TCLK.SEL_CD
                     <<       Syn_DCLK.SEL_CD
                     <<     Syn_DC_CLK.SEL_CD
                     <<     Syn_DX_CLK.SEL_CD
                     <<    Syn_HPU_CLK.SEL_CD
                     <<    Syn_DPU_CLK.SEL_CD
                     <<  Syn_DXINT_CLK.SEL_CD;
 
 
// synthesizer outputs:
    "SYN_RCLK"       <<       Syn_RCLK.OUT;
    "SYN_SCLK"       <<       Syn_SCLK.OUT;
    "SYN_TCLK"       <<       Syn_TCLK.OUT;
    "SYN_DCLK"       <<       Syn_DCLK.OUT;
    "SYN_DC_CLK"     <<     Syn_DC_CLK.OUT;
    "SYN_DX_CLK"     <<     Syn_DX_CLK.OUT;
    "SYN_HPU_CLK"    <<    Syn_HPU_CLK.OUT  ^  PulldownSyn_HPU  ^  GND;  // pulldown in case output is floated
    "SYN_DPU_CLK"    <<    Syn_DPU_CLK.OUT;
    "SYN_DXINT_CLK"  <<  Syn_DXINT_CLK.OUT;
 
 
// synthesizer OE's -- all synthesizers permanently OE'd except for HPU_CLK
    "/NC" << Syn_RCLK.OE;
    "/NC" << Syn_SCLK.OE;
    "/NC" << Syn_TCLK.OE;
    "/NC" << Syn_DCLK.OE;
    "/NC" << Syn_DC_CLK.OE;
    "/NC" << Syn_DX_CLK.OE;
    "/NC" << Syn_DPU_CLK.OE;
    "/NC" << Syn_DXINT_CLK.OE;
 
// CDC319 OE's -- these drivers are always OE'd (never tristated)
    "/NC" << Drv_IRCLK.OE;
    "/NC" << Drv_ISCLK.OE;
    "/NC" << Drv_ITCLK.OE;
    "/NC" << Drv_SYN_BASE.OE;
 
 
// oscillator outputs via series termination:
// install only one oscillator (OscT... or OscS...)
    "OSC_HPU"   ^  STerm_Osc_HPU   ^  "LOC_OSC_HPU"  <<  OscT_HPU.OUT <<  OscS_HPU.OUT;
    "OSC_BASE"  ^  STerm_Osc_BASE  ^  "LOC_OSC_BASE" << OscT_BASE.OUT << OscS_BASE.OUT;
    "OSC_VME"                                        <<  OscT_VME.OUT <<  OscS_VME.OUT;
 
    "OSCOE_HPU"  <<   OscT_HPU.OE  <<   OscS_HPU.OE;
 
// series termination for internal clocks
 
    "IRCLK" << Drv_IRCLK.OUT( 4, 0 );
    "ISCLK" << Drv_ISCLK.OUT( 4, 0 );
    "ITCLK" << Drv_ITCLK.OUT( 4, 0 );
 
    merge( "/NC", Drv_IRCLK.OUT(     7,  5 ) );
    merge( "/NC", Drv_ISCLK.OUT(     7,  5 ) );
    merge( "/NC", Drv_ITCLK.OUT(     7,  5 ) );
                                 // 8  is sent to QuietPLD as possible source of DERIVED_BASE
                                 // 9  is used for feedback
 
// **** RCLK ****
    SMux_RCLK.B1( 0 )  <<  GND;                // secondary mux
    SMux_RCLK.B1( 1 )  <<  "BP_RCLKI";
    SMux_RCLK.B1( 2 )  <<  GND;
    SMux_RCLK.B1( 3 )  <<  "FP_RCLKI";
    SMux_RCLK.A1       <<  "EXT_RCLK";
 
    Mux_RCLK.B1(  0 )  <<  "EXT_RCLK";         // primary mux
    Mux_RCLK.B1(  1 )  <<  Drv_ISCLK.OUT( 3 );  // SCLK
    Mux_RCLK.B1(  2 )  <<  Drv_ITCLK.OUT( 3 );  // TCLK
    Mux_RCLK.B1(  3 )  <<  "SYN_RCLK";         // synthesizer
    Mux_RCLK.A1        <<  "DRVIN_RCLK";       // to driver
 
 
// **** SCLK ****
    // no secondary mux for SCLK
    Mux_SCLK.B1(  0 )  <<  GND;                // primary mux
    Mux_SCLK.B1(  1 )  <<  Drv_IRCLK.OUT( 3 );  // RCLK
    Mux_SCLK.B1(  2 )  <<  Drv_ITCLK.OUT( 4 );  // TCLK
    Mux_SCLK.B1(  3 )  <<  "SYN_SCLK";         // synthesizer
    Mux_SCLK.A1        <<  "DRVIN_SCLK";       // to driver
 
 
// **** TCLK ****
    SMux_TCLK.B1( 0 )  <<  GND;                // secondary mux
    SMux_TCLK.B1( 1 )  <<  "BP_TCLKI";
    SMux_TCLK.B1( 2 )  <<  GND;
    SMux_TCLK.B1( 3 )  <<  "FP_TCLKI";
    SMux_TCLK.A1       <<  "EXT_TCLK";
 
    Mux_TCLK.B1(  0 )  <<  "EXT_TCLK";         // primary mux
    Mux_TCLK.B1(  1 )  <<  Drv_IRCLK.OUT( 4 );  // SCLK
    Mux_TCLK.B1(  2 )  <<  Drv_ISCLK.OUT( 4 );  // TCLK
    Mux_TCLK.B1(  3 )  <<  "SYN_TCLK";         // synthesizer
    Mux_TCLK.A1        <<  "DRVIN_TCLK";       // to driver
 
 
// **** DCLK ****
    Mux_DCLK.B1(  0 )  <<  Drv_IRCLK.OUT( 0 );  // RCLK
    Mux_DCLK.B1(  1 )  <<  Drv_ISCLK.OUT( 0 );  // SCLK
    Mux_DCLK.B1(  2 )  <<  Drv_ITCLK.OUT( 0 );  // TCLK
    Mux_DCLK.B1(  3 )  <<  "SYN_DCLK";         // synthesizer
    Mux_DCLK.A1        <<  "DRVIN_DCLK";       // to driver
 
 
// **** DC_CLK ****
    Mux_DC_CLK.B1(  0 )  <<  Drv_IRCLK.OUT( 1 );  // RCLK
    Mux_DC_CLK.B1(  1 )  <<  Drv_ISCLK.OUT( 1 );  // SCLK
    Mux_DC_CLK.B1(  2 )  <<  Drv_ITCLK.OUT( 1 );  // TCLK
    Mux_DC_CLK.B1(  3 )  <<  "SYN_DC_CLK";       // synthesizer
    Mux_DC_CLK.A1        <<  "DRVIN_DC_CLK";     // to driver
 
 
// **** DX_CLK ****
    Mux_DX_CLK.B1(  0 )  <<  Drv_IRCLK.OUT( 2 );  // RCLK
    Mux_DX_CLK.B1(  1 )  <<  Drv_ISCLK.OUT( 2 );  // SCLK
    Mux_DX_CLK.B1(  2 )  <<  Drv_ITCLK.OUT( 2 );  // TCLK
    Mux_DX_CLK.B1(  3 )  <<  "SYN_DX_CLK";       // synthesizer
    Mux_DX_CLK.A1        <<  "DRVIN_DX_CLK";     // to driver
 
 
// **** HPU_CLK ****
// both mux's share the same single address line: S1;
    SMux_HPU_CLK.B1( 0 )  <<  GND;                   // secondary mux, necessary only to prevent oscillator from causing jitter on synthesizer-based clock
    SMux_HPU_CLK.B1( 1 )  <<  "OSC_HPU";             // oscillator via resistor
    SMux_HPU_CLK.B1( 2 )  <<  GND;
    SMux_HPU_CLK.B1( 3 )  <<  GND;
    SMux_HPU_CLK.A1       <<  "SMUX_HPU_CLK";
 
    Mux_HPU_CLK.B1(  0 )  <<  GND;                   // primary mux
    Mux_HPU_CLK.B1(  1 )  <<  "SMUX_HPU_CLK";
    Mux_HPU_CLK.B1(  2 )  <<  GND;
    Mux_HPU_CLK.B1(  3 )  <<  "SYN_HPU_CLK";         // synthesizer
    Mux_HPU_CLK.A1        <<  "DRVIN_HPU_CLK";       // to driver
 
     // only address 1 and address 3 are allowed, synthesizer's ouput is disabled when on address 1
    MB_VCC << Mux_HPU_CLK.S( 0 )  <<  SMux_HPU_CLK.S( 0 );     // only odd addresses are allowed
              Mux_HPU_CLK.S( 1 )  <<  SMux_HPU_CLK.S( 1 )  << Syn_HPU_CLK.OE;
 
 
// **** DPU_CLK ****
// no mux, driver input is directly from synthesizer
 
// **** DXINT_CLK ****
// no mux, driver input is directly from synthesizer
 
// **** VME_CLK ****
// no mux, driver input is directly from oscillator
 
 
// **** SYN_BASE ****  base clock for all synthesizers
// both mux's share the same single address line: S1;
    SMux_SYN_BASE.B1( 0 )  <<  GND;                // secondary mux, necessary only to prevent oscillator from causing jitter on synthesizer-based clock
    SMux_SYN_BASE.B1( 1 )  <<  "OSC_BASE";         // oscillator via resistor
    SMux_SYN_BASE.B1( 2 )  <<  GND;
    SMux_SYN_BASE.B1( 3 )  <<  GND;
    SMux_SYN_BASE.A1       <<  "SMUX_SYN_BASE";
 
    Mux_SYN_BASE.B1(  0 )  <<  GND;                // primary mux
    Mux_SYN_BASE.B1(  1 )  <<  "SMUX_SYN_BASE";
    Mux_SYN_BASE.B1(  2 )  <<  GND;
    Mux_SYN_BASE.B1(  3 )  <<  "DERIVED_BASE";     // PLD output derived from RCLK, SCLK or TCLK (via series terminator)
    Mux_SYN_BASE.A1        <<  "DRVIN_SYN_BASE";   // to driver
 
    MB_VCC << Mux_SYN_BASE.S( 0 ) << SMux_SYN_BASE.S( 0 );    // only odd addresses are allowed
              Mux_SYN_BASE.S( 1 ) << SMux_SYN_BASE.S( 1 );     // select between address 1 and address 3
 
// SYN_BASE output to synthesizers
    "DC_SYN_BASE"          <<  Drv_SYN_BASE.OUT;     // SYN_BASE after series termination but before AC couple
    Drv_SYN_BASE.OUT( 0 )  <<  Syn_RCLK.IN;
    Drv_SYN_BASE.OUT( 1 )  <<  Syn_SCLK.IN;
    Drv_SYN_BASE.OUT( 2 )  <<  Syn_TCLK.IN;
    Drv_SYN_BASE.OUT( 3 )  <<  Syn_DCLK.IN;
    Drv_SYN_BASE.OUT( 4 )  <<  Syn_DC_CLK.IN;
    Drv_SYN_BASE.OUT( 5 )  <<  Syn_DX_CLK.IN;
    Drv_SYN_BASE.OUT( 6 )  <<  Syn_DPU_CLK.IN;
    Drv_SYN_BASE.OUT( 7 )  <<  Syn_DXINT_CLK.IN;
    Drv_SYN_BASE.OUT( 8 )  <<  "/NC";
    Drv_SYN_BASE.OUT( 9 )  <<  Syn_HPU_CLK.IN;       // put HPU clock in separate I2C register of CDC319
 
 
 
// **** drivers ****
 
// Disabling clocks:
//  VME_CLK (driver) and BASE_CLK (oscillator) can be disabled via a front panel DIP Switch (to disable them during PLD ISP)
//  all other clocks (except JTAG, Emulator, and FPGA configuration clocks) are disabled:
//    1. via front-panel DIPSW (shorts driver G's to GND) (e.g., during JTAG), or
//    2. when DSP_VCOK is false (DSP_VCOK is attached to all G's via 1K resistor) (prevents clocks from driving non-powered DSP's)
 
    "CLK_OE"  ^ SeriesVCOK ^  PWR.DSP_VCOK;
    "CLK_OE"  <<  FP.CKOE_DIPSW;          // dip switch can ground CLK_OE to override DSP_VCOK
 
                                          // CDC2516/CDC2510 input leakage current is 5 uA.  5uA * 22 * 1kohm = .11V
    merge( "CLK_OE", Drv_RCLK0.G );       // driver .G's force outputs to low state
    merge( "CLK_OE", Drv_RCLK1.G );
    merge( "CLK_OE", Drv_SCLK.G );
    merge( "CLK_OE", Drv_TCLK.G );
    merge( "CLK_OE", Drv_DCLK.G );
    merge( "CLK_OE", Drv_DC_CLK.G );
    merge( "CLK_OE", Drv_DX_CLK.G );
    merge( "CLK_OE", Drv_HPU_CLK.G );
    merge( "CLK_OE", Drv_DPU_CLK.G );
    merge( "CLK_OE", Drv_DXINT_CLK.G );
 
    // Drv_VME_CLK must be active before DSP_VCOK, because VME can be used to turn on DSP power (which is necessary for DSP_VCOK to be active)
 
     OscT_BASE.OUT              ^ PullupOsc_BASE ^  MB_VCC;   // pullup in case Osc_BASE output is floated
    "VB_OE"  <<  FP.VBOE_DIPSW  ^ PullupVB_OE    ^  MB_VCC;   // dip switch signal for enabling VME_CLK and BASE_CLK (BASE_OSC)
    "VB_OE"  <<  OscT_BASE.OE  <<  OscS_BASE.OE;              // oscillator .OE's float output
 
    merge( "VB_OE",  Drv_VME_CLK.G );
    "/NC"  <<  OscT_VME.OE  <<  OscS_VME.OE;                  // VME oscillator is always OE'd
 
 
// multiplier input
    "FB_RCLK0"      <<   Mpy_IRCLK.IN;  // all other outputs used -> use FBOUT  >>> place Mpy_IRCLK near Drv_RCLK
    "MPYI_SCLK"     <<   Mpy_ISCLK.IN;
    "MPYI_TCLK"     <<   Mpy_ITCLK.IN;
 
// driver input
//              multiplier output    series termination                  driver input
    "MPY_IRCLK" << Mpy_IRCLK.OUT1  ^  STerm_Mpy_IRCLK  ^  "DRVIN_IRCLK" << Drv_IRCLK.IN;
    "MPY_ISCLK" << Mpy_ISCLK.OUT1  ^  STerm_Mpy_ISCLK  ^  "DRVIN_ISCLK" << Drv_ISCLK.IN;
    "MPY_ITCLK" << Mpy_ITCLK.OUT1  ^  STerm_Mpy_ITCLK  ^  "DRVIN_ITCLK" << Drv_ITCLK.IN;
    "/NC"       << Mpy_IRCLK.OUT2;
    "/NC"       << Mpy_ISCLK.OUT2;
    "/NC"       << Mpy_ITCLK.OUT2;
 
    "DRVIN_RCLK"      <<  Drv_RCLK0.IN;
    "DRVIN_RCLK"      <<  Drv_RCLK1.IN;    // >>> place Drv_RCLK0 near Drv_RCLK1
    "DRVIN_SCLK"      <<  Drv_SCLK.IN;
    "DRVIN_TCLK"      <<  Drv_TCLK.IN;
    "DRVIN_DCLK"      <<  Drv_DCLK.IN;
    "DRVIN_DC_CLK"    <<  Drv_DC_CLK.IN;
    "DRVIN_DX_CLK"    <<  Drv_DX_CLK.IN;
    "DRVIN_HPU_CLK"   <<  Drv_HPU_CLK.IN;
    "SYN_DPU_CLK"     <<  Drv_DPU_CLK.IN;
    "SYN_DXINT_CLK"   <<  Drv_DXINT_CLK.IN;
    "OSC_VME"         <<  Drv_VME_CLK.IN;
    "DRVIN_SYN_BASE"  <<  Drv_SYN_BASE.IN;
 
// driver feedback (some with load capacitors)
    "FB_IRCLK"      <<      Drv_IRCLK.OUT( 9 )  <<    Mpy_IRCLK.FBIN ^ CLC_IRCLK  ^ GND;
    "FB_ISCLK"      <<      Drv_ISCLK.OUT( 9 )  <<    Mpy_ISCLK.FBIN ^ CLC_ISCLK  ^ GND;
    "FB_ITCLK"      <<      Drv_ITCLK.OUT( 9 )  <<    Mpy_ITCLK.FBIN ^ CLC_ITCLK  ^ GND;
 
    "FB_RCLK0"      <<      Drv_RCLK0.FBOUT   <<      Drv_RCLK0.FBIN;
    "FB_RCLK1"      <<      Drv_RCLK1.FBOUT   <<      Drv_RCLK1.FBIN;
    "FB_SCLK"       <<       Drv_SCLK.FBOUT   <<       Drv_SCLK.FBIN;
    "FB_TCLK"       <<       Drv_TCLK.FBOUT   <<       Drv_TCLK.FBIN;
    "FB_DCLK"       <<       Drv_DCLK.FBOUT   <<       Drv_DCLK.FBIN;
    "FB_DC_CLK"     <<     Drv_DC_CLK.FBOUT   <<     Drv_DC_CLK.FBIN;
    "FB_DX_CLK"     <<     Drv_DX_CLK.FBOUT   <<     Drv_DX_CLK.FBIN;
 
    "FB_HPU_CLK"    <<    Drv_HPU_CLK.FBOUT   <<    Drv_HPU_CLK.FBIN;
    "FB_DPU_CLK"    <<    Drv_DPU_CLK.FBOUT   <<    Drv_DPU_CLK.FBIN;
    "FB_DXINT_CLK"  <<  Drv_DXINT_CLK.FBOUT   <<  Drv_DXINT_CLK.FBIN;
    "FB_VME_CLK"    <<    Drv_VME_CLK.FBOUT   <<    Drv_VME_CLK.FBIN;
 
 
// connect clocks to interfaces to other subsytems
// i and n are used to automate bus indexing
// the order of the statements makes bus assignments reasonably consistent among several clocks
    int i = 0, n = 0, m = 0, clc = 0;
    n = 6;  Drv_RCLK0.OUT(    i+n-1, i  )  <<   A.RCLK;         i+=n;     // single RCLK driver was replaced with two drivers, 6-08-01
    n = 4;  Drv_RCLK0.OUT(    i+n-1, i  )  <<   B.RCLK( 3, 0 ); i+=n;
 
    i = 0;
            Drv_RCLK1.OUT(           i++)  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_RCLK";
    n = 1;  Drv_RCLK1.OUT(    i+n-1, i  )  <<  DC.RCLK;             i+=n;
    n = 1;  Drv_RCLK1.OUT(    i+n-1, i  )  <<  HO.RCLK;             i+=n;
    n = 2;  Drv_RCLK1.OUT(    i+n-1, i  )  <<   B.RCLK( 5, 4 );     i+=n;
    n = 4;  Drv_RCLK1.OUT(    i+n-1, i  )  <<  IC.RCLK;             i+=n;
                                                                  // see backplane LVDS drivers below
    DC.RCLK      ^ CLC[ clc++ ] ^ GND;        // load capacitor: DC.RCLK has only one load, increase to two
    IC.RCLK( 3 ) ^ CLC[ clc++ ] ^ GND;        // load capacitor: IC.RCLK( 3 ) has only one load (TTC_FPGA)
 
 
    i = 0;
            Drv_DX_CLK.OUT(         i++)  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_DX_CLK";
    n = 1;  Drv_DX_CLK.OUT(  i+n-1, i  )  <<  DC.DX_CLK;       i+=n;
    n = 1;  Drv_DX_CLK.OUT(  i+n-1, i  )  <<  HO.DX_CLK;       i+=n;
                                                                     // for best layout, some clocks are dedicated, others paired
            Drv_DX_CLK.OUT(         i  )  <<   B.DX_CLK( 0 );  i++;  // dedicated B0
            Drv_DX_CLK.OUT(         i  )  <<   B.DX_CLK( 1 )         // pair      B1, B2
                                          <<   B.DX_CLK( 2 );  i++;
            Drv_DX_CLK.OUT(         i  )  <<   B.DX_CLK( 3 )         // pair      B3, B4
                                          <<   B.DX_CLK( 4 );  i++;
            Drv_DX_CLK.OUT(         i  )  <<   B.DX_CLK( 5 )         // pair      B5, A0
                                          <<   A.DX_CLK( 0 );  i++;
            Drv_DX_CLK.OUT(         i  )  <<   A.DX_CLK( 1 )         // pair      A1, A2
                                          <<   A.DX_CLK( 2 );  i++;
            Drv_DX_CLK.OUT(         i  )  <<   A.DX_CLK( 3 )         // pair      A3, A4
                                          <<   A.DX_CLK( 4 );  i++;
            Drv_DX_CLK.OUT(         i  )  <<   A.DX_CLK( 5 );  i++;  // dedicated A5
    n = 2;  Drv_DX_CLK.OUT(  i+n-1, i  )  <<  DX.DX_CLK;       i+=n;
    merge( "/NC", Drv_DX_CLK.OUT( 15, i  ) );
 
    DC.DX_CLK      ^ CLC[ clc++ ] ^ GND;        // load capacitor: DC.DX_CLK    has only one load
    HO.DX_CLK      ^ CLC[ clc++ ] ^ GND;        // load capacitor: HO.DX_CLK    has only one load
    DX.DX_CLK( 1 ) ^ CLC[ clc++ ] ^ GND;        // load capacitor: DX.DX_CLK(1) has only one load (DXB_FPGA)
// see below for load capacitors for dedicated clocks
 
 
    i = 0;
            Drv_SCLK.OUT(           i++)  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_SCLK";
    n = 1;  Drv_SCLK.OUT(    i+n-1, i  )  <<  DC.SCLK;     i+=n;
    n = 1;  Drv_SCLK.OUT(    i+n-1, i  )  <<  HO.SCLK;     i+=n;
                                                                   // for best layout, some clocks are dedicated, others paired
            Drv_SCLK.OUT(           i  )  <<   B.SCLK( 0 );  i++;  // dedicated B0
            Drv_SCLK.OUT(           i  )  <<   B.SCLK( 1 )         // pair      B1, B2
                                          <<   B.SCLK( 2 );  i++;
            Drv_SCLK.OUT(           i  )  <<   B.SCLK( 3 )         // pair      B3, B4
                                          <<   B.SCLK( 4 );  i++;
            Drv_SCLK.OUT(           i  )  <<   B.SCLK( 5 )         // pair      B5, A0
                                          <<   A.SCLK( 0 );  i++;
            Drv_SCLK.OUT(           i  )  <<   A.SCLK( 1 )         // pair      A1, A2
                                          <<   A.SCLK( 2 );  i++;
            Drv_SCLK.OUT(           i  )  <<   A.SCLK( 3 )         // pair      A3, A4
                                          <<   A.SCLK( 4 );  i++;
            Drv_SCLK.OUT(           i  )  <<   A.SCLK( 5 );  i++;  // dedicated A5
    n = 4;  Drv_SCLK.OUT(    i+n-1, i  )  <<  IC.SCLK;     i+=n;
    n = 1;  Drv_SCLK.OUT(    i+n-1, i  )  <<  "MPYI_SCLK"; i+=n; // output to multiplier
                                                                 // see backplane LVDS drivers below
 
    DC.SCLK      ^ CLC[ clc++ ] ^ GND;        // load capacitor: DC.SCLK has only one load
    IC.SCLK( 3 ) ^ CLC[ clc++ ] ^ GND;        // load capacitor: IC.SCLK( 3 ) has only one load (TTC_FPGA)
// see below for load capacitors for dedicated clocks
 
 
    i = 0;
            Drv_DC_CLK.OUT(         i++)  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_DC_CLK";
    n = 1;  Drv_DC_CLK.OUT(  i+n-1, i  )  <<  DC.DC_CLK;   i+=n;
    n = 1;  Drv_DC_CLK.OUT(  i+n-1, i  )  <<  HO.DC_CLK;   i+=n;
    n = 6;  Drv_DC_CLK.OUT(  i+n-1, i  )  <<   A.DC_CLK;   i+=n;
    n = 6;  Drv_DC_CLK.OUT(  i+n-1, i  )  <<   B.DC_CLK;   i+=n;
    merge( "/NC", Drv_DC_CLK.OUT( 15, i  ) );
    DC.DC_CLK ^ CLC_DC_CLK ^ GND;        // load capacitor: DPU's have 4 loads, DC.DC_CLK has only one load
 
 
    i = 0;
            Drv_DPU_CLK.OUT(           i++)  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_DPU_CLK";
                                                                         // for best layout, some clocks are dedicated, others paired
            Drv_DPU_CLK.OUT(           i  )  <<   B.DPU_CLK( 0 );  i++;  // dedicated B0
            Drv_DPU_CLK.OUT(           i  )  <<   B.DPU_CLK( 1 )         // pair      B1, B2
                                             <<   B.DPU_CLK( 2 );  i++;
            Drv_DPU_CLK.OUT(           i  )  <<   B.DPU_CLK( 3 )         // pair      B3, B4
                                             <<   B.DPU_CLK( 4 );  i++;
            Drv_DPU_CLK.OUT(           i  )  <<   B.DPU_CLK( 5 )         // pair      B5, A0
                                             <<   A.DPU_CLK( 0 );  i++;
            Drv_DPU_CLK.OUT(           i  )  <<   A.DPU_CLK( 1 )         // pair      A1, A2
                                             <<   A.DPU_CLK( 2 );  i++;
            Drv_DPU_CLK.OUT(           i  )  <<   A.DPU_CLK( 3 )         // pair      A3, A4
                                             <<   A.DPU_CLK( 4 );  i++;
            Drv_DPU_CLK.OUT(           i  )  <<   A.DPU_CLK( 5 );  i++;  // dedicated A5
    merge( "/NC", Drv_DPU_CLK.OUT(  9, i  ) );
 
    Drv_TCLK.OUT(         0 )  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_TCLK";
    Drv_DCLK.OUT(         0 )  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_DCLK";
    Drv_HPU_CLK.OUT(      0 )  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_HPU_CLK";
    Drv_DXINT_CLK.OUT(    0 )  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_DXINT_CLK";
    Drv_VME_CLK.OUT(      0 )  <<  NoisyPLD.MEAS_IN( m++ )  <<  "MEAS_VME_CLK";
 
    Drv_DCLK.OUT(      3, 1 )  <<  DX.DCLK;       merge( "/NC",      Drv_DCLK.OUT( 8, 4 ) );  // see backplane LVDS drivers below
    Drv_HPU_CLK.OUT(      1 )  <<  HO.HPU_CLK;    merge( "/NC",   Drv_HPU_CLK.OUT( 9, 2 ) );
    Drv_DXINT_CLK.OUT( 4, 1 )  <<  DX.DXINT_CLK;  merge( "/NC", Drv_DXINT_CLK.OUT( 9, 5 ) );
    Drv_VME_CLK.OUT(   3, 1 )  <<  VME.VME_CLK;   merge( "/NC",   Drv_VME_CLK.OUT( 9, 4 ) );
 
    Drv_TCLK.OUT(      4, 1 )  <<  IC.TCLK;
    Drv_TCLK.OUT(         5 )  <<  "MPYI_TCLK"; // output to multiplier
    merge( "/NC",      Drv_TCLK.OUT( 8, 6 ) );  // see backplane LVDS drivers below
    IC.TCLK( 3 ) ^ CLC[ clc++ ] ^ GND;          // load capacitor: IC.TCLK( 3 ) has only one load (TTC_FPGA)
 
// load capacitors for dedicated clocks going to DPU's B0 and A5
    B.DX_CLK( 0 ) ^ CLC[ clc++ ] ^ GND;
    A.DX_CLK( 5 ) ^ CLC[ clc++ ] ^ GND;
    B.SCLK(   0 ) ^ CLC[ clc++ ] ^ GND;
    A.SCLK(   5 ) ^ CLC[ clc++ ] ^ GND;
 
 
// backplane LVDS drivers
    "BP_RCLKO" << Drv_RCLK1.OUT(  9 )  <<  Drv_BP_RCLKO.IN;   // inputs to drivers
    "BP_SCLKO" <<  Drv_SCLK.OUT( 15 )  <<  Drv_BP_SCLKO.IN;
    "BP_TCLKO" <<  Drv_TCLK.OUT(  9 )  <<  Drv_BP_TCLKO.IN;
    "BP_DCLKO" <<  Drv_DCLK.OUT(  9 )  <<  Drv_BP_DCLKO.IN;
 
 
    Drv_BP_RCLKO.OUT_P << BK.RCLKOP;  // LVDS output clocks to backplane
    Drv_BP_RCLKO.OUT_N << BK.RCLKON;
 
    Drv_BP_SCLKO.OUT_P << BK.SCLKOP;
    Drv_BP_SCLKO.OUT_N << BK.SCLKON;
 
    Drv_BP_TCLKO.OUT_P << BK.TCLKOP;
    Drv_BP_TCLKO.OUT_N << BK.TCLKON;
 
    Drv_BP_DCLKO.OUT_P << BK.DCLKOP;
    Drv_BP_DCLKO.OUT_N << BK.DCLKON;
 
 
// input clocks with differential termination
    Rcv_BP_RCLKI.IN_P1  << BK.RCLKIP  << DTerm_BP_RCLKI.A;     // default:  install terminator
    Rcv_BP_RCLKI.IN_N1  << BK.RCLKIN  << DTerm_BP_RCLKI.B;
 
    Rcv_BP_TCLKI.IN_P1  << BK.TCLKIP  << DTerm_BP_TCLKI.A;     // default:  install terminator
    Rcv_BP_TCLKI.IN_N1  << BK.TCLKIN  << DTerm_BP_TCLKI.B;
 
    Rcv_FP_RCLKI.IN_P1  << FP.RCLKIP  << DTerm_FP_RCLKI.A;     // default:  do not install terminator
    Rcv_FP_RCLKI.IN_N1  << FP.RCLKIN  << DTerm_FP_RCLKI.B;
 
    Rcv_FP_TCLKI.IN_P1  << FP.TCLKIP  << DTerm_FP_TCLKI.A;     // default:  do not install terminator
    Rcv_FP_TCLKI.IN_N1  << FP.TCLKIN  << DTerm_FP_TCLKI.B;
 
 
    "BP_RCLKI"  ^ STerm_BP_RCLKI ^  "LOC_BP_RCLKI" << Rcv_BP_RCLKI.OUT1;
    "BP_TCLKI"  ^ STerm_BP_TCLKI ^  "LOC_BP_TCLKI" << Rcv_BP_TCLKI.OUT1;
    "FP_RCLKI"  ^ STerm_FP_RCLKI ^  "LOC_FP_RCLKI" << Rcv_FP_RCLKI.OUT1;
    "FP_TCLKI"  ^ STerm_FP_TCLKI ^  "LOC_FP_TCLKI" << Rcv_FP_TCLKI.OUT1;
 
 
    "/NC" << Rcv_BP_RCLKI.IN_P2;   // one half of dual receiver is not used
    "/NC" << Rcv_BP_RCLKI.IN_N2;
    "/NC" << Rcv_BP_RCLKI.OUT2;
 
    "/NC" << Rcv_BP_TCLKI.IN_P2;
    "/NC" << Rcv_BP_TCLKI.IN_N2;
    "/NC" << Rcv_BP_TCLKI.OUT2;
 
    "/NC" << Rcv_FP_RCLKI.IN_P2;
    "/NC" << Rcv_FP_RCLKI.IN_N2;
    "/NC" << Rcv_FP_RCLKI.OUT2;
 
    "/NC" << Rcv_FP_TCLKI.IN_P2;
    "/NC" << Rcv_FP_TCLKI.IN_N2;
    "/NC" << Rcv_FP_TCLKI.OUT2;
 
 
    property( CR_MatchClock, Match1 );   // properties for matching clock trace lengths
    property( CR_MatchClock, Match2 );
    property( CR_MatchClock, Match3 );
    property( CR_MatchClock, Match4 );
    property( CR_MatchClock, Match5 );
    property( CR_MatchClock, Match6 );
    property( CR_MatchClock, Match7 );
    property( CR_MatchClock, Match8 );
    property( CR_MatchClock, Match9 );
 
    int mp = 0;   // index for monopin array
 
    Match1   <= Drv_RCLK0.OUT <= Drv_RCLK1.OUT;   // >> place Drv_RCLK0 near Drv_RCLK1
      for ( int i = 0; i <=  9; ++i ) { Mono[ mp++ ].A  <<  Drv_RCLK0.OUT( i ); }
      for ( int i = 1; i <=  8; ++i ) { Mono[ mp++ ].A  <<  Drv_RCLK1.OUT( i ); }
    Match2   <= Drv_SCLK.OUT;
      for ( int i = 3; i <= 13; ++i ) { Mono[ mp++ ].A  <<  Drv_SCLK.OUT(  i ); }
                                        Mono[ mp++ ].A  <<  Drv_SCLK.OUT(  1 );
    Match3   <= Drv_TCLK.OUT;
      for ( int i = 1; i <=  4; ++i ) { Mono[ mp++ ].A  <<  Drv_TCLK.OUT( i ); }
    Match4   <= Drv_DCLK.OUT;
    Match5   <= Drv_DC_CLK.OUT;
                                        Mono[ mp++ ].A  <<  Drv_DC_CLK.OUT( 1 );
    Match6   <= Drv_DX_CLK.OUT;
      for ( int i = 1; i <= 11; ++i ) { Mono[ mp++ ].A  <<  Drv_DX_CLK.OUT( i ); }
    Match7   <= Drv_DXINT_CLK.OUT;
    Match8   <= Drv_VME_CLK.OUT;
    Match9   <= Drv_DPU_CLK.OUT;  Match9.LongLengthMatchTolerance = -1;               // do not match long length
      for ( int i = 2; i <=  6; ++i ) { Mono[ mp++ ].A  <<  Drv_DPU_CLK.OUT( i ); }
      
    if ( mp != mono_count )
      BEGERR << "CM_ClockGeneration::Connect():  mp value of " << mp << " does not equal mono_count" << ENDERR;
  }
};
 
#endif

 

Design Home <<  File View  >> Class View Output (partial) Parts Library Examples Home

Legal Copyright © 2007 by Coolquest, Inc. Contact