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 _JTAGH_
#define _JTAGH_
 
#include "std_drivers.h"
#include "sn74lvth162245.h"
#include "sn74cbtlv3253.h"
#include "sn74cbtlv1g125.h"
#include "headers.h"          // for CP_Header2
#include "monopins.h"
 
// This file contains support for:
//    JTAG boundary scan / In-System Programming for PLD's and FPGA's
//    TI TDS emulator
//    FPGA configuration
 
// For many signals, CM_JTAG just distributes signals generated elsewhere.
// For some, it adds buffering.
 
// Though the TDS emulator uses a JTAG chain, the term "JTAG" in this file typically refers
// to JTAG boundary scan / in-system programming for PLD's and FPGA's.
 
// The JTAG and emulator ports ("TAP's") of all participating devices are brought
// to the JTAG subsystem in the CB_..._JT interfaces below.
// The emulator and JTAG chains are fully managed in the JTAG subsystem except:
//   FET switches between the emulator TDI and TDO of the HPU and all DPU's
//   FET switch   between the JTAG     TDI and TDO of the HPU
 
// The TAP's of the following JTAG devices are not used:
//   JTAG for DPU FPGA's
 
// JTAG and Emulator TDI/TDO daisy chain order is partly determined by layout considerations.
 
 
// summary of JTAG and CONF bundles:
//   Bundle     Used for
//   ----------     ---------------------------------------------------------
//   CB_JTAG        PLD's,      base class for CB_JTAG_CONF and CB_JTAG_CONF2
//   CB_CONF2       GPU FPGA's
//   CB_JTAG_CONF   motherboard FPGA's
//   CB_JTAG_CONF2  HPU FPGA's, backplane JTAG and CONF
 
 
// JTAG bundle
class CB_JTAG : public TBundle {
public:
  port TMS;
  port TDI;
  port TDO;
  port TCK;
  virtual void Register() {
    reg( TMS );
    reg( TDI );
    reg( TDO );
    reg( TCK );
  }
};
 
// bundle with configuration signals for one FPGA
class CB_CONF : public TBundle {
public:
  port CCLK;
  port DIN;
  port PROGRAM_N;
  virtual void Register() {
    reg( CCLK );
    reg( DIN );
    reg( PROGRAM_N );
  }
};
 
// bundle with configuration signals for two FPGA's
class CB_CONF2 : public TBundle {
public:
  port CCLK;         // to both FPGA's
  port DIN;          // to both FPGA's
  port PROGRAM0_N;   // one per FPGA
  port PROGRAM1_N;
  virtual void Register() {
    reg( CCLK );
    reg( DIN );
    reg( PROGRAM0_N );
    reg( PROGRAM1_N );
  }
};
 
// JTAG bundle that also includes configuration signals for one FPGA
class CB_JTAG_CONF : public CB_JTAG {
public:
  port CCLK;
  port DIN;
  port PROGRAM_N;
  virtual void Register() {
    CB_JTAG::Register();
    reg( CCLK );
    reg( DIN );
    reg( PROGRAM_N );
  }
};
 
// JTAG bundle that also includes configuration signals for two FPGA's
class CB_JTAG_CONF2 : public CB_JTAG {
public:
  port CCLK;         // to both FPGA's
  port DIN;          // to both FPGA's
  port PROGRAM0_N;   // one per FPGA
  port PROGRAM1_N;
  virtual void Register() {
    CB_JTAG::Register();
    reg( CCLK );
    reg( DIN );
    reg( PROGRAM0_N );
    reg( PROGRAM1_N );
  }
};
 
 
// TI TDS JTAG emulator
class CB_Emulator : public TBundle {
public:
  port TMS;
  port TDI;
  port TDO;
  port TCK;
  port TRST_N;
  port EMU0;
  port EMU1;
  virtual void Register() {
    reg( TMS    );
    reg( TDI    );
    reg( TDO    );
    reg( TCK    );
    reg( TRST_N );
    reg( EMU0   );
    reg( EMU1   );
  }
};
 
 
// CB_Front_JTAG: interface between JTAG and FrontPanel
 
class CB_Front_JT : public TBundle {
public:
  CB_JTAG      JTAG;           // to JTAG header on front panel
  CB_Emulator  Emulator;       // to emulator header on front panel
  port         TCK_RET;        // emulator header on front panel has TCK_RET in addition to the signals in Emulator
  port         JTAG_DIPSW;     // dip switch signals for selecting JTAG chains
  virtual void Register() {
    reg( JTAG     );
    reg( Emulator );
    reg( TCK_RET  );
    regb( JTAG_DIPSW, 2, 0 );
  }
};
 
 
// interfaces to other subsystems
//   Backplane
class CB_Back_JT : public TBundle {
public:
  CB_JTAG_CONF2  JTAG_CONF;        // to backplane
  virtual void Register() {
    reg( JTAG_CONF );
  }
};
 
//   ClockGeneration
class CB_CG_JT : public TBundle {
public:
  CB_JTAG  NoisyPLD;        // to Noisy PLD
  CB_JTAG  QuietPLD;        // to Quiet PLD
  port     PROGRAM_N;       // PROGRAM_N signals for FPGA configuration--output from ClockGeneration, distributed by JTAG subsystem
  virtual void Register() {
    reg(  NoisyPLD );
    reg(  QuietPLD );
    regb( PROGRAM_N, 36, 0 );
  }
};
 
//   DPU_Control
class CB_DC_JT : public TBundle {
public:
  CB_JTAG_CONF  DC_FPGA;         // to DC FPGA
  virtual void Register() {
    reg( DC_FPGA );
  }
};
 
