diff --git a/b_asic/utils.py b/b_asic/utils.py
index baa3b29afded1d29eb60271cf80815722d7b4892..19cf56422c359b682174f7a5660a5cf4a3eb8f0a 100644
--- a/b_asic/utils.py
+++ b/b_asic/utils.py
@@ -1,4 +1,4 @@
-"""B-ASIC Utils."""
+"""B-ASIC Utilities."""
 
 from typing import List, Sequence
 
@@ -9,17 +9,22 @@ def interleave(*args) -> List[Num]:
     """
     Interleave a number of arrays.
 
-    For the input ``interleave([1, 2], [3, 4])``, return ``[1, 3, 2, 4]``.
-
     Parameters
     ----------
     *args : a number of arrays
         Arrays to interleave. Must be of the same length.
 
-    Returns
-    -------
-
-
+    Examples
+    --------
+    >>> from b_asic.utils import interleave
+    ...
+    ... a = [1, 2]
+    ... b = [3, 4]
+    ... interleave(a, b)
+    [1, 3, 2, 4]
+    >>> c = [-1, 0]
+    ... interleave(a, b, c)
+    [1, 3, -1, 2, 4, 0]
     """
     return [val for tup in zip(*args) for val in tup]
 
@@ -39,9 +44,77 @@ def downsample(a: Sequence[Num], factor: int, phase: int = 0) -> List[Num]:
     phase : int, default: 0
         The phase of the downsampling.
 
-    Returns
-    -------
+    Examples
+    --------
+    >>> from b_asic.utils import downsample
+    ...
+    ... a = list(range(6))
+    ... downsample(a, 3)
+    [0, 3]
+    >>> downsample(a, 3, 1)
+    [1, 4]
+    """
+    return a[phase::factor]
 
 
+def upsample(a: Sequence[Num], factor: int, phase: int = 0) -> List[Num]:
     """
-    return a[phase::factor]
+    Upsample a sequence with an integer factor.
+
+    Insert *factor* - 1 zeros between every value, starting with *phase* zeros.
+
+    Parameters
+    ----------
+    a : array
+        The array to upsample.
+    factor : int
+        The factor to upsample with.
+    phase : int, default: 0
+        The phase of the upsampling.
+
+    Examples
+    --------
+    >>> from b_asic.utils import upsample
+    ...
+    ... a = list(range(1, 4))
+    ... upsample(a, 3)
+    [1, 0, 0, 2, 0, 0, 3, 0, 0]
+    >>> upsample(a, 3, 1)
+    [0, 1, 0, 0, 2, 0, 0, 3, 0]
+    """
+    length = len(a)
+    zeros = [0] * length
+    args = []
+    for _ in range(phase):
+        args.append(zeros)
+    args.append(a)
+    for _ in range(factor - phase - 1):
+        args.append(zeros)
+    return interleave(*args)
+
+
+def decompose(a: Sequence[Num], factor: int) -> List[List[Num]]:
+    """
+    Polyphase decompose signal *a* into *factor* parts.
+
+    Return *factor* lists, each with every *factor* value.
+
+    Parameters
+    ----------
+    a : array
+        The array to polyphase decompose.
+    factor : int
+        The number of polyphase components with.
+
+    Examples
+    --------
+    >>> from b_asic.utils import decompose
+    ...
+    ... a = list(range(6))
+    ... decompose(a, 2)
+    [[0, 2, 4], [1, 3, 5]]
+    >>> decompose(a, 3)
+    [[0, 3], [1, 4], [2, 5]]
+
+    """
+    return [downsample(a, factor, phase) for phase in range(factor)]
diff --git a/test/test_utils.py b/test/test_utils.py
index b67446a98fc1364ddeb4affcd156d9fb2773af83..823f01924894884f152b90805b1a2184a70ec6be 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -2,7 +2,7 @@
 B-ASIC test suite for the utils module.
 """
 
-from b_asic.utils import downsample, interleave
+from b_asic.utils import decompose, downsample, interleave, upsample
 
 
 def test_interleave():
@@ -20,3 +20,18 @@ def test_downsample():
     assert downsample(a, 6, 3) == [3, 9]
     assert downsample(a, 4) == [0, 4, 8]
     assert downsample(a, 3, 1) == [1, 4, 7, 10]
+
+
+def test_upsample():
+    a = list(range(3))
+    assert upsample(a, 2) == [0, 0, 1, 0, 2, 0]
+    assert upsample(a, 2, 1) == [0, 0, 0, 1, 0, 2]
+    a = list(range(1, 4))
+    assert upsample(a, 3) == [1, 0, 0, 2, 0, 0, 3, 0, 0]
+    assert upsample(a, 3, 1) == [0, 1, 0, 0, 2, 0, 0, 3, 0]
+
+
+def test_decompose():
+    a = list(range(6))
+    assert decompose(a, 2) == [[0, 2, 4], [1, 3, 5]]
+    assert decompose(a, 3) == [[0, 3], [1, 4], [2, 5]]