diff --git a/Data/VCD.hs b/Data/VCD.hs
--- a/Data/VCD.hs
+++ b/Data/VCD.hs
@@ -7,7 +7,6 @@
   , Variable (..)
   , variable
   , newVCD
-  , scope
   , step
   , step'
   -- * VCD Parsing
@@ -23,6 +22,7 @@
 import Data.Int
 import Data.IORef
 import Data.Word
+import Language.ImProve.Tree
 import System.IO
 import Text.ParserCombinators.Poly.Lazy
 import Text.Printf
@@ -35,6 +35,7 @@
   , time     :: IORef Int
   , codes    :: IORef [String]
   , dumpvars :: IORef (IO ())
+  , vars     :: IORef [(String, Int, String, [String])] -- ^ (typ, width, code, path)
   }
 
 -- | VCD Timescale.
@@ -70,7 +71,7 @@
 -- | Types that can be recorded as VCD variables.
 class Variable a where
   -- | Define a new variable.
-  var :: VCDHandle -> String -> a -> IO (a -> IO ())
+  var :: VCDHandle -> [String] -> a -> IO (a -> IO ())
 
 instance Variable Bool   where var = variable "wire" 1 (\ a -> if a then "1" else "0")
 instance Variable Int    where var vcd name init = variable "integer" (bitSize init) bitString vcd name init
@@ -91,10 +92,10 @@
   bits = dropWhile (== '0') $ [ if testBit n i then '1' else '0' | i <- [bitSize n - 1, bitSize n - 2 .. 0] ]
 
 -- | Helper to create new 'Variable' instances.
-variable :: Eq a => String -> Int -> (a -> String) -> VCDHandle -> String -> a -> IO (a -> IO ())
-variable typ width value vcd name init = do
+variable :: Eq a => String -> Int -> (a -> String) -> VCDHandle -> [String] -> a -> IO (a -> IO ())
+variable typ width value vcd path init = do
   code <- nextCode vcd
-  hPutStrLn (handle vcd) $ printf "$var %s %d %s %s $end" typ width code name
+  modifyIORef (vars vcd) ((typ, width, code, path) :)
   last <- newIORef Nothing
   let sample a = do assertNotDefs vcd
                     last' <- readIORef last
@@ -117,6 +118,7 @@
   time     <- newIORef 0
   codes    <- newIORef identCodes
   dumpvars <- newIORef $ return ()
+  vars     <- newIORef []
   return VCDHandle
     { handle   = h
     , defs     = defs
@@ -124,27 +126,30 @@
     , time     = time
     , codes    = codes
     , dumpvars = dumpvars
+    , vars     = vars
     }
 
--- | Define a hierarchical scope.
-scope :: VCDHandle -> String -> IO a -> IO a
-scope vcd name a = do
-  hPutStrLn (handle vcd) $ "$scope module " ++ name ++ " $end"
-  a <- a
-  hPutStrLn (handle vcd) $ "$upscope $end"
-  return a
-
 stepInit :: VCDHandle -> IO ()
 stepInit vcd = do
   defs'     <- readIORef $ defs     vcd
   dumpvars' <- readIORef $ dumpvars vcd
+  vars'     <- readIORef $ vars     vcd
   when defs' $ do
     writeIORef (defs vcd) False
+    mapM_ (defineVar $ handle vcd) $ tree (\ (_, _, _, a) -> a) vars'
     hPutStrLn (handle vcd) "$enddefinitions $end"
     hPutStrLn (handle vcd) "$dumpvars"
     dumpvars'
     hPutStrLn (handle vcd) "$end"
     writeIORef (dirty vcd) True
+
+defineVar :: Handle -> Tree String (String, Int, String, [String]) -> IO ()
+defineVar h a = case a of
+  Branch name subs -> do
+    hPutStrLn h $ "$scope module " ++ name ++ " $end"
+    mapM_ (defineVar h) subs
+    hPutStrLn h $ "$upscope $end"
+  Leaf name (typ, width, code, _) -> hPutStrLn h $ printf "$var %s %d %s %s $end" typ width code name
 
 -- | Set a time step.  'step' will also transition a VCDHandle from the definition to the recording phase.
 step :: VCDHandle -> Int -> IO ()
diff --git a/vcd.cabal b/vcd.cabal
--- a/vcd.cabal
+++ b/vcd.cabal
@@ -1,13 +1,13 @@
 name:    vcd
-version: 0.1.4
+version: 0.2.0
 
-category: Data
+category: Data, Hardware, Embedded
 
-synopsis: Tools for reading and writing VCD files.
+synopsis: Reading and writing VCD files.
 
 description:
-  VCD (value change dump) is a format for capturing digital and analog waveforms.
-  GTKWave is a popular viewer of VCD files.
+  Defined by the Verilog standard, VCD (value change dump) is a file format for
+  capturing digital and analog waveforms, typically from HDL simulation.
 
 author:     Tom Hawkins <tomahawkins@gmail.com>
 maintainer: Tom Hawkins <tomahawkins@gmail.com>
@@ -22,16 +22,13 @@
 
 library
     build-depends:
-        base       >= 4.0 && < 5.0,
-        polyparse  >= 1.4
+        base       >= 4.0   && < 5.0,
+        polyparse  >= 1.4   && < 1.5,
+        improve    >= 0.1.0 && < 0.2
 
     exposed-modules:
         Data.VCD
 
---    extensions:
-
-    if impl(ghc > 6.8)
-          ghc-options: -fwarn-tabs
     ghc-options:       -W
 
 source-repository head