//   DataExchange
class CB_DX_JT : public TBundle {
public:
  CB_JTAG_CONF  DXF_FPGA_A;       // to DXF FPGA's
  CB_JTAG_CONF  DXF_FPGA_B;
  CB_JTAG_CONF  DXB_FPGA;         // to DXB FPGA
  virtual void Register() {
    reg( DXF_FPGA_A );
    reg( DXF_FPGA_B );
    reg( DXB_FPGA   );
  }
};
 
//   HalfROD
class CB_Half_JT : public TBundle {
public:
  CB_Emulator  EMU[   DPU_HalfCount ];    // emulator signals for DPU DSP's
  CB_CONF2     CONF[  DPU_HalfCount ];    // configuration signals for DPU FPGA's
  virtual void Register() {
    rega( EMU,  DPU_HalfCount );
    rega( CONF, DPU_HalfCount );
  }
};
 
//   Host
class CB_Host_JT : public TBundle {
public:
  port           CCLK;         // configuration signals for HPU's FPGA's (PROGRAM_N's come from FlashPLD)
  port           DIN;
  CB_Emulator    HPU_DSP;      // to DSP on HPU
  CB_JTAG        HPU_FPGA;     // to FPGA's on HPU (currently two FPGA's)
  CB_JTAG        HostPLD;      // to Host PLD
  virtual void Register() {
    reg( CCLK    );
    reg( DIN     );
    reg( HPU_DSP     );
    reg( HPU_FPGA    );
    reg( HostPLD     );
  }
};
 
//   Interconnect
class CB_IC_JT : public TBundle {
public:
  CB_JTAG_CONF  BPI_FPGA[ 6 ];    // to BPI FPGA's
  CB_JTAG_CONF  TTC_FPGA;         // to TTC FPGA
  virtual void Register() {
    rega( BPI_FPGA, 6 );
    reg(  TTC_FPGA    );
  }
};
 
//   VME_Interface
class CB_VME_JT : public TBundle {
public:
  CB_JTAG  VMEC_PLD;         // to VME control PLD
  CB_JTAG  VMED_PLD;         // to VME data PLD
  CB_JTAG  FlashPLD;         // to flash PLD
  port     CCLK;             // unbuffered FPGA configuration signals
  port     DIN;
  virtual void Register() {
    reg( VMEC_PLD );
    reg( VMED_PLD );
    reg( FlashPLD );
    reg( CCLK );
    reg( DIN );
  }
};
 
 
 
class CM_JTAG : public TModule {    // JTAG Subsystem
public:
// ***** member bundles ***** //
  CB_Front_JT    FP;      // Frontpanel
  CB_Back_JT     BK;      // Backplane
  CB_CG_JT       CG;      // ClockGeneration
  CB_DC_JT       DC;      // DPU_Control
  CB_DX_JT       DX;      // DataExchange
  CB_Half_JT     A;       // Half A
  CB_Half_JT     B;       // Half B
  CB_Host_JT     HO;      // HPU
  CB_IC_JT       IC;      // Interconnect
  CB_VME_JT      VME;     // VME_Interface
 
 
// ***** member ports ***** //
  port MB_VCC;      // 3.3V for JTAG buffers and muxes
  port DSP_VCC;     // 3.3V for emulator buffers
  port GND;
 
 
// ***** member modules and parts ***** //
                                     // buffers for emulator and JTAG signals other than TCK
  CP_SN74LVTH162245  Buf_Emulator;   // >>> place near emulator connector
  CP_SN74LVTH162245  Buf_JTAG;       // >>> place near JTAG connector
 
  CM_STD_CDC319       Drv_ETCK;       // TCK drivers for emulator TCK and JTAG TCK
  CM_STD_CDC319       Drv_JTCK;
  CM_STD_CDC319       Drv_CCLK;       // driver for FPGA configuration clock
 
  CP_R30             STerm_ETCK;     // series terminators for TCK driver inputs
  CP_R30             STerm_JTCK;
 
  CP_R4_7K           Pull_E[ 6 ];    // pullup for TCK, TMS, TDI, EMU0, EMU1; pulldown for TRST_N
  CP_R4_7K           Pull_J[ 5 ];    // pullup for TCK, TMS, TDI, FP DIPSW( 1, 0 )
 
  CP_SN74CBTLV3253   Mux_JTMS;       // FET mux for driving TMS high when part of JTAG chain is not used
  CP_SN74CBTLV3253   Mux_JTDO;       // FET mux for circumventing parts of JTAG chain
 
                                     // >>> install MB_JTAG_Short jumper to short first motherboard TDI to last motherboard TDO
  CP_HEADER2         MB_JTAG_Short;  // >>> only install if motherboard FPGA's are not yet installed and configuration of HPU FPGA's via JTAG is desired
 
  CP_R30             STerm_CCLK;     // series terminator for CCLK driver input
 
