diff --git a/src/topsideZDC.cpp b/src/topsideZDC.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..17778d7faf8b9bb4032d1d42ed391ed9d380419f
--- /dev/null
+++ b/src/topsideZDC.cpp
@@ -0,0 +1,117 @@
+//==========================================================================
+//  Zero Degree Calorimeter Detector implementation 
+//--------------------------------------------------------------------------
+//  Build two towers of ZDC - small and large
+//  Sampling type calorimeter
+//  J.KIM
+//  Created  2020-07-21 
+//  Modified 2020-07-22
+//==========================================================================
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/Printout.h"
+#include <XML/Helper.h>
+#include "TMath.h"
+#include "DDRec/Surface.h"
+#include "DDRec/DetectorData.h"
+#include "XML/Layering.h"
+#include "Math/Transform3D.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace dd4hep::rec;
+using namespace dd4hep::detail;
+
+/** \addtogroup calorimeters Calorimeters 
+ */
+
+/** \addtogroup ZeroDegreeCalorimeter Zero-degree calorimeter
+ * \brief Type: **ZeroDegreeCAL**.
+ * \author J. Kim
+ * \ingroup calorimeters
+ *
+ *
+ * \code
+ *  	<detector id="2" name="largeZDC" type="ZDC" readout="ZDCHits" vis="RedVis">
+ *   
+ * \endcode
+ *
+ * @{
+ */
+static Ref_t createDetector(Detector& lcdd, xml_h e, SensitiveDetector sens) {
+  	xml_det_t  x_det     = e;
+	int        det_id    = x_det.id();
+  	string     det_name  = x_det.nameStr();
+  	xml_dim_t  pos       = x_det.position();
+  	double     x_pos     = dd4hep::getAttrOrDefault(pos, _Unicode(x),0.0);
+  	double     y_pos     = dd4hep::getAttrOrDefault(pos, _Unicode(y),0.0);
+  	double     z_pos     = dd4hep::getAttrOrDefault(pos, _Unicode(z),0.0);
+	xml_dim_t  dim       = x_det.dimensions();
+	double     pixel_x   = dim.x();
+	double     pixel_y   = dim.y();
+	Material   air       = lcdd.material("Air");	
+	double     z         = z_pos;
+	double     zmin      = z_pos;
+	DetElement det(det_name, det_id);
+	
+	int layer_num = 1;
+	int slice_num = 1;
+	double totWidth = Layering(x_det).totalThickness();
+	Box envelope (pixel_x/2.0, pixel_y/2.0,totWidth);
+	Volume envelopeVol(det_name+"_envelope",envelope,air); 
+	PlacedVolume pv;
+	
+	xml_comp_t x_layer = x_det.child(_U(layer));
+
+	// Read layers
+	for(xml_coll_t c(x_det,_U(layer)); c; ++c)
+	{
+		xml_comp_t x_layer = c;
+		int repeat = x_layer.repeat();
+		double layerWidth = 0;
+		for(xml_coll_t l(x_layer,_U(slice)); l; ++l)
+			layerWidth += xml_comp_t(l).thickness();
+
+		// Loop over repeat#
+		for(int i=0; i< repeat; i++)
+		{
+			double zlayer = z;
+			string layer_name = det_name + _toString(layer_num,"_layer%d");
+			Volume layer_vol(layer_name,Box(pixel_x/2.0, pixel_y/2.0,layerWidth/2.0),air);
+
+			// Loop over slices
+			for(xml_coll_t l(x_layer,_U(slice)); l; ++l)
+			{
+				xml_comp_t x_slice = l;
+				double w = x_slice.thickness();
+				string slice_name = layer_name + _toString(slice_num,"slice%d");
+				Material slice_mat = lcdd.material(x_slice.materialStr());		
+				Volume slice_vol (slice_name,Box(pixel_x/2.0, pixel_y/2.0,w/2.0),slice_mat);
+				if(x_slice.isSensitive())
+				{
+					sens.setType("calorimeter");
+					slice_vol.setSensitiveDetector(sens);
+				}
+				slice_vol.setAttributes(lcdd,x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
+				pv = layer_vol.placeVolume(slice_vol, Transform3D(RotationZYX(0.0,0.0,0.0),Position(0.0,0.0,z-zlayer-layerWidth/2.0+w/2.0)));
+				pv.addPhysVolID("slice", slice_num);
+				z += w;
+				++slice_num;
+			}
+			string layer_vis = dd4hep::getAttrOrDefault(x_layer, _Unicode(vis), "InvisibleWithDaughters");
+			layer_vol.setAttributes(lcdd, x_layer.regionStr(), x_layer.limitsStr(), layer_vis);
+			pv = envelopeVol.placeVolume(layer_vol, Transform3D(RotationZYX(0.0,0.0,0.0), Position(0,0,zlayer-zmin-totWidth/2.0+layerWidth/2.0)));
+			pv.addPhysVolID("layer", layer_num);
+			++layer_num;
+		}
+	}
+	envelopeVol.setAttributes(lcdd,x_det.regionStr(), x_det.limitsStr(), "InvisibleWithDaughters");
+
+	Volume motherVol = lcdd.pickMotherVolume(det);
+	PlacedVolume phv = motherVol.placeVolume(envelopeVol, Position(x_pos,y_pos,z_pos+totWidth/2.0));
+	phv.addPhysVolID("system", det.id());
+	det.setPlacement(phv);
+
+	return det;
+}
+
+DECLARE_DETELEMENT(topsideZDC, createDetector)
diff --git a/topside.xml b/topside.xml
index 19bcbfdcd1b88227d68f4120d6fe0d7cc2776d59..fbdce383aa283df622f8a3fcd433b16b0e42cf06 100644
--- a/topside.xml
+++ b/topside.xml
@@ -115,6 +115,7 @@
   <include ref="topside/hcal.xml"/>
   <include ref="topside/solenoid.xml"/>
   <include ref="topside/forward_rich.xml"/>
+  <include ref="topside/zero_degree_cal.xml"/>
   <!--
   <include ref="topside/roman_pots.xml"/>
   -->
diff --git a/topside/topside_defs.xml b/topside/topside_defs.xml
index 46fe8c3030083ebbb672140aa19c2fc2c9ebb864..f33ba14ef45e89cd50160f315b298f7ef3b43e23 100644
--- a/topside/topside_defs.xml
+++ b/topside/topside_defs.xml
@@ -218,7 +218,7 @@
 
     </comment>
     <constant name="ForwardRomanPot_ID" value="150"/>
-    <constant name="ZDC_ID"             value="160"/>
+    <constant name="ZDC_lt_ID"          value="160"/>
 
     <comment> 
       =====================================
diff --git a/topside/zero_degree_cal.xml b/topside/zero_degree_cal.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c377e323283c24c8418e1d948833e36f89ed288e
--- /dev/null
+++ b/topside/zero_degree_cal.xml
@@ -0,0 +1,66 @@
+<lccdd>
+  <define>
+    <constant name="offset_ZDC"    value="5.0*mm"/>
+    <constant name="lt_length"     value="400.0*mm"/>
+    <constant name="total_length"  value="210.0*mm"/>
+    <constant name="lt_ZDC_z_pos"  value="B2PF_CenterPosition - B2PF_Length/2.0 - total_length - 12.0*cm"/>
+    <constant name="lt_ZDC_x_pos"  value="lt_ZDC_z_pos * ionCrossingAngle"/>
+    <constant name="lt_ZDC_y_pos"  value="0.0*mm"/>
+  </define>
+
+  <detectors>
+    <detector id="ZDC_lt_ID" name="largeZDC" type="topsideZDC" readout="ZDCHits" vis="RedVis">
+      <position x="lt_ZDC_x_pos" y="lt_ZDC_y_pos" z="lt_ZDC_z_pos"/>
+      <dimensions x = "lt_length" y = "lt_length"/>
+      <layer repeat="2">
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+        <slice name="Scint_slice"    material="PlasticScint"   thickness="3*mm" vis = "BlueVis" sensitive = "true"/>
+      </layer>
+      <layer repeat="1">
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+        <slice name="SciFi_belt"     material="PlasticScint"   thickness="1*mm" vis = "RedVis"  sensitive = "true"/>
+        <slice name="SciFi_belt"     material="PlasticScint"   thickness="1*mm" vis = "RedVis"  sensitive = "true"/>
+      </layer>
+      <layer repeat="2">
+        <slice name="Scint_slice"    material="PlasticScint"   thickness="3*mm" vis = "BlueVis" sensitive = "true"/>
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+      </layer>
+      <layer repeat="2">
+        <slice name="SciFi_belt"     material="PlasticScint"   thickness="1*mm" vis = "RedVis"  sensitive = "true"/>
+      </layer>
+      <layer repeat="7">
+        <slice name="Scint_slice"    material="PlasticScint"   thickness="3*mm" vis = "BlueVis" sensitive = "true"/>
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+      </layer>
+      <layer repeat="1">
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+        <slice name="Scint_slice"    material="PlasticScint"   thickness="3*mm" vis = "BlueVis" sensitive = "true"/>
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+      </layer>
+      <layer repeat="2">
+        <slice name="SciFi_belt"     material="PlasticScint"   thickness="1*mm" vis = "RedVis"  sensitive = "true"/>
+      </layer>
+      <layer repeat="3">
+        <slice name="Scint_slice"    material="PlasticScint"   thickness="3*mm" vis = "BlueVis" sensitive = "true"/>
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+      </layer>
+      <layer repeat="2">
+        <slice name="SciFi_belt"     material="PlasticScint"   thickness="1*mm" vis = "RedVis"  sensitive = "true"/>
+      </layer>
+      <layer repeat="1">
+        <slice name="Scint_slice"    material="PlasticScint"   thickness="3*mm" vis = "BlueVis" sensitive = "true"/>
+        <slice name="Tungsten_slice" material="TungstenDens24" thickness="7*mm" vis = "GrayVis"/>
+      </layer>
+    </detector>		
+  </detectors>
+  
+  <readouts>
+    <readout name="ZDCHits">
+      <segmentation type="CartesianGridXY" grid_size_x="1.0*mm" grid_size_y="1.0*mm" />
+        <id>system:8,layer:12,slice:12,x:48:-8,y:-8</id>  
+    </readout>
+  </readouts>
+
+</lccdd>