diff --git a/tests/fpgadataflow/test_fpgadataflow_fclayer.py b/tests/fpgadataflow/test_fpgadataflow_fclayer.py
index 4f1648feabd690da4a73b2d201dcaad4149725e7..058cb74396176bee5fcde3ccfffb312bbaede45a 100644
--- a/tests/fpgadataflow/test_fpgadataflow_fclayer.py
+++ b/tests/fpgadataflow/test_fpgadataflow_fclayer.py
@@ -7,7 +7,8 @@ import finn.core.onnx_exec as oxe
 import finn.custom_op.xnorpopcount as xp
 from finn.core.datatype import DataType
 from finn.core.modelwrapper import ModelWrapper
-from finn.core.utils import gen_finn_dt_tensor
+from finn.core.utils import calculate_signed_dot_prod_range, gen_finn_dt_tensor
+from finn.custom_op.multithreshold import multithreshold
 from finn.transformation.fpgadataflow.cleanup import CleanUp
 from finn.transformation.fpgadataflow.codegen import CodeGen
 from finn.transformation.fpgadataflow.compile import Compile
@@ -31,9 +32,14 @@ def make_single_fclayer_modelwrapper(W, pe, simd, wdt, idt, odt, T=None, tdt=Non
     outp = helper.make_tensor_value_info("outp", TensorProto.FLOAT, [1, nf, pe])
     if T is not None:
         node_inp_list = ["inp", "weights", "thresh"]
+        if odt == DataType.BIPOLAR:
+            actval = 0
+        else:
+            actval = odt.min()
     else:
         # no thresholds
         node_inp_list = ["inp", "weights"]
+        actval = 0
     FCLayer_node = helper.make_node(
         "StreamingFCLayer_Batch",
         node_inp_list,
@@ -50,6 +56,7 @@ def make_single_fclayer_modelwrapper(W, pe, simd, wdt, idt, odt, T=None, tdt=Non
         inputDataType=idt.name,
         weightDataType=wdt.name,
         outputDataType=odt.name,
+        ActVal=actval,
     )
     graph = helper.make_graph(
         nodes=[FCLayer_node], name="fclayer_graph", inputs=[inp], outputs=[outp]
@@ -77,6 +84,8 @@ def prepare_inputs(model, input_tensor, idt):
     return {"inp": input_tensor}
 
 
+# activation: None or DataType
+@pytest.mark.parametrize("act", [None, DataType.BIPOLAR])
 # weight datatype
 @pytest.mark.parametrize("wdt", [DataType.BIPOLAR, DataType.INT2])
 # input datatype
@@ -89,7 +98,7 @@ def prepare_inputs(model, input_tensor, idt):
 @pytest.mark.parametrize("mw", [4])
 # HLS matrix height (output features)
 @pytest.mark.parametrize("mh", [4])
-def test_fpgadataflow_fclayer_noact(idt, wdt, nf, sf, mw, mh):
+def test_fpgadataflow_fclayer(idt, wdt, act, nf, sf, mw, mh):
     if nf == -1:
         nf = mh
     if sf == -1:
@@ -98,15 +107,32 @@ def test_fpgadataflow_fclayer_noact(idt, wdt, nf, sf, mw, mh):
     simd = mw // sf
     assert mh % pe == 0
     assert mw % sf == 0
-    if wdt == DataType.BIPOLAR and idt == DataType.BIPOLAR:
-        odt = DataType.UINT32
-    else:
-        odt = DataType.INT32
     # generate weights
     W = gen_finn_dt_tensor(wdt, (mw, mh))
     # generate input data
     x = gen_finn_dt_tensor(idt, (1, mw))
-    model = make_single_fclayer_modelwrapper(W, pe, simd, wdt, idt, odt)
+    if act is None:
+        # no activation, produce accumulators
+        T = None
+        tdt = None
+        if wdt == DataType.BIPOLAR and idt == DataType.BIPOLAR:
+            odt = DataType.UINT32
+        else:
+            odt = DataType.INT32
+    else:
+        odt = act
+        (min, max) = calculate_signed_dot_prod_range(idt, wdt, mw)
+        n_steps = act.get_num_possible_values() - 1
+        T = np.random.randint(min, max - 1, (mh, n_steps)).astype(np.float32)
+        # generate thresholds for activation
+        if wdt == DataType.BIPOLAR and idt == DataType.BIPOLAR:
+            tdt = DataType.UINT32
+            # bias thresholds to be positive
+            T = np.ceil((T + mw) / 2)
+            assert (T >= 0).all()
+        else:
+            tdt = DataType.INT32
+    model = make_single_fclayer_modelwrapper(W, pe, simd, wdt, idt, odt, T, tdt)
     model = model.transform(CodeGen())
     model = model.transform(Compile())
     # prepare input data
@@ -116,6 +142,14 @@ def test_fpgadataflow_fclayer_noact(idt, wdt, nf, sf, mw, mh):
         y = xp.xnorpopcountmatmul((x + 1) / 2, (W + 1) / 2)
     else:
         y = np.matmul(x, W)
+    if T is not None:
+        y = multithreshold(y, T)
+        if act == DataType.BIPOLAR:
+            # binary to bipolar
+            y = 2 * y - 1
+        else:
+            # signed offset
+            y -= act.min()
     oshape = model.get_tensor_shape("outp")
     y_expected = y.reshape(oshape)
     # execute model