  enum { mono_count = 19 };          // monopins for routing far-end cluster of some clock nets
  CP_MONOPIN25       Mono[ mono_count ];
 
 
  // decoupling
  enum { e_cdc_count =  8,             // 4 for buf,   4 for drv
         j_cdc_count = 14,             // 4 for buf, 4*2 for drv, 2 for mux
         e_tdc_count =  2,             // 1 near header + buf, 1 near drv
         j_tdc_count =  1 };           // 1 near header + buf
  CP_CDC_POS  E_CDC[ e_cdc_count ];    // ceramic decoupling
  CP_CDC_POS  J_CDC[ j_cdc_count ];
  CP_TDC_POS  E_TDC[ e_tdc_count ];    // tantalum decoupling
  CP_TDC_POS  J_TDC[ j_tdc_count ];
 
 
  virtual void Register() {
// bundles
    reg( FP  );
    reg( BK  );
    reg( CG  );
    reg( DC  );
    reg( DX  );
    reg( A   );
    reg( B   );
    reg( HO  );
    reg( IC  );
    reg( VME );
 
// ports
    reg( MB_VCC );
    reg( DSP_VCC );
    reg( GND );
 
// parts and modules
    reg(  Buf_Emulator );
    reg(  Buf_JTAG     );
 
    reg(  Drv_ETCK     );
    reg(  Drv_JTCK     );
    reg(  Drv_CCLK     );
 
    reg(  STerm_ETCK   );
    reg(  STerm_JTCK   );
 
    rega( Pull_E,    6 );
    rega( Pull_J,    5 );
 
    reg(  Mux_JTMS      );
    reg(  Mux_JTDO      );
 
    reg(  MB_JTAG_Short );
 
    reg(  STerm_CCLK    );
 
    rega( Mono,  mono_count );
 
    rega( E_CDC, e_cdc_count );
    rega( J_CDC, j_cdc_count );
    rega( E_TDC, e_tdc_count );
    rega( J_TDC, j_tdc_count );
 
  }
 
