diff --git a/CHANGELOG.md b/CHANGELOG.md
index f365da9d..503ac041 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
 
 ## [Unreleased]
 
+- Move `Reg` in separate file
 - Use `warning` class in docs
 - Refactor `Accessor`
 
diff --git a/src/generate/device.rs b/src/generate/device.rs
index 25d6bdd2..dd601ada 100644
--- a/src/generate/device.rs
+++ b/src/generate/device.rs
@@ -140,6 +140,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
     }
 
     let generic_file = include_str!("generic.rs");
+    let generic_reg_file = include_str!("generic_reg_vcell.rs");
     let generic_atomic_file = include_str!("generic_atomic.rs");
     if config.generic_mod {
         let mut file = File::create(
@@ -150,6 +151,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
                 .join("generic.rs"),
         )?;
         writeln!(file, "{generic_file}")?;
+        writeln!(file, "{generic_reg_file}")?;
         if config.atomics {
             if let Some(atomics_feature) = config.atomics_feature.as_ref() {
                 writeln!(file, "#[cfg(feature = \"{atomics_feature}\")]")?;
@@ -167,6 +169,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
         }
     } else {
         let mut tokens = syn::parse_file(generic_file)?.into_token_stream();
+        syn::parse_file(generic_reg_file)?.to_tokens(&mut tokens);
         if config.atomics {
             if let Some(atomics_feature) = config.atomics_feature.as_ref() {
                 quote!(#[cfg(feature = #atomics_feature)]).to_tokens(&mut tokens);
@@ -246,9 +249,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
                     #feature_attribute
                     pub #p_singleton: #p_ty,
                 });
-                exprs.extend(
-                    quote!(#feature_attribute #p_singleton: #p_ty { _marker: PhantomData },),
-                );
+                exprs.extend(quote!(#feature_attribute #p_singleton: #p_ty::steal(),));
             }
             Peripheral::Array(p, dim_element) => {
                 for p_name in names(p, dim_element) {
@@ -263,9 +264,7 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
                         #feature_attribute
                         pub #p_singleton: #p_ty,
                     });
-                    exprs.extend(
-                        quote!(#feature_attribute #p_singleton: #p_ty { _marker: PhantomData },),
-                    );
+                    exprs.extend(quote!(#feature_attribute #p_singleton: #p_ty::steal(),));
                 }
             }
         }
diff --git a/src/generate/generic.rs b/src/generate/generic.rs
index 6921b5ab..2f8d6f7b 100644
--- a/src/generate/generic.rs
+++ b/src/generate/generic.rs
@@ -95,178 +95,6 @@ pub trait Resettable: RegisterSpec {
     }
 }
 
-/// This structure provides volatile access to registers.
-#[repr(transparent)]
-pub struct Reg<REG: RegisterSpec> {
-    register: vcell::VolatileCell<REG::Ux>,
-    _marker: marker::PhantomData<REG>,
-}
-
-unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
-
-impl<REG: RegisterSpec> Reg<REG> {
-    /// Returns the underlying memory address of register.
-    ///
-    /// ```ignore
-    /// let reg_ptr = periph.reg.as_ptr();
-    /// ```
-    #[inline(always)]
-    pub fn as_ptr(&self) -> *mut REG::Ux {
-        self.register.as_ptr()
-    }
-}
-
-impl<REG: Readable> Reg<REG> {
-    /// Reads the contents of a `Readable` register.
-    ///
-    /// You can read the raw contents of a register by using `bits`:
-    /// ```ignore
-    /// let bits = periph.reg.read().bits();
-    /// ```
-    /// or get the content of a particular field of a register:
-    /// ```ignore
-    /// let reader = periph.reg.read();
-    /// let bits = reader.field1().bits();
-    /// let flag = reader.field2().bit_is_set();
-    /// ```
-    #[inline(always)]
-    pub fn read(&self) -> R<REG> {
-        R {
-            bits: self.register.get(),
-            _reg: marker::PhantomData,
-        }
-    }
-}
-
-impl<REG: Resettable + Writable> Reg<REG> {
-    /// Writes the reset value to `Writable` register.
-    ///
-    /// Resets the register to its initial state.
-    #[inline(always)]
-    pub fn reset(&self) {
-        self.register.set(REG::RESET_VALUE)
-    }
-
-    /// Writes bits to a `Writable` register.
-    ///
-    /// You can write raw bits into a register:
-    /// ```ignore
-    /// periph.reg.write(|w| unsafe { w.bits(rawbits) });
-    /// ```
-    /// or write only the fields you need:
-    /// ```ignore
-    /// periph.reg.write(|w| w
-    ///     .field1().bits(newfield1bits)
-    ///     .field2().set_bit()
-    ///     .field3().variant(VARIANT)
-    /// );
-    /// ```
-    /// or an alternative way of saying the same:
-    /// ```ignore
-    /// periph.reg.write(|w| {
-    ///     w.field1().bits(newfield1bits);
-    ///     w.field2().set_bit();
-    ///     w.field3().variant(VARIANT)
-    /// });
-    /// ```
-    /// In the latter case, other fields will be set to their reset value.
-    #[inline(always)]
-    pub fn write<F>(&self, f: F)
-    where
-        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
-    {
-        self.register.set(
-            f(&mut W {
-                bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
-                    | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
-                _reg: marker::PhantomData,
-            })
-            .bits,
-        );
-    }
-}
-
-impl<REG: Writable> Reg<REG> {
-    /// Writes 0 to a `Writable` register.
-    ///
-    /// Similar to `write`, but unused bits will contain 0.
-    ///
-    /// # Safety
-    ///
-    /// Unsafe to use with registers which don't allow to write 0.
-    #[inline(always)]
-    pub unsafe fn write_with_zero<F>(&self, f: F)
-    where
-        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
-    {
-        self.register.set(
-            f(&mut W {
-                bits: REG::Ux::default(),
-                _reg: marker::PhantomData,
-            })
-            .bits,
-        );
-    }
-}
-
-impl<REG: Readable + Writable> Reg<REG> {
-    /// Modifies the contents of the register by reading and then writing it.
-    ///
-    /// E.g. to do a read-modify-write sequence to change parts of a register:
-    /// ```ignore
-    /// periph.reg.modify(|r, w| unsafe { w.bits(
-    ///    r.bits() | 3
-    /// ) });
-    /// ```
-    /// or
-    /// ```ignore
-    /// periph.reg.modify(|_, w| w
-    ///     .field1().bits(newfield1bits)
-    ///     .field2().set_bit()
-    ///     .field3().variant(VARIANT)
-    /// );
-    /// ```
-    /// or an alternative way of saying the same:
-    /// ```ignore
-    /// periph.reg.modify(|_, w| {
-    ///     w.field1().bits(newfield1bits);
-    ///     w.field2().set_bit();
-    ///     w.field3().variant(VARIANT)
-    /// });
-    /// ```
-    /// Other fields will have the value they had before the call to `modify`.
-    #[inline(always)]
-    pub fn modify<F>(&self, f: F)
-    where
-        for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
-    {
-        let bits = self.register.get();
-        self.register.set(
-            f(
-                &R {
-                    bits,
-                    _reg: marker::PhantomData,
-                },
-                &mut W {
-                    bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
-                        | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
-                    _reg: marker::PhantomData,
-                },
-            )
-            .bits,
-        );
-    }
-}
-
-impl<REG: Readable> core::fmt::Debug for crate::generic::Reg<REG>
-where
-    R<REG>: core::fmt::Debug
-{
-    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        core::fmt::Debug::fmt(&self.read(), f)
-    }
-}
-
 #[doc(hidden)]
 pub mod raw {
     use super::{marker, BitM, FieldSpec, RegisterSpec, Unsafe, Writable};
diff --git a/src/generate/generic_reg_vcell.rs b/src/generate/generic_reg_vcell.rs
new file mode 100644
index 00000000..5081ae20
--- /dev/null
+++ b/src/generate/generic_reg_vcell.rs
@@ -0,0 +1,171 @@
+/// This structure provides volatile access to registers.
+#[repr(transparent)]
+pub struct Reg<REG: RegisterSpec> {
+    register: vcell::VolatileCell<REG::Ux>,
+    _marker: marker::PhantomData<REG>,
+}
+
+unsafe impl<REG: RegisterSpec> Send for Reg<REG> where REG::Ux: Send {}
+
+impl<REG: RegisterSpec> Reg<REG> {
+    /// Returns the underlying memory address of register.
+    ///
+    /// ```ignore
+    /// let reg_ptr = periph.reg.as_ptr();
+    /// ```
+    #[inline(always)]
+    pub fn as_ptr(&self) -> *mut REG::Ux {
+        self.register.as_ptr()
+    }
+}
+
+impl<REG: Readable> Reg<REG> {
+    /// Reads the contents of a `Readable` register.
+    ///
+    /// You can read the raw contents of a register by using `bits`:
+    /// ```ignore
+    /// let bits = periph.reg.read().bits();
+    /// ```
+    /// or get the content of a particular field of a register:
+    /// ```ignore
+    /// let reader = periph.reg.read();
+    /// let bits = reader.field1().bits();
+    /// let flag = reader.field2().bit_is_set();
+    /// ```
+    #[inline(always)]
+    pub fn read(&self) -> R<REG> {
+        R {
+            bits: self.register.get(),
+            _reg: marker::PhantomData,
+        }
+    }
+}
+
+impl<REG: Resettable + Writable> Reg<REG> {
+    /// Writes the reset value to `Writable` register.
+    ///
+    /// Resets the register to its initial state.
+    #[inline(always)]
+    pub fn reset(&self) {
+        self.register.set(REG::RESET_VALUE)
+    }
+
+    /// Writes bits to a `Writable` register.
+    ///
+    /// You can write raw bits into a register:
+    /// ```ignore
+    /// periph.reg.write(|w| unsafe { w.bits(rawbits) });
+    /// ```
+    /// or write only the fields you need:
+    /// ```ignore
+    /// periph.reg.write(|w| w
+    ///     .field1().bits(newfield1bits)
+    ///     .field2().set_bit()
+    ///     .field3().variant(VARIANT)
+    /// );
+    /// ```
+    /// or an alternative way of saying the same:
+    /// ```ignore
+    /// periph.reg.write(|w| {
+    ///     w.field1().bits(newfield1bits);
+    ///     w.field2().set_bit();
+    ///     w.field3().variant(VARIANT)
+    /// });
+    /// ```
+    /// In the latter case, other fields will be set to their reset value.
+    #[inline(always)]
+    pub fn write<F>(&self, f: F)
+    where
+        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
+    {
+        self.register.set(
+            f(&mut W {
+                bits: REG::RESET_VALUE & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
+                    | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
+                _reg: marker::PhantomData,
+            })
+            .bits,
+        );
+    }
+}
+
+impl<REG: Writable> Reg<REG> {
+    /// Writes 0 to a `Writable` register.
+    ///
+    /// Similar to `write`, but unused bits will contain 0.
+    ///
+    /// # Safety
+    ///
+    /// Unsafe to use with registers which don't allow to write 0.
+    #[inline(always)]
+    pub unsafe fn write_with_zero<F>(&self, f: F)
+    where
+        F: FnOnce(&mut W<REG>) -> &mut W<REG>,
+    {
+        self.register.set(
+            f(&mut W {
+                bits: REG::Ux::default(),
+                _reg: marker::PhantomData,
+            })
+            .bits,
+        );
+    }
+}
+
+impl<REG: Readable + Writable> Reg<REG> {
+    /// Modifies the contents of the register by reading and then writing it.
+    ///
+    /// E.g. to do a read-modify-write sequence to change parts of a register:
+    /// ```ignore
+    /// periph.reg.modify(|r, w| unsafe { w.bits(
+    ///    r.bits() | 3
+    /// ) });
+    /// ```
+    /// or
+    /// ```ignore
+    /// periph.reg.modify(|_, w| w
+    ///     .field1().bits(newfield1bits)
+    ///     .field2().set_bit()
+    ///     .field3().variant(VARIANT)
+    /// );
+    /// ```
+    /// or an alternative way of saying the same:
+    /// ```ignore
+    /// periph.reg.modify(|_, w| {
+    ///     w.field1().bits(newfield1bits);
+    ///     w.field2().set_bit();
+    ///     w.field3().variant(VARIANT)
+    /// });
+    /// ```
+    /// Other fields will have the value they had before the call to `modify`.
+    #[inline(always)]
+    pub fn modify<F>(&self, f: F)
+    where
+        for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
+    {
+        let bits = self.register.get();
+        self.register.set(
+            f(
+                &R {
+                    bits,
+                    _reg: marker::PhantomData,
+                },
+                &mut W {
+                    bits: bits & !REG::ONE_TO_MODIFY_FIELDS_BITMAP
+                        | REG::ZERO_TO_MODIFY_FIELDS_BITMAP,
+                    _reg: marker::PhantomData,
+                },
+            )
+            .bits,
+        );
+    }
+}
+
+impl<REG: Readable> core::fmt::Debug for crate::generic::Reg<REG>
+where
+    R<REG>: core::fmt::Debug
+{
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        core::fmt::Debug::fmt(&self.read(), f)
+    }
+}