Coolquest, Inc. | Home | Products | Support | About | Contact | |||
|
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 |