  virtual void Connect() {
    int mp = 0;   // monopin array index
 
// some net names will be overridden by a higher-level net name
 
    wireall( GND );
 
    for ( int i = 0; i < e_cdc_count; ++ i )  DSP_VCC  <<  E_CDC[ i ].POS;
    for ( int i = 0; i < j_cdc_count; ++ i )  MB_VCC   <<  J_CDC[ i ].POS;
    for ( int i = 0; i < e_tdc_count; ++ i )  DSP_VCC  <<  E_TDC[ i ].POS;
    for ( int i = 0; i < j_tdc_count; ++ i )  MB_VCC   <<  J_TDC[ i ].POS;
 
    GND  <<      Buf_JTAG.OE_N;       // buffer outputs are always enabled
    GND  <<  Buf_Emulator.OE_N;
    GND  <<      Buf_JTAG.DIR;        // buffer direction is always B --> A (A ports have 22 ohm series resistors)
    GND  <<  Buf_Emulator.DIR;
 
 
                                  // CDC319 contains pullups on all these signals
    "/NC"  <<  Drv_ETCK.OE;       // output always active
    "/NC"  <<  Drv_ETCK.SCLOCK;   // I2C interface not used --> all outputs enabled on power-up
    "/NC"  <<  Drv_ETCK.SDATA;
    "/NC"  <<  Drv_JTCK.SCLOCK;   // a DIP switch connected to JTCK OE disables JTAG TCK
    "/NC"  <<  Drv_JTCK.SDATA;
    "/NC"  <<  Drv_CCLK.OE;
    "/NC"  <<  Drv_CCLK.SCLOCK;
    "/NC"  <<  Drv_CCLK.SDATA;
 
 
 
 
 
// *** Emulator Drivers *** //
    DSP_VCC  <<     Buf_Emulator.VCC;   // Emulator devices are on GPU's (DSP modules) --> use DSP_VCC
    DSP_VCC  <<     Drv_ETCK.VCC;
 
 
    // TMS to all DSP's via 1x7 buffer
    "RAW_ETMS"  <<  FP.Emulator.TMS  ^  Pull_E[ 0 ]  ^  DSP_VCC;
    merge( "RAW_ETMS",      Buf_Emulator.B(  6, 0 ) );
    "ETMS"              <<  Buf_Emulator.A(  6, 0 );
 
    "/NC"               <<  Buf_Emulator.A(  7 )
                        <<  Buf_Emulator.B(  7 );
 
 
    // TCK via 1x1 buffer, series resistor, 1 x 10 driver, series resistors
    FP.Emulator.TCK     <<  Buf_Emulator.B(  8 )   ^  Pull_E[ 1 ]  ^  DSP_VCC;    // from connector to 1x1 buffer
                            Buf_Emulator.A(  8 )  <<  "BUFO_ETCK"                 // from 1x1 buffer...
                         ^  STerm_ETCK            ^  "DRIVIN_ETCK"                // via series resistor...
                        <<  Drv_ETCK.IN;                                          // to 1x10 driver
    "ETCK"              <<                    Drv_ETCK.OUT( 8, 0 );               // driver outputs
    "/NC"               <<                    Drv_ETCK.OUT( 9 );
 
 
 
    // TCK_RET via buffer
    Drv_ETCK.OUT( 8 )   <<  Buf_Emulator.B(  9 );      // TCK into buffer
    FP.TCK_RET          <<  Buf_Emulator.A(  9 );      // TCK_RET out of buffer
 
    // TDI to first DSP in the chain
    FP.Emulator.TDI     <<  Buf_Emulator.B( 10 )  ^  Pull_E[ 2 ]  ^  DSP_VCC;
    "ETDI"              <<  Buf_Emulator.A( 10 );
 
    // TDO from last DSP in the chain
    FP.Emulator.TDO     <<  Buf_Emulator.A( 11 );
    "ETDO"              <<  Buf_Emulator.B( 11 );
 
 
    // TRST_N to all DSP's in the chain
    FP.Emulator.TRST_N  <<  Buf_Emulator.B( 12 )  ^  Pull_E[ 3 ]  ^  GND;  // pulldown --> emulator port in reset while emulator is not connected
    "TRST_N"            <<  Buf_Emulator.A( 12 );
 
 
    // EMU0, EMU1 to/from all DSP's in the chain
    FP.Emulator.EMU0    <<  Buf_Emulator.A( 13 );
    FP.Emulator.EMU1    <<  Buf_Emulator.A( 14 );
    "EMU0"              <<  Buf_Emulator.B( 13 )  ^  Pull_E[ 4 ]  ^  DSP_VCC;
    "EMU1"              <<  Buf_Emulator.B( 14 )  ^  Pull_E[ 5 ]  ^  DSP_VCC;
 
    "/NC"               <<  Buf_Emulator.A( 15 )
                        <<  Buf_Emulator.B( 15 );
 
 
// *** actual emulator connections to DSP's *** //
 
// parallel connections, one signal shared by all DSP's
    "TRST_N"    <<  HO.HPU_DSP.TRST_N;
    "EMU0"      <<  HO.HPU_DSP.EMU0;
    "EMU1"      <<  HO.HPU_DSP.EMU1;
    for ( int i = 0; i < DPU_HalfCount; ++ i ) {
      "TRST_N"  <<  A.EMU[ i ].TRST_N;
      "TRST_N"  <<  B.EMU[ i ].TRST_N;
      "EMU0"    <<  A.EMU[ i ].EMU0;
      "EMU0"    <<  B.EMU[ i ].EMU0;
      "EMU1"    <<  A.EMU[ i ].EMU1;
      "EMU1"    <<  B.EMU[ i ].EMU1;
    }
 
// parallel connections, but multiple buffered copies
 
    int ck = 0;    // index in TCK driver output
    int ms = 0;    // index in TMS buffer
    Drv_ETCK.OUT(     ck++ ) <<  HO.HPU_DSP.TCK;                           // dedicated signal for HPU
    Buf_Emulator.A(   ms++ ) <<  HO.HPU_DSP.TMS;
 
// some paired, some dedicated, according to layout
    Drv_ETCK.OUT( ck++ )  <<   B.EMU[ 0 ].TCK;        // dedicated B0
    Drv_ETCK.OUT( ck++ )  <<   B.EMU[ 1 ].TCK         // pair      B1, B2
                          <<   B.EMU[ 2 ].TCK ^ Mono[ mp++ ];
    Drv_ETCK.OUT( ck++ )  <<   B.EMU[ 3 ].TCK         // pair      B3, B4
                          <<   B.EMU[ 4 ].TCK ^ Mono[ mp++ ];
    Drv_ETCK.OUT( ck++ )  <<   B.EMU[ 5 ].TCK         // pair      B5, A0
                          <<   A.EMU[ 0 ].TCK ^ Mono[ mp++ ];
    Drv_ETCK.OUT( ck++ )  <<   A.EMU[ 1 ].TCK         // pair      A1, A2
                          <<   A.EMU[ 2 ].TCK ^ Mono[ mp++ ];
    Drv_ETCK.OUT( ck++ )  <<   A.EMU[ 3 ].TCK         // pair      A3, A4
                          <<   A.EMU[ 4 ].TCK ^ Mono[ mp++ ];
    Drv_ETCK.OUT( ck++ )  <<   A.EMU[ 5 ].TCK;        // dedicated A5
 
    
    property( CR_MatchClock, MatchETCK );       // use CR_MatchClock to form a far-end cluster on each TCK net
                                               // property must be associated with a range of a port of a TPart
    MatchETCK   <= Drv_ETCK.Term1.A( 5    );   // 5
    MatchETCK   <= Drv_ETCK.Term2.B( 5, 0 );   // 0, 1, 3, 5
    MatchETCK.LongLengthMatchTolerance = -1;   // do not match long length, just form the far-end cluster
 
 
    for ( int i = 0; i < DPU_HalfCount; i += 2 ) {                        // side A: one signal per pair of DPU's
      Buf_Emulator.A(   ms++ ) <<  A.EMU[ i ].TMS  <<  A.EMU[ i+1 ].TMS;
    }
    for ( int i = 0; i < DPU_HalfCount; i += 2 ) {                        // side B: one signal per pair of DPU's
      Buf_Emulator.A(   ms++ ) <<  B.EMU[ i ].TMS  <<  B.EMU[ i+1 ].TMS;
    }
 
 
// Emulator TDI/TDO chain:
//   FP.TDI                      // the emulator POD's TDI is an output to the first TDI in the chain
//   --> Host
//   --> B[ 0, 1, 2, 3, 4, 5 ]
//   --> A[ 0, 1, 2, 3, 4, 5 ]
//   --> FP.TDO                  // the emulator POD's TDO is an input from the last TDO in the chain
 
    int LastDPU = DPU_HalfCount - 1;
 
// the implementation below seems like the best way to get reasonable final net names
    int a = 0;
    int b = 0;
    "ETDI"     <<  HO.HPU_DSP.TDI;                                // FP     --> HPU
    "ETDO_H"   <<  HO.HPU_DSP.TDO  <<  B.EMU[ b   ].TDI;          // HPU    --> side B
    "ETDO_B0"  <<  B.EMU[ b ].TDO  <<  B.EMU[ b+1 ].TDI;  b++;
    "ETDO_B1"  <<  B.EMU[ b ].TDO  <<  B.EMU[ b+1 ].TDI;  b++;
    "ETDO_B2"  <<  B.EMU[ b ].TDO  <<  B.EMU[ b+1 ].TDI;  b++;
    "ETDO_B3"  <<  B.EMU[ b ].TDO  <<  B.EMU[ b+1 ].TDI;  b++;
    "ETDO_B4"  <<  B.EMU[ b ].TDO  <<  B.EMU[ b+1 ].TDI;  b++;
    "ETDO_B5"  <<  B.EMU[ b ].TDO  <<  A.EMU[ a   ].TDI;          // side B --> Side A
 
    "ETDO_A0"  <<  A.EMU[ a ].TDO  <<  A.EMU[ a+1 ].TDI;  a++;
    "ETDO_A1"  <<  A.EMU[ a ].TDO  <<  A.EMU[ a+1 ].TDI;  a++;
    "ETDO_A2"  <<  A.EMU[ a ].TDO  <<  A.EMU[ a+1 ].TDI;  a++;
    "ETDO_A3"  <<  A.EMU[ a ].TDO  <<  A.EMU[ a+1 ].TDI;  a++;
    "ETDO_A4"  <<  A.EMU[ a ].TDO  <<  A.EMU[ a+1 ].TDI;  a++;
    "ETDO"     <<  A.EMU[ a ].TDO;                                // side A --> FP
 
 
 
 
// JTAG summary
// ========================================================================================
//                         JTAG device count
// subsystem                   PLD   FPGA       comment
// ------------               ----   ----       -------------
//   FrontPanel                                 the JTAG connector is in the front panel subsystem
//   Host                        1      2       HPU FPGA's are part of the FPGA JTAG chain
//   ClockGeneration             2
//   VME_Interface               3              Flash PLD is part of VME
//   DataExchange                       3
//   DPU_Control                        1
//   Interconnect                       7
//   Backplane                                  the FPGA/PLD JTAG chain extends through backplane
//   HalfROD                      none          DPU's are not in FPGA/PLD JTAG chain
//   Power                        none
 
 
// JTAG TDI/TDO is chained as follows:
//   Front panel TDI ----> PLD's ----> FPGA's ----> Backplane ---,
//                                                               |
//   Front panel TDO <-------------------------------------------'
//
//   The PLD's are always included in the chain.
//   The FPGA's and/or the Backplane may be circumvented.
//   The HPU's FPGA's are included in the "FPGA" part of the chain.
//   No GPU FPGA's are included in the chain.
//   When the HPU is not installed, the HPU's TDI/TDO pins are connected together via a FET switch
//   A jumper allows HPU FPGA's to be configured without any motherboard FPGA's in the chain
//   The JTAG TAP of circumvented devices is held in the reset state by setting TMS high for these devices.
 
// See detailed layout of JTAG chains below
 
 
// *** JTAG Drivers *** //
    MB_VCC  <<     Buf_JTAG.VCC;   // JTAG devices are on the motherboard (except the HPU's FPGA's and backplane devices)
    MB_VCC  <<     Drv_JTCK.VCC;
    MB_VCC  <<     Mux_JTMS.VCC;
    MB_VCC  <<     Mux_JTDO.VCC;
    GND     <<     Mux_JTMS.OE1_N  <<  Mux_JTMS.OE2_N;     // always OE'd
    GND     <<     Mux_JTDO.OE1_N  <<  Mux_JTDO.OE2_N;
 
    FP.JTAG_DIPSW( 0 )     ^  Pull_J[ 3 ]  ^  MB_VCC;
    FP.JTAG_DIPSW( 1 )     ^  Pull_J[ 4 ]  ^  MB_VCC;
    FP.JTAG_DIPSW( 1, 0 ) <<  Mux_JTMS.S  <<  Mux_JTDO.S;       // both muxes get same address
    FP.JTAG_DIPSW( 2 )    <<  Drv_JTCK.OE;                      // CDC319 has a pullup on OE
 
// JTMS
    //              JTMS mux                  JTDO mux
    //        ======================   ======================
    //            B2           B1          B2           B1
    //   S    (back TMS)   (fpga TMS)  (back JTDI)    (JTDO)
    //  --    ----------------------   ----------------------
    //   0       VCC           VCC      GND         last cpld     // cpld only
    //   1       TMS           VCC      last PLD      back        // cpld + backplane
    //   2       VCC           TMS      GND         last fpga     // cpld + fpga
    //   3       TMS           TMS      last FPGA     back        // all
 
 
    // TMS to all devices via 1x1 buffer, JTMS mux, 1x8 buffer
    "RAW_JTMS"   <<  FP.JTAG.TMS <<  Buf_JTAG.B( 10 )  ^ Pull_J[ 0 ]  ^  MB_VCC;
    "BUF_JTMS"                   <<  Buf_JTAG.A( 10 );
 
    merge( "BUF_JTMS",               Buf_JTAG.B(  3,  0 ) );   // direct:         TMS for CPLD's (before final buffer)
    merge( "BUF_JTMS_FPGA",          Buf_JTAG.B(  8,  4 ) );   // see mux below:  TMS for FPGA's (before final buffer)
    merge( "BUF_JTMS_BACK",          Buf_JTAG.B(  9     ) );   // see mux below:  TMS for backplane (before final buffer)
 
    "JTMS"                       <<  Buf_JTAG.A(  9,  0 );
 
// JTMS multiplexer                          // mux for FPGA JTMS
    MB_VCC           <<  Mux_JTMS.B1( 0 );   // cpld only
    MB_VCC           <<  Mux_JTMS.B1( 1 );   // cpld + backplane
    "BUF_JTMS"       <<  Mux_JTMS.B1( 2 );   // cpld + fpga
    "BUF_JTMS"       <<  Mux_JTMS.B1( 3 );   // all
    "BUF_JTMS_FPGA"  <<  Mux_JTMS.A1;        // output to final drivers
 
                                             // mux for backplane JTMS
    MB_VCC           <<  Mux_JTMS.B2( 0 );   // cpld only
    "BUF_JTMS"       <<  Mux_JTMS.B2( 1 );   // cpld + backplane
    MB_VCC           <<  Mux_JTMS.B2( 2 );   // cpld + fpga
    "BUF_JTMS"       <<  Mux_JTMS.B2( 3 );   // all
    "BUF_JTMS_BACK"  <<  Mux_JTMS.A2;        // output to final driver
 
 
    // TCK via series resistor, 1 x 10 driver, series resistors
    FP.JTAG.TCK    ^  Pull_J[ 1 ]    ^  MB_VCC;                      // pullup
    FP.JTAG.TCK    ^  STerm_JTCK     ^  "DRIVIN_JTCK"                // from connector via series resistor...
                  <<  Drv_JTCK.IN;                                   // to 1x10 driver
    "JTCK"        <<                    Drv_JTCK.OUT( 9, 0 );        // driver outputs
 
    // TDI to first device in the chain
    FP.JTAG.TDI   <<  Buf_JTAG.B( 11 )  ^  Pull_J[ 2 ]  ^  MB_VCC;
    "JTDI"        <<  Buf_JTAG.A( 11 );
 
    // TDO from last device in the chain
    FP.JTAG.TDO   <<  Buf_JTAG.A( 12 );
    "JTDO"        <<  Buf_JTAG.B( 12 );
 
    // Buf_JTAG.A( 15, 13 ) are used to buffer RAW_DIN, see below
 
 
 
// *** actual JTAG connections to devices *** //
 
//                                                             driver#
// JTAG chains:                                                TCK/TMS     subsystem
// PLD:        --> HostPLD                                        0          HO
//             --> FlashPLD                                       1          VME
//             --> VMED_PLD --> VMEC_PLD                          2          VME
//             --> NoisyPLD --> QuietPLD                          3          CG
//                 ------------------------------------------------
// FPGA:       --> HPU FPGA's                                     4          HO
//             --> DXF_FPGA_A                                     5          DX
//             --> DXF_FPGA_B                                     6          DX
//             --> DXB_FPGA                                       6          DX
//             --> DC_FPGA                                        5          DC
//             --> TTC_FPGA                                       7          IC
//             --> BPI_FPGA[ 5, 4, 3 ]                            7          IC
//             --> BPI_FPGA[ 2, 1, 0 ]                            8          IC
//                 ------------------------------------------------
// Backplane:  --> Backplane                                      9          BK
 
// TCK
// TCK assignments to OUT() have been optimized for layout
// PLD TCK's only share an OUT() with other PLD's, not FPGA's or HPU -- this restriction may be unnecessary
    Drv_JTCK.OUT( 0 ) <<        HO.HostPLD.TCK;
    Drv_JTCK.OUT( 1 ) <<      VME.FlashPLD.TCK;
    Drv_JTCK.OUT( 2 ) <<      VME.VMED_PLD.TCK
                      <<      VME.VMEC_PLD.TCK ^ Mono[ mp++ ];
    Drv_JTCK.OUT( 3 ) <<       CG.NoisyPLD.TCK
                      <<       CG.QuietPLD.TCK ^ Mono[ mp++ ];
    Drv_JTCK.OUT( 4 ) <<       HO.HPU_FPGA.TCK;
    Drv_JTCK.OUT( 5 ) <<        DC.DC_FPGA.TCK
                      <<     DX.DXF_FPGA_A.TCK ^ Mono[ mp++ ];
    Drv_JTCK.OUT( 6 ) <<     DX.DXF_FPGA_B.TCK
                      <<       DX.DXB_FPGA.TCK ^ Mono[ mp++ ];
    Drv_JTCK.OUT( 7 ) <<       IC.TTC_FPGA.TCK
                      <<  IC.BPI_FPGA[ 5 ].TCK
                      <<  IC.BPI_FPGA[ 4 ].TCK
                      <<  IC.BPI_FPGA[ 3 ].TCK ^ Mono[ mp++ ];
    Drv_JTCK.OUT( 8 ) <<  IC.BPI_FPGA[ 2 ].TCK
                      <<  IC.BPI_FPGA[ 1 ].TCK
                      <<  IC.BPI_FPGA[ 0 ].TCK ^ Mono[ mp++ ];
    Drv_JTCK.OUT( 9 ) <<      BK.JTAG_CONF.TCK;
 
    property( CR_MatchClock, MatchJTCK );       // use CR_MatchClock to form a far-end cluster on each TCK net
                                               // property must be associated with a range of a port of a TPart
    MatchJTCK   <= Drv_JTCK.Term1.A( 5, 1 );   // 1, 3, 5
    MatchJTCK   <= Drv_JTCK.Term2.B( 1, 0 );   // 0, 1, 5
    MatchJTCK   <= Drv_JTCK.Term2.B( 5    );
    MatchJTCK.LongLengthMatchTolerance = -1;   // do not match long length, just form the far-end cluster
    MatchJTCK.ShortMaxLength = 3000;           // override default max length for short stubs
 
 
// TMS
    Buf_JTAG.A( 0 ) <<        HO.HostPLD.TMS;
    Buf_JTAG.A( 1 ) <<      VME.FlashPLD.TMS;
    Buf_JTAG.A( 2 ) <<      VME.VMED_PLD.TMS
                    <<      VME.VMEC_PLD.TMS;
    Buf_JTAG.A( 3 ) <<       CG.NoisyPLD.TMS
                    <<       CG.QuietPLD.TMS;
    Buf_JTAG.A( 4 ) <<       HO.HPU_FPGA.TMS;
    Buf_JTAG.A( 5 ) <<        DC.DC_FPGA.TMS
                    <<     DX.DXF_FPGA_A.TMS;
    Buf_JTAG.A( 6 ) <<     DX.DXF_FPGA_B.TMS
                    <<       DX.DXB_FPGA.TMS;
    Buf_JTAG.A( 7 ) <<       IC.TTC_FPGA.TMS
                    <<  IC.BPI_FPGA[ 5 ].TMS
                    <<  IC.BPI_FPGA[ 4 ].TMS
                    <<  IC.BPI_FPGA[ 3 ].TMS;
    Buf_JTAG.A( 8 ) <<  IC.BPI_FPGA[ 2 ].TMS
                    <<  IC.BPI_FPGA[ 1 ].TMS
                    <<  IC.BPI_FPGA[ 0 ].TMS;
    Buf_JTAG.A( 9 ) <<      BK.JTAG_CONF.TMS;
 
 
// JTAG TDI/TDO chain:
// the implementation below seems like the best way to get reasonable final net names
 
    "JTDI"         <<                                  HO.HostPLD.TDI;
    "JTDO_CPLD0"   <<        HO.HostPLD.TDO  <<      VME.FlashPLD.TDI;
    "JTDO_CPLD1"   <<      VME.FlashPLD.TDO  <<      VME.VMED_PLD.TDI;
    "JTDO_CPLD2"   <<      VME.VMED_PLD.TDO  <<      VME.VMEC_PLD.TDI;
    "JTDO_CPLD3"   <<      VME.VMEC_PLD.TDO  <<       CG.NoisyPLD.TDI;
    "JTDO_CPLD4"   <<       CG.NoisyPLD.TDO  <<       CG.QuietPLD.TDI;
    "JTDO_CPLD5"   <<       CG.QuietPLD.TDO;
 
    "JTDO_CPLD5"   <<                                 HO.HPU_FPGA.TDI;  // no mux between CPLD's and FPGA's
    "JTDO_FPGA0"   <<       HO.HPU_FPGA.TDO  <<     DX.DXF_FPGA_A.TDI;
    "JTDO_FPGA1"   <<     DX.DXF_FPGA_A.TDO  <<     DX.DXF_FPGA_B.TDI;
    "JTDO_FPGA2"   <<     DX.DXF_FPGA_B.TDO  <<       DX.DXB_FPGA.TDI;
    "JTDO_FPGA3"   <<       DX.DXB_FPGA.TDO  <<        DC.DC_FPGA.TDI;
    "JTDO_FPGA4"   <<        DC.DC_FPGA.TDO  <<       IC.TTC_FPGA.TDI;
    "JTDO_FPGA5"   <<       IC.TTC_FPGA.TDO  <<  IC.BPI_FPGA[ 5 ].TDI;
    "JTDO_FPGA6"   <<  IC.BPI_FPGA[ 5 ].TDO  <<  IC.BPI_FPGA[ 4 ].TDI;
    "JTDO_FPGA7"   <<  IC.BPI_FPGA[ 4 ].TDO  <<  IC.BPI_FPGA[ 3 ].TDI;
    "JTDO_FPGA8"   <<  IC.BPI_FPGA[ 3 ].TDO  <<  IC.BPI_FPGA[ 2 ].TDI;
    "JTDO_FPGA9"   <<  IC.BPI_FPGA[ 2 ].TDO  <<  IC.BPI_FPGA[ 1 ].TDI;
    "JTDO_FPGA10"  <<  IC.BPI_FPGA[ 1 ].TDO  <<  IC.BPI_FPGA[ 0 ].TDI;
    "JTDO_FPGA11"  <<  IC.BPI_FPGA[ 0 ].TDO;
 
    "JTDI_BACK"    <<                                BK.JTAG_CONF.TDI;
    "JTDO_BACK"    <<      BK.JTAG_CONF.TDO;
 
// MB_JTAG_Short Jumper
    "JTDO_FPGA0"   <<  MB_JTAG_Short.P( 1 );   // shorts the first motherboard FPGA TDI to the last motherboard FPGA TDO
    "JTDO_FPGA11"  <<  MB_JTAG_Short.P( 2 );
 
// JTDO multiplexer                        // mux for final TDO
    "JTDO_CPLD5"   <<  Mux_JTDO.B1( 0 );   // cpld only
    "JTDO_BACK"    <<  Mux_JTDO.B1( 1 );   // cpld + backplane
    "JTDO_FPGA11"  <<  Mux_JTDO.B1( 2 );   // cpld + fpga
    "JTDO_BACK"    <<  Mux_JTDO.B1( 3 );   // all
    "JTDO"         <<  Mux_JTDO.A1;        // output to TDO driver
 
                                           // mux for backplane JTDI
    GND            <<  Mux_JTDO.B2( 0 );   // cpld only
    "JTDO_CPLD5"   <<  Mux_JTDO.B2( 1 );   // cpld + backplane
    GND            <<  Mux_JTDO.B2( 2 );   // cpld + fpga
    "JTDO_FPGA11"  <<  Mux_JTDO.B2( 3 );   // all
    "JTDI_BACK"    <<  Mux_JTDO.A2;        // output to backplane TDI
 
 
// *** FPGA configuration Drivers *** //
    MB_VCC         <<  Drv_CCLK.VCC;
    "LOC_CCLK"     <<  VME.CCLK ^ STerm_CCLK ^ "DRVIN_CCLK"  <<  Drv_CCLK.IN;
    "CCLK"         <<  Drv_CCLK.OUT( 9, 0 );    // driver outputs
 
    "RAW_DIN"      <<  VME.DIN;                     // for readable net name
    merge( "RAW_DIN", Buf_JTAG.B( 15, 13 ) );       // use 3 leftover buffers from Buf_JTAG
    "DIN_A"   <<  Buf_JTAG.A( 13 );   // DIN for side A DPU's and HPU
    "DIN_B"   <<  Buf_JTAG.A( 14 );   // DIN for side B DPU's
    "DIN_MB"  <<  Buf_JTAG.A( 15 );   // DIN for all other FPGA's (motherboard FPGA's)
 
 
// *** actual configuration connections to FPGA's *** //
 
// PROGRAM_N
    "PROGRAM_N"  <<  CG.PROGRAM_N;    // PROGRAM_N signals generated in the ClockGeneration subsystem
 
    int p = 0;
    for ( int i = 0; i < DPU_HalfCount; ++ i ) {               // side A DPU's
      CG.PROGRAM_N( p++ )  <<  A.CONF[ i ].PROGRAM0_N;
      CG.PROGRAM_N( p++ )  <<  A.CONF[ i ].PROGRAM1_N;
    }
    for ( int i = 0; i < DPU_HalfCount; ++ i ) {               // side B DPU's
      CG.PROGRAM_N( p++ )  <<  B.CONF[ i ].PROGRAM0_N;
      CG.PROGRAM_N( p++ )  <<  B.CONF[ i ].PROGRAM1_N;
    }
 
    CG.PROGRAM_N( p++ )  <<      BK.JTAG_CONF.PROGRAM0_N;  // backplane
    CG.PROGRAM_N( p++ )  <<      BK.JTAG_CONF.PROGRAM1_N;  // two PROGRAM_N's provided
 
    CG.PROGRAM_N( p++ )  <<        DC.DC_FPGA.PROGRAM_N;   // motherboard FPGA's
    CG.PROGRAM_N( p++ )  <<     DX.DXF_FPGA_A.PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<     DX.DXF_FPGA_B.PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<       DX.DXB_FPGA.PROGRAM_N;
 
    CG.PROGRAM_N( p++ )  <<       IC.TTC_FPGA.PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<  IC.BPI_FPGA[ 0 ].PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<  IC.BPI_FPGA[ 1 ].PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<  IC.BPI_FPGA[ 2 ].PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<  IC.BPI_FPGA[ 3 ].PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<  IC.BPI_FPGA[ 4 ].PROGRAM_N;
    CG.PROGRAM_N( p++ )  <<  IC.BPI_FPGA[ 5 ].PROGRAM_N;
 
 
// CCLK assignments to OUT() have been optimized for layout
    int c = 0;
    Drv_CCLK.OUT( c ++ )  <<       B.CONF[ 0 ].CCLK;  // B0
    Drv_CCLK.OUT( c ++ )  <<       B.CONF[ 1 ].CCLK   // B1-B4
                          <<       B.CONF[ 2 ].CCLK
                          <<       B.CONF[ 3 ].CCLK
                          <<       B.CONF[ 4 ].CCLK ^ Mono[ mp++ ];
    Drv_CCLK.OUT( c ++ )  <<       B.CONF[ 5 ].CCLK   // B5, A0-A2
                          <<       A.CONF[ 0 ].CCLK
                          <<       A.CONF[ 1 ].CCLK
                          <<       A.CONF[ 2 ].CCLK ^ Mono[ mp++ ];
    Drv_CCLK.OUT( c ++ )  <<       A.CONF[ 3 ].CCLK   // A3, A4
                          <<       A.CONF[ 4 ].CCLK ^ Mono[ mp++ ];
    Drv_CCLK.OUT( c ++ )  <<       A.CONF[ 5 ].CCLK   // A5, HO
                          <<                HO.CCLK ^ Mono[ mp++ ];
 
    Drv_CCLK.OUT( c ++ )  <<        DC.DC_FPGA.CCLK   // motherboard FPGA's
                          <<     DX.DXF_FPGA_A.CCLK ^ Mono[ mp++ ];
    Drv_CCLK.OUT( c ++ )  <<     DX.DXF_FPGA_B.CCLK
                          <<       DX.DXB_FPGA.CCLK ^ Mono[ mp++ ];
    Drv_CCLK.OUT( c ++ )  <<       IC.TTC_FPGA.CCLK
                          <<  IC.BPI_FPGA[ 5 ].CCLK
                          <<  IC.BPI_FPGA[ 4 ].CCLK
                          <<  IC.BPI_FPGA[ 3 ].CCLK ^ Mono[ mp++ ];
    Drv_CCLK.OUT( c ++ )  <<  IC.BPI_FPGA[ 2 ].CCLK
                          <<  IC.BPI_FPGA[ 1 ].CCLK
                          <<  IC.BPI_FPGA[ 0 ].CCLK ^ Mono[ mp++ ];
    Drv_CCLK.OUT( c ++ )  <<      BK.JTAG_CONF.CCLK;
 
 
    property( CR_MatchClock, MatchCCLK );      // use CR_MatchClock to form a far-end cluster on each TCK net
                                               // property must be associated with a range of a port of a TPart
    MatchCCLK   <= Drv_CCLK.Term1.A( 7, 1 );   // 1, 3, 5, 7
    MatchCCLK   <= Drv_CCLK.Term2.B( 5, 0 );   // 0, 1, 3, 5
    MatchCCLK.LongLengthMatchTolerance = -1;   // do not match long length, just form the far-end cluster
    MatchCCLK.ShortMaxLength = 3000;           // override default max length for short stubs
 
 
// DIN
    for ( int i = 0; i < DPU_HalfCount; ++ i ) {
      "DIN_A"  <<       A.CONF[ i ].DIN               // one DIN per half
               <<                HO.DIN;              // Host GPU is nearest A half
      "DIN_B"  <<       B.CONF[ i ].DIN;
    }
 
    "DIN_MB"   <<      BK.JTAG_CONF.DIN               // one DIN for all others
               <<        DC.DC_FPGA.DIN
               <<     DX.DXF_FPGA_A.DIN
               <<     DX.DXF_FPGA_B.DIN
               <<       DX.DXB_FPGA.DIN
               <<       IC.TTC_FPGA.DIN
               <<  IC.BPI_FPGA[ 0 ].DIN
               <<  IC.BPI_FPGA[ 1 ].DIN
               <<  IC.BPI_FPGA[ 2 ].DIN
               <<  IC.BPI_FPGA[ 3 ].DIN
               <<  IC.BPI_FPGA[ 4 ].DIN
               <<  IC.BPI_FPGA[ 5 ].DIN;
 
    if ( mp != mono_count )
      BEGERR << "CM_JTAG::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